/* 
 * SSL v2 handshake functions, and functions common to SSL2 and SSL3.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nssrenam.h"
#include "cert.h"
#include "secitem.h"
#include "sechash.h"
#include "cryptohi.h"		/* for SGN_ funcs */
#include "keyhi.h" 		/* for SECKEY_ high level functions. */
#include "ssl.h"
#include "sslimpl.h"
#include "sslproto.h"
#include "ssl3prot.h"
#include "sslerr.h"
#include "pk11func.h"
#include "prinit.h"
#include "prtime.h" 	/* for PR_Now() */

static PRBool policyWasSet;

/* This ordered list is indexed by (SSL_CK_xx * 3)   */
/* Second and third bytes are MSB and LSB of master key length. */
static const PRUint8 allCipherSuites[] = {
    0,						0,    0,
    SSL_CK_RC4_128_WITH_MD5,			0x00, 0x80,
    SSL_CK_RC4_128_EXPORT40_WITH_MD5,		0x00, 0x80,
    SSL_CK_RC2_128_CBC_WITH_MD5,		0x00, 0x80,
    SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5,	0x00, 0x80,
    SSL_CK_IDEA_128_CBC_WITH_MD5,		0x00, 0x80,
    SSL_CK_DES_64_CBC_WITH_MD5,			0x00, 0x40,
    SSL_CK_DES_192_EDE3_CBC_WITH_MD5,		0x00, 0xC0,
    0,						0,    0
};

#define ssl2_NUM_SUITES_IMPLEMENTED 6

/* This list is sent back to the client when the client-hello message 
 * contains no overlapping ciphers, so the client can report what ciphers
 * are supported by the server.  Unlike allCipherSuites (above), this list
 * is sorted by descending preference, not by cipherSuite number. 
 */
static const PRUint8 implementedCipherSuites[ssl2_NUM_SUITES_IMPLEMENTED * 3] = {
    SSL_CK_RC4_128_WITH_MD5,			0x00, 0x80,
    SSL_CK_RC2_128_CBC_WITH_MD5,		0x00, 0x80,
    SSL_CK_DES_192_EDE3_CBC_WITH_MD5,		0x00, 0xC0,
    SSL_CK_DES_64_CBC_WITH_MD5,			0x00, 0x40,
    SSL_CK_RC4_128_EXPORT40_WITH_MD5,		0x00, 0x80,
    SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5,	0x00, 0x80
};

typedef struct ssl2SpecsStr {
    PRUint8           nkm; /* do this many hashes to generate key material. */
    PRUint8           nkd; /* size of readKey and writeKey in bytes. */
    PRUint8           blockSize;
    PRUint8           blockShift;
    CK_MECHANISM_TYPE mechanism;
    PRUint8           keyLen;	/* cipher symkey size in bytes. */
    PRUint8           pubLen;	/* publicly reveal this many bytes of key. */
    PRUint8           ivLen;	/* length of IV data at *ca.	*/
} ssl2Specs;

static const ssl2Specs ssl_Specs[] = {
/* NONE                                 */ 
				{  0,  0, 0, 0, },
/* SSL_CK_RC4_128_WITH_MD5		*/ 
				{  2, 16, 1, 0, CKM_RC4,       16,   0, 0, },
/* SSL_CK_RC4_128_EXPORT40_WITH_MD5	*/ 
				{  2, 16, 1, 0, CKM_RC4,       16,  11, 0, },
/* SSL_CK_RC2_128_CBC_WITH_MD5		*/ 
				{  2, 16, 8, 3, CKM_RC2_CBC,   16,   0, 8, },
/* SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5	*/ 
				{  2, 16, 8, 3, CKM_RC2_CBC,   16,  11, 8, },
/* SSL_CK_IDEA_128_CBC_WITH_MD5		*/ 
				{  0,  0, 0, 0, },
/* SSL_CK_DES_64_CBC_WITH_MD5		*/ 
				{  1,  8, 8, 3, CKM_DES_CBC,    8,   0, 8, },
/* SSL_CK_DES_192_EDE3_CBC_WITH_MD5	*/ 
				{  3, 24, 8, 3, CKM_DES3_CBC,  24,   0, 8, },
};

#define SET_ERROR_CODE	  /* reminder */
#define TEST_FOR_FAILURE  /* reminder */

/*
** Put a string tag in the library so that we can examine an executable
** and see what kind of security it supports.
*/
const char *ssl_version = "SECURITY_VERSION:"
			" +us"
			" +export"
#ifdef TRACE
			" +trace"
#endif
#ifdef DEBUG
			" +debug"
#endif
			;

const char * const ssl_cipherName[] = {
    "unknown",
    "RC4",
    "RC4-Export",
    "RC2-CBC",
    "RC2-CBC-Export",
    "IDEA-CBC",
    "DES-CBC",
    "DES-EDE3-CBC",
    "unknown",
    "unknown", /* was fortezza, NO LONGER USED */
};


/* bit-masks, showing which SSLv2 suites are allowed.
 * lsb corresponds to first cipher suite in allCipherSuites[].
 */
static PRUint16	allowedByPolicy;          /* all off by default */
static PRUint16	maybeAllowedByPolicy;     /* all off by default */
static PRUint16	chosenPreference = 0xff;  /* all on  by default */

/* bit values for the above two bit masks */
#define SSL_CB_RC4_128_WITH_MD5              (1 << SSL_CK_RC4_128_WITH_MD5)
#define SSL_CB_RC4_128_EXPORT40_WITH_MD5     (1 << SSL_CK_RC4_128_EXPORT40_WITH_MD5)
#define SSL_CB_RC2_128_CBC_WITH_MD5          (1 << SSL_CK_RC2_128_CBC_WITH_MD5)
#define SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)
#define SSL_CB_IDEA_128_CBC_WITH_MD5         (1 << SSL_CK_IDEA_128_CBC_WITH_MD5)
#define SSL_CB_DES_64_CBC_WITH_MD5           (1 << SSL_CK_DES_64_CBC_WITH_MD5)
#define SSL_CB_DES_192_EDE3_CBC_WITH_MD5     (1 << SSL_CK_DES_192_EDE3_CBC_WITH_MD5)
#define SSL_CB_IMPLEMENTED \
   (SSL_CB_RC4_128_WITH_MD5              | \
    SSL_CB_RC4_128_EXPORT40_WITH_MD5     | \
    SSL_CB_RC2_128_CBC_WITH_MD5          | \
    SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 | \
    SSL_CB_DES_64_CBC_WITH_MD5           | \
    SSL_CB_DES_192_EDE3_CBC_WITH_MD5)


/* Construct a socket's list of cipher specs from the global default values.
 */
static SECStatus
ssl2_ConstructCipherSpecs(sslSocket *ss) 
{
    PRUint8 *	        cs		= NULL;
    unsigned int	allowed;
    unsigned int	count;
    int 		ssl3_count	= 0;
    int 		final_count;
    int 		i;
    SECStatus 		rv;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    count = 0;
    PORT_Assert(ss != 0);
    allowed = !ss->opt.enableSSL2 ? 0 :
    	(ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED);
    while (allowed) {
    	if (allowed & 1) 
	    ++count;
	allowed >>= 1;
    }

    /* Call ssl3_config_match_init() once here, 
     * instead of inside ssl3_ConstructV2CipherSpecsHack(),
     * because the latter gets called twice below, 
     * and then again in ssl2_BeginClientHandshake().
     */
    ssl3_config_match_init(ss);

    /* ask SSL3 how many cipher suites it has. */
    rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3_count);
    if (rv < 0) 
	return rv;
    count += ssl3_count;

    /* Allocate memory to hold cipher specs */
    if (count > 0)
	cs = (PRUint8*) PORT_Alloc(count * 3);
    else
	PORT_SetError(SSL_ERROR_SSL_DISABLED);
    if (cs == NULL)
    	return SECFailure;

    if (ss->cipherSpecs != NULL) {
	PORT_Free(ss->cipherSpecs);
    }
    ss->cipherSpecs     = cs;
    ss->sizeCipherSpecs = count * 3;

    /* fill in cipher specs for SSL2 cipher suites */
    allowed = !ss->opt.enableSSL2 ? 0 :
    	(ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED);
    for (i = 0; i < ssl2_NUM_SUITES_IMPLEMENTED * 3; i += 3) {
	const PRUint8 * hs = implementedCipherSuites + i;
	int             ok = allowed & (1U << hs[0]);
	if (ok) {
	    cs[0] = hs[0];
	    cs[1] = hs[1];
	    cs[2] = hs[2];
	    cs += 3;
	}
    }

    /* now have SSL3 add its suites onto the end */
    rv = ssl3_ConstructV2CipherSpecsHack(ss, cs, &final_count);
    
    /* adjust for any difference between first pass and second pass */
    ss->sizeCipherSpecs -= (ssl3_count - final_count) * 3;

    return rv;
}

/* This function is called immediately after ssl2_ConstructCipherSpecs()
** at the beginning of a handshake.  It detects cases where a protocol
** (e.g. SSL2 or SSL3) is logically enabled, but all its cipher suites
** for that protocol have been disabled.  If such cases, it clears the 
** enable bit for the protocol.  If no protocols remain enabled, or
** if no cipher suites are found, it sets the error code and returns
** SECFailure, otherwise it returns SECSuccess.
*/
static SECStatus
ssl2_CheckConfigSanity(sslSocket *ss)
{
    unsigned int      allowed;
    int               ssl3CipherCount = 0;
    SECStatus         rv;

    /* count the SSL2 and SSL3 enabled ciphers.
     * if either is zero, clear the socket's enable for that protocol.
     */
    if (!ss->cipherSpecs)
    	goto disabled;

    allowed = ss->allowedByPolicy & ss->chosenPreference;
    if (! allowed)
	ss->opt.enableSSL2 = PR_FALSE; /* not really enabled if no ciphers */

    /* ssl3_config_match_init was called in ssl2_ConstructCipherSpecs(). */
    /* Ask how many ssl3 CipherSuites were enabled. */
    rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3CipherCount);
    if (rv != SECSuccess || ssl3CipherCount <= 0) {
	/* SSL3/TLS not really enabled if no ciphers */
	ss->vrange.min = SSL_LIBRARY_VERSION_NONE;
	ss->vrange.max = SSL_LIBRARY_VERSION_NONE;
    }

    if (!ss->opt.enableSSL2 && SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
	SSL_DBG(("%d: SSL[%d]: Can't handshake! all versions disabled.",
		 SSL_GETPID(), ss->fd));
disabled:
	PORT_SetError(SSL_ERROR_SSL_DISABLED);
	return SECFailure;
    }
    return SECSuccess;
}

/* 
 * Since this is a global (not per-socket) setting, we cannot use the
 * HandshakeLock to protect this.  Probably want a global lock.
 */
SECStatus
ssl2_SetPolicy(PRInt32 which, PRInt32 policy)
{
    PRUint32  bitMask;
    SECStatus rv       = SECSuccess;

    which &= 0x000f;
    bitMask = 1 << which;

    if (!(bitMask & SSL_CB_IMPLEMENTED)) {
    	PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
    	return SECFailure;
    }

    if (policy == SSL_ALLOWED) {
	allowedByPolicy 	|= bitMask;
	maybeAllowedByPolicy 	|= bitMask;
    } else if (policy == SSL_RESTRICTED) {
    	allowedByPolicy 	&= ~bitMask;
	maybeAllowedByPolicy 	|= bitMask;
    } else {
    	allowedByPolicy 	&= ~bitMask;
    	maybeAllowedByPolicy 	&= ~bitMask;
    }
    allowedByPolicy 		&= SSL_CB_IMPLEMENTED;
    maybeAllowedByPolicy 	&= SSL_CB_IMPLEMENTED;

    policyWasSet = PR_TRUE;
    return rv;
}

SECStatus
ssl2_GetPolicy(PRInt32 which, PRInt32 *oPolicy)
{
    PRUint32     bitMask;
    PRInt32      policy;

    which &= 0x000f;
    bitMask = 1 << which;

    /* Caller assures oPolicy is not null. */
    if (!(bitMask & SSL_CB_IMPLEMENTED)) {
    	PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
	*oPolicy = SSL_NOT_ALLOWED;
    	return SECFailure;
    }

    if (maybeAllowedByPolicy & bitMask) {
    	policy = (allowedByPolicy & bitMask) ? SSL_ALLOWED : SSL_RESTRICTED;
    } else {
	policy = SSL_NOT_ALLOWED;
    }

    *oPolicy = policy;
    return SECSuccess;
}

/* 
 * Since this is a global (not per-socket) setting, we cannot use the
 * HandshakeLock to protect this.  Probably want a global lock.
 * Called from SSL_CipherPrefSetDefault in sslsock.c
 * These changes have no effect on any sslSockets already created. 
 */
SECStatus
ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
{
    PRUint32     bitMask;
    
    which &= 0x000f;
    bitMask = 1 << which;

    if (!(bitMask & SSL_CB_IMPLEMENTED)) {
    	PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
    	return SECFailure;
    }

    if (enabled)
	chosenPreference |= bitMask;
    else
    	chosenPreference &= ~bitMask;
    chosenPreference &= SSL_CB_IMPLEMENTED;

    return SECSuccess;
}

SECStatus 
ssl2_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
{
    PRBool       rv       = PR_FALSE;
    PRUint32     bitMask;

    which &= 0x000f;
    bitMask = 1 << which;

    if (!(bitMask & SSL_CB_IMPLEMENTED)) {
    	PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
	*enabled = PR_FALSE;
    	return SECFailure;
    }

    rv = (PRBool)((chosenPreference & bitMask) != 0);
    *enabled = rv;
    return SECSuccess;
}

SECStatus 
ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled)
{
    PRUint32     bitMask;
    
    which &= 0x000f;
    bitMask = 1 << which;

    if (!(bitMask & SSL_CB_IMPLEMENTED)) {
    	PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
    	return SECFailure;
    }

    if (enabled)
	ss->chosenPreference |= bitMask;
    else
    	ss->chosenPreference &= ~bitMask;
    ss->chosenPreference &= SSL_CB_IMPLEMENTED;

    return SECSuccess;
}

SECStatus 
ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled)
{
    PRBool       rv       = PR_FALSE;
    PRUint32     bitMask;

    which &= 0x000f;
    bitMask = 1 << which;

    if (!(bitMask & SSL_CB_IMPLEMENTED)) {
    	PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
	*enabled = PR_FALSE;
    	return SECFailure;
    }

    rv = (PRBool)((ss->chosenPreference & bitMask) != 0);
    *enabled = rv;
    return SECSuccess;
}


/* copy global default policy into socket. */
void      
ssl2_InitSocketPolicy(sslSocket *ss)
{
    ss->allowedByPolicy		= allowedByPolicy;
    ss->maybeAllowedByPolicy	= maybeAllowedByPolicy;
    ss->chosenPreference 	= chosenPreference;
}


/************************************************************************/

/* Called from ssl2_CreateSessionCypher(), which already holds handshake lock.
 */
static SECStatus
ssl2_CreateMAC(sslSecurityInfo *sec, SECItem *readKey, SECItem *writeKey, 
          int cipherChoice)
{
    switch (cipherChoice) {
      case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
      case SSL_CK_RC2_128_CBC_WITH_MD5:
      case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
      case SSL_CK_RC4_128_WITH_MD5:
      case SSL_CK_DES_64_CBC_WITH_MD5:
      case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
	sec->hash = HASH_GetHashObject(HASH_AlgMD5);
	if (SECITEM_CopyItem(0, &sec->sendSecret, writeKey) ||
	    SECITEM_CopyItem(0, &sec->rcvSecret, readKey)) {
	    return SECFailure;
	}
	break;

      default:
	PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
	return SECFailure;
    }
    sec->hashcx = (*sec->hash->create)();
    if (sec->hashcx == NULL)
	return SECFailure;
    return SECSuccess;
}

