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