• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1diff -pu a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c
2--- a/nss/lib/ssl/ssl3con.c	2014-01-17 17:55:01.518095989 -0800
3+++ b/nss/lib/ssl/ssl3con.c	2014-01-17 17:55:19.158389328 -0800
4@@ -7199,6 +7199,85 @@ done:
5     return rv;
6 }
7
8+/*
9+ * attempt to restart the handshake after asynchronously handling
10+ * a request for the client's certificate.
11+ *
12+ * inputs:
13+ *	cert	Client cert chosen by application.
14+ *		Note: ssl takes this reference, and does not bump the
15+ *		reference count.  The caller should drop its reference
16+ *		without calling CERT_DestroyCert after calling this function.
17+ *
18+ *	key	Private key associated with cert.  This function takes
19+ *		ownership of the private key, so the caller should drop its
20+ *		reference without destroying the private key after this
21+ *		function returns.
22+ *
23+ *	certChain  DER-encoded certs, client cert and its signers.
24+ *		Note: ssl takes this reference, and does not copy the chain.
25+ *		The caller should drop its reference without destroying the
26+ *		chain.  SSL will free the chain when it is done with it.
27+ *
28+ * Return value: XXX
29+ *
30+ * XXX This code only works on the initial handshake on a connection, XXX
31+ *     It does not work on a subsequent handshake (redo).
32+ *
33+ * Caller holds 1stHandshakeLock.
34+ */
35+SECStatus
36+ssl3_RestartHandshakeAfterCertReq(sslSocket *         ss,
37+				CERTCertificate *    cert,
38+				SECKEYPrivateKey *   key,
39+				CERTCertificateList *certChain)
40+{
41+    SECStatus        rv          = SECSuccess;
42+
43+    /* XXX This code only works on the initial handshake on a connection,
44+    ** XXX It does not work on a subsequent handshake (redo).
45+    */
46+    if (ss->handshake != 0) {
47+	ss->handshake              = ssl_GatherRecord1stHandshake;
48+	ss->ssl3.clientCertificate = cert;
49+	ss->ssl3.clientPrivateKey  = key;
50+	ss->ssl3.clientCertChain   = certChain;
51+        if (!cert || !key || !certChain) {
52+            /* we are missing the key, cert, or cert chain */
53+            if (ss->ssl3.clientCertificate) {
54+                CERT_DestroyCertificate(ss->ssl3.clientCertificate);
55+                ss->ssl3.clientCertificate = NULL;
56+            }
57+            if (ss->ssl3.clientPrivateKey) {
58+                SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
59+                ss->ssl3.clientPrivateKey = NULL;
60+            }
61+            if (ss->ssl3.clientCertChain != NULL) {
62+                CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
63+                ss->ssl3.clientCertChain = NULL;
64+            }
65+            if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) {
66+                ss->ssl3.sendEmptyCert = PR_TRUE;
67+            } else {
68+                (void)SSL3_SendAlert(ss, alert_warning, no_certificate);
69+            }
70+	}
71+    } else {
72+	if (cert) {
73+	    CERT_DestroyCertificate(cert);
74+	}
75+	if (key) {
76+	    SECKEY_DestroyPrivateKey(key);
77+	}
78+	if (certChain) {
79+	    CERT_DestroyCertificateList(certChain);
80+	}
81+	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
82+	rv = SECFailure;
83+    }
84+    return rv;
85+}
86+
87 static SECStatus
88 ssl3_CheckFalseStart(sslSocket *ss)
89 {
90diff -pu a/nss/lib/ssl/ssl.h b/nss/lib/ssl/ssl.h
91--- a/nss/lib/ssl/ssl.h	2014-01-17 17:55:01.538096321 -0800
92+++ b/nss/lib/ssl/ssl.h	2014-01-17 17:55:19.158389328 -0800
93@@ -399,6 +399,11 @@ SSL_IMPORT SECStatus SSL_ForceHandshake(
94 SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
95                                                    PRIntervalTime timeout);
96
97+SSL_IMPORT SECStatus SSL_RestartHandshakeAfterCertReq(PRFileDesc *fd,
98+					    CERTCertificate *cert,
99+					    SECKEYPrivateKey *key,
100+					    CERTCertificateList *certChain);
101+
102 /*
103 ** Query security status of socket. *on is set to one if security is
104 ** enabled. *keySize will contain the stream key size used. *issuer will
105diff -pu a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h
106--- a/nss/lib/ssl/sslimpl.h	2014-01-17 17:55:01.538096321 -0800
107+++ b/nss/lib/ssl/sslimpl.h	2014-01-17 17:55:19.158389328 -0800
108@@ -1588,16 +1588,17 @@ extern  SECStatus ssl3_MasterKeyDeriveBy
109 /* These functions are called from secnav, even though they're "private". */
110
111 extern int ssl2_SendErrorMessage(struct sslSocketStr *ss, int error);
112-extern int SSL_RestartHandshakeAfterCertReq(struct sslSocketStr *ss,
113-					    CERTCertificate *cert,
114-					    SECKEYPrivateKey *key,
115-					    CERTCertificateList *certChain);
116 extern sslSocket *ssl_FindSocket(PRFileDesc *fd);
117 extern void ssl_FreeSocket(struct sslSocketStr *ssl);
118 extern SECStatus SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level,
119 				SSL3AlertDescription desc);
120 extern SECStatus ssl3_DecodeError(sslSocket *ss);
121
122+extern SECStatus ssl3_RestartHandshakeAfterCertReq(sslSocket *    ss,
123+					     CERTCertificate *    cert,
124+					     SECKEYPrivateKey *   key,
125+					     CERTCertificateList *certChain);
126+
127 extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error);
128
129 /*
130diff -pu a/nss/lib/ssl/sslsecur.c b/nss/lib/ssl/sslsecur.c
131--- a/nss/lib/ssl/sslsecur.c	2014-01-17 17:49:26.072517368 -0800
132+++ b/nss/lib/ssl/sslsecur.c	2014-01-17 17:55:19.158389328 -0800
133@@ -1518,17 +1518,70 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERT
134     return SECSuccess;
135 }
136
137-/* DO NOT USE. This function was exported in ssl.def with the wrong signature;
138- * this implementation exists to maintain link-time compatibility.
139+/*
140+ * attempt to restart the handshake after asynchronously handling
141+ * a request for the client's certificate.
142+ *
143+ * inputs:
144+ *	cert	Client cert chosen by application.
145+ *		Note: ssl takes this reference, and does not bump the
146+ *		reference count.  The caller should drop its reference
147+ *		without calling CERT_DestroyCertificate after calling this
148+ *		function.
149+ *
150+ *	key	Private key associated with cert.  This function takes
151+ *		ownership of the private key, so the caller should drop its
152+ *		reference without destroying the private key after this
153+ *		function returns.
154+ *
155+ *	certChain  Chain of signers for cert.
156+ *		Note: ssl takes this reference, and does not copy the chain.
157+ *		The caller should drop its reference without destroying the
158+ *		chain.  SSL will free the chain when it is done with it.
159+ *
160+ * Return value: XXX
161+ *
162+ * XXX This code only works on the initial handshake on a connection, XXX
163+ *     It does not work on a subsequent handshake (redo).
164  */
165-int
166-SSL_RestartHandshakeAfterCertReq(sslSocket *         ss,
167+SECStatus
168+SSL_RestartHandshakeAfterCertReq(PRFileDesc *        fd,
169 				CERTCertificate *    cert,
170 				SECKEYPrivateKey *   key,
171 				CERTCertificateList *certChain)
172 {
173-    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
174-    return -1;
175+    sslSocket *   ss = ssl_FindSocket(fd);
176+    SECStatus     ret;
177+
178+    if (!ss) {
179+	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RestartHandshakeAfterCertReq",
180+		 SSL_GETPID(), fd));
181+	if (cert) {
182+	    CERT_DestroyCertificate(cert);
183+	}
184+	if (key) {
185+	    SECKEY_DestroyPrivateKey(key);
186+	}
187+	if (certChain) {
188+	    CERT_DestroyCertificateList(certChain);
189+	}
190+	return SECFailure;
191+    }
192+
193+    ssl_Get1stHandshakeLock(ss);   /************************************/
194+
195+    if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
196+	ret = ssl3_RestartHandshakeAfterCertReq(ss, cert, key, certChain);
197+    } else {
198+	if (certChain != NULL) {
199+	    CERT_DestroyCertificateList(certChain);
200+	}
201+	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
202+	ret = SECFailure;
203+    }
204+
205+    ssl_Release1stHandshakeLock(ss);  /************************************/
206+    return ret;
207 }
208
209 /* DO NOT USE. This function was exported in ssl.def with the wrong signature;
210