/************************************************************************
 * All the Send functions below must acquire and release the socket's 
 * xmitBufLock.
 */

/* Called from all the Send* functions below. */
static SECStatus
ssl2_GetSendBuffer(sslSocket *ss, unsigned int len)
{
    SECStatus rv = SECSuccess;

    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));

    if (len < 128) {
	len = 128;
    }
    if (len > ss->sec.ci.sendBuf.space) {
	rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, len);
	if (rv != SECSuccess) {
	    SSL_DBG(("%d: SSL[%d]: ssl2_GetSendBuffer failed, tried to get %d bytes",
		     SSL_GETPID(), ss->fd, len));
	    rv = SECFailure;
	}
    }
    return rv;
}

/* Called from:
 * ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
 * ssl2_HandleRequestCertificate()     <- ssl2_HandleMessage() <- 
 					ssl_Do1stHandshake()
 * ssl2_HandleMessage()                <- ssl_Do1stHandshake()
 * ssl2_HandleServerHelloMessage() <- ssl_Do1stHandshake()
                                     after ssl2_BeginClientHandshake()
 * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake() 
                                     after ssl2_BeginServerHandshake()
 * 
 * Acquires and releases the socket's xmitBufLock.
 */	
int
ssl2_SendErrorMessage(sslSocket *ss, int error)
{
    int rv;
    PRUint8 msg[SSL_HL_ERROR_HBYTES];

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    msg[0] = SSL_MT_ERROR;
    msg[1] = MSB(error);
    msg[2] = LSB(error);

    ssl_GetXmitBufLock(ss);    /***************************************/

    SSL_TRC(3, ("%d: SSL[%d]: sending error %d", SSL_GETPID(), ss->fd, error));

    ss->handshakeBegun = 1;
    rv = (*ss->sec.send)(ss, msg, sizeof(msg), 0);
    if (rv >= 0) {
	rv = SECSuccess;
    }
    ssl_ReleaseXmitBufLock(ss);    /***************************************/
    return rv;
}

/* Called from ssl2_TryToFinish().  
 * Acquires and releases the socket's xmitBufLock.
 */
static SECStatus
ssl2_SendClientFinishedMessage(sslSocket *ss)
{
    SECStatus        rv    = SECSuccess;
    int              sent;
    PRUint8    msg[1 + SSL_CONNECTIONID_BYTES];

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    ssl_GetXmitBufLock(ss);    /***************************************/

    if (ss->sec.ci.sentFinished == 0) {
	ss->sec.ci.sentFinished = 1;

	SSL_TRC(3, ("%d: SSL[%d]: sending client-finished",
		    SSL_GETPID(), ss->fd));

	msg[0] = SSL_MT_CLIENT_FINISHED;
	PORT_Memcpy(msg+1, ss->sec.ci.connectionID, 
	            sizeof(ss->sec.ci.connectionID));

	DUMP_MSG(29, (ss, msg, 1 + sizeof(ss->sec.ci.connectionID)));
	sent = (*ss->sec.send)(ss, msg, 1 + sizeof(ss->sec.ci.connectionID), 0);
	rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
    }
    ssl_ReleaseXmitBufLock(ss);    /***************************************/
    return rv;
}

/* Called from 
 * ssl2_HandleClientSessionKeyMessage() <- ssl2_HandleClientHelloMessage()
 * ssl2_HandleClientHelloMessage()  <- ssl_Do1stHandshake() 
                                      after ssl2_BeginServerHandshake()
 * Acquires and releases the socket's xmitBufLock.
 */
static SECStatus
ssl2_SendServerVerifyMessage(sslSocket *ss)
{
    PRUint8 *        msg;
    int              sendLen;
    int              sent;
    SECStatus        rv;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    ssl_GetXmitBufLock(ss);    /***************************************/

    sendLen = 1 + SSL_CHALLENGE_BYTES;
    rv = ssl2_GetSendBuffer(ss, sendLen);
    if (rv != SECSuccess) {
	goto done;
    }

    msg = ss->sec.ci.sendBuf.buf;
    msg[0] = SSL_MT_SERVER_VERIFY;
    PORT_Memcpy(msg+1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);

    DUMP_MSG(29, (ss, msg, sendLen));
    sent = (*ss->sec.send)(ss, msg, sendLen, 0);

    rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;

done:
    ssl_ReleaseXmitBufLock(ss);    /***************************************/
    return rv;
}

/* Called from ssl2_TryToFinish(). 
 * Acquires and releases the socket's xmitBufLock.
 */
static SECStatus
ssl2_SendServerFinishedMessage(sslSocket *ss)
{
    sslSessionID *   sid;
    PRUint8 *        msg;
    int              sendLen, sent;
    SECStatus        rv    = SECSuccess;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    ssl_GetXmitBufLock(ss);    /***************************************/

    if (ss->sec.ci.sentFinished == 0) {
	ss->sec.ci.sentFinished = 1;
	PORT_Assert(ss->sec.ci.sid != 0);
	sid = ss->sec.ci.sid;

	SSL_TRC(3, ("%d: SSL[%d]: sending server-finished",
		    SSL_GETPID(), ss->fd));

	sendLen = 1 + sizeof(sid->u.ssl2.sessionID);
	rv = ssl2_GetSendBuffer(ss, sendLen);
	if (rv != SECSuccess) {
	    goto done;
	}

	msg = ss->sec.ci.sendBuf.buf;
	msg[0] = SSL_MT_SERVER_FINISHED;
	PORT_Memcpy(msg+1, sid->u.ssl2.sessionID,
		    sizeof(sid->u.ssl2.sessionID));

	DUMP_MSG(29, (ss, msg, sendLen));
	sent = (*ss->sec.send)(ss, msg, sendLen, 0);

	if (sent < 0) {
	    /* If send failed, it is now a bogus  session-id */
	    if (ss->sec.uncache)
		(*ss->sec.uncache)(sid);
	    rv = (SECStatus)sent;
	} else if (!ss->opt.noCache) {
	    if (sid->cached == never_cached) {
		(*ss->sec.cache)(sid);
	    }
	    rv = SECSuccess;
	}
	ssl_FreeSID(sid);
	ss->sec.ci.sid = 0;
    }
done:
    ssl_ReleaseXmitBufLock(ss);    /***************************************/
    return rv;
}

/* Called from ssl2_ClientSetupSessionCypher() <- 
 *						ssl2_HandleServerHelloMessage() 
 *                                           after ssl2_BeginClientHandshake()
 * Acquires and releases the socket's xmitBufLock.
 */
static SECStatus
ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize,
		      PRUint8 *ca, int caLen,
		      PRUint8 *ck, int ckLen,
		      PRUint8 *ek, int ekLen)
{
    PRUint8 *        msg;
    int              sendLen;
    int              sent;
    SECStatus        rv;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    ssl_GetXmitBufLock(ss);    /***************************************/

    sendLen = SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen;
    rv = ssl2_GetSendBuffer(ss, sendLen);
    if (rv != SECSuccess) 
	goto done;

    SSL_TRC(3, ("%d: SSL[%d]: sending client-session-key",
		SSL_GETPID(), ss->fd));

    msg = ss->sec.ci.sendBuf.buf;
    msg[0] = SSL_MT_CLIENT_MASTER_KEY;
    msg[1] = cipher;
    msg[2] = MSB(keySize);
    msg[3] = LSB(keySize);
    msg[4] = MSB(ckLen);
    msg[5] = LSB(ckLen);
    msg[6] = MSB(ekLen);
    msg[7] = LSB(ekLen);
    msg[8] = MSB(caLen);
    msg[9] = LSB(caLen);
    PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES, ck, ckLen);
    PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen, ek, ekLen);
    PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen+ekLen, ca, caLen);

    DUMP_MSG(29, (ss, msg, sendLen));
    sent = (*ss->sec.send)(ss, msg, sendLen, 0);
    rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
done:
    ssl_ReleaseXmitBufLock(ss);    /***************************************/
    return rv;
}

/* Called from ssl2_TriggerNextMessage() <- ssl2_HandleMessage() 
 * Acquires and releases the socket's xmitBufLock.
 */
static SECStatus
ssl2_SendCertificateRequestMessage(sslSocket *ss)
{
    PRUint8 *        msg;
    int              sent;
    int              sendLen;
    SECStatus        rv;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    ssl_GetXmitBufLock(ss);    /***************************************/

    sendLen = SSL_HL_REQUEST_CERTIFICATE_HBYTES + SSL_CHALLENGE_BYTES;
    rv = ssl2_GetSendBuffer(ss, sendLen);
    if (rv != SECSuccess) 
	goto done;

    SSL_TRC(3, ("%d: SSL[%d]: sending certificate request",
		SSL_GETPID(), ss->fd));

    /* Generate random challenge for client to encrypt */
    PK11_GenerateRandom(ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);

    msg = ss->sec.ci.sendBuf.buf;
    msg[0] = SSL_MT_REQUEST_CERTIFICATE;
    msg[1] = SSL_AT_MD5_WITH_RSA_ENCRYPTION;
    PORT_Memcpy(msg + SSL_HL_REQUEST_CERTIFICATE_HBYTES, 
                ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);

    DUMP_MSG(29, (ss, msg, sendLen));
    sent = (*ss->sec.send)(ss, msg, sendLen, 0);
    rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
done:
    ssl_ReleaseXmitBufLock(ss);    /***************************************/
    return rv;
}

/* Called from ssl2_HandleRequestCertificate() <- ssl2_HandleMessage()
 * Acquires and releases the socket's xmitBufLock.
 */
static int
ssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert, 
                                    SECItem *encCode)
{
    PRUint8 *msg;
    int rv, sendLen;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    ssl_GetXmitBufLock(ss);    /***************************************/

    sendLen = SSL_HL_CLIENT_CERTIFICATE_HBYTES + encCode->len + cert->len;
    rv = ssl2_GetSendBuffer(ss, sendLen);
    if (rv) 
    	goto done;

    SSL_TRC(3, ("%d: SSL[%d]: sending certificate response",
		SSL_GETPID(), ss->fd));

    msg = ss->sec.ci.sendBuf.buf;
    msg[0] = SSL_MT_CLIENT_CERTIFICATE;
    msg[1] = SSL_CT_X509_CERTIFICATE;
    msg[2] = MSB(cert->len);
    msg[3] = LSB(cert->len);
    msg[4] = MSB(encCode->len);
    msg[5] = LSB(encCode->len);
    PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES, cert->data, cert->len);
    PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES + cert->len,
	      encCode->data, encCode->len);

    DUMP_MSG(29, (ss, msg, sendLen));
    rv = (*ss->sec.send)(ss, msg, sendLen, 0);
    if (rv >= 0) {
	rv = SECSuccess;
    }
done:
    ssl_ReleaseXmitBufLock(ss);    /***************************************/
    return rv;
}

/********************************************************************
**  Send functions above this line must aquire & release the socket's   
**	xmitBufLock.  
** All the ssl2_Send functions below this line are called vis ss->sec.send
**	and require that the caller hold the xmitBufLock.
*/

/*
** Called from ssl2_SendStream, ssl2_SendBlock, but not from ssl2_SendClear.
*/
static SECStatus
ssl2_CalcMAC(PRUint8             * result, 
	     sslSecurityInfo     * sec,
	     const PRUint8       * data, 
	     unsigned int          dataLen,
	     unsigned int          paddingLen)
{
    const PRUint8 *      secret		= sec->sendSecret.data;
    unsigned int         secretLen	= sec->sendSecret.len;
    unsigned long        sequenceNumber = sec->sendSequence;
    unsigned int         nout;
    PRUint8              seq[4];
    PRUint8              padding[32];/* XXX max blocksize? */

    if (!sec->hash || !sec->hash->length)
    	return SECSuccess;
    if (!sec->hashcx)
    	return SECFailure;

    /* Reset hash function */
    (*sec->hash->begin)(sec->hashcx);

    /* Feed hash the data */
    (*sec->hash->update)(sec->hashcx, secret, secretLen);
    (*sec->hash->update)(sec->hashcx, data, dataLen);
    PORT_Memset(padding, paddingLen, paddingLen);
    (*sec->hash->update)(sec->hashcx, padding, paddingLen);

    seq[0] = (PRUint8) (sequenceNumber >> 24);
    seq[1] = (PRUint8) (sequenceNumber >> 16);
    seq[2] = (PRUint8) (sequenceNumber >> 8);
    seq[3] = (PRUint8) (sequenceNumber);

    PRINT_BUF(60, (0, "calc-mac secret:", secret, secretLen));
    PRINT_BUF(60, (0, "calc-mac data:", data, dataLen));
    PRINT_BUF(60, (0, "calc-mac padding:", padding, paddingLen));
    PRINT_BUF(60, (0, "calc-mac seq:", seq, 4));

    (*sec->hash->update)(sec->hashcx, seq, 4);

    /* Get result */
    (*sec->hash->end)(sec->hashcx, result, &nout, sec->hash->length);

    return SECSuccess;
}

/*
** Maximum transmission amounts. These are tiny bit smaller than they
** need to be (they account for the MAC length plus some padding),
** assuming the MAC is 16 bytes long and the padding is a max of 7 bytes
** long. This gives an additional 9 bytes of slop to work within.
*/
#define MAX_STREAM_CYPHER_LEN	0x7fe0
#define MAX_BLOCK_CYPHER_LEN	0x3fe0

/*
** Send some data in the clear. 
** Package up data with the length header and send it.
**
** Return count of bytes successfully written, or negative number (failure).
*/
static PRInt32 
ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
{
    PRUint8         * out;
    int               rv;
    int               amount;
    int               count	= 0;

    PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );

    SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes in the clear",
		 SSL_GETPID(), ss->fd, len));
    PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len));

    while (len) {
	amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN );
	if (amount + 2 > ss->sec.writeBuf.space) {
	    rv = sslBuffer_Grow(&ss->sec.writeBuf, amount + 2);
	    if (rv != SECSuccess) {
		count = rv;
		break;
	    }
	}
	out = ss->sec.writeBuf.buf;

	/*
	** Construct message.
	*/
	out[0] = 0x80 | MSB(amount);
	out[1] = LSB(amount);
	PORT_Memcpy(&out[2], in, amount);

	/* Now send the data */
	rv = ssl_DefSend(ss, out, amount + 2, flags & ~ssl_SEND_FLAG_MASK);
	if (rv < 0) {
	    if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
		rv = 0;
	    } else {
		/* Return short write if some data already went out... */
		if (count == 0)
		    count = rv;
		break;
	    }
	}

	if ((unsigned)rv < (amount + 2)) {
	    /* Short write.  Save the data and return. */
	    if (ssl_SaveWriteData(ss, out + rv, amount + 2 - rv) 
	        == SECFailure) {
		count = SECFailure;
	    } else {
		count += amount;
		ss->sec.sendSequence++;
	    }
	    break;
	}

	ss->sec.sendSequence++;
	in    += amount;
	count += amount;
	len   -= amount;
    }

    return count;
}

