/* 
 * 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);
	SECITEM_CopyItem(0, &sec->sendSecret, writeKey);
	SECITEM_CopyItem(0, &sec->rcvSecret, readKey);
	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;
    }
#if defined(NSS_ENABLE_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

    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;
}
