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