/*
** Send some data, when using a stream cipher. Stream ciphers have a
** block size of 1. Package up the data with the length header
** and send it.
*/
static PRInt32 
ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
{
    PRUint8       *  out;
    int              rv;
    int              count	= 0;

    int              amount;
    PRUint8          macLen;
    int              nout;
    int              buflen;

    PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );

    SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using stream cipher",
		 SSL_GETPID(), ss->fd, len));
    PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len));

    while (len) {
	ssl_GetSpecReadLock(ss);  /*************************************/

	macLen = ss->sec.hash->length;
	amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN );
	buflen = amount + 2 + macLen;
	if (buflen > ss->sec.writeBuf.space) {
	    rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen);
	    if (rv != SECSuccess) {
		goto loser;
	    }
	}
	out    = ss->sec.writeBuf.buf;
	nout   = amount + macLen;
	out[0] = 0x80 | MSB(nout);
	out[1] = LSB(nout);

	/* Calculate MAC */
	rv = ssl2_CalcMAC(out+2, 		/* put MAC here */
	                  &ss->sec, 
		          in, amount, 		/* input addr & length */
			  0); 			/* no padding */
	if (rv != SECSuccess) 
	    goto loser;

	/* Encrypt MAC */
	rv = (*ss->sec.enc)(ss->sec.writecx, out+2, &nout, macLen, out+2, macLen);
	if (rv) goto loser;

	/* Encrypt data from caller */
	rv = (*ss->sec.enc)(ss->sec.writecx, out+2+macLen, &nout, amount, in, amount);
	if (rv) goto loser;

	ssl_ReleaseSpecReadLock(ss);  /*************************************/

	PRINT_BUF(50, (ss, "encrypted data:", out, buflen));

	rv = ssl_DefSend(ss, out, buflen, flags & ~ssl_SEND_FLAG_MASK);
	if (rv < 0) {
	    if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
		SSL_TRC(50, ("%d: SSL[%d]: send stream would block, "
			     "saving data", SSL_GETPID(), ss->fd));
		rv = 0;
	    } else {
		SSL_TRC(10, ("%d: SSL[%d]: send stream error %d",
			     SSL_GETPID(), ss->fd, PORT_GetError()));
		/* Return short write if some data already went out... */
		if (count == 0)
		    count = rv;
		goto done;
	    }
	}

	if ((unsigned)rv < buflen) {
	    /* Short write.  Save the data and return. */
	    if (ssl_SaveWriteData(ss, out + rv, buflen - rv) == SECFailure) {
		count = SECFailure;
	    } else {
	    	count += amount;
		ss->sec.sendSequence++;
	    }
	    goto done;
	}

	ss->sec.sendSequence++;
	in    += amount;
	count += amount;
	len   -= amount;
    }

done:
    return count;

loser:
    ssl_ReleaseSpecReadLock(ss);
    return SECFailure;
}

/*
** Send some data, when using a block cipher. Package up the data with
** the length header and send it.
*/
/* XXX assumes blocksize is > 7 */
static PRInt32
ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
{
    PRUint8       *  out;  		    /* begining of output buffer.    */
    PRUint8       *  op;		    /* next output byte goes here.   */
    int              rv;		    /* value from funcs we called.   */
    int              count	= 0;        /* this function's return value. */

    unsigned int     hlen;		    /* output record hdr len, 2 or 3 */
    unsigned int     macLen;		    /* MAC is this many bytes long.  */
    int              amount;		    /* of plaintext to go in record. */
    unsigned int     padding;		    /* add this many padding byte.   */
    int              nout;		    /* ciphertext size after header. */
    int              buflen;		    /* size of generated record.     */

    PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );

    SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using block cipher",
		 SSL_GETPID(), ss->fd, len));
    PRINT_BUF(50, (ss, "clear data:", in, len));

    while (len) {
	ssl_GetSpecReadLock(ss);  /*************************************/

	macLen = ss->sec.hash->length;
	/* Figure out how much to send, including mac and padding */
	amount  = PR_MIN( len, MAX_BLOCK_CYPHER_LEN );
	nout    = amount + macLen;
	padding = nout & (ss->sec.blockSize - 1);
	if (padding) {
	    hlen    = 3;
	    padding = ss->sec.blockSize - padding;
	    nout   += padding;
	} else {
	    hlen = 2;
	}
	buflen = hlen + nout;
	if (buflen > ss->sec.writeBuf.space) {
	    rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen);
	    if (rv != SECSuccess) {
		goto loser;
	    }
	}
	out = ss->sec.writeBuf.buf;

	/* Construct header */
	op = out;
	if (padding) {
	    *op++ = MSB(nout);
	    *op++ = LSB(nout);
	    *op++ = padding;
	} else {
	    *op++ = 0x80 | MSB(nout);
	    *op++ = LSB(nout);
	}

	/* Calculate MAC */
	rv = ssl2_CalcMAC(op, 		/* MAC goes here. */
	                  &ss->sec, 
		          in, amount, 	/* intput addr, len */
			  padding);
	if (rv != SECSuccess) 
	    goto loser;
	op += macLen;

	/* Copy in the input data */
	/* XXX could eliminate the copy by folding it into the encryption */
	PORT_Memcpy(op, in, amount);
	op += amount;
	if (padding) {
	    PORT_Memset(op, padding, padding);
	    op += padding;
	}

	/* Encrypt result */
	rv = (*ss->sec.enc)(ss->sec.writecx, out+hlen, &nout, buflen-hlen,
			 out+hlen, op - (out + hlen));
	if (rv) 
	    goto loser;

	ssl_ReleaseSpecReadLock(ss);  /*************************************/

	PRINT_BUF(50, (ss, "final xmit data:", out, op - out));

	rv = ssl_DefSend(ss, out, op - out, flags & ~ssl_SEND_FLAG_MASK);
	if (rv < 0) {
	    if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
		rv = 0;
	    } else {
		SSL_TRC(10, ("%d: SSL[%d]: send block error %d",
			     SSL_GETPID(), ss->fd, PORT_GetError()));
		/* Return short write if some data already went out... */
		if (count == 0)
		    count = rv;
		goto done;
	    }
	}

	if (rv < (op - out)) {
	    /* Short write.  Save the data and return. */
	    if (ssl_SaveWriteData(ss, out + rv, op - out - rv) == SECFailure) {
		count = SECFailure;
	    } else {
		count += amount;
		ss->sec.sendSequence++;
	    }
	    goto done;
	}

	ss->sec.sendSequence++;
	in    += amount;
	count += amount;
	len   -= amount;
    }

done:
    return count;

loser:
    ssl_ReleaseSpecReadLock(ss);
    return SECFailure;
}

/*
** Called from: ssl2_HandleServerHelloMessage,
**              ssl2_HandleClientSessionKeyMessage,
**              ssl2_HandleClientHelloMessage,
**              
*/
static void
ssl2_UseEncryptedSendFunc(sslSocket *ss)
{
    ssl_GetXmitBufLock(ss);
    PORT_Assert(ss->sec.hashcx != 0);

    ss->gs.encrypted = 1;
    ss->sec.send = (ss->sec.blockSize > 1) ? ssl2_SendBlock : ssl2_SendStream;
    ssl_ReleaseXmitBufLock(ss);
}

/* Called while initializing socket in ssl_CreateSecurityInfo().
** This function allows us to keep the name of ssl2_SendClear static.
*/
void
ssl2_UseClearSendFunc(sslSocket *ss)
{
    ss->sec.send = ssl2_SendClear;
}

/************************************************************************
** 			END of Send functions.                          * 
*************************************************************************/

/***********************************************************************
 * For SSL3, this gathers in and handles records/messages until either 
 *	the handshake is complete or application data is available.
 *
 * For SSL2, this gathers in only the next SSLV2 record.
 *
 * Called from ssl_Do1stHandshake() via function pointer ss->handshake.
 * Caller must hold handshake lock.
 * This function acquires and releases the RecvBufLock.
 *
 * returns SECSuccess for success.
 * returns SECWouldBlock when that value is returned by ssl2_GatherRecord() or
 *	ssl3_GatherCompleteHandshake().
 * returns SECFailure on all other errors.
 *
 * The gather functions called by ssl_GatherRecord1stHandshake are expected 
 * 	to return values interpreted as follows:
 *  1 : the function completed without error.
 *  0 : the function read EOF.
 * -1 : read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
 * -2 : the function wants ssl_GatherRecord1stHandshake to be called again 
 *	immediately, by ssl_Do1stHandshake.
 *
 * This code is similar to, and easily confused with, DoRecv() in sslsecur.c
 *
 * This function is called from ssl_Do1stHandshake().  
 * The following functions put ssl_GatherRecord1stHandshake into ss->handshake:
 *	ssl2_HandleMessage
 *	ssl2_HandleVerifyMessage
 *	ssl2_HandleServerHelloMessage
 *	ssl2_BeginClientHandshake	
 *	ssl2_HandleClientSessionKeyMessage
 *	ssl3_RestartHandshakeAfterCertReq 
 *	ssl3_RestartHandshakeAfterServerCert 
 *	ssl2_HandleClientHelloMessage
 *	ssl2_BeginServerHandshake
 */
SECStatus
ssl_GatherRecord1stHandshake(sslSocket *ss)
{
    int rv;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    ssl_GetRecvBufLock(ss);

    /* The special case DTLS logic is needed here because the SSL/TLS
     * version wants to auto-detect SSL2 vs. SSL3 on the initial handshake
     * (ss->version == 0) but with DTLS it gets confused, so we force the
     * SSL3 version.
     */
    if ((ss->version >= SSL_LIBRARY_VERSION_3_0) || IS_DTLS(ss)) {
	/* Wait for handshake to complete, or application data to arrive.  */
	rv = ssl3_GatherCompleteHandshake(ss, 0);
    } else {
	/* See if we have a complete record */
	rv = ssl2_GatherRecord(ss, 0);
    }
    SSL_TRC(10, ("%d: SSL[%d]: handshake gathering, rv=%d",
		 SSL_GETPID(), ss->fd, rv));

    ssl_ReleaseRecvBufLock(ss);

    if (rv <= 0) {
	if (rv == SECWouldBlock) {
	    /* Progress is blocked waiting for callback completion.  */
	    SSL_TRC(10, ("%d: SSL[%d]: handshake blocked (need %d)",
			 SSL_GETPID(), ss->fd, ss->gs.remainder));
	    return SECWouldBlock;
	}
	if (rv == 0) {
	    /* EOF. Loser  */
	    PORT_SetError(PR_END_OF_FILE_ERROR);
	}
	return SECFailure;	/* rv is < 0 here. */
    }

    SSL_TRC(10, ("%d: SSL[%d]: got handshake record of %d bytes",
		 SSL_GETPID(), ss->fd, ss->gs.recordLen));

    ss->handshake = 0;	/* makes ssl_Do1stHandshake call ss->nextHandshake.*/
    return SECSuccess;
}

/************************************************************************/

/* Called from ssl2_ServerSetupSessionCypher()
 *             ssl2_ClientSetupSessionCypher()
 */
static SECStatus
ssl2_FillInSID(sslSessionID * sid, 
          int            cipher,
	  PRUint8       *keyData, 
	  int            keyLen,
	  PRUint8       *ca, 
	  int            caLen,
	  int            keyBits, 
	  int            secretKeyBits,
	  SSLSignType    authAlgorithm,
	  PRUint32       authKeyBits,
	  SSLKEAType     keaType,
	  PRUint32       keaKeyBits)
{
    PORT_Assert(sid->references == 1);
    PORT_Assert(sid->cached == never_cached);
    PORT_Assert(sid->u.ssl2.masterKey.data == 0);
    PORT_Assert(sid->u.ssl2.cipherArg.data == 0);

    sid->version = SSL_LIBRARY_VERSION_2;

    sid->u.ssl2.cipherType = cipher;
    sid->u.ssl2.masterKey.data = (PRUint8*) PORT_Alloc(keyLen);
    if (!sid->u.ssl2.masterKey.data) {
	return SECFailure;
    }
    PORT_Memcpy(sid->u.ssl2.masterKey.data, keyData, keyLen);
    sid->u.ssl2.masterKey.len = keyLen;
    sid->u.ssl2.keyBits       = keyBits;
    sid->u.ssl2.secretKeyBits = secretKeyBits;
    sid->authAlgorithm        = authAlgorithm;
    sid->authKeyBits          = authKeyBits;
    sid->keaType              = keaType;
    sid->keaKeyBits           = keaKeyBits;
    sid->lastAccessTime = sid->creationTime = ssl_Time();
    sid->expirationTime = sid->creationTime + ssl_sid_timeout;

    if (caLen) {
	sid->u.ssl2.cipherArg.data = (PRUint8*) PORT_Alloc(caLen);
	if (!sid->u.ssl2.cipherArg.data) {
	    return SECFailure;
	}
	sid->u.ssl2.cipherArg.len = caLen;
	PORT_Memcpy(sid->u.ssl2.cipherArg.data, ca, caLen);
    }
    return SECSuccess;
}

/*
** Construct session keys given the masterKey (tied to the session-id),
** the client's challenge and the server's nonce.
**
** Called from ssl2_CreateSessionCypher() <-
*/
static SECStatus
ssl2_ProduceKeys(sslSocket *    ss, 
            SECItem *      readKey, 
	    SECItem *      writeKey,
	    SECItem *      masterKey, 
	    PRUint8 *      challenge,
	    PRUint8 *      nonce, 
	    int            cipherType)
{
    PK11Context * cx        = 0;
    unsigned      nkm       = 0; /* number of hashes to generate key mat. */
    unsigned      nkd       = 0; /* size of readKey and writeKey. */
    unsigned      part;
    unsigned      i;
    unsigned      off;
    SECStatus     rv;
    PRUint8       countChar;
    PRUint8       km[3*16];	/* buffer for key material. */

    readKey->data = 0;
    writeKey->data = 0;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    rv = SECSuccess;
    cx = PK11_CreateDigestContext(SEC_OID_MD5);
    if (cx == NULL) {
	ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
	return SECFailure;
    }

    nkm = ssl_Specs[cipherType].nkm;
    nkd = ssl_Specs[cipherType].nkd;

    readKey->data = (PRUint8*) PORT_Alloc(nkd);
    if (!readKey->data) 
    	goto loser;
    readKey->len = nkd;

    writeKey->data = (PRUint8*) PORT_Alloc(nkd);
    if (!writeKey->data) 
    	goto loser;
    writeKey->len = nkd;

    /* Produce key material */
    countChar = '0';
    for (i = 0, off = 0; i < nkm; i++, off += 16) {
	rv  = PK11_DigestBegin(cx);
	rv |= PK11_DigestOp(cx, masterKey->data, masterKey->len);
	rv |= PK11_DigestOp(cx, &countChar,      1);
	rv |= PK11_DigestOp(cx, challenge,       SSL_CHALLENGE_BYTES);
	rv |= PK11_DigestOp(cx, nonce,           SSL_CONNECTIONID_BYTES);
	rv |= PK11_DigestFinal(cx, km+off, &part, MD5_LENGTH);
	if (rv != SECSuccess) {
	    ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
	    rv = SECFailure;
	    goto loser;
	}
	countChar++;
    }

    /* Produce keys */
    PORT_Memcpy(readKey->data,  km,       nkd);
    PORT_Memcpy(writeKey->data, km + nkd, nkd);

loser:
    PK11_DestroyContext(cx, PR_TRUE);
    return rv;
}

