summaryrefslogtreecommitdiffstats
path: root/net/third_party
diff options
context:
space:
mode:
authorwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-17 21:17:55 +0000
committerwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-17 21:17:55 +0000
commit44461ab16be07990bc94232b5bde10e2b14f537a (patch)
tree4ddfdb3d4aaae0e29a779015d3b59a22fa2f01ea /net/third_party
parent5f8589feb682a4829f43b4325c3d373d78283444 (diff)
downloadchromium_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.chromium3
-rwxr-xr-xnet/third_party/nss/patches/applypatches.sh2
-rw-r--r--net/third_party/nss/patches/restartclientauth.patch149
-rw-r--r--net/third_party/nss/ssl/ssl.h5
-rw-r--r--net/third_party/nss/ssl/ssl3con.c32
-rw-r--r--net/third_party/nss/ssl/sslimpl.h4
-rw-r--r--net/third_party/nss/ssl/sslsecur.c26
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);
}