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