/* Called from ssl2_ServerSetupSessionCypher() 
**                  <- ssl2_HandleClientSessionKeyMessage()
**                          <- ssl2_HandleClientHelloMessage()
** and from    ssl2_ClientSetupSessionCypher() 
**                  <- ssl2_HandleServerHelloMessage()
*/
static SECStatus
ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient)
{
    SECItem         * rk = NULL;
    SECItem         * wk = NULL;
    SECItem *         param;
    SECStatus         rv;
    int               cipherType  = sid->u.ssl2.cipherType;
    PK11SlotInfo *    slot        = NULL;
    CK_MECHANISM_TYPE mechanism;
    SECItem           readKey;
    SECItem           writeKey;

    void *readcx = 0;
    void *writecx = 0;
    readKey.data = 0;
    writeKey.data = 0;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    if (ss->sec.ci.sid == 0)
    	goto sec_loser;	/* don't crash if asserts are off */

    /* Trying to cut down on all these switch statements that should be tables.
     * So, test cipherType once, here, and then use tables below. 
     */
    switch (cipherType) {
    case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
    case SSL_CK_RC4_128_WITH_MD5:
    case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
    case SSL_CK_RC2_128_CBC_WITH_MD5:
    case SSL_CK_DES_64_CBC_WITH_MD5:
    case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
	break;

    default:
	SSL_DBG(("%d: SSL[%d]: ssl2_CreateSessionCypher: unknown cipher=%d",
		 SSL_GETPID(), ss->fd, cipherType));
	PORT_SetError(isClient ? SSL_ERROR_BAD_SERVER : SSL_ERROR_BAD_CLIENT);
	goto sec_loser;
    }
 
    rk = isClient ? &readKey  : &writeKey;
    wk = isClient ? &writeKey : &readKey;

    /* Produce the keys for this session */
    rv = ssl2_ProduceKeys(ss, &readKey, &writeKey, &sid->u.ssl2.masterKey,
		     ss->sec.ci.clientChallenge, ss->sec.ci.connectionID,
		     cipherType);
    if (rv != SECSuccess) 
	goto loser;
    PRINT_BUF(7, (ss, "Session read-key: ", rk->data, rk->len));
    PRINT_BUF(7, (ss, "Session write-key: ", wk->data, wk->len));

    PORT_Memcpy(ss->sec.ci.readKey, readKey.data, readKey.len);
    PORT_Memcpy(ss->sec.ci.writeKey, writeKey.data, writeKey.len);
    ss->sec.ci.keySize = readKey.len;

    /* Setup the MAC */
    rv = ssl2_CreateMAC(&ss->sec, rk, wk, cipherType);
    if (rv != SECSuccess) 
    	goto loser;

    /* First create the session key object */
    SSL_TRC(3, ("%d: SSL[%d]: using %s", SSL_GETPID(), ss->fd,
	    ssl_cipherName[cipherType]));


    mechanism  = ssl_Specs[cipherType].mechanism;

    /* set destructer before we call loser... */
    ss->sec.destroy = (void (*)(void*, PRBool)) PK11_DestroyContext;
    slot = PK11_GetBestSlot(mechanism, ss->pkcs11PinArg);
    if (slot == NULL)
	goto loser;

    param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg);
    if (param == NULL)
	goto loser;
    readcx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap,
					CKA_DECRYPT, rk, param,
					ss->pkcs11PinArg);
    SECITEM_FreeItem(param, PR_TRUE);
    if (readcx == NULL)
	goto loser;

    /* build the client context */
    param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg);
    if (param == NULL)
	goto loser;
    writecx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap,
					 CKA_ENCRYPT, wk, param,
					 ss->pkcs11PinArg);
    SECITEM_FreeItem(param,PR_TRUE);
    if (writecx == NULL)
	goto loser;
    PK11_FreeSlot(slot);

    rv = SECSuccess;
    ss->sec.enc           = (SSLCipher) PK11_CipherOp;
    ss->sec.dec           = (SSLCipher) PK11_CipherOp;
    ss->sec.readcx        = (void *) readcx;
    ss->sec.writecx       = (void *) writecx;
    ss->sec.blockSize     = ssl_Specs[cipherType].blockSize;
    ss->sec.blockShift    = ssl_Specs[cipherType].blockShift;
    ss->sec.cipherType    = sid->u.ssl2.cipherType;
    ss->sec.keyBits       = sid->u.ssl2.keyBits;
    ss->sec.secretKeyBits = sid->u.ssl2.secretKeyBits;
    goto done;

  loser:
    if (ss->sec.destroy) {
	if (readcx)  (*ss->sec.destroy)(readcx, PR_TRUE);
	if (writecx) (*ss->sec.destroy)(writecx, PR_TRUE);
    }
    ss->sec.destroy = NULL;
    if (slot) PK11_FreeSlot(slot);

  sec_loser:
    rv = SECFailure;

  done:
    if (rk) {
	SECITEM_ZfreeItem(rk, PR_FALSE);
    }
    if (wk) {
	SECITEM_ZfreeItem(wk, PR_FALSE);
    }
    return rv;
}

/*
** Setup the server ciphers given information from a CLIENT-MASTER-KEY
** message.
** 	"ss"      pointer to the ssl-socket object
** 	"cipher"  the cipher type to use
** 	"keyBits" the size of the final cipher key
** 	"ck"      the clear-key data
** 	"ckLen"   the number of bytes of clear-key data
** 	"ek"      the encrypted-key data
** 	"ekLen"   the number of bytes of encrypted-key data
** 	"ca"      the cipher-arg data
** 	"caLen"   the number of bytes of cipher-arg data
**
** The MASTER-KEY is constructed by first decrypting the encrypted-key
** data. This produces the SECRET-KEY-DATA. The MASTER-KEY is composed by
** concatenating the clear-key data with the SECRET-KEY-DATA. This code
** checks to make sure that the client didn't send us an improper amount
** of SECRET-KEY-DATA (it restricts the length of that data to match the
** spec).
**
** Called from ssl2_HandleClientSessionKeyMessage().
*/
static SECStatus
ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits,
			 PRUint8 *ck, unsigned int ckLen,
			 PRUint8 *ek, unsigned int ekLen,
			 PRUint8 *ca, unsigned int caLen)
{
    PRUint8      *    dk   = NULL; /* decrypted master key */
    sslSessionID *    sid;
    sslServerCerts *  sc   = ss->serverCerts + kt_rsa;
    PRUint8       *   kbuf = 0;	/* buffer for RSA decrypted data. */
    unsigned int      ddLen;	/* length of RSA decrypted data in kbuf */
    unsigned int      keySize;
    unsigned int      dkLen;    /* decrypted key length in bytes */
    int               modulusLen;
    SECStatus         rv;
    PRUint16          allowed;  /* cipher kinds enabled and allowed by policy */
    PRUint8           mkbuf[SSL_MAX_MASTER_KEY_BYTES];

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );
    PORT_Assert((sc->SERVERKEY != 0));
    PORT_Assert((ss->sec.ci.sid != 0));
    sid = ss->sec.ci.sid;

    /* Trying to cut down on all these switch statements that should be tables.
     * So, test cipherType once, here, and then use tables below. 
     */
    switch (cipher) {
    case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
    case SSL_CK_RC4_128_WITH_MD5:
    case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
    case SSL_CK_RC2_128_CBC_WITH_MD5:
    case SSL_CK_DES_64_CBC_WITH_MD5:
    case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
	break;

    default:
	SSL_DBG(("%d: SSL[%d]: ssl2_ServerSetupSessionCypher: unknown cipher=%d",
		 SSL_GETPID(), ss->fd, cipher));
	PORT_SetError(SSL_ERROR_BAD_CLIENT);
	goto loser;
    }

    allowed = ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED;
    if (!(allowed & (1 << cipher))) {
    	/* client chose a kind we don't allow! */
	SSL_DBG(("%d: SSL[%d]: disallowed cipher=%d",
		 SSL_GETPID(), ss->fd, cipher));
	PORT_SetError(SSL_ERROR_BAD_CLIENT);
	goto loser;
    }

    keySize = ssl_Specs[cipher].keyLen;
    if (keyBits != keySize * BPB) {
	SSL_DBG(("%d: SSL[%d]: invalid master secret key length=%d (bits)!",
		 SSL_GETPID(), ss->fd, keyBits));
	PORT_SetError(SSL_ERROR_BAD_CLIENT);
	goto loser;
    }

    if (ckLen != ssl_Specs[cipher].pubLen) {
	SSL_DBG(("%d: SSL[%d]: invalid clear key length, ckLen=%d (bytes)!",
		 SSL_GETPID(), ss->fd, ckLen));
	PORT_SetError(SSL_ERROR_BAD_CLIENT);
	goto loser;
    }

    if (caLen != ssl_Specs[cipher].ivLen) {
	SSL_DBG(("%d: SSL[%d]: invalid key args length, caLen=%d (bytes)!",
		 SSL_GETPID(), ss->fd, caLen));
	PORT_SetError(SSL_ERROR_BAD_CLIENT);
	goto loser;
    }

    modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY);
    if (modulusLen == -1) {
	/* XXX If the key is bad, then PK11_PubDecryptRaw will fail below. */
	modulusLen = ekLen;
    }
    if (ekLen > modulusLen || ekLen + ckLen < keySize) {
	SSL_DBG(("%d: SSL[%d]: invalid encrypted key length, ekLen=%d (bytes)!",
		 SSL_GETPID(), ss->fd, ekLen));
	PORT_SetError(SSL_ERROR_BAD_CLIENT);
	goto loser;
    }

    /* allocate the buffer to hold the decrypted portion of the key. */
    kbuf = (PRUint8*)PORT_Alloc(modulusLen);
    if (!kbuf) {
	goto loser;
    }
    dkLen = keySize - ckLen;
    dk    = kbuf + modulusLen - dkLen;

    /* Decrypt encrypted half of the key. 
    ** NOTE: PK11_PubDecryptRaw will barf on a non-RSA key. This is
    ** desired behavior here.
    */
    rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &ddLen, modulusLen, ek, ekLen);
    if (rv != SECSuccess) 
	goto hide_loser;

    /* Is the length of the decrypted data (ddLen) the expected value? */
    if (modulusLen != ddLen) 
	goto hide_loser;

    /* Cheaply verify that PKCS#1 was used to format the encryption block */
    if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (dk[-1] != 0x00)) {
	SSL_DBG(("%d: SSL[%d]: strange encryption block",
		 SSL_GETPID(), ss->fd));
	PORT_SetError(SSL_ERROR_BAD_CLIENT);
	goto hide_loser;
    }

    /* Make sure we're not subject to a version rollback attack. */
    if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
	static const PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03,
			                   0x03, 0x03, 0x03, 0x03 };
	
	if (PORT_Memcmp(dk - 8 - 1, threes, 8) == 0) {
	    PORT_SetError(SSL_ERROR_BAD_CLIENT);
	    goto hide_loser;
	}
    }
    if (0) {
hide_loser:
	/* Defense against the Bleichenbacher attack.
	 * Provide the client with NO CLUES that the decrypted master key
	 * was erroneous.  Don't send any error messages.
	 * Instead, Generate a completely bogus master key .
	 */
	PK11_GenerateRandom(dk, dkLen);
    }

    /*
    ** Construct master key out of the pieces.
    */
    if (ckLen) {
	PORT_Memcpy(mkbuf, ck, ckLen);
    }
    PORT_Memcpy(mkbuf + ckLen, dk, dkLen);

    /* Fill in session-id */
    rv = ssl2_FillInSID(sid, cipher, mkbuf, keySize, ca, caLen,
		   keyBits, keyBits - (ckLen<<3),
		   ss->sec.authAlgorithm, ss->sec.authKeyBits,
		   ss->sec.keaType,       ss->sec.keaKeyBits);
    if (rv != SECSuccess) {
	goto loser;
    }

    /* Create session ciphers */
    rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
    if (rv != SECSuccess) {
	goto loser;
    }

    SSL_TRC(1, ("%d: SSL[%d]: server, using %s cipher, clear=%d total=%d",
		SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
		ckLen<<3, keySize<<3));
    rv = SECSuccess;
    goto done;

  loser:
    rv = SECFailure;

  done:
    PORT_Free(kbuf);
    return rv;
}

/************************************************************************/

/*
** Rewrite the incoming cipher specs, comparing to list of specs we support,
** (ss->cipherSpecs) and eliminating anything we don't support
**
*  Note: Our list may contain SSL v3 ciphers.  
*  We MUST NOT match on any of those.  
*  Fortunately, this is easy to detect because SSLv3 ciphers have zero
*  in the first byte, and none of the SSLv2 ciphers do.
*
*  Called from ssl2_HandleClientHelloMessage().
*  Returns the number of bytes of "qualified cipher specs", 
*  which is typically a multiple of 3, but will be zero if there are none.
*/
static int
ssl2_QualifyCypherSpecs(sslSocket *ss, 
                        PRUint8 *  cs, /* cipher specs in client hello msg. */
		        int        csLen)
{
    PRUint8 *    ms;
    PRUint8 *    hs;
    PRUint8 *    qs;
    int          mc;
    int          hc;
    PRUint8      qualifiedSpecs[ssl2_NUM_SUITES_IMPLEMENTED * 3];

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );

    if (!ss->cipherSpecs) {
	SECStatus rv = ssl2_ConstructCipherSpecs(ss);
	if (rv != SECSuccess || !ss->cipherSpecs) 
	    return 0;
    }

    PRINT_BUF(10, (ss, "specs from client:", cs, csLen));
    qs = qualifiedSpecs;
    ms = ss->cipherSpecs;
    for (mc = ss->sizeCipherSpecs; mc > 0; mc -= 3, ms += 3) {
	if (ms[0] == 0)
	    continue;
	for (hs = cs, hc = csLen; hc > 0; hs += 3, hc -= 3) {
	    if ((hs[0] == ms[0]) &&
		(hs[1] == ms[1]) &&
		(hs[2] == ms[2])) {
		/* Copy this cipher spec into the "keep" section */
		qs[0] = hs[0];
		qs[1] = hs[1];
		qs[2] = hs[2];
		qs   += 3;
		break;
	    }
	}
    }
    hc = qs - qualifiedSpecs;
    PRINT_BUF(10, (ss, "qualified specs from client:", qualifiedSpecs, hc));
    PORT_Memcpy(cs, qualifiedSpecs, hc);
    return hc;
}

/*
** Pick the best cipher we can find, given the array of server cipher
** specs.  Returns cipher number (e.g. SSL_CK_*), or -1 for no overlap.
** If successful, stores the master key size (bytes) in *pKeyLen.
**
** This is correct only for the client side, but presently
** this function is only called from 
**	ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
**
** Note that most servers only return a single cipher suite in their 
** ServerHello messages.  So, the code below for finding the "best" cipher
** suite usually has only one choice.  The client and server should send 
** their cipher suite lists sorted in descending order by preference.
*/
static int
ssl2_ChooseSessionCypher(sslSocket *ss, 
                         int        hc,    /* number of cs's in hs. */
		         PRUint8 *  hs,    /* server hello's cipher suites. */
		         int *      pKeyLen) /* out: sym key size in bytes. */
{
    PRUint8 *       ms;
    unsigned int    i;
    int             bestKeySize;
    int             bestRealKeySize;
    int             bestCypher;
    int             keySize;
    int             realKeySize;
    PRUint8 *       ohs               = hs;
    const PRUint8 * preferred;
    static const PRUint8 noneSuch[3] = { 0, 0, 0 };

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );

    if (!ss->cipherSpecs) {
	SECStatus rv = ssl2_ConstructCipherSpecs(ss);
	if (rv != SECSuccess || !ss->cipherSpecs) 
	    goto loser;
    }

    if (!ss->preferredCipher) {
    	unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference &
	                       SSL_CB_IMPLEMENTED;
	if (allowed) {
	    preferred = implementedCipherSuites;
	    for (i = ssl2_NUM_SUITES_IMPLEMENTED; i > 0; --i) {
		if (0 != (allowed & (1U << preferred[0]))) {
		    ss->preferredCipher = preferred;
		    break;
		}
		preferred += 3;
	    }
	}
    }
    preferred = ss->preferredCipher ? ss->preferredCipher : noneSuch;
    /*
    ** Scan list of ciphers received from peer and look for a match in
    ** our list.  
    *  Note: Our list may contain SSL v3 ciphers.  
    *  We MUST NOT match on any of those.  
    *  Fortunately, this is easy to detect because SSLv3 ciphers have zero
    *  in the first byte, and none of the SSLv2 ciphers do.
    */
    bestKeySize = bestRealKeySize = 0;
    bestCypher = -1;
    while (--hc >= 0) {
	for (i = 0, ms = ss->cipherSpecs; i < ss->sizeCipherSpecs; i += 3, ms += 3) {
	    if ((hs[0] == preferred[0]) &&
		(hs[1] == preferred[1]) &&
		(hs[2] == preferred[2]) &&
		 hs[0] != 0) {
		/* Pick this cipher immediately! */
		*pKeyLen = (((hs[1] << 8) | hs[2]) + 7) >> 3;
		return hs[0];
	    }
	    if ((hs[0] == ms[0]) && (hs[1] == ms[1]) && (hs[2] == ms[2]) &&
	         hs[0] != 0) {
		/* Found a match */

		/* Use secret keySize to determine which cipher is best */
		realKeySize = (hs[1] << 8) | hs[2];
		switch (hs[0]) {
		  case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
		  case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
		    keySize = 40;
		    break;
		  default:
		    keySize = realKeySize;
		    break;
		}
		if (keySize > bestKeySize) {
		    bestCypher = hs[0];
		    bestKeySize = keySize;
		    bestRealKeySize = realKeySize;
		}
	    }
	}
	hs += 3;
    }
    if (bestCypher < 0) {
	/*
	** No overlap between server and client. Re-examine server list
	** to see what kind of ciphers it does support so that we can set
	** the error code appropriately.
	*/
	if ((ohs[0] == SSL_CK_RC4_128_WITH_MD5) ||
	    (ohs[0] == SSL_CK_RC2_128_CBC_WITH_MD5)) {
	    PORT_SetError(SSL_ERROR_US_ONLY_SERVER);
	} else if ((ohs[0] == SSL_CK_RC4_128_EXPORT40_WITH_MD5) ||
		   (ohs[0] == SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)) {
	    PORT_SetError(SSL_ERROR_EXPORT_ONLY_SERVER);
	} else {
	    PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
	}
	SSL_DBG(("%d: SSL[%d]: no cipher overlap", SSL_GETPID(), ss->fd));
	goto loser;
    }
    *pKeyLen = (bestRealKeySize + 7) >> 3;
    return bestCypher;

  loser:
    return -1;
}

