diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-17 21:17:55 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-17 21:17:55 +0000 |
commit | 44461ab16be07990bc94232b5bde10e2b14f537a (patch) | |
tree | 4ddfdb3d4aaae0e29a779015d3b59a22fa2f01ea /net/third_party | |
parent | 5f8589feb682a4829f43b4325c3d373d78283444 (diff) | |
download | chromium_src-44461ab16be07990bc94232b5bde10e2b14f537a.zip chromium_src-44461ab16be07990bc94232b5bde10e2b14f537a.tar.gz chromium_src-44461ab16be07990bc94232b5bde10e2b14f537a.tar.bz2 |
Add an NSS function to restart the handshake after a client certificate
request.
R=agl@chromium.org,rkn@chromium.org
BUG=88782
TEST=none
Review URL: http://codereview.chromium.org/7590017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97208 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/third_party')
-rw-r--r-- | net/third_party/nss/README.chromium | 3 | ||||
-rwxr-xr-x | net/third_party/nss/patches/applypatches.sh | 2 | ||||
-rw-r--r-- | net/third_party/nss/patches/restartclientauth.patch | 149 | ||||
-rw-r--r-- | net/third_party/nss/ssl/ssl.h | 5 | ||||
-rw-r--r-- | net/third_party/nss/ssl/ssl3con.c | 32 | ||||
-rw-r--r-- | net/third_party/nss/ssl/sslimpl.h | 4 | ||||
-rw-r--r-- | net/third_party/nss/ssl/sslsecur.c | 26 |
7 files changed, 202 insertions, 19 deletions
diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium index 790bc61..0e7206c 100644 --- a/net/third_party/nss/README.chromium +++ b/net/third_party/nss/README.chromium @@ -64,6 +64,9 @@ Patches: patches/handshakeshortwrite.patch https://bugzilla.mozilla.org/show_bug.cgi?id=676729 + * Add a function to restart a handshake after a client certificate request. + patches/restartclientauth.patch + Apply the patches to NSS by running the patches/applypatches.sh script. Read the comments at the top of patches/applypatches.sh for instructions. diff --git a/net/third_party/nss/patches/applypatches.sh b/net/third_party/nss/patches/applypatches.sh index db9b423..3bf1561 100755 --- a/net/third_party/nss/patches/applypatches.sh +++ b/net/third_party/nss/patches/applypatches.sh @@ -28,3 +28,5 @@ patch -p6 < $patches_dir/origin_bound_certs.patch patch -p6 < $patches_dir/secret_exporter.patch patch -p5 < $patches_dir/handshakeshortwrite.patch + +patch -p5 < $patches_dir/restartclientauth.patch diff --git a/net/third_party/nss/patches/restartclientauth.patch b/net/third_party/nss/patches/restartclientauth.patch new file mode 100644 index 0000000..736428d --- /dev/null +++ b/net/third_party/nss/patches/restartclientauth.patch @@ -0,0 +1,149 @@ +Index: mozilla/security/nss/lib/ssl/ssl.h +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl.h,v +retrieving revision 1.38.2.4 +diff -u -p -r1.38.2.4 ssl.h +--- mozilla/security/nss/lib/ssl/ssl.h 8 Apr 2011 05:44:32 -0000 1.38.2.4 ++++ mozilla/security/nss/lib/ssl/ssl.h 17 Aug 2011 18:13:58 -0000 +@@ -220,6 +220,11 @@ SSL_IMPORT SECStatus SSL_ForceHandshake( + SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd, + PRIntervalTime timeout); + ++SSL_IMPORT SECStatus SSL_RestartHandshakeAfterCertReq(PRFileDesc *fd, ++ CERTCertificate *cert, ++ SECKEYPrivateKey *key, ++ CERTCertificateList *certChain); ++ + /* + ** Query security status of socket. *on is set to one if security is + ** enabled. *keySize will contain the stream key size used. *issuer will +Index: mozilla/security/nss/lib/ssl/ssl3con.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl3con.c,v +retrieving revision 1.142.2.5 +diff -u -p -r1.142.2.5 ssl3con.c +--- mozilla/security/nss/lib/ssl/ssl3con.c 25 Jan 2011 01:49:22 -0000 1.142.2.5 ++++ mozilla/security/nss/lib/ssl/ssl3con.c 17 Aug 2011 18:13:58 -0000 +@@ -5621,9 +5621,10 @@ done: + * reference count. The caller should drop its reference + * without calling CERT_DestroyCert after calling this function. + * +- * key Private key associated with cert. This function makes a +- * copy of the private key, so the caller remains responsible +- * for destroying its copy after this function returns. ++ * key Private key associated with cert. This function takes ++ * ownership of the private key, so the caller should drop its ++ * reference without destroying the private key after this ++ * function returns. + * + * certChain DER-encoded certs, client cert and its signers. + * Note: ssl takes this reference, and does not copy the chain. +@@ -5652,12 +5653,27 @@ ssl3_RestartHandshakeAfterCertReq(sslSoc + if (ss->handshake != 0) { + ss->handshake = ssl_GatherRecord1stHandshake; + ss->ssl3.clientCertificate = cert; ++ ss->ssl3.clientPrivateKey = key; + ss->ssl3.clientCertChain = certChain; +- if (key == NULL) { +- (void)SSL3_SendAlert(ss, alert_warning, no_certificate); +- ss->ssl3.clientPrivateKey = NULL; +- } else { +- ss->ssl3.clientPrivateKey = SECKEY_CopyPrivateKey(key); ++ if (!cert || !key || !certChain) { ++ /* we are missing the key, cert, or cert chain */ ++ if (ss->ssl3.clientCertificate) { ++ CERT_DestroyCertificate(ss->ssl3.clientCertificate); ++ ss->ssl3.clientCertificate = NULL; ++ } ++ if (ss->ssl3.clientPrivateKey) { ++ SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); ++ ss->ssl3.clientPrivateKey = NULL; ++ } ++ if (ss->ssl3.clientCertChain != NULL) { ++ CERT_DestroyCertificateList(ss->ssl3.clientCertChain); ++ ss->ssl3.clientCertChain = NULL; ++ } ++ if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) { ++ ss->ssl3.sendEmptyCert = PR_TRUE; ++ } else { ++ (void)SSL3_SendAlert(ss, alert_warning, no_certificate); ++ } + } + ssl_GetRecvBufLock(ss); + if (ss->ssl3.hs.msgState.buf != NULL) { +Index: mozilla/security/nss/lib/ssl/sslimpl.h +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslimpl.h,v +retrieving revision 1.77.2.2 +diff -u -p -r1.77.2.2 sslimpl.h +--- mozilla/security/nss/lib/ssl/sslimpl.h 16 Mar 2011 18:55:38 -0000 1.77.2.2 ++++ mozilla/security/nss/lib/ssl/sslimpl.h 17 Aug 2011 18:13:58 -0000 +@@ -1310,10 +1310,6 @@ extern SECStatus ssl3_MasterKeyDeriveBy + + extern int ssl2_SendErrorMessage(struct sslSocketStr *ss, int error); + extern int SSL_RestartHandshakeAfterServerCert(struct sslSocketStr *ss); +-extern int SSL_RestartHandshakeAfterCertReq(struct sslSocketStr *ss, +- CERTCertificate *cert, +- SECKEYPrivateKey *key, +- CERTCertificateList *certChain); + extern sslSocket *ssl_FindSocket(PRFileDesc *fd); + extern void ssl_FreeSocket(struct sslSocketStr *ssl); + extern SECStatus SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, +Index: mozilla/security/nss/lib/ssl/sslsecur.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslsecur.c,v +retrieving revision 1.43.2.4 +diff -u -p -r1.43.2.4 sslsecur.c +--- mozilla/security/nss/lib/ssl/sslsecur.c 8 Apr 2011 05:25:21 -0000 1.43.2.4 ++++ mozilla/security/nss/lib/ssl/sslsecur.c 17 Aug 2011 18:13:58 -0000 +@@ -1453,11 +1453,13 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERT + * cert Client cert chosen by application. + * Note: ssl takes this reference, and does not bump the + * reference count. The caller should drop its reference +- * without calling CERT_DestroyCert after calling this function. ++ * without calling CERT_DestroyCertificate after calling this ++ * function. + * +- * key Private key associated with cert. This function makes a +- * copy of the private key, so the caller remains responsible +- * for destroying its copy after this function returns. ++ * key Private key associated with cert. This function takes ++ * ownership of the private key, so the caller should drop its ++ * reference without destroying the private key after this ++ * function returns. + * + * certChain Chain of signers for cert. + * Note: ssl takes this reference, and does not copy the chain. +@@ -1469,19 +1471,29 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERT + * XXX This code only works on the initial handshake on a connection, XXX + * It does not work on a subsequent handshake (redo). + */ +-int +-SSL_RestartHandshakeAfterCertReq(sslSocket * ss, ++SECStatus ++SSL_RestartHandshakeAfterCertReq(PRFileDesc * fd, + CERTCertificate * cert, + SECKEYPrivateKey * key, + CERTCertificateList *certChain) + { +- int ret; ++ sslSocket * ss = ssl_FindSocket(fd); ++ SECStatus ret; ++ ++ if (!ss) { ++ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RestartHandshakeAfterCertReq", ++ SSL_GETPID(), fd)); ++ return SECFailure; ++ } + + ssl_Get1stHandshakeLock(ss); /************************************/ + + if (ss->version >= SSL_LIBRARY_VERSION_3_0) { + ret = ssl3_RestartHandshakeAfterCertReq(ss, cert, key, certChain); + } else { ++ if (certChain != NULL) { ++ CERT_DestroyCertificateList(certChain); ++ } + ret = ssl2_RestartHandshakeAfterCertReq(ss, cert, key); + } + diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h index 6b364bb..d0e0595 100644 --- a/net/third_party/nss/ssl/ssl.h +++ b/net/third_party/nss/ssl/ssl.h @@ -236,6 +236,11 @@ SSL_IMPORT SECStatus SSL_ForceHandshake(PRFileDesc *fd); SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd, PRIntervalTime timeout); +SSL_IMPORT SECStatus SSL_RestartHandshakeAfterCertReq(PRFileDesc *fd, + CERTCertificate *cert, + SECKEYPrivateKey *key, + CERTCertificateList *certChain); + /* ** Query security status of socket. *on is set to one if security is ** enabled. *keySize will contain the stream key size used. *issuer will diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c index 3f3e7fd..65bd6ae 100644 --- a/net/third_party/nss/ssl/ssl3con.c +++ b/net/third_party/nss/ssl/ssl3con.c @@ -5703,9 +5703,10 @@ done: * reference count. The caller should drop its reference * without calling CERT_DestroyCert after calling this function. * - * key Private key associated with cert. This function makes a - * copy of the private key, so the caller remains responsible - * for destroying its copy after this function returns. + * key Private key associated with cert. This function takes + * ownership of the private key, so the caller should drop its + * reference without destroying the private key after this + * function returns. * * certChain DER-encoded certs, client cert and its signers. * Note: ssl takes this reference, and does not copy the chain. @@ -5734,12 +5735,27 @@ ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, if (ss->handshake != 0) { ss->handshake = ssl_GatherRecord1stHandshake; ss->ssl3.clientCertificate = cert; + ss->ssl3.clientPrivateKey = key; ss->ssl3.clientCertChain = certChain; - if (key == NULL) { - (void)SSL3_SendAlert(ss, alert_warning, no_certificate); - ss->ssl3.clientPrivateKey = NULL; - } else { - ss->ssl3.clientPrivateKey = SECKEY_CopyPrivateKey(key); + if (!cert || !key || !certChain) { + /* we are missing the key, cert, or cert chain */ + if (ss->ssl3.clientCertificate) { + CERT_DestroyCertificate(ss->ssl3.clientCertificate); + ss->ssl3.clientCertificate = NULL; + } + if (ss->ssl3.clientPrivateKey) { + SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); + ss->ssl3.clientPrivateKey = NULL; + } + if (ss->ssl3.clientCertChain != NULL) { + CERT_DestroyCertificateList(ss->ssl3.clientCertChain); + ss->ssl3.clientCertChain = NULL; + } + if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) { + ss->ssl3.sendEmptyCert = PR_TRUE; + } else { + (void)SSL3_SendAlert(ss, alert_warning, no_certificate); + } } ssl_GetRecvBufLock(ss); if (ss->ssl3.hs.msgState.buf != NULL) { diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h index 073616f..e447a7d 100644 --- a/net/third_party/nss/ssl/sslimpl.h +++ b/net/third_party/nss/ssl/sslimpl.h @@ -1382,10 +1382,6 @@ extern SECStatus ssl3_MasterKeyDeriveBypass( ssl3CipherSpec * pwSpec, extern int ssl2_SendErrorMessage(struct sslSocketStr *ss, int error); extern int SSL_RestartHandshakeAfterServerCert(struct sslSocketStr *ss); -extern int SSL_RestartHandshakeAfterCertReq(struct sslSocketStr *ss, - CERTCertificate *cert, - SECKEYPrivateKey *key, - CERTCertificateList *certChain); extern sslSocket *ssl_FindSocket(PRFileDesc *fd); extern void ssl_FreeSocket(struct sslSocketStr *ssl); extern SECStatus SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, diff --git a/net/third_party/nss/ssl/sslsecur.c b/net/third_party/nss/ssl/sslsecur.c index dc374e0..e2e49ca 100644 --- a/net/third_party/nss/ssl/sslsecur.c +++ b/net/third_party/nss/ssl/sslsecur.c @@ -1460,11 +1460,13 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle) * cert Client cert chosen by application. * Note: ssl takes this reference, and does not bump the * reference count. The caller should drop its reference - * without calling CERT_DestroyCert after calling this function. + * without calling CERT_DestroyCertificate after calling this + * function. * - * key Private key associated with cert. This function makes a - * copy of the private key, so the caller remains responsible - * for destroying its copy after this function returns. + * key Private key associated with cert. This function takes + * ownership of the private key, so the caller should drop its + * reference without destroying the private key after this + * function returns. * * certChain Chain of signers for cert. * Note: ssl takes this reference, and does not copy the chain. @@ -1476,19 +1478,29 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle) * XXX This code only works on the initial handshake on a connection, XXX * It does not work on a subsequent handshake (redo). */ -int -SSL_RestartHandshakeAfterCertReq(sslSocket * ss, +SECStatus +SSL_RestartHandshakeAfterCertReq(PRFileDesc * fd, CERTCertificate * cert, SECKEYPrivateKey * key, CERTCertificateList *certChain) { - int ret; + sslSocket * ss = ssl_FindSocket(fd); + SECStatus ret; + + if (!ss) { + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RestartHandshakeAfterCertReq", + SSL_GETPID(), fd)); + return SECFailure; + } ssl_Get1stHandshakeLock(ss); /************************************/ if (ss->version >= SSL_LIBRARY_VERSION_3_0) { ret = ssl3_RestartHandshakeAfterCertReq(ss, cert, key, certChain); } else { + if (certChain != NULL) { + CERT_DestroyCertificateList(certChain); + } ret = ssl2_RestartHandshakeAfterCertReq(ss, cert, key); } |