• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Various SSL functions.
3  *
4  * ***** BEGIN LICENSE BLOCK *****
5  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is the Netscape security libraries.
18  *
19  * The Initial Developer of the Original Code is
20  * Netscape Communications Corporation.
21  * Portions created by the Initial Developer are Copyright (C) 1994-2000
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *   Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
26  *
27  * Alternatively, the contents of this file may be used under the terms of
28  * either the GNU General Public License Version 2 or later (the "GPL"), or
29  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30  * in which case the provisions of the GPL or the LGPL are applicable instead
31  * of those above. If you wish to allow use of your version of this file only
32  * under the terms of either the GPL or the LGPL, and not to allow others to
33  * use your version of this file under the terms of the MPL, indicate your
34  * decision by deleting the provisions above and replace them with the notice
35  * and other provisions required by the GPL or the LGPL. If you do not delete
36  * the provisions above, a recipient may use your version of this file under
37  * the terms of any one of the MPL, the GPL or the LGPL.
38  *
39  * ***** END LICENSE BLOCK ***** */
40 /* $Id: sslsecur.c,v 1.42 2008/10/03 19:20:20 wtc%google.com Exp $ */
41 #include "cert.h"
42 #include "secitem.h"
43 #include "keyhi.h"
44 #include "ssl.h"
45 #include "sslimpl.h"
46 #include "sslproto.h"
47 #include "secoid.h"	/* for SECOID_GetALgorithmTag */
48 #include "pk11func.h"	/* for PK11_GenerateRandom */
49 #include "nss.h"        /* for NSS_RegisterShutdown */
50 #include "prinit.h"     /* for PR_CallOnceWithArg */
51 
52 #define MAX_BLOCK_CYPHER_SIZE	32
53 
54 #define TEST_FOR_FAILURE	/* reminder */
55 #define SET_ERROR_CODE		/* reminder */
56 
57 /* Returns a SECStatus: SECSuccess or SECFailure, NOT SECWouldBlock.
58  *
59  * Currently, the list of functions called through ss->handshake is:
60  *
61  * In sslsocks.c:
62  *  SocksGatherRecord
63  *  SocksHandleReply
64  *  SocksStartGather
65  *
66  * In sslcon.c:
67  *  ssl_GatherRecord1stHandshake
68  *  ssl2_HandleClientSessionKeyMessage
69  *  ssl2_HandleMessage
70  *  ssl2_HandleVerifyMessage
71  *  ssl2_BeginClientHandshake
72  *  ssl2_BeginServerHandshake
73  *  ssl2_HandleClientHelloMessage
74  *  ssl2_HandleServerHelloMessage
75  *
76  * The ss->handshake function returns SECWouldBlock under these conditions:
77  * 1.	ssl_GatherRecord1stHandshake called ssl2_GatherData which read in
78  *	the beginning of an SSL v3 hello message and returned SECWouldBlock
79  *	to switch to SSL v3 handshake processing.
80  *
81  * 2.	ssl2_HandleClientHelloMessage discovered version 3.0 in the incoming
82  *	v2 client hello msg, and called ssl3_HandleV2ClientHello which
83  *	returned SECWouldBlock.
84  *
85  * 3.   SECWouldBlock was returned by one of the callback functions, via
86  *	one of these paths:
87  * -	ssl2_HandleMessage() -> ssl2_HandleRequestCertificate() -> ss->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
ssl_Do1stHandshake(sslSocket * ss)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
AlwaysBlock(sslSocket * ss)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
ssl_SetAlwaysBlock(sslSocket * ss)183 ssl_SetAlwaysBlock(sslSocket *ss)
184 {
185     if (!ss->firstHsDone) {
186 	ss->handshake = AlwaysBlock;
187 	ss->nextHandshake = 0;
188     }
189 }
190 
191 static SECStatus
ssl_SetTimeout(PRFileDesc * fd,PRIntervalTime timeout)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
SSL_ResetHandshake(PRFileDesc * s,PRBool asServer)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
SSL_ReHandshake(PRFileDesc * fd,PRBool flushCache)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  */
SSL_ReHandshakeWithTimeout(PRFileDesc * fd,PRBool flushCache,PRIntervalTime timeout)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
SSL_RedoHandshake(PRFileDesc * fd)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
SSL_HandshakeCallback(PRFileDesc * fd,SSLHandshakeCallback cb,void * client_data)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
SSL_ForceHandshake(PRFileDesc * fd)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  */
SSL_ForceHandshakeWithTimeout(PRFileDesc * fd,PRIntervalTime timeout)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
sslBuffer_Grow(sslBuffer * b,unsigned int newLen)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
sslBuffer_Append(sslBuffer * b,const void * data,unsigned int len)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
ssl_SaveWriteData(sslSocket * ss,const void * data,unsigned int len)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
ssl_SendSavedWriteData(sslSocket * ss)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
DoRecv(sslSocket * ss,unsigned char * out,int len,int flags)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
ssl_FindCertKEAType(CERTCertificate * cert)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 
serverCAListShutdown(void * appData,void * nssData)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 
serverCAListSetup(void * arg)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
SSL_ConfigSecureServer(PRFileDesc * fd,CERTCertificate * cert,SECKEYPrivateKey * key,SSL3KEAType kea)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
ssl_CreateSecurityInfo(sslSocket * ss)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
ssl_CopySecurityInfo(sslSocket * ss,sslSocket * os)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
ssl_ResetSecurityInfo(sslSecurityInfo * sec,PRBool doMemset)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
ssl_DestroySecurityInfo(sslSecurityInfo * sec)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
ssl_SecureConnect(sslSocket * ss,const PRNetAddr * sa)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
ssl_SecureClose(sslSocket * ss)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
ssl_SecureShutdown(sslSocket * ss,int nsprHow)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
ssl_SecureRecv(sslSocket * ss,unsigned char * buf,int len,int flags)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
ssl_SecureRead(sslSocket * ss,unsigned char * buf,int len)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
ssl_SecureSend(sslSocket * ss,const unsigned char * buf,int len,int flags)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
ssl_SecureWrite(sslSocket * ss,const unsigned char * buf,int len)1219 ssl_SecureWrite(sslSocket *ss, const unsigned char *buf, int len)
1220 {
1221     return ssl_SecureSend(ss, buf, len, 0);
1222 }
1223 
1224 SECStatus
SSL_BadCertHook(PRFileDesc * fd,SSLBadCertHandler f,void * arg)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
SSL_SetURL(PRFileDesc * fd,const char * url)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
SSL_DataPending(PRFileDesc * fd)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
SSL_InvalidateSession(PRFileDesc * fd)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 *
SSL_GetSessionID(PRFileDesc * fd)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
SSL_CertDBHandleSet(PRFileDesc * fd,CERTCertDBHandle * dbHandle)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
SSL_RestartHandshakeAfterCertReq(sslSocket * ss,CERTCertificate * cert,SECKEYPrivateKey * key,CERTCertificateList * certChain)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
SSL_RestartHandshakeAfterServerCert(sslSocket * ss)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