|
1 /* |
|
2 * Various SSL functions. |
|
3 * |
|
4 * This Source Code Form is subject to the terms of the Mozilla Public |
|
5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
7 #include "cert.h" |
|
8 #include "secitem.h" |
|
9 #include "keyhi.h" |
|
10 #include "ssl.h" |
|
11 #include "sslimpl.h" |
|
12 #include "sslproto.h" |
|
13 #include "secoid.h" /* for SECOID_GetALgorithmTag */ |
|
14 #include "pk11func.h" /* for PK11_GenerateRandom */ |
|
15 #include "nss.h" /* for NSS_RegisterShutdown */ |
|
16 #include "prinit.h" /* for PR_CallOnceWithArg */ |
|
17 |
|
18 #define MAX_BLOCK_CYPHER_SIZE 32 |
|
19 |
|
20 #define TEST_FOR_FAILURE /* reminder */ |
|
21 #define SET_ERROR_CODE /* reminder */ |
|
22 |
|
23 /* Returns a SECStatus: SECSuccess or SECFailure, NOT SECWouldBlock. |
|
24 * |
|
25 * Currently, the list of functions called through ss->handshake is: |
|
26 * |
|
27 * In sslsocks.c: |
|
28 * SocksGatherRecord |
|
29 * SocksHandleReply |
|
30 * SocksStartGather |
|
31 * |
|
32 * In sslcon.c: |
|
33 * ssl_GatherRecord1stHandshake |
|
34 * ssl2_HandleClientSessionKeyMessage |
|
35 * ssl2_HandleMessage |
|
36 * ssl2_HandleVerifyMessage |
|
37 * ssl2_BeginClientHandshake |
|
38 * ssl2_BeginServerHandshake |
|
39 * ssl2_HandleClientHelloMessage |
|
40 * ssl2_HandleServerHelloMessage |
|
41 * |
|
42 * The ss->handshake function returns SECWouldBlock under these conditions: |
|
43 * 1. ssl_GatherRecord1stHandshake called ssl2_GatherData which read in |
|
44 * the beginning of an SSL v3 hello message and returned SECWouldBlock |
|
45 * to switch to SSL v3 handshake processing. |
|
46 * |
|
47 * 2. ssl2_HandleClientHelloMessage discovered version 3.0 in the incoming |
|
48 * v2 client hello msg, and called ssl3_HandleV2ClientHello which |
|
49 * returned SECWouldBlock. |
|
50 * |
|
51 * 3. SECWouldBlock was returned by one of the callback functions, via |
|
52 * one of these paths: |
|
53 * - ssl2_HandleMessage() -> ssl2_HandleRequestCertificate() -> |
|
54 * ss->getClientAuthData() |
|
55 * |
|
56 * - ssl2_HandleServerHelloMessage() -> ss->handleBadCert() |
|
57 * |
|
58 * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() -> |
|
59 * ssl3_HandleRecord() -> ssl3_HandleHandshake() -> |
|
60 * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificate() -> |
|
61 * ss->handleBadCert() |
|
62 * |
|
63 * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() -> |
|
64 * ssl3_HandleRecord() -> ssl3_HandleHandshake() -> |
|
65 * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificateRequest() -> |
|
66 * ss->getClientAuthData() |
|
67 * |
|
68 * Called from: SSL_ForceHandshake (below), |
|
69 * ssl_SecureRecv (below) and |
|
70 * ssl_SecureSend (below) |
|
71 * from: WaitForResponse in sslsocks.c |
|
72 * ssl_SocksRecv in sslsocks.c |
|
73 * ssl_SocksSend in sslsocks.c |
|
74 * |
|
75 * Caller must hold the (write) handshakeLock. |
|
76 */ |
|
77 int |
|
78 ssl_Do1stHandshake(sslSocket *ss) |
|
79 { |
|
80 int rv = SECSuccess; |
|
81 int loopCount = 0; |
|
82 |
|
83 do { |
|
84 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
85 PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss)); |
|
86 PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss)); |
|
87 PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss)); |
|
88 |
|
89 if (ss->handshake == 0) { |
|
90 /* Previous handshake finished. Switch to next one */ |
|
91 ss->handshake = ss->nextHandshake; |
|
92 ss->nextHandshake = 0; |
|
93 } |
|
94 if (ss->handshake == 0) { |
|
95 /* Previous handshake finished. Switch to security handshake */ |
|
96 ss->handshake = ss->securityHandshake; |
|
97 ss->securityHandshake = 0; |
|
98 } |
|
99 if (ss->handshake == 0) { |
|
100 /* for v3 this is done in ssl3_FinishHandshake */ |
|
101 if (!ss->firstHsDone && ss->version < SSL_LIBRARY_VERSION_3_0) { |
|
102 ssl_GetRecvBufLock(ss); |
|
103 ss->gs.recordLen = 0; |
|
104 ssl_FinishHandshake(ss); |
|
105 ssl_ReleaseRecvBufLock(ss); |
|
106 } |
|
107 break; |
|
108 } |
|
109 rv = (*ss->handshake)(ss); |
|
110 ++loopCount; |
|
111 /* This code must continue to loop on SECWouldBlock, |
|
112 * or any positive value. See XXX_1 comments. |
|
113 */ |
|
114 } while (rv != SECFailure); /* was (rv >= 0); XXX_1 */ |
|
115 |
|
116 PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss)); |
|
117 PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss)); |
|
118 PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss)); |
|
119 |
|
120 if (rv == SECWouldBlock) { |
|
121 PORT_SetError(PR_WOULD_BLOCK_ERROR); |
|
122 rv = SECFailure; |
|
123 } |
|
124 return rv; |
|
125 } |
|
126 |
|
127 void |
|
128 ssl_FinishHandshake(sslSocket *ss) |
|
129 { |
|
130 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
131 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
|
132 |
|
133 SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", SSL_GETPID(), ss->fd)); |
|
134 |
|
135 ss->firstHsDone = PR_TRUE; |
|
136 ss->enoughFirstHsDone = PR_TRUE; |
|
137 ss->gs.writeOffset = 0; |
|
138 ss->gs.readOffset = 0; |
|
139 |
|
140 if (ss->handshakeCallback) { |
|
141 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); |
|
142 } |
|
143 } |
|
144 |
|
145 /* |
|
146 * Handshake function that blocks. Used to force a |
|
147 * retry on a connection on the next read/write. |
|
148 */ |
|
149 static SECStatus |
|
150 ssl3_AlwaysBlock(sslSocket *ss) |
|
151 { |
|
152 PORT_SetError(PR_WOULD_BLOCK_ERROR); /* perhaps redundant. */ |
|
153 return SECWouldBlock; |
|
154 } |
|
155 |
|
156 /* |
|
157 * set the initial handshake state machine to block |
|
158 */ |
|
159 void |
|
160 ssl3_SetAlwaysBlock(sslSocket *ss) |
|
161 { |
|
162 if (!ss->firstHsDone) { |
|
163 ss->handshake = ssl3_AlwaysBlock; |
|
164 ss->nextHandshake = 0; |
|
165 } |
|
166 } |
|
167 |
|
168 static SECStatus |
|
169 ssl_SetTimeout(PRFileDesc *fd, PRIntervalTime timeout) |
|
170 { |
|
171 sslSocket *ss; |
|
172 |
|
173 ss = ssl_FindSocket(fd); |
|
174 if (!ss) { |
|
175 SSL_DBG(("%d: SSL[%d]: bad socket in SetTimeout", SSL_GETPID(), fd)); |
|
176 return SECFailure; |
|
177 } |
|
178 SSL_LOCK_READER(ss); |
|
179 ss->rTimeout = timeout; |
|
180 if (ss->opt.fdx) { |
|
181 SSL_LOCK_WRITER(ss); |
|
182 } |
|
183 ss->wTimeout = timeout; |
|
184 if (ss->opt.fdx) { |
|
185 SSL_UNLOCK_WRITER(ss); |
|
186 } |
|
187 SSL_UNLOCK_READER(ss); |
|
188 return SECSuccess; |
|
189 } |
|
190 |
|
191 /* Acquires and releases HandshakeLock. |
|
192 */ |
|
193 SECStatus |
|
194 SSL_ResetHandshake(PRFileDesc *s, PRBool asServer) |
|
195 { |
|
196 sslSocket *ss; |
|
197 SECStatus status; |
|
198 PRNetAddr addr; |
|
199 |
|
200 ss = ssl_FindSocket(s); |
|
201 if (!ss) { |
|
202 SSL_DBG(("%d: SSL[%d]: bad socket in ResetHandshake", SSL_GETPID(), s)); |
|
203 return SECFailure; |
|
204 } |
|
205 |
|
206 /* Don't waste my time */ |
|
207 if (!ss->opt.useSecurity) |
|
208 return SECSuccess; |
|
209 |
|
210 SSL_LOCK_READER(ss); |
|
211 SSL_LOCK_WRITER(ss); |
|
212 |
|
213 /* Reset handshake state */ |
|
214 ssl_Get1stHandshakeLock(ss); |
|
215 |
|
216 ss->firstHsDone = PR_FALSE; |
|
217 ss->enoughFirstHsDone = PR_FALSE; |
|
218 if ( asServer ) { |
|
219 ss->handshake = ssl2_BeginServerHandshake; |
|
220 ss->handshaking = sslHandshakingAsServer; |
|
221 } else { |
|
222 ss->handshake = ssl2_BeginClientHandshake; |
|
223 ss->handshaking = sslHandshakingAsClient; |
|
224 } |
|
225 ss->nextHandshake = 0; |
|
226 ss->securityHandshake = 0; |
|
227 |
|
228 ssl_GetRecvBufLock(ss); |
|
229 status = ssl_InitGather(&ss->gs); |
|
230 ssl_ReleaseRecvBufLock(ss); |
|
231 |
|
232 ssl_GetSSL3HandshakeLock(ss); |
|
233 ss->ssl3.hs.canFalseStart = PR_FALSE; |
|
234 ss->ssl3.hs.restartTarget = NULL; |
|
235 |
|
236 /* |
|
237 ** Blow away old security state and get a fresh setup. |
|
238 */ |
|
239 ssl_GetXmitBufLock(ss); |
|
240 ssl_ResetSecurityInfo(&ss->sec, PR_TRUE); |
|
241 status = ssl_CreateSecurityInfo(ss); |
|
242 ssl_ReleaseXmitBufLock(ss); |
|
243 |
|
244 ssl_ReleaseSSL3HandshakeLock(ss); |
|
245 ssl_Release1stHandshakeLock(ss); |
|
246 |
|
247 if (!ss->TCPconnected) |
|
248 ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr)); |
|
249 |
|
250 SSL_UNLOCK_WRITER(ss); |
|
251 SSL_UNLOCK_READER(ss); |
|
252 |
|
253 return status; |
|
254 } |
|
255 |
|
256 /* For SSLv2, does nothing but return an error. |
|
257 ** For SSLv3, flushes SID cache entry (if requested), |
|
258 ** and then starts new client hello or hello request. |
|
259 ** Acquires and releases HandshakeLock. |
|
260 */ |
|
261 SECStatus |
|
262 SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache) |
|
263 { |
|
264 sslSocket *ss; |
|
265 SECStatus rv; |
|
266 |
|
267 ss = ssl_FindSocket(fd); |
|
268 if (!ss) { |
|
269 SSL_DBG(("%d: SSL[%d]: bad socket in RedoHandshake", SSL_GETPID(), fd)); |
|
270 return SECFailure; |
|
271 } |
|
272 |
|
273 if (!ss->opt.useSecurity) |
|
274 return SECSuccess; |
|
275 |
|
276 ssl_Get1stHandshakeLock(ss); |
|
277 |
|
278 /* SSL v2 protocol does not support subsequent handshakes. */ |
|
279 if (ss->version < SSL_LIBRARY_VERSION_3_0) { |
|
280 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); |
|
281 rv = SECFailure; |
|
282 } else { |
|
283 ssl_GetSSL3HandshakeLock(ss); |
|
284 rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */ |
|
285 ssl_ReleaseSSL3HandshakeLock(ss); |
|
286 } |
|
287 |
|
288 ssl_Release1stHandshakeLock(ss); |
|
289 |
|
290 return rv; |
|
291 } |
|
292 |
|
293 /* |
|
294 ** Same as above, but with an I/O timeout. |
|
295 */ |
|
296 SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd, |
|
297 PRBool flushCache, |
|
298 PRIntervalTime timeout) |
|
299 { |
|
300 if (SECSuccess != ssl_SetTimeout(fd, timeout)) { |
|
301 return SECFailure; |
|
302 } |
|
303 return SSL_ReHandshake(fd, flushCache); |
|
304 } |
|
305 |
|
306 SECStatus |
|
307 SSL_RedoHandshake(PRFileDesc *fd) |
|
308 { |
|
309 return SSL_ReHandshake(fd, PR_TRUE); |
|
310 } |
|
311 |
|
312 /* Register an application callback to be called when SSL handshake completes. |
|
313 ** Acquires and releases HandshakeLock. |
|
314 */ |
|
315 SECStatus |
|
316 SSL_HandshakeCallback(PRFileDesc *fd, SSLHandshakeCallback cb, |
|
317 void *client_data) |
|
318 { |
|
319 sslSocket *ss; |
|
320 |
|
321 ss = ssl_FindSocket(fd); |
|
322 if (!ss) { |
|
323 SSL_DBG(("%d: SSL[%d]: bad socket in HandshakeCallback", |
|
324 SSL_GETPID(), fd)); |
|
325 return SECFailure; |
|
326 } |
|
327 |
|
328 if (!ss->opt.useSecurity) { |
|
329 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
|
330 return SECFailure; |
|
331 } |
|
332 |
|
333 ssl_Get1stHandshakeLock(ss); |
|
334 ssl_GetSSL3HandshakeLock(ss); |
|
335 |
|
336 ss->handshakeCallback = cb; |
|
337 ss->handshakeCallbackData = client_data; |
|
338 |
|
339 ssl_ReleaseSSL3HandshakeLock(ss); |
|
340 ssl_Release1stHandshakeLock(ss); |
|
341 |
|
342 return SECSuccess; |
|
343 } |
|
344 |
|
345 /* Register an application callback to be called when false start may happen. |
|
346 ** Acquires and releases HandshakeLock. |
|
347 */ |
|
348 SECStatus |
|
349 SSL_SetCanFalseStartCallback(PRFileDesc *fd, SSLCanFalseStartCallback cb, |
|
350 void *arg) |
|
351 { |
|
352 sslSocket *ss; |
|
353 |
|
354 ss = ssl_FindSocket(fd); |
|
355 if (!ss) { |
|
356 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCanFalseStartCallback", |
|
357 SSL_GETPID(), fd)); |
|
358 return SECFailure; |
|
359 } |
|
360 |
|
361 if (!ss->opt.useSecurity) { |
|
362 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
|
363 return SECFailure; |
|
364 } |
|
365 |
|
366 ssl_Get1stHandshakeLock(ss); |
|
367 ssl_GetSSL3HandshakeLock(ss); |
|
368 |
|
369 ss->canFalseStartCallback = cb; |
|
370 ss->canFalseStartCallbackData = arg; |
|
371 |
|
372 ssl_ReleaseSSL3HandshakeLock(ss); |
|
373 ssl_Release1stHandshakeLock(ss); |
|
374 |
|
375 return SECSuccess; |
|
376 } |
|
377 |
|
378 SECStatus |
|
379 SSL_RecommendedCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart) |
|
380 { |
|
381 sslSocket *ss; |
|
382 |
|
383 *canFalseStart = PR_FALSE; |
|
384 ss = ssl_FindSocket(fd); |
|
385 if (!ss) { |
|
386 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RecommendedCanFalseStart", |
|
387 SSL_GETPID(), fd)); |
|
388 return SECFailure; |
|
389 } |
|
390 |
|
391 if (!ss->ssl3.initialized) { |
|
392 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
|
393 return SECFailure; |
|
394 } |
|
395 |
|
396 if (ss->version < SSL_LIBRARY_VERSION_3_0) { |
|
397 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); |
|
398 return SECFailure; |
|
399 } |
|
400 |
|
401 /* Require a forward-secret key exchange. */ |
|
402 *canFalseStart = ss->ssl3.hs.kea_def->kea == kea_dhe_dss || |
|
403 ss->ssl3.hs.kea_def->kea == kea_dhe_rsa || |
|
404 ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa || |
|
405 ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa; |
|
406 |
|
407 return SECSuccess; |
|
408 } |
|
409 |
|
410 /* Try to make progress on an SSL handshake by attempting to read the |
|
411 ** next handshake from the peer, and sending any responses. |
|
412 ** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK if it cannot |
|
413 ** read the next handshake from the underlying socket. |
|
414 ** For SSLv2, returns when handshake is complete or fatal error occurs. |
|
415 ** For SSLv3, returns when handshake is complete, or application data has |
|
416 ** arrived that must be taken by application before handshake can continue, |
|
417 ** or a fatal error occurs. |
|
418 ** Application should use handshake completion callback to tell which. |
|
419 */ |
|
420 SECStatus |
|
421 SSL_ForceHandshake(PRFileDesc *fd) |
|
422 { |
|
423 sslSocket *ss; |
|
424 SECStatus rv = SECFailure; |
|
425 |
|
426 ss = ssl_FindSocket(fd); |
|
427 if (!ss) { |
|
428 SSL_DBG(("%d: SSL[%d]: bad socket in ForceHandshake", |
|
429 SSL_GETPID(), fd)); |
|
430 return rv; |
|
431 } |
|
432 |
|
433 /* Don't waste my time */ |
|
434 if (!ss->opt.useSecurity) |
|
435 return SECSuccess; |
|
436 |
|
437 if (!ssl_SocketIsBlocking(ss)) { |
|
438 ssl_GetXmitBufLock(ss); |
|
439 if (ss->pendingBuf.len != 0) { |
|
440 int sent = ssl_SendSavedWriteData(ss); |
|
441 if ((sent < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) { |
|
442 ssl_ReleaseXmitBufLock(ss); |
|
443 return SECFailure; |
|
444 } |
|
445 } |
|
446 ssl_ReleaseXmitBufLock(ss); |
|
447 } |
|
448 |
|
449 ssl_Get1stHandshakeLock(ss); |
|
450 |
|
451 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { |
|
452 int gatherResult; |
|
453 |
|
454 ssl_GetRecvBufLock(ss); |
|
455 gatherResult = ssl3_GatherCompleteHandshake(ss, 0); |
|
456 ssl_ReleaseRecvBufLock(ss); |
|
457 if (gatherResult > 0) { |
|
458 rv = SECSuccess; |
|
459 } else if (gatherResult == 0) { |
|
460 PORT_SetError(PR_END_OF_FILE_ERROR); |
|
461 } else if (gatherResult == SECWouldBlock) { |
|
462 PORT_SetError(PR_WOULD_BLOCK_ERROR); |
|
463 } |
|
464 } else if (!ss->firstHsDone) { |
|
465 rv = ssl_Do1stHandshake(ss); |
|
466 } else { |
|
467 /* tried to force handshake on an SSL 2 socket that has |
|
468 ** already completed the handshake. */ |
|
469 rv = SECSuccess; /* just pretend we did it. */ |
|
470 } |
|
471 |
|
472 ssl_Release1stHandshakeLock(ss); |
|
473 |
|
474 return rv; |
|
475 } |
|
476 |
|
477 /* |
|
478 ** Same as above, but with an I/O timeout. |
|
479 */ |
|
480 SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd, |
|
481 PRIntervalTime timeout) |
|
482 { |
|
483 if (SECSuccess != ssl_SetTimeout(fd, timeout)) { |
|
484 return SECFailure; |
|
485 } |
|
486 return SSL_ForceHandshake(fd); |
|
487 } |
|
488 |
|
489 |
|
490 /************************************************************************/ |
|
491 |
|
492 /* |
|
493 ** Grow a buffer to hold newLen bytes of data. |
|
494 ** Called for both recv buffers and xmit buffers. |
|
495 ** Caller must hold xmitBufLock or recvBufLock, as appropriate. |
|
496 */ |
|
497 SECStatus |
|
498 sslBuffer_Grow(sslBuffer *b, unsigned int newLen) |
|
499 { |
|
500 newLen = PR_MAX(newLen, MAX_FRAGMENT_LENGTH + 2048); |
|
501 if (newLen > b->space) { |
|
502 unsigned char *newBuf; |
|
503 if (b->buf) { |
|
504 newBuf = (unsigned char *) PORT_Realloc(b->buf, newLen); |
|
505 } else { |
|
506 newBuf = (unsigned char *) PORT_Alloc(newLen); |
|
507 } |
|
508 if (!newBuf) { |
|
509 return SECFailure; |
|
510 } |
|
511 SSL_TRC(10, ("%d: SSL: grow buffer from %d to %d", |
|
512 SSL_GETPID(), b->space, newLen)); |
|
513 b->buf = newBuf; |
|
514 b->space = newLen; |
|
515 } |
|
516 return SECSuccess; |
|
517 } |
|
518 |
|
519 SECStatus |
|
520 sslBuffer_Append(sslBuffer *b, const void * data, unsigned int len) |
|
521 { |
|
522 unsigned int newLen = b->len + len; |
|
523 SECStatus rv; |
|
524 |
|
525 rv = sslBuffer_Grow(b, newLen); |
|
526 if (rv != SECSuccess) |
|
527 return rv; |
|
528 PORT_Memcpy(b->buf + b->len, data, len); |
|
529 b->len += len; |
|
530 return SECSuccess; |
|
531 } |
|
532 |
|
533 /* |
|
534 ** Save away write data that is trying to be written before the security |
|
535 ** handshake has been completed. When the handshake is completed, we will |
|
536 ** flush this data out. |
|
537 ** Caller must hold xmitBufLock |
|
538 */ |
|
539 SECStatus |
|
540 ssl_SaveWriteData(sslSocket *ss, const void *data, unsigned int len) |
|
541 { |
|
542 SECStatus rv; |
|
543 |
|
544 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); |
|
545 rv = sslBuffer_Append(&ss->pendingBuf, data, len); |
|
546 SSL_TRC(5, ("%d: SSL[%d]: saving %u bytes of data (%u total saved so far)", |
|
547 SSL_GETPID(), ss->fd, len, ss->pendingBuf.len)); |
|
548 return rv; |
|
549 } |
|
550 |
|
551 /* |
|
552 ** Send saved write data. This will flush out data sent prior to a |
|
553 ** complete security handshake. Hopefully there won't be too much of it. |
|
554 ** Returns count of the bytes sent, NOT a SECStatus. |
|
555 ** Caller must hold xmitBufLock |
|
556 */ |
|
557 int |
|
558 ssl_SendSavedWriteData(sslSocket *ss) |
|
559 { |
|
560 int rv = 0; |
|
561 |
|
562 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); |
|
563 if (ss->pendingBuf.len != 0) { |
|
564 SSL_TRC(5, ("%d: SSL[%d]: sending %d bytes of saved data", |
|
565 SSL_GETPID(), ss->fd, ss->pendingBuf.len)); |
|
566 rv = ssl_DefSend(ss, ss->pendingBuf.buf, ss->pendingBuf.len, 0); |
|
567 if (rv < 0) { |
|
568 return rv; |
|
569 } |
|
570 ss->pendingBuf.len -= rv; |
|
571 if (ss->pendingBuf.len > 0 && rv > 0) { |
|
572 /* UGH !! This shifts the whole buffer down by copying it */ |
|
573 PORT_Memmove(ss->pendingBuf.buf, ss->pendingBuf.buf + rv, |
|
574 ss->pendingBuf.len); |
|
575 } |
|
576 } |
|
577 return rv; |
|
578 } |
|
579 |
|
580 /************************************************************************/ |
|
581 |
|
582 /* |
|
583 ** Receive some application data on a socket. Reads SSL records from the input |
|
584 ** stream, decrypts them and then copies them to the output buffer. |
|
585 ** Called from ssl_SecureRecv() below. |
|
586 ** |
|
587 ** Caller does NOT hold 1stHandshakeLock because that handshake is over. |
|
588 ** Caller doesn't call this until initial handshake is complete. |
|
589 ** For SSLv2, there is no subsequent handshake. |
|
590 ** For SSLv3, the call to ssl3_GatherAppDataRecord may encounter handshake |
|
591 ** messages from a subsequent handshake. |
|
592 ** |
|
593 ** This code is similar to, and easily confused with, |
|
594 ** ssl_GatherRecord1stHandshake() in sslcon.c |
|
595 */ |
|
596 static int |
|
597 DoRecv(sslSocket *ss, unsigned char *out, int len, int flags) |
|
598 { |
|
599 int rv; |
|
600 int amount; |
|
601 int available; |
|
602 |
|
603 /* ssl3_GatherAppDataRecord may call ssl_FinishHandshake, which needs the |
|
604 * 1stHandshakeLock. */ |
|
605 ssl_Get1stHandshakeLock(ss); |
|
606 ssl_GetRecvBufLock(ss); |
|
607 |
|
608 available = ss->gs.writeOffset - ss->gs.readOffset; |
|
609 if (available == 0) { |
|
610 /* Get some more data */ |
|
611 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { |
|
612 /* Wait for application data to arrive. */ |
|
613 rv = ssl3_GatherAppDataRecord(ss, 0); |
|
614 } else { |
|
615 /* See if we have a complete record */ |
|
616 rv = ssl2_GatherRecord(ss, 0); |
|
617 } |
|
618 if (rv <= 0) { |
|
619 if (rv == 0) { |
|
620 /* EOF */ |
|
621 SSL_TRC(10, ("%d: SSL[%d]: ssl_recv EOF", |
|
622 SSL_GETPID(), ss->fd)); |
|
623 goto done; |
|
624 } |
|
625 if ((rv != SECWouldBlock) && |
|
626 (PR_GetError() != PR_WOULD_BLOCK_ERROR)) { |
|
627 /* Some random error */ |
|
628 goto done; |
|
629 } |
|
630 |
|
631 /* |
|
632 ** Gather record is blocked waiting for more record data to |
|
633 ** arrive. Try to process what we have already received |
|
634 */ |
|
635 } else { |
|
636 /* Gather record has finished getting a complete record */ |
|
637 } |
|
638 |
|
639 /* See if any clear data is now available */ |
|
640 available = ss->gs.writeOffset - ss->gs.readOffset; |
|
641 if (available == 0) { |
|
642 /* |
|
643 ** No partial data is available. Force error code to |
|
644 ** EWOULDBLOCK so that caller will try again later. Note |
|
645 ** that the error code is probably EWOULDBLOCK already, |
|
646 ** but if it isn't (for example, if we received a zero |
|
647 ** length record) then this will force it to be correct. |
|
648 */ |
|
649 PORT_SetError(PR_WOULD_BLOCK_ERROR); |
|
650 rv = SECFailure; |
|
651 goto done; |
|
652 } |
|
653 SSL_TRC(30, ("%d: SSL[%d]: partial data ready, available=%d", |
|
654 SSL_GETPID(), ss->fd, available)); |
|
655 } |
|
656 |
|
657 /* Dole out clear data to reader */ |
|
658 amount = PR_MIN(len, available); |
|
659 PORT_Memcpy(out, ss->gs.buf.buf + ss->gs.readOffset, amount); |
|
660 if (!(flags & PR_MSG_PEEK)) { |
|
661 ss->gs.readOffset += amount; |
|
662 } |
|
663 PORT_Assert(ss->gs.readOffset <= ss->gs.writeOffset); |
|
664 rv = amount; |
|
665 |
|
666 SSL_TRC(30, ("%d: SSL[%d]: amount=%d available=%d", |
|
667 SSL_GETPID(), ss->fd, amount, available)); |
|
668 PRINT_BUF(4, (ss, "DoRecv receiving plaintext:", out, amount)); |
|
669 |
|
670 done: |
|
671 ssl_ReleaseRecvBufLock(ss); |
|
672 ssl_Release1stHandshakeLock(ss); |
|
673 return rv; |
|
674 } |
|
675 |
|
676 /************************************************************************/ |
|
677 |
|
678 /* |
|
679 ** Return SSLKEAType derived from cert's Public Key algorithm info. |
|
680 */ |
|
681 SSLKEAType |
|
682 NSS_FindCertKEAType(CERTCertificate * cert) |
|
683 { |
|
684 SSLKEAType keaType = kt_null; |
|
685 int tag; |
|
686 |
|
687 if (!cert) goto loser; |
|
688 |
|
689 tag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm)); |
|
690 |
|
691 switch (tag) { |
|
692 case SEC_OID_X500_RSA_ENCRYPTION: |
|
693 case SEC_OID_PKCS1_RSA_ENCRYPTION: |
|
694 keaType = kt_rsa; |
|
695 break; |
|
696 case SEC_OID_X942_DIFFIE_HELMAN_KEY: |
|
697 keaType = kt_dh; |
|
698 break; |
|
699 #ifndef NSS_DISABLE_ECC |
|
700 case SEC_OID_ANSIX962_EC_PUBLIC_KEY: |
|
701 keaType = kt_ecdh; |
|
702 break; |
|
703 #endif /* NSS_DISABLE_ECC */ |
|
704 default: |
|
705 keaType = kt_null; |
|
706 } |
|
707 |
|
708 loser: |
|
709 |
|
710 return keaType; |
|
711 } |
|
712 |
|
713 static const PRCallOnceType pristineCallOnce; |
|
714 static PRCallOnceType setupServerCAListOnce; |
|
715 |
|
716 static SECStatus serverCAListShutdown(void* appData, void* nssData) |
|
717 { |
|
718 PORT_Assert(ssl3_server_ca_list); |
|
719 if (ssl3_server_ca_list) { |
|
720 CERT_FreeDistNames(ssl3_server_ca_list); |
|
721 ssl3_server_ca_list = NULL; |
|
722 } |
|
723 setupServerCAListOnce = pristineCallOnce; |
|
724 return SECSuccess; |
|
725 } |
|
726 |
|
727 static PRStatus serverCAListSetup(void *arg) |
|
728 { |
|
729 CERTCertDBHandle *dbHandle = (CERTCertDBHandle *)arg; |
|
730 SECStatus rv = NSS_RegisterShutdown(serverCAListShutdown, NULL); |
|
731 PORT_Assert(SECSuccess == rv); |
|
732 if (SECSuccess == rv) { |
|
733 ssl3_server_ca_list = CERT_GetSSLCACerts(dbHandle); |
|
734 return PR_SUCCESS; |
|
735 } |
|
736 return PR_FAILURE; |
|
737 } |
|
738 |
|
739 SECStatus |
|
740 ssl_ConfigSecureServer(sslSocket *ss, CERTCertificate *cert, |
|
741 const CERTCertificateList *certChain, |
|
742 ssl3KeyPair *keyPair, SSLKEAType kea) |
|
743 { |
|
744 CERTCertificateList *localCertChain = NULL; |
|
745 sslServerCerts *sc = ss->serverCerts + kea; |
|
746 |
|
747 /* load the server certificate */ |
|
748 if (sc->serverCert != NULL) { |
|
749 CERT_DestroyCertificate(sc->serverCert); |
|
750 sc->serverCert = NULL; |
|
751 sc->serverKeyBits = 0; |
|
752 } |
|
753 /* load the server cert chain */ |
|
754 if (sc->serverCertChain != NULL) { |
|
755 CERT_DestroyCertificateList(sc->serverCertChain); |
|
756 sc->serverCertChain = NULL; |
|
757 } |
|
758 if (cert) { |
|
759 sc->serverCert = CERT_DupCertificate(cert); |
|
760 /* get the size of the cert's public key, and remember it */ |
|
761 sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->pubKey); |
|
762 if (!certChain) { |
|
763 localCertChain = |
|
764 CERT_CertChainFromCert(sc->serverCert, certUsageSSLServer, |
|
765 PR_TRUE); |
|
766 if (!localCertChain) |
|
767 goto loser; |
|
768 } |
|
769 sc->serverCertChain = (certChain) ? CERT_DupCertList(certChain) : |
|
770 localCertChain; |
|
771 if (!sc->serverCertChain) { |
|
772 goto loser; |
|
773 } |
|
774 localCertChain = NULL; /* consumed */ |
|
775 } |
|
776 |
|
777 /* get keyPair */ |
|
778 if (sc->serverKeyPair != NULL) { |
|
779 ssl3_FreeKeyPair(sc->serverKeyPair); |
|
780 sc->serverKeyPair = NULL; |
|
781 } |
|
782 if (keyPair) { |
|
783 SECKEY_CacheStaticFlags(keyPair->privKey); |
|
784 sc->serverKeyPair = ssl3_GetKeyPairRef(keyPair); |
|
785 } |
|
786 if (kea == kt_rsa && cert && sc->serverKeyBits > 512 && |
|
787 !ss->opt.noStepDown && !ss->stepDownKeyPair) { |
|
788 if (ssl3_CreateRSAStepDownKeys(ss) != SECSuccess) { |
|
789 goto loser; |
|
790 } |
|
791 } |
|
792 return SECSuccess; |
|
793 |
|
794 loser: |
|
795 if (localCertChain) { |
|
796 CERT_DestroyCertificateList(localCertChain); |
|
797 } |
|
798 if (sc->serverCert != NULL) { |
|
799 CERT_DestroyCertificate(sc->serverCert); |
|
800 sc->serverCert = NULL; |
|
801 } |
|
802 if (sc->serverCertChain != NULL) { |
|
803 CERT_DestroyCertificateList(sc->serverCertChain); |
|
804 sc->serverCertChain = NULL; |
|
805 } |
|
806 if (sc->serverKeyPair != NULL) { |
|
807 ssl3_FreeKeyPair(sc->serverKeyPair); |
|
808 sc->serverKeyPair = NULL; |
|
809 } |
|
810 return SECFailure; |
|
811 } |
|
812 |
|
813 /* XXX need to protect the data that gets changed here.!! */ |
|
814 |
|
815 SECStatus |
|
816 SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, |
|
817 SECKEYPrivateKey *key, SSL3KEAType kea) |
|
818 { |
|
819 |
|
820 return SSL_ConfigSecureServerWithCertChain(fd, cert, NULL, key, kea); |
|
821 } |
|
822 |
|
823 SECStatus |
|
824 SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert, |
|
825 const CERTCertificateList *certChainOpt, |
|
826 SECKEYPrivateKey *key, SSL3KEAType kea) |
|
827 { |
|
828 sslSocket *ss; |
|
829 SECKEYPublicKey *pubKey = NULL; |
|
830 ssl3KeyPair *keyPair = NULL; |
|
831 SECStatus rv = SECFailure; |
|
832 |
|
833 ss = ssl_FindSocket(fd); |
|
834 if (!ss) { |
|
835 return SECFailure; |
|
836 } |
|
837 |
|
838 /* Both key and cert must have a value or be NULL */ |
|
839 /* Passing a value of NULL will turn off key exchange algorithms that were |
|
840 * previously turned on */ |
|
841 if (!cert != !key) { |
|
842 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
|
843 return SECFailure; |
|
844 } |
|
845 |
|
846 /* make sure the key exchange is recognized */ |
|
847 if ((kea >= kt_kea_size) || (kea < kt_null)) { |
|
848 PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); |
|
849 return SECFailure; |
|
850 } |
|
851 |
|
852 if (kea != NSS_FindCertKEAType(cert)) { |
|
853 PORT_SetError(SSL_ERROR_CERT_KEA_MISMATCH); |
|
854 return SECFailure; |
|
855 } |
|
856 |
|
857 if (cert) { |
|
858 /* get the size of the cert's public key, and remember it */ |
|
859 pubKey = CERT_ExtractPublicKey(cert); |
|
860 if (!pubKey) |
|
861 return SECFailure; |
|
862 } |
|
863 |
|
864 if (key) { |
|
865 SECKEYPrivateKey * keyCopy = NULL; |
|
866 CK_MECHANISM_TYPE keyMech = CKM_INVALID_MECHANISM; |
|
867 |
|
868 if (key->pkcs11Slot) { |
|
869 PK11SlotInfo * bestSlot; |
|
870 bestSlot = PK11_ReferenceSlot(key->pkcs11Slot); |
|
871 if (bestSlot) { |
|
872 keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key); |
|
873 PK11_FreeSlot(bestSlot); |
|
874 } |
|
875 } |
|
876 if (keyCopy == NULL) |
|
877 keyMech = PK11_MapSignKeyType(key->keyType); |
|
878 if (keyMech != CKM_INVALID_MECHANISM) { |
|
879 PK11SlotInfo * bestSlot; |
|
880 /* XXX Maybe should be bestSlotMultiple? */ |
|
881 bestSlot = PK11_GetBestSlot(keyMech, NULL /* wincx */); |
|
882 if (bestSlot) { |
|
883 keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key); |
|
884 PK11_FreeSlot(bestSlot); |
|
885 } |
|
886 } |
|
887 if (keyCopy == NULL) |
|
888 keyCopy = SECKEY_CopyPrivateKey(key); |
|
889 if (keyCopy == NULL) |
|
890 goto loser; |
|
891 keyPair = ssl3_NewKeyPair(keyCopy, pubKey); |
|
892 if (keyPair == NULL) { |
|
893 SECKEY_DestroyPrivateKey(keyCopy); |
|
894 goto loser; |
|
895 } |
|
896 pubKey = NULL; /* adopted by serverKeyPair */ |
|
897 } |
|
898 if (ssl_ConfigSecureServer(ss, cert, certChainOpt, |
|
899 keyPair, kea) == SECFailure) { |
|
900 goto loser; |
|
901 } |
|
902 |
|
903 /* Only do this once because it's global. */ |
|
904 if (PR_SUCCESS == PR_CallOnceWithArg(&setupServerCAListOnce, |
|
905 &serverCAListSetup, |
|
906 (void *)(ss->dbHandle))) { |
|
907 rv = SECSuccess; |
|
908 } |
|
909 |
|
910 loser: |
|
911 if (keyPair) { |
|
912 ssl3_FreeKeyPair(keyPair); |
|
913 } |
|
914 if (pubKey) { |
|
915 SECKEY_DestroyPublicKey(pubKey); |
|
916 pubKey = NULL; |
|
917 } |
|
918 return rv; |
|
919 } |
|
920 |
|
921 /************************************************************************/ |
|
922 |
|
923 SECStatus |
|
924 ssl_CreateSecurityInfo(sslSocket *ss) |
|
925 { |
|
926 SECStatus status; |
|
927 |
|
928 /* initialize sslv2 socket to send data in the clear. */ |
|
929 ssl2_UseClearSendFunc(ss); |
|
930 |
|
931 ss->sec.blockSize = 1; |
|
932 ss->sec.blockShift = 0; |
|
933 |
|
934 ssl_GetXmitBufLock(ss); |
|
935 status = sslBuffer_Grow(&ss->sec.writeBuf, 4096); |
|
936 ssl_ReleaseXmitBufLock(ss); |
|
937 |
|
938 return status; |
|
939 } |
|
940 |
|
941 SECStatus |
|
942 ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os) |
|
943 { |
|
944 ss->sec.send = os->sec.send; |
|
945 ss->sec.isServer = os->sec.isServer; |
|
946 ss->sec.keyBits = os->sec.keyBits; |
|
947 ss->sec.secretKeyBits = os->sec.secretKeyBits; |
|
948 |
|
949 ss->sec.peerCert = CERT_DupCertificate(os->sec.peerCert); |
|
950 if (os->sec.peerCert && !ss->sec.peerCert) |
|
951 goto loser; |
|
952 |
|
953 ss->sec.cache = os->sec.cache; |
|
954 ss->sec.uncache = os->sec.uncache; |
|
955 |
|
956 /* we don't dup the connection info. */ |
|
957 |
|
958 ss->sec.sendSequence = os->sec.sendSequence; |
|
959 ss->sec.rcvSequence = os->sec.rcvSequence; |
|
960 |
|
961 if (os->sec.hash && os->sec.hashcx) { |
|
962 ss->sec.hash = os->sec.hash; |
|
963 ss->sec.hashcx = os->sec.hash->clone(os->sec.hashcx); |
|
964 if (os->sec.hashcx && !ss->sec.hashcx) |
|
965 goto loser; |
|
966 } else { |
|
967 ss->sec.hash = NULL; |
|
968 ss->sec.hashcx = NULL; |
|
969 } |
|
970 |
|
971 SECITEM_CopyItem(0, &ss->sec.sendSecret, &os->sec.sendSecret); |
|
972 if (os->sec.sendSecret.data && !ss->sec.sendSecret.data) |
|
973 goto loser; |
|
974 SECITEM_CopyItem(0, &ss->sec.rcvSecret, &os->sec.rcvSecret); |
|
975 if (os->sec.rcvSecret.data && !ss->sec.rcvSecret.data) |
|
976 goto loser; |
|
977 |
|
978 /* XXX following code is wrong if either cx != 0 */ |
|
979 PORT_Assert(os->sec.readcx == 0); |
|
980 PORT_Assert(os->sec.writecx == 0); |
|
981 ss->sec.readcx = os->sec.readcx; |
|
982 ss->sec.writecx = os->sec.writecx; |
|
983 ss->sec.destroy = 0; |
|
984 |
|
985 ss->sec.enc = os->sec.enc; |
|
986 ss->sec.dec = os->sec.dec; |
|
987 |
|
988 ss->sec.blockShift = os->sec.blockShift; |
|
989 ss->sec.blockSize = os->sec.blockSize; |
|
990 |
|
991 return SECSuccess; |
|
992 |
|
993 loser: |
|
994 return SECFailure; |
|
995 } |
|
996 |
|
997 /* Reset sec back to its initial state. |
|
998 ** Caller holds any relevant locks. |
|
999 */ |
|
1000 void |
|
1001 ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset) |
|
1002 { |
|
1003 /* Destroy MAC */ |
|
1004 if (sec->hash && sec->hashcx) { |
|
1005 (*sec->hash->destroy)(sec->hashcx, PR_TRUE); |
|
1006 sec->hashcx = NULL; |
|
1007 sec->hash = NULL; |
|
1008 } |
|
1009 SECITEM_ZfreeItem(&sec->sendSecret, PR_FALSE); |
|
1010 SECITEM_ZfreeItem(&sec->rcvSecret, PR_FALSE); |
|
1011 |
|
1012 /* Destroy ciphers */ |
|
1013 if (sec->destroy) { |
|
1014 (*sec->destroy)(sec->readcx, PR_TRUE); |
|
1015 (*sec->destroy)(sec->writecx, PR_TRUE); |
|
1016 sec->readcx = NULL; |
|
1017 sec->writecx = NULL; |
|
1018 } else { |
|
1019 PORT_Assert(sec->readcx == 0); |
|
1020 PORT_Assert(sec->writecx == 0); |
|
1021 } |
|
1022 sec->readcx = 0; |
|
1023 sec->writecx = 0; |
|
1024 |
|
1025 if (sec->localCert) { |
|
1026 CERT_DestroyCertificate(sec->localCert); |
|
1027 sec->localCert = NULL; |
|
1028 } |
|
1029 if (sec->peerCert) { |
|
1030 CERT_DestroyCertificate(sec->peerCert); |
|
1031 sec->peerCert = NULL; |
|
1032 } |
|
1033 if (sec->peerKey) { |
|
1034 SECKEY_DestroyPublicKey(sec->peerKey); |
|
1035 sec->peerKey = NULL; |
|
1036 } |
|
1037 |
|
1038 /* cleanup the ci */ |
|
1039 if (sec->ci.sid != NULL) { |
|
1040 ssl_FreeSID(sec->ci.sid); |
|
1041 } |
|
1042 PORT_ZFree(sec->ci.sendBuf.buf, sec->ci.sendBuf.space); |
|
1043 if (doMemset) { |
|
1044 memset(&sec->ci, 0, sizeof sec->ci); |
|
1045 } |
|
1046 |
|
1047 } |
|
1048 |
|
1049 /* |
|
1050 ** Called from SSL_ResetHandshake (above), and |
|
1051 ** from ssl_FreeSocket in sslsock.c |
|
1052 ** Caller should hold relevant locks (e.g. XmitBufLock) |
|
1053 */ |
|
1054 void |
|
1055 ssl_DestroySecurityInfo(sslSecurityInfo *sec) |
|
1056 { |
|
1057 ssl_ResetSecurityInfo(sec, PR_FALSE); |
|
1058 |
|
1059 PORT_ZFree(sec->writeBuf.buf, sec->writeBuf.space); |
|
1060 sec->writeBuf.buf = 0; |
|
1061 |
|
1062 memset(sec, 0, sizeof *sec); |
|
1063 } |
|
1064 |
|
1065 /************************************************************************/ |
|
1066 |
|
1067 int |
|
1068 ssl_SecureConnect(sslSocket *ss, const PRNetAddr *sa) |
|
1069 { |
|
1070 PRFileDesc *osfd = ss->fd->lower; |
|
1071 int rv; |
|
1072 |
|
1073 if ( ss->opt.handshakeAsServer ) { |
|
1074 ss->securityHandshake = ssl2_BeginServerHandshake; |
|
1075 ss->handshaking = sslHandshakingAsServer; |
|
1076 } else { |
|
1077 ss->securityHandshake = ssl2_BeginClientHandshake; |
|
1078 ss->handshaking = sslHandshakingAsClient; |
|
1079 } |
|
1080 |
|
1081 /* connect to server */ |
|
1082 rv = osfd->methods->connect(osfd, sa, ss->cTimeout); |
|
1083 if (rv == PR_SUCCESS) { |
|
1084 ss->TCPconnected = 1; |
|
1085 } else { |
|
1086 int err = PR_GetError(); |
|
1087 SSL_DBG(("%d: SSL[%d]: connect failed, errno=%d", |
|
1088 SSL_GETPID(), ss->fd, err)); |
|
1089 if (err == PR_IS_CONNECTED_ERROR) { |
|
1090 ss->TCPconnected = 1; |
|
1091 } |
|
1092 } |
|
1093 |
|
1094 SSL_TRC(5, ("%d: SSL[%d]: secure connect completed, rv == %d", |
|
1095 SSL_GETPID(), ss->fd, rv)); |
|
1096 return rv; |
|
1097 } |
|
1098 |
|
1099 /* |
|
1100 * The TLS 1.2 RFC 5246, Section 7.2.1 says: |
|
1101 * |
|
1102 * Unless some other fatal alert has been transmitted, each party is |
|
1103 * required to send a close_notify alert before closing the write side |
|
1104 * of the connection. The other party MUST respond with a close_notify |
|
1105 * alert of its own and close down the connection immediately, |
|
1106 * discarding any pending writes. It is not required for the initiator |
|
1107 * of the close to wait for the responding close_notify alert before |
|
1108 * closing the read side of the connection. |
|
1109 * |
|
1110 * The second sentence requires that we send a close_notify alert when we |
|
1111 * have received a close_notify alert. In practice, all SSL implementations |
|
1112 * close the socket immediately after sending a close_notify alert (which is |
|
1113 * allowed by the third sentence), so responding with a close_notify alert |
|
1114 * would result in a write failure with the ECONNRESET error. This is why |
|
1115 * we don't respond with a close_notify alert. |
|
1116 * |
|
1117 * Also, in the unlikely event that the TCP pipe is full and the peer stops |
|
1118 * reading, the SSL3_SendAlert call in ssl_SecureClose and ssl_SecureShutdown |
|
1119 * may block indefinitely in blocking mode, and may fail (without retrying) |
|
1120 * in non-blocking mode. |
|
1121 */ |
|
1122 |
|
1123 int |
|
1124 ssl_SecureClose(sslSocket *ss) |
|
1125 { |
|
1126 int rv; |
|
1127 |
|
1128 if (ss->version >= SSL_LIBRARY_VERSION_3_0 && |
|
1129 !(ss->shutdownHow & ssl_SHUTDOWN_SEND) && |
|
1130 ss->firstHsDone && |
|
1131 !ss->recvdCloseNotify && |
|
1132 ss->ssl3.initialized) { |
|
1133 |
|
1134 /* We don't want the final alert to be Nagle delayed. */ |
|
1135 if (!ss->delayDisabled) { |
|
1136 ssl_EnableNagleDelay(ss, PR_FALSE); |
|
1137 ss->delayDisabled = 1; |
|
1138 } |
|
1139 |
|
1140 (void) SSL3_SendAlert(ss, alert_warning, close_notify); |
|
1141 } |
|
1142 rv = ssl_DefClose(ss); |
|
1143 return rv; |
|
1144 } |
|
1145 |
|
1146 /* Caller handles all locking */ |
|
1147 int |
|
1148 ssl_SecureShutdown(sslSocket *ss, int nsprHow) |
|
1149 { |
|
1150 PRFileDesc *osfd = ss->fd->lower; |
|
1151 int rv; |
|
1152 PRIntn sslHow = nsprHow + 1; |
|
1153 |
|
1154 if ((unsigned)nsprHow > PR_SHUTDOWN_BOTH) { |
|
1155 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
|
1156 return PR_FAILURE; |
|
1157 } |
|
1158 |
|
1159 if ((sslHow & ssl_SHUTDOWN_SEND) != 0 && |
|
1160 ss->version >= SSL_LIBRARY_VERSION_3_0 && |
|
1161 !(ss->shutdownHow & ssl_SHUTDOWN_SEND) && |
|
1162 ss->firstHsDone && |
|
1163 !ss->recvdCloseNotify && |
|
1164 ss->ssl3.initialized) { |
|
1165 |
|
1166 (void) SSL3_SendAlert(ss, alert_warning, close_notify); |
|
1167 } |
|
1168 |
|
1169 rv = osfd->methods->shutdown(osfd, nsprHow); |
|
1170 |
|
1171 ss->shutdownHow |= sslHow; |
|
1172 |
|
1173 return rv; |
|
1174 } |
|
1175 |
|
1176 /************************************************************************/ |
|
1177 |
|
1178 |
|
1179 int |
|
1180 ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags) |
|
1181 { |
|
1182 sslSecurityInfo *sec; |
|
1183 int rv = 0; |
|
1184 |
|
1185 sec = &ss->sec; |
|
1186 |
|
1187 if (ss->shutdownHow & ssl_SHUTDOWN_RCV) { |
|
1188 PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR); |
|
1189 return PR_FAILURE; |
|
1190 } |
|
1191 if (flags & ~PR_MSG_PEEK) { |
|
1192 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
|
1193 return PR_FAILURE; |
|
1194 } |
|
1195 |
|
1196 if (!ssl_SocketIsBlocking(ss) && !ss->opt.fdx) { |
|
1197 ssl_GetXmitBufLock(ss); |
|
1198 if (ss->pendingBuf.len != 0) { |
|
1199 rv = ssl_SendSavedWriteData(ss); |
|
1200 if ((rv < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) { |
|
1201 ssl_ReleaseXmitBufLock(ss); |
|
1202 return SECFailure; |
|
1203 } |
|
1204 } |
|
1205 ssl_ReleaseXmitBufLock(ss); |
|
1206 } |
|
1207 |
|
1208 rv = 0; |
|
1209 /* If any of these is non-zero, the initial handshake is not done. */ |
|
1210 if (!ss->firstHsDone) { |
|
1211 ssl_Get1stHandshakeLock(ss); |
|
1212 if (ss->handshake || ss->nextHandshake || ss->securityHandshake) { |
|
1213 rv = ssl_Do1stHandshake(ss); |
|
1214 } |
|
1215 ssl_Release1stHandshakeLock(ss); |
|
1216 } |
|
1217 if (rv < 0) { |
|
1218 return rv; |
|
1219 } |
|
1220 |
|
1221 if (len == 0) return 0; |
|
1222 |
|
1223 rv = DoRecv(ss, (unsigned char*) buf, len, flags); |
|
1224 SSL_TRC(2, ("%d: SSL[%d]: recving %d bytes securely (errno=%d)", |
|
1225 SSL_GETPID(), ss->fd, rv, PORT_GetError())); |
|
1226 return rv; |
|
1227 } |
|
1228 |
|
1229 int |
|
1230 ssl_SecureRead(sslSocket *ss, unsigned char *buf, int len) |
|
1231 { |
|
1232 return ssl_SecureRecv(ss, buf, len, 0); |
|
1233 } |
|
1234 |
|
1235 /* Caller holds the SSL Socket's write lock. SSL_LOCK_WRITER(ss) */ |
|
1236 int |
|
1237 ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) |
|
1238 { |
|
1239 int rv = 0; |
|
1240 |
|
1241 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes", |
|
1242 SSL_GETPID(), ss->fd, len)); |
|
1243 |
|
1244 if (ss->shutdownHow & ssl_SHUTDOWN_SEND) { |
|
1245 PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR); |
|
1246 rv = PR_FAILURE; |
|
1247 goto done; |
|
1248 } |
|
1249 if (flags) { |
|
1250 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
|
1251 rv = PR_FAILURE; |
|
1252 goto done; |
|
1253 } |
|
1254 |
|
1255 ssl_GetXmitBufLock(ss); |
|
1256 if (ss->pendingBuf.len != 0) { |
|
1257 PORT_Assert(ss->pendingBuf.len > 0); |
|
1258 rv = ssl_SendSavedWriteData(ss); |
|
1259 if (rv >= 0 && ss->pendingBuf.len != 0) { |
|
1260 PORT_Assert(ss->pendingBuf.len > 0); |
|
1261 PORT_SetError(PR_WOULD_BLOCK_ERROR); |
|
1262 rv = SECFailure; |
|
1263 } |
|
1264 } |
|
1265 ssl_ReleaseXmitBufLock(ss); |
|
1266 if (rv < 0) { |
|
1267 goto done; |
|
1268 } |
|
1269 |
|
1270 if (len > 0) |
|
1271 ss->writerThread = PR_GetCurrentThread(); |
|
1272 /* If any of these is non-zero, the initial handshake is not done. */ |
|
1273 if (!ss->firstHsDone) { |
|
1274 PRBool falseStart = PR_FALSE; |
|
1275 ssl_Get1stHandshakeLock(ss); |
|
1276 if (ss->opt.enableFalseStart && |
|
1277 ss->version >= SSL_LIBRARY_VERSION_3_0) { |
|
1278 ssl_GetSSL3HandshakeLock(ss); |
|
1279 falseStart = ss->ssl3.hs.canFalseStart; |
|
1280 ssl_ReleaseSSL3HandshakeLock(ss); |
|
1281 } |
|
1282 if (!falseStart && |
|
1283 (ss->handshake || ss->nextHandshake || ss->securityHandshake)) { |
|
1284 rv = ssl_Do1stHandshake(ss); |
|
1285 } |
|
1286 ssl_Release1stHandshakeLock(ss); |
|
1287 } |
|
1288 if (rv < 0) { |
|
1289 ss->writerThread = NULL; |
|
1290 goto done; |
|
1291 } |
|
1292 |
|
1293 /* Check for zero length writes after we do housekeeping so we make forward |
|
1294 * progress. |
|
1295 */ |
|
1296 if (len == 0) { |
|
1297 rv = 0; |
|
1298 goto done; |
|
1299 } |
|
1300 PORT_Assert(buf != NULL); |
|
1301 if (!buf) { |
|
1302 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
|
1303 rv = PR_FAILURE; |
|
1304 goto done; |
|
1305 } |
|
1306 |
|
1307 if (!ss->firstHsDone) { |
|
1308 PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_3_0); |
|
1309 #ifdef DEBUG |
|
1310 ssl_GetSSL3HandshakeLock(ss); |
|
1311 PORT_Assert(ss->ssl3.hs.canFalseStart); |
|
1312 ssl_ReleaseSSL3HandshakeLock(ss); |
|
1313 #endif |
|
1314 SSL_TRC(3, ("%d: SSL[%d]: SecureSend: sending data due to false start", |
|
1315 SSL_GETPID(), ss->fd)); |
|
1316 } |
|
1317 |
|
1318 /* Send out the data using one of these functions: |
|
1319 * ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock, |
|
1320 * ssl3_SendApplicationData |
|
1321 */ |
|
1322 ssl_GetXmitBufLock(ss); |
|
1323 rv = (*ss->sec.send)(ss, buf, len, flags); |
|
1324 ssl_ReleaseXmitBufLock(ss); |
|
1325 ss->writerThread = NULL; |
|
1326 done: |
|
1327 if (rv < 0) { |
|
1328 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count, error %d", |
|
1329 SSL_GETPID(), ss->fd, rv, PORT_GetError())); |
|
1330 } else { |
|
1331 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count", |
|
1332 SSL_GETPID(), ss->fd, rv)); |
|
1333 } |
|
1334 return rv; |
|
1335 } |
|
1336 |
|
1337 int |
|
1338 ssl_SecureWrite(sslSocket *ss, const unsigned char *buf, int len) |
|
1339 { |
|
1340 return ssl_SecureSend(ss, buf, len, 0); |
|
1341 } |
|
1342 |
|
1343 SECStatus |
|
1344 SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg) |
|
1345 { |
|
1346 sslSocket *ss; |
|
1347 |
|
1348 ss = ssl_FindSocket(fd); |
|
1349 if (!ss) { |
|
1350 SSL_DBG(("%d: SSL[%d]: bad socket in SSLBadCertHook", |
|
1351 SSL_GETPID(), fd)); |
|
1352 return SECFailure; |
|
1353 } |
|
1354 |
|
1355 ss->handleBadCert = f; |
|
1356 ss->badCertArg = arg; |
|
1357 |
|
1358 return SECSuccess; |
|
1359 } |
|
1360 |
|
1361 /* |
|
1362 * Allow the application to pass the url or hostname into the SSL library |
|
1363 * so that we can do some checking on it. It will be used for the value in |
|
1364 * SNI extension of client hello message. |
|
1365 */ |
|
1366 SECStatus |
|
1367 SSL_SetURL(PRFileDesc *fd, const char *url) |
|
1368 { |
|
1369 sslSocket * ss = ssl_FindSocket(fd); |
|
1370 SECStatus rv = SECSuccess; |
|
1371 |
|
1372 if (!ss) { |
|
1373 SSL_DBG(("%d: SSL[%d]: bad socket in SSLSetURL", |
|
1374 SSL_GETPID(), fd)); |
|
1375 return SECFailure; |
|
1376 } |
|
1377 ssl_Get1stHandshakeLock(ss); |
|
1378 ssl_GetSSL3HandshakeLock(ss); |
|
1379 |
|
1380 if ( ss->url ) { |
|
1381 PORT_Free((void *)ss->url); /* CONST */ |
|
1382 } |
|
1383 |
|
1384 ss->url = (const char *)PORT_Strdup(url); |
|
1385 if ( ss->url == NULL ) { |
|
1386 rv = SECFailure; |
|
1387 } |
|
1388 |
|
1389 ssl_ReleaseSSL3HandshakeLock(ss); |
|
1390 ssl_Release1stHandshakeLock(ss); |
|
1391 |
|
1392 return rv; |
|
1393 } |
|
1394 |
|
1395 /* |
|
1396 * Allow the application to pass the set of trust anchors |
|
1397 */ |
|
1398 SECStatus |
|
1399 SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *certList) |
|
1400 { |
|
1401 sslSocket * ss = ssl_FindSocket(fd); |
|
1402 CERTDistNames *names = NULL; |
|
1403 |
|
1404 if (!certList) { |
|
1405 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
|
1406 return SECFailure; |
|
1407 } |
|
1408 if (!ss) { |
|
1409 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetTrustAnchors", |
|
1410 SSL_GETPID(), fd)); |
|
1411 return SECFailure; |
|
1412 } |
|
1413 |
|
1414 names = CERT_DistNamesFromCertList(certList); |
|
1415 if (names == NULL) { |
|
1416 return SECFailure; |
|
1417 } |
|
1418 ssl_Get1stHandshakeLock(ss); |
|
1419 ssl_GetSSL3HandshakeLock(ss); |
|
1420 if (ss->ssl3.ca_list) { |
|
1421 CERT_FreeDistNames(ss->ssl3.ca_list); |
|
1422 } |
|
1423 ss->ssl3.ca_list = names; |
|
1424 ssl_ReleaseSSL3HandshakeLock(ss); |
|
1425 ssl_Release1stHandshakeLock(ss); |
|
1426 |
|
1427 return SECSuccess; |
|
1428 } |
|
1429 |
|
1430 /* |
|
1431 ** Returns Negative number on error, zero or greater on success. |
|
1432 ** Returns the amount of data immediately available to be read. |
|
1433 */ |
|
1434 int |
|
1435 SSL_DataPending(PRFileDesc *fd) |
|
1436 { |
|
1437 sslSocket *ss; |
|
1438 int rv = 0; |
|
1439 |
|
1440 ss = ssl_FindSocket(fd); |
|
1441 |
|
1442 if (ss && ss->opt.useSecurity) { |
|
1443 ssl_GetRecvBufLock(ss); |
|
1444 rv = ss->gs.writeOffset - ss->gs.readOffset; |
|
1445 ssl_ReleaseRecvBufLock(ss); |
|
1446 } |
|
1447 |
|
1448 return rv; |
|
1449 } |
|
1450 |
|
1451 SECStatus |
|
1452 SSL_InvalidateSession(PRFileDesc *fd) |
|
1453 { |
|
1454 sslSocket * ss = ssl_FindSocket(fd); |
|
1455 SECStatus rv = SECFailure; |
|
1456 |
|
1457 if (ss) { |
|
1458 ssl_Get1stHandshakeLock(ss); |
|
1459 ssl_GetSSL3HandshakeLock(ss); |
|
1460 |
|
1461 if (ss->sec.ci.sid && ss->sec.uncache) { |
|
1462 ss->sec.uncache(ss->sec.ci.sid); |
|
1463 rv = SECSuccess; |
|
1464 } |
|
1465 |
|
1466 ssl_ReleaseSSL3HandshakeLock(ss); |
|
1467 ssl_Release1stHandshakeLock(ss); |
|
1468 } |
|
1469 return rv; |
|
1470 } |
|
1471 |
|
1472 SECItem * |
|
1473 SSL_GetSessionID(PRFileDesc *fd) |
|
1474 { |
|
1475 sslSocket * ss; |
|
1476 SECItem * item = NULL; |
|
1477 |
|
1478 ss = ssl_FindSocket(fd); |
|
1479 if (ss) { |
|
1480 ssl_Get1stHandshakeLock(ss); |
|
1481 ssl_GetSSL3HandshakeLock(ss); |
|
1482 |
|
1483 if (ss->opt.useSecurity && ss->firstHsDone && ss->sec.ci.sid) { |
|
1484 item = (SECItem *)PORT_Alloc(sizeof(SECItem)); |
|
1485 if (item) { |
|
1486 sslSessionID * sid = ss->sec.ci.sid; |
|
1487 if (sid->version < SSL_LIBRARY_VERSION_3_0) { |
|
1488 item->len = SSL2_SESSIONID_BYTES; |
|
1489 item->data = (unsigned char*)PORT_Alloc(item->len); |
|
1490 PORT_Memcpy(item->data, sid->u.ssl2.sessionID, item->len); |
|
1491 } else { |
|
1492 item->len = sid->u.ssl3.sessionIDLength; |
|
1493 item->data = (unsigned char*)PORT_Alloc(item->len); |
|
1494 PORT_Memcpy(item->data, sid->u.ssl3.sessionID, item->len); |
|
1495 } |
|
1496 } |
|
1497 } |
|
1498 |
|
1499 ssl_ReleaseSSL3HandshakeLock(ss); |
|
1500 ssl_Release1stHandshakeLock(ss); |
|
1501 } |
|
1502 return item; |
|
1503 } |
|
1504 |
|
1505 SECStatus |
|
1506 SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle) |
|
1507 { |
|
1508 sslSocket * ss; |
|
1509 |
|
1510 ss = ssl_FindSocket(fd); |
|
1511 if (!ss) |
|
1512 return SECFailure; |
|
1513 if (!dbHandle) { |
|
1514 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
|
1515 return SECFailure; |
|
1516 } |
|
1517 ss->dbHandle = dbHandle; |
|
1518 return SECSuccess; |
|
1519 } |
|
1520 |
|
1521 /* DO NOT USE. This function was exported in ssl.def with the wrong signature; |
|
1522 * this implementation exists to maintain link-time compatibility. |
|
1523 */ |
|
1524 int |
|
1525 SSL_RestartHandshakeAfterCertReq(sslSocket * ss, |
|
1526 CERTCertificate * cert, |
|
1527 SECKEYPrivateKey * key, |
|
1528 CERTCertificateList *certChain) |
|
1529 { |
|
1530 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); |
|
1531 return -1; |
|
1532 } |
|
1533 |
|
1534 /* DO NOT USE. This function was exported in ssl.def with the wrong signature; |
|
1535 * this implementation exists to maintain link-time compatibility. |
|
1536 */ |
|
1537 int |
|
1538 SSL_RestartHandshakeAfterServerCert(sslSocket * ss) |
|
1539 { |
|
1540 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); |
|
1541 return -1; |
|
1542 } |
|
1543 |
|
1544 /* See documentation in ssl.h */ |
|
1545 SECStatus |
|
1546 SSL_AuthCertificateComplete(PRFileDesc *fd, PRErrorCode error) |
|
1547 { |
|
1548 SECStatus rv; |
|
1549 sslSocket *ss = ssl_FindSocket(fd); |
|
1550 |
|
1551 if (!ss) { |
|
1552 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_AuthCertificateComplete", |
|
1553 SSL_GETPID(), fd)); |
|
1554 return SECFailure; |
|
1555 } |
|
1556 |
|
1557 ssl_Get1stHandshakeLock(ss); |
|
1558 |
|
1559 if (!ss->ssl3.initialized) { |
|
1560 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
|
1561 rv = SECFailure; |
|
1562 } else if (ss->version < SSL_LIBRARY_VERSION_3_0) { |
|
1563 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); |
|
1564 rv = SECFailure; |
|
1565 } else { |
|
1566 rv = ssl3_AuthCertificateComplete(ss, error); |
|
1567 } |
|
1568 |
|
1569 ssl_Release1stHandshakeLock(ss); |
|
1570 |
|
1571 return rv; |
|
1572 } |
|
1573 |
|
1574 /* For more info see ssl.h */ |
|
1575 SECStatus |
|
1576 SSL_SNISocketConfigHook(PRFileDesc *fd, SSLSNISocketConfig func, |
|
1577 void *arg) |
|
1578 { |
|
1579 sslSocket *ss; |
|
1580 |
|
1581 ss = ssl_FindSocket(fd); |
|
1582 if (!ss) { |
|
1583 SSL_DBG(("%d: SSL[%d]: bad socket in SNISocketConfigHook", |
|
1584 SSL_GETPID(), fd)); |
|
1585 return SECFailure; |
|
1586 } |
|
1587 |
|
1588 ss->sniSocketConfig = func; |
|
1589 ss->sniSocketConfigArg = arg; |
|
1590 return SECSuccess; |
|
1591 } |