static SECStatus
ssl2_ClientHandleServerCert(sslSocket *ss, PRUint8 *certData, int certLen)
{
    CERTCertificate *cert      = NULL;
    SECItem          certItem;

    certItem.data = certData;
    certItem.len  = certLen;

    /* decode the certificate */
    cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
				   PR_FALSE, PR_TRUE);
    
    if (cert == NULL) {
	SSL_DBG(("%d: SSL[%d]: decode of server certificate fails",
		 SSL_GETPID(), ss->fd));
	PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
	return SECFailure;
    }

#ifdef TRACE
    {
	if (ssl_trace >= 1) {
	    char *issuer;
	    char *subject;
	    issuer = CERT_NameToAscii(&cert->issuer);
	    subject = CERT_NameToAscii(&cert->subject);
	    SSL_TRC(1,("%d: server certificate issuer: '%s'",
		       SSL_GETPID(), issuer ? issuer : "OOPS"));
	    SSL_TRC(1,("%d: server name: '%s'",
		       SSL_GETPID(), subject ? subject : "OOPS"));
	    PORT_Free(issuer);
	    PORT_Free(subject);
	}
    }
#endif

    ss->sec.peerCert = cert;
    return SECSuccess;
}


/*
 * Format one block of data for public/private key encryption using
 * the rules defined in PKCS #1. SSL2 does this itself to handle the
 * rollback detection.
 */
#define RSA_BLOCK_MIN_PAD_LEN           8
#define RSA_BLOCK_FIRST_OCTET           0x00
#define RSA_BLOCK_AFTER_PAD_OCTET       0x00
#define RSA_BLOCK_PUBLIC_OCTET       	0x02
unsigned char *
ssl_FormatSSL2Block(unsigned modulusLen, SECItem *data)
{
    unsigned char *block;
    unsigned char *bp;
    int padLen;
    SECStatus rv;
    int i;

    if (modulusLen < data->len + (3 + RSA_BLOCK_MIN_PAD_LEN)) {
	PORT_SetError(SEC_ERROR_BAD_KEY);
    	return NULL;
    }
    block = (unsigned char *) PORT_Alloc(modulusLen);
    if (block == NULL)
	return NULL;

    bp = block;

    /*
     * All RSA blocks start with two octets:
     *	0x00 || BlockType
     */
    *bp++ = RSA_BLOCK_FIRST_OCTET;
    *bp++ = RSA_BLOCK_PUBLIC_OCTET;

    /*
     * 0x00 || BT || Pad || 0x00 || ActualData
     *   1      1   padLen    1      data->len
     * Pad is all non-zero random bytes.
     */
    padLen = modulusLen - data->len - 3;
    PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
    rv = PK11_GenerateRandom(bp, padLen);
    if (rv == SECFailure) goto loser;
    /* replace all the 'zero' bytes */
    for (i = 0; i < padLen; i++) {
	while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET) {
    	    rv = PK11_GenerateRandom(bp+i, 1);
	    if (rv == SECFailure) goto loser;
	}
    }
    bp += padLen;
    *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
    PORT_Memcpy (bp, data->data, data->len);

    return block;
loser:
    if (block) PORT_Free(block);
    return NULL;
}

/*
** Given the server's public key and cipher specs, generate a session key
** that is ready to use for encrypting/decrypting the byte stream. At
** the same time, generate the SSL_MT_CLIENT_MASTER_KEY message and
** send it to the server.
**
** Called from ssl2_HandleServerHelloMessage()
*/
static SECStatus
ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen)
{
    sslSessionID *    sid;
    PRUint8 *         ca;	/* points to iv data, or NULL if none. */
    PRUint8 *         ekbuf 		= 0;
    CERTCertificate * cert 		= 0;
    SECKEYPublicKey * serverKey 	= 0;
    unsigned          modulusLen 	= 0;
    SECStatus         rv;
    int               cipher;
    int               keyLen;	/* cipher symkey size in bytes. */
    int               ckLen;	/* publicly reveal this many bytes of key. */
    int               caLen;	/* length of IV data at *ca.	*/
    int               nc;

    unsigned char *eblock;	/* holds unencrypted PKCS#1 formatted key. */
    SECItem           rek;	/* holds portion of symkey to be encrypted. */

    PRUint8           keyData[SSL_MAX_MASTER_KEY_BYTES];
    PRUint8           iv     [8];

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    eblock = NULL;

    sid = ss->sec.ci.sid;
    PORT_Assert(sid != 0);

    cert = ss->sec.peerCert;
    
    serverKey = CERT_ExtractPublicKey(cert);
    if (!serverKey) {
	SSL_DBG(("%d: SSL[%d]: extract public key failed: error=%d",
		 SSL_GETPID(), ss->fd, PORT_GetError()));
	PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
	rv = SECFailure;
	goto loser2;
    }

    ss->sec.authAlgorithm = ssl_sign_rsa;
    ss->sec.keaType       = ssl_kea_rsa;
    ss->sec.keaKeyBits    = \
    ss->sec.authKeyBits   = SECKEY_PublicKeyStrengthInBits(serverKey);

    /* Choose a compatible cipher with the server */
    nc = csLen / 3;
    cipher = ssl2_ChooseSessionCypher(ss, nc, cs, &keyLen);
    if (cipher < 0) {
	/* ssl2_ChooseSessionCypher has set error code. */
	ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
	goto loser;
    }

    /* Generate the random keys */
    PK11_GenerateRandom(keyData, sizeof(keyData));

    /*
    ** Next, carve up the keys into clear and encrypted portions. The
    ** clear data is taken from the start of keyData and the encrypted
    ** portion from the remainder. Note that each of these portions is
    ** carved in half, one half for the read-key and one for the
    ** write-key.
    */
    ca = 0;

    /* We know that cipher is a legit value here, because 
     * ssl2_ChooseSessionCypher doesn't return bogus values.
     */
    ckLen = ssl_Specs[cipher].pubLen;	/* cleartext key length. */
    caLen = ssl_Specs[cipher].ivLen;	/* IV length.		*/
    if (caLen) {
	PORT_Assert(sizeof iv >= caLen);
    	PK11_GenerateRandom(iv, caLen);
	ca = iv;
    }

    /* Fill in session-id */
    rv = ssl2_FillInSID(sid, cipher, keyData, keyLen,
		   ca, caLen, keyLen << 3, (keyLen - ckLen) << 3,
		   ss->sec.authAlgorithm, ss->sec.authKeyBits,
		   ss->sec.keaType,       ss->sec.keaKeyBits);
    if (rv != SECSuccess) {
	goto loser;
    }

    SSL_TRC(1, ("%d: SSL[%d]: client, using %s cipher, clear=%d total=%d",
		SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
		ckLen<<3, keyLen<<3));

    /* Now setup read and write ciphers */
    rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE);
    if (rv != SECSuccess) {
	goto loser;
    }

    /*
    ** Fill in the encryption buffer with some random bytes. Then 
    ** copy in the portion of the session key we are encrypting.
    */
    modulusLen = SECKEY_PublicKeyStrength(serverKey);
    rek.data   = keyData + ckLen;
    rek.len    = keyLen  - ckLen;
    eblock = ssl_FormatSSL2Block(modulusLen, &rek);
    if (eblock == NULL) 
    	goto loser;

    /* Set up the padding for version 2 rollback detection. */
    /* XXX We should really use defines here */
    if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
	PORT_Assert((modulusLen - rek.len) > 12);
	PORT_Memset(eblock + modulusLen - rek.len - 8 - 1, 0x03, 8);
    }
    ekbuf = (PRUint8*) PORT_Alloc(modulusLen);
    if (!ekbuf) 
	goto loser;
    PRINT_BUF(10, (ss, "master key encryption block:",
		   eblock, modulusLen));

    /* Encrypt ekitem */
    rv = PK11_PubEncryptRaw(serverKey, ekbuf, eblock, modulusLen,
						ss->pkcs11PinArg);
    if (rv) 
    	goto loser;

    /*  Now we have everything ready to send */
    rv = ssl2_SendSessionKeyMessage(ss, cipher, keyLen << 3, ca, caLen,
			       keyData, ckLen, ekbuf, modulusLen);
    if (rv != SECSuccess) {
	goto loser;
    }
    rv = SECSuccess;
    goto done;

  loser:
    rv = SECFailure;

  loser2:
  done:
    PORT_Memset(keyData, 0, sizeof(keyData));
    PORT_ZFree(ekbuf, modulusLen);
    PORT_ZFree(eblock, modulusLen);
    SECKEY_DestroyPublicKey(serverKey);
    return rv;
}

/************************************************************************/

/* 
 * Called from ssl2_HandleMessage in response to SSL_MT_SERVER_FINISHED message.
 * Caller holds recvBufLock and handshakeLock
 */
static void
ssl2_ClientRegSessionID(sslSocket *ss, PRUint8 *s)
{
    sslSessionID *sid = ss->sec.ci.sid;

    /* Record entry in nonce cache */
    if (sid->peerCert == NULL) {
	PORT_Memcpy(sid->u.ssl2.sessionID, s, sizeof(sid->u.ssl2.sessionID));
	sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);

    }
    if (!ss->opt.noCache && sid->cached == never_cached)
	(*ss->sec.cache)(sid);
}

/* Called from ssl2_HandleMessage() */
static SECStatus
ssl2_TriggerNextMessage(sslSocket *ss)
{
    SECStatus        rv;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    if ((ss->sec.ci.requiredElements & CIS_HAVE_CERTIFICATE) &&
	!(ss->sec.ci.sentElements & CIS_HAVE_CERTIFICATE)) {
	ss->sec.ci.sentElements |= CIS_HAVE_CERTIFICATE;
	rv = ssl2_SendCertificateRequestMessage(ss);
	return rv;
    }
    return SECSuccess;
}

/* See if it's time to send our finished message, or if the handshakes are
** complete.  Send finished message if appropriate.
** Returns SECSuccess unless anything goes wrong.
**
** Called from ssl2_HandleMessage,
**             ssl2_HandleVerifyMessage 
**             ssl2_HandleServerHelloMessage
**             ssl2_HandleClientSessionKeyMessage
*/
static SECStatus
ssl2_TryToFinish(sslSocket *ss)
{
    SECStatus        rv;
    char             e, ef;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    e = ss->sec.ci.elements;
    ef = e | CIS_HAVE_FINISHED;
    if ((ef & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) {
	if (ss->sec.isServer) {
	    /* Send server finished message if we already didn't */
	    rv = ssl2_SendServerFinishedMessage(ss);
	} else {
	    /* Send client finished message if we already didn't */
	    rv = ssl2_SendClientFinishedMessage(ss);
	}
	if (rv != SECSuccess) {
	    return rv;
	}
	if ((e & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) {
	    /* Totally finished */
	    ss->handshake = 0;
	    return SECSuccess;
	}
    }
    return SECSuccess;
}

/*
** Called from ssl2_HandleRequestCertificate
*/
static SECStatus
ssl2_SignResponse(sslSocket *ss,
	     SECKEYPrivateKey *key,
	     SECItem *response)
{
    SGNContext *     sgn = NULL;
    PRUint8 *        challenge;
    unsigned int     len;
    SECStatus        rv		= SECFailure;
    
    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    challenge = ss->sec.ci.serverChallenge;
    len = ss->sec.ci.serverChallengeLen;
    
    /* Sign the expected data... */
    sgn = SGN_NewContext(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION,key);
    if (!sgn) 
    	goto done;
    rv = SGN_Begin(sgn);
    if (rv != SECSuccess) 
    	goto done;
    rv = SGN_Update(sgn, ss->sec.ci.readKey, ss->sec.ci.keySize);
    if (rv != SECSuccess) 
    	goto done;
    rv = SGN_Update(sgn, ss->sec.ci.writeKey, ss->sec.ci.keySize);
    if (rv != SECSuccess) 
    	goto done;
    rv = SGN_Update(sgn, challenge, len);
    if (rv != SECSuccess) 
    	goto done;
    rv = SGN_Update(sgn, ss->sec.peerCert->derCert.data, 
                         ss->sec.peerCert->derCert.len);
    if (rv != SECSuccess) 
    	goto done;
    rv = SGN_End(sgn, response);
    if (rv != SECSuccess) 
    	goto done;

done:
    SGN_DestroyContext(sgn, PR_TRUE);
    return rv == SECSuccess ? SECSuccess : SECFailure;
}

/*
** Try to handle a request-certificate message. Get client's certificate
** and private key and sign a message for the server to see.
** Caller must hold handshakeLock 
**
** Called from ssl2_HandleMessage().
*/
static int
ssl2_HandleRequestCertificate(sslSocket *ss)
{
    CERTCertificate * cert	= NULL;	/* app-selected client cert. */
    SECKEYPrivateKey *key	= NULL;	/* priv key for cert. */
    SECStatus         rv;
    SECItem           response;
    int               ret	= 0;
    PRUint8           authType;


    /*
     * These things all need to be initialized before we can "goto loser".
     */
    response.data = NULL;

    /* get challenge info from connectionInfo */
    authType = ss->sec.ci.authType;

    if (authType != SSL_AT_MD5_WITH_RSA_ENCRYPTION) {
	SSL_TRC(7, ("%d: SSL[%d]: unsupported auth type 0x%x", SSL_GETPID(),
		    ss->fd, authType));
	goto no_cert_error;
    }

    /* Get certificate and private-key from client */
    if (!ss->getClientAuthData) {
	SSL_TRC(7, ("%d: SSL[%d]: client doesn't support client-auth",
		    SSL_GETPID(), ss->fd));
	goto no_cert_error;
    }
    ret = (*ss->getClientAuthData)(ss->getClientAuthDataArg, ss->fd,
				   NULL, &cert, &key);
    if ( ret == SECWouldBlock ) {
	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
	ret = -1;
	goto loser;
    }

    if (ret) {
	goto no_cert_error;
    }

    /* check what the callback function returned */
    if ((!cert) || (!key)) {
        /* we are missing either the key or cert */
        if (cert) {
            /* got a cert, but no key - free it */
            CERT_DestroyCertificate(cert);
            cert = NULL;
        }
        if (key) {
            /* got a key, but no cert - free it */
            SECKEY_DestroyPrivateKey(key);
            key = NULL;
        }
        goto no_cert_error;
    }

    rv = ssl2_SignResponse(ss, key, &response);
    if ( rv != SECSuccess ) {
	ret = -1;
	goto loser;
    }

    /* Send response message */
    ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response);

    /* Now, remember the cert we sent. But first, forget any previous one. */
    if (ss->sec.localCert) {
	CERT_DestroyCertificate(ss->sec.localCert);
    }
    ss->sec.localCert = CERT_DupCertificate(cert);
    PORT_Assert(!ss->sec.ci.sid->localCert);
    if (ss->sec.ci.sid->localCert) {
	CERT_DestroyCertificate(ss->sec.ci.sid->localCert);
    }
    ss->sec.ci.sid->localCert = cert;
    cert = NULL;

    goto done;

  no_cert_error:
    SSL_TRC(7, ("%d: SSL[%d]: no certificate (ret=%d)", SSL_GETPID(),
		ss->fd, ret));
    ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE);

  loser:
  done:
    if ( cert ) {
	CERT_DestroyCertificate(cert);
    }
    if ( key ) {
	SECKEY_DestroyPrivateKey(key);
    }
    if ( response.data ) {
	PORT_Free(response.data);
    }
    
    return ret;
}

