Home | History | Annotate | Download | only in ssl
      1 /*
      2  * SSL v2 handshake functions, and functions common to SSL2 and SSL3.
      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: sslcon.c,v 1.37 2009/10/16 17:45:35 wtc%google.com Exp $ */
     41 
     42 #include "nssrenam.h"
     43 #include "cert.h"
     44 #include "secitem.h"
     45 #include "sechash.h"
     46 #include "cryptohi.h"		/* for SGN_ funcs */
     47 #include "keyhi.h" 		/* for SECKEY_ high level functions. */
     48 #include "ssl.h"
     49 #include "sslimpl.h"
     50 #include "sslproto.h"
     51 #include "ssl3prot.h"
     52 #include "sslerr.h"
     53 #include "pk11func.h"
     54 #include "prinit.h"
     55 #include "prtime.h" 	/* for PR_Now() */
     56 
     57 #define XXX
     58 static PRBool policyWasSet;
     59 
     60 /* This ordered list is indexed by (SSL_CK_xx * 3)   */
     61 /* Second and third bytes are MSB and LSB of master key length. */
     62 static const PRUint8 allCipherSuites[] = {
     63     0,						0,    0,
     64     SSL_CK_RC4_128_WITH_MD5,			0x00, 0x80,
     65     SSL_CK_RC4_128_EXPORT40_WITH_MD5,		0x00, 0x80,
     66     SSL_CK_RC2_128_CBC_WITH_MD5,		0x00, 0x80,
     67     SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5,	0x00, 0x80,
     68     SSL_CK_IDEA_128_CBC_WITH_MD5,		0x00, 0x80,
     69     SSL_CK_DES_64_CBC_WITH_MD5,			0x00, 0x40,
     70     SSL_CK_DES_192_EDE3_CBC_WITH_MD5,		0x00, 0xC0,
     71     0,						0,    0
     72 };
     73 
     74 #define ssl2_NUM_SUITES_IMPLEMENTED 6
     75 
     76 /* This list is sent back to the client when the client-hello message
     77  * contains no overlapping ciphers, so the client can report what ciphers
     78  * are supported by the server.  Unlike allCipherSuites (above), this list
     79  * is sorted by descending preference, not by cipherSuite number.
     80  */
     81 static const PRUint8 implementedCipherSuites[ssl2_NUM_SUITES_IMPLEMENTED * 3] = {
     82     SSL_CK_RC4_128_WITH_MD5,			0x00, 0x80,
     83     SSL_CK_RC2_128_CBC_WITH_MD5,		0x00, 0x80,
     84     SSL_CK_DES_192_EDE3_CBC_WITH_MD5,		0x00, 0xC0,
     85     SSL_CK_DES_64_CBC_WITH_MD5,			0x00, 0x40,
     86     SSL_CK_RC4_128_EXPORT40_WITH_MD5,		0x00, 0x80,
     87     SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5,	0x00, 0x80
     88 };
     89 
     90 typedef struct ssl2SpecsStr {
     91     PRUint8           nkm; /* do this many hashes to generate key material. */
     92     PRUint8           nkd; /* size of readKey and writeKey in bytes. */
     93     PRUint8           blockSize;
     94     PRUint8           blockShift;
     95     CK_MECHANISM_TYPE mechanism;
     96     PRUint8           keyLen;	/* cipher symkey size in bytes. */
     97     PRUint8           pubLen;	/* publicly reveal this many bytes of key. */
     98     PRUint8           ivLen;	/* length of IV data at *ca.	*/
     99 } ssl2Specs;
    100 
    101 static const ssl2Specs ssl_Specs[] = {
    102 /* NONE                                 */
    103 				{  0,  0, 0, 0, },
    104 /* SSL_CK_RC4_128_WITH_MD5		*/
    105 				{  2, 16, 1, 0, CKM_RC4,       16,   0, 0, },
    106 /* SSL_CK_RC4_128_EXPORT40_WITH_MD5	*/
    107 				{  2, 16, 1, 0, CKM_RC4,       16,  11, 0, },
    108 /* SSL_CK_RC2_128_CBC_WITH_MD5		*/
    109 				{  2, 16, 8, 3, CKM_RC2_CBC,   16,   0, 8, },
    110 /* SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5	*/
    111 				{  2, 16, 8, 3, CKM_RC2_CBC,   16,  11, 8, },
    112 /* SSL_CK_IDEA_128_CBC_WITH_MD5		*/
    113 				{  0,  0, 0, 0, },
    114 /* SSL_CK_DES_64_CBC_WITH_MD5		*/
    115 				{  1,  8, 8, 3, CKM_DES_CBC,    8,   0, 8, },
    116 /* SSL_CK_DES_192_EDE3_CBC_WITH_MD5	*/
    117 				{  3, 24, 8, 3, CKM_DES3_CBC,  24,   0, 8, },
    118 };
    119 
    120 #define SET_ERROR_CODE	  /* reminder */
    121 #define TEST_FOR_FAILURE  /* reminder */
    122 
    123 /*
    124 ** Put a string tag in the library so that we can examine an executable
    125 ** and see what kind of security it supports.
    126 */
    127 const char *ssl_version = "SECURITY_VERSION:"
    128 			" +us"
    129 			" +export"
    130 #ifdef TRACE
    131 			" +trace"
    132 #endif
    133 #ifdef DEBUG
    134 			" +debug"
    135 #endif
    136 			;
    137 
    138 const char * const ssl_cipherName[] = {
    139     "unknown",
    140     "RC4",
    141     "RC4-Export",
    142     "RC2-CBC",
    143     "RC2-CBC-Export",
    144     "IDEA-CBC",
    145     "DES-CBC",
    146     "DES-EDE3-CBC",
    147     "unknown",
    148     "unknown", /* was fortezza, NO LONGER USED */
    149 };
    150 
    151 
    152 /* bit-masks, showing which SSLv2 suites are allowed.
    153  * lsb corresponds to first cipher suite in allCipherSuites[].
    154  */
    155 static PRUint16	allowedByPolicy;          /* all off by default */
    156 static PRUint16	maybeAllowedByPolicy;     /* all off by default */
    157 static PRUint16	chosenPreference = 0xff;  /* all on  by default */
    158 
    159 /* bit values for the above two bit masks */
    160 #define SSL_CB_RC4_128_WITH_MD5              (1 << SSL_CK_RC4_128_WITH_MD5)
    161 #define SSL_CB_RC4_128_EXPORT40_WITH_MD5     (1 << SSL_CK_RC4_128_EXPORT40_WITH_MD5)
    162 #define SSL_CB_RC2_128_CBC_WITH_MD5          (1 << SSL_CK_RC2_128_CBC_WITH_MD5)
    163 #define SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)
    164 #define SSL_CB_IDEA_128_CBC_WITH_MD5         (1 << SSL_CK_IDEA_128_CBC_WITH_MD5)
    165 #define SSL_CB_DES_64_CBC_WITH_MD5           (1 << SSL_CK_DES_64_CBC_WITH_MD5)
    166 #define SSL_CB_DES_192_EDE3_CBC_WITH_MD5     (1 << SSL_CK_DES_192_EDE3_CBC_WITH_MD5)
    167 #define SSL_CB_IMPLEMENTED \
    168    (SSL_CB_RC4_128_WITH_MD5              | \
    169     SSL_CB_RC4_128_EXPORT40_WITH_MD5     | \
    170     SSL_CB_RC2_128_CBC_WITH_MD5          | \
    171     SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 | \
    172     SSL_CB_DES_64_CBC_WITH_MD5           | \
    173     SSL_CB_DES_192_EDE3_CBC_WITH_MD5)
    174 
    175 
    176 /* Construct a socket's list of cipher specs from the global default values.
    177  */
    178 static SECStatus
    179 ssl2_ConstructCipherSpecs(sslSocket *ss)
    180 {
    181     PRUint8 *	        cs		= NULL;
    182     unsigned int	allowed;
    183     unsigned int	count;
    184     int 		ssl3_count	= 0;
    185     int 		final_count;
    186     int 		i;
    187     SECStatus 		rv;
    188 
    189     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    190 
    191     count = 0;
    192     PORT_Assert(ss != 0);
    193     allowed = !ss->opt.enableSSL2 ? 0 :
    194     	(ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED);
    195     while (allowed) {
    196     	if (allowed & 1)
    197 	    ++count;
    198 	allowed >>= 1;
    199     }
    200 
    201     /* Call ssl3_config_match_init() once here,
    202      * instead of inside ssl3_ConstructV2CipherSpecsHack(),
    203      * because the latter gets called twice below,
    204      * and then again in ssl2_BeginClientHandshake().
    205      */
    206     ssl3_config_match_init(ss);
    207 
    208     /* ask SSL3 how many cipher suites it has. */
    209     rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3_count);
    210     if (rv < 0)
    211 	return rv;
    212     count += ssl3_count;
    213 
    214     /* Allocate memory to hold cipher specs */
    215     if (count > 0)
    216 	cs = (PRUint8*) PORT_Alloc(count * 3);
    217     else
    218 	PORT_SetError(SSL_ERROR_SSL_DISABLED);
    219     if (cs == NULL)
    220     	return SECFailure;
    221 
    222     if (ss->cipherSpecs != NULL) {
    223 	PORT_Free(ss->cipherSpecs);
    224     }
    225     ss->cipherSpecs     = cs;
    226     ss->sizeCipherSpecs = count * 3;
    227 
    228     /* fill in cipher specs for SSL2 cipher suites */
    229     allowed = !ss->opt.enableSSL2 ? 0 :
    230     	(ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED);
    231     for (i = 0; i < ssl2_NUM_SUITES_IMPLEMENTED * 3; i += 3) {
    232 	const PRUint8 * hs = implementedCipherSuites + i;
    233 	int             ok = allowed & (1U << hs[0]);
    234 	if (ok) {
    235 	    cs[0] = hs[0];
    236 	    cs[1] = hs[1];
    237 	    cs[2] = hs[2];
    238 	    cs += 3;
    239 	}
    240     }
    241 
    242     /* now have SSL3 add its suites onto the end */
    243     rv = ssl3_ConstructV2CipherSpecsHack(ss, cs, &final_count);
    244 
    245     /* adjust for any difference between first pass and second pass */
    246     ss->sizeCipherSpecs -= (ssl3_count - final_count) * 3;
    247 
    248     return rv;
    249 }
    250 
    251 /* This function is called immediately after ssl2_ConstructCipherSpecs()
    252 ** at the beginning of a handshake.  It detects cases where a protocol
    253 ** (e.g. SSL2 or SSL3) is logically enabled, but all its cipher suites
    254 ** for that protocol have been disabled.  If such cases, it clears the
    255 ** enable bit for the protocol.  If no protocols remain enabled, or
    256 ** if no cipher suites are found, it sets the error code and returns
    257 ** SECFailure, otherwise it returns SECSuccess.
    258 */
    259 static SECStatus
    260 ssl2_CheckConfigSanity(sslSocket *ss)
    261 {
    262     unsigned int      allowed;
    263     int               ssl3CipherCount = 0;
    264     SECStatus         rv;
    265 
    266     /* count the SSL2 and SSL3 enabled ciphers.
    267      * if either is zero, clear the socket's enable for that protocol.
    268      */
    269     if (!ss->cipherSpecs)
    270     	goto disabled;
    271 
    272     allowed = ss->allowedByPolicy & ss->chosenPreference;
    273     if (! allowed)
    274 	ss->opt.enableSSL2 = PR_FALSE; /* not really enabled if no ciphers */
    275 
    276     /* ssl3_config_match_init was called in ssl2_ConstructCipherSpecs(). */
    277     /* Ask how many ssl3 CipherSuites were enabled. */
    278     rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3CipherCount);
    279     if (rv != SECSuccess || ssl3CipherCount <= 0) {
    280 	ss->opt.enableSSL3 = PR_FALSE; /* not really enabled if no ciphers */
    281 	ss->opt.enableTLS  = PR_FALSE;
    282     }
    283 
    284     if (!ss->opt.enableSSL2 && !ss->opt.enableSSL3 && !ss->opt.enableTLS) {
    285 	SSL_DBG(("%d: SSL[%d]: Can't handshake! both v2 and v3 disabled.",
    286 		 SSL_GETPID(), ss->fd));
    287 disabled:
    288 	PORT_SetError(SSL_ERROR_SSL_DISABLED);
    289 	return SECFailure;
    290     }
    291     return SECSuccess;
    292 }
    293 
    294 /*
    295  * Since this is a global (not per-socket) setting, we cannot use the
    296  * HandshakeLock to protect this.  Probably want a global lock.
    297  */
    298 SECStatus
    299 ssl2_SetPolicy(PRInt32 which, PRInt32 policy)
    300 {
    301     PRUint32  bitMask;
    302     SECStatus rv       = SECSuccess;
    303 
    304     which &= 0x000f;
    305     bitMask = 1 << which;
    306 
    307     if (!(bitMask & SSL_CB_IMPLEMENTED)) {
    308     	PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
    309     	return SECFailure;
    310     }
    311 
    312     if (policy == SSL_ALLOWED) {
    313 	allowedByPolicy 	|= bitMask;
    314 	maybeAllowedByPolicy 	|= bitMask;
    315     } else if (policy == SSL_RESTRICTED) {
    316     	allowedByPolicy 	&= ~bitMask;
    317 	maybeAllowedByPolicy 	|= bitMask;
    318     } else {
    319     	allowedByPolicy 	&= ~bitMask;
    320     	maybeAllowedByPolicy 	&= ~bitMask;
    321     }
    322     allowedByPolicy 		&= SSL_CB_IMPLEMENTED;
    323     maybeAllowedByPolicy 	&= SSL_CB_IMPLEMENTED;
    324 
    325     policyWasSet = PR_TRUE;
    326     return rv;
    327 }
    328 
    329 SECStatus
    330 ssl2_GetPolicy(PRInt32 which, PRInt32 *oPolicy)
    331 {
    332     PRUint32     bitMask;
    333     PRInt32      policy;
    334 
    335     which &= 0x000f;
    336     bitMask = 1 << which;
    337 
    338     /* Caller assures oPolicy is not null. */
    339     if (!(bitMask & SSL_CB_IMPLEMENTED)) {
    340     	PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
    341 	*oPolicy = SSL_NOT_ALLOWED;
    342     	return SECFailure;
    343     }
    344 
    345     if (maybeAllowedByPolicy & bitMask) {
    346     	policy = (allowedByPolicy & bitMask) ? SSL_ALLOWED : SSL_RESTRICTED;
    347     } else {
    348 	policy = SSL_NOT_ALLOWED;
    349     }
    350 
    351     *oPolicy = policy;
    352     return SECSuccess;
    353 }
    354 
    355 /*
    356  * Since this is a global (not per-socket) setting, we cannot use the
    357  * HandshakeLock to protect this.  Probably want a global lock.
    358  * Called from SSL_CipherPrefSetDefault in sslsock.c
    359  * These changes have no effect on any sslSockets already created.
    360  */
    361 SECStatus
    362 ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
    363 {
    364     PRUint32     bitMask;
    365 
    366     which &= 0x000f;
    367     bitMask = 1 << which;
    368 
    369     if (!(bitMask & SSL_CB_IMPLEMENTED)) {
    370     	PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
    371     	return SECFailure;
    372     }
    373 
    374     if (enabled)
    375 	chosenPreference |= bitMask;
    376     else
    377     	chosenPreference &= ~bitMask;
    378     chosenPreference &= SSL_CB_IMPLEMENTED;
    379 
    380     return SECSuccess;
    381 }
    382 
    383 SECStatus
    384 ssl2_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
    385 {
    386     PRBool       rv       = PR_FALSE;
    387     PRUint32     bitMask;
    388 
    389     which &= 0x000f;
    390     bitMask = 1 << which;
    391 
    392     if (!(bitMask & SSL_CB_IMPLEMENTED)) {
    393     	PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
    394 	*enabled = PR_FALSE;
    395     	return SECFailure;
    396     }
    397 
    398     rv = (PRBool)((chosenPreference & bitMask) != 0);
    399     *enabled = rv;
    400     return SECSuccess;
    401 }
    402 
    403 SECStatus
    404 ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled)
    405 {
    406     PRUint32     bitMask;
    407 
    408     which &= 0x000f;
    409     bitMask = 1 << which;
    410 
    411     if (!(bitMask & SSL_CB_IMPLEMENTED)) {
    412     	PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
    413     	return SECFailure;
    414     }
    415 
    416     if (enabled)
    417 	ss->chosenPreference |= bitMask;
    418     else
    419     	ss->chosenPreference &= ~bitMask;
    420     ss->chosenPreference &= SSL_CB_IMPLEMENTED;
    421 
    422     return SECSuccess;
    423 }
    424 
    425 SECStatus
    426 ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled)
    427 {
    428     PRBool       rv       = PR_FALSE;
    429     PRUint32     bitMask;
    430 
    431     which &= 0x000f;
    432     bitMask = 1 << which;
    433 
    434     if (!(bitMask & SSL_CB_IMPLEMENTED)) {
    435     	PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
    436 	*enabled = PR_FALSE;
    437     	return SECFailure;
    438     }
    439 
    440     rv = (PRBool)((ss->chosenPreference & bitMask) != 0);
    441     *enabled = rv;
    442     return SECSuccess;
    443 }
    444 
    445 
    446 /* copy global default policy into socket. */
    447 void
    448 ssl2_InitSocketPolicy(sslSocket *ss)
    449 {
    450     ss->allowedByPolicy		= allowedByPolicy;
    451     ss->maybeAllowedByPolicy	= maybeAllowedByPolicy;
    452     ss->chosenPreference 	= chosenPreference;
    453 }
    454 
    455 
    456 /************************************************************************/
    457 
    458 /* Called from ssl2_CreateSessionCypher(), which already holds handshake lock.
    459  */
    460 static SECStatus
    461 ssl2_CreateMAC(sslSecurityInfo *sec, SECItem *readKey, SECItem *writeKey,
    462           int cipherChoice)
    463 {
    464     switch (cipherChoice) {
    465 
    466       case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
    467       case SSL_CK_RC2_128_CBC_WITH_MD5:
    468       case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
    469       case SSL_CK_RC4_128_WITH_MD5:
    470       case SSL_CK_DES_64_CBC_WITH_MD5:
    471       case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
    472 	sec->hash = HASH_GetHashObject(HASH_AlgMD5);
    473 	SECITEM_CopyItem(0, &sec->sendSecret, writeKey);
    474 	SECITEM_CopyItem(0, &sec->rcvSecret, readKey);
    475 	break;
    476 
    477       default:
    478 	PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
    479 	return SECFailure;
    480     }
    481     sec->hashcx = (*sec->hash->create)();
    482     if (sec->hashcx == NULL)
    483 	return SECFailure;
    484     return SECSuccess;
    485 }
    486 
    487 /************************************************************************
    488  * All the Send functions below must acquire and release the socket's
    489  * xmitBufLock.
    490  */
    491 
    492 /* Called from all the Send* functions below. */
    493 static SECStatus
    494 ssl2_GetSendBuffer(sslSocket *ss, unsigned int len)
    495 {
    496     SECStatus rv = SECSuccess;
    497 
    498     PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
    499 
    500     if (len < 128) {
    501 	len = 128;
    502     }
    503     if (len > ss->sec.ci.sendBuf.space) {
    504 	rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, len);
    505 	if (rv != SECSuccess) {
    506 	    SSL_DBG(("%d: SSL[%d]: ssl2_GetSendBuffer failed, tried to get %d bytes",
    507 		     SSL_GETPID(), ss->fd, len));
    508 	    rv = SECFailure;
    509 	}
    510     }
    511     return rv;
    512 }
    513 
    514 /* Called from:
    515  * ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
    516  * ssl2_HandleRequestCertificate()     <- ssl2_HandleMessage() <-
    517  					ssl_Do1stHandshake()
    518  * ssl2_HandleMessage()                <- ssl_Do1stHandshake()
    519  * ssl2_HandleServerHelloMessage() <- ssl_Do1stHandshake()
    520                                      after ssl2_BeginClientHandshake()
    521  * ssl2_RestartHandshakeAfterCertReq() <- Called from certdlgs.c in nav.
    522  * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake()
    523                                      after ssl2_BeginServerHandshake()
    524  *
    525  * Acquires and releases the socket's xmitBufLock.
    526  */
    527 int
    528 ssl2_SendErrorMessage(sslSocket *ss, int error)
    529 {
    530     int rv;
    531     PRUint8 msg[SSL_HL_ERROR_HBYTES];
    532 
    533     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    534 
    535     msg[0] = SSL_MT_ERROR;
    536     msg[1] = MSB(error);
    537     msg[2] = LSB(error);
    538 
    539     ssl_GetXmitBufLock(ss);    /***************************************/
    540 
    541     SSL_TRC(3, ("%d: SSL[%d]: sending error %d", SSL_GETPID(), ss->fd, error));
    542 
    543     ss->handshakeBegun = 1;
    544     rv = (*ss->sec.send)(ss, msg, sizeof(msg), 0);
    545     if (rv >= 0) {
    546 	rv = SECSuccess;
    547     }
    548     ssl_ReleaseXmitBufLock(ss);    /***************************************/
    549     return rv;
    550 }
    551 
    552 /* Called from ssl2_TryToFinish().
    553  * Acquires and releases the socket's xmitBufLock.
    554  */
    555 static SECStatus
    556 ssl2_SendClientFinishedMessage(sslSocket *ss)
    557 {
    558     SECStatus        rv    = SECSuccess;
    559     int              sent;
    560     PRUint8    msg[1 + SSL_CONNECTIONID_BYTES];
    561 
    562     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    563 
    564     ssl_GetXmitBufLock(ss);    /***************************************/
    565 
    566     if (ss->sec.ci.sentFinished == 0) {
    567 	ss->sec.ci.sentFinished = 1;
    568 
    569 	SSL_TRC(3, ("%d: SSL[%d]: sending client-finished",
    570 		    SSL_GETPID(), ss->fd));
    571 
    572 	msg[0] = SSL_MT_CLIENT_FINISHED;
    573 	PORT_Memcpy(msg+1, ss->sec.ci.connectionID,
    574 	            sizeof(ss->sec.ci.connectionID));
    575 
    576 	DUMP_MSG(29, (ss, msg, 1 + sizeof(ss->sec.ci.connectionID)));
    577 	sent = (*ss->sec.send)(ss, msg, 1 + sizeof(ss->sec.ci.connectionID), 0);
    578 	rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
    579     }
    580     ssl_ReleaseXmitBufLock(ss);    /***************************************/
    581     return rv;
    582 }
    583 
    584 /* Called from
    585  * ssl2_HandleClientSessionKeyMessage() <- ssl2_HandleClientHelloMessage()
    586  * ssl2_HandleClientHelloMessage()  <- ssl_Do1stHandshake()
    587                                       after ssl2_BeginServerHandshake()
    588  * Acquires and releases the socket's xmitBufLock.
    589  */
    590 static SECStatus
    591 ssl2_SendServerVerifyMessage(sslSocket *ss)
    592 {
    593     PRUint8 *        msg;
    594     int              sendLen;
    595     int              sent;
    596     SECStatus        rv;
    597 
    598     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    599 
    600     ssl_GetXmitBufLock(ss);    /***************************************/
    601 
    602     sendLen = 1 + SSL_CHALLENGE_BYTES;
    603     rv = ssl2_GetSendBuffer(ss, sendLen);
    604     if (rv != SECSuccess) {
    605 	goto done;
    606     }
    607 
    608     msg = ss->sec.ci.sendBuf.buf;
    609     msg[0] = SSL_MT_SERVER_VERIFY;
    610     PORT_Memcpy(msg+1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
    611 
    612     DUMP_MSG(29, (ss, msg, sendLen));
    613     sent = (*ss->sec.send)(ss, msg, sendLen, 0);
    614 
    615     rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
    616 
    617 done:
    618     ssl_ReleaseXmitBufLock(ss);    /***************************************/
    619     return rv;
    620 }
    621 
    622 /* Called from ssl2_TryToFinish().
    623  * Acquires and releases the socket's xmitBufLock.
    624  */
    625 static SECStatus
    626 ssl2_SendServerFinishedMessage(sslSocket *ss)
    627 {
    628     sslSessionID *   sid;
    629     PRUint8 *        msg;
    630     int              sendLen, sent;
    631     SECStatus        rv    = SECSuccess;
    632 
    633     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    634 
    635     ssl_GetXmitBufLock(ss);    /***************************************/
    636 
    637     if (ss->sec.ci.sentFinished == 0) {
    638 	ss->sec.ci.sentFinished = 1;
    639 	PORT_Assert(ss->sec.ci.sid != 0);
    640 	sid = ss->sec.ci.sid;
    641 
    642 	SSL_TRC(3, ("%d: SSL[%d]: sending server-finished",
    643 		    SSL_GETPID(), ss->fd));
    644 
    645 	sendLen = 1 + sizeof(sid->u.ssl2.sessionID);
    646 	rv = ssl2_GetSendBuffer(ss, sendLen);
    647 	if (rv != SECSuccess) {
    648 	    goto done;
    649 	}
    650 
    651 	msg = ss->sec.ci.sendBuf.buf;
    652 	msg[0] = SSL_MT_SERVER_FINISHED;
    653 	PORT_Memcpy(msg+1, sid->u.ssl2.sessionID,
    654 		    sizeof(sid->u.ssl2.sessionID));
    655 
    656 	DUMP_MSG(29, (ss, msg, sendLen));
    657 	sent = (*ss->sec.send)(ss, msg, sendLen, 0);
    658 
    659 	if (sent < 0) {
    660 	    /* If send failed, it is now a bogus  session-id */
    661 	    (*ss->sec.uncache)(sid);
    662 	    rv = (SECStatus)sent;
    663 	} else if (!ss->opt.noCache) {
    664 	    /* Put the sid in session-id cache, (may already be there) */
    665 	    (*ss->sec.cache)(sid);
    666 	    rv = SECSuccess;
    667 	}
    668 	ssl_FreeSID(sid);
    669 	ss->sec.ci.sid = 0;
    670     }
    671 done:
    672     ssl_ReleaseXmitBufLock(ss);    /***************************************/
    673     return rv;
    674 }
    675 
    676 /* Called from ssl2_ClientSetupSessionCypher() <-
    677  *						ssl2_HandleServerHelloMessage()
    678  *                                           after ssl2_BeginClientHandshake()
    679  * Acquires and releases the socket's xmitBufLock.
    680  */
    681 static SECStatus
    682 ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize,
    683 		      PRUint8 *ca, int caLen,
    684 		      PRUint8 *ck, int ckLen,
    685 		      PRUint8 *ek, int ekLen)
    686 {
    687     PRUint8 *        msg;
    688     int              sendLen;
    689     int              sent;
    690     SECStatus        rv;
    691 
    692     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    693 
    694     ssl_GetXmitBufLock(ss);    /***************************************/
    695 
    696     sendLen = SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen;
    697     rv = ssl2_GetSendBuffer(ss, sendLen);
    698     if (rv != SECSuccess)
    699 	goto done;
    700 
    701     SSL_TRC(3, ("%d: SSL[%d]: sending client-session-key",
    702 		SSL_GETPID(), ss->fd));
    703 
    704     msg = ss->sec.ci.sendBuf.buf;
    705     msg[0] = SSL_MT_CLIENT_MASTER_KEY;
    706     msg[1] = cipher;
    707     msg[2] = MSB(keySize);
    708     msg[3] = LSB(keySize);
    709     msg[4] = MSB(ckLen);
    710     msg[5] = LSB(ckLen);
    711     msg[6] = MSB(ekLen);
    712     msg[7] = LSB(ekLen);
    713     msg[8] = MSB(caLen);
    714     msg[9] = LSB(caLen);
    715     PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES, ck, ckLen);
    716     PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen, ek, ekLen);
    717     PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen+ekLen, ca, caLen);
    718 
    719     DUMP_MSG(29, (ss, msg, sendLen));
    720     sent = (*ss->sec.send)(ss, msg, sendLen, 0);
    721     rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
    722 done:
    723     ssl_ReleaseXmitBufLock(ss);    /***************************************/
    724     return rv;
    725 }
    726 
    727 /* Called from ssl2_TriggerNextMessage() <- ssl2_HandleMessage()
    728  * Acquires and releases the socket's xmitBufLock.
    729  */
    730 static SECStatus
    731 ssl2_SendCertificateRequestMessage(sslSocket *ss)
    732 {
    733     PRUint8 *        msg;
    734     int              sent;
    735     int              sendLen;
    736     SECStatus        rv;
    737 
    738     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    739 
    740     ssl_GetXmitBufLock(ss);    /***************************************/
    741 
    742     sendLen = SSL_HL_REQUEST_CERTIFICATE_HBYTES + SSL_CHALLENGE_BYTES;
    743     rv = ssl2_GetSendBuffer(ss, sendLen);
    744     if (rv != SECSuccess)
    745 	goto done;
    746 
    747     SSL_TRC(3, ("%d: SSL[%d]: sending certificate request",
    748 		SSL_GETPID(), ss->fd));
    749 
    750     /* Generate random challenge for client to encrypt */
    751     PK11_GenerateRandom(ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
    752 
    753     msg = ss->sec.ci.sendBuf.buf;
    754     msg[0] = SSL_MT_REQUEST_CERTIFICATE;
    755     msg[1] = SSL_AT_MD5_WITH_RSA_ENCRYPTION;
    756     PORT_Memcpy(msg + SSL_HL_REQUEST_CERTIFICATE_HBYTES,
    757                 ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
    758 
    759     DUMP_MSG(29, (ss, msg, sendLen));
    760     sent = (*ss->sec.send)(ss, msg, sendLen, 0);
    761     rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
    762 done:
    763     ssl_ReleaseXmitBufLock(ss);    /***************************************/
    764     return rv;
    765 }
    766 
    767 /* Called from ssl2_HandleRequestCertificate() <- ssl2_HandleMessage()
    768  *             ssl2_RestartHandshakeAfterCertReq() <- (application)
    769  * Acquires and releases the socket's xmitBufLock.
    770  */
    771 static int
    772 ssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert,
    773                                     SECItem *encCode)
    774 {
    775     PRUint8 *msg;
    776     int rv, sendLen;
    777 
    778     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    779 
    780     ssl_GetXmitBufLock(ss);    /***************************************/
    781 
    782     sendLen = SSL_HL_CLIENT_CERTIFICATE_HBYTES + encCode->len + cert->len;
    783     rv = ssl2_GetSendBuffer(ss, sendLen);
    784     if (rv)
    785     	goto done;
    786 
    787     SSL_TRC(3, ("%d: SSL[%d]: sending certificate response",
    788 		SSL_GETPID(), ss->fd));
    789 
    790     msg = ss->sec.ci.sendBuf.buf;
    791     msg[0] = SSL_MT_CLIENT_CERTIFICATE;
    792     msg[1] = SSL_CT_X509_CERTIFICATE;
    793     msg[2] = MSB(cert->len);
    794     msg[3] = LSB(cert->len);
    795     msg[4] = MSB(encCode->len);
    796     msg[5] = LSB(encCode->len);
    797     PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES, cert->data, cert->len);
    798     PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES + cert->len,
    799 	      encCode->data, encCode->len);
    800 
    801     DUMP_MSG(29, (ss, msg, sendLen));
    802     rv = (*ss->sec.send)(ss, msg, sendLen, 0);
    803     if (rv >= 0) {
    804 	rv = SECSuccess;
    805     }
    806 done:
    807     ssl_ReleaseXmitBufLock(ss);    /***************************************/
    808     return rv;
    809 }
    810 
    811 /********************************************************************
    812 **  Send functions above this line must aquire & release the socket's
    813 **	xmitBufLock.
    814 ** All the ssl2_Send functions below this line are called vis ss->sec.send
    815 **	and require that the caller hold the xmitBufLock.
    816 */
    817 
    818 /*
    819 ** Called from ssl2_SendStream, ssl2_SendBlock, but not from ssl2_SendClear.
    820 */
    821 static SECStatus
    822 ssl2_CalcMAC(PRUint8             * result,
    823 	     sslSecurityInfo     * sec,
    824 	     const PRUint8       * data,
    825 	     unsigned int          dataLen,
    826 	     unsigned int          paddingLen)
    827 {
    828     const PRUint8 *      secret		= sec->sendSecret.data;
    829     unsigned int         secretLen	= sec->sendSecret.len;
    830     unsigned long        sequenceNumber = sec->sendSequence;
    831     unsigned int         nout;
    832     PRUint8              seq[4];
    833     PRUint8              padding[32];/* XXX max blocksize? */
    834 
    835     if (!sec->hash || !sec->hash->length)
    836     	return SECSuccess;
    837     if (!sec->hashcx)
    838     	return SECFailure;
    839 
    840     /* Reset hash function */
    841     (*sec->hash->begin)(sec->hashcx);
    842 
    843     /* Feed hash the data */
    844     (*sec->hash->update)(sec->hashcx, secret, secretLen);
    845     (*sec->hash->update)(sec->hashcx, data, dataLen);
    846     PORT_Memset(padding, paddingLen, paddingLen);
    847     (*sec->hash->update)(sec->hashcx, padding, paddingLen);
    848 
    849     seq[0] = (PRUint8) (sequenceNumber >> 24);
    850     seq[1] = (PRUint8) (sequenceNumber >> 16);
    851     seq[2] = (PRUint8) (sequenceNumber >> 8);
    852     seq[3] = (PRUint8) (sequenceNumber);
    853 
    854     PRINT_BUF(60, (0, "calc-mac secret:", secret, secretLen));
    855     PRINT_BUF(60, (0, "calc-mac data:", data, dataLen));
    856     PRINT_BUF(60, (0, "calc-mac padding:", padding, paddingLen));
    857     PRINT_BUF(60, (0, "calc-mac seq:", seq, 4));
    858 
    859     (*sec->hash->update)(sec->hashcx, seq, 4);
    860 
    861     /* Get result */
    862     (*sec->hash->end)(sec->hashcx, result, &nout, sec->hash->length);
    863 
    864     return SECSuccess;
    865 }
    866 
    867 /*
    868 ** Maximum transmission amounts. These are tiny bit smaller than they
    869 ** need to be (they account for the MAC length plus some padding),
    870 ** assuming the MAC is 16 bytes long and the padding is a max of 7 bytes
    871 ** long. This gives an additional 9 bytes of slop to work within.
    872 */
    873 #define MAX_STREAM_CYPHER_LEN	0x7fe0
    874 #define MAX_BLOCK_CYPHER_LEN	0x3fe0
    875 
    876 /*
    877 ** Send some data in the clear.
    878 ** Package up data with the length header and send it.
    879 **
    880 ** Return count of bytes successfully written, or negative number (failure).
    881 */
    882 static PRInt32
    883 ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
    884 {
    885     PRUint8         * out;
    886     int               rv;
    887     int               amount;
    888     int               count	= 0;
    889 
    890     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
    891 
    892     SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes in the clear",
    893 		 SSL_GETPID(), ss->fd, len));
    894     PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len));
    895 
    896     while (len) {
    897 	amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN );
    898 	if (amount + 2 > ss->sec.writeBuf.space) {
    899 	    rv = sslBuffer_Grow(&ss->sec.writeBuf, amount + 2);
    900 	    if (rv != SECSuccess) {
    901 		count = rv;
    902 		break;
    903 	    }
    904 	}
    905 	out = ss->sec.writeBuf.buf;
    906 
    907 	/*
    908 	** Construct message.
    909 	*/
    910 	out[0] = 0x80 | MSB(amount);
    911 	out[1] = LSB(amount);
    912 	PORT_Memcpy(&out[2], in, amount);
    913 
    914 	/* Now send the data */
    915 	rv = ssl_DefSend(ss, out, amount + 2, flags & ~ssl_SEND_FLAG_MASK);
    916 	if (rv < 0) {
    917 	    if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
    918 		rv = 0;
    919 	    } else {
    920 		/* Return short write if some data already went out... */
    921 		if (count == 0)
    922 		    count = rv;
    923 		break;
    924 	    }
    925 	}
    926 
    927 	if ((unsigned)rv < (amount + 2)) {
    928 	    /* Short write.  Save the data and return. */
    929 	    if (ssl_SaveWriteData(ss, out + rv, amount + 2 - rv)
    930 	        == SECFailure) {
    931 		count = SECFailure;
    932 	    } else {
    933 		count += amount;
    934 		ss->sec.sendSequence++;
    935 	    }
    936 	    break;
    937 	}
    938 
    939 	ss->sec.sendSequence++;
    940 	in    += amount;
    941 	count += amount;
    942 	len   -= amount;
    943     }
    944 
    945     return count;
    946 }
    947 
    948 /*
    949 ** Send some data, when using a stream cipher. Stream ciphers have a
    950 ** block size of 1. Package up the data with the length header
    951 ** and send it.
    952 */
    953 static PRInt32
    954 ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
    955 {
    956     PRUint8       *  out;
    957     int              rv;
    958     int              count	= 0;
    959 
    960     int              amount;
    961     PRUint8          macLen;
    962     int              nout;
    963     int              buflen;
    964 
    965     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
    966 
    967     SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using stream cipher",
    968 		 SSL_GETPID(), ss->fd, len));
    969     PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len));
    970 
    971     while (len) {
    972 	ssl_GetSpecReadLock(ss);  /*************************************/
    973 
    974 	macLen = ss->sec.hash->length;
    975 	amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN );
    976 	buflen = amount + 2 + macLen;
    977 	if (buflen > ss->sec.writeBuf.space) {
    978 	    rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen);
    979 	    if (rv != SECSuccess) {
    980 		goto loser;
    981 	    }
    982 	}
    983 	out    = ss->sec.writeBuf.buf;
    984 	nout   = amount + macLen;
    985 	out[0] = 0x80 | MSB(nout);
    986 	out[1] = LSB(nout);
    987 
    988 	/* Calculate MAC */
    989 	rv = ssl2_CalcMAC(out+2, 		/* put MAC here */
    990 	                  &ss->sec,
    991 		          in, amount, 		/* input addr & length */
    992 			  0); 			/* no padding */
    993 	if (rv != SECSuccess)
    994 	    goto loser;
    995 
    996 	/* Encrypt MAC */
    997 	rv = (*ss->sec.enc)(ss->sec.writecx, out+2, &nout, macLen, out+2, macLen);
    998 	if (rv) goto loser;
    999 
   1000 	/* Encrypt data from caller */
   1001 	rv = (*ss->sec.enc)(ss->sec.writecx, out+2+macLen, &nout, amount, in, amount);
   1002 	if (rv) goto loser;
   1003 
   1004 	ssl_ReleaseSpecReadLock(ss);  /*************************************/
   1005 
   1006 	PRINT_BUF(50, (ss, "encrypted data:", out, buflen));
   1007 
   1008 	rv = ssl_DefSend(ss, out, buflen, flags & ~ssl_SEND_FLAG_MASK);
   1009 	if (rv < 0) {
   1010 	    if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
   1011 		SSL_TRC(50, ("%d: SSL[%d]: send stream would block, "
   1012 			     "saving data", SSL_GETPID(), ss->fd));
   1013 		rv = 0;
   1014 	    } else {
   1015 		SSL_TRC(10, ("%d: SSL[%d]: send stream error %d",
   1016 			     SSL_GETPID(), ss->fd, PORT_GetError()));
   1017 		/* Return short write if some data already went out... */
   1018 		if (count == 0)
   1019 		    count = rv;
   1020 		goto done;
   1021 	    }
   1022 	}
   1023 
   1024 	if ((unsigned)rv < buflen) {
   1025 	    /* Short write.  Save the data and return. */
   1026 	    if (ssl_SaveWriteData(ss, out + rv, buflen - rv) == SECFailure) {
   1027 		count = SECFailure;
   1028 	    } else {
   1029 	    	count += amount;
   1030 		ss->sec.sendSequence++;
   1031 	    }
   1032 	    goto done;
   1033 	}
   1034 
   1035 	ss->sec.sendSequence++;
   1036 	in    += amount;
   1037 	count += amount;
   1038 	len   -= amount;
   1039     }
   1040 
   1041 done:
   1042     return count;
   1043 
   1044 loser:
   1045     ssl_ReleaseSpecReadLock(ss);
   1046     return SECFailure;
   1047 }
   1048 
   1049 /*
   1050 ** Send some data, when using a block cipher. Package up the data with
   1051 ** the length header and send it.
   1052 */
   1053 /* XXX assumes blocksize is > 7 */
   1054 static PRInt32
   1055 ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
   1056 {
   1057     PRUint8       *  out;  		    /* begining of output buffer.    */
   1058     PRUint8       *  op;		    /* next output byte goes here.   */
   1059     int              rv;		    /* value from funcs we called.   */
   1060     int              count	= 0;        /* this function's return value. */
   1061 
   1062     unsigned int     hlen;		    /* output record hdr len, 2 or 3 */
   1063     unsigned int     macLen;		    /* MAC is this many bytes long.  */
   1064     int              amount;		    /* of plaintext to go in record. */
   1065     unsigned int     padding;		    /* add this many padding byte.   */
   1066     int              nout;		    /* ciphertext size after header. */
   1067     int              buflen;		    /* size of generated record.     */
   1068 
   1069     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
   1070 
   1071     SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using block cipher",
   1072 		 SSL_GETPID(), ss->fd, len));
   1073     PRINT_BUF(50, (ss, "clear data:", in, len));
   1074 
   1075     while (len) {
   1076 	ssl_GetSpecReadLock(ss);  /*************************************/
   1077 
   1078 	macLen = ss->sec.hash->length;
   1079 	/* Figure out how much to send, including mac and padding */
   1080 	amount  = PR_MIN( len, MAX_BLOCK_CYPHER_LEN );
   1081 	nout    = amount + macLen;
   1082 	padding = nout & (ss->sec.blockSize - 1);
   1083 	if (padding) {
   1084 	    hlen    = 3;
   1085 	    padding = ss->sec.blockSize - padding;
   1086 	    nout   += padding;
   1087 	} else {
   1088 	    hlen = 2;
   1089 	}
   1090 	buflen = hlen + nout;
   1091 	if (buflen > ss->sec.writeBuf.space) {
   1092 	    rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen);
   1093 	    if (rv != SECSuccess) {
   1094 		goto loser;
   1095 	    }
   1096 	}
   1097 	out = ss->sec.writeBuf.buf;
   1098 
   1099 	/* Construct header */
   1100 	op = out;
   1101 	if (padding) {
   1102 	    *op++ = MSB(nout);
   1103 	    *op++ = LSB(nout);
   1104 	    *op++ = padding;
   1105 	} else {
   1106 	    *op++ = 0x80 | MSB(nout);
   1107 	    *op++ = LSB(nout);
   1108 	}
   1109 
   1110 	/* Calculate MAC */
   1111 	rv = ssl2_CalcMAC(op, 		/* MAC goes here. */
   1112 	                  &ss->sec,
   1113 		          in, amount, 	/* intput addr, len */
   1114 			  padding);
   1115 	if (rv != SECSuccess)
   1116 	    goto loser;
   1117 	op += macLen;
   1118 
   1119 	/* Copy in the input data */
   1120 	/* XXX could eliminate the copy by folding it into the encryption */
   1121 	PORT_Memcpy(op, in, amount);
   1122 	op += amount;
   1123 	if (padding) {
   1124 	    PORT_Memset(op, padding, padding);
   1125 	    op += padding;
   1126 	}
   1127 
   1128 	/* Encrypt result */
   1129 	rv = (*ss->sec.enc)(ss->sec.writecx, out+hlen, &nout, buflen-hlen,
   1130 			 out+hlen, op - (out + hlen));
   1131 	if (rv)
   1132 	    goto loser;
   1133 
   1134 	ssl_ReleaseSpecReadLock(ss);  /*************************************/
   1135 
   1136 	PRINT_BUF(50, (ss, "final xmit data:", out, op - out));
   1137 
   1138 	rv = ssl_DefSend(ss, out, op - out, flags & ~ssl_SEND_FLAG_MASK);
   1139 	if (rv < 0) {
   1140 	    if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
   1141 		rv = 0;
   1142 	    } else {
   1143 		SSL_TRC(10, ("%d: SSL[%d]: send block error %d",
   1144 			     SSL_GETPID(), ss->fd, PORT_GetError()));
   1145 		/* Return short write if some data already went out... */
   1146 		if (count == 0)
   1147 		    count = rv;
   1148 		goto done;
   1149 	    }
   1150 	}
   1151 
   1152 	if (rv < (op - out)) {
   1153 	    /* Short write.  Save the data and return. */
   1154 	    if (ssl_SaveWriteData(ss, out + rv, op - out - rv) == SECFailure) {
   1155 		count = SECFailure;
   1156 	    } else {
   1157 		count += amount;
   1158 		ss->sec.sendSequence++;
   1159 	    }
   1160 	    goto done;
   1161 	}
   1162 
   1163 	ss->sec.sendSequence++;
   1164 	in    += amount;
   1165 	count += amount;
   1166 	len   -= amount;
   1167     }
   1168 
   1169 done:
   1170     return count;
   1171 
   1172 loser:
   1173     ssl_ReleaseSpecReadLock(ss);
   1174     return SECFailure;
   1175 }
   1176 
   1177 /*
   1178 ** Called from: ssl2_HandleServerHelloMessage,
   1179 **              ssl2_HandleClientSessionKeyMessage,
   1180 **              ssl2_RestartHandshakeAfterServerCert,
   1181 **              ssl2_HandleClientHelloMessage,
   1182 **
   1183 */
   1184 static void
   1185 ssl2_UseEncryptedSendFunc(sslSocket *ss)
   1186 {
   1187     ssl_GetXmitBufLock(ss);
   1188     PORT_Assert(ss->sec.hashcx != 0);
   1189 
   1190     ss->gs.encrypted = 1;
   1191     ss->sec.send = (ss->sec.blockSize > 1) ? ssl2_SendBlock : ssl2_SendStream;
   1192     ssl_ReleaseXmitBufLock(ss);
   1193 }
   1194 
   1195 /* Called while initializing socket in ssl_CreateSecurityInfo().
   1196 ** This function allows us to keep the name of ssl2_SendClear static.
   1197 */
   1198 void
   1199 ssl2_UseClearSendFunc(sslSocket *ss)
   1200 {
   1201     ss->sec.send = ssl2_SendClear;
   1202 }
   1203 
   1204 /************************************************************************
   1205 ** 			END of Send functions.                          *
   1206 *************************************************************************/
   1207 
   1208 /***********************************************************************
   1209  * For SSL3, this gathers in and handles records/messages until either
   1210  *	the handshake is complete or application data is available.
   1211  *
   1212  * For SSL2, this gathers in only the next SSLV2 record.
   1213  *
   1214  * Called from ssl_Do1stHandshake() via function pointer ss->handshake.
   1215  * Caller must hold handshake lock.
   1216  * This function acquires and releases the RecvBufLock.
   1217  *
   1218  * returns SECSuccess for success.
   1219  * returns SECWouldBlock when that value is returned by ssl2_GatherRecord() or
   1220  *	ssl3_GatherCompleteHandshake().
   1221  * returns SECFailure on all other errors.
   1222  *
   1223  * The gather functions called by ssl_GatherRecord1stHandshake are expected
   1224  * 	to return values interpreted as follows:
   1225  *  1 : the function completed without error.
   1226  *  0 : the function read EOF.
   1227  * -1 : read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
   1228  * -2 : the function wants ssl_GatherRecord1stHandshake to be called again
   1229  *	immediately, by ssl_Do1stHandshake.
   1230  *
   1231  * This code is similar to, and easily confused with, DoRecv() in sslsecur.c
   1232  *
   1233  * This function is called from ssl_Do1stHandshake().
   1234  * The following functions put ssl_GatherRecord1stHandshake into ss->handshake:
   1235  *	ssl2_HandleMessage
   1236  *	ssl2_HandleVerifyMessage
   1237  *	ssl2_HandleServerHelloMessage
   1238  *	ssl2_BeginClientHandshake
   1239  *	ssl2_HandleClientSessionKeyMessage
   1240  *	ssl2_RestartHandshakeAfterCertReq
   1241  *	ssl3_RestartHandshakeAfterCertReq
   1242  *	ssl2_RestartHandshakeAfterServerCert
   1243  *	ssl3_RestartHandshakeAfterServerCert
   1244  *	ssl2_HandleClientHelloMessage
   1245  *	ssl2_BeginServerHandshake
   1246  */
   1247 SECStatus
   1248 ssl_GatherRecord1stHandshake(sslSocket *ss)
   1249 {
   1250     int rv;
   1251 
   1252     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   1253 
   1254     ssl_GetRecvBufLock(ss);
   1255 
   1256     if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
   1257 	/* Wait for handshake to complete, or application data to arrive.  */
   1258 	rv = ssl3_GatherCompleteHandshake(ss, 0);
   1259     } else {
   1260 	/* See if we have a complete record */
   1261 	rv = ssl2_GatherRecord(ss, 0);
   1262     }
   1263     SSL_TRC(10, ("%d: SSL[%d]: handshake gathering, rv=%d",
   1264 		 SSL_GETPID(), ss->fd, rv));
   1265 
   1266     ssl_ReleaseRecvBufLock(ss);
   1267 
   1268     if (rv <= 0) {
   1269 	if (rv == SECWouldBlock) {
   1270 	    /* Progress is blocked waiting for callback completion.  */
   1271 	    SSL_TRC(10, ("%d: SSL[%d]: handshake blocked (need %d)",
   1272 			 SSL_GETPID(), ss->fd, ss->gs.remainder));
   1273 	    return SECWouldBlock;
   1274 	}
   1275 	if (rv == 0) {
   1276 	    /* EOF. Loser  */
   1277 	    PORT_SetError(PR_END_OF_FILE_ERROR);
   1278 	}
   1279 	return SECFailure;	/* rv is < 0 here. */
   1280     }
   1281 
   1282     SSL_TRC(10, ("%d: SSL[%d]: got handshake record of %d bytes",
   1283 		 SSL_GETPID(), ss->fd, ss->gs.recordLen));
   1284 
   1285     ss->handshake = 0;	/* makes ssl_Do1stHandshake call ss->nextHandshake.*/
   1286     return SECSuccess;
   1287 }
   1288 
   1289 /************************************************************************/
   1290 
   1291 /* Called from ssl2_ServerSetupSessionCypher()
   1292  *             ssl2_ClientSetupSessionCypher()
   1293  */
   1294 static SECStatus
   1295 ssl2_FillInSID(sslSessionID * sid,
   1296           int            cipher,
   1297 	  PRUint8       *keyData,
   1298 	  int            keyLen,
   1299 	  PRUint8       *ca,
   1300 	  int            caLen,
   1301 	  int            keyBits,
   1302 	  int            secretKeyBits,
   1303 	  SSLSignType    authAlgorithm,
   1304 	  PRUint32       authKeyBits,
   1305 	  SSLKEAType     keaType,
   1306 	  PRUint32       keaKeyBits)
   1307 {
   1308     PORT_Assert(sid->references == 1);
   1309     PORT_Assert(sid->cached == never_cached);
   1310     PORT_Assert(sid->u.ssl2.masterKey.data == 0);
   1311     PORT_Assert(sid->u.ssl2.cipherArg.data == 0);
   1312 
   1313     sid->version = SSL_LIBRARY_VERSION_2;
   1314 
   1315     sid->u.ssl2.cipherType = cipher;
   1316     sid->u.ssl2.masterKey.data = (PRUint8*) PORT_Alloc(keyLen);
   1317     if (!sid->u.ssl2.masterKey.data) {
   1318 	return SECFailure;
   1319     }
   1320     PORT_Memcpy(sid->u.ssl2.masterKey.data, keyData, keyLen);
   1321     sid->u.ssl2.masterKey.len = keyLen;
   1322     sid->u.ssl2.keyBits       = keyBits;
   1323     sid->u.ssl2.secretKeyBits = secretKeyBits;
   1324     sid->authAlgorithm        = authAlgorithm;
   1325     sid->authKeyBits          = authKeyBits;
   1326     sid->keaType              = keaType;
   1327     sid->keaKeyBits           = keaKeyBits;
   1328     sid->lastAccessTime = sid->creationTime = ssl_Time();
   1329     sid->expirationTime = sid->creationTime + ssl_sid_timeout;
   1330 
   1331     if (caLen) {
   1332 	sid->u.ssl2.cipherArg.data = (PRUint8*) PORT_Alloc(caLen);
   1333 	if (!sid->u.ssl2.cipherArg.data) {
   1334 	    return SECFailure;
   1335 	}
   1336 	sid->u.ssl2.cipherArg.len = caLen;
   1337 	PORT_Memcpy(sid->u.ssl2.cipherArg.data, ca, caLen);
   1338     }
   1339     return SECSuccess;
   1340 }
   1341 
   1342 /*
   1343 ** Construct session keys given the masterKey (tied to the session-id),
   1344 ** the client's challenge and the server's nonce.
   1345 **
   1346 ** Called from ssl2_CreateSessionCypher() <-
   1347 */
   1348 static SECStatus
   1349 ssl2_ProduceKeys(sslSocket *    ss,
   1350             SECItem *      readKey,
   1351 	    SECItem *      writeKey,
   1352 	    SECItem *      masterKey,
   1353 	    PRUint8 *      challenge,
   1354 	    PRUint8 *      nonce,
   1355 	    int            cipherType)
   1356 {
   1357     PK11Context * cx        = 0;
   1358     unsigned      nkm       = 0; /* number of hashes to generate key mat. */
   1359     unsigned      nkd       = 0; /* size of readKey and writeKey. */
   1360     unsigned      part;
   1361     unsigned      i;
   1362     unsigned      off;
   1363     SECStatus     rv;
   1364     PRUint8       countChar;
   1365     PRUint8       km[3*16];	/* buffer for key material. */
   1366 
   1367     readKey->data = 0;
   1368     writeKey->data = 0;
   1369 
   1370     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   1371 
   1372     rv = SECSuccess;
   1373     cx = PK11_CreateDigestContext(SEC_OID_MD5);
   1374     if (cx == NULL) {
   1375 	ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
   1376 	return SECFailure;
   1377     }
   1378 
   1379     nkm = ssl_Specs[cipherType].nkm;
   1380     nkd = ssl_Specs[cipherType].nkd;
   1381 
   1382     readKey->data = (PRUint8*) PORT_Alloc(nkd);
   1383     if (!readKey->data)
   1384     	goto loser;
   1385     readKey->len = nkd;
   1386 
   1387     writeKey->data = (PRUint8*) PORT_Alloc(nkd);
   1388     if (!writeKey->data)
   1389     	goto loser;
   1390     writeKey->len = nkd;
   1391 
   1392     /* Produce key material */
   1393     countChar = '0';
   1394     for (i = 0, off = 0; i < nkm; i++, off += 16) {
   1395 	rv  = PK11_DigestBegin(cx);
   1396 	rv |= PK11_DigestOp(cx, masterKey->data, masterKey->len);
   1397 	rv |= PK11_DigestOp(cx, &countChar,      1);
   1398 	rv |= PK11_DigestOp(cx, challenge,       SSL_CHALLENGE_BYTES);
   1399 	rv |= PK11_DigestOp(cx, nonce,           SSL_CONNECTIONID_BYTES);
   1400 	rv |= PK11_DigestFinal(cx, km+off, &part, MD5_LENGTH);
   1401 	if (rv != SECSuccess) {
   1402 	    ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
   1403 	    rv = SECFailure;
   1404 	    goto loser;
   1405 	}
   1406 	countChar++;
   1407     }
   1408 
   1409     /* Produce keys */
   1410     PORT_Memcpy(readKey->data,  km,       nkd);
   1411     PORT_Memcpy(writeKey->data, km + nkd, nkd);
   1412 
   1413 loser:
   1414     PK11_DestroyContext(cx, PR_TRUE);
   1415     return rv;
   1416 }
   1417 
   1418 /* Called from ssl2_ServerSetupSessionCypher()
   1419 **                  <- ssl2_HandleClientSessionKeyMessage()
   1420 **                          <- ssl2_HandleClientHelloMessage()
   1421 ** and from    ssl2_ClientSetupSessionCypher()
   1422 **                  <- ssl2_HandleServerHelloMessage()
   1423 */
   1424 static SECStatus
   1425 ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient)
   1426 {
   1427     SECItem         * rk = NULL;
   1428     SECItem         * wk = NULL;
   1429     SECItem *         param;
   1430     SECStatus         rv;
   1431     int               cipherType  = sid->u.ssl2.cipherType;
   1432     PK11SlotInfo *    slot        = NULL;
   1433     CK_MECHANISM_TYPE mechanism;
   1434     SECItem           readKey;
   1435     SECItem           writeKey;
   1436 
   1437     void *readcx = 0;
   1438     void *writecx = 0;
   1439     readKey.data = 0;
   1440     writeKey.data = 0;
   1441 
   1442     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   1443     if((ss->sec.ci.sid == 0))
   1444     	goto sec_loser;	/* don't crash if asserts are off */
   1445 
   1446     /* Trying to cut down on all these switch statements that should be tables.
   1447      * So, test cipherType once, here, and then use tables below.
   1448      */
   1449     switch (cipherType) {
   1450     case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
   1451     case SSL_CK_RC4_128_WITH_MD5:
   1452     case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
   1453     case SSL_CK_RC2_128_CBC_WITH_MD5:
   1454     case SSL_CK_DES_64_CBC_WITH_MD5:
   1455     case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
   1456 	break;
   1457 
   1458     default:
   1459 	SSL_DBG(("%d: SSL[%d]: ssl2_CreateSessionCypher: unknown cipher=%d",
   1460 		 SSL_GETPID(), ss->fd, cipherType));
   1461 	PORT_SetError(isClient ? SSL_ERROR_BAD_SERVER : SSL_ERROR_BAD_CLIENT);
   1462 	goto sec_loser;
   1463     }
   1464 
   1465     rk = isClient ? &readKey  : &writeKey;
   1466     wk = isClient ? &writeKey : &readKey;
   1467 
   1468     /* Produce the keys for this session */
   1469     rv = ssl2_ProduceKeys(ss, &readKey, &writeKey, &sid->u.ssl2.masterKey,
   1470 		     ss->sec.ci.clientChallenge, ss->sec.ci.connectionID,
   1471 		     cipherType);
   1472     if (rv != SECSuccess)
   1473 	goto loser;
   1474     PRINT_BUF(7, (ss, "Session read-key: ", rk->data, rk->len));
   1475     PRINT_BUF(7, (ss, "Session write-key: ", wk->data, wk->len));
   1476 
   1477     PORT_Memcpy(ss->sec.ci.readKey, readKey.data, readKey.len);
   1478     PORT_Memcpy(ss->sec.ci.writeKey, writeKey.data, writeKey.len);
   1479     ss->sec.ci.keySize = readKey.len;
   1480 
   1481     /* Setup the MAC */
   1482     rv = ssl2_CreateMAC(&ss->sec, rk, wk, cipherType);
   1483     if (rv != SECSuccess)
   1484     	goto loser;
   1485 
   1486     /* First create the session key object */
   1487     SSL_TRC(3, ("%d: SSL[%d]: using %s", SSL_GETPID(), ss->fd,
   1488 	    ssl_cipherName[cipherType]));
   1489 
   1490 
   1491     mechanism  = ssl_Specs[cipherType].mechanism;
   1492 
   1493     /* set destructer before we call loser... */
   1494     ss->sec.destroy = (void (*)(void*, PRBool)) PK11_DestroyContext;
   1495     slot = PK11_GetBestSlot(mechanism, ss->pkcs11PinArg);
   1496     if (slot == NULL)
   1497 	goto loser;
   1498 
   1499     param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg);
   1500     if (param == NULL)
   1501 	goto loser;
   1502     readcx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap,
   1503 					CKA_DECRYPT, rk, param,
   1504 					ss->pkcs11PinArg);
   1505     SECITEM_FreeItem(param, PR_TRUE);
   1506     if (readcx == NULL)
   1507 	goto loser;
   1508 
   1509     /* build the client context */
   1510     param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg);
   1511     if (param == NULL)
   1512 	goto loser;
   1513     writecx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap,
   1514 					 CKA_ENCRYPT, wk, param,
   1515 					 ss->pkcs11PinArg);
   1516     SECITEM_FreeItem(param,PR_TRUE);
   1517     if (writecx == NULL)
   1518 	goto loser;
   1519     PK11_FreeSlot(slot);
   1520 
   1521     rv = SECSuccess;
   1522     ss->sec.enc           = (SSLCipher) PK11_CipherOp;
   1523     ss->sec.dec           = (SSLCipher) PK11_CipherOp;
   1524     ss->sec.readcx        = (void *) readcx;
   1525     ss->sec.writecx       = (void *) writecx;
   1526     ss->sec.blockSize     = ssl_Specs[cipherType].blockSize;
   1527     ss->sec.blockShift    = ssl_Specs[cipherType].blockShift;
   1528     ss->sec.cipherType    = sid->u.ssl2.cipherType;
   1529     ss->sec.keyBits       = sid->u.ssl2.keyBits;
   1530     ss->sec.secretKeyBits = sid->u.ssl2.secretKeyBits;
   1531     goto done;
   1532 
   1533   loser:
   1534     if (ss->sec.destroy) {
   1535 	if (readcx)  (*ss->sec.destroy)(readcx, PR_TRUE);
   1536 	if (writecx) (*ss->sec.destroy)(writecx, PR_TRUE);
   1537     }
   1538     ss->sec.destroy = NULL;
   1539     if (slot) PK11_FreeSlot(slot);
   1540 
   1541   sec_loser:
   1542     rv = SECFailure;
   1543 
   1544   done:
   1545     if (rk) {
   1546 	SECITEM_ZfreeItem(rk, PR_FALSE);
   1547     }
   1548     if (wk) {
   1549 	SECITEM_ZfreeItem(wk, PR_FALSE);
   1550     }
   1551     return rv;
   1552 }
   1553 
   1554 /*
   1555 ** Setup the server ciphers given information from a CLIENT-MASTER-KEY
   1556 ** message.
   1557 ** 	"ss"      pointer to the ssl-socket object
   1558 ** 	"cipher"  the cipher type to use
   1559 ** 	"keyBits" the size of the final cipher key
   1560 ** 	"ck"      the clear-key data
   1561 ** 	"ckLen"   the number of bytes of clear-key data
   1562 ** 	"ek"      the encrypted-key data
   1563 ** 	"ekLen"   the number of bytes of encrypted-key data
   1564 ** 	"ca"      the cipher-arg data
   1565 ** 	"caLen"   the number of bytes of cipher-arg data
   1566 **
   1567 ** The MASTER-KEY is constructed by first decrypting the encrypted-key
   1568 ** data. This produces the SECRET-KEY-DATA. The MASTER-KEY is composed by
   1569 ** concatenating the clear-key data with the SECRET-KEY-DATA. This code
   1570 ** checks to make sure that the client didn't send us an improper amount
   1571 ** of SECRET-KEY-DATA (it restricts the length of that data to match the
   1572 ** spec).
   1573 **
   1574 ** Called from ssl2_HandleClientSessionKeyMessage().
   1575 */
   1576 static SECStatus
   1577 ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits,
   1578 			 PRUint8 *ck, unsigned int ckLen,
   1579 			 PRUint8 *ek, unsigned int ekLen,
   1580 			 PRUint8 *ca, unsigned int caLen)
   1581 {
   1582     PRUint8      *    dk   = NULL; /* decrypted master key */
   1583     sslSessionID *    sid;
   1584     sslServerCerts *  sc   = ss->serverCerts + kt_rsa;
   1585     PRUint8       *   kbuf = 0;	/* buffer for RSA decrypted data. */
   1586     unsigned int      ddLen;	/* length of RSA decrypted data in kbuf */
   1587     unsigned int      keySize;
   1588     unsigned int      dkLen;    /* decrypted key length in bytes */
   1589     int               modulusLen;
   1590     SECStatus         rv;
   1591     PRUint16          allowed;  /* cipher kinds enabled and allowed by policy */
   1592     PRUint8           mkbuf[SSL_MAX_MASTER_KEY_BYTES];
   1593 
   1594     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   1595     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );
   1596     PORT_Assert((sc->SERVERKEY != 0));
   1597     PORT_Assert((ss->sec.ci.sid != 0));
   1598     sid = ss->sec.ci.sid;
   1599 
   1600     /* Trying to cut down on all these switch statements that should be tables.
   1601      * So, test cipherType once, here, and then use tables below.
   1602      */
   1603     switch (cipher) {
   1604     case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
   1605     case SSL_CK_RC4_128_WITH_MD5:
   1606     case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
   1607     case SSL_CK_RC2_128_CBC_WITH_MD5:
   1608     case SSL_CK_DES_64_CBC_WITH_MD5:
   1609     case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
   1610 	break;
   1611 
   1612     default:
   1613 	SSL_DBG(("%d: SSL[%d]: ssl2_ServerSetupSessionCypher: unknown cipher=%d",
   1614 		 SSL_GETPID(), ss->fd, cipher));
   1615 	PORT_SetError(SSL_ERROR_BAD_CLIENT);
   1616 	goto loser;
   1617     }
   1618 
   1619     allowed = ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED;
   1620     if (!(allowed & (1 << cipher))) {
   1621     	/* client chose a kind we don't allow! */
   1622 	SSL_DBG(("%d: SSL[%d]: disallowed cipher=%d",
   1623 		 SSL_GETPID(), ss->fd, cipher));
   1624 	PORT_SetError(SSL_ERROR_BAD_CLIENT);
   1625 	goto loser;
   1626     }
   1627 
   1628     keySize = ssl_Specs[cipher].keyLen;
   1629     if (keyBits != keySize * BPB) {
   1630 	SSL_DBG(("%d: SSL[%d]: invalid master secret key length=%d (bits)!",
   1631 		 SSL_GETPID(), ss->fd, keyBits));
   1632 	PORT_SetError(SSL_ERROR_BAD_CLIENT);
   1633 	goto loser;
   1634     }
   1635 
   1636     if (ckLen != ssl_Specs[cipher].pubLen) {
   1637 	SSL_DBG(("%d: SSL[%d]: invalid clear key length, ckLen=%d (bytes)!",
   1638 		 SSL_GETPID(), ss->fd, ckLen));
   1639 	PORT_SetError(SSL_ERROR_BAD_CLIENT);
   1640 	goto loser;
   1641     }
   1642 
   1643     if (caLen != ssl_Specs[cipher].ivLen) {
   1644 	SSL_DBG(("%d: SSL[%d]: invalid key args length, caLen=%d (bytes)!",
   1645 		 SSL_GETPID(), ss->fd, caLen));
   1646 	PORT_SetError(SSL_ERROR_BAD_CLIENT);
   1647 	goto loser;
   1648     }
   1649 
   1650     modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY);
   1651     if (modulusLen == -1) {
   1652 	/* XXX If the key is bad, then PK11_PubDecryptRaw will fail below. */
   1653 	modulusLen = ekLen;
   1654     }
   1655     if (ekLen > modulusLen || ekLen + ckLen < keySize) {
   1656 	SSL_DBG(("%d: SSL[%d]: invalid encrypted key length, ekLen=%d (bytes)!",
   1657 		 SSL_GETPID(), ss->fd, ekLen));
   1658 	PORT_SetError(SSL_ERROR_BAD_CLIENT);
   1659 	goto loser;
   1660     }
   1661 
   1662     /* allocate the buffer to hold the decrypted portion of the key. */
   1663     kbuf = (PRUint8*)PORT_Alloc(modulusLen);
   1664     if (!kbuf) {
   1665 	goto loser;
   1666     }
   1667     dkLen = keySize - ckLen;
   1668     dk    = kbuf + modulusLen - dkLen;
   1669 
   1670     /* Decrypt encrypted half of the key.
   1671     ** NOTE: PK11_PubDecryptRaw will barf on a non-RSA key. This is
   1672     ** desired behavior here.
   1673     */
   1674     rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &ddLen, modulusLen, ek, ekLen);
   1675     if (rv != SECSuccess)
   1676 	goto hide_loser;
   1677 
   1678     /* Is the length of the decrypted data (ddLen) the expected value? */
   1679     if (modulusLen != ddLen)
   1680 	goto hide_loser;
   1681 
   1682     /* Cheaply verify that PKCS#1 was used to format the encryption block */
   1683     if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (dk[-1] != 0x00)) {
   1684 	SSL_DBG(("%d: SSL[%d]: strange encryption block",
   1685 		 SSL_GETPID(), ss->fd));
   1686 	PORT_SetError(SSL_ERROR_BAD_CLIENT);
   1687 	goto hide_loser;
   1688     }
   1689 
   1690     /* Make sure we're not subject to a version rollback attack. */
   1691     if (ss->opt.enableSSL3 || ss->opt.enableTLS) {
   1692 	static const PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03,
   1693 			                   0x03, 0x03, 0x03, 0x03 };
   1694 
   1695 	if (PORT_Memcmp(dk - 8 - 1, threes, 8) == 0) {
   1696 	    PORT_SetError(SSL_ERROR_BAD_CLIENT);
   1697 	    goto hide_loser;
   1698 	}
   1699     }
   1700     if (0) {
   1701 hide_loser:
   1702 	/* Defense against the Bleichenbacher attack.
   1703 	 * Provide the client with NO CLUES that the decrypted master key
   1704 	 * was erroneous.  Don't send any error messages.
   1705 	 * Instead, Generate a completely bogus master key .
   1706 	 */
   1707 	PK11_GenerateRandom(dk, dkLen);
   1708     }
   1709 
   1710     /*
   1711     ** Construct master key out of the pieces.
   1712     */
   1713     if (ckLen) {
   1714 	PORT_Memcpy(mkbuf, ck, ckLen);
   1715     }
   1716     PORT_Memcpy(mkbuf + ckLen, dk, dkLen);
   1717 
   1718     /* Fill in session-id */
   1719     rv = ssl2_FillInSID(sid, cipher, mkbuf, keySize, ca, caLen,
   1720 		   keyBits, keyBits - (ckLen<<3),
   1721 		   ss->sec.authAlgorithm, ss->sec.authKeyBits,
   1722 		   ss->sec.keaType,       ss->sec.keaKeyBits);
   1723     if (rv != SECSuccess) {
   1724 	goto loser;
   1725     }
   1726 
   1727     /* Create session ciphers */
   1728     rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
   1729     if (rv != SECSuccess) {
   1730 	goto loser;
   1731     }
   1732 
   1733     SSL_TRC(1, ("%d: SSL[%d]: server, using %s cipher, clear=%d total=%d",
   1734 		SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
   1735 		ckLen<<3, keySize<<3));
   1736     rv = SECSuccess;
   1737     goto done;
   1738 
   1739   loser:
   1740     rv = SECFailure;
   1741 
   1742   done:
   1743     PORT_Free(kbuf);
   1744     return rv;
   1745 }
   1746 
   1747 /************************************************************************/
   1748 
   1749 /*
   1750 ** Rewrite the incoming cipher specs, comparing to list of specs we support,
   1751 ** (ss->cipherSpecs) and eliminating anything we don't support
   1752 **
   1753 *  Note: Our list may contain SSL v3 ciphers.
   1754 *  We MUST NOT match on any of those.
   1755 *  Fortunately, this is easy to detect because SSLv3 ciphers have zero
   1756 *  in the first byte, and none of the SSLv2 ciphers do.
   1757 *
   1758 *  Called from ssl2_HandleClientHelloMessage().
   1759 *  Returns the number of bytes of "qualified cipher specs",
   1760 *  which is typically a multiple of 3, but will be zero if there are none.
   1761 */
   1762 static int
   1763 ssl2_QualifyCypherSpecs(sslSocket *ss,
   1764                         PRUint8 *  cs, /* cipher specs in client hello msg. */
   1765 		        int        csLen)
   1766 {
   1767     PRUint8 *    ms;
   1768     PRUint8 *    hs;
   1769     PRUint8 *    qs;
   1770     int          mc;
   1771     int          hc;
   1772     PRUint8      qualifiedSpecs[ssl2_NUM_SUITES_IMPLEMENTED * 3];
   1773 
   1774     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   1775     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );
   1776 
   1777     if (!ss->cipherSpecs) {
   1778 	SECStatus rv = ssl2_ConstructCipherSpecs(ss);
   1779 	if (rv != SECSuccess || !ss->cipherSpecs)
   1780 	    return 0;
   1781     }
   1782 
   1783     PRINT_BUF(10, (ss, "specs from client:", cs, csLen));
   1784     qs = qualifiedSpecs;
   1785     ms = ss->cipherSpecs;
   1786     for (mc = ss->sizeCipherSpecs; mc > 0; mc -= 3, ms += 3) {
   1787 	if (ms[0] == 0)
   1788 	    continue;
   1789 	for (hs = cs, hc = csLen; hc > 0; hs += 3, hc -= 3) {
   1790 	    if ((hs[0] == ms[0]) &&
   1791 		(hs[1] == ms[1]) &&
   1792 		(hs[2] == ms[2])) {
   1793 		/* Copy this cipher spec into the "keep" section */
   1794 		qs[0] = hs[0];
   1795 		qs[1] = hs[1];
   1796 		qs[2] = hs[2];
   1797 		qs   += 3;
   1798 		break;
   1799 	    }
   1800 	}
   1801     }
   1802     hc = qs - qualifiedSpecs;
   1803     PRINT_BUF(10, (ss, "qualified specs from client:", qualifiedSpecs, hc));
   1804     PORT_Memcpy(cs, qualifiedSpecs, hc);
   1805     return hc;
   1806 }
   1807 
   1808 /*
   1809 ** Pick the best cipher we can find, given the array of server cipher
   1810 ** specs.  Returns cipher number (e.g. SSL_CK_*), or -1 for no overlap.
   1811 ** If successful, stores the master key size (bytes) in *pKeyLen.
   1812 **
   1813 ** This is correct only for the client side, but presently
   1814 ** this function is only called from
   1815 **	ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
   1816 **
   1817 ** Note that most servers only return a single cipher suite in their
   1818 ** ServerHello messages.  So, the code below for finding the "best" cipher
   1819 ** suite usually has only one choice.  The client and server should send
   1820 ** their cipher suite lists sorted in descending order by preference.
   1821 */
   1822 static int
   1823 ssl2_ChooseSessionCypher(sslSocket *ss,
   1824                          int        hc,    /* number of cs's in hs. */
   1825 		         PRUint8 *  hs,    /* server hello's cipher suites. */
   1826 		         int *      pKeyLen) /* out: sym key size in bytes. */
   1827 {
   1828     PRUint8 *       ms;
   1829     unsigned int    i;
   1830     int             bestKeySize;
   1831     int             bestRealKeySize;
   1832     int             bestCypher;
   1833     int             keySize;
   1834     int             realKeySize;
   1835     PRUint8 *       ohs               = hs;
   1836     const PRUint8 * preferred;
   1837     static const PRUint8 noneSuch[3] = { 0, 0, 0 };
   1838 
   1839     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   1840     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );
   1841 
   1842     if (!ss->cipherSpecs) {
   1843 	SECStatus rv = ssl2_ConstructCipherSpecs(ss);
   1844 	if (rv != SECSuccess || !ss->cipherSpecs)
   1845 	    goto loser;
   1846     }
   1847 
   1848     if (!ss->preferredCipher) {
   1849     	unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference &
   1850 	                       SSL_CB_IMPLEMENTED;
   1851 	if (allowed) {
   1852 	    preferred = implementedCipherSuites;
   1853 	    for (i = ssl2_NUM_SUITES_IMPLEMENTED; i > 0; --i) {
   1854 		if (0 != (allowed & (1U << preferred[0]))) {
   1855 		    ss->preferredCipher = preferred;
   1856 		    break;
   1857 		}
   1858 		preferred += 3;
   1859 	    }
   1860 	}
   1861     }
   1862     preferred = ss->preferredCipher ? ss->preferredCipher : noneSuch;
   1863     /*
   1864     ** Scan list of ciphers recieved from peer and look for a match in
   1865     ** our list.
   1866     *  Note: Our list may contain SSL v3 ciphers.
   1867     *  We MUST NOT match on any of those.
   1868     *  Fortunately, this is easy to detect because SSLv3 ciphers have zero
   1869     *  in the first byte, and none of the SSLv2 ciphers do.
   1870     */
   1871     bestKeySize = bestRealKeySize = 0;
   1872     bestCypher = -1;
   1873     while (--hc >= 0) {
   1874 	for (i = 0, ms = ss->cipherSpecs; i < ss->sizeCipherSpecs; i += 3, ms += 3) {
   1875 	    if ((hs[0] == preferred[0]) &&
   1876 		(hs[1] == preferred[1]) &&
   1877 		(hs[2] == preferred[2]) &&
   1878 		 hs[0] != 0) {
   1879 		/* Pick this cipher immediately! */
   1880 		*pKeyLen = (((hs[1] << 8) | hs[2]) + 7) >> 3;
   1881 		return hs[0];
   1882 	    }
   1883 	    if ((hs[0] == ms[0]) && (hs[1] == ms[1]) && (hs[2] == ms[2]) &&
   1884 	         hs[0] != 0) {
   1885 		/* Found a match */
   1886 
   1887 		/* Use secret keySize to determine which cipher is best */
   1888 		realKeySize = (hs[1] << 8) | hs[2];
   1889 		switch (hs[0]) {
   1890 		  case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
   1891 		  case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
   1892 		    keySize = 40;
   1893 		    break;
   1894 		  default:
   1895 		    keySize = realKeySize;
   1896 		    break;
   1897 		}
   1898 		if (keySize > bestKeySize) {
   1899 		    bestCypher = hs[0];
   1900 		    bestKeySize = keySize;
   1901 		    bestRealKeySize = realKeySize;
   1902 		}
   1903 	    }
   1904 	}
   1905 	hs += 3;
   1906     }
   1907     if (bestCypher < 0) {
   1908 	/*
   1909 	** No overlap between server and client. Re-examine server list
   1910 	** to see what kind of ciphers it does support so that we can set
   1911 	** the error code appropriately.
   1912 	*/
   1913 	if ((ohs[0] == SSL_CK_RC4_128_WITH_MD5) ||
   1914 	    (ohs[0] == SSL_CK_RC2_128_CBC_WITH_MD5)) {
   1915 	    PORT_SetError(SSL_ERROR_US_ONLY_SERVER);
   1916 	} else if ((ohs[0] == SSL_CK_RC4_128_EXPORT40_WITH_MD5) ||
   1917 		   (ohs[0] == SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)) {
   1918 	    PORT_SetError(SSL_ERROR_EXPORT_ONLY_SERVER);
   1919 	} else {
   1920 	    PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
   1921 	}
   1922 	SSL_DBG(("%d: SSL[%d]: no cipher overlap", SSL_GETPID(), ss->fd));
   1923 	goto loser;
   1924     }
   1925     *pKeyLen = (bestRealKeySize + 7) >> 3;
   1926     return bestCypher;
   1927 
   1928   loser:
   1929     return -1;
   1930 }
   1931 
   1932 static SECStatus
   1933 ssl2_ClientHandleServerCert(sslSocket *ss, PRUint8 *certData, int certLen)
   1934 {
   1935     CERTCertificate *cert      = NULL;
   1936     SECItem          certItem;
   1937 
   1938     certItem.data = certData;
   1939     certItem.len  = certLen;
   1940 
   1941     /* decode the certificate */
   1942     cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
   1943 				   PR_FALSE, PR_TRUE);
   1944 
   1945     if (cert == NULL) {
   1946 	SSL_DBG(("%d: SSL[%d]: decode of server certificate fails",
   1947 		 SSL_GETPID(), ss->fd));
   1948 	PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
   1949 	return SECFailure;
   1950     }
   1951 
   1952 #ifdef TRACE
   1953     {
   1954 	if (ssl_trace >= 1) {
   1955 	    char *issuer;
   1956 	    char *subject;
   1957 	    issuer = CERT_NameToAscii(&cert->issuer);
   1958 	    subject = CERT_NameToAscii(&cert->subject);
   1959 	    SSL_TRC(1,("%d: server certificate issuer: '%s'",
   1960 		       SSL_GETPID(), issuer ? issuer : "OOPS"));
   1961 	    SSL_TRC(1,("%d: server name: '%s'",
   1962 		       SSL_GETPID(), subject ? subject : "OOPS"));
   1963 	    PORT_Free(issuer);
   1964 	    PORT_Free(subject);
   1965 	}
   1966     }
   1967 #endif
   1968 
   1969     ss->sec.peerCert = cert;
   1970     return SECSuccess;
   1971 }
   1972 
   1973 
   1974 /*
   1975  * Format one block of data for public/private key encryption using
   1976  * the rules defined in PKCS #1. SSL2 does this itself to handle the
   1977  * rollback detection.
   1978  */
   1979 #define RSA_BLOCK_MIN_PAD_LEN           8
   1980 #define RSA_BLOCK_FIRST_OCTET           0x00
   1981 #define RSA_BLOCK_AFTER_PAD_OCTET       0x00
   1982 #define RSA_BLOCK_PUBLIC_OCTET       	0x02
   1983 unsigned char *
   1984 ssl_FormatSSL2Block(unsigned modulusLen, SECItem *data)
   1985 {
   1986     unsigned char *block;
   1987     unsigned char *bp;
   1988     int padLen;
   1989     SECStatus rv;
   1990     int i;
   1991 
   1992     if (modulusLen < data->len + (3 + RSA_BLOCK_MIN_PAD_LEN)) {
   1993 	PORT_SetError(SEC_ERROR_BAD_KEY);
   1994     	return NULL;
   1995     }
   1996     block = (unsigned char *) PORT_Alloc(modulusLen);
   1997     if (block == NULL)
   1998 	return NULL;
   1999 
   2000     bp = block;
   2001 
   2002     /*
   2003      * All RSA blocks start with two octets:
   2004      *	0x00 || BlockType
   2005      */
   2006     *bp++ = RSA_BLOCK_FIRST_OCTET;
   2007     *bp++ = RSA_BLOCK_PUBLIC_OCTET;
   2008 
   2009     /*
   2010      * 0x00 || BT || Pad || 0x00 || ActualData
   2011      *   1      1   padLen    1      data->len
   2012      * Pad is all non-zero random bytes.
   2013      */
   2014     padLen = modulusLen - data->len - 3;
   2015     PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
   2016     rv = PK11_GenerateRandom(bp, padLen);
   2017     if (rv == SECFailure) goto loser;
   2018     /* replace all the 'zero' bytes */
   2019     for (i = 0; i < padLen; i++) {
   2020 	while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET) {
   2021     	    rv = PK11_GenerateRandom(bp+i, 1);
   2022 	    if (rv == SECFailure) goto loser;
   2023 	}
   2024     }
   2025     bp += padLen;
   2026     *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
   2027     PORT_Memcpy (bp, data->data, data->len);
   2028 
   2029     return block;
   2030 loser:
   2031     if (block) PORT_Free(block);
   2032     return NULL;
   2033 }
   2034 
   2035 /*
   2036 ** Given the server's public key and cipher specs, generate a session key
   2037 ** that is ready to use for encrypting/decrypting the byte stream. At
   2038 ** the same time, generate the SSL_MT_CLIENT_MASTER_KEY message and
   2039 ** send it to the server.
   2040 **
   2041 ** Called from ssl2_HandleServerHelloMessage()
   2042 */
   2043 static SECStatus
   2044 ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen)
   2045 {
   2046     sslSessionID *    sid;
   2047     PRUint8 *         ca;	/* points to iv data, or NULL if none. */
   2048     PRUint8 *         ekbuf 		= 0;
   2049     CERTCertificate * cert 		= 0;
   2050     SECKEYPublicKey * serverKey 	= 0;
   2051     unsigned          modulusLen 	= 0;
   2052     SECStatus         rv;
   2053     int               cipher;
   2054     int               keyLen;	/* cipher symkey size in bytes. */
   2055     int               ckLen;	/* publicly reveal this many bytes of key. */
   2056     int               caLen;	/* length of IV data at *ca.	*/
   2057     int               nc;
   2058 
   2059     unsigned char *eblock;	/* holds unencrypted PKCS#1 formatted key. */
   2060     SECItem           rek;	/* holds portion of symkey to be encrypted. */
   2061 
   2062     PRUint8           keyData[SSL_MAX_MASTER_KEY_BYTES];
   2063     PRUint8           iv     [8];
   2064 
   2065     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   2066 
   2067     eblock = NULL;
   2068 
   2069     sid = ss->sec.ci.sid;
   2070     PORT_Assert(sid != 0);
   2071 
   2072     cert = ss->sec.peerCert;
   2073 
   2074     serverKey = CERT_ExtractPublicKey(cert);
   2075     if (!serverKey) {
   2076 	SSL_DBG(("%d: SSL[%d]: extract public key failed: error=%d",
   2077 		 SSL_GETPID(), ss->fd, PORT_GetError()));
   2078 	PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
   2079 	rv = SECFailure;
   2080 	goto loser2;
   2081     }
   2082 
   2083     ss->sec.authAlgorithm = ssl_sign_rsa;
   2084     ss->sec.keaType       = ssl_kea_rsa;
   2085     ss->sec.keaKeyBits    = \
   2086     ss->sec.authKeyBits   = SECKEY_PublicKeyStrengthInBits(serverKey);
   2087 
   2088     /* Choose a compatible cipher with the server */
   2089     nc = csLen / 3;
   2090     cipher = ssl2_ChooseSessionCypher(ss, nc, cs, &keyLen);
   2091     if (cipher < 0) {
   2092 	/* ssl2_ChooseSessionCypher has set error code. */
   2093 	ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
   2094 	goto loser;
   2095     }
   2096 
   2097     /* Generate the random keys */
   2098     PK11_GenerateRandom(keyData, sizeof(keyData));
   2099 
   2100     /*
   2101     ** Next, carve up the keys into clear and encrypted portions. The
   2102     ** clear data is taken from the start of keyData and the encrypted
   2103     ** portion from the remainder. Note that each of these portions is
   2104     ** carved in half, one half for the read-key and one for the
   2105     ** write-key.
   2106     */
   2107     ca = 0;
   2108 
   2109     /* We know that cipher is a legit value here, because
   2110      * ssl2_ChooseSessionCypher doesn't return bogus values.
   2111      */
   2112     ckLen = ssl_Specs[cipher].pubLen;	/* cleartext key length. */
   2113     caLen = ssl_Specs[cipher].ivLen;	/* IV length.		*/
   2114     if (caLen) {
   2115 	PORT_Assert(sizeof iv >= caLen);
   2116     	PK11_GenerateRandom(iv, caLen);
   2117 	ca = iv;
   2118     }
   2119 
   2120     /* Fill in session-id */
   2121     rv = ssl2_FillInSID(sid, cipher, keyData, keyLen,
   2122 		   ca, caLen, keyLen << 3, (keyLen - ckLen) << 3,
   2123 		   ss->sec.authAlgorithm, ss->sec.authKeyBits,
   2124 		   ss->sec.keaType,       ss->sec.keaKeyBits);
   2125     if (rv != SECSuccess) {
   2126 	goto loser;
   2127     }
   2128 
   2129     SSL_TRC(1, ("%d: SSL[%d]: client, using %s cipher, clear=%d total=%d",
   2130 		SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
   2131 		ckLen<<3, keyLen<<3));
   2132 
   2133     /* Now setup read and write ciphers */
   2134     rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE);
   2135     if (rv != SECSuccess) {
   2136 	goto loser;
   2137     }
   2138 
   2139     /*
   2140     ** Fill in the encryption buffer with some random bytes. Then
   2141     ** copy in the portion of the session key we are encrypting.
   2142     */
   2143     modulusLen = SECKEY_PublicKeyStrength(serverKey);
   2144     rek.data   = keyData + ckLen;
   2145     rek.len    = keyLen  - ckLen;
   2146     eblock = ssl_FormatSSL2Block(modulusLen, &rek);
   2147     if (eblock == NULL)
   2148     	goto loser;
   2149 
   2150     /* Set up the padding for version 2 rollback detection. */
   2151     /* XXX We should really use defines here */
   2152     if (ss->opt.enableSSL3 || ss->opt.enableTLS) {
   2153 	PORT_Assert((modulusLen - rek.len) > 12);
   2154 	PORT_Memset(eblock + modulusLen - rek.len - 8 - 1, 0x03, 8);
   2155     }
   2156     ekbuf = (PRUint8*) PORT_Alloc(modulusLen);
   2157     if (!ekbuf)
   2158 	goto loser;
   2159     PRINT_BUF(10, (ss, "master key encryption block:",
   2160 		   eblock, modulusLen));
   2161 
   2162     /* Encrypt ekitem */
   2163     rv = PK11_PubEncryptRaw(serverKey, ekbuf, eblock, modulusLen,
   2164 						ss->pkcs11PinArg);
   2165     if (rv)
   2166     	goto loser;
   2167 
   2168     /*  Now we have everything ready to send */
   2169     rv = ssl2_SendSessionKeyMessage(ss, cipher, keyLen << 3, ca, caLen,
   2170 			       keyData, ckLen, ekbuf, modulusLen);
   2171     if (rv != SECSuccess) {
   2172 	goto loser;
   2173     }
   2174     rv = SECSuccess;
   2175     goto done;
   2176 
   2177   loser:
   2178     rv = SECFailure;
   2179 
   2180   loser2:
   2181   done:
   2182     PORT_Memset(keyData, 0, sizeof(keyData));
   2183     PORT_ZFree(ekbuf, modulusLen);
   2184     PORT_ZFree(eblock, modulusLen);
   2185     SECKEY_DestroyPublicKey(serverKey);
   2186     return rv;
   2187 }
   2188 
   2189 /************************************************************************/
   2190 
   2191 /*
   2192  * Called from ssl2_HandleMessage in response to SSL_MT_SERVER_FINISHED message.
   2193  * Caller holds recvBufLock and handshakeLock
   2194  */
   2195 static void
   2196 ssl2_ClientRegSessionID(sslSocket *ss, PRUint8 *s)
   2197 {
   2198     sslSessionID *sid = ss->sec.ci.sid;
   2199 
   2200     /* Record entry in nonce cache */
   2201     if (sid->peerCert == NULL) {
   2202 	PORT_Memcpy(sid->u.ssl2.sessionID, s, sizeof(sid->u.ssl2.sessionID));
   2203 	sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
   2204 
   2205     }
   2206     if (!ss->opt.noCache)
   2207 	(*ss->sec.cache)(sid);
   2208 }
   2209 
   2210 /* Called from ssl2_HandleMessage() */
   2211 static SECStatus
   2212 ssl2_TriggerNextMessage(sslSocket *ss)
   2213 {
   2214     SECStatus        rv;
   2215 
   2216     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   2217 
   2218     if ((ss->sec.ci.requiredElements & CIS_HAVE_CERTIFICATE) &&
   2219 	!(ss->sec.ci.sentElements & CIS_HAVE_CERTIFICATE)) {
   2220 	ss->sec.ci.sentElements |= CIS_HAVE_CERTIFICATE;
   2221 	rv = ssl2_SendCertificateRequestMessage(ss);
   2222 	return rv;
   2223     }
   2224     return SECSuccess;
   2225 }
   2226 
   2227 /* See if it's time to send our finished message, or if the handshakes are
   2228 ** complete.  Send finished message if appropriate.
   2229 ** Returns SECSuccess unless anything goes wrong.
   2230 **
   2231 ** Called from ssl2_HandleMessage,
   2232 **             ssl2_HandleVerifyMessage
   2233 **             ssl2_HandleServerHelloMessage
   2234 **             ssl2_HandleClientSessionKeyMessage
   2235 **             ssl2_RestartHandshakeAfterCertReq
   2236 **             ssl2_RestartHandshakeAfterServerCert
   2237 */
   2238 static SECStatus
   2239 ssl2_TryToFinish(sslSocket *ss)
   2240 {
   2241     SECStatus        rv;
   2242     char             e, ef;
   2243 
   2244     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   2245 
   2246     e = ss->sec.ci.elements;
   2247     ef = e | CIS_HAVE_FINISHED;
   2248     if ((ef & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) {
   2249 	if (ss->sec.isServer) {
   2250 	    /* Send server finished message if we already didn't */
   2251 	    rv = ssl2_SendServerFinishedMessage(ss);
   2252 	} else {
   2253 	    /* Send client finished message if we already didn't */
   2254 	    rv = ssl2_SendClientFinishedMessage(ss);
   2255 	}
   2256 	if (rv != SECSuccess) {
   2257 	    return rv;
   2258 	}
   2259 	if ((e & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) {
   2260 	    /* Totally finished */
   2261 	    ss->handshake = 0;
   2262 	    return SECSuccess;
   2263 	}
   2264     }
   2265     return SECSuccess;
   2266 }
   2267 
   2268 /*
   2269 ** Called from ssl2_HandleRequestCertificate
   2270 **             ssl2_RestartHandshakeAfterCertReq
   2271 */
   2272 static SECStatus
   2273 ssl2_SignResponse(sslSocket *ss,
   2274 	     SECKEYPrivateKey *key,
   2275 	     SECItem *response)
   2276 {
   2277     SGNContext *     sgn = NULL;
   2278     PRUint8 *        challenge;
   2279     unsigned int     len;
   2280     SECStatus        rv		= SECFailure;
   2281 
   2282     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   2283 
   2284     challenge = ss->sec.ci.serverChallenge;
   2285     len = ss->sec.ci.serverChallengeLen;
   2286 
   2287     /* Sign the expected data... */
   2288     sgn = SGN_NewContext(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION,key);
   2289     if (!sgn)
   2290     	goto done;
   2291     rv = SGN_Begin(sgn);
   2292     if (rv != SECSuccess)
   2293     	goto done;
   2294     rv = SGN_Update(sgn, ss->sec.ci.readKey, ss->sec.ci.keySize);
   2295     if (rv != SECSuccess)
   2296     	goto done;
   2297     rv = SGN_Update(sgn, ss->sec.ci.writeKey, ss->sec.ci.keySize);
   2298     if (rv != SECSuccess)
   2299     	goto done;
   2300     rv = SGN_Update(sgn, challenge, len);
   2301     if (rv != SECSuccess)
   2302     	goto done;
   2303     rv = SGN_Update(sgn, ss->sec.peerCert->derCert.data,
   2304                          ss->sec.peerCert->derCert.len);
   2305     if (rv != SECSuccess)
   2306     	goto done;
   2307     rv = SGN_End(sgn, response);
   2308     if (rv != SECSuccess)
   2309     	goto done;
   2310 
   2311 done:
   2312     SGN_DestroyContext(sgn, PR_TRUE);
   2313     return rv == SECSuccess ? SECSuccess : SECFailure;
   2314 }
   2315 
   2316 /*
   2317 ** Try to handle a request-certificate message. Get client's certificate
   2318 ** and private key and sign a message for the server to see.
   2319 ** Caller must hold handshakeLock
   2320 **
   2321 ** Called from ssl2_HandleMessage().
   2322 */
   2323 static int
   2324 ssl2_HandleRequestCertificate(sslSocket *ss)
   2325 {
   2326     CERTCertificate * cert	= NULL;	/* app-selected client cert. */
   2327     SECKEYPrivateKey *key	= NULL;	/* priv key for cert. */
   2328     SECStatus         rv;
   2329     SECItem           response;
   2330     int               ret	= 0;
   2331     PRUint8           authType;
   2332 
   2333 
   2334     /*
   2335      * These things all need to be initialized before we can "goto loser".
   2336      */
   2337     response.data = NULL;
   2338 
   2339     /* get challenge info from connectionInfo */
   2340     authType = ss->sec.ci.authType;
   2341 
   2342     if (authType != SSL_AT_MD5_WITH_RSA_ENCRYPTION) {
   2343 	SSL_TRC(7, ("%d: SSL[%d]: unsupported auth type 0x%x", SSL_GETPID(),
   2344 		    ss->fd, authType));
   2345 	goto no_cert_error;
   2346     }
   2347 
   2348     /* Get certificate and private-key from client */
   2349     if (!ss->getClientAuthData) {
   2350 	SSL_TRC(7, ("%d: SSL[%d]: client doesn't support client-auth",
   2351 		    SSL_GETPID(), ss->fd));
   2352 	goto no_cert_error;
   2353     }
   2354     ret = (*ss->getClientAuthData)(ss->getClientAuthDataArg, ss->fd,
   2355 				   NULL, &cert, &key);
   2356     if ( ret == SECWouldBlock ) {
   2357 	ssl_SetAlwaysBlock(ss);
   2358 	goto done;
   2359     }
   2360 
   2361     if (ret) {
   2362 	goto no_cert_error;
   2363     }
   2364 
   2365     /* check what the callback function returned */
   2366     if ((!cert) || (!key)) {
   2367         /* we are missing either the key or cert */
   2368         if (cert) {
   2369             /* got a cert, but no key - free it */
   2370             CERT_DestroyCertificate(cert);
   2371             cert = NULL;
   2372         }
   2373         if (key) {
   2374             /* got a key, but no cert - free it */
   2375             SECKEY_DestroyPrivateKey(key);
   2376             key = NULL;
   2377         }
   2378         goto no_cert_error;
   2379     }
   2380 
   2381     rv = ssl2_SignResponse(ss, key, &response);
   2382     if ( rv != SECSuccess ) {
   2383 	ret = -1;
   2384 	goto loser;
   2385     }
   2386 
   2387     /* Send response message */
   2388     ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response);
   2389 
   2390     /* Now, remember the cert we sent. But first, forget any previous one. */
   2391     if (ss->sec.localCert) {
   2392 	CERT_DestroyCertificate(ss->sec.localCert);
   2393     }
   2394     ss->sec.localCert = CERT_DupCertificate(cert);
   2395     PORT_Assert(!ss->sec.ci.sid->localCert);
   2396     if (ss->sec.ci.sid->localCert) {
   2397 	CERT_DestroyCertificate(ss->sec.ci.sid->localCert);
   2398     }
   2399     ss->sec.ci.sid->localCert = cert;
   2400     cert = NULL;
   2401 
   2402     goto done;
   2403 
   2404   no_cert_error:
   2405     SSL_TRC(7, ("%d: SSL[%d]: no certificate (ret=%d)", SSL_GETPID(),
   2406 		ss->fd, ret));
   2407     ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE);
   2408 
   2409   loser:
   2410   done:
   2411     if ( cert ) {
   2412 	CERT_DestroyCertificate(cert);
   2413     }
   2414     if ( key ) {
   2415 	SECKEY_DestroyPrivateKey(key);
   2416     }
   2417     if ( response.data ) {
   2418 	PORT_Free(response.data);
   2419     }
   2420 
   2421     return ret;
   2422 }
   2423 
   2424 /*
   2425 ** Called from ssl2_HandleMessage for SSL_MT_CLIENT_CERTIFICATE message.
   2426 ** Caller must hold HandshakeLock and RecvBufLock, since cd and response
   2427 ** are contained in the gathered input data.
   2428 */
   2429 static SECStatus
   2430 ssl2_HandleClientCertificate(sslSocket *    ss,
   2431                              PRUint8        certType,	/* XXX unused */
   2432 			     PRUint8 *      cd,
   2433 			     unsigned int   cdLen,
   2434 			     PRUint8 *      response,
   2435 			     unsigned int   responseLen)
   2436 {
   2437     CERTCertificate *cert	= NULL;
   2438     SECKEYPublicKey *pubKey	= NULL;
   2439     VFYContext *     vfy	= NULL;
   2440     SECItem *        derCert;
   2441     SECStatus        rv		= SECFailure;
   2442     SECItem          certItem;
   2443     SECItem          rep;
   2444 
   2445     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   2446     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );
   2447 
   2448     /* Extract the certificate */
   2449     certItem.data = cd;
   2450     certItem.len  = cdLen;
   2451 
   2452     cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
   2453 			 	   PR_FALSE, PR_TRUE);
   2454     if (cert == NULL) {
   2455 	goto loser;
   2456     }
   2457 
   2458     /* save the certificate, since the auth routine will need it */
   2459     ss->sec.peerCert = cert;
   2460 
   2461     /* Extract the public key */
   2462     pubKey = CERT_ExtractPublicKey(cert);
   2463     if (!pubKey)
   2464     	goto loser;
   2465 
   2466     /* Verify the response data... */
   2467     rep.data = response;
   2468     rep.len = responseLen;
   2469     /* SSL 2.0 only supports RSA certs, so we don't have to worry about
   2470      * DSA here. */
   2471     vfy = VFY_CreateContext(pubKey, &rep, SEC_OID_PKCS1_RSA_ENCRYPTION,
   2472 			    ss->pkcs11PinArg);
   2473     if (!vfy)
   2474     	goto loser;
   2475     rv = VFY_Begin(vfy);
   2476     if (rv)
   2477     	goto loser;
   2478 
   2479     rv = VFY_Update(vfy, ss->sec.ci.readKey, ss->sec.ci.keySize);
   2480     if (rv)
   2481     	goto loser;
   2482     rv = VFY_Update(vfy, ss->sec.ci.writeKey, ss->sec.ci.keySize);
   2483     if (rv)
   2484     	goto loser;
   2485     rv = VFY_Update(vfy, ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
   2486     if (rv)
   2487     	goto loser;
   2488 
   2489     derCert = &ss->serverCerts[kt_rsa].serverCert->derCert;
   2490     rv = VFY_Update(vfy, derCert->data, derCert->len);
   2491     if (rv)
   2492     	goto loser;
   2493     rv = VFY_End(vfy);
   2494     if (rv)
   2495     	goto loser;
   2496 
   2497     /* Now ask the server application if it likes the certificate... */
   2498     rv = (SECStatus) (*ss->authCertificate)(ss->authCertificateArg,
   2499 					    ss->fd, PR_TRUE, PR_TRUE);
   2500     /* Hey, it liked it. */
   2501     if (SECSuccess == rv)
   2502 	goto done;
   2503 
   2504 loser:
   2505     ss->sec.peerCert = NULL;
   2506     CERT_DestroyCertificate(cert);
   2507 
   2508 done:
   2509     VFY_DestroyContext(vfy, PR_TRUE);
   2510     SECKEY_DestroyPublicKey(pubKey);
   2511     return rv;
   2512 }
   2513 
   2514 /*
   2515 ** Handle remaining messages between client/server. Process finished
   2516 ** messages from either side and any authentication requests.
   2517 ** This should only be called for SSLv2 handshake messages,
   2518 ** not for application data records.
   2519 ** Caller must hold handshake lock.
   2520 **
   2521 ** Called from ssl_Do1stHandshake().
   2522 **
   2523 */
   2524 static SECStatus
   2525 ssl2_HandleMessage(sslSocket *ss)
   2526 {
   2527     PRUint8 *        data;
   2528     PRUint8 *        cid;
   2529     unsigned         len, certType, certLen, responseLen;
   2530     int              rv;
   2531     int              rv2;
   2532 
   2533     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   2534 
   2535     ssl_GetRecvBufLock(ss);
   2536 
   2537     data = ss->gs.buf.buf + ss->gs.recordOffset;
   2538 
   2539     if (ss->gs.recordLen < 1) {
   2540 	goto bad_peer;
   2541     }
   2542     SSL_TRC(3, ("%d: SSL[%d]: received %d message",
   2543 		SSL_GETPID(), ss->fd, data[0]));
   2544     DUMP_MSG(29, (ss, data, ss->gs.recordLen));
   2545 
   2546     switch (data[0]) {
   2547     case SSL_MT_CLIENT_FINISHED:
   2548 	if (ss->sec.ci.elements & CIS_HAVE_FINISHED) {
   2549 	    SSL_DBG(("%d: SSL[%d]: dup client-finished message",
   2550 		     SSL_GETPID(), ss->fd));
   2551 	    goto bad_peer;
   2552 	}
   2553 
   2554 	/* See if nonce matches */
   2555 	len = ss->gs.recordLen - 1;
   2556 	cid = data + 1;
   2557 	if ((len != sizeof(ss->sec.ci.connectionID)) ||
   2558 	    (PORT_Memcmp(ss->sec.ci.connectionID, cid, len) != 0)) {
   2559 	    SSL_DBG(("%d: SSL[%d]: bad connection-id", SSL_GETPID(), ss->fd));
   2560 	    PRINT_BUF(5, (ss, "sent connection-id",
   2561 			  ss->sec.ci.connectionID,
   2562 			  sizeof(ss->sec.ci.connectionID)));
   2563 	    PRINT_BUF(5, (ss, "rcvd connection-id", cid, len));
   2564 	    goto bad_peer;
   2565 	}
   2566 
   2567 	SSL_TRC(5, ("%d: SSL[%d]: got client finished, waiting for 0x%d",
   2568 		    SSL_GETPID(), ss->fd,
   2569 		    ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
   2570 	ss->sec.ci.elements |= CIS_HAVE_FINISHED;
   2571 	break;
   2572 
   2573     case SSL_MT_SERVER_FINISHED:
   2574 	if (ss->sec.ci.elements & CIS_HAVE_FINISHED) {
   2575 	    SSL_DBG(("%d: SSL[%d]: dup server-finished message",
   2576 		     SSL_GETPID(), ss->fd));
   2577 	    goto bad_peer;
   2578 	}
   2579 
   2580 	if (ss->gs.recordLen - 1 != SSL2_SESSIONID_BYTES) {
   2581 	    SSL_DBG(("%d: SSL[%d]: bad server-finished message, len=%d",
   2582 		     SSL_GETPID(), ss->fd, ss->gs.recordLen));
   2583 	    goto bad_peer;
   2584 	}
   2585 	ssl2_ClientRegSessionID(ss, data+1);
   2586 	SSL_TRC(5, ("%d: SSL[%d]: got server finished, waiting for 0x%d",
   2587 		    SSL_GETPID(), ss->fd,
   2588 		    ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
   2589 	ss->sec.ci.elements |= CIS_HAVE_FINISHED;
   2590 	break;
   2591 
   2592     case SSL_MT_REQUEST_CERTIFICATE:
   2593 	len = ss->gs.recordLen - 2;
   2594 	if ((len < SSL_MIN_CHALLENGE_BYTES) ||
   2595 	    (len > SSL_MAX_CHALLENGE_BYTES)) {
   2596 	    /* Bad challenge */
   2597 	    SSL_DBG(("%d: SSL[%d]: bad cert request message: code len=%d",
   2598 		     SSL_GETPID(), ss->fd, len));
   2599 	    goto bad_peer;
   2600 	}
   2601 
   2602 	/* save auth request info */
   2603 	ss->sec.ci.authType           = data[1];
   2604 	ss->sec.ci.serverChallengeLen = len;
   2605 	PORT_Memcpy(ss->sec.ci.serverChallenge, data + 2, len);
   2606 
   2607 	rv = ssl2_HandleRequestCertificate(ss);
   2608 	if (rv == SECWouldBlock) {
   2609 	    SSL_TRC(3, ("%d: SSL[%d]: async cert request",
   2610 			SSL_GETPID(), ss->fd));
   2611 	    /* someone is handling this asynchronously */
   2612 	    ssl_ReleaseRecvBufLock(ss);
   2613 	    return SECWouldBlock;
   2614 	}
   2615 	if (rv) {
   2616 	    SET_ERROR_CODE
   2617 	    goto loser;
   2618 	}
   2619 	break;
   2620 
   2621     case SSL_MT_CLIENT_CERTIFICATE:
   2622 	if (!ss->authCertificate) {
   2623 	    /* Server asked for authentication and can't handle it */
   2624 	    PORT_SetError(SSL_ERROR_BAD_SERVER);
   2625 	    goto loser;
   2626 	}
   2627 	if (ss->gs.recordLen < SSL_HL_CLIENT_CERTIFICATE_HBYTES) {
   2628 	    SET_ERROR_CODE
   2629 	    goto loser;
   2630 	}
   2631 	certType    = data[1];
   2632 	certLen     = (data[2] << 8) | data[3];
   2633 	responseLen = (data[4] << 8) | data[5];
   2634 	if (certType != SSL_CT_X509_CERTIFICATE) {
   2635 	    PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
   2636 	    goto loser;
   2637 	}
   2638 	if (certLen + responseLen + SSL_HL_CLIENT_CERTIFICATE_HBYTES
   2639 	    > ss->gs.recordLen) {
   2640 	    /* prevent overflow crash. */
   2641 	    rv = SECFailure;
   2642 	} else
   2643 	rv = ssl2_HandleClientCertificate(ss, data[1],
   2644 		data + SSL_HL_CLIENT_CERTIFICATE_HBYTES,
   2645 		certLen,
   2646 		data + SSL_HL_CLIENT_CERTIFICATE_HBYTES + certLen,
   2647 		responseLen);
   2648 	if (rv) {
   2649 	    rv2 = ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
   2650 	    SET_ERROR_CODE
   2651 	    goto loser;
   2652 	}
   2653 	ss->sec.ci.elements |= CIS_HAVE_CERTIFICATE;
   2654 	break;
   2655 
   2656     case SSL_MT_ERROR:
   2657 	rv = (data[1] << 8) | data[2];
   2658 	SSL_TRC(2, ("%d: SSL[%d]: got error message, error=0x%x",
   2659 		    SSL_GETPID(), ss->fd, rv));
   2660 
   2661 	/* Convert protocol error number into API error number */
   2662 	switch (rv) {
   2663 	  case SSL_PE_NO_CYPHERS:
   2664 	    rv = SSL_ERROR_NO_CYPHER_OVERLAP;
   2665 	    break;
   2666 	  case SSL_PE_NO_CERTIFICATE:
   2667 	    rv = SSL_ERROR_NO_CERTIFICATE;
   2668 	    break;
   2669 	  case SSL_PE_BAD_CERTIFICATE:
   2670 	    rv = SSL_ERROR_BAD_CERTIFICATE;
   2671 	    break;
   2672 	  case SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE:
   2673 	    rv = SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE;
   2674 	    break;
   2675 	  default:
   2676 	    goto bad_peer;
   2677 	}
   2678 	/* XXX make certificate-request optionally fail... */
   2679 	PORT_SetError(rv);
   2680 	goto loser;
   2681 
   2682     default:
   2683 	SSL_DBG(("%d: SSL[%d]: unknown message %d",
   2684 		 SSL_GETPID(), ss->fd, data[0]));
   2685 	goto loser;
   2686     }
   2687 
   2688     SSL_TRC(3, ("%d: SSL[%d]: handled %d message, required=0x%x got=0x%x",
   2689 		SSL_GETPID(), ss->fd, data[0],
   2690 		ss->sec.ci.requiredElements, ss->sec.ci.elements));
   2691 
   2692     rv = ssl2_TryToFinish(ss);
   2693     if (rv != SECSuccess)
   2694 	goto loser;
   2695 
   2696     ss->gs.recordLen = 0;
   2697     ssl_ReleaseRecvBufLock(ss);
   2698 
   2699     if (ss->handshake == 0) {
   2700 	return SECSuccess;
   2701     }
   2702 
   2703     ss->handshake     = ssl_GatherRecord1stHandshake;
   2704     ss->nextHandshake = ssl2_HandleMessage;
   2705     return ssl2_TriggerNextMessage(ss);
   2706 
   2707   bad_peer:
   2708     PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT : SSL_ERROR_BAD_SERVER);
   2709     /* FALL THROUGH */
   2710 
   2711   loser:
   2712     ssl_ReleaseRecvBufLock(ss);
   2713     return SECFailure;
   2714 }
   2715 
   2716 /************************************************************************/
   2717 
   2718 /* Called from ssl_Do1stHandshake, after ssl2_HandleServerHelloMessage or
   2719 ** ssl2_RestartHandshakeAfterServerCert.
   2720 */
   2721 static SECStatus
   2722 ssl2_HandleVerifyMessage(sslSocket *ss)
   2723 {
   2724     PRUint8 *        data;
   2725     SECStatus        rv;
   2726 
   2727     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   2728     ssl_GetRecvBufLock(ss);
   2729 
   2730     data = ss->gs.buf.buf + ss->gs.recordOffset;
   2731     DUMP_MSG(29, (ss, data, ss->gs.recordLen));
   2732     if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) ||
   2733 	(data[0] != SSL_MT_SERVER_VERIFY) ||
   2734 	NSS_SecureMemcmp(data+1, ss->sec.ci.clientChallenge,
   2735 	                 SSL_CHALLENGE_BYTES)) {
   2736 	/* Bad server */
   2737 	PORT_SetError(SSL_ERROR_BAD_SERVER);
   2738 	goto loser;
   2739     }
   2740     ss->sec.ci.elements |= CIS_HAVE_VERIFY;
   2741 
   2742     SSL_TRC(5, ("%d: SSL[%d]: got server-verify, required=0x%d got=0x%x",
   2743 		SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements,
   2744 		ss->sec.ci.elements));
   2745 
   2746     rv = ssl2_TryToFinish(ss);
   2747     if (rv)
   2748 	goto loser;
   2749 
   2750     ss->gs.recordLen = 0;
   2751     ssl_ReleaseRecvBufLock(ss);
   2752 
   2753     if (ss->handshake == 0) {
   2754 	return SECSuccess;
   2755     }
   2756     ss->handshake         = ssl_GatherRecord1stHandshake;
   2757     ss->nextHandshake     = ssl2_HandleMessage;
   2758     return SECSuccess;
   2759 
   2760 
   2761   loser:
   2762     ssl_ReleaseRecvBufLock(ss);
   2763     return SECFailure;
   2764 }
   2765 
   2766 /* Not static because ssl2_GatherData() tests ss->nextHandshake for this value.
   2767  * ICK!
   2768  * Called from ssl_Do1stHandshake after ssl2_BeginClientHandshake()
   2769  */
   2770 SECStatus
   2771 ssl2_HandleServerHelloMessage(sslSocket *ss)
   2772 {
   2773     sslSessionID *   sid;
   2774     PRUint8 *        cert;
   2775     PRUint8 *        cs;
   2776     PRUint8 *        data;
   2777     SECStatus        rv;
   2778     int              needed, sidHit, certLen, csLen, cidLen, certType, err;
   2779 
   2780     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   2781 
   2782     if (!ss->opt.enableSSL2) {
   2783 	PORT_SetError(SSL_ERROR_SSL2_DISABLED);
   2784 	return SECFailure;
   2785     }
   2786 
   2787     ssl_GetRecvBufLock(ss);
   2788 
   2789     PORT_Assert(ss->sec.ci.sid != 0);
   2790     sid = ss->sec.ci.sid;
   2791 
   2792     data = ss->gs.buf.buf + ss->gs.recordOffset;
   2793     DUMP_MSG(29, (ss, data, ss->gs.recordLen));
   2794 
   2795     /* Make sure first message has some data and is the server hello message */
   2796     if ((ss->gs.recordLen < SSL_HL_SERVER_HELLO_HBYTES)
   2797 	|| (data[0] != SSL_MT_SERVER_HELLO)) {
   2798 	if ((data[0] == SSL_MT_ERROR) && (ss->gs.recordLen == 3)) {
   2799 	    err = (data[1] << 8) | data[2];
   2800 	    if (err == SSL_PE_NO_CYPHERS) {
   2801 		PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
   2802 		goto loser;
   2803 	    }
   2804 	}
   2805 	goto bad_server;
   2806     }
   2807 
   2808     sidHit      = data[1];
   2809     certType    = data[2];
   2810     ss->version = (data[3] << 8) | data[4];
   2811     certLen     = (data[5] << 8) | data[6];
   2812     csLen       = (data[7] << 8) | data[8];
   2813     cidLen      = (data[9] << 8) | data[10];
   2814     cert        = data + SSL_HL_SERVER_HELLO_HBYTES;
   2815     cs          = cert + certLen;
   2816 
   2817     SSL_TRC(5,
   2818 	    ("%d: SSL[%d]: server-hello, hit=%d vers=%x certLen=%d csLen=%d cidLen=%d",
   2819 	     SSL_GETPID(), ss->fd, sidHit, ss->version, certLen,
   2820 	     csLen, cidLen));
   2821     if (ss->version != SSL_LIBRARY_VERSION_2) {
   2822         if (ss->version < SSL_LIBRARY_VERSION_2) {
   2823 	  SSL_TRC(3, ("%d: SSL[%d]: demoting self (%x) to server version (%x)",
   2824 		      SSL_GETPID(), ss->fd, SSL_LIBRARY_VERSION_2,
   2825 		      ss->version));
   2826 	} else {
   2827 	  SSL_TRC(1, ("%d: SSL[%d]: server version is %x (we are %x)",
   2828 		    SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
   2829 	  /* server claims to be newer but does not follow protocol */
   2830 	  PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
   2831 	  goto loser;
   2832 	}
   2833     }
   2834 
   2835     if ((SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen + cidLen
   2836                                                   > ss->gs.recordLen)
   2837 	|| (csLen % 3) != 0
   2838 	/* || cidLen < SSL_CONNECTIONID_BYTES || cidLen > 32  */
   2839 	) {
   2840 	goto bad_server;
   2841     }
   2842 
   2843     /* Save connection-id.
   2844     ** This code only saves the first 16 byte of the connectionID.
   2845     ** If the connectionID is shorter than 16 bytes, it is zero-padded.
   2846     */
   2847     if (cidLen < sizeof ss->sec.ci.connectionID)
   2848 	memset(ss->sec.ci.connectionID, 0, sizeof ss->sec.ci.connectionID);
   2849     cidLen = PR_MIN(cidLen, sizeof ss->sec.ci.connectionID);
   2850     PORT_Memcpy(ss->sec.ci.connectionID, cs + csLen, cidLen);
   2851 
   2852     /* See if session-id hit */
   2853     needed = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED | CIS_HAVE_VERIFY;
   2854     if (sidHit) {
   2855 	if (certLen || csLen) {
   2856 	    /* Uh oh - bogus server */
   2857 	    SSL_DBG(("%d: SSL[%d]: client, huh? hit=%d certLen=%d csLen=%d",
   2858 		     SSL_GETPID(), ss->fd, sidHit, certLen, csLen));
   2859 	    goto bad_server;
   2860 	}
   2861 
   2862 	/* Total winner. */
   2863 	SSL_TRC(1, ("%d: SSL[%d]: client, using nonce for peer=0x%08x "
   2864 		    "port=0x%04x",
   2865 		    SSL_GETPID(), ss->fd, ss->sec.ci.peer, ss->sec.ci.port));
   2866 	ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
   2867         ss->sec.authAlgorithm = sid->authAlgorithm;
   2868 	ss->sec.authKeyBits   = sid->authKeyBits;
   2869 	ss->sec.keaType       = sid->keaType;
   2870 	ss->sec.keaKeyBits    = sid->keaKeyBits;
   2871 	rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE);
   2872 	if (rv != SECSuccess) {
   2873 	    goto loser;
   2874 	}
   2875     } else {
   2876 	if (certType != SSL_CT_X509_CERTIFICATE) {
   2877 	    PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
   2878 	    goto loser;
   2879 	}
   2880 	if (csLen == 0) {
   2881 	    PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
   2882 	    SSL_DBG(("%d: SSL[%d]: no cipher overlap",
   2883 		     SSL_GETPID(), ss->fd));
   2884 	    goto loser;
   2885 	}
   2886 	if (certLen == 0) {
   2887 	    SSL_DBG(("%d: SSL[%d]: client, huh? certLen=%d csLen=%d",
   2888 		     SSL_GETPID(), ss->fd, certLen, csLen));
   2889 	    goto bad_server;
   2890 	}
   2891 
   2892 	if (sid->cached != never_cached) {
   2893 	    /* Forget our session-id - server didn't like it */
   2894 	    SSL_TRC(7, ("%d: SSL[%d]: server forgot me, uncaching session-id",
   2895 			SSL_GETPID(), ss->fd));
   2896 	    (*ss->sec.uncache)(sid);
   2897 	    ssl_FreeSID(sid);
   2898 	    ss->sec.ci.sid = sid = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID));
   2899 	    if (!sid) {
   2900 		goto loser;
   2901 	    }
   2902 	    sid->references = 1;
   2903 	    sid->addr = ss->sec.ci.peer;
   2904 	    sid->port = ss->sec.ci.port;
   2905 	}
   2906 
   2907 	/* decode the server's certificate */
   2908 	rv = ssl2_ClientHandleServerCert(ss, cert, certLen);
   2909 	if (rv != SECSuccess) {
   2910 	    if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
   2911 		(void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
   2912 	    }
   2913 	    goto loser;
   2914 	}
   2915 
   2916 	/* Setup new session cipher */
   2917 	rv = ssl2_ClientSetupSessionCypher(ss, cs, csLen);
   2918 	if (rv != SECSuccess) {
   2919 	    if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
   2920 		(void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
   2921 	    }
   2922 	    goto loser;
   2923 	}
   2924     }
   2925 
   2926     /* Build up final list of required elements */
   2927     ss->sec.ci.elements         = CIS_HAVE_MASTER_KEY;
   2928     ss->sec.ci.requiredElements = needed;
   2929 
   2930   if (!sidHit) {
   2931     /* verify the server's certificate. if sidHit, don't check signatures */
   2932     rv = (* ss->authCertificate)(ss->authCertificateArg, ss->fd,
   2933 				 (PRBool)(!sidHit), PR_FALSE);
   2934     if (rv) {
   2935 	if (ss->handleBadCert) {
   2936 	    rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd);
   2937 	    if ( rv ) {
   2938 		if ( rv == SECWouldBlock ) {
   2939 		    /* someone will handle this connection asynchronously*/
   2940 
   2941 		    SSL_DBG(("%d: SSL[%d]: go to async cert handler",
   2942 			     SSL_GETPID(), ss->fd));
   2943 		    ssl_ReleaseRecvBufLock(ss);
   2944 		    ssl_SetAlwaysBlock(ss);
   2945 		    return SECWouldBlock;
   2946 		}
   2947 		/* cert is bad */
   2948 		SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
   2949 			 SSL_GETPID(), ss->fd, PORT_GetError()));
   2950 		goto loser;
   2951 
   2952 	    }
   2953 	    /* cert is good */
   2954 	} else {
   2955 	    SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
   2956 		     SSL_GETPID(), ss->fd, PORT_GetError()));
   2957 	    goto loser;
   2958 	}
   2959     }
   2960   }
   2961     /*
   2962     ** At this point we have a completed session key and our session
   2963     ** cipher is setup and ready to go. Switch to encrypted write routine
   2964     ** as all future message data is to be encrypted.
   2965     */
   2966     ssl2_UseEncryptedSendFunc(ss);
   2967 
   2968     rv = ssl2_TryToFinish(ss);
   2969     if (rv != SECSuccess)
   2970 	goto loser;
   2971 
   2972     ss->gs.recordLen = 0;
   2973 
   2974     ssl_ReleaseRecvBufLock(ss);
   2975 
   2976     if (ss->handshake == 0) {
   2977 	return SECSuccess;
   2978     }
   2979 
   2980     SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x",
   2981 		SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements,
   2982 		ss->sec.ci.elements));
   2983     ss->handshake     = ssl_GatherRecord1stHandshake;
   2984     ss->nextHandshake = ssl2_HandleVerifyMessage;
   2985     return SECSuccess;
   2986 
   2987   bad_server:
   2988     PORT_SetError(SSL_ERROR_BAD_SERVER);
   2989     /* FALL THROUGH */
   2990 
   2991   loser:
   2992     ssl_ReleaseRecvBufLock(ss);
   2993     return SECFailure;
   2994 }
   2995 
   2996 /* Sends out the initial client Hello message on the connection.
   2997  * Acquires and releases the socket's xmitBufLock.
   2998  */
   2999 SECStatus
   3000 ssl2_BeginClientHandshake(sslSocket *ss)
   3001 {
   3002     sslSessionID      *sid;
   3003     PRUint8           *msg;
   3004     PRUint8           *cp;
   3005     PRUint8           *localCipherSpecs = NULL;
   3006     unsigned int      localCipherSize;
   3007     unsigned int      i;
   3008     int               sendLen, sidLen = 0;
   3009     SECStatus         rv;
   3010 
   3011     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   3012 
   3013     ss->sec.isServer     = 0;
   3014     ss->sec.sendSequence = 0;
   3015     ss->sec.rcvSequence  = 0;
   3016     ssl_ChooseSessionIDProcs(&ss->sec);
   3017 
   3018     if (!ss->cipherSpecs) {
   3019 	rv = ssl2_ConstructCipherSpecs(ss);
   3020 	if (rv != SECSuccess)
   3021 	    goto loser;
   3022     }
   3023 
   3024     /* count the SSL2 and SSL3 enabled ciphers.
   3025      * if either is zero, clear the socket's enable for that protocol.
   3026      */
   3027     rv = ssl2_CheckConfigSanity(ss);
   3028     if (rv != SECSuccess)
   3029 	goto loser;
   3030 
   3031     /* Get peer name of server */
   3032     rv = ssl_GetPeerInfo(ss);
   3033     if (rv < 0) {
   3034 #ifdef HPUX11
   3035         /*
   3036          * On some HP-UX B.11.00 systems, getpeername() occasionally
   3037          * fails with ENOTCONN after a successful completion of
   3038          * non-blocking connect.  I found that if we do a write()
   3039          * and then retry getpeername(), it will work.
   3040          */
   3041         if (PR_GetError() == PR_NOT_CONNECTED_ERROR) {
   3042             char dummy;
   3043             (void) PR_Write(ss->fd->lower, &dummy, 0);
   3044             rv = ssl_GetPeerInfo(ss);
   3045             if (rv < 0) {
   3046                 goto loser;
   3047             }
   3048         }
   3049 #else
   3050 	goto loser;
   3051 #endif
   3052     }
   3053 
   3054     SSL_TRC(3, ("%d: SSL[%d]: sending client-hello", SSL_GETPID(), ss->fd));
   3055 
   3056     /* Try to find server in our session-id cache */
   3057     if (ss->opt.noCache) {
   3058 	sid = NULL;
   3059     } else {
   3060 	sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID,
   3061 	                    ss->url);
   3062     }
   3063     while (sid) {  /* this isn't really a loop */
   3064 	/* if we're not doing this SID's protocol any more, drop it. */
   3065 	if (((sid->version  < SSL_LIBRARY_VERSION_3_0) && !ss->opt.enableSSL2) ||
   3066 	    ((sid->version == SSL_LIBRARY_VERSION_3_0) && !ss->opt.enableSSL3) ||
   3067 	    ((sid->version >  SSL_LIBRARY_VERSION_3_0) && !ss->opt.enableTLS)) {
   3068 	    ss->sec.uncache(sid);
   3069 	    ssl_FreeSID(sid);
   3070 	    sid = NULL;
   3071 	    break;
   3072 	}
   3073 	if (ss->opt.enableSSL2 && sid->version < SSL_LIBRARY_VERSION_3_0) {
   3074 	    /* If the cipher in this sid is not enabled, drop it. */
   3075 	    for (i = 0; i < ss->sizeCipherSpecs; i += 3) {
   3076 		if (ss->cipherSpecs[i] == sid->u.ssl2.cipherType)
   3077 		    break;
   3078 	    }
   3079 	    if (i >= ss->sizeCipherSpecs) {
   3080 		ss->sec.uncache(sid);
   3081 		ssl_FreeSID(sid);
   3082 		sid = NULL;
   3083 		break;
   3084 	    }
   3085 	}
   3086 	sidLen = sizeof(sid->u.ssl2.sessionID);
   3087 	PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl2.sessionID,
   3088 		      sidLen));
   3089 	ss->version = sid->version;
   3090 	PORT_Assert(!ss->sec.localCert);
   3091 	if (ss->sec.localCert) {
   3092 	    CERT_DestroyCertificate(ss->sec.localCert);
   3093 	}
   3094 	ss->sec.localCert     = CERT_DupCertificate(sid->localCert);
   3095 	break;  /* this isn't really a loop */
   3096     }
   3097     if (!sid) {
   3098 	sidLen = 0;
   3099 	sid = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID));
   3100 	if (!sid) {
   3101 	    goto loser;
   3102 	}
   3103 	sid->references = 1;
   3104 	sid->cached     = never_cached;
   3105 	sid->addr       = ss->sec.ci.peer;
   3106 	sid->port       = ss->sec.ci.port;
   3107 	if (ss->peerID != NULL) {
   3108 	    sid->peerID = PORT_Strdup(ss->peerID);
   3109 	}
   3110 	if (ss->url != NULL) {
   3111 	    sid->urlSvrName = PORT_Strdup(ss->url);
   3112 	}
   3113     }
   3114     ss->sec.ci.sid = sid;
   3115 
   3116     PORT_Assert(sid != NULL);
   3117 
   3118     if ((sid->version >= SSL_LIBRARY_VERSION_3_0 || !ss->opt.v2CompatibleHello) &&
   3119         (ss->opt.enableSSL3 || ss->opt.enableTLS)) {
   3120 
   3121 	ss->gs.state      = GS_INIT;
   3122 	ss->handshake     = ssl_GatherRecord1stHandshake;
   3123 
   3124 	/* ssl3_SendClientHello will override this if it succeeds. */
   3125 	ss->version       = SSL_LIBRARY_VERSION_3_0;
   3126 
   3127 	ssl_GetXmitBufLock(ss);    /***************************************/
   3128 	ssl_GetSSL3HandshakeLock(ss);
   3129 	rv =  ssl3_SendClientHello(ss);
   3130 	ssl_ReleaseSSL3HandshakeLock(ss);
   3131 	ssl_ReleaseXmitBufLock(ss); /***************************************/
   3132 
   3133 	return rv;
   3134     }
   3135 #if defined(NSS_ENABLE_ECC) && !defined(NSS_ECC_MORE_THAN_SUITE_B)
   3136     /* ensure we don't neogtiate ECC cipher suites with SSL2 hello */
   3137     ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */
   3138     if (ss->cipherSpecs != NULL) {
   3139 	PORT_Free(ss->cipherSpecs);
   3140 	ss->cipherSpecs     = NULL;
   3141 	ss->sizeCipherSpecs = 0;
   3142     }
   3143 #endif
   3144 
   3145     if (!ss->cipherSpecs) {
   3146         rv = ssl2_ConstructCipherSpecs(ss);
   3147 	if (rv < 0) {
   3148 	    return rv;
   3149     	}
   3150     }
   3151     localCipherSpecs = ss->cipherSpecs;
   3152     localCipherSize  = ss->sizeCipherSpecs;
   3153 
   3154     sendLen = SSL_HL_CLIENT_HELLO_HBYTES + localCipherSize + sidLen +
   3155 	SSL_CHALLENGE_BYTES;
   3156 
   3157     /* Generate challenge bytes for server */
   3158     PK11_GenerateRandom(ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
   3159 
   3160     ssl_GetXmitBufLock(ss);    /***************************************/
   3161 
   3162     rv = ssl2_GetSendBuffer(ss, sendLen);
   3163     if (rv)
   3164     	goto unlock_loser;
   3165 
   3166     /* Construct client-hello message */
   3167     cp = msg = ss->sec.ci.sendBuf.buf;
   3168     msg[0] = SSL_MT_CLIENT_HELLO;
   3169     if ( ss->opt.enableTLS ) {
   3170 	ss->clientHelloVersion = SSL_LIBRARY_VERSION_3_1_TLS;
   3171     } else if ( ss->opt.enableSSL3 ) {
   3172 	ss->clientHelloVersion = SSL_LIBRARY_VERSION_3_0;
   3173     } else {
   3174 	ss->clientHelloVersion = SSL_LIBRARY_VERSION_2;
   3175     }
   3176 
   3177     msg[1] = MSB(ss->clientHelloVersion);
   3178     msg[2] = LSB(ss->clientHelloVersion);
   3179     msg[3] = MSB(localCipherSize);
   3180     msg[4] = LSB(localCipherSize);
   3181     msg[5] = MSB(sidLen);
   3182     msg[6] = LSB(sidLen);
   3183     msg[7] = MSB(SSL_CHALLENGE_BYTES);
   3184     msg[8] = LSB(SSL_CHALLENGE_BYTES);
   3185     cp += SSL_HL_CLIENT_HELLO_HBYTES;
   3186     PORT_Memcpy(cp, localCipherSpecs, localCipherSize);
   3187     cp += localCipherSize;
   3188     if (sidLen) {
   3189 	PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen);
   3190 	cp += sidLen;
   3191     }
   3192     PORT_Memcpy(cp, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
   3193 
   3194     /* Send it to the server */
   3195     DUMP_MSG(29, (ss, msg, sendLen));
   3196     ss->handshakeBegun = 1;
   3197     rv = (*ss->sec.send)(ss, msg, sendLen, 0);
   3198 
   3199     ssl_ReleaseXmitBufLock(ss);    /***************************************/
   3200 
   3201     if (rv < 0) {
   3202 	goto loser;
   3203     }
   3204 
   3205     rv = ssl3_StartHandshakeHash(ss, msg, sendLen);
   3206     if (rv < 0) {
   3207 	goto loser;
   3208     }
   3209 
   3210     /* Setup to receive servers hello message */
   3211     ssl_GetRecvBufLock(ss);
   3212     ss->gs.recordLen = 0;
   3213     ssl_ReleaseRecvBufLock(ss);
   3214 
   3215     ss->handshake     = ssl_GatherRecord1stHandshake;
   3216     ss->nextHandshake = ssl2_HandleServerHelloMessage;
   3217     return SECSuccess;
   3218 
   3219 unlock_loser:
   3220     ssl_ReleaseXmitBufLock(ss);
   3221 loser:
   3222     return SECFailure;
   3223 }
   3224 
   3225 /************************************************************************/
   3226 
   3227 /* Handle the CLIENT-MASTER-KEY message.
   3228 ** Acquires and releases RecvBufLock.
   3229 ** Called from ssl2_HandleClientHelloMessage().
   3230 */
   3231 static SECStatus
   3232 ssl2_HandleClientSessionKeyMessage(sslSocket *ss)
   3233 {
   3234     PRUint8 *        data;
   3235     unsigned int     caLen;
   3236     unsigned int     ckLen;
   3237     unsigned int     ekLen;
   3238     unsigned int     keyBits;
   3239     int              cipher;
   3240     SECStatus        rv;
   3241 
   3242 
   3243     ssl_GetRecvBufLock(ss);
   3244 
   3245     data = ss->gs.buf.buf + ss->gs.recordOffset;
   3246     DUMP_MSG(29, (ss, data, ss->gs.recordLen));
   3247 
   3248     if ((ss->gs.recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES)
   3249 	|| (data[0] != SSL_MT_CLIENT_MASTER_KEY)) {
   3250 	goto bad_client;
   3251     }
   3252     cipher  = data[1];
   3253     keyBits = (data[2] << 8) | data[3];
   3254     ckLen   = (data[4] << 8) | data[5];
   3255     ekLen   = (data[6] << 8) | data[7];
   3256     caLen   = (data[8] << 8) | data[9];
   3257 
   3258     SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keyBits=%d ckLen=%d ekLen=%d caLen=%d",
   3259 		SSL_GETPID(), ss->fd, cipher, keyBits, ckLen, ekLen, caLen));
   3260 
   3261     if (ss->gs.recordLen <
   3262     	    SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen) {
   3263 	SSL_DBG(("%d: SSL[%d]: protocol size mismatch dataLen=%d",
   3264 		 SSL_GETPID(), ss->fd, ss->gs.recordLen));
   3265 	goto bad_client;
   3266     }
   3267 
   3268     /* Use info from client to setup session key */
   3269     rv = ssl2_ServerSetupSessionCypher(ss, cipher, keyBits,
   3270 		data + SSL_HL_CLIENT_MASTER_KEY_HBYTES,                 ckLen,
   3271 		data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen,         ekLen,
   3272 		data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen, caLen);
   3273     ss->gs.recordLen = 0;	/* we're done with this record. */
   3274 
   3275     ssl_ReleaseRecvBufLock(ss);
   3276 
   3277     if (rv != SECSuccess) {
   3278 	goto loser;
   3279     }
   3280     ss->sec.ci.elements |= CIS_HAVE_MASTER_KEY;
   3281     ssl2_UseEncryptedSendFunc(ss);
   3282 
   3283     /* Send server verify message now that keys are established */
   3284     rv = ssl2_SendServerVerifyMessage(ss);
   3285     if (rv != SECSuccess)
   3286 	goto loser;
   3287 
   3288     rv = ssl2_TryToFinish(ss);
   3289     if (rv != SECSuccess)
   3290 	goto loser;
   3291     if (ss->handshake == 0) {
   3292 	return SECSuccess;
   3293     }
   3294 
   3295     SSL_TRC(5, ("%d: SSL[%d]: server: waiting for elements=0x%d",
   3296 		SSL_GETPID(), ss->fd,
   3297 		ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
   3298     ss->handshake         = ssl_GatherRecord1stHandshake;
   3299     ss->nextHandshake     = ssl2_HandleMessage;
   3300 
   3301     return ssl2_TriggerNextMessage(ss);
   3302 
   3303 bad_client:
   3304     ssl_ReleaseRecvBufLock(ss);
   3305     PORT_SetError(SSL_ERROR_BAD_CLIENT);
   3306     /* FALLTHROUGH */
   3307 
   3308 loser:
   3309     return SECFailure;
   3310 }
   3311 
   3312 /*
   3313  * attempt to restart the handshake after asynchronously handling
   3314  * a request for the client's certificate.
   3315  *
   3316  * inputs:
   3317  *	cert	Client cert chosen by application.
   3318  *	key	Private key associated with cert.
   3319  *
   3320  * XXX: need to make ssl2 and ssl3 versions of this function agree on whether
   3321  *	they take the reference, or bump the ref count!
   3322  *
   3323  * Return value: XXX
   3324  *
   3325  * Caller holds 1stHandshakeLock.
   3326  */
   3327 int
   3328 ssl2_RestartHandshakeAfterCertReq(sslSocket *          ss,
   3329 				  CERTCertificate *    cert,
   3330 				  SECKEYPrivateKey *   key)
   3331 {
   3332     int              ret;
   3333     SECStatus        rv          = SECSuccess;
   3334     SECItem          response;
   3335 
   3336     if (ss->version >= SSL_LIBRARY_VERSION_3_0)
   3337     	return SECFailure;
   3338 
   3339     response.data = NULL;
   3340 
   3341     /* generate error if no cert or key */
   3342     if ( ( cert == NULL ) || ( key == NULL ) ) {
   3343 	goto no_cert;
   3344     }
   3345 
   3346     /* generate signed response to the challenge */
   3347     rv = ssl2_SignResponse(ss, key, &response);
   3348     if ( rv != SECSuccess ) {
   3349 	goto no_cert;
   3350     }
   3351 
   3352     /* Send response message */
   3353     ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response);
   3354     if (ret) {
   3355 	goto no_cert;
   3356     }
   3357 
   3358     /* try to finish the handshake */
   3359     ret = ssl2_TryToFinish(ss);
   3360     if (ret) {
   3361 	goto loser;
   3362     }
   3363 
   3364     /* done with handshake */
   3365     if (ss->handshake == 0) {
   3366 	ret = SECSuccess;
   3367 	goto done;
   3368     }
   3369 
   3370     /* continue handshake */
   3371     ssl_GetRecvBufLock(ss);
   3372     ss->gs.recordLen = 0;
   3373     ssl_ReleaseRecvBufLock(ss);
   3374 
   3375     ss->handshake     = ssl_GatherRecord1stHandshake;
   3376     ss->nextHandshake = ssl2_HandleMessage;
   3377     ret = ssl2_TriggerNextMessage(ss);
   3378     goto done;
   3379 
   3380 no_cert:
   3381     /* no cert - send error */
   3382     ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE);
   3383     goto done;
   3384 
   3385 loser:
   3386     ret = SECFailure;
   3387 done:
   3388     /* free allocated data */
   3389     if ( response.data ) {
   3390 	PORT_Free(response.data);
   3391     }
   3392 
   3393     return ret;
   3394 }
   3395 
   3396 
   3397 /* restart an SSL connection that we stopped to run certificate dialogs
   3398 ** XXX	Need to document here how an application marks a cert to show that
   3399 **	the application has accepted it (overridden CERT_VerifyCert).
   3400  *
   3401  * Return value: XXX
   3402  *
   3403  * Caller holds 1stHandshakeLock.
   3404 */
   3405 int
   3406 ssl2_RestartHandshakeAfterServerCert(sslSocket *ss)
   3407 {
   3408     int rv	= SECSuccess;
   3409 
   3410     if (ss->version >= SSL_LIBRARY_VERSION_3_0)
   3411 	return SECFailure;
   3412 
   3413     /* SSL 2
   3414     ** At this point we have a completed session key and our session
   3415     ** cipher is setup and ready to go. Switch to encrypted write routine
   3416     ** as all future message data is to be encrypted.
   3417     */
   3418     ssl2_UseEncryptedSendFunc(ss);
   3419 
   3420     rv = ssl2_TryToFinish(ss);
   3421     if (rv == SECSuccess && ss->handshake != NULL) {
   3422 	/* handshake is not yet finished. */
   3423 
   3424 	SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x",
   3425 		SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements,
   3426 		ss->sec.ci.elements));
   3427 
   3428 	ssl_GetRecvBufLock(ss);
   3429 	ss->gs.recordLen = 0;	/* mark it all used up. */
   3430 	ssl_ReleaseRecvBufLock(ss);
   3431 
   3432 	ss->handshake     = ssl_GatherRecord1stHandshake;
   3433 	ss->nextHandshake = ssl2_HandleVerifyMessage;
   3434     }
   3435 
   3436     return rv;
   3437 }
   3438 
   3439 /*
   3440 ** Handle the initial hello message from the client
   3441 **
   3442 ** not static because ssl2_GatherData() tests ss->nextHandshake for this value.
   3443 */
   3444 SECStatus
   3445 ssl2_HandleClientHelloMessage(sslSocket *ss)
   3446 {
   3447     sslSessionID    *sid;
   3448     sslServerCerts * sc;
   3449     CERTCertificate *serverCert;
   3450     PRUint8         *msg;
   3451     PRUint8         *data;
   3452     PRUint8         *cs;
   3453     PRUint8         *sd;
   3454     PRUint8         *cert = NULL;
   3455     PRUint8         *challenge;
   3456     unsigned int    challengeLen;
   3457     SECStatus       rv;
   3458     int             csLen;
   3459     int             sendLen;
   3460     int             sdLen;
   3461     int             certLen;
   3462     int             pid;
   3463     int             sent;
   3464     int             gotXmitBufLock = 0;
   3465 #if defined(SOLARIS) && defined(i386)
   3466     volatile PRUint8 hit;
   3467 #else
   3468     int             hit;
   3469 #endif
   3470     PRUint8         csImpl[sizeof implementedCipherSuites];
   3471 
   3472     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   3473 
   3474     sc = ss->serverCerts + kt_rsa;
   3475     serverCert = sc->serverCert;
   3476 
   3477     ssl_GetRecvBufLock(ss);
   3478 
   3479 
   3480     data = ss->gs.buf.buf + ss->gs.recordOffset;
   3481     DUMP_MSG(29, (ss, data, ss->gs.recordLen));
   3482 
   3483     /* Make sure first message has some data and is the client hello message */
   3484     if ((ss->gs.recordLen < SSL_HL_CLIENT_HELLO_HBYTES)
   3485 	|| (data[0] != SSL_MT_CLIENT_HELLO)) {
   3486 	goto bad_client;
   3487     }
   3488 
   3489     /* Get peer name of client */
   3490     rv = ssl_GetPeerInfo(ss);
   3491     if (rv != SECSuccess) {
   3492 	goto loser;
   3493     }
   3494 
   3495     /* Examine version information */
   3496     /*
   3497      * See if this might be a V2 client hello asking to use the V3 protocol
   3498      */
   3499     if ((data[0] == SSL_MT_CLIENT_HELLO) &&
   3500         (data[1] >= MSB(SSL_LIBRARY_VERSION_3_0)) &&
   3501 	(ss->opt.enableSSL3 || ss->opt.enableTLS)) {
   3502 	rv = ssl3_HandleV2ClientHello(ss, data, ss->gs.recordLen);
   3503 	if (rv != SECFailure) { /* Success */
   3504 	    ss->handshake             = NULL;
   3505 	    ss->nextHandshake         = ssl_GatherRecord1stHandshake;
   3506 	    ss->securityHandshake     = NULL;
   3507 	    ss->gs.state              = GS_INIT;
   3508 
   3509 	    /* ssl3_HandleV3ClientHello has set ss->version,
   3510 	    ** and has gotten us a brand new sid.
   3511 	    */
   3512 	    ss->sec.ci.sid->version  = ss->version;
   3513 	}
   3514 	ssl_ReleaseRecvBufLock(ss);
   3515 	return rv;
   3516     }
   3517     /* Previously, there was a test here to see if SSL2 was enabled.
   3518     ** If not, an error code was set, and SECFailure was returned,
   3519     ** without sending any error code to the other end of the connection.
   3520     ** That test has been removed.  If SSL2 has been disabled, there
   3521     ** should be no SSL2 ciphers enabled, and consequently, the code
   3522     ** below should send the ssl2 error message SSL_PE_NO_CYPHERS.
   3523     ** We now believe this is the correct thing to do, even when SSL2
   3524     ** has been explicitly disabled by the application.
   3525     */
   3526 
   3527     /* Extract info from message */
   3528     ss->version = (data[1] << 8) | data[2];
   3529 
   3530     /* If some client thinks ssl v2 is 2.0 instead of 0.2, we'll allow it.  */
   3531     if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
   3532 	ss->version = SSL_LIBRARY_VERSION_2;
   3533     }
   3534 
   3535     csLen        = (data[3] << 8) | data[4];
   3536     sdLen        = (data[5] << 8) | data[6];
   3537     challengeLen = (data[7] << 8) | data[8];
   3538     cs           = data + SSL_HL_CLIENT_HELLO_HBYTES;
   3539     sd           = cs + csLen;
   3540     challenge    = sd + sdLen;
   3541     PRINT_BUF(7, (ss, "server, client session-id value:", sd, sdLen));
   3542 
   3543     if (!csLen || (csLen % 3) != 0 ||
   3544         (sdLen != 0 && sdLen != SSL2_SESSIONID_BYTES) ||
   3545 	challengeLen < SSL_MIN_CHALLENGE_BYTES ||
   3546 	challengeLen > SSL_MAX_CHALLENGE_BYTES ||
   3547         (unsigned)ss->gs.recordLen !=
   3548             SSL_HL_CLIENT_HELLO_HBYTES + csLen + sdLen + challengeLen) {
   3549 	SSL_DBG(("%d: SSL[%d]: bad client hello message, len=%d should=%d",
   3550 		 SSL_GETPID(), ss->fd, ss->gs.recordLen,
   3551 		 SSL_HL_CLIENT_HELLO_HBYTES+csLen+sdLen+challengeLen));
   3552 	goto bad_client;
   3553     }
   3554 
   3555     SSL_TRC(3, ("%d: SSL[%d]: client version is %x",
   3556 		SSL_GETPID(), ss->fd, ss->version));
   3557     if (ss->version != SSL_LIBRARY_VERSION_2) {
   3558 	if (ss->version > SSL_LIBRARY_VERSION_2) {
   3559 	    /*
   3560 	    ** Newer client than us. Things are ok because new clients
   3561 	    ** are required to be backwards compatible with old servers.
   3562 	    ** Change version number to our version number so that client
   3563 	    ** knows whats up.
   3564 	    */
   3565 	    ss->version = SSL_LIBRARY_VERSION_2;
   3566 	} else {
   3567 	    SSL_TRC(1, ("%d: SSL[%d]: client version is %x (we are %x)",
   3568 		SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
   3569 	    PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
   3570 	    goto loser;
   3571 	}
   3572     }
   3573 
   3574     /* Qualify cipher specs before returning them to client */
   3575     csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
   3576     if (csLen == 0) {
   3577 	/* no overlap, send client our list of supported SSL v2 ciphers. */
   3578         cs    = csImpl;
   3579 	csLen = sizeof implementedCipherSuites;
   3580     	PORT_Memcpy(cs, implementedCipherSuites, csLen);
   3581 	csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
   3582 	if (csLen == 0) {
   3583 	  /* We don't support any SSL v2 ciphers! */
   3584 	  ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
   3585 	  PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
   3586 	  goto loser;
   3587 	}
   3588 	/* Since this handhsake is going to fail, don't cache it. */
   3589 	ss->opt.noCache = 1;
   3590     }
   3591 
   3592     /* Squirrel away the challenge for later */
   3593     PORT_Memcpy(ss->sec.ci.clientChallenge, challenge, challengeLen);
   3594 
   3595     /* Examine message and see if session-id is good */
   3596     ss->sec.ci.elements = 0;
   3597     if (sdLen > 0 && !ss->opt.noCache) {
   3598 	SSL_TRC(7, ("%d: SSL[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x",
   3599 		    SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0],
   3600 		    ss->sec.ci.peer.pr_s6_addr32[1],
   3601 		    ss->sec.ci.peer.pr_s6_addr32[2],
   3602 		    ss->sec.ci.peer.pr_s6_addr32[3]));
   3603 	sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sd, sdLen, ss->dbHandle);
   3604     } else {
   3605 	sid = NULL;
   3606     }
   3607     if (sid) {
   3608 	/* Got a good session-id. Short cut! */
   3609 	SSL_TRC(1, ("%d: SSL[%d]: server, using session-id for 0x%08x (age=%d)",
   3610 		    SSL_GETPID(), ss->fd, ss->sec.ci.peer,
   3611 		    ssl_Time() - sid->creationTime));
   3612 	PRINT_BUF(1, (ss, "session-id value:", sd, sdLen));
   3613 	ss->sec.ci.sid = sid;
   3614 	ss->sec.ci.elements = CIS_HAVE_MASTER_KEY;
   3615 	hit = 1;
   3616 	certLen = 0;
   3617 	csLen = 0;
   3618 
   3619         ss->sec.authAlgorithm = sid->authAlgorithm;
   3620 	ss->sec.authKeyBits   = sid->authKeyBits;
   3621 	ss->sec.keaType       = sid->keaType;
   3622 	ss->sec.keaKeyBits    = sid->keaKeyBits;
   3623 
   3624 	rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
   3625 	if (rv != SECSuccess) {
   3626 	    goto loser;
   3627 	}
   3628     } else {
   3629 	SECItem * derCert   = &serverCert->derCert;
   3630 
   3631 	SSL_TRC(7, ("%d: SSL[%d]: server, lookup nonce missed",
   3632 		    SSL_GETPID(), ss->fd));
   3633 	if (!serverCert) {
   3634 	    SET_ERROR_CODE
   3635 	    goto loser;
   3636 	}
   3637 	hit = 0;
   3638 	sid = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID));
   3639 	if (!sid) {
   3640 	    goto loser;
   3641 	}
   3642 	sid->references = 1;
   3643 	sid->addr = ss->sec.ci.peer;
   3644 	sid->port = ss->sec.ci.port;
   3645 
   3646 	/* Invent a session-id */
   3647 	ss->sec.ci.sid = sid;
   3648 	PK11_GenerateRandom(sid->u.ssl2.sessionID+2, SSL2_SESSIONID_BYTES-2);
   3649 
   3650 	pid = SSL_GETPID();
   3651 	sid->u.ssl2.sessionID[0] = MSB(pid);
   3652 	sid->u.ssl2.sessionID[1] = LSB(pid);
   3653 	cert    = derCert->data;
   3654 	certLen = derCert->len;
   3655 
   3656 	/* pretend that server sids remember the local cert. */
   3657 	PORT_Assert(!sid->localCert);
   3658 	if (sid->localCert) {
   3659 	    CERT_DestroyCertificate(sid->localCert);
   3660 	}
   3661 	sid->localCert     = CERT_DupCertificate(serverCert);
   3662 
   3663 	ss->sec.authAlgorithm = ssl_sign_rsa;
   3664 	ss->sec.keaType       = ssl_kea_rsa;
   3665 	ss->sec.keaKeyBits    = \
   3666 	ss->sec.authKeyBits   = ss->serverCerts[kt_rsa].serverKeyBits;
   3667     }
   3668 
   3669     /* server sids don't remember the local cert, so whether we found
   3670     ** a sid or not, just "remember" we used the rsa server cert.
   3671     */
   3672     if (ss->sec.localCert) {
   3673 	CERT_DestroyCertificate(ss->sec.localCert);
   3674     }
   3675     ss->sec.localCert     = CERT_DupCertificate(serverCert);
   3676 
   3677     /* Build up final list of required elements */
   3678     ss->sec.ci.requiredElements = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED;
   3679     if (ss->opt.requestCertificate) {
   3680 	ss->sec.ci.requiredElements |= CIS_HAVE_CERTIFICATE;
   3681     }
   3682     ss->sec.ci.sentElements = 0;
   3683 
   3684     /* Send hello message back to client */
   3685     sendLen = SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen
   3686 	    + SSL_CONNECTIONID_BYTES;
   3687 
   3688     ssl_GetXmitBufLock(ss); gotXmitBufLock = 1;
   3689     rv = ssl2_GetSendBuffer(ss, sendLen);
   3690     if (rv != SECSuccess) {
   3691 	goto loser;
   3692     }
   3693 
   3694     SSL_TRC(3, ("%d: SSL[%d]: sending server-hello (%d)",
   3695 		SSL_GETPID(), ss->fd, sendLen));
   3696 
   3697     msg = ss->sec.ci.sendBuf.buf;
   3698     msg[0] = SSL_MT_SERVER_HELLO;
   3699     msg[1] = hit;
   3700     msg[2] = SSL_CT_X509_CERTIFICATE;
   3701     msg[3] = MSB(ss->version);
   3702     msg[4] = LSB(ss->version);
   3703     msg[5] = MSB(certLen);
   3704     msg[6] = LSB(certLen);
   3705     msg[7] = MSB(csLen);
   3706     msg[8] = LSB(csLen);
   3707     msg[9] = MSB(SSL_CONNECTIONID_BYTES);
   3708     msg[10] = LSB(SSL_CONNECTIONID_BYTES);
   3709     if (certLen) {
   3710 	PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES, cert, certLen);
   3711     }
   3712     if (csLen) {
   3713 	PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen, cs, csLen);
   3714     }
   3715     PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen+csLen,
   3716                 ss->sec.ci.connectionID, SSL_CONNECTIONID_BYTES);
   3717 
   3718     DUMP_MSG(29, (ss, msg, sendLen));
   3719 
   3720     ss->handshakeBegun = 1;
   3721     sent = (*ss->sec.send)(ss, msg, sendLen, 0);
   3722     if (sent < 0) {
   3723 	goto loser;
   3724     }
   3725     ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0;
   3726 
   3727     ss->gs.recordLen = 0;
   3728     ss->handshake = ssl_GatherRecord1stHandshake;
   3729     if (hit) {
   3730 	/* Old SID Session key is good. Go encrypted */
   3731 	ssl2_UseEncryptedSendFunc(ss);
   3732 
   3733 	/* Send server verify message now that keys are established */
   3734 	rv = ssl2_SendServerVerifyMessage(ss);
   3735 	if (rv != SECSuccess)
   3736 	    goto loser;
   3737 
   3738 	ss->nextHandshake = ssl2_HandleMessage;
   3739 	ssl_ReleaseRecvBufLock(ss);
   3740 	rv = ssl2_TriggerNextMessage(ss);
   3741 	return rv;
   3742     }
   3743     ss->nextHandshake = ssl2_HandleClientSessionKeyMessage;
   3744     ssl_ReleaseRecvBufLock(ss);
   3745     return SECSuccess;
   3746 
   3747   bad_client:
   3748     PORT_SetError(SSL_ERROR_BAD_CLIENT);
   3749     /* FALLTHROUGH */
   3750 
   3751   loser:
   3752     if (gotXmitBufLock) {
   3753     	ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0;
   3754     }
   3755     SSL_TRC(10, ("%d: SSL[%d]: server, wait for client-hello lossage",
   3756 		 SSL_GETPID(), ss->fd));
   3757     ssl_ReleaseRecvBufLock(ss);
   3758     return SECFailure;
   3759 }
   3760 
   3761 SECStatus
   3762 ssl2_BeginServerHandshake(sslSocket *ss)
   3763 {
   3764     SECStatus        rv;
   3765     sslServerCerts * rsaAuth = ss->serverCerts + kt_rsa;
   3766 
   3767     ss->sec.isServer = 1;
   3768     ssl_ChooseSessionIDProcs(&ss->sec);
   3769     ss->sec.sendSequence = 0;
   3770     ss->sec.rcvSequence = 0;
   3771 
   3772     /* don't turn on SSL2 if we don't have an RSA key and cert */
   3773     if (!rsaAuth->serverKeyPair || !rsaAuth->SERVERKEY ||
   3774         !rsaAuth->serverCert) {
   3775 	ss->opt.enableSSL2 = PR_FALSE;
   3776     }
   3777 
   3778     if (!ss->cipherSpecs) {
   3779 	rv = ssl2_ConstructCipherSpecs(ss);
   3780 	if (rv != SECSuccess)
   3781 	    goto loser;
   3782     }
   3783 
   3784     /* count the SSL2 and SSL3 enabled ciphers.
   3785      * if either is zero, clear the socket's enable for that protocol.
   3786      */
   3787     rv = ssl2_CheckConfigSanity(ss);
   3788     if (rv != SECSuccess)
   3789 	goto loser;
   3790 
   3791     /*
   3792     ** Generate connection-id. Always do this, even if things fail
   3793     ** immediately. This way the random number generator is always
   3794     ** rolling around, every time we get a connection.
   3795     */
   3796     PK11_GenerateRandom(ss->sec.ci.connectionID,
   3797                         sizeof(ss->sec.ci.connectionID));
   3798 
   3799     ss->gs.recordLen = 0;
   3800     ss->handshake     = ssl_GatherRecord1stHandshake;
   3801     ss->nextHandshake = ssl2_HandleClientHelloMessage;
   3802     return SECSuccess;
   3803 
   3804 loser:
   3805     return SECFailure;
   3806 }
   3807 
   3808 /* This function doesn't really belong in this file.
   3809 ** It's here to keep AIX compilers from optimizing it away,
   3810 ** and not including it in the DSO.
   3811 */
   3812 
   3813 #include "nss.h"
   3814 extern const char __nss_ssl_rcsid[];
   3815 extern const char __nss_ssl_sccsid[];
   3816 
   3817 PRBool
   3818 NSSSSL_VersionCheck(const char *importedVersion)
   3819 {
   3820     /*
   3821      * This is the secret handshake algorithm.
   3822      *
   3823      * This release has a simple version compatibility
   3824      * check algorithm.  This release is not backward
   3825      * compatible with previous major releases.  It is
   3826      * not compatible with future major, minor, or
   3827      * patch releases.
   3828      */
   3829     volatile char c; /* force a reference that won't get optimized away */
   3830 
   3831     c = __nss_ssl_rcsid[0] + __nss_ssl_sccsid[0];
   3832     return NSS_VersionCheck(importedVersion);
   3833 }
   3834