diff options
Diffstat (limited to 'chromium/net/third_party/nss/patches/restartclientauth.patch')
-rw-r--r-- | chromium/net/third_party/nss/patches/restartclientauth.patch | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/chromium/net/third_party/nss/patches/restartclientauth.patch b/chromium/net/third_party/nss/patches/restartclientauth.patch new file mode 100644 index 00000000000..84f18f391e0 --- /dev/null +++ b/chromium/net/third_party/nss/patches/restartclientauth.patch @@ -0,0 +1,209 @@ +diff -pu a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c +--- a/nss/lib/ssl/ssl3con.c 2013-07-31 12:44:31.987362835 -0700 ++++ b/nss/lib/ssl/ssl3con.c 2013-07-31 12:44:50.987642452 -0700 +@@ -6756,6 +6756,85 @@ done: + return rv; + } + ++/* ++ * attempt to restart the handshake after asynchronously handling ++ * a request for the client's certificate. ++ * ++ * inputs: ++ * 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. ++ * ++ * 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. ++ * The caller should drop its reference without destroying the ++ * chain. SSL will free the chain when it is done with it. ++ * ++ * Return value: XXX ++ * ++ * XXX This code only works on the initial handshake on a connection, XXX ++ * It does not work on a subsequent handshake (redo). ++ * ++ * Caller holds 1stHandshakeLock. ++ */ ++SECStatus ++ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, ++ CERTCertificate * cert, ++ SECKEYPrivateKey * key, ++ CERTCertificateList *certChain) ++{ ++ SECStatus rv = SECSuccess; ++ ++ /* XXX This code only works on the initial handshake on a connection, ++ ** XXX It does not work on a subsequent handshake (redo). ++ */ ++ if (ss->handshake != 0) { ++ ss->handshake = ssl_GatherRecord1stHandshake; ++ ss->ssl3.clientCertificate = cert; ++ ss->ssl3.clientPrivateKey = key; ++ ss->ssl3.clientCertChain = certChain; ++ 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); ++ } ++ } ++ } else { ++ if (cert) { ++ CERT_DestroyCertificate(cert); ++ } ++ if (key) { ++ SECKEY_DestroyPrivateKey(key); ++ } ++ if (certChain) { ++ CERT_DestroyCertificateList(certChain); ++ } ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); ++ rv = SECFailure; ++ } ++ return rv; ++} ++ + PRBool + ssl3_CanFalseStart(sslSocket *ss) { + PRBool rv; +diff -pu a/nss/lib/ssl/ssl.h b/nss/lib/ssl/ssl.h +--- a/nss/lib/ssl/ssl.h 2013-07-31 12:44:31.987362835 -0700 ++++ b/nss/lib/ssl/ssl.h 2013-07-31 12:44:50.987642452 -0700 +@@ -366,6 +366,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 +diff -pu a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h +--- a/nss/lib/ssl/sslimpl.h 2013-07-31 12:44:31.997362988 -0700 ++++ b/nss/lib/ssl/sslimpl.h 2013-07-31 12:44:50.987642452 -0700 +@@ -1513,16 +1513,17 @@ extern SECStatus ssl3_MasterKeyDeriveBy + /* These functions are called from secnav, even though they're "private". */ + + extern int ssl2_SendErrorMessage(struct sslSocketStr *ss, int error); +-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, + SSL3AlertDescription desc); + extern SECStatus ssl3_DecodeError(sslSocket *ss); + ++extern SECStatus ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, ++ CERTCertificate * cert, ++ SECKEYPrivateKey * key, ++ CERTCertificateList *certChain); ++ + extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error); + + /* +diff -pu a/nss/lib/ssl/sslsecur.c b/nss/lib/ssl/sslsecur.c +--- a/nss/lib/ssl/sslsecur.c 2013-07-31 12:28:39.283413269 -0700 ++++ b/nss/lib/ssl/sslsecur.c 2013-07-31 12:44:50.987642452 -0700 +@@ -1436,17 +1436,70 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERT + return SECSuccess; + } + +-/* DO NOT USE. This function was exported in ssl.def with the wrong signature; +- * this implementation exists to maintain link-time compatibility. ++/* ++ * attempt to restart the handshake after asynchronously handling ++ * a request for the client's certificate. ++ * ++ * inputs: ++ * 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_DestroyCertificate after calling this ++ * function. ++ * ++ * 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. ++ * The caller should drop its reference without destroying the ++ * chain. SSL will free the chain when it is done with it. ++ * ++ * Return value: XXX ++ * ++ * 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) + { +- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); +- return -1; ++ sslSocket * ss = ssl_FindSocket(fd); ++ SECStatus ret; ++ ++ if (!ss) { ++ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RestartHandshakeAfterCertReq", ++ SSL_GETPID(), fd)); ++ if (cert) { ++ CERT_DestroyCertificate(cert); ++ } ++ if (key) { ++ SECKEY_DestroyPrivateKey(key); ++ } ++ if (certChain) { ++ CERT_DestroyCertificateList(certChain); ++ } ++ 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); ++ } ++ PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); ++ ret = SECFailure; ++ } ++ ++ ssl_Release1stHandshakeLock(ss); /************************************/ ++ return ret; + } + + /* DO NOT USE. This function was exported in ssl.def with the wrong signature; |