/*
** Called from ssl2_HandleMessage for SSL_MT_CLIENT_CERTIFICATE message.
** Caller must hold HandshakeLock and RecvBufLock, since cd and response
** are contained in the gathered input data.
*/
static SECStatus
ssl2_HandleClientCertificate(sslSocket *    ss, 
                             PRUint8        certType,	/* XXX unused */
			     PRUint8 *      cd, 
			     unsigned int   cdLen,
			     PRUint8 *      response,
			     unsigned int   responseLen)
{
    CERTCertificate *cert	= NULL;
    SECKEYPublicKey *pubKey	= NULL;
    VFYContext *     vfy	= NULL;
    SECItem *        derCert;
    SECStatus        rv		= SECFailure;
    SECItem          certItem;
    SECItem          rep;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );

    /* Extract the certificate */
    certItem.data = cd;
    certItem.len  = cdLen;

    cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
			 	   PR_FALSE, PR_TRUE);
    if (cert == NULL) {
	goto loser;
    }

    /* save the certificate, since the auth routine will need it */
    ss->sec.peerCert = cert;

    /* Extract the public key */
    pubKey = CERT_ExtractPublicKey(cert);
    if (!pubKey) 
    	goto loser;
    
    /* Verify the response data... */
    rep.data = response;
    rep.len = responseLen;
    /* SSL 2.0 only supports RSA certs, so we don't have to worry about
     * DSA here. */
    vfy = VFY_CreateContext(pubKey, &rep, SEC_OID_PKCS1_RSA_ENCRYPTION,
			    ss->pkcs11PinArg);
    if (!vfy) 
    	goto loser;
    rv = VFY_Begin(vfy);
    if (rv) 
    	goto loser;

    rv = VFY_Update(vfy, ss->sec.ci.readKey, ss->sec.ci.keySize);
    if (rv) 
    	goto loser;
    rv = VFY_Update(vfy, ss->sec.ci.writeKey, ss->sec.ci.keySize);
    if (rv) 
    	goto loser;
    rv = VFY_Update(vfy, ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
    if (rv) 
    	goto loser;

    derCert = &ss->serverCerts[kt_rsa].serverCert->derCert;
    rv = VFY_Update(vfy, derCert->data, derCert->len);
    if (rv) 
    	goto loser;
    rv = VFY_End(vfy);
    if (rv) 
    	goto loser;

    /* Now ask the server application if it likes the certificate... */
    rv = (SECStatus) (*ss->authCertificate)(ss->authCertificateArg,
					    ss->fd, PR_TRUE, PR_TRUE);
    /* Hey, it liked it. */
    if (SECSuccess == rv) 
	goto done;

loser:
    ss->sec.peerCert = NULL;
    CERT_DestroyCertificate(cert);

done:
    VFY_DestroyContext(vfy, PR_TRUE);
    SECKEY_DestroyPublicKey(pubKey);
    return rv;
}

/*
** Handle remaining messages between client/server. Process finished
** messages from either side and any authentication requests.
** This should only be called for SSLv2 handshake messages, 
** not for application data records.
** Caller must hold handshake lock.
**
** Called from ssl_Do1stHandshake().
** 
*/
static SECStatus
ssl2_HandleMessage(sslSocket *ss)
{
    PRUint8 *        data;
    PRUint8 *        cid;
    unsigned         len, certType, certLen, responseLen;
    int              rv;
    int              rv2;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    ssl_GetRecvBufLock(ss);

    data = ss->gs.buf.buf + ss->gs.recordOffset;

    if (ss->gs.recordLen < 1) {
	goto bad_peer;
    }
    SSL_TRC(3, ("%d: SSL[%d]: received %d message",
		SSL_GETPID(), ss->fd, data[0]));
    DUMP_MSG(29, (ss, data, ss->gs.recordLen));

    switch (data[0]) {
    case SSL_MT_CLIENT_FINISHED:
	if (ss->sec.ci.elements & CIS_HAVE_FINISHED) {
	    SSL_DBG(("%d: SSL[%d]: dup client-finished message",
		     SSL_GETPID(), ss->fd));
	    goto bad_peer;
	}

	/* See if nonce matches */
	len = ss->gs.recordLen - 1;
	cid = data + 1;
	if ((len != sizeof(ss->sec.ci.connectionID)) ||
	    (PORT_Memcmp(ss->sec.ci.connectionID, cid, len) != 0)) {
	    SSL_DBG(("%d: SSL[%d]: bad connection-id", SSL_GETPID(), ss->fd));
	    PRINT_BUF(5, (ss, "sent connection-id",
			  ss->sec.ci.connectionID, 
			  sizeof(ss->sec.ci.connectionID)));
	    PRINT_BUF(5, (ss, "rcvd connection-id", cid, len));
	    goto bad_peer;
	}

	SSL_TRC(5, ("%d: SSL[%d]: got client finished, waiting for 0x%d",
		    SSL_GETPID(), ss->fd, 
		    ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
	ss->sec.ci.elements |= CIS_HAVE_FINISHED;
	break;

    case SSL_MT_SERVER_FINISHED:
	if (ss->sec.ci.elements & CIS_HAVE_FINISHED) {
	    SSL_DBG(("%d: SSL[%d]: dup server-finished message",
		     SSL_GETPID(), ss->fd));
	    goto bad_peer;
	}

	if (ss->gs.recordLen - 1 != SSL2_SESSIONID_BYTES) {
	    SSL_DBG(("%d: SSL[%d]: bad server-finished message, len=%d",
		     SSL_GETPID(), ss->fd, ss->gs.recordLen));
	    goto bad_peer;
	}
	ssl2_ClientRegSessionID(ss, data+1);
	SSL_TRC(5, ("%d: SSL[%d]: got server finished, waiting for 0x%d",
		    SSL_GETPID(), ss->fd, 
		    ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
	ss->sec.ci.elements |= CIS_HAVE_FINISHED;
	break;

    case SSL_MT_REQUEST_CERTIFICATE:
	len = ss->gs.recordLen - 2;
	if ((len < SSL_MIN_CHALLENGE_BYTES) ||
	    (len > SSL_MAX_CHALLENGE_BYTES)) {
	    /* Bad challenge */
	    SSL_DBG(("%d: SSL[%d]: bad cert request message: code len=%d",
		     SSL_GETPID(), ss->fd, len));
	    goto bad_peer;
	}
	
	/* save auth request info */
	ss->sec.ci.authType           = data[1];
	ss->sec.ci.serverChallengeLen = len;
	PORT_Memcpy(ss->sec.ci.serverChallenge, data + 2, len);
	
	rv = ssl2_HandleRequestCertificate(ss);
	if (rv == SECWouldBlock) {
	    SSL_TRC(3, ("%d: SSL[%d]: async cert request",
			SSL_GETPID(), ss->fd));
	    /* someone is handling this asynchronously */
	    ssl_ReleaseRecvBufLock(ss);
	    return SECWouldBlock;
	}
	if (rv) {
	    SET_ERROR_CODE
	    goto loser;
	}
	break;

    case SSL_MT_CLIENT_CERTIFICATE:
	if (!ss->authCertificate) {
	    /* Server asked for authentication and can't handle it */
	    PORT_SetError(SSL_ERROR_BAD_SERVER);
	    goto loser;
	}
	if (ss->gs.recordLen < SSL_HL_CLIENT_CERTIFICATE_HBYTES) {
	    SET_ERROR_CODE
	    goto loser;
	}
	certType    = data[1];
	certLen     = (data[2] << 8) | data[3];
	responseLen = (data[4] << 8) | data[5];
	if (certType != SSL_CT_X509_CERTIFICATE) {
	    PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
	    goto loser;
	}
	if (certLen + responseLen + SSL_HL_CLIENT_CERTIFICATE_HBYTES 
	    > ss->gs.recordLen) {
	    /* prevent overflow crash. */
	    rv = SECFailure;
	} else
	rv = ssl2_HandleClientCertificate(ss, data[1],
		data + SSL_HL_CLIENT_CERTIFICATE_HBYTES,
		certLen,
		data + SSL_HL_CLIENT_CERTIFICATE_HBYTES + certLen,
		responseLen);
	if (rv) {
	    rv2 = ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
	    SET_ERROR_CODE
	    goto loser;
	}
	ss->sec.ci.elements |= CIS_HAVE_CERTIFICATE;
	break;

    case SSL_MT_ERROR:
	rv = (data[1] << 8) | data[2];
	SSL_TRC(2, ("%d: SSL[%d]: got error message, error=0x%x",
		    SSL_GETPID(), ss->fd, rv));

	/* Convert protocol error number into API error number */
	switch (rv) {
	  case SSL_PE_NO_CYPHERS:
	    rv = SSL_ERROR_NO_CYPHER_OVERLAP;
	    break;
	  case SSL_PE_NO_CERTIFICATE:
	    rv = SSL_ERROR_NO_CERTIFICATE;
	    break;
	  case SSL_PE_BAD_CERTIFICATE:
	    rv = SSL_ERROR_BAD_CERTIFICATE;
	    break;
	  case SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE:
	    rv = SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE;
	    break;
	  default:
	    goto bad_peer;
	}
	/* XXX make certificate-request optionally fail... */
	PORT_SetError(rv);
	goto loser;

    default:
	SSL_DBG(("%d: SSL[%d]: unknown message %d",
		 SSL_GETPID(), ss->fd, data[0]));
	goto loser;
    }

    SSL_TRC(3, ("%d: SSL[%d]: handled %d message, required=0x%x got=0x%x",
		SSL_GETPID(), ss->fd, data[0],
		ss->sec.ci.requiredElements, ss->sec.ci.elements));

    rv = ssl2_TryToFinish(ss);
    if (rv != SECSuccess) 
	goto loser;

    ss->gs.recordLen = 0;
    ssl_ReleaseRecvBufLock(ss);

    if (ss->handshake == 0) {
	return SECSuccess;
    }

    ss->handshake     = ssl_GatherRecord1stHandshake;
    ss->nextHandshake = ssl2_HandleMessage;
    return ssl2_TriggerNextMessage(ss);

  bad_peer:
    PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT : SSL_ERROR_BAD_SERVER);
    /* FALL THROUGH */

  loser:
    ssl_ReleaseRecvBufLock(ss);
    return SECFailure;
}

/************************************************************************/

/* Called from ssl_Do1stHandshake, after ssl2_HandleServerHelloMessage.
*/
static SECStatus
ssl2_HandleVerifyMessage(sslSocket *ss)
{
    PRUint8 *        data;
    SECStatus        rv;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    ssl_GetRecvBufLock(ss);

    data = ss->gs.buf.buf + ss->gs.recordOffset;
    DUMP_MSG(29, (ss, data, ss->gs.recordLen));
    if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) ||
	(data[0] != SSL_MT_SERVER_VERIFY) ||
	NSS_SecureMemcmp(data+1, ss->sec.ci.clientChallenge,
	                 SSL_CHALLENGE_BYTES)) {
	/* Bad server */
	PORT_SetError(SSL_ERROR_BAD_SERVER);
	goto loser;
    }
    ss->sec.ci.elements |= CIS_HAVE_VERIFY;

    SSL_TRC(5, ("%d: SSL[%d]: got server-verify, required=0x%d got=0x%x",
		SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements,
		ss->sec.ci.elements));

    rv = ssl2_TryToFinish(ss);
    if (rv) 
	goto loser;

    ss->gs.recordLen = 0;
    ssl_ReleaseRecvBufLock(ss);

    if (ss->handshake == 0) {
	return SECSuccess;
    }
    ss->handshake         = ssl_GatherRecord1stHandshake;
    ss->nextHandshake     = ssl2_HandleMessage;
    return SECSuccess;


  loser:
    ssl_ReleaseRecvBufLock(ss);
    return SECFailure;
}

/* Not static because ssl2_GatherData() tests ss->nextHandshake for this value.
 * ICK! 
 * Called from ssl_Do1stHandshake after ssl2_BeginClientHandshake()
 */
SECStatus
ssl2_HandleServerHelloMessage(sslSocket *ss)
{
    sslSessionID *   sid;
    PRUint8 *        cert;
    PRUint8 *        cs;
    PRUint8 *        data;
    SECStatus        rv; 
    int              needed, sidHit, certLen, csLen, cidLen, certType, err;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    if (!ss->opt.enableSSL2) {
	PORT_SetError(SSL_ERROR_SSL2_DISABLED);
	return SECFailure;
    }

    ssl_GetRecvBufLock(ss);

    PORT_Assert(ss->sec.ci.sid != 0);
    sid = ss->sec.ci.sid;

    data = ss->gs.buf.buf + ss->gs.recordOffset;
    DUMP_MSG(29, (ss, data, ss->gs.recordLen));

    /* Make sure first message has some data and is the server hello message */
    if ((ss->gs.recordLen < SSL_HL_SERVER_HELLO_HBYTES)
	|| (data[0] != SSL_MT_SERVER_HELLO)) {
	if ((data[0] == SSL_MT_ERROR) && (ss->gs.recordLen == 3)) {
	    err = (data[1] << 8) | data[2];
	    if (err == SSL_PE_NO_CYPHERS) {
		PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
		goto loser;
	    }
	}
	goto bad_server;
    }

    sidHit      = data[1];
    certType    = data[2];
    ss->version = (data[3] << 8) | data[4];
    certLen     = (data[5] << 8) | data[6];
    csLen       = (data[7] << 8) | data[8];
    cidLen      = (data[9] << 8) | data[10];
    cert        = data + SSL_HL_SERVER_HELLO_HBYTES;
    cs          = cert + certLen;

    SSL_TRC(5,
	    ("%d: SSL[%d]: server-hello, hit=%d vers=%x certLen=%d csLen=%d cidLen=%d",
	     SSL_GETPID(), ss->fd, sidHit, ss->version, certLen,
	     csLen, cidLen));
    if (ss->version != SSL_LIBRARY_VERSION_2) {
        if (ss->version < SSL_LIBRARY_VERSION_2) {
	  SSL_TRC(3, ("%d: SSL[%d]: demoting self (%x) to server version (%x)",
		      SSL_GETPID(), ss->fd, SSL_LIBRARY_VERSION_2,
		      ss->version));
	} else {
	  SSL_TRC(1, ("%d: SSL[%d]: server version is %x (we are %x)",
		    SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
	  /* server claims to be newer but does not follow protocol */
	  PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
	  goto loser;
	}
    }

    if ((SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen + cidLen 
                                                  > ss->gs.recordLen)
	|| (csLen % 3) != 0   
	/* || cidLen < SSL_CONNECTIONID_BYTES || cidLen > 32  */
	) {
	goto bad_server;
    }

    /* Save connection-id.
    ** This code only saves the first 16 byte of the connectionID.
    ** If the connectionID is shorter than 16 bytes, it is zero-padded.
    */
    if (cidLen < sizeof ss->sec.ci.connectionID)
	memset(ss->sec.ci.connectionID, 0, sizeof ss->sec.ci.connectionID);
    cidLen = PR_MIN(cidLen, sizeof ss->sec.ci.connectionID);
    PORT_Memcpy(ss->sec.ci.connectionID, cs + csLen, cidLen);

    /* See if session-id hit */
    needed = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED | CIS_HAVE_VERIFY;
    if (sidHit) {
	if (certLen || csLen) {
	    /* Uh oh - bogus server */
	    SSL_DBG(("%d: SSL[%d]: client, huh? hit=%d certLen=%d csLen=%d",
		     SSL_GETPID(), ss->fd, sidHit, certLen, csLen));
	    goto bad_server;
	}

	/* Total winner. */
	SSL_TRC(1, ("%d: SSL[%d]: client, using nonce for peer=0x%08x "
		    "port=0x%04x",
		    SSL_GETPID(), ss->fd, ss->sec.ci.peer, ss->sec.ci.port));
	ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
        ss->sec.authAlgorithm = sid->authAlgorithm;
	ss->sec.authKeyBits   = sid->authKeyBits;
	ss->sec.keaType       = sid->keaType;
	ss->sec.keaKeyBits    = sid->keaKeyBits;
	rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE);
	if (rv != SECSuccess) {
	    goto loser;
	}
    } else {
	if (certType != SSL_CT_X509_CERTIFICATE) {
	    PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
	    goto loser;
	}
	if (csLen == 0) {
	    PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
	    SSL_DBG(("%d: SSL[%d]: no cipher overlap",
		     SSL_GETPID(), ss->fd));
	    goto loser;
	}
	if (certLen == 0) {
	    SSL_DBG(("%d: SSL[%d]: client, huh? certLen=%d csLen=%d",
		     SSL_GETPID(), ss->fd, certLen, csLen));
	    goto bad_server;
	}

	if (sid->cached != never_cached) {
	    /* Forget our session-id - server didn't like it */
	    SSL_TRC(7, ("%d: SSL[%d]: server forgot me, uncaching session-id",
			SSL_GETPID(), ss->fd));
	    if (ss->sec.uncache)
		(*ss->sec.uncache)(sid);
	    ssl_FreeSID(sid);
	    ss->sec.ci.sid = sid = PORT_ZNew(sslSessionID);
	    if (!sid) {
		goto loser;
	    }
	    sid->references = 1;
	    sid->addr = ss->sec.ci.peer;
	    sid->port = ss->sec.ci.port;
	}

	/* decode the server's certificate */
	rv = ssl2_ClientHandleServerCert(ss, cert, certLen);
	if (rv != SECSuccess) {
	    if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
		(void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
	    }
	    goto loser;
	}

	/* Setup new session cipher */
	rv = ssl2_ClientSetupSessionCypher(ss, cs, csLen);
	if (rv != SECSuccess) {
	    if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
		(void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
	    }
	    goto loser;
	}
    }

    /* Build up final list of required elements */
    ss->sec.ci.elements         = CIS_HAVE_MASTER_KEY;
    ss->sec.ci.requiredElements = needed;

  if (!sidHit) {
    /* verify the server's certificate. if sidHit, don't check signatures */
    rv = (* ss->authCertificate)(ss->authCertificateArg, ss->fd, 
				 (PRBool)(!sidHit), PR_FALSE);
    if (rv) {
	if (ss->handleBadCert) {
	    rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd);
	    if ( rv ) {
		if ( rv == SECWouldBlock ) {
		    SSL_DBG(("%d: SSL[%d]: SSL2 bad cert handler returned "
			     "SECWouldBlock", SSL_GETPID(), ss->fd));
		    PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
		    rv = SECFailure;
		} else {
		    /* cert is bad */
		    SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
			     SSL_GETPID(), ss->fd, PORT_GetError()));
		}
		goto loser;
	    }
	    /* cert is good */
	} else {
	    SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
		     SSL_GETPID(), ss->fd, PORT_GetError()));
	    goto loser;
	}
    }
  }
    /*
    ** At this point we have a completed session key and our session
    ** cipher is setup and ready to go. Switch to encrypted write routine
    ** as all future message data is to be encrypted.
    */
    ssl2_UseEncryptedSendFunc(ss);

    rv = ssl2_TryToFinish(ss);
    if (rv != SECSuccess) 
	goto loser;

    ss->gs.recordLen = 0;

    ssl_ReleaseRecvBufLock(ss);

    if (ss->handshake == 0) {
	return SECSuccess;
    }

    SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x",
		SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements, 
		ss->sec.ci.elements));
    ss->handshake     = ssl_GatherRecord1stHandshake;
    ss->nextHandshake = ssl2_HandleVerifyMessage;
    return SECSuccess;

  bad_server:
    PORT_SetError(SSL_ERROR_BAD_SERVER);
    /* FALL THROUGH */

  loser:
    ssl_ReleaseRecvBufLock(ss);
    return SECFailure;
}

