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 $ */
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:
34 * ssl_GatherRecord1stHandshake
35 * ssl2_HandleClientSessionKeyMessage
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
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() ->
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.
79 ssl_Do1stHandshake(sslSocket
*ss
)
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;
120 rv
= (*ss
->handshake
)(ss
);
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
);
139 * Handshake function that blocks. Used to force a
140 * retry on a connection on the next read/write.
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
153 ssl3_SetAlwaysBlock(sslSocket
*ss
)
155 if (!ss
->firstHsDone
) {
156 ss
->handshake
= ssl3_AlwaysBlock
;
157 ss
->nextHandshake
= 0;
162 ssl_SetTimeout(PRFileDesc
*fd
, PRIntervalTime timeout
)
166 ss
= ssl_FindSocket(fd
);
168 SSL_DBG(("%d: SSL[%d]: bad socket in SetTimeout", SSL_GETPID(), fd
));
172 ss
->rTimeout
= timeout
;
176 ss
->wTimeout
= timeout
;
178 SSL_UNLOCK_WRITER(ss
);
180 SSL_UNLOCK_READER(ss
);
184 /* Acquires and releases HandshakeLock.
187 SSL_ResetHandshake(PRFileDesc
*s
, PRBool asServer
)
193 ss
= ssl_FindSocket(s
);
195 SSL_DBG(("%d: SSL[%d]: bad socket in ResetHandshake", SSL_GETPID(), s
));
199 /* Don't waste my time */
200 if (!ss
->opt
.useSecurity
)
206 /* Reset handshake state */
207 ssl_Get1stHandshakeLock(ss
);
209 ss
->firstHsDone
= PR_FALSE
;
211 ss
->handshake
= ssl2_BeginServerHandshake
;
212 ss
->handshaking
= sslHandshakingAsServer
;
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
);
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.
252 SSL_ReHandshake(PRFileDesc
*fd
, PRBool flushCache
)
257 ss
= ssl_FindSocket(fd
);
259 SSL_DBG(("%d: SSL[%d]: bad socket in RedoHandshake", SSL_GETPID(), fd
));
263 if (!ss
->opt
.useSecurity
)
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
);
273 ssl_GetSSL3HandshakeLock(ss
);
274 rv
= ssl3_RedoHandshake(ss
, flushCache
); /* force full handshake. */
275 ssl_ReleaseSSL3HandshakeLock(ss
);
278 ssl_Release1stHandshakeLock(ss
);
284 ** Same as above, but with an I/O timeout.
286 SSL_IMPORT SECStatus
SSL_ReHandshakeWithTimeout(PRFileDesc
*fd
,
288 PRIntervalTime timeout
)
290 if (SECSuccess
!= ssl_SetTimeout(fd
, timeout
)) {
293 return SSL_ReHandshake(fd
, flushCache
);
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.
306 SSL_HandshakeCallback(PRFileDesc
*fd
, SSLHandshakeCallback cb
,
311 ss
= ssl_FindSocket(fd
);
313 SSL_DBG(("%d: SSL[%d]: bad socket in HandshakeCallback",
318 if (!ss
->opt
.useSecurity
) {
319 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
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
);
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.
346 SSL_ForceHandshake(PRFileDesc
*fd
)
349 SECStatus rv
= SECFailure
;
351 ss
= ssl_FindSocket(fd
);
353 SSL_DBG(("%d: SSL[%d]: bad socket in ForceHandshake",
358 /* Don't waste my time */
359 if (!ss
->opt
.useSecurity
)
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
);
371 ssl_ReleaseXmitBufLock(ss
);
374 ssl_Get1stHandshakeLock(ss
);
376 if (ss
->version
>= SSL_LIBRARY_VERSION_3_0
) {
379 ssl_GetRecvBufLock(ss
);
380 gatherResult
= ssl3_GatherCompleteHandshake(ss
, 0);
381 ssl_ReleaseRecvBufLock(ss
);
382 if (gatherResult
> 0) {
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
);
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
);
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
)) {
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.
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
;
429 newBuf
= (unsigned char *) PORT_Realloc(b
->buf
, newLen
);
431 newBuf
= (unsigned char *) PORT_Alloc(newLen
);
436 SSL_TRC(10, ("%d: SSL: grow buffer from %d to %d",
437 SSL_GETPID(), b
->space
, newLen
));
445 sslBuffer_Append(sslBuffer
*b
, const void * data
, unsigned int len
)
447 unsigned int newLen
= b
->len
+ len
;
450 rv
= sslBuffer_Grow(b
, newLen
);
451 if (rv
!= SECSuccess
)
453 PORT_Memcpy(b
->buf
+ b
->len
, data
, len
);
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
465 ssl_SaveWriteData(sslSocket
*ss
, const void *data
, unsigned int len
)
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
));
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
483 ssl_SendSavedWriteData(sslSocket
*ss
)
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);
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
,
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
522 DoRecv(sslSocket
*ss
, unsigned char *out
, int len
, int flags
)
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);
537 /* See if we have a complete record */
538 rv
= ssl2_GatherRecord(ss
, 0);
543 SSL_TRC(10, ("%d: SSL[%d]: ssl_recv EOF",
544 SSL_GETPID(), ss
->fd
));
547 if ((rv
!= SECWouldBlock
) &&
548 (PR_GetError() != PR_WOULD_BLOCK_ERROR
)) {
549 /* Some random error */
554 ** Gather record is blocked waiting for more record data to
555 ** arrive. Try to process what we have already received
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
);
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
);
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
));
593 ssl_ReleaseRecvBufLock(ss
);
597 /************************************************************************/
600 ** Return SSLKEAType derived from cert's Public Key algorithm info.
603 NSS_FindCertKEAType(CERTCertificate
* cert
)
605 SSLKEAType keaType
= kt_null
;
608 if (!cert
) goto loser
;
610 tag
= SECOID_GetAlgorithmTag(&(cert
->subjectPublicKeyInfo
.algorithm
));
613 case SEC_OID_X500_RSA_ENCRYPTION
:
614 case SEC_OID_PKCS1_RSA_ENCRYPTION
:
617 case SEC_OID_X942_DIFFIE_HELMAN_KEY
:
620 #ifdef NSS_ENABLE_ECC
621 case SEC_OID_ANSIX962_EC_PUBLIC_KEY
:
624 #endif /* NSS_ENABLE_ECC */
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
;
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
);
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
;
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
);
685 CERT_CertChainFromCert(sc
->serverCert
, certUsageSSLServer
,
690 sc
->serverCertChain
= (certChain
) ? CERT_DupCertList(certChain
) :
692 if (!sc
->serverCertChain
) {
695 localCertChain
= NULL
; /* consumed */
699 if (sc
->serverKeyPair
!= NULL
) {
700 ssl3_FreeKeyPair(sc
->serverKeyPair
);
701 sc
->serverKeyPair
= NULL
;
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
) {
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
;
734 /* XXX need to protect the data that gets changed here.!! */
737 SSL_ConfigSecureServer(PRFileDesc
*fd
, CERTCertificate
*cert
,
738 SECKEYPrivateKey
*key
, SSL3KEAType kea
)
741 return SSL_ConfigSecureServerWithCertChain(fd
, cert
, NULL
, key
, kea
);
745 SSL_ConfigSecureServerWithCertChain(PRFileDesc
*fd
, CERTCertificate
*cert
,
746 const CERTCertificateList
*certChainOpt
,
747 SECKEYPrivateKey
*key
, SSL3KEAType kea
)
750 SECKEYPublicKey
*pubKey
= NULL
;
751 ssl3KeyPair
*keyPair
= NULL
;
752 SECStatus rv
= SECFailure
;
754 ss
= ssl_FindSocket(fd
);
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 */
763 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
767 /* make sure the key exchange is recognized */
768 if ((kea
>= kt_kea_size
) || (kea
< kt_null
)) {
769 PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG
);
773 if (kea
!= NSS_FindCertKEAType(cert
)) {
774 PORT_SetError(SSL_ERROR_CERT_KEA_MISMATCH
);
779 /* get the size of the cert's public key, and remember it */
780 pubKey
= CERT_ExtractPublicKey(cert
);
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
);
793 keyCopy
= PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot
, key
);
794 PK11_FreeSlot(bestSlot
);
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 */);
804 keyCopy
= PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot
, key
);
805 PK11_FreeSlot(bestSlot
);
809 keyCopy
= SECKEY_CopyPrivateKey(key
);
812 keyPair
= ssl3_NewKeyPair(keyCopy
, pubKey
);
813 if (keyPair
== NULL
) {
814 SECKEY_DestroyPrivateKey(keyCopy
);
817 pubKey
= NULL
; /* adopted by serverKeyPair */
819 if (ssl_ConfigSecureServer(ss
, cert
, certChainOpt
,
820 keyPair
, kea
) == SECFailure
) {
824 /* Only do this once because it's global. */
825 if (PR_SUCCESS
== PR_CallOnceWithArg(&setupServerCAListOnce
,
827 (void *)(ss
->dbHandle
))) {
833 ssl3_FreeKeyPair(keyPair
);
836 SECKEY_DestroyPublicKey(pubKey
);
842 /************************************************************************/
845 ssl_CreateSecurityInfo(sslSocket
*ss
)
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
);
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
)
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
)
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
)
895 SECITEM_CopyItem(0, &ss
->sec
.rcvSecret
, &os
->sec
.rcvSecret
);
896 if (os
->sec
.rcvSecret
.data
&& !ss
->sec
.rcvSecret
.data
)
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
;
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
;
918 /* Reset sec back to its initial state.
919 ** Caller holds any relevant locks.
922 ssl_ResetSecurityInfo(sslSecurityInfo
*sec
, PRBool doMemset
)
925 if (sec
->hash
&& sec
->hashcx
) {
926 (*sec
->hash
->destroy
)(sec
->hashcx
, PR_TRUE
);
930 SECITEM_ZfreeItem(&sec
->sendSecret
, PR_FALSE
);
931 SECITEM_ZfreeItem(&sec
->rcvSecret
, PR_FALSE
);
933 /* Destroy ciphers */
935 (*sec
->destroy
)(sec
->readcx
, PR_TRUE
);
936 (*sec
->destroy
)(sec
->writecx
, PR_TRUE
);
940 PORT_Assert(sec
->readcx
== 0);
941 PORT_Assert(sec
->writecx
== 0);
946 if (sec
->localCert
) {
947 CERT_DestroyCertificate(sec
->localCert
);
948 sec
->localCert
= NULL
;
951 CERT_DestroyCertificate(sec
->peerCert
);
952 sec
->peerCert
= NULL
;
955 SECKEY_DestroyPublicKey(sec
->peerKey
);
960 if (sec
->ci
.sid
!= NULL
) {
961 ssl_FreeSID(sec
->ci
.sid
);
963 PORT_ZFree(sec
->ci
.sendBuf
.buf
, sec
->ci
.sendBuf
.space
);
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)
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 /************************************************************************/
989 ssl_SecureConnect(sslSocket
*ss
, const PRNetAddr
*sa
)
991 PRFileDesc
*osfd
= ss
->fd
->lower
;
994 if ( ss
->opt
.handshakeAsServer
) {
995 ss
->securityHandshake
= ssl2_BeginServerHandshake
;
996 ss
->handshaking
= sslHandshakingAsServer
;
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;
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
));
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
)
1049 if (ss
->version
>= SSL_LIBRARY_VERSION_3_0
&&
1050 !(ss
->shutdownHow
& ssl_SHUTDOWN_SEND
) &&
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
);
1067 /* Caller handles all locking */
1069 ssl_SecureShutdown(sslSocket
*ss
, int nsprHow
)
1071 PRFileDesc
*osfd
= ss
->fd
->lower
;
1073 PRIntn sslHow
= nsprHow
+ 1;
1075 if ((unsigned)nsprHow
> PR_SHUTDOWN_BOTH
) {
1076 PORT_SetError(PR_INVALID_ARGUMENT_ERROR
);
1080 if ((sslHow
& ssl_SHUTDOWN_SEND
) != 0 &&
1081 ss
->version
>= SSL_LIBRARY_VERSION_3_0
&&
1082 !(ss
->shutdownHow
& ssl_SHUTDOWN_SEND
) &&
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
;
1097 /************************************************************************/
1101 ssl_SecureRecv(sslSocket
*ss
, unsigned char *buf
, int len
, int flags
)
1103 sslSecurityInfo
*sec
;
1108 if (ss
->shutdownHow
& ssl_SHUTDOWN_RCV
) {
1109 PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR
);
1112 if (flags
& ~PR_MSG_PEEK
) {
1113 PORT_SetError(PR_INVALID_ARGUMENT_ERROR
);
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
);
1126 ssl_ReleaseXmitBufLock(ss
);
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
);
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()));
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
)
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
);
1171 PORT_SetError(PR_INVALID_ARGUMENT_ERROR
);
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
);
1186 ssl_ReleaseXmitBufLock(ss
);
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
);
1214 ss
->writerThread
= NULL
;
1218 /* Check for zero length writes after we do housekeeping so we make forward
1225 PORT_Assert(buf
!= NULL
);
1227 PORT_SetError(PR_INVALID_ARGUMENT_ERROR
);
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
;
1242 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count, error %d",
1243 SSL_GETPID(), ss
->fd
, rv
, PORT_GetError()));
1245 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count",
1246 SSL_GETPID(), ss
->fd
, rv
));
1252 ssl_SecureWrite(sslSocket
*ss
, const unsigned char *buf
, int len
)
1254 return ssl_SecureSend(ss
, buf
, len
, 0);
1258 SSL_BadCertHook(PRFileDesc
*fd
, SSLBadCertHandler f
, void *arg
)
1262 ss
= ssl_FindSocket(fd
);
1264 SSL_DBG(("%d: SSL[%d]: bad socket in SSLBadCertHook",
1269 ss
->handleBadCert
= f
;
1270 ss
->badCertArg
= arg
;
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.
1281 SSL_SetURL(PRFileDesc
*fd
, const char *url
)
1283 sslSocket
* ss
= ssl_FindSocket(fd
);
1284 SECStatus rv
= SECSuccess
;
1287 SSL_DBG(("%d: SSL[%d]: bad socket in SSLSetURL",
1291 ssl_Get1stHandshakeLock(ss
);
1292 ssl_GetSSL3HandshakeLock(ss
);
1295 PORT_Free((void *)ss
->url
); /* CONST */
1298 ss
->url
= (const char *)PORT_Strdup(url
);
1299 if ( ss
->url
== NULL
) {
1303 ssl_ReleaseSSL3HandshakeLock(ss
);
1304 ssl_Release1stHandshakeLock(ss
);
1310 * Allow the application to pass the set of trust anchors
1313 SSL_SetTrustAnchors(PRFileDesc
*fd
, CERTCertList
*certList
)
1315 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR
);
1316 PR_NOT_REACHED("not implemented");
1319 sslSocket
* ss
= ssl_FindSocket(fd
);
1320 CERTDistNames
*names
= NULL
;
1323 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1327 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetTrustAnchors",
1332 names
= CERT_DistNamesFromCertList(certList
);
1333 if (names
== NULL
) {
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
);
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
)
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
);
1371 SSL_InvalidateSession(PRFileDesc
*fd
)
1373 sslSocket
* ss
= ssl_FindSocket(fd
);
1374 SECStatus rv
= SECFailure
;
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
);
1385 ssl_ReleaseSSL3HandshakeLock(ss
);
1386 ssl_Release1stHandshakeLock(ss
);
1392 SSL_GetSessionID(PRFileDesc
*fd
)
1395 SECItem
* item
= NULL
;
1397 ss
= ssl_FindSocket(fd
);
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
));
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
);
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
);
1425 SSL_CertDBHandleSet(PRFileDesc
*fd
, CERTCertDBHandle
*dbHandle
)
1429 ss
= ssl_FindSocket(fd
);
1433 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1436 ss
->dbHandle
= dbHandle
;
1441 * attempt to restart the handshake after asynchronously handling
1442 * a request for the client's certificate.
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
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
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.
1463 * XXX This code only works on the initial handshake on a connection, XXX
1464 * It does not work on a subsequent handshake (redo).
1467 SSL_RestartHandshakeAfterCertReq(PRFileDesc
* fd
,
1468 CERTCertificate
* cert
,
1469 SECKEYPrivateKey
* key
,
1470 CERTCertificateList
*certChain
)
1472 sslSocket
* ss
= ssl_FindSocket(fd
);
1476 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RestartHandshakeAfterCertReq",
1479 CERT_DestroyCertificate(cert
);
1482 SECKEY_DestroyPrivateKey(key
);
1485 CERT_DestroyCertificateList(certChain
);
1490 ssl_Get1stHandshakeLock(ss
); /************************************/
1492 if (ss
->version
>= SSL_LIBRARY_VERSION_3_0
) {
1493 ret
= ssl3_RestartHandshakeAfterCertReq(ss
, cert
, key
, certChain
);
1495 if (certChain
!= NULL
) {
1496 CERT_DestroyCertificateList(certChain
);
1498 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2
);
1502 ssl_Release1stHandshakeLock(ss
); /************************************/
1507 SSL_RestartHandshakeAfterChannelIDReq(PRFileDesc
* fd
,
1508 SECKEYPublicKey
* channelIDPub
,
1509 SECKEYPrivateKey
*channelID
)
1511 sslSocket
* ss
= ssl_FindSocket(fd
);
1515 SSL_DBG(("%d: SSL[%d]: bad socket in"
1516 " SSL_RestartHandshakeAfterChannelIDReq",
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
);
1530 ret
= ssl3_RestartHandshakeAfterChannelIDReq(ss
, channelIDPub
,
1532 ssl_Release1stHandshakeLock(ss
);
1537 SECKEY_DestroyPublicKey(channelIDPub
);
1538 SECKEY_DestroyPrivateKey(channelID
);
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
);
1552 /* See documentation in ssl.h */
1554 SSL_AuthCertificateComplete(PRFileDesc
*fd
, PRErrorCode error
)
1557 sslSocket
*ss
= ssl_FindSocket(fd
);
1560 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_AuthCertificateComplete",
1565 ssl_Get1stHandshakeLock(ss
);
1567 if (!ss
->ssl3
.initialized
) {
1568 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1570 } else if (ss
->version
< SSL_LIBRARY_VERSION_3_0
) {
1571 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2
);
1574 rv
= ssl3_AuthCertificateComplete(ss
, error
);
1577 ssl_Release1stHandshakeLock(ss
);
1582 /* For more info see ssl.h */
1584 SSL_SNISocketConfigHook(PRFileDesc
*fd
, SSLSNISocketConfig func
,
1589 ss
= ssl_FindSocket(fd
);
1591 SSL_DBG(("%d: SSL[%d]: bad socket in SNISocketConfigHook",
1596 ss
->sniSocketConfig
= func
;
1597 ss
->sniSocketConfigArg
= arg
;