OLD | NEW |
| (Empty) |
1 diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h | |
2 index 9e57220..aa4a3e5 100644 | |
3 --- a/lib/ssl/ssl.h | |
4 +++ b/lib/ssl/ssl.h | |
5 @@ -516,6 +516,11 @@ SSL_IMPORT SECStatus SSL_ForceHandshake(PRFileDesc *fd); | |
6 SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd, | |
7 PRIntervalTime timeout); | |
8 | |
9 +SSL_IMPORT SECStatus SSL_RestartHandshakeAfterCertReq(PRFileDesc *fd, | |
10 + CERTCertificate *cert, | |
11 + SECKEYPrivateKey *key, | |
12 + CERTCertificateList *cert
Chain); | |
13 + | |
14 /* | |
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/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c | |
18 index 784f59b..2a2e644 100644 | |
19 --- a/lib/ssl/ssl3con.c | |
20 +++ b/lib/ssl/ssl3con.c | |
21 @@ -7803,6 +7803,85 @@ ssl3_CompleteHandleCertificateRequest(sslSocket *ss, SECI
tem *algorithms, | |
22 return rv; | |
23 } | |
24 | |
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) | |
57 +{ | |
58 + SECStatus rv = SECSuccess; | |
59 + | |
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; | |
100 + } | |
101 + return rv; | |
102 +} | |
103 + | |
104 static SECStatus | |
105 ssl3_CheckFalseStart(sslSocket *ss) | |
106 { | |
107 diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h | |
108 index 5f0e6c9..dad75b2 100644 | |
109 --- a/lib/ssl/sslimpl.h | |
110 +++ b/lib/ssl/sslimpl.h | |
111 @@ -1702,16 +1702,16 @@ extern SECStatus ssl3_MasterSecretDeriveBypass(ssl3Ciphe
rSpec *pwSpec, | |
112 /* These functions are called from secnav, even though they're "private". */ | |
113 | |
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); | |
124 | |
125 +extern SECStatus ssl3_RestartHandshakeAfterCertReq(struct sslSocketStr *ss, | |
126 + CERTCertificate *cert, | |
127 + SECKEYPrivateKey *key, | |
128 + CERTCertificateList *certCha
in); | |
129 extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error)
; | |
130 | |
131 /* | |
132 diff --git a/lib/ssl/sslsecur.c b/lib/ssl/sslsecur.c | |
133 index 5773748..a087ffc 100644 | |
134 --- a/lib/ssl/sslsecur.c | |
135 +++ b/lib/ssl/sslsecur.c | |
136 @@ -1535,17 +1535,70 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *db
Handle) | |
137 return SECSuccess; | |
138 } | |
139 | |
140 -/* DO NOT USE. This function was exported in ssl.def with the wrong signature; | |
141 - * this implementation exists to maintain link-time compatibility. | |
142 - */ | |
143 -int | |
144 -SSL_RestartHandshakeAfterCertReq(sslSocket *ss, | |
145 +/* | |
146 + * attempt to restart the handshake after asynchronously handling | |
147 + * a request for the client's certificate. | |
148 + * | |
149 + * inputs: | |
150 + * cert Client cert chosen by application. | |
151 + * Note: ssl takes this reference, and does not bump the | |
152 + * reference count. The caller should drop its reference | |
153 + * without calling CERT_DestroyCertificate after calling this | |
154 + * function. | |
155 + * | |
156 + * key Private key associated with cert. This function takes | |
157 + * ownership of the private key, so the caller should drop its | |
158 + * reference without destroying the private key after this | |
159 + * function returns. | |
160 + * | |
161 + * certChain Chain of signers for cert. | |
162 + * Note: ssl takes this reference, and does not copy the chain. | |
163 + * The caller should drop its reference without destroying the | |
164 + * chain. SSL will free the chain when it is done with it. | |
165 + * | |
166 + * Return value: XXX | |
167 + * | |
168 + * XXX This code only works on the initial handshake on a connection, XXX | |
169 + * It does not work on a subsequent handshake (redo). | |
170 + */ | |
171 +SECStatus | |
172 +SSL_RestartHandshakeAfterCertReq(PRFileDesc *fd, | |
173 CERTCertificate *cert, | |
174 SECKEYPrivateKey *key, | |
175 CERTCertificateList *certChain) | |
176 { | |
177 - PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); | |
178 - return -1; | |
179 + sslSocket *ss = ssl_FindSocket(fd); | |
180 + SECStatus ret; | |
181 + | |
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); | |
187 + } | |
188 + if (key) { | |
189 + SECKEY_DestroyPrivateKey(key); | |
190 + } | |
191 + if (certChain) { | |
192 + CERT_DestroyCertificateList(certChain); | |
193 + } | |
194 + return SECFailure; | |
195 + } | |
196 + | |
197 + ssl_Get1stHandshakeLock(ss); /************************************/ | |
198 + | |
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); | |
204 + } | |
205 + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); | |
206 + ret = SECFailure; | |
207 + } | |
208 + | |
209 + ssl_Release1stHandshakeLock(ss); /************************************/ | |
210 + return ret; | |
211 } | |
212 | |
213 /* DO NOT USE. This function was exported in ssl.def with the wrong signature; | |
OLD | NEW |