/* Sends out the initial client Hello message on the connection.
 * Acquires and releases the socket's xmitBufLock.
 */
SECStatus
ssl2_BeginClientHandshake(sslSocket *ss)
{
    sslSessionID      *sid;
    PRUint8           *msg;
    PRUint8           *cp;
    PRUint8           *localCipherSpecs = NULL;
    unsigned int      localCipherSize;
    unsigned int      i;
    int               sendLen, sidLen = 0;
    SECStatus         rv;
    TLSExtensionData  *xtnData;

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    ss->sec.isServer     = 0;
    ss->sec.sendSequence = 0;
    ss->sec.rcvSequence  = 0;
    ssl_ChooseSessionIDProcs(&ss->sec);

    if (!ss->cipherSpecs) {
	rv = ssl2_ConstructCipherSpecs(ss);
	if (rv != SECSuccess)
	    goto loser;
    }

    /* count the SSL2 and SSL3 enabled ciphers.
     * if either is zero, clear the socket's enable for that protocol.
     */
    rv = ssl2_CheckConfigSanity(ss);
    if (rv != SECSuccess)
	goto loser;

    /* Get peer name of server */
    rv = ssl_GetPeerInfo(ss);
    if (rv < 0) {
#ifdef HPUX11
        /*
         * On some HP-UX B.11.00 systems, getpeername() occasionally
         * fails with ENOTCONN after a successful completion of
         * non-blocking connect.  I found that if we do a write()
         * and then retry getpeername(), it will work.
         */
        if (PR_GetError() == PR_NOT_CONNECTED_ERROR) {
            char dummy;
            (void) PR_Write(ss->fd->lower, &dummy, 0);
            rv = ssl_GetPeerInfo(ss);
            if (rv < 0) {
                goto loser;
            }
        }
#else
	goto loser;
#endif
    }

    SSL_TRC(3, ("%d: SSL[%d]: sending client-hello", SSL_GETPID(), ss->fd));

    /* Try to find server in our session-id cache */
    if (ss->opt.noCache) {
	sid = NULL;
    } else {
	sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, 
	                    ss->url);
    }
    while (sid) {  /* this isn't really a loop */
	PRBool sidVersionEnabled =
	    (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) &&
	     sid->version >= ss->vrange.min &&
	     sid->version <= ss->vrange.max) ||
	    (sid->version < SSL_LIBRARY_VERSION_3_0 && ss->opt.enableSSL2);

	/* if we're not doing this SID's protocol any more, drop it. */
	if (!sidVersionEnabled) {
	    if (ss->sec.uncache)
		ss->sec.uncache(sid);
	    ssl_FreeSID(sid);
	    sid = NULL;
	    break;
	}
	if (sid->version < SSL_LIBRARY_VERSION_3_0) {
	    /* If the cipher in this sid is not enabled, drop it. */
	    for (i = 0; i < ss->sizeCipherSpecs; i += 3) {
		if (ss->cipherSpecs[i] == sid->u.ssl2.cipherType)
		    break;
	    }
	    if (i >= ss->sizeCipherSpecs) {
		if (ss->sec.uncache)
		    ss->sec.uncache(sid);
		ssl_FreeSID(sid);
		sid = NULL;
		break;
	    }
	}
	sidLen = sizeof(sid->u.ssl2.sessionID);
	PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl2.sessionID,
		      sidLen));
	ss->version = sid->version;
	PORT_Assert(!ss->sec.localCert);
	if (ss->sec.localCert) {
	    CERT_DestroyCertificate(ss->sec.localCert);
	}
	ss->sec.localCert     = CERT_DupCertificate(sid->localCert);
	break;  /* this isn't really a loop */
    } 
    if (!sid) {
	sidLen = 0;
	sid = PORT_ZNew(sslSessionID);
	if (!sid) {
	    goto loser;
	}
	sid->references = 1;
	sid->cached     = never_cached;
	sid->addr       = ss->sec.ci.peer;
	sid->port       = ss->sec.ci.port;
	if (ss->peerID != NULL) {
	    sid->peerID = PORT_Strdup(ss->peerID);
	}
	if (ss->url != NULL) {
	    sid->urlSvrName = PORT_Strdup(ss->url);
	}
    }
    ss->sec.ci.sid = sid;

    PORT_Assert(sid != NULL);

    if ((sid->version >= SSL_LIBRARY_VERSION_3_0 || !ss->opt.v2CompatibleHello) &&
	!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
	ss->gs.state      = GS_INIT;
	ss->handshake     = ssl_GatherRecord1stHandshake;

	/* ssl3_SendClientHello will override this if it succeeds. */
	ss->version       = SSL_LIBRARY_VERSION_3_0;

	ssl_GetSSL3HandshakeLock(ss);
	ssl_GetXmitBufLock(ss);
	rv =  ssl3_SendClientHello(ss, PR_FALSE);
	ssl_ReleaseXmitBufLock(ss);
	ssl_ReleaseSSL3HandshakeLock(ss);

	return rv;
    }
#ifndef NSS_DISABLE_ECC
    /* ensure we don't neogtiate ECC cipher suites with SSL2 hello */
    ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */
    if (ss->cipherSpecs != NULL) {
	PORT_Free(ss->cipherSpecs);
	ss->cipherSpecs     = NULL;
	ss->sizeCipherSpecs = 0;
    }
#endif /* NSS_DISABLE_ECC */

    if (!ss->cipherSpecs) {
        rv = ssl2_ConstructCipherSpecs(ss);
	if (rv < 0) {
	    return rv;
    	}
    }
    localCipherSpecs = ss->cipherSpecs;
    localCipherSize  = ss->sizeCipherSpecs;

    /* Add 3 for SCSV */
    sendLen = SSL_HL_CLIENT_HELLO_HBYTES + localCipherSize + 3 + sidLen +
	SSL_CHALLENGE_BYTES;

    /* Generate challenge bytes for server */
    PK11_GenerateRandom(ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);

    ssl_GetXmitBufLock(ss);    /***************************************/

    rv = ssl2_GetSendBuffer(ss, sendLen);
    if (rv) 
    	goto unlock_loser;

    /* Construct client-hello message */
    cp = msg = ss->sec.ci.sendBuf.buf;
    msg[0] = SSL_MT_CLIENT_HELLO;
    ss->clientHelloVersion = SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) ?
	SSL_LIBRARY_VERSION_2 : ss->vrange.max;

    msg[1] = MSB(ss->clientHelloVersion);
    msg[2] = LSB(ss->clientHelloVersion);
    /* Add 3 for SCSV */
    msg[3] = MSB(localCipherSize + 3);
    msg[4] = LSB(localCipherSize + 3);
    msg[5] = MSB(sidLen);
    msg[6] = LSB(sidLen);
    msg[7] = MSB(SSL_CHALLENGE_BYTES);
    msg[8] = LSB(SSL_CHALLENGE_BYTES);
    cp += SSL_HL_CLIENT_HELLO_HBYTES;
    PORT_Memcpy(cp, localCipherSpecs, localCipherSize);
    cp += localCipherSize;
    /*
     * Add SCSV.  SSL 2.0 cipher suites are listed before SSL 3.0 cipher
     * suites in localCipherSpecs for compatibility with SSL 2.0 servers.
     * Since SCSV looks like an SSL 3.0 cipher suite, we can't add it at
     * the beginning.
     */
    cp[0] = 0x00;
    cp[1] = 0x00;
    cp[2] = 0xff;
    cp += 3;
    if (sidLen) {
	PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen);
	cp += sidLen;
    }
    PORT_Memcpy(cp, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);

    /* Send it to the server */
    DUMP_MSG(29, (ss, msg, sendLen));
    ss->handshakeBegun = 1;
    rv = (*ss->sec.send)(ss, msg, sendLen, 0);

    ssl_ReleaseXmitBufLock(ss);    /***************************************/

    if (rv < 0) {
	goto loser;
    }

    rv = ssl3_StartHandshakeHash(ss, msg, sendLen);
    if (rv < 0) {
	goto loser;
    }

    /*
     * Since we sent the SCSV, pretend we sent empty RI extension.  We need
     * to record the extension has been advertised after ssl3_InitState has
     * been called, which ssl3_StartHandshakeHash took care for us above.
     */
    xtnData = &ss->xtnData;
    xtnData->advertised[xtnData->numAdvertised++] = ssl_renegotiation_info_xtn;

    /* Setup to receive servers hello message */
    ssl_GetRecvBufLock(ss);
    ss->gs.recordLen = 0;
    ssl_ReleaseRecvBufLock(ss);

    ss->handshake     = ssl_GatherRecord1stHandshake;
    ss->nextHandshake = ssl2_HandleServerHelloMessage;
    return SECSuccess;

unlock_loser:
    ssl_ReleaseXmitBufLock(ss);
loser:
    return SECFailure;
}

/************************************************************************/

