Revert "Merged all Chromoting Host code into remoting_core.dll (Windows)."
[chromium-blink-merge.git] / net / third_party / nss / ssl / sslsecur.c
blobae9771e653b3f296314e688e8b9bc8b759ae0e93
1 /*
2 * Various SSL functions.
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 /* $Id: sslsecur.c,v 1.61 2012/05/24 20:34:51 wtc%google.com Exp $ */
8 #include "cert.h"
9 #include "secitem.h"
10 #include "keyhi.h"
11 #include "ssl.h"
12 #include "sslimpl.h"
13 #include "sslproto.h"
14 #include "secoid.h" /* for SECOID_GetALgorithmTag */
15 #include "pk11func.h" /* for PK11_GenerateRandom */
16 #include "nss.h" /* for NSS_RegisterShutdown */
17 #include "prinit.h" /* for PR_CallOnceWithArg */
19 #define MAX_BLOCK_CYPHER_SIZE 32
21 #define TEST_FOR_FAILURE /* reminder */
22 #define SET_ERROR_CODE /* reminder */
24 /* Returns a SECStatus: SECSuccess or SECFailure, NOT SECWouldBlock.
26 * Currently, the list of functions called through ss->handshake is:
28 * In sslsocks.c:
29 * SocksGatherRecord
30 * SocksHandleReply
31 * SocksStartGather
33 * In sslcon.c:
34 * ssl_GatherRecord1stHandshake
35 * ssl2_HandleClientSessionKeyMessage
36 * ssl2_HandleMessage
37 * ssl2_HandleVerifyMessage
38 * ssl2_BeginClientHandshake
39 * ssl2_BeginServerHandshake
40 * ssl2_HandleClientHelloMessage
41 * ssl2_HandleServerHelloMessage
43 * The ss->handshake function returns SECWouldBlock under these conditions:
44 * 1. ssl_GatherRecord1stHandshake called ssl2_GatherData which read in
45 * the beginning of an SSL v3 hello message and returned SECWouldBlock
46 * to switch to SSL v3 handshake processing.
48 * 2. ssl2_HandleClientHelloMessage discovered version 3.0 in the incoming
49 * v2 client hello msg, and called ssl3_HandleV2ClientHello which
50 * returned SECWouldBlock.
52 * 3. SECWouldBlock was returned by one of the callback functions, via
53 * one of these paths:
54 * - ssl2_HandleMessage() -> ssl2_HandleRequestCertificate() ->
55 * ss->getClientAuthData()
57 * - ssl2_HandleServerHelloMessage() -> ss->handleBadCert()
59 * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() ->
60 * ssl3_HandleRecord() -> ssl3_HandleHandshake() ->
61 * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificate() ->
62 * ss->handleBadCert()
64 * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() ->
65 * ssl3_HandleRecord() -> ssl3_HandleHandshake() ->
66 * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificateRequest() ->
67 * ss->getClientAuthData()
69 * Called from: SSL_ForceHandshake (below),
70 * ssl_SecureRecv (below) and
71 * ssl_SecureSend (below)
72 * from: WaitForResponse in sslsocks.c
73 * ssl_SocksRecv in sslsocks.c
74 * ssl_SocksSend in sslsocks.c
76 * Caller must hold the (write) handshakeLock.
78 int
79 ssl_Do1stHandshake(sslSocket *ss)
81 int rv = SECSuccess;
82 int loopCount = 0;
84 do {
85 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
86 PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss));
87 PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss));
88 PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss));
90 if (ss->handshake == 0) {
91 /* Previous handshake finished. Switch to next one */
92 ss->handshake = ss->nextHandshake;
93 ss->nextHandshake = 0;
95 if (ss->handshake == 0) {
96 /* Previous handshake finished. Switch to security handshake */
97 ss->handshake = ss->securityHandshake;
98 ss->securityHandshake = 0;
100 if (ss->handshake == 0) {
101 ssl_GetRecvBufLock(ss);
102 ss->gs.recordLen = 0;
103 ssl_ReleaseRecvBufLock(ss);
105 SSL_TRC(3, ("%d: SSL[%d]: handshake is completed",
106 SSL_GETPID(), ss->fd));
107 /* call handshake callback for ssl v2 */
108 /* for v3 this is done in ssl3_HandleFinished() */
109 if ((ss->handshakeCallback != NULL) && /* has callback */
110 (!ss->firstHsDone) && /* only first time */
111 (ss->version < SSL_LIBRARY_VERSION_3_0)) { /* not ssl3 */
112 ss->firstHsDone = PR_TRUE;
113 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
115 ss->firstHsDone = PR_TRUE;
116 ss->gs.writeOffset = 0;
117 ss->gs.readOffset = 0;
118 break;
120 rv = (*ss->handshake)(ss);
121 ++loopCount;
122 /* This code must continue to loop on SECWouldBlock,
123 * or any positive value. See XXX_1 comments.
125 } while (rv != SECFailure); /* was (rv >= 0); XXX_1 */
127 PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss));
128 PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss));
129 PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss));
131 if (rv == SECWouldBlock) {
132 PORT_SetError(PR_WOULD_BLOCK_ERROR);
133 rv = SECFailure;
135 return rv;
139 * Handshake function that blocks. Used to force a
140 * retry on a connection on the next read/write.
142 static SECStatus
143 ssl3_AlwaysBlock(sslSocket *ss)
145 PORT_SetError(PR_WOULD_BLOCK_ERROR); /* perhaps redundant. */
146 return SECWouldBlock;
150 * set the initial handshake state machine to block
152 void
153 ssl3_SetAlwaysBlock(sslSocket *ss)
155 if (!ss->firstHsDone) {
156 ss->handshake = ssl3_AlwaysBlock;
157 ss->nextHandshake = 0;
161 static SECStatus
162 ssl_SetTimeout(PRFileDesc *fd, PRIntervalTime timeout)
164 sslSocket *ss;
166 ss = ssl_FindSocket(fd);
167 if (!ss) {
168 SSL_DBG(("%d: SSL[%d]: bad socket in SetTimeout", SSL_GETPID(), fd));
169 return SECFailure;
171 SSL_LOCK_READER(ss);
172 ss->rTimeout = timeout;
173 if (ss->opt.fdx) {
174 SSL_LOCK_WRITER(ss);
176 ss->wTimeout = timeout;
177 if (ss->opt.fdx) {
178 SSL_UNLOCK_WRITER(ss);
180 SSL_UNLOCK_READER(ss);
181 return SECSuccess;
184 /* Acquires and releases HandshakeLock.
186 SECStatus
187 SSL_ResetHandshake(PRFileDesc *s, PRBool asServer)
189 sslSocket *ss;
190 SECStatus status;
191 PRNetAddr addr;
193 ss = ssl_FindSocket(s);
194 if (!ss) {
195 SSL_DBG(("%d: SSL[%d]: bad socket in ResetHandshake", SSL_GETPID(), s));
196 return SECFailure;
199 /* Don't waste my time */
200 if (!ss->opt.useSecurity)
201 return SECSuccess;
203 SSL_LOCK_READER(ss);
204 SSL_LOCK_WRITER(ss);
206 /* Reset handshake state */
207 ssl_Get1stHandshakeLock(ss);
209 ss->firstHsDone = PR_FALSE;
210 if ( asServer ) {
211 ss->handshake = ssl2_BeginServerHandshake;
212 ss->handshaking = sslHandshakingAsServer;
213 } else {
214 ss->handshake = ssl2_BeginClientHandshake;
215 ss->handshaking = sslHandshakingAsClient;
217 ss->nextHandshake = 0;
218 ss->securityHandshake = 0;
220 ssl_GetRecvBufLock(ss);
221 status = ssl_InitGather(&ss->gs);
222 ssl_ReleaseRecvBufLock(ss);
224 ssl_GetSSL3HandshakeLock(ss);
227 ** Blow away old security state and get a fresh setup.
229 ssl_GetXmitBufLock(ss);
230 ssl_ResetSecurityInfo(&ss->sec, PR_TRUE);
231 status = ssl_CreateSecurityInfo(ss);
232 ssl_ReleaseXmitBufLock(ss);
234 ssl_ReleaseSSL3HandshakeLock(ss);
235 ssl_Release1stHandshakeLock(ss);
237 if (!ss->TCPconnected)
238 ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr));
240 SSL_UNLOCK_WRITER(ss);
241 SSL_UNLOCK_READER(ss);
243 return status;
246 /* For SSLv2, does nothing but return an error.
247 ** For SSLv3, flushes SID cache entry (if requested),
248 ** and then starts new client hello or hello request.
249 ** Acquires and releases HandshakeLock.
251 SECStatus
252 SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache)
254 sslSocket *ss;
255 SECStatus rv;
257 ss = ssl_FindSocket(fd);
258 if (!ss) {
259 SSL_DBG(("%d: SSL[%d]: bad socket in RedoHandshake", SSL_GETPID(), fd));
260 return SECFailure;
263 if (!ss->opt.useSecurity)
264 return SECSuccess;
266 ssl_Get1stHandshakeLock(ss);
268 /* SSL v2 protocol does not support subsequent handshakes. */
269 if (ss->version < SSL_LIBRARY_VERSION_3_0) {
270 PORT_SetError(SEC_ERROR_INVALID_ARGS);
271 rv = SECFailure;
272 } else {
273 ssl_GetSSL3HandshakeLock(ss);
274 rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */
275 ssl_ReleaseSSL3HandshakeLock(ss);
278 ssl_Release1stHandshakeLock(ss);
280 return rv;
284 ** Same as above, but with an I/O timeout.
286 SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd,
287 PRBool flushCache,
288 PRIntervalTime timeout)
290 if (SECSuccess != ssl_SetTimeout(fd, timeout)) {
291 return SECFailure;
293 return SSL_ReHandshake(fd, flushCache);
296 SECStatus
297 SSL_RedoHandshake(PRFileDesc *fd)
299 return SSL_ReHandshake(fd, PR_TRUE);
302 /* Register an application callback to be called when SSL handshake completes.
303 ** Acquires and releases HandshakeLock.
305 SECStatus
306 SSL_HandshakeCallback(PRFileDesc *fd, SSLHandshakeCallback cb,
307 void *client_data)
309 sslSocket *ss;
311 ss = ssl_FindSocket(fd);
312 if (!ss) {
313 SSL_DBG(("%d: SSL[%d]: bad socket in HandshakeCallback",
314 SSL_GETPID(), fd));
315 return SECFailure;
318 if (!ss->opt.useSecurity) {
319 PORT_SetError(SEC_ERROR_INVALID_ARGS);
320 return SECFailure;
323 ssl_Get1stHandshakeLock(ss);
324 ssl_GetSSL3HandshakeLock(ss);
326 ss->handshakeCallback = cb;
327 ss->handshakeCallbackData = client_data;
329 ssl_ReleaseSSL3HandshakeLock(ss);
330 ssl_Release1stHandshakeLock(ss);
332 return SECSuccess;
335 /* Try to make progress on an SSL handshake by attempting to read the
336 ** next handshake from the peer, and sending any responses.
337 ** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK if it cannot
338 ** read the next handshake from the underlying socket.
339 ** For SSLv2, returns when handshake is complete or fatal error occurs.
340 ** For SSLv3, returns when handshake is complete, or application data has
341 ** arrived that must be taken by application before handshake can continue,
342 ** or a fatal error occurs.
343 ** Application should use handshake completion callback to tell which.
345 SECStatus
346 SSL_ForceHandshake(PRFileDesc *fd)
348 sslSocket *ss;
349 SECStatus rv = SECFailure;
351 ss = ssl_FindSocket(fd);
352 if (!ss) {
353 SSL_DBG(("%d: SSL[%d]: bad socket in ForceHandshake",
354 SSL_GETPID(), fd));
355 return rv;
358 /* Don't waste my time */
359 if (!ss->opt.useSecurity)
360 return SECSuccess;
362 if (!ssl_SocketIsBlocking(ss)) {
363 ssl_GetXmitBufLock(ss);
364 if (ss->pendingBuf.len != 0) {
365 int sent = ssl_SendSavedWriteData(ss);
366 if ((sent < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) {
367 ssl_ReleaseXmitBufLock(ss);
368 return SECFailure;
371 ssl_ReleaseXmitBufLock(ss);
374 ssl_Get1stHandshakeLock(ss);
376 if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
377 int gatherResult;
379 ssl_GetRecvBufLock(ss);
380 gatherResult = ssl3_GatherCompleteHandshake(ss, 0);
381 ssl_ReleaseRecvBufLock(ss);
382 if (gatherResult > 0) {
383 rv = SECSuccess;
384 } else if (gatherResult == 0) {
385 PORT_SetError(PR_END_OF_FILE_ERROR);
386 } else if (gatherResult == SECWouldBlock) {
387 PORT_SetError(PR_WOULD_BLOCK_ERROR);
389 } else if (!ss->firstHsDone) {
390 rv = ssl_Do1stHandshake(ss);
391 } else {
392 /* tried to force handshake on an SSL 2 socket that has
393 ** already completed the handshake. */
394 rv = SECSuccess; /* just pretend we did it. */
397 ssl_Release1stHandshakeLock(ss);
399 return rv;
403 ** Same as above, but with an I/O timeout.
405 SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
406 PRIntervalTime timeout)
408 if (SECSuccess != ssl_SetTimeout(fd, timeout)) {
409 return SECFailure;
411 return SSL_ForceHandshake(fd);
415 /************************************************************************/
418 ** Grow a buffer to hold newLen bytes of data.
419 ** Called for both recv buffers and xmit buffers.
420 ** Caller must hold xmitBufLock or recvBufLock, as appropriate.
422 SECStatus
423 sslBuffer_Grow(sslBuffer *b, unsigned int newLen)
425 newLen = PR_MAX(newLen, MAX_FRAGMENT_LENGTH + 2048);
426 if (newLen > b->space) {
427 unsigned char *newBuf;
428 if (b->buf) {
429 newBuf = (unsigned char *) PORT_Realloc(b->buf, newLen);
430 } else {
431 newBuf = (unsigned char *) PORT_Alloc(newLen);
433 if (!newBuf) {
434 return SECFailure;
436 SSL_TRC(10, ("%d: SSL: grow buffer from %d to %d",
437 SSL_GETPID(), b->space, newLen));
438 b->buf = newBuf;
439 b->space = newLen;
441 return SECSuccess;
444 SECStatus
445 sslBuffer_Append(sslBuffer *b, const void * data, unsigned int len)
447 unsigned int newLen = b->len + len;
448 SECStatus rv;
450 rv = sslBuffer_Grow(b, newLen);
451 if (rv != SECSuccess)
452 return rv;
453 PORT_Memcpy(b->buf + b->len, data, len);
454 b->len += len;
455 return SECSuccess;
459 ** Save away write data that is trying to be written before the security
460 ** handshake has been completed. When the handshake is completed, we will
461 ** flush this data out.
462 ** Caller must hold xmitBufLock
464 SECStatus
465 ssl_SaveWriteData(sslSocket *ss, const void *data, unsigned int len)
467 SECStatus rv;
469 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
470 rv = sslBuffer_Append(&ss->pendingBuf, data, len);
471 SSL_TRC(5, ("%d: SSL[%d]: saving %u bytes of data (%u total saved so far)",
472 SSL_GETPID(), ss->fd, len, ss->pendingBuf.len));
473 return rv;
477 ** Send saved write data. This will flush out data sent prior to a
478 ** complete security handshake. Hopefully there won't be too much of it.
479 ** Returns count of the bytes sent, NOT a SECStatus.
480 ** Caller must hold xmitBufLock
482 int
483 ssl_SendSavedWriteData(sslSocket *ss)
485 int rv = 0;
487 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
488 if (ss->pendingBuf.len != 0) {
489 SSL_TRC(5, ("%d: SSL[%d]: sending %d bytes of saved data",
490 SSL_GETPID(), ss->fd, ss->pendingBuf.len));
491 rv = ssl_DefSend(ss, ss->pendingBuf.buf, ss->pendingBuf.len, 0);
492 if (rv < 0) {
493 return rv;
495 ss->pendingBuf.len -= rv;
496 if (ss->pendingBuf.len > 0 && rv > 0) {
497 /* UGH !! This shifts the whole buffer down by copying it */
498 PORT_Memmove(ss->pendingBuf.buf, ss->pendingBuf.buf + rv,
499 ss->pendingBuf.len);
502 return rv;
505 /************************************************************************/
508 ** Receive some application data on a socket. Reads SSL records from the input
509 ** stream, decrypts them and then copies them to the output buffer.
510 ** Called from ssl_SecureRecv() below.
512 ** Caller does NOT hold 1stHandshakeLock because that handshake is over.
513 ** Caller doesn't call this until initial handshake is complete.
514 ** For SSLv2, there is no subsequent handshake.
515 ** For SSLv3, the call to ssl3_GatherAppDataRecord may encounter handshake
516 ** messages from a subsequent handshake.
518 ** This code is similar to, and easily confused with,
519 ** ssl_GatherRecord1stHandshake() in sslcon.c
521 static int
522 DoRecv(sslSocket *ss, unsigned char *out, int len, int flags)
524 int rv;
525 int amount;
526 int available;
528 ssl_GetRecvBufLock(ss);
530 available = ss->gs.writeOffset - ss->gs.readOffset;
531 if (available == 0) {
532 /* Get some more data */
533 if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
534 /* Wait for application data to arrive. */
535 rv = ssl3_GatherAppDataRecord(ss, 0);
536 } else {
537 /* See if we have a complete record */
538 rv = ssl2_GatherRecord(ss, 0);
540 if (rv <= 0) {
541 if (rv == 0) {
542 /* EOF */
543 SSL_TRC(10, ("%d: SSL[%d]: ssl_recv EOF",
544 SSL_GETPID(), ss->fd));
545 goto done;
547 if ((rv != SECWouldBlock) &&
548 (PR_GetError() != PR_WOULD_BLOCK_ERROR)) {
549 /* Some random error */
550 goto done;
554 ** Gather record is blocked waiting for more record data to
555 ** arrive. Try to process what we have already received
557 } else {
558 /* Gather record has finished getting a complete record */
561 /* See if any clear data is now available */
562 available = ss->gs.writeOffset - ss->gs.readOffset;
563 if (available == 0) {
565 ** No partial data is available. Force error code to
566 ** EWOULDBLOCK so that caller will try again later. Note
567 ** that the error code is probably EWOULDBLOCK already,
568 ** but if it isn't (for example, if we received a zero
569 ** length record) then this will force it to be correct.
571 PORT_SetError(PR_WOULD_BLOCK_ERROR);
572 rv = SECFailure;
573 goto done;
575 SSL_TRC(30, ("%d: SSL[%d]: partial data ready, available=%d",
576 SSL_GETPID(), ss->fd, available));
579 /* Dole out clear data to reader */
580 amount = PR_MIN(len, available);
581 PORT_Memcpy(out, ss->gs.buf.buf + ss->gs.readOffset, amount);
582 if (!(flags & PR_MSG_PEEK)) {
583 ss->gs.readOffset += amount;
585 PORT_Assert(ss->gs.readOffset <= ss->gs.writeOffset);
586 rv = amount;
588 SSL_TRC(30, ("%d: SSL[%d]: amount=%d available=%d",
589 SSL_GETPID(), ss->fd, amount, available));
590 PRINT_BUF(4, (ss, "DoRecv receiving plaintext:", out, amount));
592 done:
593 ssl_ReleaseRecvBufLock(ss);
594 return rv;
597 /************************************************************************/
600 ** Return SSLKEAType derived from cert's Public Key algorithm info.
602 SSLKEAType
603 NSS_FindCertKEAType(CERTCertificate * cert)
605 SSLKEAType keaType = kt_null;
606 int tag;
608 if (!cert) goto loser;
610 tag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
612 switch (tag) {
613 case SEC_OID_X500_RSA_ENCRYPTION:
614 case SEC_OID_PKCS1_RSA_ENCRYPTION:
615 keaType = kt_rsa;
616 break;
617 case SEC_OID_X942_DIFFIE_HELMAN_KEY:
618 keaType = kt_dh;
619 break;
620 #ifdef NSS_ENABLE_ECC
621 case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
622 keaType = kt_ecdh;
623 break;
624 #endif /* NSS_ENABLE_ECC */
625 default:
626 keaType = kt_null;
629 loser:
631 return keaType;
634 static const PRCallOnceType pristineCallOnce;
635 static PRCallOnceType setupServerCAListOnce;
637 static SECStatus serverCAListShutdown(void* appData, void* nssData)
639 PORT_Assert(ssl3_server_ca_list);
640 if (ssl3_server_ca_list) {
641 CERT_FreeDistNames(ssl3_server_ca_list);
642 ssl3_server_ca_list = NULL;
644 setupServerCAListOnce = pristineCallOnce;
645 return SECSuccess;
648 static PRStatus serverCAListSetup(void *arg)
650 CERTCertDBHandle *dbHandle = (CERTCertDBHandle *)arg;
651 SECStatus rv = NSS_RegisterShutdown(serverCAListShutdown, NULL);
652 PORT_Assert(SECSuccess == rv);
653 if (SECSuccess == rv) {
654 ssl3_server_ca_list = CERT_GetSSLCACerts(dbHandle);
655 return PR_SUCCESS;
657 return PR_FAILURE;
660 SECStatus
661 ssl_ConfigSecureServer(sslSocket *ss, CERTCertificate *cert,
662 const CERTCertificateList *certChain,
663 ssl3KeyPair *keyPair, SSLKEAType kea)
665 CERTCertificateList *localCertChain = NULL;
666 sslServerCerts *sc = ss->serverCerts + kea;
668 /* load the server certificate */
669 if (sc->serverCert != NULL) {
670 CERT_DestroyCertificate(sc->serverCert);
671 sc->serverCert = NULL;
672 sc->serverKeyBits = 0;
674 /* load the server cert chain */
675 if (sc->serverCertChain != NULL) {
676 CERT_DestroyCertificateList(sc->serverCertChain);
677 sc->serverCertChain = NULL;
679 if (cert) {
680 sc->serverCert = CERT_DupCertificate(cert);
681 /* get the size of the cert's public key, and remember it */
682 sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->pubKey);
683 if (!certChain) {
684 localCertChain =
685 CERT_CertChainFromCert(sc->serverCert, certUsageSSLServer,
686 PR_TRUE);
687 if (!localCertChain)
688 goto loser;
690 sc->serverCertChain = (certChain) ? CERT_DupCertList(certChain) :
691 localCertChain;
692 if (!sc->serverCertChain) {
693 goto loser;
695 localCertChain = NULL; /* consumed */
698 /* get keyPair */
699 if (sc->serverKeyPair != NULL) {
700 ssl3_FreeKeyPair(sc->serverKeyPair);
701 sc->serverKeyPair = NULL;
703 if (keyPair) {
704 SECKEY_CacheStaticFlags(keyPair->privKey);
705 sc->serverKeyPair = ssl3_GetKeyPairRef(keyPair);
707 if (kea == kt_rsa && cert && sc->serverKeyBits > 512 &&
708 !ss->opt.noStepDown && !ss->stepDownKeyPair) {
709 if (ssl3_CreateRSAStepDownKeys(ss) != SECSuccess) {
710 goto loser;
713 return SECSuccess;
715 loser:
716 if (localCertChain) {
717 CERT_DestroyCertificateList(localCertChain);
719 if (sc->serverCert != NULL) {
720 CERT_DestroyCertificate(sc->serverCert);
721 sc->serverCert = NULL;
723 if (sc->serverCertChain != NULL) {
724 CERT_DestroyCertificateList(sc->serverCertChain);
725 sc->serverCertChain = NULL;
727 if (sc->serverKeyPair != NULL) {
728 ssl3_FreeKeyPair(sc->serverKeyPair);
729 sc->serverKeyPair = NULL;
731 return SECFailure;
734 /* XXX need to protect the data that gets changed here.!! */
736 SECStatus
737 SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert,
738 SECKEYPrivateKey *key, SSL3KEAType kea)
741 return SSL_ConfigSecureServerWithCertChain(fd, cert, NULL, key, kea);
744 SECStatus
745 SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert,
746 const CERTCertificateList *certChainOpt,
747 SECKEYPrivateKey *key, SSL3KEAType kea)
749 sslSocket *ss;
750 SECKEYPublicKey *pubKey = NULL;
751 ssl3KeyPair *keyPair = NULL;
752 SECStatus rv = SECFailure;
754 ss = ssl_FindSocket(fd);
755 if (!ss) {
756 return SECFailure;
759 /* Both key and cert must have a value or be NULL */
760 /* Passing a value of NULL will turn off key exchange algorithms that were
761 * previously turned on */
762 if (!cert != !key) {
763 PORT_SetError(SEC_ERROR_INVALID_ARGS);
764 return SECFailure;
767 /* make sure the key exchange is recognized */
768 if ((kea >= kt_kea_size) || (kea < kt_null)) {
769 PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
770 return SECFailure;
773 if (kea != NSS_FindCertKEAType(cert)) {
774 PORT_SetError(SSL_ERROR_CERT_KEA_MISMATCH);
775 return SECFailure;
778 if (cert) {
779 /* get the size of the cert's public key, and remember it */
780 pubKey = CERT_ExtractPublicKey(cert);
781 if (!pubKey)
782 return SECFailure;
785 if (key) {
786 SECKEYPrivateKey * keyCopy = NULL;
787 CK_MECHANISM_TYPE keyMech = CKM_INVALID_MECHANISM;
789 if (key->pkcs11Slot) {
790 PK11SlotInfo * bestSlot;
791 bestSlot = PK11_ReferenceSlot(key->pkcs11Slot);
792 if (bestSlot) {
793 keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
794 PK11_FreeSlot(bestSlot);
797 if (keyCopy == NULL)
798 keyMech = PK11_MapSignKeyType(key->keyType);
799 if (keyMech != CKM_INVALID_MECHANISM) {
800 PK11SlotInfo * bestSlot;
801 /* XXX Maybe should be bestSlotMultiple? */
802 bestSlot = PK11_GetBestSlot(keyMech, NULL /* wincx */);
803 if (bestSlot) {
804 keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
805 PK11_FreeSlot(bestSlot);
808 if (keyCopy == NULL)
809 keyCopy = SECKEY_CopyPrivateKey(key);
810 if (keyCopy == NULL)
811 goto loser;
812 keyPair = ssl3_NewKeyPair(keyCopy, pubKey);
813 if (keyPair == NULL) {
814 SECKEY_DestroyPrivateKey(keyCopy);
815 goto loser;
817 pubKey = NULL; /* adopted by serverKeyPair */
819 if (ssl_ConfigSecureServer(ss, cert, certChainOpt,
820 keyPair, kea) == SECFailure) {
821 goto loser;
824 /* Only do this once because it's global. */
825 if (PR_SUCCESS == PR_CallOnceWithArg(&setupServerCAListOnce,
826 &serverCAListSetup,
827 (void *)(ss->dbHandle))) {
828 rv = SECSuccess;
831 loser:
832 if (keyPair) {
833 ssl3_FreeKeyPair(keyPair);
835 if (pubKey) {
836 SECKEY_DestroyPublicKey(pubKey);
837 pubKey = NULL;
839 return rv;
842 /************************************************************************/
844 SECStatus
845 ssl_CreateSecurityInfo(sslSocket *ss)
847 SECStatus status;
849 /* initialize sslv2 socket to send data in the clear. */
850 ssl2_UseClearSendFunc(ss);
852 ss->sec.blockSize = 1;
853 ss->sec.blockShift = 0;
855 ssl_GetXmitBufLock(ss);
856 status = sslBuffer_Grow(&ss->sec.writeBuf, 4096);
857 ssl_ReleaseXmitBufLock(ss);
859 return status;
862 SECStatus
863 ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os)
865 ss->sec.send = os->sec.send;
866 ss->sec.isServer = os->sec.isServer;
867 ss->sec.keyBits = os->sec.keyBits;
868 ss->sec.secretKeyBits = os->sec.secretKeyBits;
870 ss->sec.peerCert = CERT_DupCertificate(os->sec.peerCert);
871 if (os->sec.peerCert && !ss->sec.peerCert)
872 goto loser;
874 ss->sec.cache = os->sec.cache;
875 ss->sec.uncache = os->sec.uncache;
877 /* we don't dup the connection info. */
879 ss->sec.sendSequence = os->sec.sendSequence;
880 ss->sec.rcvSequence = os->sec.rcvSequence;
882 if (os->sec.hash && os->sec.hashcx) {
883 ss->sec.hash = os->sec.hash;
884 ss->sec.hashcx = os->sec.hash->clone(os->sec.hashcx);
885 if (os->sec.hashcx && !ss->sec.hashcx)
886 goto loser;
887 } else {
888 ss->sec.hash = NULL;
889 ss->sec.hashcx = NULL;
892 SECITEM_CopyItem(0, &ss->sec.sendSecret, &os->sec.sendSecret);
893 if (os->sec.sendSecret.data && !ss->sec.sendSecret.data)
894 goto loser;
895 SECITEM_CopyItem(0, &ss->sec.rcvSecret, &os->sec.rcvSecret);
896 if (os->sec.rcvSecret.data && !ss->sec.rcvSecret.data)
897 goto loser;
899 /* XXX following code is wrong if either cx != 0 */
900 PORT_Assert(os->sec.readcx == 0);
901 PORT_Assert(os->sec.writecx == 0);
902 ss->sec.readcx = os->sec.readcx;
903 ss->sec.writecx = os->sec.writecx;
904 ss->sec.destroy = 0;
906 ss->sec.enc = os->sec.enc;
907 ss->sec.dec = os->sec.dec;
909 ss->sec.blockShift = os->sec.blockShift;
910 ss->sec.blockSize = os->sec.blockSize;
912 return SECSuccess;
914 loser:
915 return SECFailure;
918 /* Reset sec back to its initial state.
919 ** Caller holds any relevant locks.
921 void
922 ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset)
924 /* Destroy MAC */
925 if (sec->hash && sec->hashcx) {
926 (*sec->hash->destroy)(sec->hashcx, PR_TRUE);
927 sec->hashcx = NULL;
928 sec->hash = NULL;
930 SECITEM_ZfreeItem(&sec->sendSecret, PR_FALSE);
931 SECITEM_ZfreeItem(&sec->rcvSecret, PR_FALSE);
933 /* Destroy ciphers */
934 if (sec->destroy) {
935 (*sec->destroy)(sec->readcx, PR_TRUE);
936 (*sec->destroy)(sec->writecx, PR_TRUE);
937 sec->readcx = NULL;
938 sec->writecx = NULL;
939 } else {
940 PORT_Assert(sec->readcx == 0);
941 PORT_Assert(sec->writecx == 0);
943 sec->readcx = 0;
944 sec->writecx = 0;
946 if (sec->localCert) {
947 CERT_DestroyCertificate(sec->localCert);
948 sec->localCert = NULL;
950 if (sec->peerCert) {
951 CERT_DestroyCertificate(sec->peerCert);
952 sec->peerCert = NULL;
954 if (sec->peerKey) {
955 SECKEY_DestroyPublicKey(sec->peerKey);
956 sec->peerKey = NULL;
959 /* cleanup the ci */
960 if (sec->ci.sid != NULL) {
961 ssl_FreeSID(sec->ci.sid);
963 PORT_ZFree(sec->ci.sendBuf.buf, sec->ci.sendBuf.space);
964 if (doMemset) {
965 memset(&sec->ci, 0, sizeof sec->ci);
971 ** Called from SSL_ResetHandshake (above), and
972 ** from ssl_FreeSocket in sslsock.c
973 ** Caller should hold relevant locks (e.g. XmitBufLock)
975 void
976 ssl_DestroySecurityInfo(sslSecurityInfo *sec)
978 ssl_ResetSecurityInfo(sec, PR_FALSE);
980 PORT_ZFree(sec->writeBuf.buf, sec->writeBuf.space);
981 sec->writeBuf.buf = 0;
983 memset(sec, 0, sizeof *sec);
986 /************************************************************************/
988 int
989 ssl_SecureConnect(sslSocket *ss, const PRNetAddr *sa)
991 PRFileDesc *osfd = ss->fd->lower;
992 int rv;
994 if ( ss->opt.handshakeAsServer ) {
995 ss->securityHandshake = ssl2_BeginServerHandshake;
996 ss->handshaking = sslHandshakingAsServer;
997 } else {
998 ss->securityHandshake = ssl2_BeginClientHandshake;
999 ss->handshaking = sslHandshakingAsClient;
1002 /* connect to server */
1003 rv = osfd->methods->connect(osfd, sa, ss->cTimeout);
1004 if (rv == PR_SUCCESS) {
1005 ss->TCPconnected = 1;
1006 } else {
1007 int err = PR_GetError();
1008 SSL_DBG(("%d: SSL[%d]: connect failed, errno=%d",
1009 SSL_GETPID(), ss->fd, err));
1010 if (err == PR_IS_CONNECTED_ERROR) {
1011 ss->TCPconnected = 1;
1015 SSL_TRC(5, ("%d: SSL[%d]: secure connect completed, rv == %d",
1016 SSL_GETPID(), ss->fd, rv));
1017 return rv;
1021 * The TLS 1.2 RFC 5246, Section 7.2.1 says:
1023 * Unless some other fatal alert has been transmitted, each party is
1024 * required to send a close_notify alert before closing the write side
1025 * of the connection. The other party MUST respond with a close_notify
1026 * alert of its own and close down the connection immediately,
1027 * discarding any pending writes. It is not required for the initiator
1028 * of the close to wait for the responding close_notify alert before
1029 * closing the read side of the connection.
1031 * The second sentence requires that we send a close_notify alert when we
1032 * have received a close_notify alert. In practice, all SSL implementations
1033 * close the socket immediately after sending a close_notify alert (which is
1034 * allowed by the third sentence), so responding with a close_notify alert
1035 * would result in a write failure with the ECONNRESET error. This is why
1036 * we don't respond with a close_notify alert.
1038 * Also, in the unlikely event that the TCP pipe is full and the peer stops
1039 * reading, the SSL3_SendAlert call in ssl_SecureClose and ssl_SecureShutdown
1040 * may block indefinitely in blocking mode, and may fail (without retrying)
1041 * in non-blocking mode.
1045 ssl_SecureClose(sslSocket *ss)
1047 int rv;
1049 if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
1050 !(ss->shutdownHow & ssl_SHUTDOWN_SEND) &&
1051 ss->firstHsDone &&
1052 !ss->recvdCloseNotify &&
1053 ss->ssl3.initialized) {
1055 /* We don't want the final alert to be Nagle delayed. */
1056 if (!ss->delayDisabled) {
1057 ssl_EnableNagleDelay(ss, PR_FALSE);
1058 ss->delayDisabled = 1;
1061 (void) SSL3_SendAlert(ss, alert_warning, close_notify);
1063 rv = ssl_DefClose(ss);
1064 return rv;
1067 /* Caller handles all locking */
1069 ssl_SecureShutdown(sslSocket *ss, int nsprHow)
1071 PRFileDesc *osfd = ss->fd->lower;
1072 int rv;
1073 PRIntn sslHow = nsprHow + 1;
1075 if ((unsigned)nsprHow > PR_SHUTDOWN_BOTH) {
1076 PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
1077 return PR_FAILURE;
1080 if ((sslHow & ssl_SHUTDOWN_SEND) != 0 &&
1081 ss->version >= SSL_LIBRARY_VERSION_3_0 &&
1082 !(ss->shutdownHow & ssl_SHUTDOWN_SEND) &&
1083 ss->firstHsDone &&
1084 !ss->recvdCloseNotify &&
1085 ss->ssl3.initialized) {
1087 (void) SSL3_SendAlert(ss, alert_warning, close_notify);
1090 rv = osfd->methods->shutdown(osfd, nsprHow);
1092 ss->shutdownHow |= sslHow;
1094 return rv;
1097 /************************************************************************/
1101 ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
1103 sslSecurityInfo *sec;
1104 int rv = 0;
1106 sec = &ss->sec;
1108 if (ss->shutdownHow & ssl_SHUTDOWN_RCV) {
1109 PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
1110 return PR_FAILURE;
1112 if (flags & ~PR_MSG_PEEK) {
1113 PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
1114 return PR_FAILURE;
1117 if (!ssl_SocketIsBlocking(ss) && !ss->opt.fdx) {
1118 ssl_GetXmitBufLock(ss);
1119 if (ss->pendingBuf.len != 0) {
1120 rv = ssl_SendSavedWriteData(ss);
1121 if ((rv < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) {
1122 ssl_ReleaseXmitBufLock(ss);
1123 return SECFailure;
1126 ssl_ReleaseXmitBufLock(ss);
1129 rv = 0;
1130 /* If any of these is non-zero, the initial handshake is not done. */
1131 if (!ss->firstHsDone) {
1132 ssl_Get1stHandshakeLock(ss);
1133 if (ss->handshake || ss->nextHandshake || ss->securityHandshake) {
1134 rv = ssl_Do1stHandshake(ss);
1136 ssl_Release1stHandshakeLock(ss);
1138 if (rv < 0) {
1139 return rv;
1142 if (len == 0) return 0;
1144 rv = DoRecv(ss, (unsigned char*) buf, len, flags);
1145 SSL_TRC(2, ("%d: SSL[%d]: recving %d bytes securely (errno=%d)",
1146 SSL_GETPID(), ss->fd, rv, PORT_GetError()));
1147 return rv;
1151 ssl_SecureRead(sslSocket *ss, unsigned char *buf, int len)
1153 return ssl_SecureRecv(ss, buf, len, 0);
1156 /* Caller holds the SSL Socket's write lock. SSL_LOCK_WRITER(ss) */
1158 ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
1160 int rv = 0;
1162 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes",
1163 SSL_GETPID(), ss->fd, len));
1165 if (ss->shutdownHow & ssl_SHUTDOWN_SEND) {
1166 PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
1167 rv = PR_FAILURE;
1168 goto done;
1170 if (flags) {
1171 PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
1172 rv = PR_FAILURE;
1173 goto done;
1176 ssl_GetXmitBufLock(ss);
1177 if (ss->pendingBuf.len != 0) {
1178 PORT_Assert(ss->pendingBuf.len > 0);
1179 rv = ssl_SendSavedWriteData(ss);
1180 if (rv >= 0 && ss->pendingBuf.len != 0) {
1181 PORT_Assert(ss->pendingBuf.len > 0);
1182 PORT_SetError(PR_WOULD_BLOCK_ERROR);
1183 rv = SECFailure;
1186 ssl_ReleaseXmitBufLock(ss);
1187 if (rv < 0) {
1188 goto done;
1191 if (len > 0)
1192 ss->writerThread = PR_GetCurrentThread();
1193 /* If any of these is non-zero, the initial handshake is not done. */
1194 if (!ss->firstHsDone) {
1195 PRBool canFalseStart = PR_FALSE;
1196 ssl_Get1stHandshakeLock(ss);
1197 if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
1198 ssl_GetSSL3HandshakeLock(ss);
1199 if ((ss->ssl3.hs.ws == wait_change_cipher ||
1200 ss->ssl3.hs.ws == wait_finished ||
1201 ss->ssl3.hs.ws == wait_new_session_ticket) &&
1202 ssl3_CanFalseStart(ss)) {
1203 canFalseStart = PR_TRUE;
1205 ssl_ReleaseSSL3HandshakeLock(ss);
1207 if (!canFalseStart &&
1208 (ss->handshake || ss->nextHandshake || ss->securityHandshake)) {
1209 rv = ssl_Do1stHandshake(ss);
1211 ssl_Release1stHandshakeLock(ss);
1213 if (rv < 0) {
1214 ss->writerThread = NULL;
1215 goto done;
1218 /* Check for zero length writes after we do housekeeping so we make forward
1219 * progress.
1221 if (len == 0) {
1222 rv = 0;
1223 goto done;
1225 PORT_Assert(buf != NULL);
1226 if (!buf) {
1227 PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
1228 rv = PR_FAILURE;
1229 goto done;
1232 /* Send out the data using one of these functions:
1233 * ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock,
1234 * ssl3_SendApplicationData
1236 ssl_GetXmitBufLock(ss);
1237 rv = (*ss->sec.send)(ss, buf, len, flags);
1238 ssl_ReleaseXmitBufLock(ss);
1239 ss->writerThread = NULL;
1240 done:
1241 if (rv < 0) {
1242 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count, error %d",
1243 SSL_GETPID(), ss->fd, rv, PORT_GetError()));
1244 } else {
1245 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count",
1246 SSL_GETPID(), ss->fd, rv));
1248 return rv;
1252 ssl_SecureWrite(sslSocket *ss, const unsigned char *buf, int len)
1254 return ssl_SecureSend(ss, buf, len, 0);
1257 SECStatus
1258 SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg)
1260 sslSocket *ss;
1262 ss = ssl_FindSocket(fd);
1263 if (!ss) {
1264 SSL_DBG(("%d: SSL[%d]: bad socket in SSLBadCertHook",
1265 SSL_GETPID(), fd));
1266 return SECFailure;
1269 ss->handleBadCert = f;
1270 ss->badCertArg = arg;
1272 return SECSuccess;
1276 * Allow the application to pass the url or hostname into the SSL library
1277 * so that we can do some checking on it. It will be used for the value in
1278 * SNI extension of client hello message.
1280 SECStatus
1281 SSL_SetURL(PRFileDesc *fd, const char *url)
1283 sslSocket * ss = ssl_FindSocket(fd);
1284 SECStatus rv = SECSuccess;
1286 if (!ss) {
1287 SSL_DBG(("%d: SSL[%d]: bad socket in SSLSetURL",
1288 SSL_GETPID(), fd));
1289 return SECFailure;
1291 ssl_Get1stHandshakeLock(ss);
1292 ssl_GetSSL3HandshakeLock(ss);
1294 if ( ss->url ) {
1295 PORT_Free((void *)ss->url); /* CONST */
1298 ss->url = (const char *)PORT_Strdup(url);
1299 if ( ss->url == NULL ) {
1300 rv = SECFailure;
1303 ssl_ReleaseSSL3HandshakeLock(ss);
1304 ssl_Release1stHandshakeLock(ss);
1306 return rv;
1310 * Allow the application to pass the set of trust anchors
1312 SECStatus
1313 SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *certList)
1315 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
1316 PR_NOT_REACHED("not implemented");
1317 return SECFailure;
1318 #if 0
1319 sslSocket * ss = ssl_FindSocket(fd);
1320 CERTDistNames *names = NULL;
1322 if (!certList) {
1323 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1324 return SECFailure;
1326 if (!ss) {
1327 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetTrustAnchors",
1328 SSL_GETPID(), fd));
1329 return SECFailure;
1332 names = CERT_DistNamesFromCertList(certList);
1333 if (names == NULL) {
1334 return SECFailure;
1336 ssl_Get1stHandshakeLock(ss);
1337 ssl_GetSSL3HandshakeLock(ss);
1338 if (ss->ssl3.ca_list) {
1339 CERT_FreeDistNames(ss->ssl3.ca_list);
1341 ss->ssl3.ca_list = names;
1342 ssl_ReleaseSSL3HandshakeLock(ss);
1343 ssl_Release1stHandshakeLock(ss);
1345 return SECSuccess;
1346 #endif
1350 ** Returns Negative number on error, zero or greater on success.
1351 ** Returns the amount of data immediately available to be read.
1354 SSL_DataPending(PRFileDesc *fd)
1356 sslSocket *ss;
1357 int rv = 0;
1359 ss = ssl_FindSocket(fd);
1361 if (ss && ss->opt.useSecurity) {
1362 ssl_GetRecvBufLock(ss);
1363 rv = ss->gs.writeOffset - ss->gs.readOffset;
1364 ssl_ReleaseRecvBufLock(ss);
1367 return rv;
1370 SECStatus
1371 SSL_InvalidateSession(PRFileDesc *fd)
1373 sslSocket * ss = ssl_FindSocket(fd);
1374 SECStatus rv = SECFailure;
1376 if (ss) {
1377 ssl_Get1stHandshakeLock(ss);
1378 ssl_GetSSL3HandshakeLock(ss);
1380 if (ss->sec.ci.sid && ss->sec.uncache) {
1381 ss->sec.uncache(ss->sec.ci.sid);
1382 rv = SECSuccess;
1385 ssl_ReleaseSSL3HandshakeLock(ss);
1386 ssl_Release1stHandshakeLock(ss);
1388 return rv;
1391 SECItem *
1392 SSL_GetSessionID(PRFileDesc *fd)
1394 sslSocket * ss;
1395 SECItem * item = NULL;
1397 ss = ssl_FindSocket(fd);
1398 if (ss) {
1399 ssl_Get1stHandshakeLock(ss);
1400 ssl_GetSSL3HandshakeLock(ss);
1402 if (ss->opt.useSecurity && ss->firstHsDone && ss->sec.ci.sid) {
1403 item = (SECItem *)PORT_Alloc(sizeof(SECItem));
1404 if (item) {
1405 sslSessionID * sid = ss->sec.ci.sid;
1406 if (sid->version < SSL_LIBRARY_VERSION_3_0) {
1407 item->len = SSL2_SESSIONID_BYTES;
1408 item->data = (unsigned char*)PORT_Alloc(item->len);
1409 PORT_Memcpy(item->data, sid->u.ssl2.sessionID, item->len);
1410 } else {
1411 item->len = sid->u.ssl3.sessionIDLength;
1412 item->data = (unsigned char*)PORT_Alloc(item->len);
1413 PORT_Memcpy(item->data, sid->u.ssl3.sessionID, item->len);
1418 ssl_ReleaseSSL3HandshakeLock(ss);
1419 ssl_Release1stHandshakeLock(ss);
1421 return item;
1424 SECStatus
1425 SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle)
1427 sslSocket * ss;
1429 ss = ssl_FindSocket(fd);
1430 if (!ss)
1431 return SECFailure;
1432 if (!dbHandle) {
1433 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1434 return SECFailure;
1436 ss->dbHandle = dbHandle;
1437 return SECSuccess;
1441 * attempt to restart the handshake after asynchronously handling
1442 * a request for the client's certificate.
1444 * inputs:
1445 * cert Client cert chosen by application.
1446 * Note: ssl takes this reference, and does not bump the
1447 * reference count. The caller should drop its reference
1448 * without calling CERT_DestroyCertificate after calling this
1449 * function.
1451 * key Private key associated with cert. This function takes
1452 * ownership of the private key, so the caller should drop its
1453 * reference without destroying the private key after this
1454 * function returns.
1456 * certChain Chain of signers for cert.
1457 * Note: ssl takes this reference, and does not copy the chain.
1458 * The caller should drop its reference without destroying the
1459 * chain. SSL will free the chain when it is done with it.
1461 * Return value: XXX
1463 * XXX This code only works on the initial handshake on a connection, XXX
1464 * It does not work on a subsequent handshake (redo).
1466 SECStatus
1467 SSL_RestartHandshakeAfterCertReq(PRFileDesc * fd,
1468 CERTCertificate * cert,
1469 SECKEYPrivateKey * key,
1470 CERTCertificateList *certChain)
1472 sslSocket * ss = ssl_FindSocket(fd);
1473 SECStatus ret;
1475 if (!ss) {
1476 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RestartHandshakeAfterCertReq",
1477 SSL_GETPID(), fd));
1478 if (cert) {
1479 CERT_DestroyCertificate(cert);
1481 if (key) {
1482 SECKEY_DestroyPrivateKey(key);
1484 if (certChain) {
1485 CERT_DestroyCertificateList(certChain);
1487 return SECFailure;
1490 ssl_Get1stHandshakeLock(ss); /************************************/
1492 if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
1493 ret = ssl3_RestartHandshakeAfterCertReq(ss, cert, key, certChain);
1494 } else {
1495 if (certChain != NULL) {
1496 CERT_DestroyCertificateList(certChain);
1498 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
1499 ret = SECFailure;
1502 ssl_Release1stHandshakeLock(ss); /************************************/
1503 return ret;
1506 SECStatus
1507 SSL_RestartHandshakeAfterChannelIDReq(PRFileDesc * fd,
1508 SECKEYPublicKey * channelIDPub,
1509 SECKEYPrivateKey *channelID)
1511 sslSocket * ss = ssl_FindSocket(fd);
1512 SECStatus ret;
1514 if (!ss) {
1515 SSL_DBG(("%d: SSL[%d]: bad socket in"
1516 " SSL_RestartHandshakeAfterChannelIDReq",
1517 SSL_GETPID(), fd));
1518 goto loser;
1522 ssl_Get1stHandshakeLock(ss);
1524 if (ss->version < SSL_LIBRARY_VERSION_3_0) {
1525 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
1526 ssl_Release1stHandshakeLock(ss);
1527 goto loser;
1530 ret = ssl3_RestartHandshakeAfterChannelIDReq(ss, channelIDPub,
1531 channelID);
1532 ssl_Release1stHandshakeLock(ss);
1534 return ret;
1536 loser:
1537 SECKEY_DestroyPublicKey(channelIDPub);
1538 SECKEY_DestroyPrivateKey(channelID);
1539 return SECFailure;
1542 /* DO NOT USE. This function was exported in ssl.def with the wrong signature;
1543 * this implementation exists to maintain link-time compatibility.
1546 SSL_RestartHandshakeAfterServerCert(sslSocket * ss)
1548 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
1549 return -1;
1552 /* See documentation in ssl.h */
1553 SECStatus
1554 SSL_AuthCertificateComplete(PRFileDesc *fd, PRErrorCode error)
1556 SECStatus rv;
1557 sslSocket *ss = ssl_FindSocket(fd);
1559 if (!ss) {
1560 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_AuthCertificateComplete",
1561 SSL_GETPID(), fd));
1562 return SECFailure;
1565 ssl_Get1stHandshakeLock(ss);
1567 if (!ss->ssl3.initialized) {
1568 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1569 rv = SECFailure;
1570 } else if (ss->version < SSL_LIBRARY_VERSION_3_0) {
1571 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
1572 rv = SECFailure;
1573 } else {
1574 rv = ssl3_AuthCertificateComplete(ss, error);
1577 ssl_Release1stHandshakeLock(ss);
1579 return rv;
1582 /* For more info see ssl.h */
1583 SECStatus
1584 SSL_SNISocketConfigHook(PRFileDesc *fd, SSLSNISocketConfig func,
1585 void *arg)
1587 sslSocket *ss;
1589 ss = ssl_FindSocket(fd);
1590 if (!ss) {
1591 SSL_DBG(("%d: SSL[%d]: bad socket in SNISocketConfigHook",
1592 SSL_GETPID(), fd));
1593 return SECFailure;
1596 ss->sniSocketConfig = func;
1597 ss->sniSocketConfigArg = arg;
1598 return SECSuccess;