Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(334)

Side by Side Diff: net/third_party/nss/ssl/sslsecur.c

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

Powered by Google App Engine
This is Rietveld 408576698