/* Handle the CLIENT-MASTER-KEY message. 
** Acquires and releases RecvBufLock.
** Called from ssl2_HandleClientHelloMessage(). 
*/
static SECStatus
ssl2_HandleClientSessionKeyMessage(sslSocket *ss)
{
    PRUint8 *        data;
    unsigned int     caLen;
    unsigned int     ckLen;
    unsigned int     ekLen;
    unsigned int     keyBits;
    int              cipher;
    SECStatus        rv;


    ssl_GetRecvBufLock(ss);

    data = ss->gs.buf.buf + ss->gs.recordOffset;
    DUMP_MSG(29, (ss, data, ss->gs.recordLen));

    if ((ss->gs.recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES)
	|| (data[0] != SSL_MT_CLIENT_MASTER_KEY)) {
	goto bad_client;
    }
    cipher  = data[1];
    keyBits = (data[2] << 8) | data[3];
    ckLen   = (data[4] << 8) | data[5];
    ekLen   = (data[6] << 8) | data[7];
    caLen   = (data[8] << 8) | data[9];

    SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keyBits=%d ckLen=%d ekLen=%d caLen=%d",
		SSL_GETPID(), ss->fd, cipher, keyBits, ckLen, ekLen, caLen));

    if (ss->gs.recordLen < 
    	    SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen) {
	SSL_DBG(("%d: SSL[%d]: protocol size mismatch dataLen=%d",
		 SSL_GETPID(), ss->fd, ss->gs.recordLen));
	goto bad_client;
    }

    /* Use info from client to setup session key */
    rv = ssl2_ServerSetupSessionCypher(ss, cipher, keyBits,
		data + SSL_HL_CLIENT_MASTER_KEY_HBYTES,                 ckLen,
		data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen,         ekLen,
		data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen, caLen);
    ss->gs.recordLen = 0;	/* we're done with this record. */

    ssl_ReleaseRecvBufLock(ss);

    if (rv != SECSuccess) {
	goto loser;
    }
    ss->sec.ci.elements |= CIS_HAVE_MASTER_KEY;
    ssl2_UseEncryptedSendFunc(ss);

    /* Send server verify message now that keys are established */
    rv = ssl2_SendServerVerifyMessage(ss);
    if (rv != SECSuccess) 
	goto loser;

    rv = ssl2_TryToFinish(ss);
    if (rv != SECSuccess) 
	goto loser;
    if (ss->handshake == 0) {
	return SECSuccess;
    }

    SSL_TRC(5, ("%d: SSL[%d]: server: waiting for elements=0x%d",
		SSL_GETPID(), ss->fd, 
		ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
    ss->handshake         = ssl_GatherRecord1stHandshake;
    ss->nextHandshake     = ssl2_HandleMessage;

    return ssl2_TriggerNextMessage(ss);

bad_client:
    ssl_ReleaseRecvBufLock(ss);
    PORT_SetError(SSL_ERROR_BAD_CLIENT);
    /* FALLTHROUGH */

loser:
    return SECFailure;
}

/*
** Handle the initial hello message from the client
**
** not static because ssl2_GatherData() tests ss->nextHandshake for this value.
*/
SECStatus
ssl2_HandleClientHelloMessage(sslSocket *ss)
{
    sslSessionID    *sid;
    sslServerCerts * sc;
    CERTCertificate *serverCert;
    PRUint8         *msg;
    PRUint8         *data;
    PRUint8         *cs;
    PRUint8         *sd;
    PRUint8         *cert = NULL;
    PRUint8         *challenge;
    unsigned int    challengeLen;
    SECStatus       rv; 
    int             csLen;
    int             sendLen;
    int             sdLen;
    int             certLen;
    int             pid;
    int             sent;
    int             gotXmitBufLock = 0;
#if defined(SOLARIS) && defined(i386)
    volatile PRUint8 hit;
#else
    int             hit;
#endif
    PRUint8         csImpl[sizeof implementedCipherSuites];

    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );

    sc = ss->serverCerts + kt_rsa;
    serverCert = sc->serverCert;

    ssl_GetRecvBufLock(ss);


    data = ss->gs.buf.buf + ss->gs.recordOffset;
    DUMP_MSG(29, (ss, data, ss->gs.recordLen));

    /* Make sure first message has some data and is the client hello message */
    if ((ss->gs.recordLen < SSL_HL_CLIENT_HELLO_HBYTES)
	|| (data[0] != SSL_MT_CLIENT_HELLO)) {
	goto bad_client;
    }

    /* Get peer name of client */
    rv = ssl_GetPeerInfo(ss);
    if (rv != SECSuccess) {
	goto loser;
    }

    /* Examine version information */
    /*
     * See if this might be a V2 client hello asking to use the V3 protocol
     */
    if ((data[0] == SSL_MT_CLIENT_HELLO) && 
        (data[1] >= MSB(SSL_LIBRARY_VERSION_3_0)) && 
	!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
	rv = ssl3_HandleV2ClientHello(ss, data, ss->gs.recordLen);
	if (rv != SECFailure) { /* Success */
	    ss->handshake             = NULL;
	    ss->nextHandshake         = ssl_GatherRecord1stHandshake;
	    ss->securityHandshake     = NULL;
	    ss->gs.state              = GS_INIT;

	    /* ssl3_HandleV3ClientHello has set ss->version,
	    ** and has gotten us a brand new sid.  
	    */
	    ss->sec.ci.sid->version  = ss->version;
	}
	ssl_ReleaseRecvBufLock(ss);
	return rv;
    }
    /* Previously, there was a test here to see if SSL2 was enabled.
    ** If not, an error code was set, and SECFailure was returned,
    ** without sending any error code to the other end of the connection.
    ** That test has been removed.  If SSL2 has been disabled, there
    ** should be no SSL2 ciphers enabled, and consequently, the code
    ** below should send the ssl2 error message SSL_PE_NO_CYPHERS.
    ** We now believe this is the correct thing to do, even when SSL2
    ** has been explicitly disabled by the application.
    */

    /* Extract info from message */
    ss->version = (data[1] << 8) | data[2];

    /* If some client thinks ssl v2 is 2.0 instead of 0.2, we'll allow it.  */
    if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
	ss->version = SSL_LIBRARY_VERSION_2;
    }
    
    csLen        = (data[3] << 8) | data[4];
    sdLen        = (data[5] << 8) | data[6];
    challengeLen = (data[7] << 8) | data[8];
    cs           = data + SSL_HL_CLIENT_HELLO_HBYTES;
    sd           = cs + csLen;
    challenge    = sd + sdLen;
    PRINT_BUF(7, (ss, "server, client session-id value:", sd, sdLen));

    if (!csLen || (csLen % 3) != 0 || 
        (sdLen != 0 && sdLen != SSL2_SESSIONID_BYTES) ||
	challengeLen < SSL_MIN_CHALLENGE_BYTES || 
	challengeLen > SSL_MAX_CHALLENGE_BYTES ||
        (unsigned)ss->gs.recordLen != 
            SSL_HL_CLIENT_HELLO_HBYTES + csLen + sdLen + challengeLen) {
	SSL_DBG(("%d: SSL[%d]: bad client hello message, len=%d should=%d",
		 SSL_GETPID(), ss->fd, ss->gs.recordLen,
		 SSL_HL_CLIENT_HELLO_HBYTES+csLen+sdLen+challengeLen));
	goto bad_client;
    }

    SSL_TRC(3, ("%d: SSL[%d]: client version is %x",
		SSL_GETPID(), ss->fd, ss->version));
    if (ss->version != SSL_LIBRARY_VERSION_2) {
	if (ss->version > SSL_LIBRARY_VERSION_2) {
	    /*
	    ** Newer client than us. Things are ok because new clients
	    ** are required to be backwards compatible with old servers.
	    ** Change version number to our version number so that client
	    ** knows whats up.
	    */
	    ss->version = SSL_LIBRARY_VERSION_2;
	} else {
	    SSL_TRC(1, ("%d: SSL[%d]: client version is %x (we are %x)",
		SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
	    PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
	    goto loser;
	}
    }

    /* Qualify cipher specs before returning them to client */
    csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
    if (csLen == 0) {
	/* no overlap, send client our list of supported SSL v2 ciphers. */
        cs    = csImpl;
	csLen = sizeof implementedCipherSuites;
    	PORT_Memcpy(cs, implementedCipherSuites, csLen);
	csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
	if (csLen == 0) {
	  /* We don't support any SSL v2 ciphers! */
	  ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
	  PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
	  goto loser;
	}
	/* Since this handhsake is going to fail, don't cache it. */
	ss->opt.noCache = 1; 
    }

    /* Squirrel away the challenge for later */
    PORT_Memcpy(ss->sec.ci.clientChallenge, challenge, challengeLen);

    /* Examine message and see if session-id is good */
    ss->sec.ci.elements = 0;
    if (sdLen > 0 && !ss->opt.noCache) {
	SSL_TRC(7, ("%d: SSL[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x",
		    SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0],
		    ss->sec.ci.peer.pr_s6_addr32[1], 
		    ss->sec.ci.peer.pr_s6_addr32[2],
		    ss->sec.ci.peer.pr_s6_addr32[3]));
	sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sd, sdLen, ss->dbHandle);
    } else {
	sid = NULL;
    }
    if (sid) {
	/* Got a good session-id. Short cut! */
	SSL_TRC(1, ("%d: SSL[%d]: server, using session-id for 0x%08x (age=%d)",
		    SSL_GETPID(), ss->fd, ss->sec.ci.peer, 
		    ssl_Time() - sid->creationTime));
	PRINT_BUF(1, (ss, "session-id value:", sd, sdLen));
	ss->sec.ci.sid = sid;
	ss->sec.ci.elements = CIS_HAVE_MASTER_KEY;
	hit = 1;
	certLen = 0;
	csLen = 0;

        ss->sec.authAlgorithm = sid->authAlgorithm;
	ss->sec.authKeyBits   = sid->authKeyBits;
	ss->sec.keaType       = sid->keaType;
	ss->sec.keaKeyBits    = sid->keaKeyBits;

	rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
	if (rv != SECSuccess) {
	    goto loser;
	}
    } else {
	SECItem * derCert   = &serverCert->derCert;

	SSL_TRC(7, ("%d: SSL[%d]: server, lookup nonce missed",
		    SSL_GETPID(), ss->fd));
	if (!serverCert) {
	    SET_ERROR_CODE
	    goto loser;
	}
	hit = 0;
	sid = PORT_ZNew(sslSessionID);
	if (!sid) {
	    goto loser;
	}
	sid->references = 1;
	sid->addr = ss->sec.ci.peer;
	sid->port = ss->sec.ci.port;

	/* Invent a session-id */
	ss->sec.ci.sid = sid;
	PK11_GenerateRandom(sid->u.ssl2.sessionID+2, SSL2_SESSIONID_BYTES-2);

	pid = SSL_GETPID();
	sid->u.ssl2.sessionID[0] = MSB(pid);
	sid->u.ssl2.sessionID[1] = LSB(pid);
	cert    = derCert->data;
	certLen = derCert->len;

	/* pretend that server sids remember the local cert. */
	PORT_Assert(!sid->localCert);
	if (sid->localCert) {
	    CERT_DestroyCertificate(sid->localCert);
	}
	sid->localCert     = CERT_DupCertificate(serverCert);

	ss->sec.authAlgorithm = ssl_sign_rsa;
	ss->sec.keaType       = ssl_kea_rsa;
	ss->sec.keaKeyBits    = \
	ss->sec.authKeyBits   = ss->serverCerts[kt_rsa].serverKeyBits;
    }

    /* server sids don't remember the local cert, so whether we found
    ** a sid or not, just "remember" we used the rsa server cert.
    */
    if (ss->sec.localCert) {
	CERT_DestroyCertificate(ss->sec.localCert);
    }
    ss->sec.localCert     = CERT_DupCertificate(serverCert);

    /* Build up final list of required elements */
    ss->sec.ci.requiredElements = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED;
    if (ss->opt.requestCertificate) {
	ss->sec.ci.requiredElements |= CIS_HAVE_CERTIFICATE;
    }
    ss->sec.ci.sentElements = 0;

    /* Send hello message back to client */
    sendLen = SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen
	    + SSL_CONNECTIONID_BYTES;

    ssl_GetXmitBufLock(ss); gotXmitBufLock = 1;
    rv = ssl2_GetSendBuffer(ss, sendLen);
    if (rv != SECSuccess) {
	goto loser;
    }

    SSL_TRC(3, ("%d: SSL[%d]: sending server-hello (%d)",
		SSL_GETPID(), ss->fd, sendLen));

    msg = ss->sec.ci.sendBuf.buf;
    msg[0] = SSL_MT_SERVER_HELLO;
    msg[1] = hit;
    msg[2] = SSL_CT_X509_CERTIFICATE;
    msg[3] = MSB(ss->version);
    msg[4] = LSB(ss->version);
    msg[5] = MSB(certLen);
    msg[6] = LSB(certLen);
    msg[7] = MSB(csLen);
    msg[8] = LSB(csLen);
    msg[9] = MSB(SSL_CONNECTIONID_BYTES);
    msg[10] = LSB(SSL_CONNECTIONID_BYTES);
    if (certLen) {
	PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES, cert, certLen);
    }
    if (csLen) {
	PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen, cs, csLen);
    }
    PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen+csLen, 
                ss->sec.ci.connectionID, SSL_CONNECTIONID_BYTES);

    DUMP_MSG(29, (ss, msg, sendLen));

    ss->handshakeBegun = 1;
    sent = (*ss->sec.send)(ss, msg, sendLen, 0);
    if (sent < 0) {
	goto loser;
    }
    ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0;

    ss->gs.recordLen = 0;
    ss->handshake = ssl_GatherRecord1stHandshake;
    if (hit) {
	/* Old SID Session key is good. Go encrypted */
	ssl2_UseEncryptedSendFunc(ss);

	/* Send server verify message now that keys are established */
	rv = ssl2_SendServerVerifyMessage(ss);
	if (rv != SECSuccess) 
	    goto loser;

	ss->nextHandshake = ssl2_HandleMessage;
	ssl_ReleaseRecvBufLock(ss);
	rv = ssl2_TriggerNextMessage(ss);
	return rv;
    }
    ss->nextHandshake = ssl2_HandleClientSessionKeyMessage;
    ssl_ReleaseRecvBufLock(ss);
    return SECSuccess;

  bad_client:
    PORT_SetError(SSL_ERROR_BAD_CLIENT);
    /* FALLTHROUGH */

  loser:
    if (gotXmitBufLock) {
    	ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0;
    }
    SSL_TRC(10, ("%d: SSL[%d]: server, wait for client-hello lossage",
		 SSL_GETPID(), ss->fd));
    ssl_ReleaseRecvBufLock(ss);
    return SECFailure;
}

SECStatus
ssl2_BeginServerHandshake(sslSocket *ss)
{
    SECStatus        rv;
    sslServerCerts * rsaAuth = ss->serverCerts + kt_rsa;

    ss->sec.isServer = 1;
    ssl_ChooseSessionIDProcs(&ss->sec);
    ss->sec.sendSequence = 0;
    ss->sec.rcvSequence = 0;

    /* don't turn on SSL2 if we don't have an RSA key and cert */
    if (!rsaAuth->serverKeyPair || !rsaAuth->SERVERKEY || 
        !rsaAuth->serverCert) {
	ss->opt.enableSSL2 = PR_FALSE;
    }

    if (!ss->cipherSpecs) {
	rv = ssl2_ConstructCipherSpecs(ss);
	if (rv != SECSuccess)
	    goto loser;
    }

    /* count the SSL2 and SSL3 enabled ciphers.
     * if either is zero, clear the socket's enable for that protocol.
     */
    rv = ssl2_CheckConfigSanity(ss);
    if (rv != SECSuccess)
	goto loser;

    /*
    ** Generate connection-id. Always do this, even if things fail
    ** immediately. This way the random number generator is always
    ** rolling around, every time we get a connection.
    */
    PK11_GenerateRandom(ss->sec.ci.connectionID, 
                        sizeof(ss->sec.ci.connectionID));

    ss->gs.recordLen = 0;
    ss->handshake     = ssl_GatherRecord1stHandshake;
    ss->nextHandshake = ssl2_HandleClientHelloMessage;
    return SECSuccess;

loser:
    return SECFailure;
}

/* This function doesn't really belong in this file.
** It's here to keep AIX compilers from optimizing it away, 
** and not including it in the DSO.
*/

#include "nss.h"
extern const char __nss_ssl_rcsid[];
extern const char __nss_ssl_sccsid[];

PRBool
NSSSSL_VersionCheck(const char *importedVersion)
{
    /*
     * This is the secret handshake algorithm.
     *
     * This release has a simple version compatibility
     * check algorithm.  This release is not backward
     * compatible with previous major releases.  It is
     * not compatible with future major, minor, or
     * patch releases.
     */
    volatile char c; /* force a reference that won't get optimized away */

    c = __nss_ssl_rcsid[0] + __nss_ssl_sccsid[0]; 
    return NSS_VersionCheck(importedVersion);
}

const char *
NSSSSL_GetVersion(void)
{
    return NSS_VERSION;
}
