summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/nss/patches/restartclientauth.patch
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/third_party/nss/patches/restartclientauth.patch')
-rw-r--r--chromium/net/third_party/nss/patches/restartclientauth.patch209
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;