/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * SSL3 Protocol
 *
 * 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/. */

/* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */

#include "cert.h"
#include "ssl.h"
#include "cryptohi.h"	/* for DSAU_ stuff */
#include "keyhi.h"
#include "secder.h"
#include "secitem.h"
#include "sechash.h"

#include "sslimpl.h"
#include "sslproto.h"
#include "sslerr.h"
#include "prtime.h"
#include "prinrval.h"
#include "prerror.h"
#include "pratom.h"
#include "prthread.h"

#include "pk11func.h"
#include "secmod.h"
#ifndef NO_PKCS11_BYPASS
#include "blapi.h"
#endif

/* This is a bodge to allow this code to be compiled against older NSS headers
 * that don't contain the TLS 1.2 changes. */
#ifndef CKM_NSS_TLS_PRF_GENERAL_SHA256
#define CKM_NSS_TLS_PRF_GENERAL_SHA256          (CKM_NSS + 21)
#define CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256    (CKM_NSS + 22)
#define CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256   (CKM_NSS + 23)
#define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24)
#endif

/* This is a bodge to allow this code to be compiled against older NSS
 * headers. */
#ifndef CKM_NSS_CHACHA20_POLY1305
#define CKM_NSS_CHACHA20_POLY1305               (CKM_NSS + 26)

typedef struct CK_NSS_AEAD_PARAMS {
    CK_BYTE_PTR  pIv;  /* This is the nonce. */
    CK_ULONG     ulIvLen;
    CK_BYTE_PTR  pAAD;
    CK_ULONG     ulAADLen;
    CK_ULONG     ulTagLen;
} CK_NSS_AEAD_PARAMS;

#endif

#include <stdio.h>
#ifdef NSS_ENABLE_ZLIB
#include "zlib.h"
#endif
#ifdef LINUX
#include <dlfcn.h>
#endif

#ifndef PK11_SETATTRS
#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
		(x)->pValue=(v); (x)->ulValueLen = (l);
#endif

static SECStatus ssl3_AuthCertificate(sslSocket *ss);
static void      ssl3_CleanupPeerCerts(sslSocket *ss);
static void      ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid);
static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
                                       PK11SlotInfo * serverKeySlot);
static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms);
static SECStatus ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss);
static SECStatus ssl3_HandshakeFailure(      sslSocket *ss);
static SECStatus ssl3_InitState(             sslSocket *ss);
static SECStatus ssl3_SendCertificate(       sslSocket *ss);
static SECStatus ssl3_SendCertificateStatus( sslSocket *ss);
static SECStatus ssl3_SendEmptyCertificate(  sslSocket *ss);
static SECStatus ssl3_SendCertificateRequest(sslSocket *ss);
static SECStatus ssl3_SendNextProto(         sslSocket *ss);
static SECStatus ssl3_SendEncryptedExtensions(sslSocket *ss);
static SECStatus ssl3_SendFinished(          sslSocket *ss, PRInt32 flags);
static SECStatus ssl3_SendServerHello(       sslSocket *ss);
static SECStatus ssl3_SendServerHelloDone(   sslSocket *ss);
static SECStatus ssl3_SendServerKeyExchange( sslSocket *ss);
static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss,
                                             const unsigned char *b,
                                             unsigned int l);
static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags);
static int       ssl3_OIDToTLSHashAlgorithm(SECOidTag oid);

static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen,
			     int maxOutputLen, const unsigned char *input,
			     int inputLen);
#ifndef NO_PKCS11_BYPASS
static SECStatus ssl3_AESGCMBypass(ssl3KeyMaterial *keys, PRBool doDecrypt,
				   unsigned char *out, int *outlen, int maxout,
				   const unsigned char *in, int inlen,
				   const unsigned char *additionalData,
				   int additionalDataLen);
#endif

#define MAX_SEND_BUF_LENGTH 32000 /* watch for 16-bit integer overflow */
#define MIN_SEND_BUF_LENGTH  4000

/* This list of SSL3 cipher suites is sorted in descending order of
 * precedence (desirability).  It only includes cipher suites we implement.
 * This table is modified by SSL3_SetPolicy(). The ordering of cipher suites
 * in this table must match the ordering in SSL_ImplementedCiphers (sslenum.c)
 *
 * Important: See bug 946147 before enabling, reordering, or adding any cipher
 * suites to this list.
 */
static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
   /*      cipher_suite                     policy       enabled   isPresent */

#ifdef NSS_ENABLE_ECC
 { TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,  SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,    SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
   /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is out of order to work around
    * bug 946147.
    */
 { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,    SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,    SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,      SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,      SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,     SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,        SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDHE_RSA_WITH_RC4_128_SHA,          SSL_ALLOWED, PR_FALSE, PR_FALSE},
#endif /* NSS_ENABLE_ECC */

 { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,     SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { TLS_DHE_RSA_WITH_AES_128_CBC_SHA,        SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { TLS_DHE_DSS_WITH_AES_128_CBC_SHA,        SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,     SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_DHE_RSA_WITH_AES_256_CBC_SHA,        SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { TLS_DHE_DSS_WITH_AES_256_CBC_SHA,        SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,     SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,       SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,       SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { TLS_DHE_DSS_WITH_RC4_128_SHA,            SSL_ALLOWED, PR_FALSE, PR_FALSE},

#ifdef NSS_ENABLE_ECC
 { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,     SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,       SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,     SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,       SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,    SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,      SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDH_ECDSA_WITH_RC4_128_SHA,         SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDH_RSA_WITH_RC4_128_SHA,           SSL_ALLOWED, PR_FALSE, PR_FALSE},
#endif /* NSS_ENABLE_ECC */

 /* RSA */
 { TLS_RSA_WITH_AES_128_GCM_SHA256,         SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { TLS_RSA_WITH_AES_128_CBC_SHA,            SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { TLS_RSA_WITH_AES_128_CBC_SHA256,         SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,       SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_RSA_WITH_AES_256_CBC_SHA,            SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { TLS_RSA_WITH_AES_256_CBC_SHA256,         SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,       SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_RSA_WITH_SEED_CBC_SHA,               SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,      SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { SSL_RSA_WITH_3DES_EDE_CBC_SHA,           SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { SSL_RSA_WITH_RC4_128_SHA,                SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 { SSL_RSA_WITH_RC4_128_MD5,                SSL_ALLOWED, PR_TRUE,  PR_FALSE},

 /* 56-bit DES "domestic" cipher suites */
 { SSL_DHE_RSA_WITH_DES_CBC_SHA,            SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { SSL_DHE_DSS_WITH_DES_CBC_SHA,            SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { SSL_RSA_FIPS_WITH_DES_CBC_SHA,           SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { SSL_RSA_WITH_DES_CBC_SHA,                SSL_ALLOWED, PR_FALSE, PR_FALSE},

 /* export ciphersuites with 1024-bit public key exchange keys */
 { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,      SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,     SSL_ALLOWED, PR_FALSE, PR_FALSE},

 /* export ciphersuites with 512-bit public key exchange keys */
 { SSL_RSA_EXPORT_WITH_RC4_40_MD5,          SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,      SSL_ALLOWED, PR_FALSE, PR_FALSE},

 /* ciphersuites with no encryption */
#ifdef NSS_ENABLE_ECC
 { TLS_ECDHE_ECDSA_WITH_NULL_SHA,           SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDHE_RSA_WITH_NULL_SHA,             SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDH_RSA_WITH_NULL_SHA,              SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_ECDH_ECDSA_WITH_NULL_SHA,            SSL_ALLOWED, PR_FALSE, PR_FALSE},
#endif /* NSS_ENABLE_ECC */
 { SSL_RSA_WITH_NULL_SHA,                   SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { TLS_RSA_WITH_NULL_SHA256,                SSL_ALLOWED, PR_FALSE, PR_FALSE},
 { SSL_RSA_WITH_NULL_MD5,                   SSL_ALLOWED, PR_FALSE, PR_FALSE},
};

/* Verify that SSL_ImplementedCiphers and cipherSuites are in consistent order.
 */
#ifdef DEBUG
void ssl3_CheckCipherSuiteOrderConsistency()
{
    unsigned int i;

    /* Note that SSL_ImplementedCiphers has more elements than cipherSuites
     * because it SSL_ImplementedCiphers includes SSL 2.0 cipher suites.
     */
    PORT_Assert(SSL_NumImplementedCiphers >= PR_ARRAY_SIZE(cipherSuites));

    for (i = 0; i < PR_ARRAY_SIZE(cipherSuites); ++i) {
        PORT_Assert(SSL_ImplementedCiphers[i] == cipherSuites[i].cipher_suite);
    }
}
#endif

/* This list of SSL3 compression methods is sorted in descending order of
 * precedence (desirability).  It only includes compression methods we
 * implement.
 */
static const /*SSLCompressionMethod*/ PRUint8 compressions [] = {
#ifdef NSS_ENABLE_ZLIB
    ssl_compression_deflate,
#endif
    ssl_compression_null
};

static const int compressionMethodsCount =
    sizeof(compressions) / sizeof(compressions[0]);

/* compressionEnabled returns true iff the compression algorithm is enabled
 * for the given SSL socket. */
static PRBool
compressionEnabled(sslSocket *ss, SSLCompressionMethod compression)
{
    switch (compression) {
    case ssl_compression_null:
	return PR_TRUE;  /* Always enabled */
#ifdef NSS_ENABLE_ZLIB
    case ssl_compression_deflate:
	return ss->opt.enableDeflate;
#endif
    default:
	return PR_FALSE;
    }
}

static const /*SSL3ClientCertificateType */ PRUint8 certificate_types [] = {
    ct_RSA_sign,
#ifdef NSS_ENABLE_ECC
    ct_ECDSA_sign,
#endif /* NSS_ENABLE_ECC */
    ct_DSS_sign,
};

/* This block is the contents of the supported_signature_algorithms field of
 * our TLS 1.2 CertificateRequest message, in wire format. See
 * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
 *
 * This block contains only sha256 entries because we only support TLS 1.2
 * CertificateVerify messages that use the handshake hash. */
static const PRUint8 supported_signature_algorithms[] = {
    tls_hash_sha256, tls_sig_rsa,
#ifdef NSS_ENABLE_ECC
    tls_hash_sha256, tls_sig_ecdsa,
#endif
    tls_hash_sha256, tls_sig_dsa,
};

#define EXPORT_RSA_KEY_LENGTH 64	/* bytes */


/* This global item is used only in servers.  It is is initialized by
** SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest().
*/
CERTDistNames *ssl3_server_ca_list = NULL;
static SSL3Statistics ssl3stats;

/* indexed by SSL3BulkCipher */
static const ssl3BulkCipherDef bulk_cipher_defs[] = {
    /*                                       |--------- Lengths --------| */
    /* cipher             calg               k  s  type         i  b  t  n */
    /*                                       e  e               v  l  a  o */
    /*                                       y  c               |  o  g  n */
    /*                                       |  r               |  c  |  c */
    /*                                       |  e               |  k  |  e */
    /*                                       |  t               |  |  |  | */
    {cipher_null,         calg_null,         0, 0, type_stream, 0, 0, 0, 0},
    {cipher_rc4,          calg_rc4,         16,16, type_stream, 0, 0, 0, 0},
    {cipher_rc4_40,       calg_rc4,         16, 5, type_stream, 0, 0, 0, 0},
    {cipher_rc4_56,       calg_rc4,         16, 7, type_stream, 0, 0, 0, 0},
    {cipher_rc2,          calg_rc2,         16,16, type_block,  8, 8, 0, 0},
    {cipher_rc2_40,       calg_rc2,         16, 5, type_block,  8, 8, 0, 0},
    {cipher_des,          calg_des,          8, 8, type_block,  8, 8, 0, 0},
    {cipher_3des,         calg_3des,        24,24, type_block,  8, 8, 0, 0},
    {cipher_des40,        calg_des,          8, 5, type_block,  8, 8, 0, 0},
    {cipher_idea,         calg_idea,        16,16, type_block,  8, 8, 0, 0},
    {cipher_aes_128,      calg_aes,         16,16, type_block, 16,16, 0, 0},
    {cipher_aes_256,      calg_aes,         32,32, type_block, 16,16, 0, 0},
    {cipher_camellia_128, calg_camellia,    16,16, type_block, 16,16, 0, 0},
    {cipher_camellia_256, calg_camellia,    32,32, type_block, 16,16, 0, 0},
    {cipher_seed,         calg_seed,        16,16, type_block, 16,16, 0, 0},
    {cipher_aes_128_gcm,  calg_aes_gcm,     16,16, type_aead,   4, 0,16, 8},
    {cipher_chacha20,     calg_chacha20,    32,32, type_aead,   0, 0,16, 0},
    {cipher_missing,      calg_null,         0, 0, type_stream, 0, 0, 0, 0},
};

static const ssl3KEADef kea_defs[] = 
{ /* indexed by SSL3KeyExchangeAlgorithm */
    /* kea              exchKeyType signKeyType is_limited limit  tls_keygen */
    {kea_null,           kt_null,     sign_null, PR_FALSE,   0, PR_FALSE},
    {kea_rsa,            kt_rsa,      sign_rsa,  PR_FALSE,   0, PR_FALSE},
    {kea_rsa_export,     kt_rsa,      sign_rsa,  PR_TRUE,  512, PR_FALSE},
    {kea_rsa_export_1024,kt_rsa,      sign_rsa,  PR_TRUE, 1024, PR_FALSE},
    {kea_dh_dss,         kt_dh,       sign_dsa,  PR_FALSE,   0, PR_FALSE},
    {kea_dh_dss_export,  kt_dh,       sign_dsa,  PR_TRUE,  512, PR_FALSE},
    {kea_dh_rsa,         kt_dh,       sign_rsa,  PR_FALSE,   0, PR_FALSE},
    {kea_dh_rsa_export,  kt_dh,       sign_rsa,  PR_TRUE,  512, PR_FALSE},
    {kea_dhe_dss,        kt_dh,       sign_dsa,  PR_FALSE,   0, PR_FALSE},
    {kea_dhe_dss_export, kt_dh,       sign_dsa,  PR_TRUE,  512, PR_FALSE},
    {kea_dhe_rsa,        kt_dh,       sign_rsa,  PR_FALSE,   0, PR_FALSE},
    {kea_dhe_rsa_export, kt_dh,       sign_rsa,  PR_TRUE,  512, PR_FALSE},
    {kea_dh_anon,        kt_dh,       sign_null, PR_FALSE,   0, PR_FALSE},
    {kea_dh_anon_export, kt_dh,       sign_null, PR_TRUE,  512, PR_FALSE},
    {kea_rsa_fips,       kt_rsa,      sign_rsa,  PR_FALSE,   0, PR_TRUE },
#ifdef NSS_ENABLE_ECC
    {kea_ecdh_ecdsa,     kt_ecdh,     sign_ecdsa,  PR_FALSE, 0, PR_FALSE},
    {kea_ecdhe_ecdsa,    kt_ecdh,     sign_ecdsa,  PR_FALSE,   0, PR_FALSE},
    {kea_ecdh_rsa,       kt_ecdh,     sign_rsa,  PR_FALSE,   0, PR_FALSE},
    {kea_ecdhe_rsa,      kt_ecdh,     sign_rsa,  PR_FALSE,   0, PR_FALSE},
    {kea_ecdh_anon,      kt_ecdh,     sign_null,  PR_FALSE,   0, PR_FALSE},
#endif /* NSS_ENABLE_ECC */
};

/* must use ssl_LookupCipherSuiteDef to access */
static const ssl3CipherSuiteDef cipher_suite_defs[] = 
{
/*  cipher_suite                    bulk_cipher_alg mac_alg key_exchange_alg */

    {SSL_NULL_WITH_NULL_NULL,       cipher_null,   mac_null, kea_null},
    {SSL_RSA_WITH_NULL_MD5,         cipher_null,   mac_md5, kea_rsa},
    {SSL_RSA_WITH_NULL_SHA,         cipher_null,   mac_sha, kea_rsa},
    {TLS_RSA_WITH_NULL_SHA256,      cipher_null,   hmac_sha256, kea_rsa},
    {SSL_RSA_EXPORT_WITH_RC4_40_MD5,cipher_rc4_40, mac_md5, kea_rsa_export},
    {SSL_RSA_WITH_RC4_128_MD5,      cipher_rc4,    mac_md5, kea_rsa},
    {SSL_RSA_WITH_RC4_128_SHA,      cipher_rc4,    mac_sha, kea_rsa},
    {SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
                                    cipher_rc2_40, mac_md5, kea_rsa_export},
#if 0 /* not implemented */
    {SSL_RSA_WITH_IDEA_CBC_SHA,     cipher_idea,   mac_sha, kea_rsa},
    {SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
                                    cipher_des40,  mac_sha, kea_rsa_export},
#endif
    {SSL_RSA_WITH_DES_CBC_SHA,      cipher_des,    mac_sha, kea_rsa},
    {SSL_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des,   mac_sha, kea_rsa},
    {SSL_DHE_DSS_WITH_DES_CBC_SHA,  cipher_des,    mac_sha, kea_dhe_dss},
    {SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
                                    cipher_3des,   mac_sha, kea_dhe_dss},
    {TLS_DHE_DSS_WITH_RC4_128_SHA,  cipher_rc4,    mac_sha, kea_dhe_dss},
#if 0 /* not implemented */
    {SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
                                    cipher_des40,  mac_sha, kea_dh_dss_export},
    {SSL_DH_DSS_DES_CBC_SHA,        cipher_des,    mac_sha, kea_dh_dss},
    {SSL_DH_DSS_3DES_CBC_SHA,       cipher_3des,   mac_sha, kea_dh_dss},
    {SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
                                    cipher_des40,  mac_sha, kea_dh_rsa_export},
    {SSL_DH_RSA_DES_CBC_SHA,        cipher_des,    mac_sha, kea_dh_rsa},
    {SSL_DH_RSA_3DES_CBC_SHA,       cipher_3des,   mac_sha, kea_dh_rsa},
    {SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
                                    cipher_des40,  mac_sha, kea_dh_dss_export},
    {SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
                                    cipher_des40,  mac_sha, kea_dh_rsa_export},
#endif
    {SSL_DHE_RSA_WITH_DES_CBC_SHA,  cipher_des,    mac_sha, kea_dhe_rsa},
    {SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
                                    cipher_3des,   mac_sha, kea_dhe_rsa},
#if 0
    {SSL_DH_ANON_EXPORT_RC4_40_MD5, cipher_rc4_40, mac_md5, kea_dh_anon_export},
    {SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA,
                                    cipher_des40,  mac_sha, kea_dh_anon_export},
    {SSL_DH_ANON_DES_CBC_SHA,       cipher_des,    mac_sha, kea_dh_anon},
    {SSL_DH_ANON_3DES_CBC_SHA,      cipher_3des,   mac_sha, kea_dh_anon},
#endif


/* New TLS cipher suites */
    {TLS_RSA_WITH_AES_128_CBC_SHA,     	cipher_aes_128, mac_sha, kea_rsa},
    {TLS_RSA_WITH_AES_128_CBC_SHA256,	cipher_aes_128, hmac_sha256, kea_rsa},
    {TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 	cipher_aes_128, mac_sha, kea_dhe_dss},
    {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 	cipher_aes_128, mac_sha, kea_dhe_rsa},
    {TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_rsa},
    {TLS_RSA_WITH_AES_256_CBC_SHA,     	cipher_aes_256, mac_sha, kea_rsa},
    {TLS_RSA_WITH_AES_256_CBC_SHA256,	cipher_aes_256, hmac_sha256, kea_rsa},
    {TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 	cipher_aes_256, mac_sha, kea_dhe_dss},
    {TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 	cipher_aes_256, mac_sha, kea_dhe_rsa},
    {TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_dhe_rsa},
#if 0
    {TLS_DH_DSS_WITH_AES_128_CBC_SHA,  	cipher_aes_128, mac_sha, kea_dh_dss},
    {TLS_DH_RSA_WITH_AES_128_CBC_SHA,  	cipher_aes_128, mac_sha, kea_dh_rsa},
    {TLS_DH_ANON_WITH_AES_128_CBC_SHA, 	cipher_aes_128, mac_sha, kea_dh_anon},
    {TLS_DH_DSS_WITH_AES_256_CBC_SHA,  	cipher_aes_256, mac_sha, kea_dh_dss},
    {TLS_DH_RSA_WITH_AES_256_CBC_SHA,  	cipher_aes_256, mac_sha, kea_dh_rsa},
    {TLS_DH_ANON_WITH_AES_256_CBC_SHA, 	cipher_aes_256, mac_sha, kea_dh_anon},
#endif

    {TLS_RSA_WITH_SEED_CBC_SHA,	    cipher_seed,   mac_sha, kea_rsa},

    {TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, cipher_camellia_128, mac_sha, kea_rsa},
    {TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
     cipher_camellia_128, mac_sha, kea_dhe_dss},
    {TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
     cipher_camellia_128, mac_sha, kea_dhe_rsa},
    {TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,	cipher_camellia_256, mac_sha, kea_rsa},
    {TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
     cipher_camellia_256, mac_sha, kea_dhe_dss},
    {TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
     cipher_camellia_256, mac_sha, kea_dhe_rsa},

    {TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
                                    cipher_des,    mac_sha,kea_rsa_export_1024},
    {TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
                                    cipher_rc4_56, mac_sha,kea_rsa_export_1024},

    {SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa_fips},
    {SSL_RSA_FIPS_WITH_DES_CBC_SHA, cipher_des,    mac_sha, kea_rsa_fips},

    {TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_rsa},
    {TLS_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_rsa},
    {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_rsa},
    {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_ecdsa},
    {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, cipher_chacha20, mac_aead, kea_ecdhe_rsa},
    {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, cipher_chacha20, mac_aead, kea_ecdhe_ecdsa},

#ifdef NSS_ENABLE_ECC
    {TLS_ECDH_ECDSA_WITH_NULL_SHA,        cipher_null, mac_sha, kea_ecdh_ecdsa},
    {TLS_ECDH_ECDSA_WITH_RC4_128_SHA,      cipher_rc4, mac_sha, kea_ecdh_ecdsa},
    {TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_ecdsa},
    {TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_ecdsa},
    {TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_ecdsa},

    {TLS_ECDHE_ECDSA_WITH_NULL_SHA,        cipher_null, mac_sha, kea_ecdhe_ecdsa},
    {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,      cipher_rc4, mac_sha, kea_ecdhe_ecdsa},
    {TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_ecdsa},
    {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_ecdsa},
    {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_ecdhe_ecdsa},
    {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_ecdsa},

    {TLS_ECDH_RSA_WITH_NULL_SHA,         cipher_null,    mac_sha, kea_ecdh_rsa},
    {TLS_ECDH_RSA_WITH_RC4_128_SHA,      cipher_rc4,     mac_sha, kea_ecdh_rsa},
    {TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des,    mac_sha, kea_ecdh_rsa},
    {TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,  cipher_aes_128, mac_sha, kea_ecdh_rsa},
    {TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,  cipher_aes_256, mac_sha, kea_ecdh_rsa},

    {TLS_ECDHE_RSA_WITH_NULL_SHA,         cipher_null,    mac_sha, kea_ecdhe_rsa},
    {TLS_ECDHE_RSA_WITH_RC4_128_SHA,      cipher_rc4,     mac_sha, kea_ecdhe_rsa},
    {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des,    mac_sha, kea_ecdhe_rsa},
    {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,  cipher_aes_128, mac_sha, kea_ecdhe_rsa},
    {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_ecdhe_rsa},
    {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,  cipher_aes_256, mac_sha, kea_ecdhe_rsa},

#if 0
    {TLS_ECDH_anon_WITH_NULL_SHA,         cipher_null,    mac_sha, kea_ecdh_anon},
    {TLS_ECDH_anon_WITH_RC4_128_SHA,      cipher_rc4,     mac_sha, kea_ecdh_anon},
    {TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, cipher_3des,    mac_sha, kea_ecdh_anon},
    {TLS_ECDH_anon_WITH_AES_128_CBC_SHA,  cipher_aes_128, mac_sha, kea_ecdh_anon},
    {TLS_ECDH_anon_WITH_AES_256_CBC_SHA,  cipher_aes_256, mac_sha, kea_ecdh_anon},
#endif
#endif /* NSS_ENABLE_ECC */
};

static const CK_MECHANISM_TYPE kea_alg_defs[] = {
    0x80000000L,
    CKM_RSA_PKCS,
    CKM_DH_PKCS_DERIVE,
    CKM_KEA_KEY_DERIVE,
    CKM_ECDH1_DERIVE
};

typedef struct SSLCipher2MechStr {
    SSLCipherAlgorithm  calg;
    CK_MECHANISM_TYPE   cmech;
} SSLCipher2Mech;

/* indexed by type SSLCipherAlgorithm */
static const SSLCipher2Mech alg2Mech[] = {
    /* calg,          cmech  */
    { calg_null     , (CK_MECHANISM_TYPE)0x80000000L	},
    { calg_rc4      , CKM_RC4				},
    { calg_rc2      , CKM_RC2_CBC			},
    { calg_des      , CKM_DES_CBC			},
    { calg_3des     , CKM_DES3_CBC			},
    { calg_idea     , CKM_IDEA_CBC			},
    { calg_fortezza , CKM_SKIPJACK_CBC64                },
    { calg_aes      , CKM_AES_CBC			},
    { calg_camellia , CKM_CAMELLIA_CBC			},
    { calg_seed     , CKM_SEED_CBC			},
    { calg_aes_gcm  , CKM_AES_GCM			},
    { calg_chacha20 , CKM_NSS_CHACHA20_POLY1305		},
/*  { calg_init     , (CK_MECHANISM_TYPE)0x7fffffffL    }  */
};

#define mmech_invalid  (CK_MECHANISM_TYPE)0x80000000L
#define mmech_md5      CKM_SSL3_MD5_MAC
#define mmech_sha      CKM_SSL3_SHA1_MAC
#define mmech_md5_hmac CKM_MD5_HMAC
#define mmech_sha_hmac CKM_SHA_1_HMAC
#define mmech_sha256_hmac CKM_SHA256_HMAC

static const ssl3MACDef mac_defs[] = { /* indexed by SSL3MACAlgorithm */
    /* pad_size is only used for SSL 3.0 MAC. See RFC 6101 Sec. 5.2.3.1. */
    /* mac      mmech       pad_size  mac_size                       */
    { mac_null, mmech_invalid,    0,  0          },
    { mac_md5,  mmech_md5,       48,  MD5_LENGTH },
    { mac_sha,  mmech_sha,       40,  SHA1_LENGTH},
    {hmac_md5,  mmech_md5_hmac,   0,  MD5_LENGTH },
    {hmac_sha,  mmech_sha_hmac,   0,  SHA1_LENGTH},
    {hmac_sha256, mmech_sha256_hmac, 0, SHA256_LENGTH},
    { mac_aead, mmech_invalid,    0,  0          },
};

/* indexed by SSL3BulkCipher */
const char * const ssl3_cipherName[] = {
    "NULL",
    "RC4",
    "RC4-40",
    "RC4-56",
    "RC2-CBC",
    "RC2-CBC-40",
    "DES-CBC",
    "3DES-EDE-CBC",
    "DES-CBC-40",
    "IDEA-CBC",
    "AES-128",
    "AES-256",
    "Camellia-128",
    "Camellia-256",
    "SEED-CBC",
    "AES-128-GCM",
    "missing"
};

#ifdef NSS_ENABLE_ECC
/* The ECCWrappedKeyInfo structure defines how various pieces of 
 * information are laid out within wrappedSymmetricWrappingkey 
 * for ECDH key exchange. Since wrappedSymmetricWrappingkey is 
 * a 512-byte buffer (see sslimpl.h), the variable length field 
 * in ECCWrappedKeyInfo can be at most (512 - 8) = 504 bytes.
 *
 * XXX For now, NSS only supports named elliptic curves of size 571 bits 
 * or smaller. The public value will fit within 145 bytes and EC params
 * will fit within 12 bytes. We'll need to revisit this when NSS
 * supports arbitrary curves.
 */
#define MAX_EC_WRAPPED_KEY_BUFLEN  504

typedef struct ECCWrappedKeyInfoStr {
    PRUint16 size;            /* EC public key size in bits */
    PRUint16 encodedParamLen; /* length (in bytes) of DER encoded EC params */
    PRUint16 pubValueLen;     /* length (in bytes) of EC public value */
    PRUint16 wrappedKeyLen;   /* length (in bytes) of the wrapped key */
    PRUint8 var[MAX_EC_WRAPPED_KEY_BUFLEN]; /* this buffer contains the */
    /* EC public-key params, the EC public value and the wrapped key  */
} ECCWrappedKeyInfo;
#endif /* NSS_ENABLE_ECC */

#if defined(TRACE)

static char *
ssl3_DecodeHandshakeType(int msgType)
{
    char * rv;
    static char line[40];

    switch(msgType) {
    case hello_request:	        rv = "hello_request (0)";               break;
    case client_hello:	        rv = "client_hello  (1)";               break;
    case server_hello:	        rv = "server_hello  (2)";               break;
    case hello_verify_request:  rv = "hello_verify_request (3)";        break;
    case certificate:	        rv = "certificate  (11)";               break;
    case server_key_exchange:	rv = "server_key_exchange (12)";        break;
    case certificate_request:	rv = "certificate_request (13)";        break;
    case server_hello_done:	rv = "server_hello_done   (14)";        break;
    case certificate_verify:	rv = "certificate_verify  (15)";        break;
    case client_key_exchange:	rv = "client_key_exchange (16)";        break;
    case finished:	        rv = "finished     (20)";               break;
    default:
        sprintf(line, "*UNKNOWN* handshake type! (%d)", msgType);
	rv = line;
    }
    return rv;
}

static char *
ssl3_DecodeContentType(int msgType)
{
    char * rv;
    static char line[40];

    switch(msgType) {
    case content_change_cipher_spec:
                                rv = "change_cipher_spec (20)";         break;
    case content_alert:	        rv = "alert      (21)";                 break;
    case content_handshake:	rv = "handshake  (22)";                 break;
    case content_application_data:
                                rv = "application_data (23)";           break;
    default:
        sprintf(line, "*UNKNOWN* record type! (%d)", msgType);
	rv = line;
    }
    return rv;
}

#endif

SSL3Statistics * 
SSL_GetStatistics(void)
{
    return &ssl3stats;
}

typedef struct tooLongStr {
#if defined(IS_LITTLE_ENDIAN)
    PRInt32 low;
    PRInt32 high;
#else
    PRInt32 high;
    PRInt32 low;
#endif
} tooLong;

void SSL_AtomicIncrementLong(long * x)
{
    if ((sizeof *x) == sizeof(PRInt32)) {
        PR_ATOMIC_INCREMENT((PRInt32 *)x);
    } else {
    	tooLong * tl = (tooLong *)x;
	if (PR_ATOMIC_INCREMENT(&tl->low) == 0)
	    PR_ATOMIC_INCREMENT(&tl->high);
    }
}

static PRBool
ssl3_CipherSuiteAllowedForVersionRange(
    ssl3CipherSuite cipherSuite,
    const SSLVersionRange *vrange)
{
    switch (cipherSuite) {
    /* See RFC 4346 A.5. Export cipher suites must not be used in TLS 1.1 or
     * later. This set of cipher suites is similar to, but different from, the
     * set of cipher suites considered exportable by SSL_IsExportCipherSuite.
     */
    case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
    case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
    /*   SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:      never implemented
     *   SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:   never implemented
     *   SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:   never implemented
     *   SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:  never implemented
     *   SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:  never implemented
     *   SSL_DH_ANON_EXPORT_WITH_RC4_40_MD5:     never implemented
     *   SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA:  never implemented
     */
	return vrange->min <= SSL_LIBRARY_VERSION_TLS_1_0;
    case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305:
    case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:
    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
    case TLS_RSA_WITH_AES_256_CBC_SHA256:
    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
    case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
    case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
    case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
    case TLS_RSA_WITH_AES_128_CBC_SHA256:
    case TLS_RSA_WITH_AES_128_GCM_SHA256:
    case TLS_RSA_WITH_NULL_SHA256:
	return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_2;
    default:
	return PR_TRUE;
    }
}

/* return pointer to ssl3CipherSuiteDef for suite, or NULL */
/* XXX This does a linear search.  A binary search would be better. */
static const ssl3CipherSuiteDef *
ssl_LookupCipherSuiteDef(ssl3CipherSuite suite)
{
    int cipher_suite_def_len =
	sizeof(cipher_suite_defs) / sizeof(cipher_suite_defs[0]);
    int i;

    for (i = 0; i < cipher_suite_def_len; i++) {
	if (cipher_suite_defs[i].cipher_suite == suite)
	    return &cipher_suite_defs[i];
    }
    PORT_Assert(PR_FALSE);  /* We should never get here. */
    PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
    return NULL;
}

/* Find the cipher configuration struct associate with suite */
/* XXX This does a linear search.  A binary search would be better. */
static ssl3CipherSuiteCfg *
ssl_LookupCipherSuiteCfg(ssl3CipherSuite suite, ssl3CipherSuiteCfg *suites)
{
    int i;

    for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
	if (suites[i].cipher_suite == suite)
	    return &suites[i];
    }
    /* return NULL and let the caller handle it.  */
    PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
    return NULL;
}


/* Initialize the suite->isPresent value for config_match
 * Returns count of enabled ciphers supported by extant tokens,
 * regardless of policy or user preference.
 * If this returns zero, the user cannot do SSL v3.
 */
int
ssl3_config_match_init(sslSocket *ss)
{
    ssl3CipherSuiteCfg *      suite;
    const ssl3CipherSuiteDef *cipher_def;
    SSLCipherAlgorithm        cipher_alg;
    CK_MECHANISM_TYPE         cipher_mech;
    SSL3KEAType               exchKeyType;
    int                       i;
    int                       numPresent		= 0;
    int                       numEnabled		= 0;
    PRBool                    isServer;
    sslServerCerts           *svrAuth;

    PORT_Assert(ss);
    if (!ss) {
    	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return 0;
    }
    if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
    	return 0;
    }
    isServer = (PRBool)(ss->sec.isServer != 0);

    for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
	suite = &ss->cipherSuites[i];
	if (suite->enabled) {
	    ++numEnabled;
	    /* We need the cipher defs to see if we have a token that can handle
	     * this cipher.  It isn't part of the static definition.
	     */
	    cipher_def = ssl_LookupCipherSuiteDef(suite->cipher_suite);
	    if (!cipher_def) {
	    	suite->isPresent = PR_FALSE;
		continue;
	    }
	    cipher_alg = bulk_cipher_defs[cipher_def->bulk_cipher_alg].calg;
	    PORT_Assert(  alg2Mech[cipher_alg].calg == cipher_alg);
	    cipher_mech = alg2Mech[cipher_alg].cmech;
	    exchKeyType =
	    	    kea_defs[cipher_def->key_exchange_alg].exchKeyType;
#ifndef NSS_ENABLE_ECC
	    svrAuth = ss->serverCerts + exchKeyType;
#else
	    /* XXX SSLKEAType isn't really a good choice for 
	     * indexing certificates. It doesn't work for
	     * (EC)DHE-* ciphers. Here we use a hack to ensure
	     * that the server uses an RSA cert for (EC)DHE-RSA.
	     */
	    switch (cipher_def->key_exchange_alg) {
	    case kea_ecdhe_rsa:
#if NSS_SERVER_DHE_IMPLEMENTED
	    /* XXX NSS does not yet implement the server side of _DHE_
	     * cipher suites.  Correcting the computation for svrAuth,
	     * as the case below does, causes NSS SSL servers to begin to
	     * negotiate cipher suites they do not implement.  So, until
	     * server side _DHE_ is implemented, keep this disabled.
	     */
	    case kea_dhe_rsa:
#endif
		svrAuth = ss->serverCerts + kt_rsa;
		break;
	    case kea_ecdh_ecdsa:
	    case kea_ecdh_rsa:
	        /* 
		 * XXX We ought to have different indices for 
		 * ECDSA- and RSA-signed EC certificates so
		 * we could support both key exchange mechanisms
		 * simultaneously. For now, both of them use
		 * whatever is in the certificate slot for kt_ecdh
		 */
	    default:
		svrAuth = ss->serverCerts + exchKeyType;
		break;
	    }
#endif /* NSS_ENABLE_ECC */

	    /* Mark the suites that are backed by real tokens, certs and keys */
	    suite->isPresent = (PRBool)
		(((exchKeyType == kt_null) ||
		   ((!isServer || (svrAuth->serverKeyPair &&
		                   svrAuth->SERVERKEY &&
				   svrAuth->serverCertChain)) &&
		    PK11_TokenExists(kea_alg_defs[exchKeyType]))) &&
		((cipher_alg == calg_null) || PK11_TokenExists(cipher_mech)));
	    if (suite->isPresent)
	    	++numPresent;
	}
    }
    PORT_Assert(numPresent > 0 || numEnabled == 0);
    if (numPresent <= 0) {
	PORT_SetError(SSL_ERROR_NO_CIPHERS_SUPPORTED);
    }
    return numPresent;
}


/* return PR_TRUE if suite matches policy, enabled state and is applicable to
 * the given version range. */
/* It would be a REALLY BAD THING (tm) if we ever permitted the use
** of a cipher that was NOT_ALLOWED.  So, if this is ever called with
** policy == SSL_NOT_ALLOWED, report no match.
*/
/* adjust suite enabled to the availability of a token that can do the
 * cipher suite. */
static PRBool
config_match(ssl3CipherSuiteCfg *suite, int policy, PRBool enabled,
	     const SSLVersionRange *vrange)
{
    PORT_Assert(policy != SSL_NOT_ALLOWED && enabled != PR_FALSE);
    if (policy == SSL_NOT_ALLOWED || !enabled)
    	return PR_FALSE;
    return (PRBool)(suite->enabled &&
                    suite->isPresent &&
	            suite->policy != SSL_NOT_ALLOWED &&
		    suite->policy <= policy &&
		    ssl3_CipherSuiteAllowedForVersionRange(
                        suite->cipher_suite, vrange));
}

/* return number of cipher suites that match policy, enabled state and are
 * applicable for the configured protocol version range. */
/* called from ssl3_SendClientHello and ssl3_ConstructV2CipherSpecsHack */
static int
count_cipher_suites(sslSocket *ss, int policy, PRBool enabled)
{
    int i, count = 0;

    if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
	return 0;
    }
    for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
	if (config_match(&ss->cipherSuites[i], policy, enabled, &ss->vrange))
	    count++;
    }
    if (count <= 0) {
	PORT_SetError(SSL_ERROR_SSL_DISABLED);
    }
    return count;
}

/*
 * Null compression, mac and encryption functions
 */

static SECStatus
Null_Cipher(void *ctx, unsigned char *output, int *outputLen, int maxOutputLen,
	    const unsigned char *input, int inputLen)
{
    if (inputLen > maxOutputLen) {
        *outputLen = 0;  /* Match PK11_CipherOp in setting outputLen */
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
        return SECFailure;
    }
    *outputLen = inputLen;
    if (input != output)
	PORT_Memcpy(output, input, inputLen);
    return SECSuccess;
}

/*
 * SSL3 Utility functions
 */

/* allowLargerPeerVersion controls whether the function will select the
 * highest enabled SSL version or fail when peerVersion is greater than the
 * highest enabled version.
 *
 * If allowLargerPeerVersion is true, peerVersion is the peer's highest
 * enabled version rather than the peer's selected version.
 */
SECStatus
ssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion,
		      PRBool allowLargerPeerVersion)
{
    if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
	PORT_SetError(SSL_ERROR_SSL_DISABLED);
	return SECFailure;
    }

    if (peerVersion < ss->vrange.min ||
	(peerVersion > ss->vrange.max && !allowLargerPeerVersion)) {
	PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
	return SECFailure;
    }

    ss->version = PR_MIN(peerVersion, ss->vrange.max);
    PORT_Assert(ssl3_VersionIsSupported(ss->protocolVariant, ss->version));

    return SECSuccess;
}

static SECStatus
ssl3_GetNewRandom(SSL3Random *random)
{
    SECStatus rv;

    /* first 4 bytes are reserverd for time */
    rv = PK11_GenerateRandom(random->rand, SSL3_RANDOM_LENGTH);
    if (rv != SECSuccess) {
	ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
    }
    return rv;
}

/* Called by ssl3_SendServerKeyExchange and ssl3_SendCertificateVerify */
SECStatus
ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf, 
                PRBool isTLS)
{
    SECStatus rv		= SECFailure;
    PRBool    doDerEncode       = PR_FALSE;
    int       signatureLen;
    SECItem   hashItem;

    buf->data    = NULL;

    switch (key->keyType) {
    case rsaKey:
	hashItem.data = hash->u.raw;
	hashItem.len = hash->len;
	break;
    case dsaKey:
	doDerEncode = isTLS;
	/* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash.
	 * In that case, we use just the SHA1 part. */
	if (hash->hashAlg == SEC_OID_UNKNOWN) {
	    hashItem.data = hash->u.s.sha;
	    hashItem.len = sizeof(hash->u.s.sha);
	} else {
	    hashItem.data = hash->u.raw;
	    hashItem.len = hash->len;
	}
	break;
#ifdef NSS_ENABLE_ECC
    case ecKey:
	doDerEncode = PR_TRUE;
	/* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash.
	 * In that case, we use just the SHA1 part. */
	if (hash->hashAlg == SEC_OID_UNKNOWN) {
	    hashItem.data = hash->u.s.sha;
	    hashItem.len = sizeof(hash->u.s.sha);
	} else {
	    hashItem.data = hash->u.raw;
	    hashItem.len = hash->len;
	}
	break;
#endif /* NSS_ENABLE_ECC */
    default:
	PORT_SetError(SEC_ERROR_INVALID_KEY);
	goto done;
    }
    PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len));

    if (hash->hashAlg == SEC_OID_UNKNOWN) {
	signatureLen = PK11_SignatureLen(key);
	if (signatureLen <= 0) {
	    PORT_SetError(SEC_ERROR_INVALID_KEY);
	    goto done;
	}

	buf->len  = (unsigned)signatureLen;
	buf->data = (unsigned char *)PORT_Alloc(signatureLen);
	if (!buf->data)
	    goto done;  /* error code was set. */

	rv = PK11_Sign(key, buf, &hashItem);
    } else {
	rv = SGN_Digest(key, hash->hashAlg, buf, &hashItem);
    }
    if (rv != SECSuccess) {
	ssl_MapLowLevelError(SSL_ERROR_SIGN_HASHES_FAILURE);
    } else if (doDerEncode) {
	SECItem   derSig	= {siBuffer, NULL, 0};

	/* This also works for an ECDSA signature */
	rv = DSAU_EncodeDerSigWithLen(&derSig, buf, buf->len);
	if (rv == SECSuccess) {
	    PORT_Free(buf->data);	/* discard unencoded signature. */
	    *buf = derSig;		/* give caller encoded signature. */
	} else if (derSig.data) {
	    PORT_Free(derSig.data);
	}
    }

    PRINT_BUF(60, (NULL, "signed hashes", (unsigned char*)buf->data, buf->len));
done:
    if (rv != SECSuccess && buf->data) {
	PORT_Free(buf->data);
	buf->data = NULL;
    }
    return rv;
}

/* Called from ssl3_HandleServerKeyExchange, ssl3_HandleCertificateVerify */
SECStatus
ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert, 
                        SECItem *buf, PRBool isTLS, void *pwArg)
{
    SECKEYPublicKey * key;
    SECItem *         signature	= NULL;
    SECStatus         rv;
    SECItem           hashItem;
    SECOidTag         encAlg;
    SECOidTag         hashAlg;


    PRINT_BUF(60, (NULL, "check signed hashes",
                  buf->data, buf->len));

    key = CERT_ExtractPublicKey(cert);
    if (key == NULL) {
	ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
    	return SECFailure;
    }

    hashAlg = hash->hashAlg;
    switch (key->keyType) {
    case rsaKey:
	encAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
	hashItem.data = hash->u.raw;
	hashItem.len = hash->len;
	break;
    case dsaKey:
	encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE;
	/* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash.
	 * In that case, we use just the SHA1 part. */
	if (hash->hashAlg == SEC_OID_UNKNOWN) {
	    hashItem.data = hash->u.s.sha;
	    hashItem.len = sizeof(hash->u.s.sha);
	} else {
	    hashItem.data = hash->u.raw;
	    hashItem.len = hash->len;
	}
	/* Allow DER encoded DSA signatures in SSL 3.0 */
	if (isTLS || buf->len != SECKEY_SignatureLen(key)) {
	    signature = DSAU_DecodeDerSigToLen(buf, SECKEY_SignatureLen(key));
	    if (!signature) {
	    	PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
		return SECFailure;
	    }
	    buf = signature;
	}
	break;

#ifdef NSS_ENABLE_ECC
    case ecKey:
	encAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
	/* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash.
	 * In that case, we use just the SHA1 part.
	 * ECDSA signatures always encode the integers r and s using ASN.1
	 * (unlike DSA where ASN.1 encoding is used with TLS but not with
	 * SSL3). So we can use VFY_VerifyDigestDirect for ECDSA.
	 */
	if (hash->hashAlg == SEC_OID_UNKNOWN) {
	    hashAlg = SEC_OID_SHA1;
	    hashItem.data = hash->u.s.sha;
	    hashItem.len = sizeof(hash->u.s.sha);
	} else {
	    hashItem.data = hash->u.raw;
	    hashItem.len = hash->len;
	}
	break;
#endif /* NSS_ENABLE_ECC */

    default:
    	SECKEY_DestroyPublicKey(key);
	PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
	return SECFailure;
    }

    PRINT_BUF(60, (NULL, "hash(es) to be verified",
                  hashItem.data, hashItem.len));

    if (hashAlg == SEC_OID_UNKNOWN || key->keyType == dsaKey) {
	/* VFY_VerifyDigestDirect requires DSA signatures to be DER-encoded.
	 * DSA signatures are DER-encoded in TLS but not in SSL3 and the code
	 * above always removes the DER encoding of DSA signatures when
	 * present. Thus DSA signatures are always verified with PK11_Verify.
	 */
	rv = PK11_Verify(key, buf, &hashItem, pwArg);
    } else {
	rv = VFY_VerifyDigestDirect(&hashItem, key, buf, encAlg, hashAlg,
				    pwArg);
    }
    SECKEY_DestroyPublicKey(key);
    if (signature) {
    	SECITEM_FreeItem(signature, PR_TRUE);
    }
    if (rv != SECSuccess) {
	ssl_MapLowLevelError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
    }
    return rv;
}


/* Caller must set hiLevel error code. */
/* Called from ssl3_ComputeExportRSAKeyHash
 *             ssl3_ComputeDHKeyHash
 * which are called from ssl3_HandleServerKeyExchange. 
 *
 * hashAlg: either the OID for a hash algorithm or SEC_OID_UNKNOWN to specify
 * the pre-1.2, MD5/SHA1 combination hash.
 */
SECStatus
ssl3_ComputeCommonKeyHash(SECOidTag hashAlg,
			  PRUint8 * hashBuf, unsigned int bufLen,
			  SSL3Hashes *hashes, PRBool bypassPKCS11)
{
    SECStatus     rv 		= SECSuccess;

#ifndef NO_PKCS11_BYPASS
    if (bypassPKCS11) {
	if (hashAlg == SEC_OID_UNKNOWN) {
	    MD5_HashBuf (hashes->u.s.md5, hashBuf, bufLen);
	    SHA1_HashBuf(hashes->u.s.sha, hashBuf, bufLen);
	    hashes->len = MD5_LENGTH + SHA1_LENGTH;
	} else if (hashAlg == SEC_OID_SHA1) {
	    SHA1_HashBuf(hashes->u.raw, hashBuf, bufLen);
	    hashes->len = SHA1_LENGTH;
	} else if (hashAlg == SEC_OID_SHA256) {
	    SHA256_HashBuf(hashes->u.raw, hashBuf, bufLen);
	    hashes->len = SHA256_LENGTH;
	} else if (hashAlg == SEC_OID_SHA384) {
	    SHA384_HashBuf(hashes->u.raw, hashBuf, bufLen);
	    hashes->len = SHA384_LENGTH;
	} else if (hashAlg == SEC_OID_SHA512) {
	    SHA512_HashBuf(hashes->u.raw, hashBuf, bufLen);
	    hashes->len = SHA512_LENGTH;
	} else {
	    PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
	    return SECFailure;
	}
    } else 
#endif
    {
	if (hashAlg == SEC_OID_UNKNOWN) {
	    rv = PK11_HashBuf(SEC_OID_MD5, hashes->u.s.md5, hashBuf, bufLen);
	    if (rv != SECSuccess) {
		ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
		rv = SECFailure;
		goto done;
	    }

	    rv = PK11_HashBuf(SEC_OID_SHA1, hashes->u.s.sha, hashBuf, bufLen);
	    if (rv != SECSuccess) {
		ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
		rv = SECFailure;
	    }
	    hashes->len = MD5_LENGTH + SHA1_LENGTH;
	} else {
	    hashes->len = HASH_ResultLenByOidTag(hashAlg);
	    if (hashes->len > sizeof(hashes->u.raw)) {
		ssl_MapLowLevelError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
		rv = SECFailure;
		goto done;
	    }
	    rv = PK11_HashBuf(hashAlg, hashes->u.raw, hashBuf, bufLen);
	    if (rv != SECSuccess) {
		ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
		rv = SECFailure;
	    }
	}
    }
    hashes->hashAlg = hashAlg;

done:
    return rv;
}

/* Caller must set hiLevel error code. 
** Called from ssl3_SendServerKeyExchange and 
**             ssl3_HandleServerKeyExchange.
*/
static SECStatus
ssl3_ComputeExportRSAKeyHash(SECOidTag hashAlg,
			     SECItem modulus, SECItem publicExponent,
			     SSL3Random *client_rand, SSL3Random *server_rand,
			     SSL3Hashes *hashes, PRBool bypassPKCS11)
{
    PRUint8     * hashBuf;
    PRUint8     * pBuf;
    SECStatus     rv 		= SECSuccess;
    unsigned int  bufLen;
    PRUint8       buf[2*SSL3_RANDOM_LENGTH + 2 + 4096/8 + 2 + 4096/8];

    bufLen = 2*SSL3_RANDOM_LENGTH + 2 + modulus.len + 2 + publicExponent.len;
    if (bufLen <= sizeof buf) {
    	hashBuf = buf;
    } else {
    	hashBuf = PORT_Alloc(bufLen);
	if (!hashBuf) {
	    return SECFailure;
	}
    }

    memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH); 
    	pBuf = hashBuf + SSL3_RANDOM_LENGTH;
    memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
    	pBuf += SSL3_RANDOM_LENGTH;
    pBuf[0]  = (PRUint8)(modulus.len >> 8);
    pBuf[1]  = (PRUint8)(modulus.len);
    	pBuf += 2;
    memcpy(pBuf, modulus.data, modulus.len);
    	pBuf += modulus.len;
    pBuf[0] = (PRUint8)(publicExponent.len >> 8);
    pBuf[1] = (PRUint8)(publicExponent.len);
    	pBuf += 2;
    memcpy(pBuf, publicExponent.data, publicExponent.len);
    	pBuf += publicExponent.len;
    PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);

    rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes,
				   bypassPKCS11);

    PRINT_BUF(95, (NULL, "RSAkey hash: ", hashBuf, bufLen));
    if (hashAlg == SEC_OID_UNKNOWN) {
	PRINT_BUF(95, (NULL, "RSAkey hash: MD5 result",
		  hashes->u.s.md5, MD5_LENGTH));
	PRINT_BUF(95, (NULL, "RSAkey hash: SHA1 result",
		  hashes->u.s.sha, SHA1_LENGTH));
    } else {
	PRINT_BUF(95, (NULL, "RSAkey hash: result",
		  hashes->u.raw, hashes->len));
    }

    if (hashBuf != buf && hashBuf != NULL)
    	PORT_Free(hashBuf);
    return rv;
}

/* Caller must set hiLevel error code. */
/* Called from ssl3_HandleServerKeyExchange. */
static SECStatus
ssl3_ComputeDHKeyHash(SECOidTag hashAlg,
		      SECItem dh_p, SECItem dh_g, SECItem dh_Ys,
		      SSL3Random *client_rand, SSL3Random *server_rand,
		      SSL3Hashes *hashes, PRBool bypassPKCS11)
{
    PRUint8     * hashBuf;
    PRUint8     * pBuf;
    SECStatus     rv 		= SECSuccess;
    unsigned int  bufLen;
    PRUint8       buf[2*SSL3_RANDOM_LENGTH + 2 + 4096/8 + 2 + 4096/8];

    bufLen = 2*SSL3_RANDOM_LENGTH + 2 + dh_p.len + 2 + dh_g.len + 2 + dh_Ys.len;
    if (bufLen <= sizeof buf) {
    	hashBuf = buf;
    } else {
    	hashBuf = PORT_Alloc(bufLen);
	if (!hashBuf) {
	    return SECFailure;
	}
    }

    memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH); 
    	pBuf = hashBuf + SSL3_RANDOM_LENGTH;
    memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
    	pBuf += SSL3_RANDOM_LENGTH;
    pBuf[0]  = (PRUint8)(dh_p.len >> 8);
    pBuf[1]  = (PRUint8)(dh_p.len);
    	pBuf += 2;
    memcpy(pBuf, dh_p.data, dh_p.len);
    	pBuf += dh_p.len;
    pBuf[0] = (PRUint8)(dh_g.len >> 8);
    pBuf[1] = (PRUint8)(dh_g.len);
    	pBuf += 2;
    memcpy(pBuf, dh_g.data, dh_g.len);
    	pBuf += dh_g.len;
    pBuf[0] = (PRUint8)(dh_Ys.len >> 8);
    pBuf[1] = (PRUint8)(dh_Ys.len);
    	pBuf += 2;
    memcpy(pBuf, dh_Ys.data, dh_Ys.len);
    	pBuf += dh_Ys.len;
    PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);

    rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes,
				   bypassPKCS11);

    PRINT_BUF(95, (NULL, "DHkey hash: ", hashBuf, bufLen));
    if (hashAlg == SEC_OID_UNKNOWN) {
	PRINT_BUF(95, (NULL, "DHkey hash: MD5 result",
		  hashes->u.s.md5, MD5_LENGTH));
	PRINT_BUF(95, (NULL, "DHkey hash: SHA1 result",
		  hashes->u.s.sha, SHA1_LENGTH));
    } else {
	PRINT_BUF(95, (NULL, "DHkey hash: result",
		  hashes->u.raw, hashes->len));
    }

    if (hashBuf != buf && hashBuf != NULL)
    	PORT_Free(hashBuf);
    return rv;
}

static void
ssl3_BumpSequenceNumber(SSL3SequenceNumber *num)
{
    num->low++;
    if (num->low == 0)
	num->high++;
}

/* Called twice, only from ssl3_DestroyCipherSpec (immediately below). */
static void
ssl3_CleanupKeyMaterial(ssl3KeyMaterial *mat)
{
    if (mat->write_key != NULL) {
	PK11_FreeSymKey(mat->write_key);
	mat->write_key = NULL;
    }
    if (mat->write_mac_key != NULL) {
	PK11_FreeSymKey(mat->write_mac_key);
	mat->write_mac_key = NULL;
    }
    if (mat->write_mac_context != NULL) {
	PK11_DestroyContext(mat->write_mac_context, PR_TRUE);
	mat->write_mac_context = NULL;
    }
}

/* Called from ssl3_SendChangeCipherSpecs() and 
**	       ssl3_HandleChangeCipherSpecs()
**             ssl3_DestroySSL3Info
** Caller must hold SpecWriteLock.
*/
void
ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName)
{
    PRBool freeit = (PRBool)(!spec->bypassCiphers);
/*  PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); Don't have ss! */
    if (spec->destroy) {
	spec->destroy(spec->encodeContext, freeit);
	spec->destroy(spec->decodeContext, freeit);
	spec->encodeContext = NULL; /* paranoia */
	spec->decodeContext = NULL;
    }
    if (spec->destroyCompressContext && spec->compressContext) {
	spec->destroyCompressContext(spec->compressContext, 1);
	spec->compressContext = NULL;
    }
    if (spec->destroyDecompressContext && spec->decompressContext) {
	spec->destroyDecompressContext(spec->decompressContext, 1);
	spec->decompressContext = NULL;
    }
    if (freeSrvName && spec->srvVirtName.data) {
        SECITEM_FreeItem(&spec->srvVirtName, PR_FALSE);
    }
    if (spec->master_secret != NULL) {
	PK11_FreeSymKey(spec->master_secret);
	spec->master_secret = NULL;
    }
    spec->msItem.data = NULL;
    spec->msItem.len  = 0;
    ssl3_CleanupKeyMaterial(&spec->client);
    ssl3_CleanupKeyMaterial(&spec->server);
    spec->bypassCiphers = PR_FALSE;
    spec->destroy=NULL;
    spec->destroyCompressContext = NULL;
    spec->destroyDecompressContext = NULL;
}

/* Fill in the pending cipher spec with info from the selected ciphersuite.
** This is as much initialization as we can do without having key material.
** Called from ssl3_HandleServerHello(), ssl3_SendServerHello()
** Caller must hold the ssl3 handshake lock.
** Acquires & releases SpecWriteLock.
*/
static SECStatus
ssl3_SetupPendingCipherSpec(sslSocket *ss)
{
    ssl3CipherSpec *          pwSpec;
    ssl3CipherSpec *          cwSpec;
    ssl3CipherSuite           suite     = ss->ssl3.hs.cipher_suite;
    SSL3MACAlgorithm          mac;
    SSL3BulkCipher            cipher;
    SSL3KeyExchangeAlgorithm  kea;
    const ssl3CipherSuiteDef *suite_def;
    PRBool                    isTLS;

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

    ssl_GetSpecWriteLock(ss);  /*******************************/

    pwSpec = ss->ssl3.pwSpec;
    PORT_Assert(pwSpec == ss->ssl3.prSpec);

    /* This hack provides maximal interoperability with SSL 3 servers. */
    cwSpec = ss->ssl3.cwSpec;
    if (cwSpec->mac_def->mac == mac_null) {
	/* SSL records are not being MACed. */
	cwSpec->version = ss->version;
    }

    pwSpec->version  = ss->version;
    isTLS  = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_0);

    SSL_TRC(3, ("%d: SSL3[%d]: Set XXX Pending Cipher Suite to 0x%04x",
		SSL_GETPID(), ss->fd, suite));

    suite_def = ssl_LookupCipherSuiteDef(suite);
    if (suite_def == NULL) {
	ssl_ReleaseSpecWriteLock(ss);
	return SECFailure;	/* error code set by ssl_LookupCipherSuiteDef */
    }

    if (IS_DTLS(ss)) {
	/* Double-check that we did not pick an RC4 suite */
	PORT_Assert((suite_def->bulk_cipher_alg != cipher_rc4) &&
		    (suite_def->bulk_cipher_alg != cipher_rc4_40) &&
		    (suite_def->bulk_cipher_alg != cipher_rc4_56));
    }

    cipher = suite_def->bulk_cipher_alg;
    kea    = suite_def->key_exchange_alg;
    mac    = suite_def->mac_alg;
    if (mac <= ssl_mac_sha && mac != ssl_mac_null && isTLS)
	mac += 2;

    ss->ssl3.hs.suite_def = suite_def;
    ss->ssl3.hs.kea_def   = &kea_defs[kea];
    PORT_Assert(ss->ssl3.hs.kea_def->kea == kea);

    pwSpec->cipher_def   = &bulk_cipher_defs[cipher];
    PORT_Assert(pwSpec->cipher_def->cipher == cipher);

    pwSpec->mac_def = &mac_defs[mac];
    PORT_Assert(pwSpec->mac_def->mac == mac);

    ss->sec.keyBits       = pwSpec->cipher_def->key_size        * BPB;
    ss->sec.secretKeyBits = pwSpec->cipher_def->secret_key_size * BPB;
    ss->sec.cipherType    = cipher;

    pwSpec->encodeContext = NULL;
    pwSpec->decodeContext = NULL;

    pwSpec->mac_size = pwSpec->mac_def->mac_size;

    pwSpec->compression_method = ss->ssl3.hs.compression;
    pwSpec->compressContext = NULL;
    pwSpec->decompressContext = NULL;

    ssl_ReleaseSpecWriteLock(ss);  /*******************************/
    return SECSuccess;
}

#ifdef NSS_ENABLE_ZLIB
#define SSL3_DEFLATE_CONTEXT_SIZE sizeof(z_stream)

static SECStatus
ssl3_MapZlibError(int zlib_error)
{
    switch (zlib_error) {
    case Z_OK:
        return SECSuccess;
    default:
        return SECFailure;
    }
}

static SECStatus
ssl3_DeflateInit(void *void_context)
{
    z_stream *context = void_context;
    context->zalloc = NULL;
    context->zfree = NULL;
    context->opaque = NULL;

    return ssl3_MapZlibError(deflateInit(context, Z_DEFAULT_COMPRESSION));
}

static SECStatus
ssl3_InflateInit(void *void_context)
{
    z_stream *context = void_context;
    context->zalloc = NULL;
    context->zfree = NULL;
    context->opaque = NULL;
    context->next_in = NULL;
    context->avail_in = 0;

    return ssl3_MapZlibError(inflateInit(context));
}

static SECStatus
ssl3_DeflateCompress(void *void_context, unsigned char *out, int *out_len,
                     int maxout, const unsigned char *in, int inlen)
{
    z_stream *context = void_context;

    if (!inlen) {
        *out_len = 0;
        return SECSuccess;
    }

    context->next_in = (unsigned char*) in;
    context->avail_in = inlen;
    context->next_out = out;
    context->avail_out = maxout;
    if (deflate(context, Z_SYNC_FLUSH) != Z_OK) {
        return SECFailure;
    }
    if (context->avail_out == 0) {
        /* We ran out of space! */
        SSL_TRC(3, ("%d: SSL3[%d] Ran out of buffer while compressing",
                    SSL_GETPID()));
        return SECFailure;
    }

    *out_len = maxout - context->avail_out;
    return SECSuccess;
}

static SECStatus
ssl3_DeflateDecompress(void *void_context, unsigned char *out, int *out_len,
                       int maxout, const unsigned char *in, int inlen)
{
    z_stream *context = void_context;

    if (!inlen) {
        *out_len = 0;
        return SECSuccess;
    }

    context->next_in = (unsigned char*) in;
    context->avail_in = inlen;
    context->next_out = out;
    context->avail_out = maxout;
    if (inflate(context, Z_SYNC_FLUSH) != Z_OK) {
        PORT_SetError(SSL_ERROR_DECOMPRESSION_FAILURE);
        return SECFailure;
    }

    *out_len = maxout - context->avail_out;
    return SECSuccess;
}

static SECStatus
ssl3_DestroyCompressContext(void *void_context, PRBool unused)
{
    deflateEnd(void_context);
    PORT_Free(void_context);
    return SECSuccess;
}

static SECStatus
ssl3_DestroyDecompressContext(void *void_context, PRBool unused)
{
    inflateEnd(void_context);
    PORT_Free(void_context);
    return SECSuccess;
}

#endif /* NSS_ENABLE_ZLIB */

/* Initialize the compression functions and contexts for the given
 * CipherSpec.  */
static SECStatus
ssl3_InitCompressionContext(ssl3CipherSpec *pwSpec)
{
    /* Setup the compression functions */
    switch (pwSpec->compression_method) {
    case ssl_compression_null:
	pwSpec->compressor = NULL;
	pwSpec->decompressor = NULL;
	pwSpec->compressContext = NULL;
	pwSpec->decompressContext = NULL;
	pwSpec->destroyCompressContext = NULL;
	pwSpec->destroyDecompressContext = NULL;
	break;
#ifdef NSS_ENABLE_ZLIB
    case ssl_compression_deflate:
	pwSpec->compressor = ssl3_DeflateCompress;
	pwSpec->decompressor = ssl3_DeflateDecompress;
	pwSpec->compressContext = PORT_Alloc(SSL3_DEFLATE_CONTEXT_SIZE);
	pwSpec->decompressContext = PORT_Alloc(SSL3_DEFLATE_CONTEXT_SIZE);
	pwSpec->destroyCompressContext = ssl3_DestroyCompressContext;
	pwSpec->destroyDecompressContext = ssl3_DestroyDecompressContext;
	ssl3_DeflateInit(pwSpec->compressContext);
	ssl3_InflateInit(pwSpec->decompressContext);
	break;
#endif /* NSS_ENABLE_ZLIB */
    default:
	PORT_Assert(0);
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	return SECFailure;
    }

    return SECSuccess;
}

#ifndef NO_PKCS11_BYPASS
/* Initialize encryption contexts for pending spec.
 * MAC contexts are set up when computing the mac, not here.
 * Master Secret already is derived in spec->msItem
 * Caller holds Spec write lock.
 */
static SECStatus
ssl3_InitPendingContextsBypass(sslSocket *ss)
{
      ssl3CipherSpec  *  pwSpec;
      const ssl3BulkCipherDef *cipher_def;
      void *             serverContext = NULL;
      void *             clientContext = NULL;
      BLapiInitContextFunc initFn = (BLapiInitContextFunc)NULL;
      int                mode     = 0;
      unsigned int       optArg1  = 0;
      unsigned int       optArg2  = 0;
      PRBool             server_encrypts = ss->sec.isServer;
      SSLCipherAlgorithm calg;
      SECStatus          rv;

    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
    PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);

    pwSpec        = ss->ssl3.pwSpec;
    cipher_def    = pwSpec->cipher_def;

    calg = cipher_def->calg;

    if (calg == ssl_calg_aes_gcm) {
	pwSpec->encode = NULL;
	pwSpec->decode = NULL;
	pwSpec->destroy = NULL;
	pwSpec->encodeContext = NULL;
	pwSpec->decodeContext = NULL;
	pwSpec->aead = ssl3_AESGCMBypass;
	ssl3_InitCompressionContext(pwSpec);
	return SECSuccess;
    }

    serverContext = pwSpec->server.cipher_context;
    clientContext = pwSpec->client.cipher_context;

    switch (calg) {
    case ssl_calg_null:
	pwSpec->encode  = Null_Cipher;
	pwSpec->decode  = Null_Cipher;
        pwSpec->destroy = NULL;
	goto success;

    case ssl_calg_rc4:
      	initFn = (BLapiInitContextFunc)RC4_InitContext;
	pwSpec->encode  = (SSLCipher) RC4_Encrypt;
	pwSpec->decode  = (SSLCipher) RC4_Decrypt;
	pwSpec->destroy = (SSLDestroy) RC4_DestroyContext;
	break;
    case ssl_calg_rc2:
      	initFn = (BLapiInitContextFunc)RC2_InitContext;
	mode = NSS_RC2_CBC;
	optArg1 = cipher_def->key_size;
	pwSpec->encode  = (SSLCipher) RC2_Encrypt;
	pwSpec->decode  = (SSLCipher) RC2_Decrypt;
	pwSpec->destroy = (SSLDestroy) RC2_DestroyContext;
	break;
    case ssl_calg_des:
      	initFn = (BLapiInitContextFunc)DES_InitContext;
	mode = NSS_DES_CBC;
	optArg1 = server_encrypts;
	pwSpec->encode  = (SSLCipher) DES_Encrypt;
	pwSpec->decode  = (SSLCipher) DES_Decrypt;
	pwSpec->destroy = (SSLDestroy) DES_DestroyContext;
	break;
    case ssl_calg_3des:
      	initFn = (BLapiInitContextFunc)DES_InitContext;
	mode = NSS_DES_EDE3_CBC;
	optArg1 = server_encrypts;
	pwSpec->encode  = (SSLCipher) DES_Encrypt;
	pwSpec->decode  = (SSLCipher) DES_Decrypt;
	pwSpec->destroy = (SSLDestroy) DES_DestroyContext;
	break;
    case ssl_calg_aes:
      	initFn = (BLapiInitContextFunc)AES_InitContext;
	mode = NSS_AES_CBC;
	optArg1 = server_encrypts;
	optArg2 = AES_BLOCK_SIZE;
	pwSpec->encode  = (SSLCipher) AES_Encrypt;
	pwSpec->decode  = (SSLCipher) AES_Decrypt;
	pwSpec->destroy = (SSLDestroy) AES_DestroyContext;
	break;

    case ssl_calg_camellia:
      	initFn = (BLapiInitContextFunc)Camellia_InitContext;
	mode = NSS_CAMELLIA_CBC;
	optArg1 = server_encrypts;
	optArg2 = CAMELLIA_BLOCK_SIZE;
	pwSpec->encode  = (SSLCipher) Camellia_Encrypt;
	pwSpec->decode  = (SSLCipher) Camellia_Decrypt;
	pwSpec->destroy = (SSLDestroy) Camellia_DestroyContext;
	break;

    case ssl_calg_seed:
      	initFn = (BLapiInitContextFunc)SEED_InitContext;
	mode = NSS_SEED_CBC;
	optArg1 = server_encrypts;
	optArg2 = SEED_BLOCK_SIZE;
	pwSpec->encode  = (SSLCipher) SEED_Encrypt;
	pwSpec->decode  = (SSLCipher) SEED_Decrypt;
	pwSpec->destroy = (SSLDestroy) SEED_DestroyContext;
	break;

    case ssl_calg_idea:
    case ssl_calg_fortezza :
    default:
	PORT_Assert(0);
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	goto bail_out;
    }
    rv = (*initFn)(serverContext,
		   pwSpec->server.write_key_item.data,
		   pwSpec->server.write_key_item.len,
		   pwSpec->server.write_iv_item.data,
		   mode, optArg1, optArg2);
    if (rv != SECSuccess) {
	PORT_Assert(0);
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	goto bail_out;
    }

    switch (calg) {
    case ssl_calg_des:
    case ssl_calg_3des:
    case ssl_calg_aes:
    case ssl_calg_camellia:
    case ssl_calg_seed:
	/* For block ciphers, if the server is encrypting, then the client
	* is decrypting, and vice versa.
	*/
        optArg1 = !optArg1;
        break;
    /* kill warnings. */
    case ssl_calg_null:
    case ssl_calg_rc4:
    case ssl_calg_rc2:
    case ssl_calg_idea:
    case ssl_calg_fortezza:
    case ssl_calg_aes_gcm:
        break;
    }

    rv = (*initFn)(clientContext,
		   pwSpec->client.write_key_item.data,
		   pwSpec->client.write_key_item.len,
		   pwSpec->client.write_iv_item.data,
		   mode, optArg1, optArg2);
    if (rv != SECSuccess) {
	PORT_Assert(0);
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	goto bail_out;
    }

    pwSpec->encodeContext = (ss->sec.isServer) ? serverContext : clientContext;
    pwSpec->decodeContext = (ss->sec.isServer) ? clientContext : serverContext;

    ssl3_InitCompressionContext(pwSpec);

success:
    return SECSuccess;

bail_out:
    return SECFailure;
}
#endif

/* This function should probably be moved to pk11wrap and be named 
 * PK11_ParamFromIVAndEffectiveKeyBits
 */
static SECItem *
ssl3_ParamFromIV(CK_MECHANISM_TYPE mtype, SECItem *iv, CK_ULONG ulEffectiveBits)
{
    SECItem * param = PK11_ParamFromIV(mtype, iv);
    if (param && param->data  && param->len >= sizeof(CK_RC2_PARAMS)) {
	switch (mtype) {
	case CKM_RC2_KEY_GEN:
	case CKM_RC2_ECB:
	case CKM_RC2_CBC:
	case CKM_RC2_MAC:
	case CKM_RC2_MAC_GENERAL:
	case CKM_RC2_CBC_PAD:
	    *(CK_RC2_PARAMS *)param->data = ulEffectiveBits;
	default: break;
	}
    }
    return param;
}

/* ssl3_BuildRecordPseudoHeader writes the SSL/TLS pseudo-header (the data
 * which is included in the MAC or AEAD additional data) to |out| and returns
 * its length. See https://tools.ietf.org/html/rfc5246#section-6.2.3.3 for the
 * definition of the AEAD additional data.
 *
 * TLS pseudo-header includes the record's version field, SSL's doesn't. Which
 * pseudo-header defintiion to use should be decided based on the version of
 * the protocol that was negotiated when the cipher spec became current, NOT
 * based on the version value in the record itself, and the decision is passed
 * to this function as the |includesVersion| argument. But, the |version|
 * argument should be the record's version value.
 */
static unsigned int
ssl3_BuildRecordPseudoHeader(unsigned char *out,
			     SSL3SequenceNumber seq_num,
			     SSL3ContentType type,
			     PRBool includesVersion,
			     SSL3ProtocolVersion version,
			     PRBool isDTLS,
			     int length)
{
    out[0] = (unsigned char)(seq_num.high >> 24);
    out[1] = (unsigned char)(seq_num.high >> 16);
    out[2] = (unsigned char)(seq_num.high >>  8);
    out[3] = (unsigned char)(seq_num.high >>  0);
    out[4] = (unsigned char)(seq_num.low  >> 24);
    out[5] = (unsigned char)(seq_num.low  >> 16);
    out[6] = (unsigned char)(seq_num.low  >>  8);
    out[7] = (unsigned char)(seq_num.low  >>  0);
    out[8] = type;

    /* SSL3 MAC doesn't include the record's version field. */
    if (!includesVersion) {
	out[9]  = MSB(length);
	out[10] = LSB(length);
	return 11;
    }

    /* TLS MAC and AEAD additional data include version. */
    if (isDTLS) {
	SSL3ProtocolVersion dtls_version;

	dtls_version = dtls_TLSVersionToDTLSVersion(version);
	out[9]  = MSB(dtls_version);
	out[10] = LSB(dtls_version);
    } else {
	out[9]  = MSB(version);
	out[10] = LSB(version);
    }
    out[11] = MSB(length);
    out[12] = LSB(length);
    return 13;
}

typedef SECStatus (*PK11CryptFcn)(
    PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism, SECItem *param,
    unsigned char *out, unsigned int *outLen, unsigned int maxLen,
    const unsigned char *in, unsigned int inLen);

static PK11CryptFcn pk11_encrypt = NULL;
static PK11CryptFcn pk11_decrypt = NULL;

static PRCallOnceType resolvePK11CryptOnce;

static PRStatus
ssl3_ResolvePK11CryptFunctions(void)
{
#ifdef LINUX
    /* On Linux we use the system NSS libraries. Look up the PK11_Encrypt and
     * PK11_Decrypt functions at run time. */
    void *handle = dlopen(NULL, RTLD_LAZY);
    if (!handle) {
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	return PR_FAILURE;
    }
    pk11_encrypt = (PK11CryptFcn)dlsym(handle, "PK11_Encrypt");
    pk11_decrypt = (PK11CryptFcn)dlsym(handle, "PK11_Decrypt");
    dlclose(handle);
    return PR_SUCCESS;
#else
    /* On other platforms we use our own copy of NSS. PK11_Encrypt and
     * PK11_Decrypt are known to be available. */
    pk11_encrypt = PK11_Encrypt;
    pk11_decrypt = PK11_Decrypt;
    return PR_SUCCESS;
#endif
}

/* 
 * In NSS 3.15, PK11_Encrypt and PK11_Decrypt were added to provide access
 * to the AES GCM implementation in the NSS softoken. So the presence of
 * these two functions implies the NSS version supports AES GCM.
 */
static PRBool
ssl3_HasGCMSupport(void)
{
    (void)PR_CallOnce(&resolvePK11CryptOnce, ssl3_ResolvePK11CryptFunctions);
    return pk11_encrypt != NULL;
}

/* On this socket, disable the GCM cipher suites */
SECStatus
ssl3_DisableGCMSuites(sslSocket * ss)
{
    unsigned int i;

    for (i = 0; i < PR_ARRAY_SIZE(cipher_suite_defs); i++) {
	const ssl3CipherSuiteDef *cipher_def = &cipher_suite_defs[i];
	if (cipher_def->bulk_cipher_alg == cipher_aes_128_gcm) {
	    SECStatus rv = ssl3_CipherPrefSet(ss, cipher_def->cipher_suite,
					      PR_FALSE);
	    PORT_Assert(rv == SECSuccess); /* else is coding error */
	}
    }
    return SECSuccess;
}

static SECStatus
ssl3_AESGCM(ssl3KeyMaterial *keys,
	    PRBool doDecrypt,
	    unsigned char *out,
	    int *outlen,
	    int maxout,
	    const unsigned char *in,
	    int inlen,
	    const unsigned char *additionalData,
	    int additionalDataLen)
{
    SECItem            param;
    SECStatus          rv = SECFailure;
    unsigned char      nonce[12];
    unsigned int       uOutLen;
    CK_GCM_PARAMS      gcmParams;

    static const int   tagSize = 16;
    static const int   explicitNonceLen = 8;

    /* See https://tools.ietf.org/html/rfc5288#section-3 for details of how the
     * nonce is formed. */
    memcpy(nonce, keys->write_iv, 4);
    if (doDecrypt) {
	memcpy(nonce + 4, in, explicitNonceLen);
	in += explicitNonceLen;
	inlen -= explicitNonceLen;
	*outlen = 0;
    } else {
	if (maxout < explicitNonceLen) {
	    PORT_SetError(SEC_ERROR_INPUT_LEN);
	    return SECFailure;
        }
	/* Use the 64-bit sequence number as the explicit nonce. */
	memcpy(nonce + 4, additionalData, explicitNonceLen);
	memcpy(out, additionalData, explicitNonceLen);
	out += explicitNonceLen;
	maxout -= explicitNonceLen;
	*outlen = explicitNonceLen;
    }

    param.type = siBuffer;
    param.data = (unsigned char *) &gcmParams;
    param.len = sizeof(gcmParams);
    gcmParams.pIv = nonce;
    gcmParams.ulIvLen = sizeof(nonce);
    gcmParams.pAAD = (unsigned char *)additionalData;  /* const cast */
    gcmParams.ulAADLen = additionalDataLen;
    gcmParams.ulTagBits = tagSize * 8;

    if (doDecrypt) {
	rv = pk11_decrypt(keys->write_key, CKM_AES_GCM, &param, out, &uOutLen,
			  maxout, in, inlen);
    } else {
	rv = pk11_encrypt(keys->write_key, CKM_AES_GCM, &param, out, &uOutLen,
			  maxout, in, inlen);
    }
    *outlen += (int) uOutLen;

    return rv;
}

#ifndef NO_PKCS11_BYPASS
static SECStatus
ssl3_AESGCMBypass(ssl3KeyMaterial *keys,
		  PRBool doDecrypt,
		  unsigned char *out,
		  int *outlen,
		  int maxout,
		  const unsigned char *in,
		  int inlen,
		  const unsigned char *additionalData,
		  int additionalDataLen)
{
    SECStatus          rv = SECFailure;
    unsigned char      nonce[12];
    unsigned int       uOutLen;
    AESContext        *cx;
    CK_GCM_PARAMS      gcmParams;

    static const int   tagSize = 16;
    static const int   explicitNonceLen = 8;

    /* See https://tools.ietf.org/html/rfc5288#section-3 for details of how the
     * nonce is formed. */
    PORT_Assert(keys->write_iv_item.len == 4);
    if (keys->write_iv_item.len != 4) {
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	return SECFailure;
    }
    memcpy(nonce, keys->write_iv_item.data, 4);
    if (doDecrypt) {
	memcpy(nonce + 4, in, explicitNonceLen);
	in += explicitNonceLen;
	inlen -= explicitNonceLen;
	*outlen = 0;
    } else {
	if (maxout < explicitNonceLen) {
	    PORT_SetError(SEC_ERROR_INPUT_LEN);
	    return SECFailure;
        }
	/* Use the 64-bit sequence number as the explicit nonce. */
	memcpy(nonce + 4, additionalData, explicitNonceLen);
	memcpy(out, additionalData, explicitNonceLen);
	out += explicitNonceLen;
	maxout -= explicitNonceLen;
	*outlen = explicitNonceLen;
    }

    gcmParams.pIv = nonce;
    gcmParams.ulIvLen = sizeof(nonce);
    gcmParams.pAAD = (unsigned char *)additionalData;  /* const cast */
    gcmParams.ulAADLen = additionalDataLen;
    gcmParams.ulTagBits = tagSize * 8;

    cx = (AESContext *)keys->cipher_context;
    rv = AES_InitContext(cx, keys->write_key_item.data,
			 keys->write_key_item.len,
			 (unsigned char *)&gcmParams, NSS_AES_GCM, !doDecrypt,
			 AES_BLOCK_SIZE);
    if (rv != SECSuccess) {
	return rv;
    }
    if (doDecrypt) {
	rv = AES_Decrypt(cx, out, &uOutLen, maxout, in, inlen);
    } else {
	rv = AES_Encrypt(cx, out, &uOutLen, maxout, in, inlen);
    }
    AES_DestroyContext(cx, PR_FALSE);
    *outlen += (int) uOutLen;

    return rv;
}
#endif

static SECStatus
ssl3_ChaCha20Poly1305(
	ssl3KeyMaterial *keys,
	PRBool doDecrypt,
	unsigned char *out,
	int *outlen,
	int maxout,
	const unsigned char *in,
	int inlen,
	const unsigned char *additionalData,
	int additionalDataLen)
{
    SECItem            param;
    SECStatus          rv = SECFailure;
    unsigned int       uOutLen;
    CK_NSS_AEAD_PARAMS aeadParams;
    static const int   tagSize = 16;

    param.type = siBuffer;
    param.len = sizeof(aeadParams);
    param.data = (unsigned char *) &aeadParams;
    memset(&aeadParams, 0, sizeof(aeadParams));
    aeadParams.pIv = (unsigned char *) additionalData;
    aeadParams.ulIvLen = 8;
    aeadParams.pAAD = (unsigned char *) additionalData;
    aeadParams.ulAADLen = additionalDataLen;
    aeadParams.ulTagLen = tagSize;

    if (doDecrypt) {
	rv = pk11_decrypt(keys->write_key, CKM_NSS_CHACHA20_POLY1305, &param,
			  out, &uOutLen, maxout, in, inlen);
    } else {
	rv = pk11_encrypt(keys->write_key, CKM_NSS_CHACHA20_POLY1305, &param,
			  out, &uOutLen, maxout, in, inlen);
    }
    *outlen = (int) uOutLen;

    return rv;
}

/* Initialize encryption and MAC contexts for pending spec.
 * Master Secret already is derived.
 * Caller holds Spec write lock.
 */
static SECStatus
ssl3_InitPendingContextsPKCS11(sslSocket *ss)
{
      ssl3CipherSpec  *  pwSpec;
      const ssl3BulkCipherDef *cipher_def;
      PK11Context *      serverContext = NULL;
      PK11Context *      clientContext = NULL;
      SECItem *          param;
      CK_MECHANISM_TYPE  mechanism;
      CK_MECHANISM_TYPE  mac_mech;
      CK_ULONG           macLength;
      CK_ULONG           effKeyBits;
      SECItem            iv;
      SECItem            mac_param;
      SSLCipherAlgorithm calg;

    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
    PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);

    pwSpec        = ss->ssl3.pwSpec;
    cipher_def    = pwSpec->cipher_def;
    macLength     = pwSpec->mac_size;
    calg          = cipher_def->calg;
    PORT_Assert(alg2Mech[calg].calg == calg);

    pwSpec->client.write_mac_context = NULL;
    pwSpec->server.write_mac_context = NULL;

    if (calg == calg_aes_gcm || calg == calg_chacha20) {
	pwSpec->encode = NULL;
	pwSpec->decode = NULL;
	pwSpec->destroy = NULL;
	pwSpec->encodeContext = NULL;
	pwSpec->decodeContext = NULL;
	if (calg == calg_aes_gcm) {
	    pwSpec->aead = ssl3_AESGCM;
	} else {
	    pwSpec->aead = ssl3_ChaCha20Poly1305;
	}
	return SECSuccess;
    }

    /* 
    ** Now setup the MAC contexts, 
    **   crypto contexts are setup below.
    */

    mac_mech       = pwSpec->mac_def->mmech;
    mac_param.data = (unsigned char *)&macLength;
    mac_param.len  = sizeof(macLength);
    mac_param.type = 0;

    pwSpec->client.write_mac_context = PK11_CreateContextBySymKey(
	    mac_mech, CKA_SIGN, pwSpec->client.write_mac_key, &mac_param);
    if (pwSpec->client.write_mac_context == NULL)  {
	ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
	goto fail;
    }
    pwSpec->server.write_mac_context = PK11_CreateContextBySymKey(
	    mac_mech, CKA_SIGN, pwSpec->server.write_mac_key, &mac_param);
    if (pwSpec->server.write_mac_context == NULL) {
	ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
	goto fail;
    }

    /* 
    ** Now setup the crypto contexts.
    */

    if (calg == calg_null) {
	pwSpec->encode  = Null_Cipher;
	pwSpec->decode  = Null_Cipher;
	pwSpec->destroy = NULL;
	return SECSuccess;
    }
    mechanism = alg2Mech[calg].cmech;
    effKeyBits = cipher_def->key_size * BPB;

    /*
     * build the server context
     */
    iv.data = pwSpec->server.write_iv;
    iv.len  = cipher_def->iv_size;
    param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits);
    if (param == NULL) {
	ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);
    	goto fail;
    }
    serverContext = PK11_CreateContextBySymKey(mechanism,
				(ss->sec.isServer ? CKA_ENCRYPT : CKA_DECRYPT),
				pwSpec->server.write_key, param);
    iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len);
    if (iv.data)
    	PORT_Memcpy(pwSpec->server.write_iv, iv.data, iv.len);
    SECITEM_FreeItem(param, PR_TRUE);
    if (serverContext == NULL) {
	ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
    	goto fail;
    }

    /*
     * build the client context
     */
    iv.data = pwSpec->client.write_iv;
    iv.len  = cipher_def->iv_size;

    param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits);
    if (param == NULL) {
	ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);
    	goto fail;
    }
    clientContext = PK11_CreateContextBySymKey(mechanism,
				(ss->sec.isServer ? CKA_DECRYPT : CKA_ENCRYPT),
				pwSpec->client.write_key, param);
    iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len);
    if (iv.data)
    	PORT_Memcpy(pwSpec->client.write_iv, iv.data, iv.len);
    SECITEM_FreeItem(param,PR_TRUE);
    if (clientContext == NULL) {
	ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
    	goto fail;
    }
    pwSpec->encode  = (SSLCipher) PK11_CipherOp;
    pwSpec->decode  = (SSLCipher) PK11_CipherOp;
    pwSpec->destroy = (SSLDestroy) PK11_DestroyContext;

    pwSpec->encodeContext = (ss->sec.isServer) ? serverContext : clientContext;
    pwSpec->decodeContext = (ss->sec.isServer) ? clientContext : serverContext;

    serverContext = NULL;
    clientContext = NULL;

    ssl3_InitCompressionContext(pwSpec);

    return SECSuccess;

fail:
    if (serverContext != NULL) PK11_DestroyContext(serverContext, PR_TRUE);
    if (clientContext != NULL) PK11_DestroyContext(clientContext, PR_TRUE);
    if (pwSpec->client.write_mac_context != NULL) {
    	PK11_DestroyContext(pwSpec->client.write_mac_context,PR_TRUE);
	pwSpec->client.write_mac_context = NULL;
    }
    if (pwSpec->server.write_mac_context != NULL) {
    	PK11_DestroyContext(pwSpec->server.write_mac_context,PR_TRUE);
	pwSpec->server.write_mac_context = NULL;
    }

    return SECFailure;
}

/* Complete the initialization of all keys, ciphers, MACs and their contexts
 * for the pending Cipher Spec.
 * Called from: ssl3_SendClientKeyExchange 	(for Full handshake)
 *              ssl3_HandleRSAClientKeyExchange	(for Full handshake)
 *              ssl3_HandleServerHello		(for session restart)
 *              ssl3_HandleClientHello		(for session restart)
 * Sets error code, but caller probably should override to disambiguate.
 * NULL pms means re-use old master_secret.
 *
 * This code is common to the bypass and PKCS11 execution paths.
 * For the bypass case,  pms is NULL.
 */
SECStatus
ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms)
{
    ssl3CipherSpec  *  pwSpec;
    ssl3CipherSpec  *  cwSpec;
    SECStatus          rv;

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

    ssl_GetSpecWriteLock(ss);	/**************************************/

    PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);

    pwSpec        = ss->ssl3.pwSpec;
    cwSpec        = ss->ssl3.cwSpec;

    if (pms || (!pwSpec->msItem.len && !pwSpec->master_secret)) {
	rv = ssl3_DeriveMasterSecret(ss, pms);
	if (rv != SECSuccess) {
	    goto done;  /* err code set by ssl3_DeriveMasterSecret */
	}
    }
#ifndef NO_PKCS11_BYPASS
    if (ss->opt.bypassPKCS11 && pwSpec->msItem.len && pwSpec->msItem.data) {
	/* Double Bypass succeeded in extracting the master_secret */
	const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
	PRBool             isTLS   = (PRBool)(kea_def->tls_keygen ||
                                (pwSpec->version > SSL_LIBRARY_VERSION_3_0));
	pwSpec->bypassCiphers = PR_TRUE;
	rv = ssl3_KeyAndMacDeriveBypass( pwSpec, 
			     (const unsigned char *)&ss->ssl3.hs.client_random,
			     (const unsigned char *)&ss->ssl3.hs.server_random,
			     isTLS, 
			     (PRBool)(kea_def->is_limited));
	if (rv == SECSuccess) {
	    rv = ssl3_InitPendingContextsBypass(ss);
	}
    } else
#endif
    if (pwSpec->master_secret) {
	rv = ssl3_DeriveConnectionKeysPKCS11(ss);
	if (rv == SECSuccess) {
	    rv = ssl3_InitPendingContextsPKCS11(ss);
	}
    } else {
	PORT_Assert(pwSpec->master_secret);
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	rv = SECFailure;
    }
    if (rv != SECSuccess) {
	goto done;
    }

    /* Generic behaviors -- common to all crypto methods */
    if (!IS_DTLS(ss)) {
	pwSpec->read_seq_num.high = pwSpec->write_seq_num.high = 0;
    } else {
	if (cwSpec->epoch == PR_UINT16_MAX) {
	    /* The problem here is that we have rehandshaked too many
	     * times (you are not allowed to wrap the epoch). The
	     * spec says you should be discarding the connection
	     * and start over, so not much we can do here. */
	    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	    rv = SECFailure;
	    goto done;
	}
	/* The sequence number has the high 16 bits as the epoch. */
	pwSpec->epoch = cwSpec->epoch + 1;
	pwSpec->read_seq_num.high = pwSpec->write_seq_num.high =
	    pwSpec->epoch << 16;

	dtls_InitRecvdRecords(&pwSpec->recvdRecords);
    }
    pwSpec->read_seq_num.low = pwSpec->write_seq_num.low = 0;

done:
    ssl_ReleaseSpecWriteLock(ss);	/******************************/
    if (rv != SECSuccess)
	ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
    return rv;
}

/*
 * 60 bytes is 3 times the maximum length MAC size that is supported.
 */
static const unsigned char mac_pad_1 [60] = {
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
    0x36, 0x36, 0x36, 0x36
};
static const unsigned char mac_pad_2 [60] = {
    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
    0x5c, 0x5c, 0x5c, 0x5c
};

/* Called from: ssl3_SendRecord()
** Caller must already hold the SpecReadLock. (wish we could assert that!)
*/
static SECStatus
ssl3_ComputeRecordMAC(
    ssl3CipherSpec *   spec,
    PRBool             useServerMacKey,
    const unsigned char *header,
    unsigned int       headerLen,
    const SSL3Opaque * input,
    int                inputLength,
    unsigned char *    outbuf,
    unsigned int *     outLength)
{
    const ssl3MACDef * mac_def;
    SECStatus          rv;

    PRINT_BUF(95, (NULL, "frag hash1: header", header, headerLen));
    PRINT_BUF(95, (NULL, "frag hash1: input", input, inputLength));

    mac_def = spec->mac_def;
    if (mac_def->mac == mac_null) {
	*outLength = 0;
	return SECSuccess;
    }
#ifndef NO_PKCS11_BYPASS
    if (spec->bypassCiphers) {
	/* bypass version */
	const SECHashObject *hashObj = NULL;
	unsigned int       pad_bytes = 0;
	PRUint64           write_mac_context[MAX_MAC_CONTEXT_LLONGS];

	switch (mac_def->mac) {
	case ssl_mac_null:
	    *outLength = 0;
	    return SECSuccess;
	case ssl_mac_md5:
	    pad_bytes = 48;
	    hashObj = HASH_GetRawHashObject(HASH_AlgMD5);
	    break;
	case ssl_mac_sha:
	    pad_bytes = 40;
	    hashObj = HASH_GetRawHashObject(HASH_AlgSHA1);
	    break;
	case ssl_hmac_md5: /* used with TLS */
	    hashObj = HASH_GetRawHashObject(HASH_AlgMD5);
	    break;
	case ssl_hmac_sha: /* used with TLS */
	    hashObj = HASH_GetRawHashObject(HASH_AlgSHA1);
	    break;
	case ssl_hmac_sha256: /* used with TLS */
	    hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
	    break;
	default:
	    break;
	}
	if (!hashObj) {
	    PORT_Assert(0);
	    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	    return SECFailure;
	}

	if (spec->version <= SSL_LIBRARY_VERSION_3_0) {
	    unsigned int tempLen;
	    unsigned char temp[MAX_MAC_LENGTH];

	    /* compute "inner" part of SSL3 MAC */
	    hashObj->begin(write_mac_context);
	    if (useServerMacKey)
		hashObj->update(write_mac_context, 
				spec->server.write_mac_key_item.data,
				spec->server.write_mac_key_item.len);
	    else
		hashObj->update(write_mac_context, 
				spec->client.write_mac_key_item.data,
				spec->client.write_mac_key_item.len);
	    hashObj->update(write_mac_context, mac_pad_1, pad_bytes);
	    hashObj->update(write_mac_context, header, headerLen);
	    hashObj->update(write_mac_context, input, inputLength);
	    hashObj->end(write_mac_context,    temp, &tempLen, sizeof temp);

	    /* compute "outer" part of SSL3 MAC */
	    hashObj->begin(write_mac_context);
	    if (useServerMacKey)
		hashObj->update(write_mac_context, 
				spec->server.write_mac_key_item.data,
				spec->server.write_mac_key_item.len);
	    else
		hashObj->update(write_mac_context, 
				spec->client.write_mac_key_item.data,
				spec->client.write_mac_key_item.len);
	    hashObj->update(write_mac_context, mac_pad_2, pad_bytes);
	    hashObj->update(write_mac_context, temp, tempLen);
	    hashObj->end(write_mac_context, outbuf, outLength, spec->mac_size);
	    rv = SECSuccess;
	} else { /* is TLS */
#define cx ((HMACContext *)write_mac_context)
	    if (useServerMacKey) {
		rv = HMAC_Init(cx, hashObj, 
			       spec->server.write_mac_key_item.data,
			       spec->server.write_mac_key_item.len, PR_FALSE);
	    } else {
		rv = HMAC_Init(cx, hashObj, 
			       spec->client.write_mac_key_item.data,
			       spec->client.write_mac_key_item.len, PR_FALSE);
	    }
	    if (rv == SECSuccess) {
		HMAC_Begin(cx);
		HMAC_Update(cx, header, headerLen);
		HMAC_Update(cx, input, inputLength);
		rv = HMAC_Finish(cx, outbuf, outLength, spec->mac_size);
		HMAC_Destroy(cx, PR_FALSE);
	    }
#undef cx
	}
    } else
#endif
    {
	PK11Context *mac_context = 
	    (useServerMacKey ? spec->server.write_mac_context
	                     : spec->client.write_mac_context);
	rv  = PK11_DigestBegin(mac_context);
	rv |= PK11_DigestOp(mac_context, header, headerLen);
	rv |= PK11_DigestOp(mac_context, input, inputLength);
	rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size);
    }

    PORT_Assert(rv != SECSuccess || *outLength == (unsigned)spec->mac_size);

    PRINT_BUF(95, (NULL, "frag hash2: result", outbuf, *outLength));

    if (rv != SECSuccess) {
    	rv = SECFailure;
	ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
    }
    return rv;
}

/* Called from: ssl3_HandleRecord()
 * Caller must already hold the SpecReadLock. (wish we could assert that!)
 *
 * On entry:
 *   originalLen >= inputLen >= MAC size
*/
static SECStatus
ssl3_ComputeRecordMACConstantTime(
    ssl3CipherSpec *   spec,
    PRBool             useServerMacKey,
    const unsigned char *header,
    unsigned int       headerLen,
    const SSL3Opaque * input,
    int                inputLen,
    int                originalLen,
    unsigned char *    outbuf,
    unsigned int *     outLen)
{
    CK_MECHANISM_TYPE            macType;
    CK_NSS_MAC_CONSTANT_TIME_PARAMS params;
    SECItem                      param, inputItem, outputItem;
    SECStatus                    rv;
    PK11SymKey *                 key;

    PORT_Assert(inputLen >= spec->mac_size);
    PORT_Assert(originalLen >= inputLen);

    if (spec->bypassCiphers) {
	/* This function doesn't support PKCS#11 bypass. We fallback on the
	 * non-constant time version. */
	goto fallback;
    }

    if (spec->mac_def->mac == mac_null) {
	*outLen = 0;
	return SECSuccess;
    }

    macType = CKM_NSS_HMAC_CONSTANT_TIME;
    if (spec->version <= SSL_LIBRARY_VERSION_3_0) {
	macType = CKM_NSS_SSL3_MAC_CONSTANT_TIME;
    }

    params.macAlg = spec->mac_def->mmech;
    params.ulBodyTotalLen = originalLen;
    params.pHeader = (unsigned char *) header;  /* const cast */
    params.ulHeaderLen = headerLen;

    param.data = (unsigned char*) &params;
    param.len = sizeof(params);
    param.type = 0;

    inputItem.data = (unsigned char *) input;
    inputItem.len = inputLen;
    inputItem.type = 0;

    outputItem.data = outbuf;
    outputItem.len = *outLen;
    outputItem.type = 0;

    key = spec->server.write_mac_key;
    if (!useServerMacKey) {
	key = spec->client.write_mac_key;
    }

    rv = PK11_SignWithSymKey(key, macType, &param, &outputItem, &inputItem);
    if (rv != SECSuccess) {
	if (PORT_GetError() == SEC_ERROR_INVALID_ALGORITHM) {
	    goto fallback;
	}

	*outLen = 0;
	rv = SECFailure;
	ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
	return rv;
    }

    PORT_Assert(outputItem.len == (unsigned)spec->mac_size);
    *outLen = outputItem.len;

    return rv;

fallback:
    /* ssl3_ComputeRecordMAC expects the MAC to have been removed from the
     * length already. */
    inputLen -= spec->mac_size;
    return ssl3_ComputeRecordMAC(spec, useServerMacKey, header, headerLen,
				 input, inputLen, outbuf, outLen);
}

static PRBool
ssl3_ClientAuthTokenPresent(sslSessionID *sid) {
    PK11SlotInfo *slot = NULL;
    PRBool isPresent = PR_TRUE;

    /* we only care if we are doing client auth */
    /* If NSS_PLATFORM_CLIENT_AUTH is defined and a platformClientKey is being
     * used, u.ssl3.clAuthValid will be false and this function will always
     * return PR_TRUE. */
    if (!sid || !sid->u.ssl3.clAuthValid) {
	return PR_TRUE;
    }

    /* get the slot */
    slot = SECMOD_LookupSlot(sid->u.ssl3.clAuthModuleID,
	                     sid->u.ssl3.clAuthSlotID);
    if (slot == NULL ||
	!PK11_IsPresent(slot) ||
	sid->u.ssl3.clAuthSeries     != PK11_GetSlotSeries(slot) ||
	sid->u.ssl3.clAuthSlotID     != PK11_GetSlotID(slot)     ||
	sid->u.ssl3.clAuthModuleID   != PK11_GetModuleID(slot)   ||
	(PK11_NeedLogin(slot) && !PK11_IsLoggedIn(slot, NULL))) {
	isPresent = PR_FALSE;
    } 
    if (slot) {
	PK11_FreeSlot(slot);
    }
    return isPresent;
}

/* Caller must hold the spec read lock. */
SECStatus
ssl3_CompressMACEncryptRecord(ssl3CipherSpec *   cwSpec,
		              PRBool             isServer,
			      PRBool             isDTLS,
			      PRBool             capRecordVersion,
                              SSL3ContentType    type,
		              const SSL3Opaque * pIn,
		              PRUint32           contentLen,
		              sslBuffer *        wrBuf)
{
    const ssl3BulkCipherDef * cipher_def;
    SECStatus                 rv;
    PRUint32                  macLen = 0;
    PRUint32                  fragLen;
    PRUint32  p1Len, p2Len, oddLen = 0;
    PRUint16                  headerLen;
    int                       ivLen = 0;
    int                       cipherBytes = 0;
    unsigned char             pseudoHeader[13];
    unsigned int              pseudoHeaderLen;

    cipher_def = cwSpec->cipher_def;
    headerLen = isDTLS ? DTLS_RECORD_HEADER_LENGTH : SSL3_RECORD_HEADER_LENGTH;

    if (cipher_def->type == type_block &&
	cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
	/* Prepend the per-record explicit IV using technique 2b from
	 * RFC 4346 section 6.2.3.2: The IV is a cryptographically
	 * strong random number XORed with the CBC residue from the previous
	 * record.
	 */
	ivLen = cipher_def->iv_size;
	if (ivLen > wrBuf->space - headerLen) {
	    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	    return SECFailure;
	}
	rv = PK11_GenerateRandom(wrBuf->buf + headerLen, ivLen);
	if (rv != SECSuccess) {
	    ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
	    return rv;
	}
	rv = cwSpec->encode( cwSpec->encodeContext, 
	    wrBuf->buf + headerLen,
	    &cipherBytes,                       /* output and actual outLen */
	    ivLen,                              /* max outlen */
	    wrBuf->buf + headerLen,
	    ivLen);                             /* input and inputLen*/
	if (rv != SECSuccess || cipherBytes != ivLen) {
	    PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
	    return SECFailure;
	}
    }

    if (cwSpec->compressor) {
	int outlen;
	rv = cwSpec->compressor(
	    cwSpec->compressContext,
	    wrBuf->buf + headerLen + ivLen, &outlen,
	    wrBuf->space - headerLen - ivLen, pIn, contentLen);
	if (rv != SECSuccess)
	    return rv;
	pIn = wrBuf->buf + headerLen + ivLen;
	contentLen = outlen;
    }

    pseudoHeaderLen = ssl3_BuildRecordPseudoHeader(
	pseudoHeader, cwSpec->write_seq_num, type,
	cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_0, cwSpec->version,
	isDTLS, contentLen);
    PORT_Assert(pseudoHeaderLen <= sizeof(pseudoHeader));
    if (cipher_def->type == type_aead) {
	const int nonceLen = cipher_def->explicit_nonce_size;
	const int tagLen = cipher_def->tag_size;

	if (headerLen + nonceLen + contentLen + tagLen > wrBuf->space) {
	    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	    return SECFailure;
	}

	cipherBytes = contentLen;
	rv = cwSpec->aead(
		isServer ? &cwSpec->server : &cwSpec->client,
		PR_FALSE,                                   /* do encrypt */
		wrBuf->buf + headerLen,                     /* output  */
		&cipherBytes,                               /* out len */
		wrBuf->space - headerLen,                   /* max out */
		pIn, contentLen,                            /* input   */
		pseudoHeader, pseudoHeaderLen);
	if (rv != SECSuccess) {
	    PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
	    return SECFailure;
	}
    } else {
	/*
	 * Add the MAC
	 */
	rv = ssl3_ComputeRecordMAC(cwSpec, isServer,
	    pseudoHeader, pseudoHeaderLen, pIn, contentLen,
	    wrBuf->buf + headerLen + ivLen + contentLen, &macLen);
	if (rv != SECSuccess) {
	    ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
	    return SECFailure;
	}
	p1Len   = contentLen;
	p2Len   = macLen;
	fragLen = contentLen + macLen;	/* needs to be encrypted */
	PORT_Assert(fragLen <= MAX_FRAGMENT_LENGTH + 1024);

	/*
	 * Pad the text (if we're doing a block cipher)
	 * then Encrypt it
	 */
	if (cipher_def->type == type_block) {
	    unsigned char * pBuf;
	    int             padding_length;
	    int             i;

	    oddLen = contentLen % cipher_def->block_size;
	    /* Assume blockSize is a power of two */
	    padding_length = cipher_def->block_size - 1 -
			    ((fragLen) & (cipher_def->block_size - 1));
	    fragLen += padding_length + 1;
	    PORT_Assert((fragLen % cipher_def->block_size) == 0);

	    /* Pad according to TLS rules (also acceptable to SSL3). */
	    pBuf = &wrBuf->buf[headerLen + ivLen + fragLen - 1];
	    for (i = padding_length + 1; i > 0; --i) {
		*pBuf-- = padding_length;
	    }
	    /* now, if contentLen is not a multiple of block size, fix it */
	    p2Len = fragLen - p1Len;
	}
	if (p1Len < 256) {
	    oddLen = p1Len;
	    p1Len = 0;
	} else {
	    p1Len -= oddLen;
	}
	if (oddLen) {
	    p2Len += oddLen;
	    PORT_Assert( (cipher_def->block_size < 2) || \
			 (p2Len % cipher_def->block_size) == 0);
	    memmove(wrBuf->buf + headerLen + ivLen + p1Len, pIn + p1Len,
		    oddLen);
	}
	if (p1Len > 0) {
	    int cipherBytesPart1 = -1;
	    rv = cwSpec->encode( cwSpec->encodeContext, 
		wrBuf->buf + headerLen + ivLen,         /* output */
		&cipherBytesPart1,                      /* actual outlen */
		p1Len,                                  /* max outlen */
		pIn, p1Len);                      /* input, and inputlen */
	    PORT_Assert(rv == SECSuccess && cipherBytesPart1 == (int) p1Len);
	    if (rv != SECSuccess || cipherBytesPart1 != (int) p1Len) {
		PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
		return SECFailure;
	    }
	    cipherBytes += cipherBytesPart1;
	}
	if (p2Len > 0) {
	    int cipherBytesPart2 = -1;
	    rv = cwSpec->encode( cwSpec->encodeContext, 
		wrBuf->buf + headerLen + ivLen + p1Len,
		&cipherBytesPart2,          /* output and actual outLen */
		p2Len,                             /* max outlen */
		wrBuf->buf + headerLen + ivLen + p1Len,
		p2Len);                            /* input and inputLen*/
	    PORT_Assert(rv == SECSuccess && cipherBytesPart2 == (int) p2Len);
	    if (rv != SECSuccess || cipherBytesPart2 != (int) p2Len) {
		PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
		return SECFailure;
	    }
	    cipherBytes += cipherBytesPart2;
	}
    }

    PORT_Assert(cipherBytes <= MAX_FRAGMENT_LENGTH + 1024);

    wrBuf->len    = cipherBytes + headerLen;
    wrBuf->buf[0] = type;
    if (isDTLS) {
	SSL3ProtocolVersion version;

	version = dtls_TLSVersionToDTLSVersion(cwSpec->version);
	wrBuf->buf[1] = MSB(version);
	wrBuf->buf[2] = LSB(version);
	wrBuf->buf[3] = (unsigned char)(cwSpec->write_seq_num.high >> 24);
	wrBuf->buf[4] = (unsigned char)(cwSpec->write_seq_num.high >> 16);
	wrBuf->buf[5] = (unsigned char)(cwSpec->write_seq_num.high >>  8);
	wrBuf->buf[6] = (unsigned char)(cwSpec->write_seq_num.high >>  0);
	wrBuf->buf[7] = (unsigned char)(cwSpec->write_seq_num.low  >> 24);
	wrBuf->buf[8] = (unsigned char)(cwSpec->write_seq_num.low  >> 16);
	wrBuf->buf[9] = (unsigned char)(cwSpec->write_seq_num.low  >>  8);
	wrBuf->buf[10] = (unsigned char)(cwSpec->write_seq_num.low >>  0);
	wrBuf->buf[11] = MSB(cipherBytes);
	wrBuf->buf[12] = LSB(cipherBytes);
    } else {
	SSL3ProtocolVersion version = cwSpec->version;

	if (capRecordVersion) {
	    version = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0, version);
	}
	wrBuf->buf[1] = MSB(version);
	wrBuf->buf[2] = LSB(version);
	wrBuf->buf[3] = MSB(cipherBytes);
	wrBuf->buf[4] = LSB(cipherBytes);
    }

    ssl3_BumpSequenceNumber(&cwSpec->write_seq_num);

    return SECSuccess;
}

/* Process the plain text before sending it.
 * Returns the number of bytes of plaintext that were successfully sent
 * 	plus the number of bytes of plaintext that were copied into the
 *	output (write) buffer.
 * Returns SECFailure on a hard IO error, memory error, or crypto error.
 * Does NOT return SECWouldBlock.
 *
 * Notes on the use of the private ssl flags:
 * (no private SSL flags)
 *    Attempt to make and send SSL records for all plaintext
 *    If non-blocking and a send gets WOULD_BLOCK,
 *    or if the pending (ciphertext) buffer is not empty,
 *    then buffer remaining bytes of ciphertext into pending buf,
 *    and continue to do that for all succssive records until all
 *    bytes are used.
 * ssl_SEND_FLAG_FORCE_INTO_BUFFER
 *    As above, except this suppresses all write attempts, and forces
 *    all ciphertext into the pending ciphertext buffer.
 * ssl_SEND_FLAG_USE_EPOCH (for DTLS)
 *    Forces the use of the provided epoch
 * ssl_SEND_FLAG_CAP_RECORD_VERSION
 *    Caps the record layer version number of TLS ClientHello to { 3, 1 }
 *    (TLS 1.0). Some TLS 1.0 servers (which seem to use F5 BIG-IP) ignore
 *    ClientHello.client_version and use the record layer version number
 *    (TLSPlaintext.version) instead when negotiating protocol versions. In
 *    addition, if the record layer version number of ClientHello is { 3, 2 }
 *    (TLS 1.1) or higher, these servers reset the TCP connections. Lastly,
 *    some F5 BIG-IP servers hang if a record containing a ClientHello has a
 *    version greater than { 3, 1 } and a length greater than 255. Set this
 *    flag to work around such servers.
 */
PRInt32
ssl3_SendRecord(   sslSocket *        ss,
                   DTLSEpoch          epoch, /* DTLS only */
                   SSL3ContentType    type,
		   const SSL3Opaque * pIn,   /* input buffer */
		   PRInt32            nIn,   /* bytes of input */
		   PRInt32            flags)
{
    sslBuffer      *          wrBuf 	  = &ss->sec.writeBuf;
    SECStatus                 rv;
    PRInt32                   totalSent   = 0;
    PRBool                    capRecordVersion;

    SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",
		SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
		nIn));
    PRINT_BUF(50, (ss, "Send record (plain text)", pIn, nIn));

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

    capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0);

    if (capRecordVersion) {
	/* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with the
	 * TLS initial ClientHello. */
	PORT_Assert(!IS_DTLS(ss));
	PORT_Assert(!ss->firstHsDone);
	PORT_Assert(type == content_handshake);
	PORT_Assert(ss->ssl3.hs.ws == wait_server_hello);
    }

    if (ss->ssl3.initialized == PR_FALSE) {
	/* This can happen on a server if the very first incoming record
	** looks like a defective ssl3 record (e.g. too long), and we're
	** trying to send an alert.
	*/
	PR_ASSERT(type == content_alert);
	rv = ssl3_InitState(ss);
	if (rv != SECSuccess) {
	    return SECFailure;	/* ssl3_InitState has set the error code. */
    	}
    }

    /* check for Token Presence */
    if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) {
	PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
	return SECFailure;
    }

    while (nIn > 0) {
	PRUint32  contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH);
	unsigned int spaceNeeded;
	unsigned int numRecords;

	ssl_GetSpecReadLock(ss);    /********************************/

	if (nIn > 1 && ss->opt.cbcRandomIV &&
	    ss->ssl3.cwSpec->version < SSL_LIBRARY_VERSION_TLS_1_1 &&
	    type == content_application_data &&
	    ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) {
	    /* We will split the first byte of the record into its own record,
	     * as explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h
	     */
	    numRecords = 2;
	} else {
	    numRecords = 1;
	}

	spaceNeeded = contentLen + (numRecords * SSL3_BUFFER_FUDGE);
	if (ss->ssl3.cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1 &&
	    ss->ssl3.cwSpec->cipher_def->type == type_block) {
	    spaceNeeded += ss->ssl3.cwSpec->cipher_def->iv_size;
	}
	if (spaceNeeded > wrBuf->space) {
	    rv = sslBuffer_Grow(wrBuf, spaceNeeded);
	    if (rv != SECSuccess) {
		SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes",
			 SSL_GETPID(), ss->fd, spaceNeeded));
		goto spec_locked_loser; /* sslBuffer_Grow set error code. */
	    }
	}

	if (numRecords == 2) {
	    sslBuffer secondRecord;

	    rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
					       ss->sec.isServer, IS_DTLS(ss),
					       capRecordVersion, type, pIn,
					       1, wrBuf);
	    if (rv != SECSuccess)
	        goto spec_locked_loser;

	    PRINT_BUF(50, (ss, "send (encrypted) record data [1/2]:",
	                   wrBuf->buf, wrBuf->len));

	    secondRecord.buf = wrBuf->buf + wrBuf->len;
	    secondRecord.len = 0;
	    secondRecord.space = wrBuf->space - wrBuf->len;

	    rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
	                                       ss->sec.isServer, IS_DTLS(ss),
					       capRecordVersion, type,
					       pIn + 1, contentLen - 1,
	                                       &secondRecord);
	    if (rv == SECSuccess) {
	        PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:",
	                       secondRecord.buf, secondRecord.len));
	        wrBuf->len += secondRecord.len;
	    }
	} else {
	    if (!IS_DTLS(ss)) {
		rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
						   ss->sec.isServer,
						   IS_DTLS(ss),
						   capRecordVersion,
						   type, pIn,
						   contentLen, wrBuf);
	    } else {
		rv = dtls_CompressMACEncryptRecord(ss, epoch,
						   !!(flags & ssl_SEND_FLAG_USE_EPOCH),
						   type, pIn,
						   contentLen, wrBuf);
	    }

	    if (rv == SECSuccess) {
	        PRINT_BUF(50, (ss, "send (encrypted) record data:",
	                       wrBuf->buf, wrBuf->len));
	    }
	}

spec_locked_loser:
	ssl_ReleaseSpecReadLock(ss); /************************************/

	if (rv != SECSuccess)
	    return SECFailure;

	pIn += contentLen;
	nIn -= contentLen;
	PORT_Assert( nIn >= 0 );

	/* If there's still some previously saved ciphertext,
	 * or the caller doesn't want us to send the data yet,
	 * then add all our new ciphertext to the amount previously saved.
	 */
	if ((ss->pendingBuf.len > 0) ||
	    (flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {

	    rv = ssl_SaveWriteData(ss, wrBuf->buf, wrBuf->len);
	    if (rv != SECSuccess) {
		/* presumably a memory error, SEC_ERROR_NO_MEMORY */
		return SECFailure;
	    }
	    wrBuf->len = 0;	/* All cipher text is saved away. */

	    if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
		PRInt32   sent;
		ss->handshakeBegun = 1;
		sent = ssl_SendSavedWriteData(ss);
		if (sent < 0 && PR_GetError() != PR_WOULD_BLOCK_ERROR) {
		    ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
		    return SECFailure;
		}
		if (ss->pendingBuf.len) {
		    flags |= ssl_SEND_FLAG_FORCE_INTO_BUFFER;
		}
	    }
	} else if (wrBuf->len > 0) {
	    PRInt32   sent;
	    ss->handshakeBegun = 1;
	    sent = ssl_DefSend(ss, wrBuf->buf, wrBuf->len,
			       flags & ~ssl_SEND_FLAG_MASK);
	    if (sent < 0) {
		if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {
		    ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
		    return SECFailure;
		}
		/* we got PR_WOULD_BLOCK_ERROR, which means none was sent. */
		sent = 0;
	    }
	    wrBuf->len -= sent;
	    if (wrBuf->len) {
		if (IS_DTLS(ss)) {
		    /* DTLS just says no in this case. No buffering */
		    PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
		    return SECFailure;
		}
		/* now take all the remaining unsent new ciphertext and 
		 * append it to the buffer of previously unsent ciphertext.
		 */
		rv = ssl_SaveWriteData(ss, wrBuf->buf + sent, wrBuf->len);
		if (rv != SECSuccess) {
		    /* presumably a memory error, SEC_ERROR_NO_MEMORY */
		    return SECFailure;
		}
	    }
	}
	totalSent += contentLen;
    }
    return totalSent;
}

#define SSL3_PENDING_HIGH_WATER 1024

/* Attempt to send the content of "in" in an SSL application_data record.
 * Returns "len" or SECFailure,   never SECWouldBlock, nor SECSuccess.
 */
int
ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
			 PRInt32 len, PRInt32 flags)
{
    PRInt32   totalSent	= 0;
    PRInt32   discarded = 0;

    PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
    /* These flags for internal use only */
    PORT_Assert(!(flags & (ssl_SEND_FLAG_USE_EPOCH |
			   ssl_SEND_FLAG_NO_RETRANSMIT)));
    if (len < 0 || !in) {
	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
	return SECFailure;
    }

    if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER &&
        !ssl_SocketIsBlocking(ss)) {
	PORT_Assert(!ssl_SocketIsBlocking(ss));
	PORT_SetError(PR_WOULD_BLOCK_ERROR);
	return SECFailure;
    }

    if (ss->appDataBuffered && len) {
	PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered));
	if (in[0] != (unsigned char)(ss->appDataBuffered)) {
	    PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
	    return SECFailure;
	}
    	in++;
	len--;
	discarded = 1;
    }
    while (len > totalSent) {
	PRInt32   sent, toSend;

	if (totalSent > 0) {
	    /*
	     * The thread yield is intended to give the reader thread a
	     * chance to get some cycles while the writer thread is in
	     * the middle of a large application data write.  (See
	     * Bugzilla bug 127740, comment #1.)
	     */
	    ssl_ReleaseXmitBufLock(ss);
	    PR_Sleep(PR_INTERVAL_NO_WAIT);	/* PR_Yield(); */
	    ssl_GetXmitBufLock(ss);
	}
	toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH);
	/*
	 * Note that the 0 epoch is OK because flags will never require 
	 * its use, as guaranteed by the PORT_Assert above.
	 */
	sent = ssl3_SendRecord(ss, 0, content_application_data,
	                       in + totalSent, toSend, flags);
	if (sent < 0) {
	    if (totalSent > 0 && PR_GetError() == PR_WOULD_BLOCK_ERROR) {
		PORT_Assert(ss->lastWriteBlocked);
	    	break;
	    }
	    return SECFailure; /* error code set by ssl3_SendRecord */
	}
	totalSent += sent;
	if (ss->pendingBuf.len) {
	    /* must be a non-blocking socket */
	    PORT_Assert(!ssl_SocketIsBlocking(ss));
	    PORT_Assert(ss->lastWriteBlocked);
	    break;	
	}
    }
    if (ss->pendingBuf.len) {
	/* Must be non-blocking. */
	PORT_Assert(!ssl_SocketIsBlocking(ss));
	if (totalSent > 0) {
	    ss->appDataBuffered = 0x100 | in[totalSent - 1];
	}

	totalSent = totalSent + discarded - 1;
	if (totalSent <= 0) {
	    PORT_SetError(PR_WOULD_BLOCK_ERROR);
	    totalSent = SECFailure;
	}
	return totalSent;
    } 
    ss->appDataBuffered = 0;
    return totalSent + discarded;
}

/* Attempt to send buffered handshake messages.
 * This function returns SECSuccess or SECFailure, never SECWouldBlock.
 * Always set sendBuf.len to 0, even when returning SECFailure.
 *
 * Depending on whether we are doing DTLS or not, this either calls
 *
 * - ssl3_FlushHandshakeMessages if non-DTLS
 * - dtls_FlushHandshakeMessages if DTLS
 *
 * Called from SSL3_SendAlert(), ssl3_SendChangeCipherSpecs(),
 *             ssl3_AppendHandshake(), ssl3_SendClientHello(),
 *             ssl3_SendHelloRequest(), ssl3_SendServerHelloDone(),
 *             ssl3_SendFinished(),
 */
static SECStatus
ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags)
{
    if (IS_DTLS(ss)) {
        return dtls_FlushHandshakeMessages(ss, flags);
    } else {
        return ssl3_FlushHandshakeMessages(ss, flags);
    }
}

/* Attempt to send the content of sendBuf buffer in an SSL handshake record.
 * This function returns SECSuccess or SECFailure, never SECWouldBlock.
 * Always set sendBuf.len to 0, even when returning SECFailure.
 *
 * Called from ssl3_FlushHandshake
 */
static SECStatus
ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
{
    static const PRInt32 allowedFlags = ssl_SEND_FLAG_FORCE_INTO_BUFFER |
                                        ssl_SEND_FLAG_CAP_RECORD_VERSION;
    PRInt32 rv = SECSuccess;

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

    if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len)
	return rv;

    /* only these flags are allowed */
    PORT_Assert(!(flags & ~allowedFlags));
    if ((flags & ~allowedFlags) != 0) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	rv = SECFailure;
    } else {
	rv = ssl3_SendRecord(ss, 0, content_handshake, ss->sec.ci.sendBuf.buf,
			     ss->sec.ci.sendBuf.len, flags);
    }
    if (rv < 0) { 
    	int err = PORT_GetError();
	PORT_Assert(err != PR_WOULD_BLOCK_ERROR);
	if (err == PR_WOULD_BLOCK_ERROR) {
	    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	}
    } else if (rv < ss->sec.ci.sendBuf.len) {
    	/* short write should never happen */
	PORT_Assert(rv >= ss->sec.ci.sendBuf.len);
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	rv = SECFailure;
    } else {
	rv = SECSuccess;
    }

    /* Whether we succeeded or failed, toss the old handshake data. */
    ss->sec.ci.sendBuf.len = 0;
    return rv;
}

/*
 * Called from ssl3_HandleAlert and from ssl3_HandleCertificate when
 * the remote client sends a negative response to our certificate request.
 * Returns SECFailure if the application has required client auth.
 *         SECSuccess otherwise.
 */
static SECStatus
ssl3_HandleNoCertificate(sslSocket *ss)
{
    if (ss->sec.peerCert != NULL) {
	if (ss->sec.peerKey != NULL) {
	    SECKEY_DestroyPublicKey(ss->sec.peerKey);
	    ss->sec.peerKey = NULL;
	}
	CERT_DestroyCertificate(ss->sec.peerCert);
	ss->sec.peerCert = NULL;
    }
    ssl3_CleanupPeerCerts(ss);

    /* If the server has required client-auth blindly but doesn't
     * actually look at the certificate it won't know that no
     * certificate was presented so we shutdown the socket to ensure
     * an error.  We only do this if we haven't already completed the
     * first handshake because if we're redoing the handshake we 
     * know the server is paying attention to the certificate.
     */
    if ((ss->opt.requireCertificate == SSL_REQUIRE_ALWAYS) ||
	(!ss->firstHsDone && 
	 (ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE))) {
	PRFileDesc * lower;

	if (ss->sec.uncache)
            ss->sec.uncache(ss->sec.ci.sid);
	SSL3_SendAlert(ss, alert_fatal, bad_certificate);

	lower = ss->fd->lower;
#ifdef _WIN32
	lower->methods->shutdown(lower, PR_SHUTDOWN_SEND);
#else
	lower->methods->shutdown(lower, PR_SHUTDOWN_BOTH);
#endif
	PORT_SetError(SSL_ERROR_NO_CERTIFICATE);
	return SECFailure;
    }
    return SECSuccess;
}

/************************************************************************
 * Alerts
 */

/*
** Acquires both handshake and XmitBuf locks.
** Called from: ssl3_IllegalParameter	<-
**              ssl3_HandshakeFailure	<-
**              ssl3_HandleAlert	<- ssl3_HandleRecord.
**              ssl3_HandleChangeCipherSpecs <- ssl3_HandleRecord
**              ssl3_ConsumeHandshakeVariable <-
**              ssl3_HandleHelloRequest	<-
**              ssl3_HandleServerHello	<-
**              ssl3_HandleServerKeyExchange <-
**              ssl3_HandleCertificateRequest <-
**              ssl3_HandleServerHelloDone <-
**              ssl3_HandleClientHello	<-
**              ssl3_HandleV2ClientHello <-
**              ssl3_HandleCertificateVerify <-
**              ssl3_HandleClientKeyExchange <-
**              ssl3_HandleCertificate	<-
**              ssl3_HandleFinished	<-
**              ssl3_HandleHandshakeMessage <-
**              ssl3_HandleRecord	<-
**
*/
SECStatus
SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc)
{
    PRUint8 	bytes[2];
    SECStatus	rv;

    SSL_TRC(3, ("%d: SSL3[%d]: send alert record, level=%d desc=%d",
		SSL_GETPID(), ss->fd, level, desc));

    bytes[0] = level;
    bytes[1] = desc;

    ssl_GetSSL3HandshakeLock(ss);
    if (level == alert_fatal) {
	if (!ss->opt.noCache && ss->sec.ci.sid && ss->sec.uncache) {
	    ss->sec.uncache(ss->sec.ci.sid);
	}
    }
    ssl_GetXmitBufLock(ss);
    rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
    if (rv == SECSuccess) {
	PRInt32 sent;
	sent = ssl3_SendRecord(ss, 0, content_alert, bytes, 2, 
			       desc == no_certificate 
			       ? ssl_SEND_FLAG_FORCE_INTO_BUFFER : 0);
	rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
    }
    ssl_ReleaseXmitBufLock(ss);
    ssl_ReleaseSSL3HandshakeLock(ss);
    return rv;	/* error set by ssl3_FlushHandshake or ssl3_SendRecord */
}

/*
 * Send illegal_parameter alert.  Set generic error number.
 */
static SECStatus
ssl3_IllegalParameter(sslSocket *ss)
{
    (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
    PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT
                                   : SSL_ERROR_BAD_SERVER );
    return SECFailure;
}

/*
 * Send handshake_Failure alert.  Set generic error number.
 */
static SECStatus
ssl3_HandshakeFailure(sslSocket *ss)
{
    (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
    PORT_SetError( ss->sec.isServer ? SSL_ERROR_BAD_CLIENT
                                    : SSL_ERROR_BAD_SERVER );
    return SECFailure;
}

static void
ssl3_SendAlertForCertError(sslSocket * ss, PRErrorCode errCode)
{
    SSL3AlertDescription desc	= bad_certificate;
    PRBool isTLS = ss->version >= SSL_LIBRARY_VERSION_3_1_TLS;

    switch (errCode) {
    case SEC_ERROR_LIBRARY_FAILURE:     desc = unsupported_certificate; break;
    case SEC_ERROR_EXPIRED_CERTIFICATE: desc = certificate_expired;     break;
    case SEC_ERROR_REVOKED_CERTIFICATE: desc = certificate_revoked;     break;
    case SEC_ERROR_INADEQUATE_KEY_USAGE:
    case SEC_ERROR_INADEQUATE_CERT_TYPE:
		                        desc = certificate_unknown;     break;
    case SEC_ERROR_UNTRUSTED_CERT:
		    desc = isTLS ? access_denied : certificate_unknown; break;
    case SEC_ERROR_UNKNOWN_ISSUER:      
    case SEC_ERROR_UNTRUSTED_ISSUER:    
		    desc = isTLS ? unknown_ca : certificate_unknown; break;
    case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
		    desc = isTLS ? unknown_ca : certificate_expired; break;

    case SEC_ERROR_CERT_NOT_IN_NAME_SPACE:
    case SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID:
    case SEC_ERROR_CA_CERT_INVALID:
    case SEC_ERROR_BAD_SIGNATURE:
    default:                            desc = bad_certificate;     break;
    }
    SSL_DBG(("%d: SSL3[%d]: peer certificate is no good: error=%d",
	     SSL_GETPID(), ss->fd, errCode));

    (void) SSL3_SendAlert(ss, alert_fatal, desc);
}


/*
 * Send decode_error alert.  Set generic error number.
 */
SECStatus
ssl3_DecodeError(sslSocket *ss)
{
    (void)SSL3_SendAlert(ss, alert_fatal, 
		  ss->version > SSL_LIBRARY_VERSION_3_0 ? decode_error 
							: illegal_parameter);
    PORT_SetError( ss->sec.isServer ? SSL_ERROR_BAD_CLIENT
                                    : SSL_ERROR_BAD_SERVER );
    return SECFailure;
}

/* Called from ssl3_HandleRecord.
** Caller must hold both RecvBuf and Handshake locks.
*/
static SECStatus
ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf)
{
    SSL3AlertLevel       level;
    SSL3AlertDescription desc;
    int                  error;

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

    SSL_TRC(3, ("%d: SSL3[%d]: handle alert record", SSL_GETPID(), ss->fd));

    if (buf->len != 2) {
	(void)ssl3_DecodeError(ss);
	PORT_SetError(SSL_ERROR_RX_MALFORMED_ALERT);
	return SECFailure;
    }
    level = (SSL3AlertLevel)buf->buf[0];
    desc  = (SSL3AlertDescription)buf->buf[1];
    buf->len = 0;
    SSL_TRC(5, ("%d: SSL3[%d] received alert, level = %d, description = %d",
        SSL_GETPID(), ss->fd, level, desc));

    switch (desc) {
    case close_notify:		ss->recvdCloseNotify = 1;
		        	error = SSL_ERROR_CLOSE_NOTIFY_ALERT;     break;
    case unexpected_message: 	error = SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT;
									  break;
    case bad_record_mac: 	error = SSL_ERROR_BAD_MAC_ALERT; 	  break;
    case decryption_failed_RESERVED:
                                error = SSL_ERROR_DECRYPTION_FAILED_ALERT; 
    									  break;
    case record_overflow: 	error = SSL_ERROR_RECORD_OVERFLOW_ALERT;  break;
    case decompression_failure: error = SSL_ERROR_DECOMPRESSION_FAILURE_ALERT;
									  break;
    case handshake_failure: 	error = SSL_ERROR_HANDSHAKE_FAILURE_ALERT;
			        					  break;
    case no_certificate: 	error = SSL_ERROR_NO_CERTIFICATE;	  break;
    case bad_certificate: 	error = SSL_ERROR_BAD_CERT_ALERT; 	  break;
    case unsupported_certificate:error = SSL_ERROR_UNSUPPORTED_CERT_ALERT;break;
    case certificate_revoked: 	error = SSL_ERROR_REVOKED_CERT_ALERT; 	  break;
    case certificate_expired: 	error = SSL_ERROR_EXPIRED_CERT_ALERT; 	  break;
    case certificate_unknown: 	error = SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT;
			        					  break;
    case illegal_parameter: 	error = SSL_ERROR_ILLEGAL_PARAMETER_ALERT;break;
    case inappropriate_fallback:
        error = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT;
        break;

    /* All alerts below are TLS only. */
    case unknown_ca: 		error = SSL_ERROR_UNKNOWN_CA_ALERT;       break;
    case access_denied: 	error = SSL_ERROR_ACCESS_DENIED_ALERT;    break;
    case decode_error: 		error = SSL_ERROR_DECODE_ERROR_ALERT;     break;
    case decrypt_error: 	error = SSL_ERROR_DECRYPT_ERROR_ALERT;    break;
    case export_restriction: 	error = SSL_ERROR_EXPORT_RESTRICTION_ALERT; 
    									  break;
    case protocol_version: 	error = SSL_ERROR_PROTOCOL_VERSION_ALERT; break;
    case insufficient_security: error = SSL_ERROR_INSUFFICIENT_SECURITY_ALERT; 
    									  break;
    case internal_error: 	error = SSL_ERROR_INTERNAL_ERROR_ALERT;   break;
    case user_canceled: 	error = SSL_ERROR_USER_CANCELED_ALERT;    break;
    case no_renegotiation: 	error = SSL_ERROR_NO_RENEGOTIATION_ALERT; break;

    /* Alerts for TLS client hello extensions */
    case unsupported_extension: 
			error = SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT;    break;
    case certificate_unobtainable: 
			error = SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT; break;
    case unrecognized_name: 
			error = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;        break;
    case bad_certificate_status_response: 
			error = SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT; break;
    case bad_certificate_hash_value: 
			error = SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT;      break;
    default: 		error = SSL_ERROR_RX_UNKNOWN_ALERT;               break;
    }
    if (level == alert_fatal) {
	if (!ss->opt.noCache) {
	    if (ss->sec.uncache)
                ss->sec.uncache(ss->sec.ci.sid);
	}
	if ((ss->ssl3.hs.ws == wait_server_hello) &&
	    (desc == handshake_failure)) {
	    /* XXX This is a hack.  We're assuming that any handshake failure
	     * XXX on the client hello is a failure to match ciphers.
	     */
	    error = SSL_ERROR_NO_CYPHER_OVERLAP;
	}
	PORT_SetError(error);
	return SECFailure;
    }
    if ((desc == no_certificate) && (ss->ssl3.hs.ws == wait_client_cert)) {
    	/* I'm a server. I've requested a client cert. He hasn't got one. */
	SECStatus rv;

	PORT_Assert(ss->sec.isServer);
	ss->ssl3.hs.ws = wait_client_key;
	rv = ssl3_HandleNoCertificate(ss);
	return rv;
    }
    return SECSuccess;
}

/*
 * Change Cipher Specs
 * Called from ssl3_HandleServerHelloDone,
 *             ssl3_HandleClientHello,
 * and         ssl3_HandleFinished
 *
 * Acquires and releases spec write lock, to protect switching the current
 * and pending write spec pointers.
 */

static SECStatus
ssl3_SendChangeCipherSpecs(sslSocket *ss)
{
    PRUint8           change = change_cipher_spec_choice;
    ssl3CipherSpec *  pwSpec;
    SECStatus         rv;
    PRInt32           sent;

    SSL_TRC(3, ("%d: SSL3[%d]: send change_cipher_spec record",
		SSL_GETPID(), ss->fd));

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

    rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
    if (rv != SECSuccess) {
	return rv;	/* error code set by ssl3_FlushHandshake */
    }
    if (!IS_DTLS(ss)) {
	sent = ssl3_SendRecord(ss, 0, content_change_cipher_spec, &change, 1,
			       ssl_SEND_FLAG_FORCE_INTO_BUFFER);
	if (sent < 0) {
	    return (SECStatus)sent;	/* error code set by ssl3_SendRecord */
	}
    } else {
	rv = dtls_QueueMessage(ss, content_change_cipher_spec, &change, 1);
	if (rv != SECSuccess) {
	    return rv;
	}
    }

    /* swap the pending and current write specs. */
    ssl_GetSpecWriteLock(ss);	/**************************************/
    pwSpec                     = ss->ssl3.pwSpec;

    ss->ssl3.pwSpec = ss->ssl3.cwSpec;
    ss->ssl3.cwSpec = pwSpec;

    SSL_TRC(3, ("%d: SSL3[%d] Set Current Write Cipher Suite to Pending",
		SSL_GETPID(), ss->fd ));

    /* We need to free up the contexts, keys and certs ! */
    /* If we are really through with the old cipher spec
     * (Both the read and write sides have changed) destroy it.
     */
    if (ss->ssl3.prSpec == ss->ssl3.pwSpec) {
	if (!IS_DTLS(ss)) {
	    ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE/*freeSrvName*/);
	} else {
	    /* With DTLS, we need to set a holddown timer in case the final
	     * message got lost */
	    ss->ssl3.hs.rtTimeoutMs = DTLS_FINISHED_TIMER_MS;
	    dtls_StartTimer(ss, dtls_FinishedTimerCb);
	}
    }
    ssl_ReleaseSpecWriteLock(ss); /**************************************/

    return SECSuccess;
}

/* Called from ssl3_HandleRecord.
** Caller must hold both RecvBuf and Handshake locks.
 *
 * Acquires and releases spec write lock, to protect switching the current
 * and pending write spec pointers.
*/
static SECStatus
ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf)
{
    ssl3CipherSpec *           prSpec;
    SSL3WaitState              ws      = ss->ssl3.hs.ws;
    SSL3ChangeCipherSpecChoice change;

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

    SSL_TRC(3, ("%d: SSL3[%d]: handle change_cipher_spec record",
		SSL_GETPID(), ss->fd));

    if (ws != wait_change_cipher) {
	if (IS_DTLS(ss)) {
	    /* Ignore this because it's out of order. */
	    SSL_TRC(3, ("%d: SSL3[%d]: discard out of order "
			"DTLS change_cipher_spec",
			SSL_GETPID(), ss->fd));
	    buf->len = 0;
	    return SECSuccess;
	}
	(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
	return SECFailure;
    }

    if(buf->len != 1) {
	(void)ssl3_DecodeError(ss);
	PORT_SetError(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER);
	return SECFailure;
    }
    change = (SSL3ChangeCipherSpecChoice)buf->buf[0];
    if (change != change_cipher_spec_choice) {
	/* illegal_parameter is correct here for both SSL3 and TLS. */
	(void)ssl3_IllegalParameter(ss);
	PORT_SetError(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER);
	return SECFailure;
    }
    buf->len = 0;

    /* Swap the pending and current read specs. */
    ssl_GetSpecWriteLock(ss);   /*************************************/
    prSpec                    = ss->ssl3.prSpec;

    ss->ssl3.prSpec  = ss->ssl3.crSpec;
    ss->ssl3.crSpec  = prSpec;
    ss->ssl3.hs.ws   = wait_finished;

    SSL_TRC(3, ("%d: SSL3[%d] Set Current Read Cipher Suite to Pending",
		SSL_GETPID(), ss->fd ));

    /* If we are really through with the old cipher prSpec
     * (Both the read and write sides have changed) destroy it.
     */
    if (ss->ssl3.prSpec == ss->ssl3.pwSpec) {
    	ssl3_DestroyCipherSpec(ss->ssl3.prSpec, PR_FALSE/*freeSrvName*/);
    }
    ssl_ReleaseSpecWriteLock(ss);   /*************************************/
    return SECSuccess;
}

/* This method uses PKCS11 to derive the MS from the PMS, where PMS 
** is a PKCS11 symkey. This is used in all cases except the 
** "triple bypass" with RSA key exchange.
** Called from ssl3_InitPendingCipherSpec.   prSpec is pwSpec.
*/
static SECStatus
ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
{
    ssl3CipherSpec *  pwSpec = ss->ssl3.pwSpec;
    const ssl3KEADef *kea_def= ss->ssl3.hs.kea_def;
    unsigned char *   cr     = (unsigned char *)&ss->ssl3.hs.client_random;
    unsigned char *   sr     = (unsigned char *)&ss->ssl3.hs.server_random;
    PRBool            isTLS  = (PRBool)(kea_def->tls_keygen ||
                                (pwSpec->version > SSL_LIBRARY_VERSION_3_0));
    PRBool            isTLS12=
	    (PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
    /* 
     * Whenever isDH is true, we need to use CKM_TLS_MASTER_KEY_DERIVE_DH
     * which, unlike CKM_TLS_MASTER_KEY_DERIVE, converts arbitrary size
     * data into a 48-byte value. 
     */
    PRBool    isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dh) ||
	                       (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh));
    SECStatus         rv = SECFailure;
    CK_MECHANISM_TYPE master_derive;
    CK_MECHANISM_TYPE key_derive;
    SECItem           params;
    CK_FLAGS          keyFlags;
    CK_VERSION        pms_version;
    CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params;

    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
    PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
    if (isTLS12) {
	if(isDH) master_derive = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256;
	else master_derive = CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256;
	key_derive    = CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256;
	keyFlags      = CKF_SIGN | CKF_VERIFY;
    } else if (isTLS) {
	if(isDH) master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH;
	else master_derive = CKM_TLS_MASTER_KEY_DERIVE;
	key_derive    = CKM_TLS_KEY_AND_MAC_DERIVE;
	keyFlags      = CKF_SIGN | CKF_VERIFY;
    } else {
	if (isDH) master_derive = CKM_SSL3_MASTER_KEY_DERIVE_DH;
	else master_derive = CKM_SSL3_MASTER_KEY_DERIVE;
	key_derive    = CKM_SSL3_KEY_AND_MAC_DERIVE;
	keyFlags      = 0;
    }

    if (pms || !pwSpec->master_secret) {
	if (isDH) {
	    master_params.pVersion                     = NULL;
	} else {
	    master_params.pVersion                     = &pms_version;
	}
	master_params.RandomInfo.pClientRandom     = cr;
	master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
	master_params.RandomInfo.pServerRandom     = sr;
	master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;

	params.data = (unsigned char *) &master_params;
	params.len  = sizeof master_params;
    }

    if (pms != NULL) {
#if defined(TRACE)
	if (ssl_trace >= 100) {
	    SECStatus extractRV = PK11_ExtractKeyValue(pms);
	    if (extractRV == SECSuccess) {
		SECItem * keyData = PK11_GetKeyData(pms);
		if (keyData && keyData->data && keyData->len) {
		    ssl_PrintBuf(ss, "Pre-Master Secret", 
				 keyData->data, keyData->len);
		}
	    }
	}
#endif
	pwSpec->master_secret = PK11_DeriveWithFlags(pms, master_derive, 
				&params, key_derive, CKA_DERIVE, 0, keyFlags);
	if (!isDH && pwSpec->master_secret && ss->opt.detectRollBack) {
	    SSL3ProtocolVersion client_version;
	    client_version = pms_version.major << 8 | pms_version.minor;

	    if (IS_DTLS(ss)) {
		client_version = dtls_DTLSVersionToTLSVersion(client_version);
	    }

	    if (client_version != ss->clientHelloVersion) {
		/* Destroy it.  Version roll-back detected. */
		PK11_FreeSymKey(pwSpec->master_secret);
	    	pwSpec->master_secret = NULL;
	    }
	}
	if (pwSpec->master_secret == NULL) {
	    /* Generate a faux master secret in the same slot as the old one. */
	    PK11SlotInfo * slot = PK11_GetSlotFromKey((PK11SymKey *)pms);
	    PK11SymKey *   fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot);

	    PK11_FreeSlot(slot);
	    if (fpms != NULL) {
		pwSpec->master_secret = PK11_DeriveWithFlags(fpms, 
					master_derive, &params, key_derive, 
					CKA_DERIVE, 0, keyFlags);
		PK11_FreeSymKey(fpms);
	    }
	}
    }
    if (pwSpec->master_secret == NULL) {
	/* Generate a faux master secret from the internal slot. */
	PK11SlotInfo *  slot = PK11_GetInternalSlot();
	PK11SymKey *    fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot);

	PK11_FreeSlot(slot);
	if (fpms != NULL) {
	    pwSpec->master_secret = PK11_DeriveWithFlags(fpms, 
					master_derive, &params, key_derive, 
					CKA_DERIVE, 0, keyFlags);
	    if (pwSpec->master_secret == NULL) {
	    	pwSpec->master_secret = fpms; /* use the fpms as the master. */
		fpms = NULL;
	    }
	}
	if (fpms) {
	    PK11_FreeSymKey(fpms);
    	}
    }
    if (pwSpec->master_secret == NULL) {
	ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
	return rv;
    }
#ifndef NO_PKCS11_BYPASS
    if (ss->opt.bypassPKCS11) {
	SECItem * keydata;
	/* In hope of doing a "double bypass", 
	 * need to extract the master secret's value from the key object 
	 * and store it raw in the sslSocket struct.
	 */
	rv = PK11_ExtractKeyValue(pwSpec->master_secret);
	if (rv != SECSuccess) {
	    return rv;
	} 
	/* This returns the address of the secItem inside the key struct,
	 * not a copy or a reference.  So, there's no need to free it.
	 */
	keydata = PK11_GetKeyData(pwSpec->master_secret);
	if (keydata && keydata->len <= sizeof pwSpec->raw_master_secret) {
	    memcpy(pwSpec->raw_master_secret, keydata->data, keydata->len);
	    pwSpec->msItem.data = pwSpec->raw_master_secret;
	    pwSpec->msItem.len  = keydata->len;
	} else {
	    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	    return SECFailure;
	}
    }
#endif
    return SECSuccess;
}


/* 
 * Derive encryption and MAC Keys (and IVs) from master secret
 * Sets a useful error code when returning SECFailure.
 *
 * Called only from ssl3_InitPendingCipherSpec(),
 * which in turn is called from
 *              sendRSAClientKeyExchange        (for Full handshake)
 *              sendDHClientKeyExchange         (for Full handshake)
 *              ssl3_HandleClientKeyExchange    (for Full handshake)
 *              ssl3_HandleServerHello          (for session restart)
 *              ssl3_HandleClientHello          (for session restart)
 * Caller MUST hold the specWriteLock, and SSL3HandshakeLock.
 * ssl3_InitPendingCipherSpec does that.
 *
 */
static SECStatus
ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss)
{
    ssl3CipherSpec *         pwSpec     = ss->ssl3.pwSpec;
    const ssl3KEADef *       kea_def    = ss->ssl3.hs.kea_def;
    unsigned char *   cr     = (unsigned char *)&ss->ssl3.hs.client_random;
    unsigned char *   sr     = (unsigned char *)&ss->ssl3.hs.server_random;
    PRBool            isTLS  = (PRBool)(kea_def->tls_keygen ||
                                (pwSpec->version > SSL_LIBRARY_VERSION_3_0));
    PRBool            isTLS12=
	    (PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
    /* following variables used in PKCS11 path */
    const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def;
    PK11SlotInfo *         slot   = NULL;
    PK11SymKey *           symKey = NULL;
    void *                 pwArg  = ss->pkcs11PinArg;
    int                    keySize;
    CK_SSL3_KEY_MAT_PARAMS key_material_params;
    CK_SSL3_KEY_MAT_OUT    returnedKeys;
    CK_MECHANISM_TYPE      key_derive;
    CK_MECHANISM_TYPE      bulk_mechanism;
    SSLCipherAlgorithm     calg;
    SECItem                params;
    PRBool         skipKeysAndIVs = (PRBool)(cipher_def->calg == calg_null);

    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
    PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);

    if (!pwSpec->master_secret) {
	PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
	return SECFailure;
    }
    /*
     * generate the key material
     */
    key_material_params.ulMacSizeInBits = pwSpec->mac_size           * BPB;
    key_material_params.ulKeySizeInBits = cipher_def->secret_key_size* BPB;
    key_material_params.ulIVSizeInBits  = cipher_def->iv_size        * BPB;
    if (cipher_def->type == type_block &&
	pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
	/* Block ciphers in >= TLS 1.1 use a per-record, explicit IV. */
	key_material_params.ulIVSizeInBits = 0;
	memset(pwSpec->client.write_iv, 0, cipher_def->iv_size);
	memset(pwSpec->server.write_iv, 0, cipher_def->iv_size);
    }

    key_material_params.bIsExport = (CK_BBOOL)(kea_def->is_limited);

    key_material_params.RandomInfo.pClientRandom     = cr;
    key_material_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
    key_material_params.RandomInfo.pServerRandom     = sr;
    key_material_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;
    key_material_params.pReturnedKeyMaterial         = &returnedKeys;

    returnedKeys.pIVClient = pwSpec->client.write_iv;
    returnedKeys.pIVServer = pwSpec->server.write_iv;
    keySize                = cipher_def->key_size;

    if (skipKeysAndIVs) {
	keySize                             = 0;
        key_material_params.ulKeySizeInBits = 0;
        key_material_params.ulIVSizeInBits  = 0;
    	returnedKeys.pIVClient              = NULL;
    	returnedKeys.pIVServer              = NULL;
    }

    calg = cipher_def->calg;
    PORT_Assert(     alg2Mech[calg].calg == calg);
    bulk_mechanism = alg2Mech[calg].cmech;

    params.data    = (unsigned char *)&key_material_params;
    params.len     = sizeof(key_material_params);

    if (isTLS12) {
	key_derive    = CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256;
    } else if (isTLS) {
	key_derive    = CKM_TLS_KEY_AND_MAC_DERIVE;
    } else {
	key_derive    = CKM_SSL3_KEY_AND_MAC_DERIVE;
    }

    /* CKM_SSL3_KEY_AND_MAC_DERIVE is defined to set ENCRYPT, DECRYPT, and
     * DERIVE by DEFAULT */
    symKey = PK11_Derive(pwSpec->master_secret, key_derive, &params,
                         bulk_mechanism, CKA_ENCRYPT, keySize);
    if (!symKey) {
	ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
	return SECFailure;
    }
    /* we really should use the actual mac'ing mechanism here, but we
     * don't because these types are used to map keytype anyway and both
     * mac's map to the same keytype.
     */
    slot  = PK11_GetSlotFromKey(symKey);

    PK11_FreeSlot(slot); /* slot is held until the key is freed */
    pwSpec->client.write_mac_key =
    	PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
	    CKM_SSL3_SHA1_MAC, returnedKeys.hClientMacSecret, PR_TRUE, pwArg);
    if (pwSpec->client.write_mac_key == NULL ) {
	goto loser;	/* loser sets err */
    }
    pwSpec->server.write_mac_key =
    	PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
	    CKM_SSL3_SHA1_MAC, returnedKeys.hServerMacSecret, PR_TRUE, pwArg);
    if (pwSpec->server.write_mac_key == NULL ) {
	goto loser;	/* loser sets err */
    }
    if (!skipKeysAndIVs) {
	pwSpec->client.write_key =
		PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
		     bulk_mechanism, returnedKeys.hClientKey, PR_TRUE, pwArg);
	if (pwSpec->client.write_key == NULL ) {
	    goto loser;	/* loser sets err */
	}
	pwSpec->server.write_key =
		PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
		     bulk_mechanism, returnedKeys.hServerKey, PR_TRUE, pwArg);
	if (pwSpec->server.write_key == NULL ) {
	    goto loser;	/* loser sets err */
	}
    }
    PK11_FreeSymKey(symKey);
    return SECSuccess;


loser:
    if (symKey) PK11_FreeSymKey(symKey);
    ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
    return SECFailure;
}

/* ssl3_InitHandshakeHashes creates handshake hash contexts and hashes in
 * buffered messages in ss->ssl3.hs.messages. */
static SECStatus
ssl3_InitHandshakeHashes(sslSocket *ss)
{
    SSL_TRC(30,("%d: SSL3[%d]: start handshake hashes", SSL_GETPID(), ss->fd));

    PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_unknown);
#ifndef NO_PKCS11_BYPASS
    if (ss->opt.bypassPKCS11) {
	PORT_Assert(!ss->ssl3.hs.sha_obj && !ss->ssl3.hs.sha_clone);
	if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
	    /* If we ever support ciphersuites where the PRF hash isn't SHA-256
	     * then this will need to be updated. */
	    ss->ssl3.hs.sha_obj = HASH_GetRawHashObject(HASH_AlgSHA256);
	    if (!ss->ssl3.hs.sha_obj) {
		ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
		return SECFailure;
	    }
	    ss->ssl3.hs.sha_clone = (void (*)(void *, void *))SHA256_Clone;
	    ss->ssl3.hs.hashType = handshake_hash_single;
	    ss->ssl3.hs.sha_obj->begin(ss->ssl3.hs.sha_cx);
	} else {
	    ss->ssl3.hs.hashType = handshake_hash_combo;
	    MD5_Begin((MD5Context *)ss->ssl3.hs.md5_cx);
	    SHA1_Begin((SHA1Context *)ss->ssl3.hs.sha_cx);
	}
    } else
#endif
    {
	PORT_Assert(!ss->ssl3.hs.md5 && !ss->ssl3.hs.sha);
	/*
	 * note: We should probably lookup an SSL3 slot for these
	 * handshake hashes in hopes that we wind up with the same slots
	 * that the master secret will wind up in ...
	 */
	if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
	    /* If we ever support ciphersuites where the PRF hash isn't SHA-256
	     * then this will need to be updated. */
	    ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA256);
	    if (ss->ssl3.hs.sha == NULL) {
		ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
		return SECFailure;
	    }
	    ss->ssl3.hs.hashType = handshake_hash_single;

	    if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) {
		ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
		return SECFailure;
	    }

	    /* Create a backup SHA-1 hash for a potential client auth
	     * signature.
	     *
	     * In TLS 1.2, ssl3_ComputeHandshakeHashes always uses the
	     * handshake hash function (SHA-256). If the server or the client
	     * does not support SHA-256 as a signature hash, we can either
	     * maintain a backup SHA-1 handshake hash or buffer all handshake
	     * messages.
	     */
	    if (!ss->sec.isServer) {
		ss->ssl3.hs.backupHash = PK11_CreateDigestContext(SEC_OID_SHA1);
		if (ss->ssl3.hs.backupHash == NULL) {
		    ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
		    return SECFailure;
		}

		if (PK11_DigestBegin(ss->ssl3.hs.backupHash) != SECSuccess) {
		    ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
		    return SECFailure;
		}
	    }
	} else {
	    /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or
	     * created successfully. */
	    ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_MD5);
	    if (ss->ssl3.hs.md5 == NULL) {
		ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
		return SECFailure;
	    }
	    ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA1);
	    if (ss->ssl3.hs.sha == NULL) {
		PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
		ss->ssl3.hs.md5 = NULL;
		ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
		return SECFailure;
	    }
	    ss->ssl3.hs.hashType = handshake_hash_combo;

	    if (PK11_DigestBegin(ss->ssl3.hs.md5) != SECSuccess) {
		ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
		return SECFailure;
	    }
	    if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) {
		ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
		return SECFailure;
	    }
	}
    }

    if (ss->ssl3.hs.messages.len > 0) {
	if (ssl3_UpdateHandshakeHashes(ss, ss->ssl3.hs.messages.buf,
				       ss->ssl3.hs.messages.len) !=
	    SECSuccess) {
	    return SECFailure;
	}
	PORT_Free(ss->ssl3.hs.messages.buf);
	ss->ssl3.hs.messages.buf = NULL;
	ss->ssl3.hs.messages.len = 0;
	ss->ssl3.hs.messages.space = 0;
    }

    return SECSuccess;
}

static SECStatus 
ssl3_RestartHandshakeHashes(sslSocket *ss)
{
    SECStatus rv = SECSuccess;

    SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes",
	    SSL_GETPID(), ss->fd ));
    ss->ssl3.hs.hashType = handshake_hash_unknown;
    ss->ssl3.hs.messages.len = 0;
#ifndef NO_PKCS11_BYPASS
    ss->ssl3.hs.sha_obj = NULL;
    ss->ssl3.hs.sha_clone = NULL;
#endif
    if (ss->ssl3.hs.md5) {
	PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE);
	ss->ssl3.hs.md5 = NULL;
    }
    if (ss->ssl3.hs.sha) {
	PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE);
	ss->ssl3.hs.sha = NULL;
    }
    return rv;
}

/*
 * Handshake messages
 */
/* Called from	ssl3_InitHandshakeHashes()
**		ssl3_AppendHandshake()
**		ssl3_StartHandshakeHash()
**		ssl3_HandleV2ClientHello()
**		ssl3_HandleHandshakeMessage()
** Caller must hold the ssl3Handshake lock.
*/
static SECStatus
ssl3_UpdateHandshakeHashes(sslSocket *ss, const unsigned char *b,
			   unsigned int l)
{
    SECStatus  rv = SECSuccess;

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

    /* We need to buffer the handshake messages until we have established
     * which handshake hash function to use. */
    if (ss->ssl3.hs.hashType == handshake_hash_unknown) {
	return sslBuffer_Append(&ss->ssl3.hs.messages, b, l);
    }

    PRINT_BUF(90, (NULL, "handshake hash input:", b, l));

#ifndef NO_PKCS11_BYPASS
    if (ss->opt.bypassPKCS11) {
	if (ss->ssl3.hs.hashType == handshake_hash_single) {
	    ss->ssl3.hs.sha_obj->update(ss->ssl3.hs.sha_cx, b, l);
	} else {
	    MD5_Update((MD5Context *)ss->ssl3.hs.md5_cx, b, l);
	    SHA1_Update((SHA1Context *)ss->ssl3.hs.sha_cx, b, l);
	}
	return rv;
    }
#endif
    if (ss->ssl3.hs.hashType == handshake_hash_single) {
	rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l);
	if (rv != SECSuccess) {
	    ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
	    return rv;
	}
	if (ss->ssl3.hs.backupHash) {
	    rv = PK11_DigestOp(ss->ssl3.hs.backupHash, b, l);
	    if (rv != SECSuccess) {
		ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
		return rv;
	    }
	}
    } else {
	rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
	if (rv != SECSuccess) {
	    ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
	    return rv;
	}
	rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l);
	if (rv != SECSuccess) {
	    ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
	    return rv;
	}
    }
    return rv;
}

/**************************************************************************
 * Append Handshake functions.
 * All these functions set appropriate error codes.
 * Most rely on ssl3_AppendHandshake to set the error code.
 **************************************************************************/
SECStatus
ssl3_AppendHandshake(sslSocket *ss, const void *void_src, PRInt32 bytes)
{
    unsigned char *  src  = (unsigned char *)void_src;
    int              room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len;
    SECStatus        rv;

    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); /* protects sendBuf. */

    if (!bytes)
    	return SECSuccess;
    if (ss->sec.ci.sendBuf.space < MAX_SEND_BUF_LENGTH && room < bytes) {
	rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, PR_MAX(MIN_SEND_BUF_LENGTH,
		 PR_MIN(MAX_SEND_BUF_LENGTH, ss->sec.ci.sendBuf.len + bytes)));
	if (rv != SECSuccess)
	    return rv;	/* sslBuffer_Grow has set a memory error code. */
	room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len;
    }

    PRINT_BUF(60, (ss, "Append to Handshake", (unsigned char*)void_src, bytes));
    rv = ssl3_UpdateHandshakeHashes(ss, src, bytes);
    if (rv != SECSuccess)
	return rv;	/* error code set by ssl3_UpdateHandshakeHashes */

    while (bytes > room) {
	if (room > 0)
	    PORT_Memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src, 
	                room);
	ss->sec.ci.sendBuf.len += room;
	rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
	if (rv != SECSuccess) {
	    return rv;	/* error code set by ssl3_FlushHandshake */
	}
	bytes -= room;
	src += room;
	room = ss->sec.ci.sendBuf.space;
	PORT_Assert(ss->sec.ci.sendBuf.len == 0);
    }
    PORT_Memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src, bytes);
    ss->sec.ci.sendBuf.len += bytes;
    return SECSuccess;
}

SECStatus
ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, PRInt32 lenSize)
{
    SECStatus rv;
    PRUint8   b[4];
    PRUint8 * p = b;

    switch (lenSize) {
      case 4:
	*p++ = (num >> 24) & 0xff;
      case 3:
	*p++ = (num >> 16) & 0xff;
      case 2:
	*p++ = (num >> 8) & 0xff;
      case 1:
	*p = num & 0xff;
    }
    SSL_TRC(60, ("%d: number:", SSL_GETPID()));
    rv = ssl3_AppendHandshake(ss, &b[0], lenSize);
    return rv;	/* error code set by AppendHandshake, if applicable. */
}

SECStatus
ssl3_AppendHandshakeVariable(
    sslSocket *ss, const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize)
{
    SECStatus rv;

    PORT_Assert((bytes < (1<<8) && lenSize == 1) ||
	      (bytes < (1L<<16) && lenSize == 2) ||
	      (bytes < (1L<<24) && lenSize == 3));

    SSL_TRC(60,("%d: append variable:", SSL_GETPID()));
    rv = ssl3_AppendHandshakeNumber(ss, bytes, lenSize);
    if (rv != SECSuccess) {
	return rv;	/* error code set by AppendHandshake, if applicable. */
    }
    SSL_TRC(60, ("data:"));
    rv = ssl3_AppendHandshake(ss, src, bytes);
    return rv;	/* error code set by AppendHandshake, if applicable. */
}

SECStatus
ssl3_AppendHandshakeHeader(sslSocket *ss, SSL3HandshakeType t, PRUint32 length)
{
    SECStatus rv;

    /* If we already have a message in place, we need to enqueue it.
     * This empties the buffer. This is a convenient place to call
     * dtls_StageHandshakeMessage to mark the message boundary.
     */
    if (IS_DTLS(ss)) {
	rv = dtls_StageHandshakeMessage(ss);
	if (rv != SECSuccess) {
	    return rv;
	}
    }

    SSL_TRC(30,("%d: SSL3[%d]: append handshake header: type %s",
    	SSL_GETPID(), ss->fd, ssl3_DecodeHandshakeType(t)));

    rv = ssl3_AppendHandshakeNumber(ss, t, 1);
    if (rv != SECSuccess) {
    	return rv;	/* error code set by AppendHandshake, if applicable. */
    }
    rv = ssl3_AppendHandshakeNumber(ss, length, 3);
    if (rv != SECSuccess) {
    	return rv;	/* error code set by AppendHandshake, if applicable. */
    }

    if (IS_DTLS(ss)) {
	/* Note that we make an unfragmented message here. We fragment in the
	 * transmission code, if necessary */
	rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.sendMessageSeq, 2);
	if (rv != SECSuccess) {
	    return rv;	/* error code set by AppendHandshake, if applicable. */
	}
	ss->ssl3.hs.sendMessageSeq++;

	/* 0 is the fragment offset, because it's not fragmented yet */
	rv = ssl3_AppendHandshakeNumber(ss, 0, 3);
	if (rv != SECSuccess) {
	    return rv;	/* error code set by AppendHandshake, if applicable. */
	}

	/* Fragment length -- set to the packet length because not fragmented */
	rv = ssl3_AppendHandshakeNumber(ss, length, 3);
	if (rv != SECSuccess) {
	    return rv;	/* error code set by AppendHandshake, if applicable. */
	}
    }

    return rv;		/* error code set by AppendHandshake, if applicable. */
}

/* ssl3_AppendSignatureAndHashAlgorithm appends the serialisation of
 * |sigAndHash| to the current handshake message. */
SECStatus
ssl3_AppendSignatureAndHashAlgorithm(
	sslSocket *ss, const SSL3SignatureAndHashAlgorithm* sigAndHash)
{
    unsigned char serialized[2];

    serialized[0] = ssl3_OIDToTLSHashAlgorithm(sigAndHash->hashAlg);
    if (serialized[0] == 0) {
	PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
	return SECFailure;
    }

    serialized[1] = sigAndHash->sigAlg;

    return ssl3_AppendHandshake(ss, serialized, sizeof(serialized));
}

/**************************************************************************
 * Consume Handshake functions.
 *
 * All data used in these functions is protected by two locks,
 * the RecvBufLock and the SSL3HandshakeLock
 **************************************************************************/

/* Read up the next "bytes" number of bytes from the (decrypted) input
 * stream "b" (which is *length bytes long). Copy them into buffer "v".
 * Reduces *length by bytes.  Advances *b by bytes.
 *
 * If this function returns SECFailure, it has already sent an alert,
 * and has set a generic error code.  The caller should probably
 * override the generic error code by setting another.
 */
SECStatus
ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b,
		      PRUint32 *length)
{
    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );

    if ((PRUint32)bytes > *length) {
	return ssl3_DecodeError(ss);
    }
    PORT_Memcpy(v, *b, bytes);
    PRINT_BUF(60, (ss, "consume bytes:", *b, bytes));
    *b      += bytes;
    *length -= bytes;
    return SECSuccess;
}

/* Read up the next "bytes" number of bytes from the (decrypted) input
 * stream "b" (which is *length bytes long), and interpret them as an
 * integer in network byte order.  Returns the received value.
 * Reduces *length by bytes.  Advances *b by bytes.
 *
 * Returns SECFailure (-1) on failure.
 * This value is indistinguishable from the equivalent received value.
 * Only positive numbers are to be received this way.
 * Thus, the largest value that may be sent this way is 0x7fffffff.
 * On error, an alert has been sent, and a generic error code has been set.
 */
PRInt32
ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, SSL3Opaque **b,
			    PRUint32 *length)
{
    PRUint8  *buf = *b;
    int       i;
    PRInt32   num = 0;

    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
    PORT_Assert( bytes <= sizeof num);

    if ((PRUint32)bytes > *length) {
	return ssl3_DecodeError(ss);
    }
    PRINT_BUF(60, (ss, "consume bytes:", *b, bytes));

    for (i = 0; i < bytes; i++)
	num = (num << 8) + buf[i];
    *b      += bytes;
    *length -= bytes;
    return num;
}

/* Read in two values from the incoming decrypted byte stream "b", which is
 * *length bytes long.  The first value is a number whose size is "bytes"
 * bytes long.  The second value is a byte-string whose size is the value
 * of the first number received.  The latter byte-string, and its length,
 * is returned in the SECItem i.
 *
 * Returns SECFailure (-1) on failure.
 * On error, an alert has been sent, and a generic error code has been set.
 *
 * RADICAL CHANGE for NSS 3.11.  All callers of this function make copies 
 * of the data returned in the SECItem *i, so making a copy of it here
 * is simply wasteful.  So, This function now just sets SECItem *i to 
 * point to the values in the buffer **b.
 */
SECStatus
ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes,
			      SSL3Opaque **b, PRUint32 *length)
{
    PRInt32   count;

    PORT_Assert(bytes <= 3);
    i->len  = 0;
    i->data = NULL;
    count = ssl3_ConsumeHandshakeNumber(ss, bytes, b, length);
    if (count < 0) { 		/* Can't test for SECSuccess here. */
    	return SECFailure;
    }
    if (count > 0) {
	if ((PRUint32)count > *length) {
	    return ssl3_DecodeError(ss);
	}
	i->data = *b;
	i->len  = count;
	*b      += count;
	*length -= count;
    }
    return SECSuccess;
}

/* tlsHashOIDMap contains the mapping between TLS hash identifiers and the
 * SECOidTag used internally by NSS. */
static const struct {
    int tlsHash;
    SECOidTag oid;
} tlsHashOIDMap[] = {
    { tls_hash_md5, SEC_OID_MD5 },
    { tls_hash_sha1, SEC_OID_SHA1 },
    { tls_hash_sha224, SEC_OID_SHA224 },
    { tls_hash_sha256, SEC_OID_SHA256 },
    { tls_hash_sha384, SEC_OID_SHA384 },
    { tls_hash_sha512, SEC_OID_SHA512 }
};

/* ssl3_TLSHashAlgorithmToOID converts a TLS hash identifier into an OID value.
 * If the hash is not recognised, SEC_OID_UNKNOWN is returned.
 *
 * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
SECOidTag
ssl3_TLSHashAlgorithmToOID(int hashFunc)
{
    unsigned int i;

    for (i = 0; i < PR_ARRAY_SIZE(tlsHashOIDMap); i++) {
	if (hashFunc == tlsHashOIDMap[i].tlsHash) {
	    return tlsHashOIDMap[i].oid;
	}
    }
    return SEC_OID_UNKNOWN;
}

/* ssl3_OIDToTLSHashAlgorithm converts an OID to a TLS hash algorithm
 * identifier. If the hash is not recognised, zero is returned.
 *
 * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
static int
ssl3_OIDToTLSHashAlgorithm(SECOidTag oid)
{
    unsigned int i;

    for (i = 0; i < PR_ARRAY_SIZE(tlsHashOIDMap); i++) {
	if (oid == tlsHashOIDMap[i].oid) {
	    return tlsHashOIDMap[i].tlsHash;
	}
    }
    return 0;
}

/* ssl3_TLSSignatureAlgorithmForKeyType returns the TLS 1.2 signature algorithm
 * identifier for a given KeyType. */
static SECStatus
ssl3_TLSSignatureAlgorithmForKeyType(KeyType keyType,
				     TLSSignatureAlgorithm *out)
{
    switch (keyType) {
    case rsaKey:
	*out = tls_sig_rsa;
	return SECSuccess;
    case dsaKey:
	*out = tls_sig_dsa;
	return SECSuccess;
    case ecKey:
	*out = tls_sig_ecdsa;
	return SECSuccess;
    default:
	PORT_SetError(SEC_ERROR_INVALID_KEY);
	return SECFailure;
    }
}

/* ssl3_TLSSignatureAlgorithmForCertificate returns the TLS 1.2 signature
 * algorithm identifier for the given certificate. */
static SECStatus
ssl3_TLSSignatureAlgorithmForCertificate(CERTCertificate *cert,
					 TLSSignatureAlgorithm *out)
{
    SECKEYPublicKey *key;
    KeyType keyType;

    key = CERT_ExtractPublicKey(cert);
    if (key == NULL) {
	ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
    	return SECFailure;
    }

    keyType = key->keyType;
    SECKEY_DestroyPublicKey(key);
    return ssl3_TLSSignatureAlgorithmForKeyType(keyType, out);
}

/* ssl3_CheckSignatureAndHashAlgorithmConsistency checks that the signature
 * algorithm identifier in |sigAndHash| is consistent with the public key in
 * |cert|. If so, SECSuccess is returned. Otherwise, PORT_SetError is called
 * and SECFailure is returned. */
SECStatus
ssl3_CheckSignatureAndHashAlgorithmConsistency(
	const SSL3SignatureAndHashAlgorithm *sigAndHash, CERTCertificate* cert)
{
    SECStatus rv;
    TLSSignatureAlgorithm sigAlg;

    rv = ssl3_TLSSignatureAlgorithmForCertificate(cert, &sigAlg);
    if (rv != SECSuccess) {
	return rv;
    }
    if (sigAlg != sigAndHash->sigAlg) {
	PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
	return SECFailure;
    }
    return SECSuccess;
}

/* ssl3_ConsumeSignatureAndHashAlgorithm reads a SignatureAndHashAlgorithm
 * structure from |b| and puts the resulting value into |out|. |b| and |length|
 * are updated accordingly.
 *
 * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
SECStatus
ssl3_ConsumeSignatureAndHashAlgorithm(sslSocket *ss,
				      SSL3Opaque **b,
				      PRUint32 *length,
				      SSL3SignatureAndHashAlgorithm *out)
{
    unsigned char bytes[2];
    SECStatus rv;

    rv = ssl3_ConsumeHandshake(ss, bytes, sizeof(bytes), b, length);
    if (rv != SECSuccess) {
	return rv;
    }

    out->hashAlg = ssl3_TLSHashAlgorithmToOID(bytes[0]);
    if (out->hashAlg == SEC_OID_UNKNOWN) {
	PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
	return SECFailure;
    }

    out->sigAlg = bytes[1];
    return SECSuccess;
}

/**************************************************************************
 * end of Consume Handshake functions.
 **************************************************************************/

/* Extract the hashes of handshake messages to this point.
 * Called from ssl3_SendCertificateVerify
 *             ssl3_SendFinished
 *             ssl3_HandleHandshakeMessage
 *
 * Caller must hold the SSL3HandshakeLock.
 * Caller must hold a read or write lock on the Spec R/W lock.
 *	(There is presently no way to assert on a Read lock.)
 */
static SECStatus
ssl3_ComputeHandshakeHashes(sslSocket *     ss,
                            ssl3CipherSpec *spec,   /* uses ->master_secret */
			    SSL3Hashes *    hashes, /* output goes here. */
			    PRUint32        sender)
{
    SECStatus     rv        = SECSuccess;
    PRBool        isTLS     = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_0);
    unsigned int  outLength;
    SSL3Opaque    md5_inner[MAX_MAC_LENGTH];
    SSL3Opaque    sha_inner[MAX_MAC_LENGTH];

    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
    hashes->hashAlg = SEC_OID_UNKNOWN;

#ifndef NO_PKCS11_BYPASS
    if (ss->opt.bypassPKCS11 &&
	ss->ssl3.hs.hashType == handshake_hash_single) {
	/* compute them without PKCS11 */
	PRUint64      sha_cx[MAX_MAC_CONTEXT_LLONGS];

	if (!spec->msItem.data) {
	    PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
	    return SECFailure;
	}

	ss->ssl3.hs.sha_clone(sha_cx, ss->ssl3.hs.sha_cx);
	ss->ssl3.hs.sha_obj->end(sha_cx, hashes->u.raw, &hashes->len,
				 sizeof(hashes->u.raw));

	PRINT_BUF(60, (NULL, "SHA-256: result", hashes->u.raw, hashes->len));

	/* If we ever support ciphersuites where the PRF hash isn't SHA-256
	 * then this will need to be updated. */
	hashes->hashAlg = SEC_OID_SHA256;
	rv = SECSuccess;
    } else if (ss->opt.bypassPKCS11) {
	/* compute them without PKCS11 */
	PRUint64      md5_cx[MAX_MAC_CONTEXT_LLONGS];
	PRUint64      sha_cx[MAX_MAC_CONTEXT_LLONGS];

#define md5cx ((MD5Context *)md5_cx)
#define shacx ((SHA1Context *)sha_cx)

	if (!spec->msItem.data) {
	    PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
	    return SECFailure;
	}

	MD5_Clone (md5cx,  (MD5Context *)ss->ssl3.hs.md5_cx);
	SHA1_Clone(shacx, (SHA1Context *)ss->ssl3.hs.sha_cx);

	if (!isTLS) {
	    /* compute hashes for SSL3. */
	    unsigned char s[4];

	    s[0] = (unsigned char)(sender >> 24);
	    s[1] = (unsigned char)(sender >> 16);
	    s[2] = (unsigned char)(sender >> 8);
	    s[3] = (unsigned char)sender;

	    if (sender != 0) {
		MD5_Update(md5cx, s, 4);
		PRINT_BUF(95, (NULL, "MD5 inner: sender", s, 4));
	    }

	    PRINT_BUF(95, (NULL, "MD5 inner: MAC Pad 1", mac_pad_1, 
			    mac_defs[mac_md5].pad_size));

	    MD5_Update(md5cx, spec->msItem.data, spec->msItem.len);
	    MD5_Update(md5cx, mac_pad_1, mac_defs[mac_md5].pad_size);
	    MD5_End(md5cx, md5_inner, &outLength, MD5_LENGTH);

	    PRINT_BUF(95, (NULL, "MD5 inner: result", md5_inner, outLength));

	    if (sender != 0) {
		SHA1_Update(shacx, s, 4);
		PRINT_BUF(95, (NULL, "SHA inner: sender", s, 4));
	    }

	    PRINT_BUF(95, (NULL, "SHA inner: MAC Pad 1", mac_pad_1, 
			    mac_defs[mac_sha].pad_size));

	    SHA1_Update(shacx, spec->msItem.data, spec->msItem.len);
	    SHA1_Update(shacx, mac_pad_1, mac_defs[mac_sha].pad_size);
	    SHA1_End(shacx, sha_inner, &outLength, SHA1_LENGTH);

	    PRINT_BUF(95, (NULL, "SHA inner: result", sha_inner, outLength));
	    PRINT_BUF(95, (NULL, "MD5 outer: MAC Pad 2", mac_pad_2, 
			    mac_defs[mac_md5].pad_size));
	    PRINT_BUF(95, (NULL, "MD5 outer: MD5 inner", md5_inner, MD5_LENGTH));

	    MD5_Begin(md5cx);
	    MD5_Update(md5cx, spec->msItem.data, spec->msItem.len);
	    MD5_Update(md5cx, mac_pad_2, mac_defs[mac_md5].pad_size);
	    MD5_Update(md5cx, md5_inner, MD5_LENGTH);
	}
	MD5_End(md5cx, hashes->u.s.md5, &outLength, MD5_LENGTH);

	PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->u.s.md5, MD5_LENGTH));

	if (!isTLS) {
	    PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2, 
			    mac_defs[mac_sha].pad_size));
	    PRINT_BUF(95, (NULL, "SHA outer: SHA inner", sha_inner, SHA1_LENGTH));

	    SHA1_Begin(shacx);
	    SHA1_Update(shacx, spec->msItem.data, spec->msItem.len);
	    SHA1_Update(shacx, mac_pad_2, mac_defs[mac_sha].pad_size);
	    SHA1_Update(shacx, sha_inner, SHA1_LENGTH);
	}
	SHA1_End(shacx, hashes->u.s.sha, &outLength, SHA1_LENGTH);

	PRINT_BUF(60, (NULL, "SHA outer: result", hashes->u.s.sha, SHA1_LENGTH));

	hashes->len = MD5_LENGTH + SHA1_LENGTH;
	rv = SECSuccess;
#undef md5cx
#undef shacx
    } else 
#endif
    if (ss->ssl3.hs.hashType == handshake_hash_single) {
	/* compute hashes with PKCS11 */
	PK11Context *h;
	unsigned int  stateLen;
	unsigned char stackBuf[1024];
	unsigned char *stateBuf = NULL;

	if (!spec->master_secret) {
	    PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
	    return SECFailure;
	}

	h = ss->ssl3.hs.sha;
	stateBuf = PK11_SaveContextAlloc(h, stackBuf,
					 sizeof(stackBuf), &stateLen);
	if (stateBuf == NULL) {
	    ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
	    goto tls12_loser;
	}
	rv |= PK11_DigestFinal(h, hashes->u.raw, &hashes->len,
			       sizeof(hashes->u.raw));
	if (rv != SECSuccess) {
	    ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
	    rv = SECFailure;
	    goto tls12_loser;
	}
	/* If we ever support ciphersuites where the PRF hash isn't SHA-256
	 * then this will need to be updated. */
	hashes->hashAlg = SEC_OID_SHA256;
	rv = SECSuccess;

tls12_loser:
	if (stateBuf) {
	    if (PK11_RestoreContext(h, stateBuf, stateLen) != SECSuccess) {
		ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
		rv = SECFailure;
	    }
	    if (stateBuf != stackBuf) {
		PORT_ZFree(stateBuf, stateLen);
	    }
	}
    } else {
	/* compute hashes with PKCS11 */
	PK11Context * md5;
	PK11Context * sha       = NULL;
	unsigned char *md5StateBuf = NULL;
	unsigned char *shaStateBuf = NULL;
	unsigned int  md5StateLen, shaStateLen;
	unsigned char md5StackBuf[256];
	unsigned char shaStackBuf[512];

	if (!spec->master_secret) {
	    PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
	    return SECFailure;
	}

	md5StateBuf = PK11_SaveContextAlloc(ss->ssl3.hs.md5, md5StackBuf,
					    sizeof md5StackBuf, &md5StateLen);
	if (md5StateBuf == NULL) {
	    ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
	    goto loser;
	}
	md5 = ss->ssl3.hs.md5;

	shaStateBuf = PK11_SaveContextAlloc(ss->ssl3.hs.sha, shaStackBuf,
					    sizeof shaStackBuf, &shaStateLen);
	if (shaStateBuf == NULL) {
	    ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
	    goto loser;
	}
	sha = ss->ssl3.hs.sha;

	if (!isTLS) {
	    /* compute hashes for SSL3. */
	    unsigned char s[4];

	    s[0] = (unsigned char)(sender >> 24);
	    s[1] = (unsigned char)(sender >> 16);
	    s[2] = (unsigned char)(sender >> 8);
	    s[3] = (unsigned char)sender;

	    if (sender != 0) {
		rv |= PK11_DigestOp(md5, s, 4);
		PRINT_BUF(95, (NULL, "MD5 inner: sender", s, 4));
	    }

	    PRINT_BUF(95, (NULL, "MD5 inner: MAC Pad 1", mac_pad_1, 
			  mac_defs[mac_md5].pad_size));

	    rv |= PK11_DigestKey(md5,spec->master_secret);
	    rv |= PK11_DigestOp(md5, mac_pad_1, mac_defs[mac_md5].pad_size);
	    rv |= PK11_DigestFinal(md5, md5_inner, &outLength, MD5_LENGTH);
	    PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH);
	    if (rv != SECSuccess) {
		ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
		rv = SECFailure;
		goto loser;
	    }

	    PRINT_BUF(95, (NULL, "MD5 inner: result", md5_inner, outLength));

	    if (sender != 0) {
		rv |= PK11_DigestOp(sha, s, 4);
		PRINT_BUF(95, (NULL, "SHA inner: sender", s, 4));
	    }

	    PRINT_BUF(95, (NULL, "SHA inner: MAC Pad 1", mac_pad_1, 
			  mac_defs[mac_sha].pad_size));

	    rv |= PK11_DigestKey(sha, spec->master_secret);
	    rv |= PK11_DigestOp(sha, mac_pad_1, mac_defs[mac_sha].pad_size);
	    rv |= PK11_DigestFinal(sha, sha_inner, &outLength, SHA1_LENGTH);
	    PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH);
	    if (rv != SECSuccess) {
		ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
		rv = SECFailure;
		goto loser;
	    }

	    PRINT_BUF(95, (NULL, "SHA inner: result", sha_inner, outLength));

	    PRINT_BUF(95, (NULL, "MD5 outer: MAC Pad 2", mac_pad_2, 
			  mac_defs[mac_md5].pad_size));
	    PRINT_BUF(95, (NULL, "MD5 outer: MD5 inner", md5_inner, MD5_LENGTH));

	    rv |= PK11_DigestBegin(md5);
	    rv |= PK11_DigestKey(md5, spec->master_secret);
	    rv |= PK11_DigestOp(md5, mac_pad_2, mac_defs[mac_md5].pad_size);
	    rv |= PK11_DigestOp(md5, md5_inner, MD5_LENGTH);
	}
	rv |= PK11_DigestFinal(md5, hashes->u.s.md5, &outLength, MD5_LENGTH);
	PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH);
	if (rv != SECSuccess) {
	    ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
	    rv = SECFailure;
	    goto loser;
	}

	PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->u.s.md5, MD5_LENGTH));

	if (!isTLS) {
	    PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2, 
			  mac_defs[mac_sha].pad_size));
	    PRINT_BUF(95, (NULL, "SHA outer: SHA inner", sha_inner, SHA1_LENGTH));

	    rv |= PK11_DigestBegin(sha);
	    rv |= PK11_DigestKey(sha,spec->master_secret);
	    rv |= PK11_DigestOp(sha, mac_pad_2, mac_defs[mac_sha].pad_size);
	    rv |= PK11_DigestOp(sha, sha_inner, SHA1_LENGTH);
	}
	rv |= PK11_DigestFinal(sha, hashes->u.s.sha, &outLength, SHA1_LENGTH);
	PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH);
	if (rv != SECSuccess) {
	    ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
	    rv = SECFailure;
	    goto loser;
	}

	PRINT_BUF(60, (NULL, "SHA outer: result", hashes->u.s.sha, SHA1_LENGTH));

	hashes->len = MD5_LENGTH + SHA1_LENGTH;
	rv = SECSuccess;

    loser:
	if (md5StateBuf) {
	    if (PK11_RestoreContext(ss->ssl3.hs.md5, md5StateBuf, md5StateLen)
		 != SECSuccess) 
	    {
		ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
		rv = SECFailure;
	    }
	    if (md5StateBuf != md5StackBuf) {
		PORT_ZFree(md5StateBuf, md5StateLen);
	    }
	}
	if (shaStateBuf) {
	    if (PK11_RestoreContext(ss->ssl3.hs.sha, shaStateBuf, shaStateLen)
		 != SECSuccess) 
	    {
		ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
		rv = SECFailure;
	    }
	    if (shaStateBuf != shaStackBuf) {
		PORT_ZFree(shaStateBuf, shaStateLen);
	    }
	}
    }
    return rv;
}

static SECStatus
ssl3_ComputeBackupHandshakeHashes(sslSocket * ss,
				  SSL3Hashes * hashes) /* output goes here. */
{
    SECStatus rv = SECSuccess;

    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
    PORT_Assert( !ss->sec.isServer );
    PORT_Assert( ss->ssl3.hs.hashType == handshake_hash_single );

    rv = PK11_DigestFinal(ss->ssl3.hs.backupHash, hashes->u.raw, &hashes->len,
			  sizeof(hashes->u.raw));
    if (rv != SECSuccess) {
	ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
	rv = SECFailure;
	goto loser;
    }
    hashes->hashAlg = SEC_OID_SHA1;

loser:
    PK11_DestroyContext(ss->ssl3.hs.backupHash, PR_TRUE);
    ss->ssl3.hs.backupHash = NULL;
    return rv;
}

/*
 * SSL 2 based implementations pass in the initial outbound buffer
 * so that the handshake hash can contain the included information.
 *
 * Called from ssl2_BeginClientHandshake() in sslcon.c
 */
SECStatus
ssl3_StartHandshakeHash(sslSocket *ss, unsigned char * buf, int length)
{
    SECStatus rv;

    ssl_GetSSL3HandshakeLock(ss);  /**************************************/

    rv = ssl3_InitState(ss);
    if (rv != SECSuccess) {
	goto done;		/* ssl3_InitState has set the error code. */
    }
    rv = ssl3_RestartHandshakeHashes(ss);
    if (rv != SECSuccess) {
	goto done;
    }

    PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
    PORT_Memcpy(
	&ss->ssl3.hs.client_random.rand[SSL3_RANDOM_LENGTH - SSL_CHALLENGE_BYTES],
	&ss->sec.ci.clientChallenge,
	SSL_CHALLENGE_BYTES);

    rv = ssl3_UpdateHandshakeHashes(ss, buf, length);
    /* if it failed, ssl3_UpdateHandshakeHashes has set the error code. */

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

/**************************************************************************
 * end of Handshake Hash functions.
 * Begin Send and Handle functions for handshakes.
 **************************************************************************/

/* Called from ssl3_HandleHelloRequest(),
 *             ssl3_RedoHandshake()
 *             ssl2_BeginClientHandshake (when resuming ssl3 session)
 *             dtls_HandleHelloVerifyRequest(with resending=PR_TRUE)
 */
SECStatus
ssl3_SendClientHello(sslSocket *ss, PRBool resending)
{
    sslSessionID *   sid;
    ssl3CipherSpec * cwSpec;
    SECStatus        rv;
    int              i;
    int              length;
    int              num_suites;
    int              actual_count = 0;
    PRBool           isTLS = PR_FALSE;
    PRBool           requestingResume = PR_FALSE, fallbackSCSV = PR_FALSE;
    PRInt32          total_exten_len = 0;
    unsigned         paddingExtensionLen;
    unsigned         numCompressionMethods;
    PRInt32          flags;

    SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(),
		ss->fd));

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

    rv = ssl3_InitState(ss);
    if (rv != SECSuccess) {
	return rv;		/* ssl3_InitState has set the error code. */
    }
    ss->ssl3.hs.sendingSCSV = PR_FALSE; /* Must be reset every handshake */
    PORT_Assert(IS_DTLS(ss) || !resending);

    SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE);
    ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE;

    /* We might be starting a session renegotiation in which case we should
     * clear previous state.
     */
    PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));

    rv = ssl3_RestartHandshakeHashes(ss);
    if (rv != SECSuccess) {
	return rv;
    }

    /*
     * During a renegotiation, ss->clientHelloVersion will be used again to
     * work around a Windows SChannel bug. Ensure that it is still enabled.
     */
    if (ss->firstHsDone) {
	if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
	    PORT_SetError(SSL_ERROR_SSL_DISABLED);
	    return SECFailure;
	}

	if (ss->clientHelloVersion < ss->vrange.min ||
	    ss->clientHelloVersion > ss->vrange.max) {
	    PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
	    return SECFailure;
	}
    }

    /* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup
     * handles expired entries and other details.
     * XXX If we've been called from ssl2_BeginClientHandshake, then
     * this lookup is duplicative and wasteful.
     */
    sid = (ss->opt.noCache) ? NULL
	    : ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, ss->url);

    /* We can't resume based on a different token. If the sid exists,
     * make sure the token that holds the master secret still exists ...
     * If we previously did client-auth, make sure that the token that holds
     * the private key still exists, is logged in, hasn't been removed, etc.
     */
    if (sid) {
	PRBool sidOK = PR_TRUE;
	if (sid->u.ssl3.keys.msIsWrapped) {
	    /* Session key was wrapped, which means it was using PKCS11, */
	    PK11SlotInfo *slot = NULL;
	    if (sid->u.ssl3.masterValid && !ss->opt.bypassPKCS11) {
		slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
					 sid->u.ssl3.masterSlotID);
	    }
	    if (slot == NULL) {
	       sidOK = PR_FALSE;
	    } else {
		PK11SymKey *wrapKey = NULL;
		if (!PK11_IsPresent(slot) ||
		    ((wrapKey = PK11_GetWrapKey(slot, 
						sid->u.ssl3.masterWrapIndex,
						sid->u.ssl3.masterWrapMech,
						sid->u.ssl3.masterWrapSeries,
						ss->pkcs11PinArg)) == NULL) ) {
		    sidOK = PR_FALSE;
		}
		if (wrapKey) PK11_FreeSymKey(wrapKey);
		PK11_FreeSlot(slot);
		slot = NULL;
	    }
	}
	/* If we previously did client-auth, make sure that the token that
	** holds the private key still exists, is logged in, hasn't been
	** removed, etc.
	*/
	if (sidOK && !ssl3_ClientAuthTokenPresent(sid)) {
	    sidOK = PR_FALSE;
	}

	/* TLS 1.0 (RFC 2246) Appendix E says:
	 *   Whenever a client already knows the highest protocol known to
	 *   a server (for example, when resuming a session), it should
	 *   initiate the connection in that native protocol.
	 * So we pass sid->version to ssl3_NegotiateVersion() here, except
	 * when renegotiating.
	 *
	 * Windows SChannel compares the client_version inside the RSA
	 * EncryptedPreMasterSecret of a renegotiation with the
	 * client_version of the initial ClientHello rather than the
	 * ClientHello in the renegotiation. To work around this bug, we
	 * continue to use the client_version used in the initial
	 * ClientHello when renegotiating.
	 */
	if (sidOK) {
	    if (ss->firstHsDone) {
		/*
		 * The client_version of the initial ClientHello is still
		 * available in ss->clientHelloVersion. Ensure that
		 * sid->version is bounded within
		 * [ss->vrange.min, ss->clientHelloVersion], otherwise we
		 * can't use sid.
		 */
		if (sid->version >= ss->vrange.min &&
		    sid->version <= ss->clientHelloVersion) {
		    ss->version = ss->clientHelloVersion;
		} else {
		    sidOK = PR_FALSE;
		}
	    } else {
		if (ssl3_NegotiateVersion(ss, sid->version,
					  PR_FALSE) != SECSuccess) {
		    sidOK = PR_FALSE;
		}
	    }
	}

	if (!sidOK) {
	    SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_not_ok );
	    if (ss->sec.uncache)
                (*ss->sec.uncache)(sid);
	    ssl_FreeSID(sid);
	    sid = NULL;
	}
    }

    if (sid) {
	requestingResume = PR_TRUE;
	SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits );

	PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID,
		      sid->u.ssl3.sessionIDLength));

	ss->ssl3.policy = sid->u.ssl3.policy;
    } else {
	SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses );

	/*
	 * Windows SChannel compares the client_version inside the RSA
	 * EncryptedPreMasterSecret of a renegotiation with the
	 * client_version of the initial ClientHello rather than the
	 * ClientHello in the renegotiation. To work around this bug, we
	 * continue to use the client_version used in the initial
	 * ClientHello when renegotiating.
	 */
	if (ss->firstHsDone) {
	    ss->version = ss->clientHelloVersion;
	} else {
	    rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED,
				       PR_TRUE);
	    if (rv != SECSuccess)
		return rv;	/* error code was set */
	}

	sid = ssl3_NewSessionID(ss, PR_FALSE);
	if (!sid) {
	    return SECFailure;	/* memory error is set */
        }
    }

    isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0);
    ssl_GetSpecWriteLock(ss);
    cwSpec = ss->ssl3.cwSpec;
    if (cwSpec->mac_def->mac == mac_null) {
	/* SSL records are not being MACed. */
	cwSpec->version = ss->version;
    }
    ssl_ReleaseSpecWriteLock(ss);

    if (ss->sec.ci.sid != NULL) {
	ssl_FreeSID(ss->sec.ci.sid);	/* decrement ref count, free if zero */
    }
    ss->sec.ci.sid = sid;

    ss->sec.send = ssl3_SendApplicationData;

    /* shouldn't get here if SSL3 is disabled, but ... */
    if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
	PR_NOT_REACHED("No versions of SSL 3.0 or later are enabled");
	PORT_SetError(SSL_ERROR_SSL_DISABLED);
    	return SECFailure;
    }

    /* how many suites does our PKCS11 support (regardless of policy)? */
    num_suites = ssl3_config_match_init(ss);
    if (!num_suites)
    	return SECFailure;	/* ssl3_config_match_init has set error code. */

    /* HACK for SCSV in SSL 3.0.  On initial handshake, prepend SCSV,
     * only if TLS is disabled.
     */
    if (!ss->firstHsDone && !isTLS) {
	/* Must set this before calling Hello Extension Senders, 
	 * to suppress sending of empty RI extension.
	 */
	ss->ssl3.hs.sendingSCSV = PR_TRUE;
    }

    /* When we attempt session resumption (only), we must lock the sid to
     * prevent races with other resumption connections that receive a
     * NewSessionTicket that will cause the ticket in the sid to be replaced.
     * Once we've copied the session ticket into our ClientHello message, it
     * is OK for the ticket to change, so we just need to make sure we hold
     * the lock across the calls to ssl3_CallHelloExtensionSenders.
     */
    if (sid->u.ssl3.lock) {
        NSSRWLock_LockRead(sid->u.ssl3.lock);
    }

    if (isTLS || (ss->firstHsDone && ss->peerRequestedProtection)) {
	PRUint32 maxBytes = 65535; /* 2^16 - 1 */
	PRInt32  extLen;

	extLen = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes, NULL);
	if (extLen < 0) {
	    if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	    return SECFailure;
	}
	maxBytes        -= extLen;
	total_exten_len += extLen;

	if (total_exten_len > 0)
	    total_exten_len += 2;
    }

#if defined(NSS_ENABLE_ECC)
    if (!total_exten_len || !isTLS) {
	/* not sending the elliptic_curves and ec_point_formats extensions */
    	ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */
    }
#endif

    if (IS_DTLS(ss)) {
	ssl3_DisableNonDTLSSuites(ss);
    }

    if (!ssl3_HasGCMSupport()) {
	ssl3_DisableGCMSuites(ss);
    }

    /* how many suites are permitted by policy and user preference? */
    num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE);
    if (!num_suites) {
    	if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
    	return SECFailure;	/* count_cipher_suites has set error code. */
    }

    fallbackSCSV = ss->opt.enableFallbackSCSV && (!requestingResume ||
						  ss->version < sid->version);
    /* make room for SCSV */
    if (ss->ssl3.hs.sendingSCSV) {
	++num_suites;
    }
    if (fallbackSCSV) {
	++num_suites;
    }

    /* count compression methods */
    numCompressionMethods = 0;
    for (i = 0; i < compressionMethodsCount; i++) {
	if (compressionEnabled(ss, compressions[i]))
	    numCompressionMethods++;
    }

    length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH +
	1 + ((sid == NULL) ? 0 : sid->u.ssl3.sessionIDLength) +
	2 + num_suites*sizeof(ssl3CipherSuite) +
	1 + numCompressionMethods + total_exten_len;
    if (IS_DTLS(ss)) {
	length += 1 + ss->ssl3.hs.cookieLen;
    }

    /* A padding extension may be included to ensure that the record containing
     * the ClientHello doesn't have a length between 256 and 511 bytes
     * (inclusive). Initial, ClientHello records with such lengths trigger bugs
     * in F5 devices.
     *
     * This is not done for DTLS nor for renegotiation. */
    if (!IS_DTLS(ss) && isTLS && !ss->firstHsDone) {
        paddingExtensionLen = ssl3_CalculatePaddingExtensionLength(length);
        total_exten_len += paddingExtensionLen;
        length += paddingExtensionLen;
    } else {
        paddingExtensionLen = 0;
    }

    rv = ssl3_AppendHandshakeHeader(ss, client_hello, length);
    if (rv != SECSuccess) {
	if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	return rv;	/* err set by ssl3_AppendHandshake* */
    }

    if (ss->firstHsDone) {
	/* The client hello version must stay unchanged to work around
	 * the Windows SChannel bug described above. */
	PORT_Assert(ss->version == ss->clientHelloVersion);
    }
    ss->clientHelloVersion = ss->version;
    if (IS_DTLS(ss)) {
	PRUint16 version;

	version = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion);
	rv = ssl3_AppendHandshakeNumber(ss, version, 2);
    } else {
	rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);
    }
    if (rv != SECSuccess) {
	if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	return rv;	/* err set by ssl3_AppendHandshake* */
    }

    if (!resending) { /* Don't re-generate if we are in DTLS re-sending mode */
	rv = ssl3_GetNewRandom(&ss->ssl3.hs.client_random);
	if (rv != SECSuccess) {
	    if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	    return rv;	/* err set by GetNewRandom. */
	}
    }
    rv = ssl3_AppendHandshake(ss, &ss->ssl3.hs.client_random,
                              SSL3_RANDOM_LENGTH);
    if (rv != SECSuccess) {
	if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	return rv;	/* err set by ssl3_AppendHandshake* */
    }

    if (sid)
	rv = ssl3_AppendHandshakeVariable(
	    ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1);
    else
	rv = ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
    if (rv != SECSuccess) {
	if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	return rv;	/* err set by ssl3_AppendHandshake* */
    }

    if (IS_DTLS(ss)) {
	rv = ssl3_AppendHandshakeVariable(
	    ss, ss->ssl3.hs.cookie, ss->ssl3.hs.cookieLen, 1);
	if (rv != SECSuccess) {
	    if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	    return rv;	/* err set by ssl3_AppendHandshake* */
	}
    }

    rv = ssl3_AppendHandshakeNumber(ss, num_suites*sizeof(ssl3CipherSuite), 2);
    if (rv != SECSuccess) {
	if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	return rv;	/* err set by ssl3_AppendHandshake* */
    }

    if (ss->ssl3.hs.sendingSCSV) {
	/* Add the actual SCSV */
	rv = ssl3_AppendHandshakeNumber(ss, TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
					sizeof(ssl3CipherSuite));
	if (rv != SECSuccess) {
	    if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	    return rv;	/* err set by ssl3_AppendHandshake* */
	}
	actual_count++;
    }
    if (fallbackSCSV) {
	rv = ssl3_AppendHandshakeNumber(ss, TLS_FALLBACK_SCSV,
					sizeof(ssl3CipherSuite));
	if (rv != SECSuccess) {
	    if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	    return rv;	/* err set by ssl3_AppendHandshake* */
	}
	actual_count++;
    }
    for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
	ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
	if (config_match(suite, ss->ssl3.policy, PR_TRUE, &ss->vrange)) {
	    actual_count++;
	    if (actual_count > num_suites) {
		if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
		/* set error card removal/insertion error */
		PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
		return SECFailure;
	    }
	    rv = ssl3_AppendHandshakeNumber(ss, suite->cipher_suite,
					    sizeof(ssl3CipherSuite));
	    if (rv != SECSuccess) {
		if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
		return rv;	/* err set by ssl3_AppendHandshake* */
	    }
	}
    }

    /* if cards were removed or inserted between count_cipher_suites and
     * generating our list, detect the error here rather than send it off to
     * the server.. */
    if (actual_count != num_suites) {
	/* Card removal/insertion error */
	if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
	return SECFailure;
    }

    rv = ssl3_AppendHandshakeNumber(ss, numCompressionMethods, 1);
    if (rv != SECSuccess) {
	if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	return rv;	/* err set by ssl3_AppendHandshake* */
    }
    for (i = 0; i < compressionMethodsCount; i++) {
	if (!compressionEnabled(ss, compressions[i]))
	    continue;
	rv = ssl3_AppendHandshakeNumber(ss, compressions[i], 1);
	if (rv != SECSuccess) {
	    if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	    return rv;	/* err set by ssl3_AppendHandshake* */
	}
    }

    if (total_exten_len) {
	PRUint32 maxBytes = total_exten_len - 2;
	PRInt32  extLen;

	rv = ssl3_AppendHandshakeNumber(ss, maxBytes, 2);
	if (rv != SECSuccess) {
	    if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	    return rv;	/* err set by AppendHandshake. */
	}

	extLen = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, maxBytes, NULL);
	if (extLen < 0) {
	    if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	    return SECFailure;
	}
	maxBytes -= extLen;

	extLen = ssl3_AppendPaddingExtension(ss, paddingExtensionLen, maxBytes);
	if (extLen < 0) {
	    if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
	    return SECFailure;
	}
	maxBytes -= extLen;

	PORT_Assert(!maxBytes);
    } 

    if (sid->u.ssl3.lock) {
        NSSRWLock_UnlockRead(sid->u.ssl3.lock);
    }

    if (ss->xtnData.sentSessionTicketInClientHello) {
        SSL_AtomicIncrementLong(&ssl3stats.sch_sid_stateless_resumes);
    }

    if (ss->ssl3.hs.sendingSCSV) {
	/* Since we sent the SCSV, pretend we sent empty RI extension. */
	TLSExtensionData *xtnData = &ss->xtnData;
	xtnData->advertised[xtnData->numAdvertised++] = 
	    ssl_renegotiation_info_xtn;
    }

    flags = 0;
    if (!ss->firstHsDone && !IS_DTLS(ss)) {
	flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION;
    }
    rv = ssl3_FlushHandshake(ss, flags);
    if (rv != SECSuccess) {
	return rv;	/* error code set by ssl3_FlushHandshake */
    }

    ss->ssl3.hs.ws = wait_server_hello;
    return rv;
}


/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
 * ssl3 Hello Request.
 * Caller must hold Handshake and RecvBuf locks.
 */
static SECStatus
ssl3_HandleHelloRequest(sslSocket *ss)
{
    sslSessionID *sid = ss->sec.ci.sid;
    SECStatus     rv;

    SSL_TRC(3, ("%d: SSL3[%d]: handle hello_request handshake",
		SSL_GETPID(), ss->fd));

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

    if (ss->ssl3.hs.ws == wait_server_hello)
	return SECSuccess;
    if (ss->ssl3.hs.ws != idle_handshake || ss->sec.isServer) {
	(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST);
	return SECFailure;
    }
    if (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) {
	ssl_GetXmitBufLock(ss);
	rv = SSL3_SendAlert(ss, alert_warning, no_renegotiation);
	ssl_ReleaseXmitBufLock(ss);
	PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED);
	return SECFailure;
    }

    if (sid) {
	if (ss->sec.uncache)
            ss->sec.uncache(sid);
	ssl_FreeSID(sid);
	ss->sec.ci.sid = NULL;
    }

    if (IS_DTLS(ss)) {
	dtls_RehandshakeCleanup(ss);
    }

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

    return rv;
}

#define UNKNOWN_WRAP_MECHANISM 0x7fffffff

static const CK_MECHANISM_TYPE wrapMechanismList[SSL_NUM_WRAP_MECHS] = {
    CKM_DES3_ECB,
    CKM_CAST5_ECB,
    CKM_DES_ECB,
    CKM_KEY_WRAP_LYNKS,
    CKM_IDEA_ECB,
    CKM_CAST3_ECB,
    CKM_CAST_ECB,
    CKM_RC5_ECB,
    CKM_RC2_ECB,
    CKM_CDMF_ECB,
    CKM_SKIPJACK_WRAP,
    CKM_SKIPJACK_CBC64,
    CKM_AES_ECB,
    CKM_CAMELLIA_ECB,
    CKM_SEED_ECB,
    UNKNOWN_WRAP_MECHANISM
};

static int
ssl_FindIndexByWrapMechanism(CK_MECHANISM_TYPE mech)
{
    const CK_MECHANISM_TYPE *pMech = wrapMechanismList;

    while (mech != *pMech && *pMech != UNKNOWN_WRAP_MECHANISM) {
    	++pMech;
    }
    return (*pMech == UNKNOWN_WRAP_MECHANISM) ? -1
                                              : (pMech - wrapMechanismList);
}

static PK11SymKey *
ssl_UnwrapSymWrappingKey(
	SSLWrappedSymWrappingKey *pWswk,
	SECKEYPrivateKey *        svrPrivKey,
	SSL3KEAType               exchKeyType,
	CK_MECHANISM_TYPE         masterWrapMech,
	void *                    pwArg)
{
    PK11SymKey *             unwrappedWrappingKey  = NULL;
    SECItem                  wrappedKey;
#ifdef NSS_ENABLE_ECC
    PK11SymKey *             Ks;
    SECKEYPublicKey          pubWrapKey;
    ECCWrappedKeyInfo        *ecWrapped;
#endif /* NSS_ENABLE_ECC */

    /* found the wrapping key on disk. */
    PORT_Assert(pWswk->symWrapMechanism == masterWrapMech);
    PORT_Assert(pWswk->exchKeyType      == exchKeyType);
    if (pWswk->symWrapMechanism != masterWrapMech ||
	pWswk->exchKeyType      != exchKeyType) {
	goto loser;
    }
    wrappedKey.type = siBuffer;
    wrappedKey.data = pWswk->wrappedSymmetricWrappingkey;
    wrappedKey.len  = pWswk->wrappedSymKeyLen;
    PORT_Assert(wrappedKey.len <= sizeof pWswk->wrappedSymmetricWrappingkey);

    switch (exchKeyType) {

    case kt_rsa:
	unwrappedWrappingKey =
	    PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey,
				 masterWrapMech, CKA_UNWRAP, 0);
	break;

#ifdef NSS_ENABLE_ECC
    case kt_ecdh:
        /* 
         * For kt_ecdh, we first create an EC public key based on
         * data stored with the wrappedSymmetricWrappingkey. Next,
         * we do an ECDH computation involving this public key and
         * the SSL server's (long-term) EC private key. The resulting
         * shared secret is treated the same way as Fortezza's Ks, i.e.,
         * it is used to recover the symmetric wrapping key.
         *
         * The data in wrappedSymmetricWrappingkey is laid out as defined
         * in the ECCWrappedKeyInfo structure.
         */
        ecWrapped = (ECCWrappedKeyInfo *) pWswk->wrappedSymmetricWrappingkey;

        PORT_Assert(ecWrapped->encodedParamLen + ecWrapped->pubValueLen + 
            ecWrapped->wrappedKeyLen <= MAX_EC_WRAPPED_KEY_BUFLEN);

        if (ecWrapped->encodedParamLen + ecWrapped->pubValueLen + 
            ecWrapped->wrappedKeyLen > MAX_EC_WRAPPED_KEY_BUFLEN) {
            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
            goto loser;
        }

        pubWrapKey.keyType = ecKey;
        pubWrapKey.u.ec.size = ecWrapped->size;
        pubWrapKey.u.ec.DEREncodedParams.len = ecWrapped->encodedParamLen;
        pubWrapKey.u.ec.DEREncodedParams.data = ecWrapped->var;
        pubWrapKey.u.ec.publicValue.len = ecWrapped->pubValueLen;
        pubWrapKey.u.ec.publicValue.data = ecWrapped->var + 
            ecWrapped->encodedParamLen;

        wrappedKey.len  = ecWrapped->wrappedKeyLen;
        wrappedKey.data = ecWrapped->var + ecWrapped->encodedParamLen + 
            ecWrapped->pubValueLen;
        
        /* Derive Ks using ECDH */
        Ks = PK11_PubDeriveWithKDF(svrPrivKey, &pubWrapKey, PR_FALSE, NULL,
				   NULL, CKM_ECDH1_DERIVE, masterWrapMech, 
				   CKA_DERIVE, 0, CKD_NULL, NULL, NULL);
        if (Ks == NULL) {
            goto loser;
        }

        /*  Use Ks to unwrap the wrapping key */
        unwrappedWrappingKey = PK11_UnwrapSymKey(Ks, masterWrapMech, NULL, 
						 &wrappedKey, masterWrapMech, 
						 CKA_UNWRAP, 0);
        PK11_FreeSymKey(Ks);
        
        break;
#endif

    default:
	/* Assert? */
	SET_ERROR_CODE
	goto loser;
    }
loser:
    return unwrappedWrappingKey;
}

/* Each process sharing the server session ID cache has its own array of
 * SymKey pointers for the symmetric wrapping keys that are used to wrap
 * the master secrets.  There is one key for each KEA type.  These Symkeys
 * correspond to the wrapped SymKeys kept in the server session cache.
 */

typedef struct {
    PK11SymKey *      symWrapKey[kt_kea_size];
} ssl3SymWrapKey;

static PZLock *          symWrapKeysLock = NULL;
static ssl3SymWrapKey    symWrapKeys[SSL_NUM_WRAP_MECHS];

SECStatus ssl_FreeSymWrapKeysLock(void)
{
    if (symWrapKeysLock) {
        PZ_DestroyLock(symWrapKeysLock);
        symWrapKeysLock = NULL;
        return SECSuccess;
    }
    PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
    return SECFailure;
}

SECStatus
SSL3_ShutdownServerCache(void)
{
    int             i, j;

    if (!symWrapKeysLock)
    	return SECSuccess;	/* lock was never initialized */
    PZ_Lock(symWrapKeysLock);
    /* get rid of all symWrapKeys */
    for (i = 0; i < SSL_NUM_WRAP_MECHS; ++i) {
    	for (j = 0; j < kt_kea_size; ++j) {
	    PK11SymKey **   pSymWrapKey;
	    pSymWrapKey = &symWrapKeys[i].symWrapKey[j];
	    if (*pSymWrapKey) {
		PK11_FreeSymKey(*pSymWrapKey);
	    	*pSymWrapKey = NULL;
	    }
	}
    }

    PZ_Unlock(symWrapKeysLock);
    return SECSuccess;
}

SECStatus ssl_InitSymWrapKeysLock(void)
{
    symWrapKeysLock = PZ_NewLock(nssILockOther);
    return symWrapKeysLock ? SECSuccess : SECFailure;
}

/* Try to get wrapping key for mechanism from in-memory array.
 * If that fails, look for one on disk.
 * If that fails, generate a new one, put the new one on disk,
 * Put the new key in the in-memory array.
 */
static PK11SymKey *
getWrappingKey( sslSocket *       ss,
		PK11SlotInfo *    masterSecretSlot,
		SSL3KEAType       exchKeyType,
                CK_MECHANISM_TYPE masterWrapMech,
	        void *            pwArg)
{
    SECKEYPrivateKey *       svrPrivKey;
    SECKEYPublicKey *        svrPubKey             = NULL;
    PK11SymKey *             unwrappedWrappingKey  = NULL;
    PK11SymKey **            pSymWrapKey;
    CK_MECHANISM_TYPE        asymWrapMechanism = CKM_INVALID_MECHANISM;
    int                      length;
    int                      symWrapMechIndex;
    SECStatus                rv;
    SECItem                  wrappedKey;
    SSLWrappedSymWrappingKey wswk;
#ifdef NSS_ENABLE_ECC
    PK11SymKey *      Ks = NULL;
    SECKEYPublicKey   *pubWrapKey = NULL;
    SECKEYPrivateKey  *privWrapKey = NULL;
    ECCWrappedKeyInfo *ecWrapped;
#endif /* NSS_ENABLE_ECC */

    svrPrivKey  = ss->serverCerts[exchKeyType].SERVERKEY;
    PORT_Assert(svrPrivKey != NULL);
    if (!svrPrivKey) {
    	return NULL;	/* why are we here?!? */
    }

    symWrapMechIndex = ssl_FindIndexByWrapMechanism(masterWrapMech);
    PORT_Assert(symWrapMechIndex >= 0);
    if (symWrapMechIndex < 0)
    	return NULL;	/* invalid masterWrapMech. */

    pSymWrapKey = &symWrapKeys[symWrapMechIndex].symWrapKey[exchKeyType];

    ssl_InitSessionCacheLocks();

    PZ_Lock(symWrapKeysLock);

    unwrappedWrappingKey = *pSymWrapKey;
    if (unwrappedWrappingKey != NULL) {
	if (PK11_VerifyKeyOK(unwrappedWrappingKey)) {
	    unwrappedWrappingKey = PK11_ReferenceSymKey(unwrappedWrappingKey);
	    goto done;
	}
	/* slot series has changed, so this key is no good any more. */
	PK11_FreeSymKey(unwrappedWrappingKey);
	*pSymWrapKey = unwrappedWrappingKey = NULL;
    }

    /* Try to get wrapped SymWrapping key out of the (disk) cache. */
    /* Following call fills in wswk on success. */
    if (ssl_GetWrappingKey(symWrapMechIndex, exchKeyType, &wswk)) {
    	/* found the wrapped sym wrapping key on disk. */
	unwrappedWrappingKey =
	    ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, exchKeyType,
                                     masterWrapMech, pwArg);
	if (unwrappedWrappingKey) {
	    goto install;
	}
    }

    if (!masterSecretSlot) 	/* caller doesn't want to create a new one. */
    	goto loser;

    length = PK11_GetBestKeyLength(masterSecretSlot, masterWrapMech);
    /* Zero length means fixed key length algorithm, or error.
     * It's ambiguous.
     */
    unwrappedWrappingKey = PK11_KeyGen(masterSecretSlot, masterWrapMech, NULL,
                                       length, pwArg);
    if (!unwrappedWrappingKey) {
    	goto loser;
    }

    /* Prepare the buffer to receive the wrappedWrappingKey,
     * the symmetric wrapping key wrapped using the server's pub key.
     */
    PORT_Memset(&wswk, 0, sizeof wswk);	/* eliminate UMRs. */

    if (ss->serverCerts[exchKeyType].serverKeyPair) {
	svrPubKey = ss->serverCerts[exchKeyType].serverKeyPair->pubKey;
    }
    if (svrPubKey == NULL) {
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	goto loser;
    }
    wrappedKey.type = siBuffer;
    wrappedKey.len  = SECKEY_PublicKeyStrength(svrPubKey);
    wrappedKey.data = wswk.wrappedSymmetricWrappingkey;

    PORT_Assert(wrappedKey.len <= sizeof wswk.wrappedSymmetricWrappingkey);
    if (wrappedKey.len > sizeof wswk.wrappedSymmetricWrappingkey)
    	goto loser;

    /* wrap symmetric wrapping key in server's public key. */
    switch (exchKeyType) {
    case kt_rsa:
	asymWrapMechanism = CKM_RSA_PKCS;
	rv = PK11_PubWrapSymKey(asymWrapMechanism, svrPubKey,
	                        unwrappedWrappingKey, &wrappedKey);
	break;

#ifdef NSS_ENABLE_ECC
    case kt_ecdh:
	/*
	 * We generate an ephemeral EC key pair. Perform an ECDH
	 * computation involving this ephemeral EC public key and
	 * the SSL server's (long-term) EC private key. The resulting
	 * shared secret is treated in the same way as Fortezza's Ks, 
	 * i.e., it is used to wrap the wrapping key. To facilitate
	 * unwrapping in ssl_UnwrapWrappingKey, we also store all
	 * relevant info about the ephemeral EC public key in
	 * wswk.wrappedSymmetricWrappingkey and lay it out as 
	 * described in the ECCWrappedKeyInfo structure.
	 */
	PORT_Assert(svrPubKey->keyType == ecKey);
	if (svrPubKey->keyType != ecKey) {
	    /* something is wrong in sslsecur.c if this isn't an ecKey */
	    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	    rv = SECFailure;
	    goto ec_cleanup;
	}

	privWrapKey = SECKEY_CreateECPrivateKey(
	    &svrPubKey->u.ec.DEREncodedParams, &pubWrapKey, NULL);
	if ((privWrapKey == NULL) || (pubWrapKey == NULL)) {
	    rv = SECFailure;
	    goto ec_cleanup;
	}
	
	/* Set the key size in bits */
	if (pubWrapKey->u.ec.size == 0) {
	    pubWrapKey->u.ec.size = SECKEY_PublicKeyStrengthInBits(svrPubKey);
	}

	PORT_Assert(pubWrapKey->u.ec.DEREncodedParams.len + 
	    pubWrapKey->u.ec.publicValue.len < MAX_EC_WRAPPED_KEY_BUFLEN);
	if (pubWrapKey->u.ec.DEREncodedParams.len + 
	    pubWrapKey->u.ec.publicValue.len >= MAX_EC_WRAPPED_KEY_BUFLEN) {
	    PORT_SetError(SEC_ERROR_INVALID_KEY);
	    rv = SECFailure;
	    goto ec_cleanup;
	}

	/* Derive Ks using ECDH */
	Ks = PK11_PubDeriveWithKDF(svrPrivKey, pubWrapKey, PR_FALSE, NULL,
				   NULL, CKM_ECDH1_DERIVE, masterWrapMech, 
				   CKA_DERIVE, 0, CKD_NULL, NULL, NULL);
	if (Ks == NULL) {
	    rv = SECFailure;
	    goto ec_cleanup;
	}

	ecWrapped = (ECCWrappedKeyInfo *) (wswk.wrappedSymmetricWrappingkey);
	ecWrapped->size = pubWrapKey->u.ec.size;
	ecWrapped->encodedParamLen = pubWrapKey->u.ec.DEREncodedParams.len;
	PORT_Memcpy(ecWrapped->var, pubWrapKey->u.ec.DEREncodedParams.data, 
	    pubWrapKey->u.ec.DEREncodedParams.len);

	ecWrapped->pubValueLen = pubWrapKey->u.ec.publicValue.len;
	PORT_Memcpy(ecWrapped->var + ecWrapped->encodedParamLen, 
		    pubWrapKey->u.ec.publicValue.data, 
		    pubWrapKey->u.ec.publicValue.len);

	wrappedKey.len = MAX_EC_WRAPPED_KEY_BUFLEN - 
	    (ecWrapped->encodedParamLen + ecWrapped->pubValueLen);
	wrappedKey.data = ecWrapped->var + ecWrapped->encodedParamLen +
	    ecWrapped->pubValueLen;

	/* wrap symmetricWrapping key with the local Ks */
	rv = PK11_WrapSymKey(masterWrapMech, NULL, Ks,
			     unwrappedWrappingKey, &wrappedKey);

	if (rv != SECSuccess) {
	    goto ec_cleanup;
	}

	/* Write down the length of wrapped key in the buffer
	 * wswk.wrappedSymmetricWrappingkey at the appropriate offset
	 */
	ecWrapped->wrappedKeyLen = wrappedKey.len;

ec_cleanup:
	if (privWrapKey) SECKEY_DestroyPrivateKey(privWrapKey);
	if (pubWrapKey) SECKEY_DestroyPublicKey(pubWrapKey);
	if (Ks) PK11_FreeSymKey(Ks);
	asymWrapMechanism = masterWrapMech;
	break;
#endif /* NSS_ENABLE_ECC */

    default:
	rv = SECFailure;
	break;
    }

    if (rv != SECSuccess) {
	ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
	goto loser;
    }

    PORT_Assert(asymWrapMechanism != CKM_INVALID_MECHANISM);

    wswk.symWrapMechanism  = masterWrapMech;
    wswk.symWrapMechIndex  = symWrapMechIndex;
    wswk.asymWrapMechanism = asymWrapMechanism;
    wswk.exchKeyType       = exchKeyType;
    wswk.wrappedSymKeyLen  = wrappedKey.len;

    /* put it on disk. */
    /* If the wrapping key for this KEA type has already been set, 
     * then abandon the value we just computed and 
     * use the one we got from the disk.
     */
    if (ssl_SetWrappingKey(&wswk)) {
    	/* somebody beat us to it.  The original contents of our wswk
	 * has been replaced with the content on disk.  Now, discard
	 * the key we just created and unwrap this new one.
	 */
    	PK11_FreeSymKey(unwrappedWrappingKey);

	unwrappedWrappingKey =
	    ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, exchKeyType,
                                     masterWrapMech, pwArg);
    }

install:
    if (unwrappedWrappingKey) {
	*pSymWrapKey = PK11_ReferenceSymKey(unwrappedWrappingKey);
    }

loser:
done:
    PZ_Unlock(symWrapKeysLock);
    return unwrappedWrappingKey;
}

/* hexEncode hex encodes |length| bytes from |in| and writes it as |length*2|
 * bytes to |out|. */
static void
hexEncode(char *out, const unsigned char *in, unsigned int length)
{
    static const char hextable[] = "0123456789abcdef";
    unsigned int i;

    for (i = 0; i < length; i++) {
	*(out++) = hextable[in[i] >> 4];
	*(out++) = hextable[in[i] & 15];
    }
}

/* Called from ssl3_SendClientKeyExchange(). */
/* Presently, this always uses PKCS11.  There is no bypass for this. */
static SECStatus
sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
{
    PK11SymKey *	pms 		= NULL;
    SECStatus           rv    		= SECFailure;
    SECItem 		enc_pms 	= {siBuffer, NULL, 0};
    PRBool              isTLS;

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

    /* Generate the pre-master secret ...  */
    ssl_GetSpecWriteLock(ss);
    isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);

    pms = ssl3_GenerateRSAPMS(ss, ss->ssl3.pwSpec, NULL);
    ssl_ReleaseSpecWriteLock(ss);
    if (pms == NULL) {
	ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
	goto loser;
    }

    /* Get the wrapped (encrypted) pre-master secret, enc_pms */
    enc_pms.len  = SECKEY_PublicKeyStrength(svrPubKey);
    enc_pms.data = (unsigned char*)PORT_Alloc(enc_pms.len);
    if (enc_pms.data == NULL) {
	goto loser;	/* err set by PORT_Alloc */
    }

    /* wrap pre-master secret in server's public key. */
    rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, svrPubKey, pms, &enc_pms);
    if (rv != SECSuccess) {
	ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
	goto loser;
    }

    if (ssl_keylog_iob) {
	SECStatus extractRV = PK11_ExtractKeyValue(pms);
	if (extractRV == SECSuccess) {
	    SECItem * keyData = PK11_GetKeyData(pms);
	    if (keyData && keyData->data && keyData->len) {
#ifdef TRACE
		if (ssl_trace >= 100) {
		    ssl_PrintBuf(ss, "Pre-Master Secret",
				 keyData->data, keyData->len);
		}
#endif
		if (ssl_keylog_iob && enc_pms.len >= 8 && keyData->len == 48) {
		    /* https://developer.mozilla.org/en/NSS_Key_Log_Format */

		    /* There could be multiple, concurrent writers to the
		     * keylog, so we have to do everything in a single call to
		     * fwrite. */
		    char buf[4 + 8*2 + 1 + 48*2 + 1];

		    strcpy(buf, "RSA ");
		    hexEncode(buf + 4, enc_pms.data, 8);
		    buf[20] = ' ';
		    hexEncode(buf + 21, keyData->data, 48);
		    buf[sizeof(buf) - 1] = '\n';

		    fwrite(buf, sizeof(buf), 1, ssl_keylog_iob);
		    fflush(ssl_keylog_iob);
		}
	    }
	}
    }

    rv = ssl3_InitPendingCipherSpec(ss,  pms);
    PK11_FreeSymKey(pms); pms = NULL;

    if (rv != SECSuccess) {
	ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
	goto loser;
    }

    rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, 
				    isTLS ? enc_pms.len + 2 : enc_pms.len);
    if (rv != SECSuccess) {
	goto loser;	/* err set by ssl3_AppendHandshake* */
    }
    if (isTLS) {
    	rv = ssl3_AppendHandshakeVariable(ss, enc_pms.data, enc_pms.len, 2);
    } else {
	rv = ssl3_AppendHandshake(ss, enc_pms.data, enc_pms.len);
    }
    if (rv != SECSuccess) {
	goto loser;	/* err set by ssl3_AppendHandshake* */
    }

    rv = SECSuccess;

loser:
    if (enc_pms.data != NULL) {
	PORT_Free(enc_pms.data);
    }
    if (pms != NULL) {
    	PK11_FreeSymKey(pms);
    }
    return rv;
}

/* Called from ssl3_SendClientKeyExchange(). */
/* Presently, this always uses PKCS11.  There is no bypass for this. */
static SECStatus
sendDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
{
    PK11SymKey *	pms 		= NULL;
    SECStatus           rv    		= SECFailure;
    PRBool              isTLS;
    CK_MECHANISM_TYPE	target;

    SECKEYDHParams	dhParam;		/* DH parameters */
    SECKEYPublicKey	*pubKey = NULL;		/* Ephemeral DH key */
    SECKEYPrivateKey	*privKey = NULL;	/* Ephemeral DH key */

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

    isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);

    /* Copy DH parameters from server key */

    if (svrPubKey->keyType != dhKey) {
	PORT_SetError(SEC_ERROR_BAD_KEY);
	goto loser;
    }
    dhParam.prime.data = svrPubKey->u.dh.prime.data;
    dhParam.prime.len = svrPubKey->u.dh.prime.len;
    dhParam.base.data = svrPubKey->u.dh.base.data;
    dhParam.base.len = svrPubKey->u.dh.base.len;

    /* Generate ephemeral DH keypair */
    privKey = SECKEY_CreateDHPrivateKey(&dhParam, &pubKey, NULL);
    if (!privKey || !pubKey) {
	    ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
	    rv = SECFailure;
	    goto loser;
    }
    PRINT_BUF(50, (ss, "DH public value:",
					pubKey->u.dh.publicValue.data,
					pubKey->u.dh.publicValue.len));

    if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
    else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;

    /* Determine the PMS */

    pms = PK11_PubDerive(privKey, svrPubKey, PR_FALSE, NULL, NULL,
			    CKM_DH_PKCS_DERIVE, target, CKA_DERIVE, 0, NULL);

    if (pms == NULL) {
	ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
	goto loser;
    }

    SECKEY_DestroyPrivateKey(privKey);
    privKey = NULL;

    rv = ssl3_InitPendingCipherSpec(ss,  pms);
    PK11_FreeSymKey(pms); pms = NULL;

    if (rv != SECSuccess) {
	ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
	goto loser;
    }

    rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, 
					pubKey->u.dh.publicValue.len + 2);
    if (rv != SECSuccess) {
	goto loser;	/* err set by ssl3_AppendHandshake* */
    }
    rv = ssl3_AppendHandshakeVariable(ss, 
					pubKey->u.dh.publicValue.data,
					pubKey->u.dh.publicValue.len, 2);
    SECKEY_DestroyPublicKey(pubKey);
    pubKey = NULL;

    if (rv != SECSuccess) {
	goto loser;	/* err set by ssl3_AppendHandshake* */
    }

    rv = SECSuccess;


loser:

    if(pms) PK11_FreeSymKey(pms);
    if(privKey) SECKEY_DestroyPrivateKey(privKey);
    if(pubKey) SECKEY_DestroyPublicKey(pubKey);
    return rv;
}





/* Called from ssl3_HandleServerHelloDone(). */
static SECStatus
ssl3_SendClientKeyExchange(sslSocket *ss)
{
    SECKEYPublicKey *	serverKey 	= NULL;
    SECStatus 		rv 		= SECFailure;
    PRBool              isTLS;

    SSL_TRC(3, ("%d: SSL3[%d]: send client_key_exchange handshake",
		SSL_GETPID(), ss->fd));

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

    if (ss->sec.peerKey == NULL) {
	serverKey = CERT_ExtractPublicKey(ss->sec.peerCert);
	if (serverKey == NULL) {
	    ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
	    return SECFailure;
	}
    } else {
	serverKey = ss->sec.peerKey;
	ss->sec.peerKey = NULL; /* we're done with it now */
    }

    isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
    /* enforce limits on kea key sizes. */
    if (ss->ssl3.hs.kea_def->is_limited) {
	int keyLen = SECKEY_PublicKeyStrength(serverKey);	/* bytes */

	if (keyLen * BPB > ss->ssl3.hs.kea_def->key_size_limit) {
	    if (isTLS)
		(void)SSL3_SendAlert(ss, alert_fatal, export_restriction);
	    else
		(void)ssl3_HandshakeFailure(ss);
	    PORT_SetError(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED);
	    goto loser;
	}
    }

    ss->sec.keaType    = ss->ssl3.hs.kea_def->exchKeyType;
    ss->sec.keaKeyBits = SECKEY_PublicKeyStrengthInBits(serverKey);

    switch (ss->ssl3.hs.kea_def->exchKeyType) {
    case kt_rsa:
	rv = sendRSAClientKeyExchange(ss, serverKey);
	break;

    case kt_dh:
	rv = sendDHClientKeyExchange(ss, serverKey);
	break;

#ifdef NSS_ENABLE_ECC
    case kt_ecdh:
	rv = ssl3_SendECDHClientKeyExchange(ss, serverKey);
	break;
#endif /* NSS_ENABLE_ECC */

    default:
	/* got an unknown or unsupported Key Exchange Algorithm.  */
	SEND_ALERT
	PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
	break;
    }

    SSL_TRC(3, ("%d: SSL3[%d]: DONE sending client_key_exchange",
		SSL_GETPID(), ss->fd));

loser:
    if (serverKey) 
    	SECKEY_DestroyPublicKey(serverKey);
    return rv;	/* err code already set. */
}

/* Called from ssl3_HandleServerHelloDone(). */
static SECStatus
ssl3_SendCertificateVerify(sslSocket *ss)
{
    SECStatus     rv		= SECFailure;
    PRBool        isTLS;
    PRBool        isTLS12;
    SECItem       buf           = {siBuffer, NULL, 0};
    SSL3Hashes    hashes;
    KeyType       keyType;
    unsigned int  len;
    SSL3SignatureAndHashAlgorithm sigAndHash;

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

    SSL_TRC(3, ("%d: SSL3[%d]: send certificate_verify handshake",
		SSL_GETPID(), ss->fd));

    ssl_GetSpecReadLock(ss);
    if (ss->ssl3.hs.hashType == handshake_hash_single &&
	ss->ssl3.hs.backupHash) {
	rv = ssl3_ComputeBackupHandshakeHashes(ss, &hashes);
	PORT_Assert(!ss->ssl3.hs.backupHash);
    } else {
	rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
    }
    ssl_ReleaseSpecReadLock(ss);
    if (rv != SECSuccess) {
	goto done;	/* err code was set by ssl3_ComputeHandshakeHashes */
    }

    isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
    isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
    if (ss->ssl3.platformClientKey) {
#ifdef NSS_PLATFORM_CLIENT_AUTH
	keyType = CERT_GetCertKeyType(
	    &ss->ssl3.clientCertificate->subjectPublicKeyInfo);
	rv = ssl3_PlatformSignHashes(
	    &hashes, ss->ssl3.platformClientKey, &buf, isTLS, keyType);
	ssl_FreePlatformKey(ss->ssl3.platformClientKey);
	ss->ssl3.platformClientKey = (PlatformKey)NULL;
#endif /* NSS_PLATFORM_CLIENT_AUTH */
    } else {
	keyType = ss->ssl3.clientPrivateKey->keyType;
	rv = ssl3_SignHashes(&hashes, ss->ssl3.clientPrivateKey, &buf, isTLS);
	if (rv == SECSuccess) {
	    PK11SlotInfo * slot;
	    sslSessionID * sid   = ss->sec.ci.sid;

	    /* Remember the info about the slot that did the signing.
	    ** Later, when doing an SSL restart handshake, verify this.
	    ** These calls are mere accessors, and can't fail.
	    */
	    slot = PK11_GetSlotFromPrivateKey(ss->ssl3.clientPrivateKey);
	    sid->u.ssl3.clAuthSeries     = PK11_GetSlotSeries(slot);
	    sid->u.ssl3.clAuthSlotID     = PK11_GetSlotID(slot);
	    sid->u.ssl3.clAuthModuleID   = PK11_GetModuleID(slot);
	    sid->u.ssl3.clAuthValid      = PR_TRUE;
	    PK11_FreeSlot(slot);
	}
	SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
	ss->ssl3.clientPrivateKey = NULL;
    }
    if (rv != SECSuccess) {
	goto done;	/* err code was set by ssl3_SignHashes */
    }

    len = buf.len + 2 + (isTLS12 ? 2 : 0);

    rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, len);
    if (rv != SECSuccess) {
	goto done;	/* error code set by AppendHandshake */
    }
    if (isTLS12) {
	rv = ssl3_TLSSignatureAlgorithmForKeyType(keyType,
						  &sigAndHash.sigAlg);
	if (rv != SECSuccess) {
	    goto done;
	}
	sigAndHash.hashAlg = hashes.hashAlg;

	rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash);
	if (rv != SECSuccess) {
	    goto done; 	/* err set by AppendHandshake. */
	}
    }
    rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2);
    if (rv != SECSuccess) {
	goto done;	/* error code set by AppendHandshake */
    }

done:
    if (buf.data)
	PORT_Free(buf.data);
    return rv;
}

/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
 * ssl3 ServerHello message.
 * Caller must hold Handshake and RecvBuf locks.
 */
static SECStatus
ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
    sslSessionID *sid		= ss->sec.ci.sid;
    PRInt32       temp;		/* allow for consume number failure */
    PRBool        suite_found   = PR_FALSE;
    int           i;
    int           errCode	= SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
    SECStatus     rv;
    SECItem       sidBytes 	= {siBuffer, NULL, 0};
    PRBool        sid_match;
    PRBool        isTLS		= PR_FALSE;
    SSL3AlertDescription desc   = illegal_parameter;
    SSL3ProtocolVersion version;

    SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello handshake",
    	SSL_GETPID(), ss->fd));
    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
    PORT_Assert( ss->ssl3.initialized );

    if (ss->ssl3.hs.ws != wait_server_hello) {
        errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO;
	desc    = unexpected_message;
	goto alert_loser;
    }

    /* clean up anything left from previous handshake. */
    if (ss->ssl3.clientCertChain != NULL) {
       CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
       ss->ssl3.clientCertChain = NULL;
    }
    if (ss->ssl3.clientCertificate != NULL) {
       CERT_DestroyCertificate(ss->ssl3.clientCertificate);
       ss->ssl3.clientCertificate = NULL;
    }
    if (ss->ssl3.clientPrivateKey != NULL) {
       SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
       ss->ssl3.clientPrivateKey = NULL;
    }
#ifdef NSS_PLATFORM_CLIENT_AUTH
    if (ss->ssl3.platformClientKey) {
       ssl_FreePlatformKey(ss->ssl3.platformClientKey);
       ss->ssl3.platformClientKey = (PlatformKey)NULL;
    }
#endif  /* NSS_PLATFORM_CLIENT_AUTH */

    if (ss->ssl3.channelID != NULL) {
	SECKEY_DestroyPrivateKey(ss->ssl3.channelID);
	ss->ssl3.channelID = NULL;
    }
    if (ss->ssl3.channelIDPub != NULL) {
	SECKEY_DestroyPublicKey(ss->ssl3.channelIDPub);
	ss->ssl3.channelIDPub = NULL;
    }

    temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
    if (temp < 0) {
    	goto loser; 	/* alert has been sent */
    }
    version = (SSL3ProtocolVersion)temp;

    if (IS_DTLS(ss)) {
	/* RFC 4347 required that you verify that the server versions
	 * match (Section 4.2.1) in the HelloVerifyRequest and the
	 * ServerHello.
	 *
	 * RFC 6347 suggests (SHOULD) that servers always use 1.0
	 * in HelloVerifyRequest and allows the versions not to match,
	 * especially when 1.2 is being negotiated.
	 *
	 * Therefore we do not check for matching here.
	 */
	version = dtls_DTLSVersionToTLSVersion(version);
	if (version == 0) {  /* Insane version number */
            goto alert_loser;
	}
    }

    rv = ssl3_NegotiateVersion(ss, version, PR_FALSE);
    if (rv != SECSuccess) {
    	desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version 
						   : handshake_failure;
	errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
	goto alert_loser;
    }
    isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0);

    rv = ssl3_InitHandshakeHashes(ss);
    if (rv != SECSuccess) {
	desc = internal_error;
	errCode = PORT_GetError();
	goto alert_loser;
    }

    rv = ssl3_ConsumeHandshake(
	ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH, &b, &length);
    if (rv != SECSuccess) {
    	goto loser; 	/* alert has been sent */
    }

    rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length);
    if (rv != SECSuccess) {
    	goto loser; 	/* alert has been sent */
    }
    if (sidBytes.len > SSL3_SESSIONID_BYTES) {
	if (isTLS)
	    desc = decode_error;
	goto alert_loser;	/* malformed. */
    }

    /* find selected cipher suite in our list. */
    temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
    if (temp < 0) {
    	goto loser; 	/* alert has been sent */
    }
    ssl3_config_match_init(ss);
    for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
	ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
	if (temp == suite->cipher_suite) {
	    SSLVersionRange vrange = {ss->version, ss->version};
	    if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange)) {
		/* config_match already checks whether the cipher suite is
		 * acceptable for the version, but the check is repeated here
		 * in order to give a more precise error code. */
		if (!ssl3_CipherSuiteAllowedForVersionRange(temp, &vrange)) {
		    desc    = handshake_failure;
		    errCode = SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION;
		    goto alert_loser;
		}

		break;	/* failure */
	    }
	
	    suite_found = PR_TRUE;
	    break;	/* success */
	}
    }
    if (!suite_found) {
    	desc    = handshake_failure;
	errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
	goto alert_loser;
    }
    ss->ssl3.hs.cipher_suite = (ssl3CipherSuite)temp;
    ss->ssl3.hs.suite_def    = ssl_LookupCipherSuiteDef((ssl3CipherSuite)temp);
    PORT_Assert(ss->ssl3.hs.suite_def);
    if (!ss->ssl3.hs.suite_def) {
    	PORT_SetError(errCode = SEC_ERROR_LIBRARY_FAILURE);
	goto loser;	/* we don't send alerts for our screw-ups. */
    }

    /* find selected compression method in our list. */
    temp = ssl3_ConsumeHandshakeNumber(ss, 1, &b, &length);
    if (temp < 0) {
    	goto loser; 	/* alert has been sent */
    }
    suite_found = PR_FALSE;
    for (i = 0; i < compressionMethodsCount; i++) {
	if (temp == compressions[i]) {
	    if (!compressionEnabled(ss, compressions[i])) {
		break;	/* failure */
	    }
	    suite_found = PR_TRUE;
	    break;	/* success */
    	}
    }
    if (!suite_found) {
    	desc    = handshake_failure;
	errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP;
	goto alert_loser;
    }
    ss->ssl3.hs.compression = (SSLCompressionMethod)temp;

    /* Note that if !isTLS and the extra stuff is not extensions, we
     * do NOT goto alert_loser.
     * There are some old SSL 3.0 implementations that do send stuff
     * after the end of the server hello, and we deliberately ignore
     * such stuff in the interest of maximal interoperability (being
     * "generous in what you accept").
     * Update: Starting in NSS 3.12.6, we handle the renegotiation_info
     * extension in SSL 3.0.
     */
    if (length != 0) {
	SECItem extensions;
	rv = ssl3_ConsumeHandshakeVariable(ss, &extensions, 2, &b, &length);
	if (rv != SECSuccess || length != 0) {
	    if (isTLS)
		goto alert_loser;
	} else {
	    rv = ssl3_HandleHelloExtensions(ss, &extensions.data,
					    &extensions.len);
	    if (rv != SECSuccess)
		goto alert_loser;
	}
    }
    if ((ss->opt.requireSafeNegotiation || 
         (ss->firstHsDone && (ss->peerRequestedProtection ||
	 ss->opt.enableRenegotiation == SSL_RENEGOTIATE_REQUIRES_XTN))) &&
	!ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) {
	desc = handshake_failure;
	errCode = ss->firstHsDone ? SSL_ERROR_RENEGOTIATION_NOT_ALLOWED
	                          : SSL_ERROR_UNSAFE_NEGOTIATION;
	goto alert_loser;
    }

    /* Any errors after this point are not "malformed" errors. */
    desc    = handshake_failure;

    /* we need to call ssl3_SetupPendingCipherSpec here so we can check the
     * key exchange algorithm. */
    rv = ssl3_SetupPendingCipherSpec(ss);
    if (rv != SECSuccess) {
	goto alert_loser;	/* error code is set. */
    }

    /* We may or may not have sent a session id, we may get one back or
     * not and if so it may match the one we sent.
     * Attempt to restore the master secret to see if this is so...
     * Don't consider failure to find a matching SID an error.
     */
    sid_match = (PRBool)(sidBytes.len > 0 &&
	sidBytes.len == sid->u.ssl3.sessionIDLength &&
	!PORT_Memcmp(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len));

    if (sid_match &&
	sid->version == ss->version &&
	sid->u.ssl3.cipherSuite == ss->ssl3.hs.cipher_suite) do {
	ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;

	SECItem       wrappedMS;   /* wrapped master secret. */

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

	/* 3 cases here:
	 * a) key is wrapped (implies using PKCS11)
	 * b) key is unwrapped, but we're still using PKCS11
	 * c) key is unwrapped, and we're bypassing PKCS11.
	 */
	if (sid->u.ssl3.keys.msIsWrapped) {
	    PK11SlotInfo *slot;
	    PK11SymKey *  wrapKey;     /* wrapping key */
	    CK_FLAGS      keyFlags      = 0;

#ifndef NO_PKCS11_BYPASS
	    if (ss->opt.bypassPKCS11) {
		/* we cannot restart a non-bypass session in a 
		** bypass socket.
		*/
		break;  
	    }
#endif
	    /* unwrap master secret with PKCS11 */
	    slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
				     sid->u.ssl3.masterSlotID);
	    if (slot == NULL) {
		break;		/* not considered an error. */
	    }
	    if (!PK11_IsPresent(slot)) {
		PK11_FreeSlot(slot);
		break;		/* not considered an error. */
	    }
	    wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex,
				      sid->u.ssl3.masterWrapMech,
				      sid->u.ssl3.masterWrapSeries,
				      ss->pkcs11PinArg);
	    PK11_FreeSlot(slot);
	    if (wrapKey == NULL) {
		break;		/* not considered an error. */
	    }

	    if (ss->version > SSL_LIBRARY_VERSION_3_0) {	/* isTLS */
		keyFlags = CKF_SIGN | CKF_VERIFY;
	    }

	    wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
	    wrappedMS.len  = sid->u.ssl3.keys.wrapped_master_secret_len;
	    pwSpec->master_secret =
		PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech, 
			    NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
			    CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
	    errCode = PORT_GetError();
	    PK11_FreeSymKey(wrapKey);
	    if (pwSpec->master_secret == NULL) {
		break;	/* errorCode set just after call to UnwrapSymKey. */
	    }
#ifndef NO_PKCS11_BYPASS
	} else if (ss->opt.bypassPKCS11) {
	    /* MS is not wrapped */
	    wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
	    wrappedMS.len  = sid->u.ssl3.keys.wrapped_master_secret_len;
	    memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len);
	    pwSpec->msItem.data = pwSpec->raw_master_secret;
	    pwSpec->msItem.len  = wrappedMS.len;
#endif
	} else {
	    /* We CAN restart a bypass session in a non-bypass socket. */
	    /* need to import the raw master secret to session object */
	    PK11SlotInfo *slot = PK11_GetInternalSlot();
	    wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
	    wrappedMS.len  = sid->u.ssl3.keys.wrapped_master_secret_len;
	    pwSpec->master_secret =  
		PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE, 
				  PK11_OriginUnwrap, CKA_ENCRYPT, 
				  &wrappedMS, NULL);
	    PK11_FreeSlot(slot);
	    if (pwSpec->master_secret == NULL) {
		break; 
	    }
	}

	/* Got a Match */
	SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_hits );

	/* If we sent a session ticket, then this is a stateless resume. */
	if (ss->xtnData.sentSessionTicketInClientHello)
	    SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_stateless_resumes );

	if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
	    ss->ssl3.hs.ws = wait_new_session_ticket;
	else
	    ss->ssl3.hs.ws = wait_change_cipher;

	ss->ssl3.hs.isResuming = PR_TRUE;

	/* copy the peer cert from the SID */
	if (sid->peerCert != NULL) {
	    ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
	    ssl3_CopyPeerCertsFromSID(ss, sid);
	}

	/* NULL value for PMS signifies re-use of the old MS */
	rv = ssl3_InitPendingCipherSpec(ss,  NULL);
	if (rv != SECSuccess) {
	    goto alert_loser;	/* err code was set */
	}
	goto winner;
    } while (0);

    if (sid_match)
	SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_not_ok );
    else
	SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_misses );

    /* throw the old one away */
    sid->u.ssl3.keys.resumable = PR_FALSE;
    if (ss->sec.uncache)
        (*ss->sec.uncache)(sid);
    ssl_FreeSID(sid);

    /* get a new sid */
    ss->sec.ci.sid = sid = ssl3_NewSessionID(ss, PR_FALSE);
    if (sid == NULL) {
	goto alert_loser;	/* memory error is set. */
    }

    sid->version = ss->version;
    sid->u.ssl3.sessionIDLength = sidBytes.len;
    PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len);

    /* Copy Signed Certificate Timestamps, if any. */
    if (ss->xtnData.signedCertTimestamps.data) {
	rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.signedCertTimestamps,
			      &ss->xtnData.signedCertTimestamps);
	if (rv != SECSuccess)
	    goto loser;
    }

    ss->ssl3.hs.isResuming = PR_FALSE;
    ss->ssl3.hs.ws         = wait_server_cert;

winner:
    /* Clean up the temporary pointer to the handshake buffer. */
    ss->xtnData.signedCertTimestamps.data = NULL;
    ss->xtnData.signedCertTimestamps.len = 0;

    /* If we will need a ChannelID key then we make the callback now. This
     * allows the handshake to be restarted cleanly if the callback returns
     * SECWouldBlock. */
    if (ssl3_ExtensionNegotiated(ss, ssl_channel_id_xtn)) {
	rv = ss->getChannelID(ss->getChannelIDArg, ss->fd,
			      &ss->ssl3.channelIDPub, &ss->ssl3.channelID);
	if (rv == SECWouldBlock) {
	    ssl3_SetAlwaysBlock(ss);
	    return rv;
	}
	if (rv != SECSuccess ||
	    ss->ssl3.channelIDPub == NULL ||
	    ss->ssl3.channelID == NULL) {
	    PORT_SetError(SSL_ERROR_GET_CHANNEL_ID_FAILED);
	    desc = internal_error;
	    goto alert_loser;
	}
    }

    return SECSuccess;

alert_loser:
    (void)SSL3_SendAlert(ss, alert_fatal, desc);

loser:
    /* Clean up the temporary pointer to the handshake buffer. */
    ss->xtnData.signedCertTimestamps.data = NULL;
    ss->xtnData.signedCertTimestamps.len = 0;
    errCode = ssl_MapLowLevelError(errCode);
    return SECFailure;
}

/* ssl3_BigIntGreaterThanOne returns true iff |mpint|, taken as an unsigned,
 * big-endian integer is > 1 */
static PRBool
ssl3_BigIntGreaterThanOne(const SECItem* mpint) {
    unsigned char firstNonZeroByte = 0;
    unsigned int i;

    for (i = 0; i < mpint->len; i++) {
	if (mpint->data[i]) {
	    firstNonZeroByte = mpint->data[i];
	    break;
	}
    }

    if (firstNonZeroByte == 0)
	return PR_FALSE;
    if (firstNonZeroByte > 1)
	return PR_TRUE;

    /* firstNonZeroByte == 1, therefore mpint > 1 iff the first non-zero byte
     * is followed by another byte. */
    return (i < mpint->len - 1);
}

/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
 * ssl3 ServerKeyExchange message.
 * Caller must hold Handshake and RecvBuf locks.
 */
static SECStatus
ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
    PLArenaPool *    arena     = NULL;
    SECKEYPublicKey *peerKey   = NULL;
    PRBool           isTLS, isTLS12;
    SECStatus        rv;
    int              errCode   = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
    SSL3AlertDescription desc  = illegal_parameter;
    SSL3Hashes       hashes;
    SECItem          signature = {siBuffer, NULL, 0};
    SSL3SignatureAndHashAlgorithm sigAndHash;

    sigAndHash.hashAlg = SEC_OID_UNKNOWN;

    SSL_TRC(3, ("%d: SSL3[%d]: handle server_key_exchange handshake",
		SSL_GETPID(), ss->fd));
    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );

    if (ss->ssl3.hs.ws != wait_server_key &&
	ss->ssl3.hs.ws != wait_server_cert) {
	errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH;
	desc    = unexpected_message;
	goto alert_loser;
    }
    if (ss->sec.peerCert == NULL) {
	errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH;
	desc    = unexpected_message;
	goto alert_loser;
    }

    isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
    isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);

    switch (ss->ssl3.hs.kea_def->exchKeyType) {

    case kt_rsa: {
	SECItem          modulus   = {siBuffer, NULL, 0};
	SECItem          exponent  = {siBuffer, NULL, 0};

    	rv = ssl3_ConsumeHandshakeVariable(ss, &modulus, 2, &b, &length);
    	if (rv != SECSuccess) {
	    goto loser;		/* malformed. */
	}
    	rv = ssl3_ConsumeHandshakeVariable(ss, &exponent, 2, &b, &length);
    	if (rv != SECSuccess) {
	    goto loser;		/* malformed. */
	}
	if (isTLS12) {
	    rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length,
						       &sigAndHash);
	    if (rv != SECSuccess) {
		goto loser;	/* malformed or unsupported. */
	    }
	    rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(
		    &sigAndHash, ss->sec.peerCert);
	    if (rv != SECSuccess) {
		goto loser;
	    }
	}
    	rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
    	if (rv != SECSuccess) {
	    goto loser;		/* malformed. */
	}
    	if (length != 0) {
	    if (isTLS)
		desc = decode_error;
	    goto alert_loser;		/* malformed. */
	}

	/* failures after this point are not malformed handshakes. */
	/* TLS: send decrypt_error if signature failed. */
    	desc = isTLS ? decrypt_error : handshake_failure;

    	/*
     	 *  check to make sure the hash is signed by right guy
     	 */
	rv = ssl3_ComputeExportRSAKeyHash(sigAndHash.hashAlg, modulus, exponent,
					  &ss->ssl3.hs.client_random,
					  &ss->ssl3.hs.server_random, 
					  &hashes, ss->opt.bypassPKCS11);
        if (rv != SECSuccess) {
	    errCode =
	    	ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
	    goto alert_loser;
	}
        rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
				    isTLS, ss->pkcs11PinArg);
	if (rv != SECSuccess)  {
	    errCode =
	    	ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
	    goto alert_loser;
	}

	/*
	 * we really need to build a new key here because we can no longer
	 * ignore calling SECKEY_DestroyPublicKey. Using the key may allocate
	 * pkcs11 slots and ID's.
	 */
    	arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
	if (arena == NULL) {
	    goto no_memory;
	}

    	peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
    	if (peerKey == NULL) {
            PORT_FreeArena(arena, PR_FALSE);
	    goto no_memory;
	}

	peerKey->arena              = arena;
	peerKey->keyType            = rsaKey;
	peerKey->pkcs11Slot         = NULL;
	peerKey->pkcs11ID           = CK_INVALID_HANDLE;
	if (SECITEM_CopyItem(arena, &peerKey->u.rsa.modulus,        &modulus) ||
	    SECITEM_CopyItem(arena, &peerKey->u.rsa.publicExponent, &exponent))
	{
            PORT_FreeArena(arena, PR_FALSE);
	    goto no_memory;
        }
    	ss->sec.peerKey = peerKey;
    	ss->ssl3.hs.ws = wait_cert_request;
    	return SECSuccess;
    }

    case kt_dh: {
	SECItem          dh_p      = {siBuffer, NULL, 0};
	SECItem          dh_g      = {siBuffer, NULL, 0};
	SECItem          dh_Ys     = {siBuffer, NULL, 0};

    	rv = ssl3_ConsumeHandshakeVariable(ss, &dh_p, 2, &b, &length);
    	if (rv != SECSuccess) {
	    goto loser;		/* malformed. */
	}
	if (dh_p.len < 512/8) {
	    errCode = SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY;
	    goto alert_loser;
	}
    	rv = ssl3_ConsumeHandshakeVariable(ss, &dh_g, 2, &b, &length);
    	if (rv != SECSuccess) {
	    goto loser;		/* malformed. */
	}
	if (dh_g.len > dh_p.len || !ssl3_BigIntGreaterThanOne(&dh_g))
	    goto alert_loser;
    	rv = ssl3_ConsumeHandshakeVariable(ss, &dh_Ys, 2, &b, &length);
    	if (rv != SECSuccess) {
	    goto loser;		/* malformed. */
	}
	if (dh_Ys.len > dh_p.len || !ssl3_BigIntGreaterThanOne(&dh_Ys))
	    goto alert_loser;
	if (isTLS12) {
	    rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length,
						       &sigAndHash);
	    if (rv != SECSuccess) {
		goto loser;	/* malformed or unsupported. */
	    }
	    rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(
		    &sigAndHash, ss->sec.peerCert);
	    if (rv != SECSuccess) {
		goto loser;
	    }
	}
    	rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
    	if (rv != SECSuccess) {
	    goto loser;		/* malformed. */
	}
    	if (length != 0) {
	    if (isTLS)
		desc = decode_error;
	    goto alert_loser;		/* malformed. */
	}

	PRINT_BUF(60, (NULL, "Server DH p", dh_p.data, dh_p.len));
	PRINT_BUF(60, (NULL, "Server DH g", dh_g.data, dh_g.len));
	PRINT_BUF(60, (NULL, "Server DH Ys", dh_Ys.data, dh_Ys.len));

	/* failures after this point are not malformed handshakes. */
	/* TLS: send decrypt_error if signature failed. */
    	desc = isTLS ? decrypt_error : handshake_failure;

    	/*
     	 *  check to make sure the hash is signed by right guy
     	 */
	rv = ssl3_ComputeDHKeyHash(sigAndHash.hashAlg, dh_p, dh_g, dh_Ys,
					  &ss->ssl3.hs.client_random,
					  &ss->ssl3.hs.server_random, 
					  &hashes, ss->opt.bypassPKCS11);
        if (rv != SECSuccess) {
	    errCode =
	    	ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
	    goto alert_loser;
	}
        rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
				    isTLS, ss->pkcs11PinArg);
	if (rv != SECSuccess)  {
	    errCode =
	    	ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
	    goto alert_loser;
	}

	/*
	 * we really need to build a new key here because we can no longer
	 * ignore calling SECKEY_DestroyPublicKey. Using the key may allocate
	 * pkcs11 slots and ID's.
	 */
    	arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
	if (arena == NULL) {
	    goto no_memory;
	}

    	ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
    	if (peerKey == NULL) {
	    goto no_memory;
	}

	peerKey->arena              = arena;
	peerKey->keyType            = dhKey;
	peerKey->pkcs11Slot         = NULL;
	peerKey->pkcs11ID           = CK_INVALID_HANDLE;

	if (SECITEM_CopyItem(arena, &peerKey->u.dh.prime,        &dh_p) ||
	    SECITEM_CopyItem(arena, &peerKey->u.dh.base,         &dh_g) ||
	    SECITEM_CopyItem(arena, &peerKey->u.dh.publicValue,  &dh_Ys))
	{
            PORT_FreeArena(arena, PR_FALSE);
	    goto no_memory;
        }
    	ss->sec.peerKey = peerKey;
    	ss->ssl3.hs.ws = wait_cert_request;
    	return SECSuccess;
    }

#ifdef NSS_ENABLE_ECC
    case kt_ecdh:
	rv = ssl3_HandleECDHServerKeyExchange(ss, b, length);
	return rv;
#endif /* NSS_ENABLE_ECC */

    default:
    	desc    = handshake_failure;
	errCode = SEC_ERROR_UNSUPPORTED_KEYALG;
	break;		/* goto alert_loser; */
    }

alert_loser:
    (void)SSL3_SendAlert(ss, alert_fatal, desc);
loser:
    PORT_SetError( errCode );
    return SECFailure;

no_memory:	/* no-memory error has already been set. */
    ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
    return SECFailure;
}


/*
 * Returns the TLS signature algorithm for the client authentication key and
 * whether it is an RSA or DSA key that may be able to sign only SHA-1 hashes.
 */
static SECStatus
ssl3_ExtractClientKeyInfo(sslSocket *ss,
			  TLSSignatureAlgorithm *sigAlg,
			  PRBool *preferSha1)
{
    SECStatus rv = SECSuccess;
    SECKEYPublicKey *pubk;

    pubk = CERT_ExtractPublicKey(ss->ssl3.clientCertificate);
    if (pubk == NULL) {
	rv = SECFailure;
	goto done;
    }

    rv = ssl3_TLSSignatureAlgorithmForKeyType(pubk->keyType, sigAlg);
    if (rv != SECSuccess) {
	goto done;
    }

#if defined(NSS_PLATFORM_CLIENT_AUTH) && defined(_WIN32)
    /* If the key is in CAPI, assume conservatively that the CAPI service
     * provider may be unable to sign SHA-256 hashes.
     */
    if (ss->ssl3.platformClientKey->dwKeySpec != CERT_NCRYPT_KEY_SPEC) {
	/* CAPI only supports RSA and DSA signatures, so we don't need to
	 * check the key type. */
	*preferSha1 = PR_TRUE;
	goto done;
    }
#endif  /* NSS_PLATFORM_CLIENT_AUTH && _WIN32 */

    /* If the key is a 1024-bit RSA or DSA key, assume conservatively that
     * it may be unable to sign SHA-256 hashes. This is the case for older
     * Estonian ID cards that have 1024-bit RSA keys. In FIPS 186-2 and
     * older, DSA key size is at most 1024 bits and the hash function must
     * be SHA-1.
     */
    if (pubk->keyType == rsaKey || pubk->keyType == dsaKey) {
	*preferSha1 = SECKEY_PublicKeyStrength(pubk) <= 128;
    } else {
	*preferSha1 = PR_FALSE;
    }

done:
    if (pubk)
	SECKEY_DestroyPublicKey(pubk);
    return rv;
}

/* Destroys the backup handshake hash context if we don't need it. Note that
 * this function selects the hash algorithm for client authentication
 * signatures; ssl3_SendCertificateVerify uses the presence of the backup hash
 * to determine whether to use SHA-1 or SHA-256. */
static void
ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss,
					   const SECItem *algorithms)
{
    SECStatus rv;
    TLSSignatureAlgorithm sigAlg;
    PRBool preferSha1;
    PRBool supportsSha1 = PR_FALSE;
    PRBool supportsSha256 = PR_FALSE;
    PRBool needBackupHash = PR_FALSE;
    unsigned int i;

#ifndef NO_PKCS11_BYPASS
    /* Backup handshake hash is not supported in PKCS #11 bypass mode. */
    if (ss->opt.bypassPKCS11) {
	PORT_Assert(!ss->ssl3.hs.backupHash);
	return;
    }
#endif
    PORT_Assert(ss->ssl3.hs.backupHash);

    /* Determine the key's signature algorithm and whether it prefers SHA-1. */
    rv = ssl3_ExtractClientKeyInfo(ss, &sigAlg, &preferSha1);
    if (rv != SECSuccess) {
	goto done;
    }

    /* Determine the server's hash support for that signature algorithm. */
    for (i = 0; i < algorithms->len; i += 2) {
	if (algorithms->data[i+1] == sigAlg) {
	    if (algorithms->data[i] == tls_hash_sha1) {
		supportsSha1 = PR_TRUE;
	    } else if (algorithms->data[i] == tls_hash_sha256) {
		supportsSha256 = PR_TRUE;
	    }
	}
    }

    /* If either the server does not support SHA-256 or the client key prefers
     * SHA-1, leave the backup hash. */
    if (supportsSha1 && (preferSha1 || !supportsSha256)) {
	needBackupHash = PR_TRUE;
    }

done:
    if (!needBackupHash) {
	PK11_DestroyContext(ss->ssl3.hs.backupHash, PR_TRUE);
	ss->ssl3.hs.backupHash = NULL;
    }
}

typedef struct dnameNode {
    struct dnameNode *next;
    SECItem           name;
} dnameNode;

/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
 * ssl3 Certificate Request message.
 * Caller must hold Handshake and RecvBuf locks.
 */
static SECStatus
ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
    PLArenaPool *        arena       = NULL;
    dnameNode *          node;
    PRInt32              remaining;
    PRBool               isTLS       = PR_FALSE;
    PRBool               isTLS12     = PR_FALSE;
    int                  i;
    int                  errCode     = SSL_ERROR_RX_MALFORMED_CERT_REQUEST;
    int                  nnames      = 0;
    SECStatus            rv;
    SSL3AlertDescription desc        = illegal_parameter;
    SECItem              cert_types  = {siBuffer, NULL, 0};
    SECItem              algorithms  = {siBuffer, NULL, 0};
    CERTDistNames        ca_list;
#ifdef NSS_PLATFORM_CLIENT_AUTH
    CERTCertList *       platform_cert_list = NULL;
    CERTCertListNode *   certNode = NULL;
#endif  /* NSS_PLATFORM_CLIENT_AUTH */

    SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_request handshake",
		SSL_GETPID(), ss->fd));
    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );

    if (ss->ssl3.hs.ws != wait_cert_request &&
    	ss->ssl3.hs.ws != wait_server_key) {
	desc    = unexpected_message;
	errCode = SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST;
	goto alert_loser;
    }

    PORT_Assert(ss->ssl3.clientCertChain == NULL);
    PORT_Assert(ss->ssl3.clientCertificate == NULL);
    PORT_Assert(ss->ssl3.clientPrivateKey == NULL);
    PORT_Assert(ss->ssl3.platformClientKey == (PlatformKey)NULL);

    isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
    isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
    rv = ssl3_ConsumeHandshakeVariable(ss, &cert_types, 1, &b, &length);
    if (rv != SECSuccess)
    	goto loser;		/* malformed, alert has been sent */

    PORT_Assert(!ss->requestedCertTypes);
    ss->requestedCertTypes = &cert_types;

    if (isTLS12) {
	rv = ssl3_ConsumeHandshakeVariable(ss, &algorithms, 2, &b, &length);
	if (rv != SECSuccess)
	    goto loser;		/* malformed, alert has been sent */
	/* An empty or odd-length value is invalid.
	 *    SignatureAndHashAlgorithm
	 *      supported_signature_algorithms<2..2^16-2>;
	 */
	if (algorithms.len == 0 || (algorithms.len & 1) != 0)
	    goto alert_loser;
    }

    arena = ca_list.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL)
    	goto no_mem;

    remaining = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
    if (remaining < 0)
    	goto loser;	 	/* malformed, alert has been sent */

    if ((PRUint32)remaining > length)
	goto alert_loser;

    ca_list.head = node = PORT_ArenaZNew(arena, dnameNode);
    if (node == NULL)
    	goto no_mem;

    while (remaining > 0) {
	PRInt32 len;

	if (remaining < 2)
	    goto alert_loser;	/* malformed */

	node->name.len = len = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
	if (len <= 0)
	    goto loser;		/* malformed, alert has been sent */

	remaining -= 2;
	if (remaining < len)
	    goto alert_loser;	/* malformed */

	node->name.data = b;
	b         += len;
	length    -= len;
	remaining -= len;
	nnames++;
	if (remaining <= 0)
	    break;		/* success */

	node->next = PORT_ArenaZNew(arena, dnameNode);
	node = node->next;
	if (node == NULL)
	    goto no_mem;
    }

    ca_list.nnames = nnames;
    ca_list.names  = PORT_ArenaNewArray(arena, SECItem, nnames);
    if (nnames > 0 && ca_list.names == NULL)
        goto no_mem;

    for(i = 0, node = (dnameNode*)ca_list.head;
	i < nnames;
	i++, node = node->next) {
	ca_list.names[i] = node->name;
    }

    if (length != 0)
        goto alert_loser;   	/* malformed */

    desc = no_certificate;
    ss->ssl3.hs.ws = wait_hello_done;

#ifdef NSS_PLATFORM_CLIENT_AUTH
    if (ss->getPlatformClientAuthData != NULL) {
	/* XXX Should pass cert_types and algorithms in this call!! */
        rv = (SECStatus)(*ss->getPlatformClientAuthData)(
                                        ss->getPlatformClientAuthDataArg,
                                        ss->fd, &ca_list,
                                        &platform_cert_list,
                                        (void**)&ss->ssl3.platformClientKey,
                                        &ss->ssl3.clientCertificate,
                                        &ss->ssl3.clientPrivateKey);
    } else
#endif
    if (ss->getClientAuthData != NULL) {
	/* XXX Should pass cert_types and algorithms in this call!! */
	rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg,
						 ss->fd, &ca_list,
						 &ss->ssl3.clientCertificate,
						 &ss->ssl3.clientPrivateKey);
    } else {
	rv = SECFailure; /* force it to send a no_certificate alert */
    }

    switch (rv) {
    case SECWouldBlock:	/* getClientAuthData has put up a dialog box. */
	ssl3_SetAlwaysBlock(ss);
	break;	/* not an error */

    case SECSuccess:
#ifdef NSS_PLATFORM_CLIENT_AUTH
        if (!platform_cert_list || CERT_LIST_EMPTY(platform_cert_list) ||
            !ss->ssl3.platformClientKey) {
            if (platform_cert_list) {
                CERT_DestroyCertList(platform_cert_list);
                platform_cert_list = NULL;
            }
            if (ss->ssl3.platformClientKey) {
                ssl_FreePlatformKey(ss->ssl3.platformClientKey);
                ss->ssl3.platformClientKey = (PlatformKey)NULL;
            }
	    /* Fall through to NSS client auth check */
        } else {
	    certNode = CERT_LIST_HEAD(platform_cert_list);
	    ss->ssl3.clientCertificate = CERT_DupCertificate(certNode->cert);

	    /* Setting ssl3.clientCertChain non-NULL will cause
	     * ssl3_HandleServerHelloDone to call SendCertificate.
	     * Note: clientCertChain should include the EE cert as
	     * clientCertificate is ignored during the actual sending
	     */
	    ss->ssl3.clientCertChain =
		    hack_NewCertificateListFromCertList(platform_cert_list);
	    CERT_DestroyCertList(platform_cert_list);
	    platform_cert_list = NULL;
	    if (ss->ssl3.clientCertChain == NULL) {
		if (ss->ssl3.clientCertificate != NULL) {
		    CERT_DestroyCertificate(ss->ssl3.clientCertificate);
		    ss->ssl3.clientCertificate = NULL;
		}
		if (ss->ssl3.platformClientKey) {
		    ssl_FreePlatformKey(ss->ssl3.platformClientKey);
		    ss->ssl3.platformClientKey = (PlatformKey)NULL;
		}
		goto send_no_certificate;
	    }
	    if (ss->ssl3.hs.hashType == handshake_hash_single) {
		ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms);
	    }
	    break;  /* not an error */
	}
#endif   /* NSS_PLATFORM_CLIENT_AUTH */
        /* check what the callback function returned */
        if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) {
            /* we are missing either the key or cert */
            if (ss->ssl3.clientCertificate) {
                /* got a cert, but no key - free it */
                CERT_DestroyCertificate(ss->ssl3.clientCertificate);
                ss->ssl3.clientCertificate = NULL;
            }
            if (ss->ssl3.clientPrivateKey) {
                /* got a key, but no cert - free it */
                SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
                ss->ssl3.clientPrivateKey = NULL;
            }
            goto send_no_certificate;
        }
	/* Setting ssl3.clientCertChain non-NULL will cause
	 * ssl3_HandleServerHelloDone to call SendCertificate.
	 */
	ss->ssl3.clientCertChain = CERT_CertChainFromCert(
					ss->ssl3.clientCertificate,
					certUsageSSLClient, PR_FALSE);
	if (ss->ssl3.clientCertChain == NULL) {
	    CERT_DestroyCertificate(ss->ssl3.clientCertificate);
	    ss->ssl3.clientCertificate = NULL;
	    SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
	    ss->ssl3.clientPrivateKey = NULL;
	    goto send_no_certificate;
	}
	if (ss->ssl3.hs.hashType == handshake_hash_single) {
	    ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms);
	}
	break;	/* not an error */

    case SECFailure:
    default:
send_no_certificate:
	if (isTLS) {
	    ss->ssl3.sendEmptyCert = PR_TRUE;
	} else {
	    (void)SSL3_SendAlert(ss, alert_warning, no_certificate);
	}
	rv = SECSuccess;
	break;
    }
    goto done;

no_mem:
    rv = SECFailure;
    PORT_SetError(SEC_ERROR_NO_MEMORY);
    goto done;

alert_loser:
    if (isTLS && desc == illegal_parameter)
    	desc = decode_error;
    (void)SSL3_SendAlert(ss, alert_fatal, desc);
loser:
    PORT_SetError(errCode);
    rv = SECFailure;
done:
    ss->requestedCertTypes = NULL;
    if (arena != NULL)
    	PORT_FreeArena(arena, PR_FALSE);
#ifdef NSS_PLATFORM_CLIENT_AUTH
    if (platform_cert_list)
        CERT_DestroyCertList(platform_cert_list);
#endif
    return rv;
}

/*
 * attempt to restart the handshake after asynchronously handling
 * a request for the client's certificate.
 *
 * inputs:
 *	cert	Client cert chosen by application.
 *		Note: ssl takes this reference, and does not bump the
 *		reference count.  The caller should drop its reference
 *		without calling CERT_DestroyCert after calling this function.
 *
 *	key	Private key associated with cert.  This function takes
 *		ownership of the private key, so the caller should drop its
 *		reference without destroying the private key after this
 *		function returns.
 *
 *	certChain  DER-encoded certs, client cert and its signers.
 *		Note: ssl takes this reference, and does not copy the chain.
 *		The caller should drop its reference without destroying the
 *		chain.  SSL will free the chain when it is done with it.
 *
 * Return value: XXX
 *
 * XXX This code only works on the initial handshake on a connection, XXX
 *     It does not work on a subsequent handshake (redo).
 *
 * Caller holds 1stHandshakeLock.
 */
SECStatus
ssl3_RestartHandshakeAfterCertReq(sslSocket *         ss,
				CERTCertificate *    cert,
				SECKEYPrivateKey *   key,
				CERTCertificateList *certChain)
{
    SECStatus        rv          = SECSuccess;

    /* XXX This code only works on the initial handshake on a connection,
    ** XXX It does not work on a subsequent handshake (redo).
    */
    if (ss->handshake != 0) {
	ss->handshake              = ssl_GatherRecord1stHandshake;
	ss->ssl3.clientCertificate = cert;
	ss->ssl3.clientPrivateKey  = key;
	ss->ssl3.clientCertChain   = certChain;
        if (!cert || !key || !certChain) {
            /* we are missing the key, cert, or cert chain */
            if (ss->ssl3.clientCertificate) {
                CERT_DestroyCertificate(ss->ssl3.clientCertificate);
                ss->ssl3.clientCertificate = NULL;
            }
            if (ss->ssl3.clientPrivateKey) {
                SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
                ss->ssl3.clientPrivateKey = NULL;
            }
            if (ss->ssl3.clientCertChain != NULL) {
                CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
                ss->ssl3.clientCertChain = NULL;
            }
            if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) {
                ss->ssl3.sendEmptyCert = PR_TRUE;
            } else {
                (void)SSL3_SendAlert(ss, alert_warning, no_certificate);
            }
	}
    } else {
	if (cert) {
	    CERT_DestroyCertificate(cert);
	}
	if (key) {
	    SECKEY_DestroyPrivateKey(key);
	}
	if (certChain) {
	    CERT_DestroyCertificateList(certChain);
	}
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	rv = SECFailure;
    }
    return rv;
}

static SECStatus
ssl3_CheckFalseStart(sslSocket *ss)
{
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
    PORT_Assert( !ss->ssl3.hs.authCertificatePending );
    PORT_Assert( !ss->ssl3.hs.canFalseStart );

    if (!ss->canFalseStartCallback) {
	SSL_TRC(3, ("%d: SSL[%d]: no false start callback so no false start",
		    SSL_GETPID(), ss->fd));
    } else {
	PRBool maybeFalseStart;
	SECStatus rv;

	/* An attacker can control the selected ciphersuite so we only wish to
	 * do False Start in the case that the selected ciphersuite is
	 * sufficiently strong that the attack can gain no advantage.
	 * Therefore we always require an 80-bit cipher. */
        ssl_GetSpecReadLock(ss);
        maybeFalseStart = ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10;
        ssl_ReleaseSpecReadLock(ss);

	if (!maybeFalseStart) {
	    SSL_TRC(3, ("%d: SSL[%d]: no false start due to weak cipher",
			SSL_GETPID(), ss->fd));
	} else {
	    rv = (ss->canFalseStartCallback)(ss->fd,
					     ss->canFalseStartCallbackData,
					     &ss->ssl3.hs.canFalseStart);
	    if (rv == SECSuccess) {
		SSL_TRC(3, ("%d: SSL[%d]: false start callback returned %s",
			    SSL_GETPID(), ss->fd,
			    ss->ssl3.hs.canFalseStart ? "TRUE" : "FALSE"));
	    } else {
		SSL_TRC(3, ("%d: SSL[%d]: false start callback failed (%s)",
			    SSL_GETPID(), ss->fd,
			    PR_ErrorToName(PR_GetError())));
	    }
	    return rv;
	}
    }

    ss->ssl3.hs.canFalseStart = PR_FALSE;
    return SECSuccess;
}

PRBool
ssl3_WaitingForStartOfServerSecondRound(sslSocket *ss)
{
    PRBool result;

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

    switch (ss->ssl3.hs.ws) {
    case wait_new_session_ticket:
        result = PR_TRUE;
        break;
    case wait_change_cipher:
        result = !ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn);
        break;
    default:
        result = PR_FALSE;
        break;
    }

    return result;
}

static SECStatus ssl3_SendClientSecondRound(sslSocket *ss);

/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
 * ssl3 Server Hello Done message.
 * Caller must hold Handshake and RecvBuf locks.
 */
static SECStatus
ssl3_HandleServerHelloDone(sslSocket *ss)
{
    SECStatus     rv;
    SSL3WaitState ws          = ss->ssl3.hs.ws;

    SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello_done handshake",
		SSL_GETPID(), ss->fd));
    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );

    if (ws != wait_hello_done  &&
        ws != wait_server_cert &&
	ws != wait_server_key  &&
	ws != wait_cert_request) {
	SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE);
	return SECFailure;
    }

    rv = ssl3_SendClientSecondRound(ss);

    return rv;
}

/* Called from ssl3_HandleServerHelloDone and ssl3_AuthCertificateComplete.
 *
 * Caller must hold Handshake and RecvBuf locks.
 */
static SECStatus
ssl3_SendClientSecondRound(sslSocket *ss)
{
    SECStatus rv;
    PRBool sendClientCert;

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

    sendClientCert = !ss->ssl3.sendEmptyCert &&
		     ss->ssl3.clientCertChain  != NULL &&
		     (ss->ssl3.platformClientKey ||
		     ss->ssl3.clientPrivateKey != NULL);

    if (!sendClientCert &&
	ss->ssl3.hs.hashType == handshake_hash_single &&
	ss->ssl3.hs.backupHash) {
	/* Don't need the backup handshake hash. */
	PK11_DestroyContext(ss->ssl3.hs.backupHash, PR_TRUE);
	ss->ssl3.hs.backupHash = NULL;
    }

    /* We must wait for the server's certificate to be authenticated before
     * sending the client certificate in order to disclosing the client
     * certificate to an attacker that does not have a valid cert for the
     * domain we are connecting to.
     *
     * XXX: We should do the same for the NPN extension, but for that we
     * need an option to give the application the ability to leak the NPN
     * information to get better performance.
     *
     * During the initial handshake on a connection, we never send/receive
     * application data until we have authenticated the server's certificate;
     * i.e. we have fully authenticated the handshake before using the cipher
     * specs agreed upon for that handshake. During a renegotiation, we may
     * continue sending and receiving application data during the handshake
     * interleaved with the handshake records. If we were to send the client's
     * second round for a renegotiation before the server's certificate was
     * authenticated, then the application data sent/received after this point
     * would be using cipher spec that hadn't been authenticated. By waiting
     * until the server's certificate has been authenticated during
     * renegotiations, we ensure that renegotiations have the same property
     * as initial handshakes; i.e. we have fully authenticated the handshake
     * before using the cipher specs agreed upon for that handshake for
     * application data.
     */
    if (ss->ssl3.hs.restartTarget) {
	PR_NOT_REACHED("unexpected ss->ssl3.hs.restartTarget");
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	return SECFailure;
    }
    if (ss->ssl3.hs.authCertificatePending &&
	(sendClientCert || ss->ssl3.sendEmptyCert || ss->firstHsDone)) {
	SSL_TRC(3, ("%d: SSL3[%p]: deferring ssl3_SendClientSecondRound because"
		    " certificate authentication is still pending.",
		    SSL_GETPID(), ss->fd));
	ss->ssl3.hs.restartTarget = ssl3_SendClientSecondRound;
	return SECWouldBlock;
    }

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

    if (ss->ssl3.sendEmptyCert) {
	ss->ssl3.sendEmptyCert = PR_FALSE;
	rv = ssl3_SendEmptyCertificate(ss);
	/* Don't send verify */
	if (rv != SECSuccess) {
	    goto loser;	/* error code is set. */
    	}
    } else if (sendClientCert) {
	rv = ssl3_SendCertificate(ss);
	if (rv != SECSuccess) {
	    goto loser;	/* error code is set. */
    	}
    }

    rv = ssl3_SendClientKeyExchange(ss);
    if (rv != SECSuccess) {
    	goto loser;	/* err is set. */
    }

    if (sendClientCert) {
	rv = ssl3_SendCertificateVerify(ss);
	if (rv != SECSuccess) {
	    goto loser;	/* err is set. */
        }
    }

    rv = ssl3_SendChangeCipherSpecs(ss);
    if (rv != SECSuccess) {
	goto loser;	/* err code was set. */
    }

    /* This must be done after we've set ss->ssl3.cwSpec in
     * ssl3_SendChangeCipherSpecs because SSL_GetChannelInfo uses information
     * from cwSpec. This must be done before we call ssl3_CheckFalseStart
     * because the false start callback (if any) may need the information from
     * the functions that depend on this being set.
     */
    ss->enoughFirstHsDone = PR_TRUE;

    if (!ss->firstHsDone) {
	/* XXX: If the server's certificate hasn't been authenticated by this
	 * point, then we may be leaking this NPN message to an attacker.
	 */
	rv = ssl3_SendNextProto(ss);
	if (rv != SECSuccess) {
	    goto loser;	/* err code was set. */
	}
    }

    rv = ssl3_SendEncryptedExtensions(ss);
    if (rv != SECSuccess) {
	goto loser; /* err code was set. */
    }

    if (!ss->firstHsDone) {
	if (ss->opt.enableFalseStart) {
	    if (!ss->ssl3.hs.authCertificatePending) {
		/* When we fix bug 589047, we will need to know whether we are
		 * false starting before we try to flush the client second
		 * round to the network. With that in mind, we purposefully
		 * call ssl3_CheckFalseStart before calling ssl3_SendFinished,
		 * which includes a call to ssl3_FlushHandshake, so that
		 * no application develops a reliance on such flushing being
		 * done before its false start callback is called.
		 */
		ssl_ReleaseXmitBufLock(ss);
		rv = ssl3_CheckFalseStart(ss);
		ssl_GetXmitBufLock(ss);
		if (rv != SECSuccess) {
		    goto loser;
		}
	    } else {
		/* The certificate authentication and the server's Finished
		 * message are racing each other. If the certificate
		 * authentication wins, then we will try to false start in
		 * ssl3_AuthCertificateComplete.
		 */
		SSL_TRC(3, ("%d: SSL3[%p]: deferring false start check because"
			    " certificate authentication is still pending.",
			    SSL_GETPID(), ss->fd));
	    }
	}
    }

    rv = ssl3_SendFinished(ss, 0);
    if (rv != SECSuccess) {
	goto loser;	/* err code was set. */
    }

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

    if (!ss->ssl3.hs.isResuming &&
        ssl3_ExtensionNegotiated(ss, ssl_channel_id_xtn)) {
        /* If we are negotiating ChannelID on a full handshake then we record
         * the handshake hashes in |sid| at this point. They will be needed in
         * the event that we resume this session and use ChannelID on the
         * resumption handshake. */
        SSL3Hashes hashes;
        SECItem *originalHandshakeHash =
            &ss->sec.ci.sid->u.ssl3.originalHandshakeHash;
        PORT_Assert(ss->sec.ci.sid->cached == never_cached);

        ssl_GetSpecReadLock(ss);
        PORT_Assert(ss->version > SSL_LIBRARY_VERSION_3_0);
        rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.cwSpec, &hashes, 0);
        ssl_ReleaseSpecReadLock(ss);
        if (rv != SECSuccess) {
            return rv;
        }

        PORT_Assert(originalHandshakeHash->len == 0);
        originalHandshakeHash->data = PORT_Alloc(hashes.len);
        if (!originalHandshakeHash->data)
            return SECFailure;
        originalHandshakeHash->len = hashes.len;
        memcpy(originalHandshakeHash->data, hashes.u.raw, hashes.len);
    }

    if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
	ss->ssl3.hs.ws = wait_new_session_ticket;
    else
	ss->ssl3.hs.ws = wait_change_cipher;

    PORT_Assert(ssl3_WaitingForStartOfServerSecondRound(ss));

    return SECSuccess;

loser:
    ssl_ReleaseXmitBufLock(ss);
    return rv;
}

/*
 * Routines used by servers
 */
static SECStatus
ssl3_SendHelloRequest(sslSocket *ss)
{
    SECStatus rv;

    SSL_TRC(3, ("%d: SSL3[%d]: send hello_request handshake", SSL_GETPID(),
		ss->fd));

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

    rv = ssl3_AppendHandshakeHeader(ss, hello_request, 0);
    if (rv != SECSuccess) {
	return rv;	/* err set by AppendHandshake */
    }
    rv = ssl3_FlushHandshake(ss, 0);
    if (rv != SECSuccess) {
	return rv;	/* error code set by ssl3_FlushHandshake */
    }
    ss->ssl3.hs.ws = wait_client_hello;
    return SECSuccess;
}

/*
 * Called from:
 *	ssl3_HandleClientHello()
 */
static SECComparison
ssl3_ServerNameCompare(const SECItem *name1, const SECItem *name2)
{
    if (!name1 != !name2) {
        return SECLessThan;
    }
    if (!name1) {
        return SECEqual;
    }
    if (name1->type != name2->type) {
        return SECLessThan;
    }
    return SECITEM_CompareItem(name1, name2);
}

/* Sets memory error when returning NULL.
 * Called from:
 *	ssl3_SendClientHello()
 *	ssl3_HandleServerHello()
 *	ssl3_HandleClientHello()
 *	ssl3_HandleV2ClientHello()
 */
sslSessionID *
ssl3_NewSessionID(sslSocket *ss, PRBool is_server)
{
    sslSessionID *sid;

    sid = PORT_ZNew(sslSessionID);
    if (sid == NULL)
    	return sid;

    if (is_server) {
        const SECItem *  srvName;
        SECStatus        rv = SECSuccess;

        ssl_GetSpecReadLock(ss);	/********************************/
        srvName = &ss->ssl3.prSpec->srvVirtName;
        if (srvName->len && srvName->data) {
            rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.srvName, srvName);
        }
        ssl_ReleaseSpecReadLock(ss); /************************************/
        if (rv != SECSuccess) {
            PORT_Free(sid);
            return NULL;
        }
    }
    sid->peerID		= (ss->peerID == NULL) ? NULL : PORT_Strdup(ss->peerID);
    sid->urlSvrName	= (ss->url    == NULL) ? NULL : PORT_Strdup(ss->url);
    sid->addr           = ss->sec.ci.peer;
    sid->port           = ss->sec.ci.port;
    sid->references     = 1;
    sid->cached         = never_cached;
    sid->version        = ss->version;

    sid->u.ssl3.keys.resumable = PR_TRUE;
    sid->u.ssl3.policy         = SSL_ALLOWED;
    sid->u.ssl3.clientWriteKey = NULL;
    sid->u.ssl3.serverWriteKey = NULL;

    if (is_server) {
	SECStatus rv;
	int       pid = SSL_GETPID();

	sid->u.ssl3.sessionIDLength = SSL3_SESSIONID_BYTES;
	sid->u.ssl3.sessionID[0]    = (pid >> 8) & 0xff;
	sid->u.ssl3.sessionID[1]    =  pid       & 0xff;
	rv = PK11_GenerateRandom(sid->u.ssl3.sessionID + 2,
	                         SSL3_SESSIONID_BYTES -2);
	if (rv != SECSuccess) {
	    ssl_FreeSID(sid);
	    ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
	    return NULL;
    	}
    }
    return sid;
}

/* Called from:  ssl3_HandleClientHello, ssl3_HandleV2ClientHello */
static SECStatus
ssl3_SendServerHelloSequence(sslSocket *ss)
{
    const ssl3KEADef *kea_def;
    SECStatus         rv;

    SSL_TRC(3, ("%d: SSL3[%d]: begin send server_hello sequence",
		SSL_GETPID(), ss->fd));

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

    rv = ssl3_SendServerHello(ss);
    if (rv != SECSuccess) {
	return rv;	/* err code is set. */
    }
    rv = ssl3_SendCertificate(ss);
    if (rv != SECSuccess) {
	return rv;	/* error code is set. */
    }
    rv = ssl3_SendCertificateStatus(ss);
    if (rv != SECSuccess) {
	return rv;	/* error code is set. */
    }
    /* We have to do this after the call to ssl3_SendServerHello,
     * because kea_def is set up by ssl3_SendServerHello().
     */
    kea_def = ss->ssl3.hs.kea_def;
    ss->ssl3.hs.usedStepDownKey = PR_FALSE;

    if (kea_def->is_limited && kea_def->exchKeyType == kt_rsa) {
	/* see if we can legally use the key in the cert. */
	int keyLen;  /* bytes */

	keyLen = PK11_GetPrivateModulusLen(
			    ss->serverCerts[kea_def->exchKeyType].SERVERKEY);

	if (keyLen > 0 &&
	    keyLen * BPB <= kea_def->key_size_limit ) {
	    /* XXX AND cert is not signing only!! */
	    /* just fall through and use it. */
	} else if (ss->stepDownKeyPair != NULL) {
	    ss->ssl3.hs.usedStepDownKey = PR_TRUE;
	    rv = ssl3_SendServerKeyExchange(ss);
	    if (rv != SECSuccess) {
		return rv;	/* err code was set. */
	    }
	} else {
#ifndef HACKED_EXPORT_SERVER
	    PORT_SetError(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED);
	    return rv;
#endif
	}
#ifdef NSS_ENABLE_ECC
    } else if ((kea_def->kea == kea_ecdhe_rsa) ||
	       (kea_def->kea == kea_ecdhe_ecdsa)) {
	rv = ssl3_SendServerKeyExchange(ss);
	if (rv != SECSuccess) {
	    return rv;	/* err code was set. */
	}
#endif /* NSS_ENABLE_ECC */
    }

    if (ss->opt.requestCertificate) {
	rv = ssl3_SendCertificateRequest(ss);
	if (rv != SECSuccess) {
	    return rv;		/* err code is set. */
	}
    }
    rv = ssl3_SendServerHelloDone(ss);
    if (rv != SECSuccess) {
	return rv;		/* err code is set. */
    }

    ss->ssl3.hs.ws = (ss->opt.requestCertificate) ? wait_client_cert
                                               : wait_client_key;
    return SECSuccess;
}

/* An empty TLS Renegotiation Info (RI) extension */
static const PRUint8 emptyRIext[5] = {0xff, 0x01, 0x00, 0x01, 0x00};

/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
 * ssl3 Client Hello message.
 * Caller must hold Handshake and RecvBuf locks.
 */
static SECStatus
ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
    sslSessionID *      sid      = NULL;
    PRInt32		tmp;
    unsigned int        i;
    int                 j;
    SECStatus           rv;
    int                 errCode  = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
    SSL3AlertDescription desc    = illegal_parameter;
    SSL3AlertLevel      level    = alert_fatal;
    SSL3ProtocolVersion version;
    SECItem             sidBytes = {siBuffer, NULL, 0};
    SECItem             cookieBytes = {siBuffer, NULL, 0};
    SECItem             suites   = {siBuffer, NULL, 0};
    SECItem             comps    = {siBuffer, NULL, 0};
    PRBool              haveSpecWriteLock = PR_FALSE;
    PRBool              haveXmitBufLock   = PR_FALSE;

    SSL_TRC(3, ("%d: SSL3[%d]: handle client_hello handshake",
    	SSL_GETPID(), ss->fd));

    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    PORT_Assert( ss->ssl3.initialized );

    /* Get peer name of client */
    rv = ssl_GetPeerInfo(ss);
    if (rv != SECSuccess) {
	return rv;		/* error code is set. */
    }

    /* Clearing the handshake pointers so that ssl_Do1stHandshake won't
     * call ssl2_HandleMessage.
     *
     * The issue here is that TLS ordinarily starts out in
     * ssl2_HandleV3HandshakeRecord() because of the backward-compatibility
     * code paths. That function zeroes these next pointers. But with DTLS,
     * we don't even try to do the v2 ClientHello so we skip that function
     * and need to reset these values here.
     */
    if (IS_DTLS(ss)) {
	ss->nextHandshake     = 0;
	ss->securityHandshake = 0;
    }

    /* We might be starting session renegotiation in which case we should
     * clear previous state.
     */
    PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));
    ss->statelessResume = PR_FALSE;

    if ((ss->ssl3.hs.ws != wait_client_hello) &&
	(ss->ssl3.hs.ws != idle_handshake)) {
	desc    = unexpected_message;
	errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO;
	goto alert_loser;
    }
    if (ss->ssl3.hs.ws == idle_handshake  &&
        ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) {
	desc    = no_renegotiation;
	level   = alert_warning;
	errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED;
	goto alert_loser;
    }

    if (IS_DTLS(ss)) {
	dtls_RehandshakeCleanup(ss);
    }

    tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
    if (tmp < 0)
	goto loser;		/* malformed, alert already sent */

    /* Translate the version */
    if (IS_DTLS(ss)) {
	ss->clientHelloVersion = version =
	    dtls_DTLSVersionToTLSVersion((SSL3ProtocolVersion)tmp);
    } else {
	ss->clientHelloVersion = version = (SSL3ProtocolVersion)tmp;
    }

    rv = ssl3_NegotiateVersion(ss, version, PR_TRUE);
    if (rv != SECSuccess) {
    	desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version 
	                                           : handshake_failure;
	errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
	goto alert_loser;
    }

    rv = ssl3_InitHandshakeHashes(ss);
    if (rv != SECSuccess) {
	desc = internal_error;
	errCode = PORT_GetError();
	goto alert_loser;
    }

    /* grab the client random data. */
    rv = ssl3_ConsumeHandshake(
	ss, &ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH, &b, &length);
    if (rv != SECSuccess) {
	goto loser;		/* malformed */
    }

    /* grab the client's SID, if present. */
    rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length);
    if (rv != SECSuccess) {
	goto loser;		/* malformed */
    }

    /* grab the client's cookie, if present. */
    if (IS_DTLS(ss)) {
	rv = ssl3_ConsumeHandshakeVariable(ss, &cookieBytes, 1, &b, &length);
	if (rv != SECSuccess) {
	    goto loser;		/* malformed */
	}
    }

    /* grab the list of cipher suites. */
    rv = ssl3_ConsumeHandshakeVariable(ss, &suites, 2, &b, &length);
    if (rv != SECSuccess) {
	goto loser;		/* malformed */
    }

    /* If the ClientHello version is less than our maximum version, check for a
     * TLS_FALLBACK_SCSV and reject the connection if found. */
    if (ss->vrange.max > ss->clientHelloVersion) {
	for (i = 0; i + 1 < suites.len; i += 2) {
	    PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1];
	    if (suite_i != TLS_FALLBACK_SCSV)
		continue;
	    desc = inappropriate_fallback;
	    errCode = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT;
	    goto alert_loser;
	}
    }

    /* grab the list of compression methods. */
    rv = ssl3_ConsumeHandshakeVariable(ss, &comps, 1, &b, &length);
    if (rv != SECSuccess) {
	goto loser;		/* malformed */
    }

    desc = handshake_failure;

    /* Handle TLS hello extensions for SSL3 & TLS. We do not know if
     * we are restarting a previous session until extensions have been
     * parsed, since we might have received a SessionTicket extension.
     * Note: we allow extensions even when negotiating SSL3 for the sake
     * of interoperability (and backwards compatibility).
     */

    if (length) {
	/* Get length of hello extensions */
	PRInt32 extension_length;
	extension_length = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
	if (extension_length < 0) {
	    goto loser;				/* alert already sent */
	}
	if (extension_length != length) {
	    ssl3_DecodeError(ss);		/* send alert */
	    goto loser;
	}
	rv = ssl3_HandleHelloExtensions(ss, &b, &length);
	if (rv != SECSuccess) {
	    goto loser;		/* malformed */
	}
    }
    if (!ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) {
    	/* If we didn't receive an RI extension, look for the SCSV,
	 * and if found, treat it just like an empty RI extension
	 * by processing a local copy of an empty RI extension.
	 */
	for (i = 0; i + 1 < suites.len; i += 2) {
	    PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1];
	    if (suite_i == TLS_EMPTY_RENEGOTIATION_INFO_SCSV) {
		SSL3Opaque * b2 = (SSL3Opaque *)emptyRIext;
		PRUint32     L2 = sizeof emptyRIext;
		(void)ssl3_HandleHelloExtensions(ss, &b2, &L2);
	    	break;
	    }
	}
    }
    if (ss->firstHsDone &&
        (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_REQUIRES_XTN ||
        ss->opt.enableRenegotiation == SSL_RENEGOTIATE_TRANSITIONAL) && 
	!ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) {
	desc    = no_renegotiation;
	level   = alert_warning;
	errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED;
	goto alert_loser;
    }
    if ((ss->opt.requireSafeNegotiation || 
         (ss->firstHsDone && ss->peerRequestedProtection)) &&
	!ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) {
	desc = handshake_failure;
	errCode = SSL_ERROR_UNSAFE_NEGOTIATION;
    	goto alert_loser;
    }

    /* We do stateful resumes only if either of the following
     * conditions are satisfied: (1) the client does not support the
     * session ticket extension, or (2) the client support the session
     * ticket extension, but sent an empty ticket.
     */
    if (!ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) ||
	ss->xtnData.emptySessionTicket) {
	if (sidBytes.len > 0 && !ss->opt.noCache) {
	    SSL_TRC(7, ("%d: SSL3[%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]));
	    if (ssl_sid_lookup) {
		sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sidBytes.data, 
					sidBytes.len, ss->dbHandle);
	    } else {
		errCode = SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED;
		goto loser;
	    }
	}
    } else if (ss->statelessResume) {
	/* Fill in the client's session ID if doing a stateless resume.
	 * (When doing stateless resumes, server echos client's SessionID.)
	 */
	sid = ss->sec.ci.sid;
	PORT_Assert(sid != NULL);  /* Should have already been filled in.*/

	if (sidBytes.len > 0 && sidBytes.len <= SSL3_SESSIONID_BYTES) {
	    sid->u.ssl3.sessionIDLength = sidBytes.len;
	    PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data,
		sidBytes.len);
	    sid->u.ssl3.sessionIDLength = sidBytes.len;
	} else {
	    sid->u.ssl3.sessionIDLength = 0;
	}
	ss->sec.ci.sid = NULL;
    }

    /* We only send a session ticket extension if the client supports
     * the extension and we are unable to do either a stateful or
     * stateless resume.
     *
     * TODO: send a session ticket if performing a stateful
     * resumption.  (As per RFC4507, a server may issue a session
     * ticket while doing a (stateless or stateful) session resume,
     * but OpenSSL-0.9.8g does not accept session tickets while
     * resuming.)
     */
    if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) && sid == NULL) {
	ssl3_RegisterServerHelloExtensionSender(ss,
	    ssl_session_ticket_xtn, ssl3_SendSessionTicketXtn);
    }

    if (sid != NULL) {
	/* We've found a session cache entry for this client.
	 * Now, if we're going to require a client-auth cert,
	 * and we don't already have this client's cert in the session cache,
	 * and this is the first handshake on this connection (not a redo),
	 * then drop this old cache entry and start a new session.
	 */
	if ((sid->peerCert == NULL) && ss->opt.requestCertificate &&
	    ((ss->opt.requireCertificate == SSL_REQUIRE_ALWAYS) ||
	     (ss->opt.requireCertificate == SSL_REQUIRE_NO_ERROR) ||
	     ((ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE) 
	      && !ss->firstHsDone))) {

	    SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_not_ok );
	    if (ss->sec.uncache)
                ss->sec.uncache(sid);
	    ssl_FreeSID(sid);
	    sid = NULL;
	}
    }

#ifdef NSS_ENABLE_ECC
    /* Disable any ECC cipher suites for which we have no cert. */
    ssl3_FilterECCipherSuitesByServerCerts(ss);
#endif

    if (IS_DTLS(ss)) {
	ssl3_DisableNonDTLSSuites(ss);
    }

    if (!ssl3_HasGCMSupport()) {
	ssl3_DisableGCMSuites(ss);
    }

#ifdef PARANOID
    /* Look for a matching cipher suite. */
    j = ssl3_config_match_init(ss);
    if (j <= 0) {		/* no ciphers are working/supported by PK11 */
    	errCode = PORT_GetError();	/* error code is already set. */
	goto alert_loser;
    }
#endif

    /* If we already have a session for this client, be sure to pick the
    ** same cipher suite and compression method we picked before.
    ** This is not a loop, despite appearances.
    */
    if (sid) do {
	ssl3CipherSuiteCfg *suite;
#ifdef PARANOID
	SSLVersionRange vrange = {ss->version, ss->version};
#endif

	/* Check that the cached compression method is still enabled. */
	if (!compressionEnabled(ss, sid->u.ssl3.compression))
	    break;

	/* Check that the cached compression method is in the client's list */
	for (i = 0; i < comps.len; i++) {
	    if (comps.data[i] == sid->u.ssl3.compression)
		break;
	}
	if (i == comps.len)
	    break;

	suite = ss->cipherSuites;
	/* Find the entry for the cipher suite used in the cached session. */
	for (j = ssl_V3_SUITES_IMPLEMENTED; j > 0; --j, ++suite) {
	    if (suite->cipher_suite == sid->u.ssl3.cipherSuite)
		break;
	}
	PORT_Assert(j > 0);
	if (j <= 0)
	    break;
#ifdef PARANOID
	/* Double check that the cached cipher suite is still enabled,
	 * implemented, and allowed by policy.  Might have been disabled.
	 * The product policy won't change during the process lifetime.  
	 * Implemented ("isPresent") shouldn't change for servers.
	 */
	if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange))
	    break;
#else
	if (!suite->enabled)
	    break;
#endif
	/* Double check that the cached cipher suite is in the client's list */
	for (i = 0; i + 1 < suites.len; i += 2) {
	    PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1];
	    if (suite_i == suite->cipher_suite) {
		ss->ssl3.hs.cipher_suite = suite->cipher_suite;
		ss->ssl3.hs.suite_def =
		    ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);

		/* Use the cached compression method. */
		ss->ssl3.hs.compression = sid->u.ssl3.compression;
		goto compression_found;
	    }
	}
    } while (0);

    /* START A NEW SESSION */

#ifndef PARANOID
    /* Look for a matching cipher suite. */
    j = ssl3_config_match_init(ss);
    if (j <= 0) {		/* no ciphers are working/supported by PK11 */
    	errCode = PORT_GetError();	/* error code is already set. */
	goto alert_loser;
    }
#endif

    /* Select a cipher suite.
    **
    ** NOTE: This suite selection algorithm should be the same as the one in
    ** ssl3_HandleV2ClientHello().
    **
    ** If TLS 1.0 is enabled, we could handle the case where the client
    ** offered TLS 1.1 but offered only export cipher suites by choosing TLS
    ** 1.0 and selecting one of those export cipher suites. However, a secure
    ** TLS 1.1 client should not have export cipher suites enabled at all,
    ** and a TLS 1.1 client should definitely not be offering *only* export
    ** cipher suites. Therefore, we refuse to negotiate export cipher suites
    ** with any client that indicates support for TLS 1.1 or higher when we
    ** (the server) have TLS 1.1 support enabled.
    */
    for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
	ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
	SSLVersionRange vrange = {ss->version, ss->version};
	if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange)) {
	    continue;
	}
	for (i = 0; i + 1 < suites.len; i += 2) {
	    PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1];
	    if (suite_i == suite->cipher_suite) {
		ss->ssl3.hs.cipher_suite = suite->cipher_suite;
		ss->ssl3.hs.suite_def =
		    ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
		goto suite_found;
	    }
	}
    }
    errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
    goto alert_loser;

suite_found:
    /* Select a compression algorithm. */
    for (i = 0; i < comps.len; i++) {
	if (!compressionEnabled(ss, comps.data[i]))
	    continue;
	for (j = 0; j < compressionMethodsCount; j++) {
	    if (comps.data[i] == compressions[j]) {
		ss->ssl3.hs.compression = 
					(SSLCompressionMethod)compressions[j];
		goto compression_found;
	    }
	}
    }
    errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP;
    				/* null compression must be supported */
    goto alert_loser;

compression_found:
    suites.data = NULL;
    comps.data = NULL;

    ss->sec.send = ssl3_SendApplicationData;

    /* If there are any failures while processing the old sid,
     * we don't consider them to be errors.  Instead, We just behave
     * as if the client had sent us no sid to begin with, and make a new one.
     */
    if (sid != NULL) do {
	ssl3CipherSpec *pwSpec;
	SECItem         wrappedMS;  	/* wrapped key */

	if (sid->version != ss->version  ||
	    sid->u.ssl3.cipherSuite != ss->ssl3.hs.cipher_suite ||
	    sid->u.ssl3.compression != ss->ssl3.hs.compression) {
	    break;	/* not an error */
	}

	if (ss->sec.ci.sid) {
	    if (ss->sec.uncache)
                ss->sec.uncache(ss->sec.ci.sid);
	    PORT_Assert(ss->sec.ci.sid != sid);  /* should be impossible, but ... */
	    if (ss->sec.ci.sid != sid) {
		ssl_FreeSID(ss->sec.ci.sid);
	    }
	    ss->sec.ci.sid = NULL;
	}
	/* we need to resurrect the master secret.... */

	ssl_GetSpecWriteLock(ss);  haveSpecWriteLock = PR_TRUE;
	pwSpec = ss->ssl3.pwSpec;
	if (sid->u.ssl3.keys.msIsWrapped) {
	    PK11SymKey *    wrapKey; 	/* wrapping key */
	    CK_FLAGS        keyFlags      = 0;
#ifndef NO_PKCS11_BYPASS
	    if (ss->opt.bypassPKCS11) {
		/* we cannot restart a non-bypass session in a 
		** bypass socket.
		*/
		break;  
	    }
#endif

	    wrapKey = getWrappingKey(ss, NULL, sid->u.ssl3.exchKeyType,
				     sid->u.ssl3.masterWrapMech, 
				     ss->pkcs11PinArg);
	    if (!wrapKey) {
		/* we have a SID cache entry, but no wrapping key for it??? */
		break;
	    }

	    if (ss->version > SSL_LIBRARY_VERSION_3_0) {	/* isTLS */
		keyFlags = CKF_SIGN | CKF_VERIFY;
	    }

	    wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
	    wrappedMS.len  = sid->u.ssl3.keys.wrapped_master_secret_len;

	    /* unwrap the master secret. */
	    pwSpec->master_secret =
		PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech, 
			    NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
			    CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
	    PK11_FreeSymKey(wrapKey);
	    if (pwSpec->master_secret == NULL) {
		break;	/* not an error */
	    }
#ifndef NO_PKCS11_BYPASS
	} else if (ss->opt.bypassPKCS11) {
	    wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
	    wrappedMS.len  = sid->u.ssl3.keys.wrapped_master_secret_len;
	    memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len);
	    pwSpec->msItem.data = pwSpec->raw_master_secret;
	    pwSpec->msItem.len  = wrappedMS.len;
#endif
	} else {
	    /* We CAN restart a bypass session in a non-bypass socket. */
	    /* need to import the raw master secret to session object */
	    PK11SlotInfo * slot;
	    wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
	    wrappedMS.len  = sid->u.ssl3.keys.wrapped_master_secret_len;
	    slot = PK11_GetInternalSlot();
	    pwSpec->master_secret =  
		PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE, 
				  PK11_OriginUnwrap, CKA_ENCRYPT, &wrappedMS, 
				  NULL);
	    PK11_FreeSlot(slot);
	    if (pwSpec->master_secret == NULL) {
		break;	/* not an error */
	    }
	}
	ss->sec.ci.sid = sid;
	if (sid->peerCert != NULL) {
	    ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
	    ssl3_CopyPeerCertsFromSID(ss, sid);
	}

	/*
	 * Old SID passed all tests, so resume this old session.
	 *
	 * XXX make sure compression still matches
	 */
	SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_hits );
	if (ss->statelessResume)
	    SSL_AtomicIncrementLong(& ssl3stats.hch_sid_stateless_resumes );
	ss->ssl3.hs.isResuming = PR_TRUE;

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

	/* server sids don't remember the server cert we previously sent,
	** but they do remember the kea type we originally used, so we
	** can locate it again, provided that the current ssl socket
	** has had its server certs configured the same as the previous one.
	*/
	ss->sec.localCert     = 
		CERT_DupCertificate(ss->serverCerts[sid->keaType].serverCert);

        /* Copy cached name in to pending spec */
        if (sid != NULL &&
            sid->version > SSL_LIBRARY_VERSION_3_0 &&
            sid->u.ssl3.srvName.len && sid->u.ssl3.srvName.data) {
            /* Set server name from sid */
            SECItem *sidName = &sid->u.ssl3.srvName;
            SECItem *pwsName = &ss->ssl3.pwSpec->srvVirtName;
            if (pwsName->data) {
                SECITEM_FreeItem(pwsName, PR_FALSE);
            }
            rv = SECITEM_CopyItem(NULL, pwsName, sidName);
            if (rv != SECSuccess) {
                errCode = PORT_GetError();
                desc = internal_error;
                goto alert_loser;
            }
        }

        /* Clean up sni name array */
        if (ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn) &&
            ss->xtnData.sniNameArr) {
            PORT_Free(ss->xtnData.sniNameArr);
            ss->xtnData.sniNameArr = NULL;
            ss->xtnData.sniNameArrSize = 0;
        }

	ssl_GetXmitBufLock(ss); haveXmitBufLock = PR_TRUE;

	rv = ssl3_SendServerHello(ss);
	if (rv != SECSuccess) {
	    errCode = PORT_GetError();
	    goto loser;
	}

	if (haveSpecWriteLock) {
	    ssl_ReleaseSpecWriteLock(ss);
	    haveSpecWriteLock = PR_FALSE;
	}

	/* NULL value for PMS signifies re-use of the old MS */
	rv = ssl3_InitPendingCipherSpec(ss,  NULL);
	if (rv != SECSuccess) {
	    errCode = PORT_GetError();
	    goto loser;
	}

	rv = ssl3_SendChangeCipherSpecs(ss);
	if (rv != SECSuccess) {
	    errCode = PORT_GetError();
	    goto loser;
	}
	rv = ssl3_SendFinished(ss, 0);
	ss->ssl3.hs.ws = wait_change_cipher;
	if (rv != SECSuccess) {
	    errCode = PORT_GetError();
	    goto loser;
	}

	if (haveXmitBufLock) {
	    ssl_ReleaseXmitBufLock(ss);
	    haveXmitBufLock = PR_FALSE;
	}

        return SECSuccess;
    } while (0);

    if (haveSpecWriteLock) {
	ssl_ReleaseSpecWriteLock(ss);
	haveSpecWriteLock = PR_FALSE;
    }

    if (sid) { 	/* we had a sid, but it's no longer valid, free it */
	SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_not_ok );
	if (ss->sec.uncache)
            ss->sec.uncache(sid);
	ssl_FreeSID(sid);
	sid = NULL;
    }
    SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_misses );

    if (ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) {
        int ret = 0;
        if (ss->sniSocketConfig) do { /* not a loop */
            ret = SSL_SNI_SEND_ALERT;
            /* If extension is negotiated, the len of names should > 0. */
            if (ss->xtnData.sniNameArrSize) {
                /* Calling client callback to reconfigure the socket. */
                ret = (SECStatus)(*ss->sniSocketConfig)(ss->fd,
                                         ss->xtnData.sniNameArr,
                                      ss->xtnData.sniNameArrSize,
                                          ss->sniSocketConfigArg);
            }
            if (ret <= SSL_SNI_SEND_ALERT) {
                /* Application does not know the name or was not able to
                 * properly reconfigure the socket. */
                errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;
                desc = unrecognized_name;
                break;
            } else if (ret == SSL_SNI_CURRENT_CONFIG_IS_USED) {
                SECStatus       rv = SECSuccess;
                SECItem *       cwsName, *pwsName;

                ssl_GetSpecWriteLock(ss);  /*******************************/
                pwsName = &ss->ssl3.pwSpec->srvVirtName;
                cwsName = &ss->ssl3.cwSpec->srvVirtName;
#ifndef SSL_SNI_ALLOW_NAME_CHANGE_2HS
                /* not allow name change on the 2d HS */
                if (ss->firstHsDone) {
                    if (ssl3_ServerNameCompare(pwsName, cwsName)) {
                        ssl_ReleaseSpecWriteLock(ss);  /******************/
                        errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;
                        desc = handshake_failure;
                        ret = SSL_SNI_SEND_ALERT;
                        break;
                    }
                }
#endif
                if (pwsName->data) {
                    SECITEM_FreeItem(pwsName, PR_FALSE);
                }
                if (cwsName->data) {
                    rv = SECITEM_CopyItem(NULL, pwsName, cwsName);
                }
                ssl_ReleaseSpecWriteLock(ss);  /**************************/
                if (rv != SECSuccess) {
                    errCode = SSL_ERROR_INTERNAL_ERROR_ALERT;
                    desc = internal_error;
                    ret = SSL_SNI_SEND_ALERT;
                    break;
                }
            } else if (ret < ss->xtnData.sniNameArrSize) {
                /* Application has configured new socket info. Lets check it
                 * and save the name. */
                SECStatus       rv;
                SECItem *       name = &ss->xtnData.sniNameArr[ret];
                int             configedCiphers;
                SECItem *       pwsName;

                /* get rid of the old name and save the newly picked. */
                /* This code is protected by ssl3HandshakeLock. */
                ssl_GetSpecWriteLock(ss);  /*******************************/
#ifndef SSL_SNI_ALLOW_NAME_CHANGE_2HS
                /* not allow name change on the 2d HS */
                if (ss->firstHsDone) {
                    SECItem *cwsName = &ss->ssl3.cwSpec->srvVirtName;
                    if (ssl3_ServerNameCompare(name, cwsName)) {
                        ssl_ReleaseSpecWriteLock(ss);  /******************/
                        errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;
                        desc = handshake_failure;
                        ret = SSL_SNI_SEND_ALERT;
                        break;
                    }
                }
#endif
                pwsName = &ss->ssl3.pwSpec->srvVirtName;
                if (pwsName->data) {
                    SECITEM_FreeItem(pwsName, PR_FALSE);
                }
                rv = SECITEM_CopyItem(NULL, pwsName, name);
                ssl_ReleaseSpecWriteLock(ss);  /***************************/
                if (rv != SECSuccess) {
                    errCode = SSL_ERROR_INTERNAL_ERROR_ALERT;
                    desc = internal_error;
                    ret = SSL_SNI_SEND_ALERT;
                    break;
                }
                configedCiphers = ssl3_config_match_init(ss);
                if (configedCiphers <= 0) {
                    /* no ciphers are working/supported */
                    errCode = PORT_GetError();
                    desc = handshake_failure;
                    ret = SSL_SNI_SEND_ALERT;
                    break;
                }
                /* Need to tell the client that application has picked
                 * the name from the offered list and reconfigured the socket.
                 */
                ssl3_RegisterServerHelloExtensionSender(ss, ssl_server_name_xtn,
                                                        ssl3_SendServerNameXtn);
            } else {
                /* Callback returned index outside of the boundary. */
                PORT_Assert(ret < ss->xtnData.sniNameArrSize);
                errCode = SSL_ERROR_INTERNAL_ERROR_ALERT;
                desc = internal_error;
                ret = SSL_SNI_SEND_ALERT;
                break;
            }
        } while (0);
        /* Free sniNameArr. The data that each SECItem in the array
         * points into is the data from the input buffer "b". It will
         * not be available outside the scope of this or it's child
         * functions.*/
        if (ss->xtnData.sniNameArr) {
            PORT_Free(ss->xtnData.sniNameArr);
            ss->xtnData.sniNameArr = NULL;
            ss->xtnData.sniNameArrSize = 0;
        }
        if (ret <= SSL_SNI_SEND_ALERT) {
            /* desc and errCode should be set. */
            goto alert_loser;
        }
    }
#ifndef SSL_SNI_ALLOW_NAME_CHANGE_2HS
    else if (ss->firstHsDone) {
        /* Check that we don't have the name is current spec
         * if this extension was not negotiated on the 2d hs. */
        PRBool passed = PR_TRUE;
        ssl_GetSpecReadLock(ss);  /*******************************/
        if (ss->ssl3.cwSpec->srvVirtName.data) {
            passed = PR_FALSE;
        }
        ssl_ReleaseSpecReadLock(ss);  /***************************/
        if (!passed) {
            errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;
            desc = handshake_failure;
            goto alert_loser;
        }
    }
#endif

    sid = ssl3_NewSessionID(ss, PR_TRUE);
    if (sid == NULL) {
	errCode = PORT_GetError();
	goto loser;	/* memory error is set. */
    }
    ss->sec.ci.sid = sid;

    ss->ssl3.hs.isResuming = PR_FALSE;
    ssl_GetXmitBufLock(ss);
    rv = ssl3_SendServerHelloSequence(ss);
    ssl_ReleaseXmitBufLock(ss);
    if (rv != SECSuccess) {
	errCode = PORT_GetError();
	goto loser;
    }

    if (haveXmitBufLock) {
	ssl_ReleaseXmitBufLock(ss);
	haveXmitBufLock = PR_FALSE;
    }

    return SECSuccess;

alert_loser:
    if (haveSpecWriteLock) {
	ssl_ReleaseSpecWriteLock(ss);
	haveSpecWriteLock = PR_FALSE;
    }
    (void)SSL3_SendAlert(ss, level, desc);
    /* FALLTHRU */
loser:
    if (haveSpecWriteLock) {
	ssl_ReleaseSpecWriteLock(ss);
	haveSpecWriteLock = PR_FALSE;
    }

    if (haveXmitBufLock) {
	ssl_ReleaseXmitBufLock(ss);
	haveXmitBufLock = PR_FALSE;
    }

    PORT_SetError(errCode);
    return SECFailure;
}

/*
 * ssl3_HandleV2ClientHello is used when a V2 formatted hello comes
 * in asking to use the V3 handshake.
 * Called from ssl2_HandleClientHelloMessage() in sslcon.c
 */
SECStatus
ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length)
{
    sslSessionID *      sid 		= NULL;
    unsigned char *     suites;
    unsigned char *     random;
    SSL3ProtocolVersion version;
    SECStatus           rv;
    int                 i;
    int                 j;
    int                 sid_length;
    int                 suite_length;
    int                 rand_length;
    int                 errCode  = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
    SSL3AlertDescription desc    = handshake_failure;

    SSL_TRC(3, ("%d: SSL3[%d]: handle v2 client_hello", SSL_GETPID(), ss->fd));

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

    ssl_GetSSL3HandshakeLock(ss);

    PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));

    rv = ssl3_InitState(ss);
    if (rv != SECSuccess) {
	ssl_ReleaseSSL3HandshakeLock(ss);
	return rv;		/* ssl3_InitState has set the error code. */
    }
    rv = ssl3_RestartHandshakeHashes(ss);
    if (rv != SECSuccess) {
	ssl_ReleaseSSL3HandshakeLock(ss);
	return rv;
    }

    if (ss->ssl3.hs.ws != wait_client_hello) {
	desc    = unexpected_message;
	errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO;
	goto loser;	/* alert_loser */
    }

    version      = (buffer[1] << 8) | buffer[2];
    suite_length = (buffer[3] << 8) | buffer[4];
    sid_length   = (buffer[5] << 8) | buffer[6];
    rand_length  = (buffer[7] << 8) | buffer[8];
    ss->clientHelloVersion = version;

    rv = ssl3_NegotiateVersion(ss, version, PR_TRUE);
    if (rv != SECSuccess) {
	/* send back which ever alert client will understand. */
    	desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version : handshake_failure;
	errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
	goto alert_loser;
    }

    rv = ssl3_InitHandshakeHashes(ss);
    if (rv != SECSuccess) {
	desc = internal_error;
	errCode = PORT_GetError();
	goto alert_loser;
    }

    /* if we get a non-zero SID, just ignore it. */
    if (length !=
        SSL_HL_CLIENT_HELLO_HBYTES + suite_length + sid_length + rand_length) {
	SSL_DBG(("%d: SSL3[%d]: bad v2 client hello message, len=%d should=%d",
		 SSL_GETPID(), ss->fd, length,
		 SSL_HL_CLIENT_HELLO_HBYTES + suite_length + sid_length +
		 rand_length));
	goto loser;	/* malformed */	/* alert_loser */
    }

    suites = buffer + SSL_HL_CLIENT_HELLO_HBYTES;
    random = suites + suite_length + sid_length;

    if (rand_length < SSL_MIN_CHALLENGE_BYTES ||
	rand_length > SSL_MAX_CHALLENGE_BYTES) {
	goto loser;	/* malformed */	/* alert_loser */
    }

    PORT_Assert(SSL_MAX_CHALLENGE_BYTES == SSL3_RANDOM_LENGTH);

    PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
    PORT_Memcpy(
	&ss->ssl3.hs.client_random.rand[SSL3_RANDOM_LENGTH - rand_length],
	random, rand_length);

    PRINT_BUF(60, (ss, "client random:", &ss->ssl3.hs.client_random.rand[0],
		   SSL3_RANDOM_LENGTH));
#ifdef NSS_ENABLE_ECC
    /* Disable any ECC cipher suites for which we have no cert. */
    ssl3_FilterECCipherSuitesByServerCerts(ss);
#endif
    i = ssl3_config_match_init(ss);
    if (i <= 0) {
    	errCode = PORT_GetError();	/* error code is already set. */
	goto alert_loser;
    }

    /* Select a cipher suite.
    **
    ** NOTE: This suite selection algorithm should be the same as the one in
    ** ssl3_HandleClientHello().
    **
    ** See the comments about export cipher suites in ssl3_HandleClientHello().
    */
    for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
	ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
	SSLVersionRange vrange = {ss->version, ss->version};
	if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange)) {
	    continue;
	}
	for (i = 0; i+2 < suite_length; i += 3) {
	    PRUint32 suite_i = (suites[i] << 16)|(suites[i+1] << 8)|suites[i+2];
	    if (suite_i == suite->cipher_suite) {
		ss->ssl3.hs.cipher_suite = suite->cipher_suite;
		ss->ssl3.hs.suite_def =
		    ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
		goto suite_found;
	    }
	}
    }
    errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
    goto alert_loser;

suite_found:

    /* Look for the SCSV, and if found, treat it just like an empty RI 
     * extension by processing a local copy of an empty RI extension.
     */
    for (i = 0; i+2 < suite_length; i += 3) {
	PRUint32 suite_i = (suites[i] << 16) | (suites[i+1] << 8) | suites[i+2];
	if (suite_i == TLS_EMPTY_RENEGOTIATION_INFO_SCSV) {
	    SSL3Opaque * b2 = (SSL3Opaque *)emptyRIext;
	    PRUint32     L2 = sizeof emptyRIext;
	    (void)ssl3_HandleHelloExtensions(ss, &b2, &L2);
	    break;
	}
    }

    if (ss->opt.requireSafeNegotiation &&
	!ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) {
	desc = handshake_failure;
	errCode = SSL_ERROR_UNSAFE_NEGOTIATION;
    	goto alert_loser;
    }

    ss->ssl3.hs.compression = ssl_compression_null;
    ss->sec.send            = ssl3_SendApplicationData;

    /* we don't even search for a cache hit here.  It's just a miss. */
    SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_misses );
    sid = ssl3_NewSessionID(ss, PR_TRUE);
    if (sid == NULL) {
    	errCode = PORT_GetError();
	goto loser;	/* memory error is set. */
    }
    ss->sec.ci.sid = sid;
    /* do not worry about memory leak of sid since it now belongs to ci */

    /* We have to update the handshake hashes before we can send stuff */
    rv = ssl3_UpdateHandshakeHashes(ss, buffer, length);
    if (rv != SECSuccess) {
    	errCode = PORT_GetError();
	goto loser;
    }

    ssl_GetXmitBufLock(ss);
    rv = ssl3_SendServerHelloSequence(ss);
    ssl_ReleaseXmitBufLock(ss);
    if (rv != SECSuccess) {
    	errCode = PORT_GetError();
	goto loser;
    }

    /* XXX_1 	The call stack to here is:
     * ssl_Do1stHandshake -> ssl2_HandleClientHelloMessage -> here.
     * ssl2_HandleClientHelloMessage returns whatever we return here.
     * ssl_Do1stHandshake will continue looping if it gets back either
     *		SECSuccess or SECWouldBlock.
     * SECSuccess is preferable here.  See XXX_1 in sslgathr.c.
     */
    ssl_ReleaseSSL3HandshakeLock(ss);
    return SECSuccess;

alert_loser:
    SSL3_SendAlert(ss, alert_fatal, desc);
loser:
    ssl_ReleaseSSL3HandshakeLock(ss);
    PORT_SetError(errCode);
    return SECFailure;
}

/* The negotiated version number has been already placed in ss->version.
**
** Called from:  ssl3_HandleClientHello                     (resuming session),
** 	ssl3_SendServerHelloSequence <- ssl3_HandleClientHello   (new session),
** 	ssl3_SendServerHelloSequence <- ssl3_HandleV2ClientHello (new session)
*/
static SECStatus
ssl3_SendServerHello(sslSocket *ss)
{
    sslSessionID *sid;
    SECStatus     rv;
    PRUint32      maxBytes = 65535;
    PRUint32      length;
    PRInt32       extensions_len = 0;
    SSL3ProtocolVersion version;

    SSL_TRC(3, ("%d: SSL3[%d]: send server_hello handshake", SSL_GETPID(),
		ss->fd));

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

    if (!IS_DTLS(ss)) {
	PORT_Assert(MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_3_0));

	if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_3_0)) {
	    PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
	    return SECFailure;
	}
    } else {
	PORT_Assert(MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_DTLS_1_0));

	if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_DTLS_1_0)) {
	    PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
	    return SECFailure;
	}
    }

    sid = ss->sec.ci.sid;

    extensions_len = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes,
					       &ss->xtnData.serverSenders[0]);
    if (extensions_len > 0)
    	extensions_len += 2; /* Add sizeof total extension length */

    length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH + 1 +
             ((sid == NULL) ? 0: sid->u.ssl3.sessionIDLength) +
	     sizeof(ssl3CipherSuite) + 1 + extensions_len;
    rv = ssl3_AppendHandshakeHeader(ss, server_hello, length);
    if (rv != SECSuccess) {
	return rv;	/* err set by AppendHandshake. */
    }

    if (IS_DTLS(ss)) {
	version = dtls_TLSVersionToDTLSVersion(ss->version);
    } else {
	version = ss->version;
    }

    rv = ssl3_AppendHandshakeNumber(ss, version, 2);
    if (rv != SECSuccess) {
	return rv;	/* err set by AppendHandshake. */
    }
    rv = ssl3_GetNewRandom(&ss->ssl3.hs.server_random);
    if (rv != SECSuccess) {
	ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
	return rv;
    }
    rv = ssl3_AppendHandshake(
	ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH);
    if (rv != SECSuccess) {
	return rv;	/* err set by AppendHandshake. */
    }

    if (sid)
	rv = ssl3_AppendHandshakeVariable(
	    ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1);
    else
	rv = ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
    if (rv != SECSuccess) {
	return rv;	/* err set by AppendHandshake. */
    }

    rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.cipher_suite, 2);
    if (rv != SECSuccess) {
	return rv;	/* err set by AppendHandshake. */
    }
    rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.compression, 1);
    if (rv != SECSuccess) {
	return rv;	/* err set by AppendHandshake. */
    }
    if (extensions_len) {
	PRInt32 sent_len;

    	extensions_len -= 2;
	rv = ssl3_AppendHandshakeNumber(ss, extensions_len, 2);
	if (rv != SECSuccess) 
	    return rv;	/* err set by ssl3_SetupPendingCipherSpec */
	sent_len = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, extensions_len,
					   &ss->xtnData.serverSenders[0]);
        PORT_Assert(sent_len == extensions_len);
	if (sent_len != extensions_len) {
	    if (sent_len >= 0)
	    	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	    return SECFailure;
	}
    }
    rv = ssl3_SetupPendingCipherSpec(ss);
    if (rv != SECSuccess) {
	return rv;	/* err set by ssl3_SetupPendingCipherSpec */
    }

    return SECSuccess;
}

/* ssl3_PickSignatureHashAlgorithm selects a hash algorithm to use when signing
 * elements of the handshake. (The negotiated cipher suite determines the
 * signature algorithm.) Prior to TLS 1.2, the MD5/SHA1 combination is always
 * used. With TLS 1.2, a client may advertise its support for signature and
 * hash combinations. */
static SECStatus
ssl3_PickSignatureHashAlgorithm(sslSocket *ss,
				SSL3SignatureAndHashAlgorithm* out)
{
    TLSSignatureAlgorithm sigAlg;
    unsigned int i, j;
    /* hashPreference expresses our preferences for hash algorithms, most
     * preferable first. */
    static const PRUint8 hashPreference[] = {
	tls_hash_sha256,
	tls_hash_sha384,
	tls_hash_sha512,
	tls_hash_sha1,
    };

    switch (ss->ssl3.hs.kea_def->kea) {
    case kea_rsa:
    case kea_rsa_export:
    case kea_rsa_export_1024:
    case kea_dh_rsa:
    case kea_dh_rsa_export:
    case kea_dhe_rsa:
    case kea_dhe_rsa_export:
    case kea_rsa_fips:
    case kea_ecdh_rsa:
    case kea_ecdhe_rsa:
	sigAlg = tls_sig_rsa;
	break;
    case kea_dh_dss:
    case kea_dh_dss_export:
    case kea_dhe_dss:
    case kea_dhe_dss_export:
	sigAlg = tls_sig_dsa;
	break;
    case kea_ecdh_ecdsa:
    case kea_ecdhe_ecdsa:
	sigAlg = tls_sig_ecdsa;
	break;
    default:
	PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
	return SECFailure;
    }
    out->sigAlg = sigAlg;

    if (ss->version <= SSL_LIBRARY_VERSION_TLS_1_1) {
	/* SEC_OID_UNKNOWN means the MD5/SHA1 combo hash used in TLS 1.1 and
	 * prior. */
	out->hashAlg = SEC_OID_UNKNOWN;
	return SECSuccess;
    }

    if (ss->ssl3.hs.numClientSigAndHash == 0) {
	/* If the client didn't provide any signature_algorithms extension then
	 * we can assume that they support SHA-1:
	 * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
	out->hashAlg = SEC_OID_SHA1;
	return SECSuccess;
    }

    for (i = 0; i < PR_ARRAY_SIZE(hashPreference); i++) {
	for (j = 0; j < ss->ssl3.hs.numClientSigAndHash; j++) {
	    const SSL3SignatureAndHashAlgorithm* sh =
		&ss->ssl3.hs.clientSigAndHash[j];
	    if (sh->sigAlg == sigAlg && sh->hashAlg == hashPreference[i]) {
		out->hashAlg = sh->hashAlg;
		return SECSuccess;
	    }
	}
    }

    PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
    return SECFailure;
}


static SECStatus
ssl3_SendServerKeyExchange(sslSocket *ss)
{
    const ssl3KEADef * kea_def     = ss->ssl3.hs.kea_def;
    SECStatus          rv          = SECFailure;
    int                length;
    PRBool             isTLS;
    SECItem            signed_hash = {siBuffer, NULL, 0};
    SSL3Hashes         hashes;
    SECKEYPublicKey *  sdPub;	/* public key for step-down */
    SSL3SignatureAndHashAlgorithm sigAndHash;

    SSL_TRC(3, ("%d: SSL3[%d]: send server_key_exchange handshake",
		SSL_GETPID(), ss->fd));

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

    if (ssl3_PickSignatureHashAlgorithm(ss, &sigAndHash) != SECSuccess) {
	return SECFailure;
    }

    switch (kea_def->exchKeyType) {
    case kt_rsa:
	/* Perform SSL Step-Down here. */
	sdPub = ss->stepDownKeyPair->pubKey;
	PORT_Assert(sdPub != NULL);
	if (!sdPub) {
	    PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
	    return SECFailure;
	}
	rv = ssl3_ComputeExportRSAKeyHash(sigAndHash.hashAlg,
					  sdPub->u.rsa.modulus,
					  sdPub->u.rsa.publicExponent,
	                                  &ss->ssl3.hs.client_random,
	                                  &ss->ssl3.hs.server_random,
					  &hashes, ss->opt.bypassPKCS11);
        if (rv != SECSuccess) {
	    ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
	    return rv;
	}

	isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
	rv = ssl3_SignHashes(&hashes, ss->serverCerts[kt_rsa].SERVERKEY, 
	                     &signed_hash, isTLS);
        if (rv != SECSuccess) {
	    goto loser;		/* ssl3_SignHashes has set err. */
	}
	if (signed_hash.data == NULL) {
	    /* how can this happen and rv == SECSuccess ?? */
	    PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
	    goto loser;
	}
	length = 2 + sdPub->u.rsa.modulus.len +
	         2 + sdPub->u.rsa.publicExponent.len +
	         2 + signed_hash.len;

	rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
	if (rv != SECSuccess) {
	    goto loser; 	/* err set by AppendHandshake. */
	}

	rv = ssl3_AppendHandshakeVariable(ss, sdPub->u.rsa.modulus.data,
					  sdPub->u.rsa.modulus.len, 2);
	if (rv != SECSuccess) {
	    goto loser; 	/* err set by AppendHandshake. */
	}

	rv = ssl3_AppendHandshakeVariable(
				ss, sdPub->u.rsa.publicExponent.data,
				sdPub->u.rsa.publicExponent.len, 2);
	if (rv != SECSuccess) {
	    goto loser; 	/* err set by AppendHandshake. */
	}

	if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
	    rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash);
	    if (rv != SECSuccess) {
		goto loser; 	/* err set by AppendHandshake. */
	    }
	}

	rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
	                                  signed_hash.len, 2);
	if (rv != SECSuccess) {
	    goto loser; 	/* err set by AppendHandshake. */
	}
	PORT_Free(signed_hash.data);
	return SECSuccess;

#ifdef NSS_ENABLE_ECC
    case kt_ecdh: {
	rv = ssl3_SendECDHServerKeyExchange(ss, &sigAndHash);
	return rv;
    }
#endif /* NSS_ENABLE_ECC */

    case kt_dh:
    case kt_null:
    default:
	PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
	break;
    }
loser:
    if (signed_hash.data != NULL) 
    	PORT_Free(signed_hash.data);
    return SECFailure;
}


static SECStatus
ssl3_SendCertificateRequest(sslSocket *ss)
{
    PRBool         isTLS12;
    SECItem *      name;
    CERTDistNames *ca_list;
    const PRUint8 *certTypes;
    const PRUint8 *sigAlgs;
    SECItem *      names	= NULL;
    SECStatus      rv;
    int            length;
    int            i;
    int            calen	= 0;
    int            nnames	= 0;
    int            certTypesLength;
    int            sigAlgsLength;

    SSL_TRC(3, ("%d: SSL3[%d]: send certificate_request handshake",
		SSL_GETPID(), ss->fd));

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

    isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);

    /* ssl3.ca_list is initialized to NULL, and never changed. */
    ca_list = ss->ssl3.ca_list;
    if (!ca_list) {
	ca_list = ssl3_server_ca_list;
    }

    if (ca_list != NULL) {
	names = ca_list->names;
	nnames = ca_list->nnames;
    }

    for (i = 0, name = names; i < nnames; i++, name++) {
	calen += 2 + name->len;
    }

    certTypes       = certificate_types;
    certTypesLength = sizeof certificate_types;
    sigAlgs         = supported_signature_algorithms;
    sigAlgsLength   = sizeof supported_signature_algorithms;

    length = 1 + certTypesLength + 2 + calen;
    if (isTLS12) {
	length += 2 + sigAlgsLength;
    }

    rv = ssl3_AppendHandshakeHeader(ss, certificate_request, length);
    if (rv != SECSuccess) {
	return rv; 		/* err set by AppendHandshake. */
    }
    rv = ssl3_AppendHandshakeVariable(ss, certTypes, certTypesLength, 1);
    if (rv != SECSuccess) {
	return rv; 		/* err set by AppendHandshake. */
    }
    if (isTLS12) {
	rv = ssl3_AppendHandshakeVariable(ss, sigAlgs, sigAlgsLength, 2);
	if (rv != SECSuccess) {
	    return rv; 		/* err set by AppendHandshake. */
	}
    }
    rv = ssl3_AppendHandshakeNumber(ss, calen, 2);
    if (rv != SECSuccess) {
	return rv; 		/* err set by AppendHandshake. */
    }
    for (i = 0, name = names; i < nnames; i++, name++) {
	rv = ssl3_AppendHandshakeVariable(ss, name->data, name->len, 2);
	if (rv != SECSuccess) {
	    return rv; 		/* err set by AppendHandshake. */
	}
    }

    return SECSuccess;
}

static SECStatus
ssl3_SendServerHelloDone(sslSocket *ss)
{
    SECStatus rv;

    SSL_TRC(3, ("%d: SSL3[%d]: send server_hello_done handshake",
		SSL_GETPID(), ss->fd));

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

    rv = ssl3_AppendHandshakeHeader(ss, server_hello_done, 0);
    if (rv != SECSuccess) {
	return rv; 		/* err set by AppendHandshake. */
    }
    rv = ssl3_FlushHandshake(ss, 0);
    if (rv != SECSuccess) {
	return rv;	/* error code set by ssl3_FlushHandshake */
    }
    return SECSuccess;
}

/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
 * ssl3 Certificate Verify message
 * Caller must hold Handshake and RecvBuf locks.
 */
static SECStatus
ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
			     SSL3Hashes *hashes)
{
    SECItem              signed_hash = {siBuffer, NULL, 0};
    SECStatus            rv;
    int                  errCode     = SSL_ERROR_RX_MALFORMED_CERT_VERIFY;
    SSL3AlertDescription desc        = handshake_failure;
    PRBool               isTLS, isTLS12;
    SSL3SignatureAndHashAlgorithm sigAndHash;

    SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_verify handshake",
		SSL_GETPID(), ss->fd));
    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );

    isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
    isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);

    if (ss->ssl3.hs.ws != wait_cert_verify || ss->sec.peerCert == NULL) {
	desc    = unexpected_message;
	errCode = SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY;
	goto alert_loser;
    }

    if (isTLS12) {
	rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length,
						   &sigAndHash);
	if (rv != SECSuccess) {
	    goto loser;	/* malformed or unsupported. */
	}
	rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(
		&sigAndHash, ss->sec.peerCert);
	if (rv != SECSuccess) {
	    errCode = PORT_GetError();
	    desc = decrypt_error;
	    goto alert_loser;
	}

	/* We only support CertificateVerify messages that use the handshake
	 * hash. */
	if (sigAndHash.hashAlg != hashes->hashAlg) {
	    errCode = SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM;
	    desc = decrypt_error;
	    goto alert_loser;
	}
    }

    rv = ssl3_ConsumeHandshakeVariable(ss, &signed_hash, 2, &b, &length);
    if (rv != SECSuccess) {
	goto loser;		/* malformed. */
    }

    /* XXX verify that the key & kea match */
    rv = ssl3_VerifySignedHashes(hashes, ss->sec.peerCert, &signed_hash,
				 isTLS, ss->pkcs11PinArg);
    if (rv != SECSuccess) {
    	errCode = PORT_GetError();
	desc = isTLS ? decrypt_error : handshake_failure;
	goto alert_loser;
    }

    signed_hash.data = NULL;

    if (length != 0) {
	desc    = isTLS ? decode_error : illegal_parameter;
	goto alert_loser;	/* malformed */
    }
    ss->ssl3.hs.ws = wait_change_cipher;
    return SECSuccess;

alert_loser:
    SSL3_SendAlert(ss, alert_fatal, desc);
loser:
    PORT_SetError(errCode);
    return SECFailure;
}


/* find a slot that is able to generate a PMS and wrap it with RSA.
 * Then generate and return the PMS.
 * If the serverKeySlot parameter is non-null, this function will use
 * that slot to do the job, otherwise it will find a slot.
 *
 * Called from  ssl3_DeriveConnectionKeysPKCS11()  (above)
 *		sendRSAClientKeyExchange()         (above)
 *		ssl3_HandleRSAClientKeyExchange()  (below)
 * Caller must hold the SpecWriteLock, the SSL3HandshakeLock
 */
static PK11SymKey *
ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
                    PK11SlotInfo * serverKeySlot)
{
    PK11SymKey *      pms		= NULL;
    PK11SlotInfo *    slot		= serverKeySlot;
    void *	      pwArg 		= ss->pkcs11PinArg;
    SECItem           param;
    CK_VERSION 	      version;
    CK_MECHANISM_TYPE mechanism_array[3];

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

    if (slot == NULL) {
	SSLCipherAlgorithm calg;
	/* The specReadLock would suffice here, but we cannot assert on
	** read locks.  Also, all the callers who call with a non-null
	** slot already hold the SpecWriteLock.
	*/
	PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
	PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);

        calg = spec->cipher_def->calg;
	PORT_Assert(alg2Mech[calg].calg == calg);

	/* First get an appropriate slot.  */
	mechanism_array[0] = CKM_SSL3_PRE_MASTER_KEY_GEN;
	mechanism_array[1] = CKM_RSA_PKCS;
	mechanism_array[2] = alg2Mech[calg].cmech;

	slot = PK11_GetBestSlotMultiple(mechanism_array, 3, pwArg);
	if (slot == NULL) {
	   /* can't find a slot with all three, find a slot with the minimum */
	    slot = PK11_GetBestSlotMultiple(mechanism_array, 2, pwArg);
	    if (slot == NULL) {
		PORT_SetError(SSL_ERROR_TOKEN_SLOT_NOT_FOUND);
		return pms;	/* which is NULL */
	    }
	}
    }

    /* Generate the pre-master secret ...  */
    if (IS_DTLS(ss)) {
	SSL3ProtocolVersion temp;

	temp = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion);
	version.major = MSB(temp);
	version.minor = LSB(temp);
    } else {
	version.major = MSB(ss->clientHelloVersion);
	version.minor = LSB(ss->clientHelloVersion);
    }

    param.data = (unsigned char *)&version;
    param.len  = sizeof version;

    pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN, &param, 0, pwArg);
    if (!serverKeySlot)
	PK11_FreeSlot(slot);
    if (pms == NULL) {
	ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
    }
    return pms;
}

/* Note: The Bleichenbacher attack on PKCS#1 necessitates that we NEVER
 * return any indication of failure of the Client Key Exchange message,
 * where that failure is caused by the content of the client's message.
 * This function must not return SECFailure for any reason that is directly
 * or indirectly caused by the content of the client's encrypted PMS.
 * We must not send an alert and also not drop the connection.
 * Instead, we generate a random PMS.  This will cause a failure
 * in the processing the finished message, which is exactly where
 * the failure must occur.
 *
 * Called from ssl3_HandleClientKeyExchange
 */
static SECStatus
ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
                                SSL3Opaque *b,
				PRUint32 length,
				SECKEYPrivateKey *serverKey)
{
    PK11SymKey *      pms;
#ifndef NO_PKCS11_BYPASS
    unsigned char *   cr     = (unsigned char *)&ss->ssl3.hs.client_random;
    unsigned char *   sr     = (unsigned char *)&ss->ssl3.hs.server_random;
    ssl3CipherSpec *  pwSpec = ss->ssl3.pwSpec;
    unsigned int      outLen = 0;
#endif
    PRBool            isTLS  = PR_FALSE;
    SECStatus         rv;
    SECItem           enc_pms;
    unsigned char     rsaPmsBuf[SSL3_RSA_PMS_LENGTH];
    SECItem           pmsItem = {siBuffer, NULL, 0};

    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
    PORT_Assert( ss->ssl3.prSpec == ss->ssl3.pwSpec );

    enc_pms.data = b;
    enc_pms.len  = length;
    pmsItem.data = rsaPmsBuf;
    pmsItem.len  = sizeof rsaPmsBuf;

    if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
	PRInt32 kLen;
	kLen = ssl3_ConsumeHandshakeNumber(ss, 2, &enc_pms.data, &enc_pms.len);
	if (kLen < 0) {
	    PORT_SetError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
	    return SECFailure;
	}
	if ((unsigned)kLen < enc_pms.len) {
	    enc_pms.len = kLen;
	}
	isTLS = PR_TRUE;
    } else {
	isTLS = (PRBool)(ss->ssl3.hs.kea_def->tls_keygen != 0);
    }

#ifndef NO_PKCS11_BYPASS
    if (ss->opt.bypassPKCS11) {
	/* TRIPLE BYPASS, get PMS directly from RSA decryption.
	 * Use PK11_PrivDecryptPKCS1 to decrypt the PMS to a buffer, 
	 * then, check for version rollback attack, then 
	 * do the equivalent of ssl3_DeriveMasterSecret, placing the MS in 
	 * pwSpec->msItem.  Finally call ssl3_InitPendingCipherSpec with 
	 * ss and NULL, so that it will use the MS we've already derived here. 
	 */

	rv = PK11_PrivDecryptPKCS1(serverKey, rsaPmsBuf, &outLen, 
				   sizeof rsaPmsBuf, enc_pms.data, enc_pms.len);
	if (rv != SECSuccess) {
	    /* triple bypass failed.  Let's try for a double bypass. */
	    goto double_bypass;
	} else if (ss->opt.detectRollBack) {
	    SSL3ProtocolVersion client_version = 
					 (rsaPmsBuf[0] << 8) | rsaPmsBuf[1];

	    if (IS_DTLS(ss)) {
		client_version = dtls_DTLSVersionToTLSVersion(client_version);
	    }

	    if (client_version != ss->clientHelloVersion) {
		/* Version roll-back detected. ensure failure.  */
		rv = PK11_GenerateRandom(rsaPmsBuf, sizeof rsaPmsBuf);
	    }
	}
	/* have PMS, build MS without PKCS11 */
	rv = ssl3_MasterKeyDeriveBypass(pwSpec, cr, sr, &pmsItem, isTLS, 
					PR_TRUE);
	if (rv != SECSuccess) {
	    pwSpec->msItem.data = pwSpec->raw_master_secret;
	    pwSpec->msItem.len  = SSL3_MASTER_SECRET_LENGTH;
	    PK11_GenerateRandom(pwSpec->msItem.data, pwSpec->msItem.len);
	}
	rv = ssl3_InitPendingCipherSpec(ss,  NULL);
    } else 
#endif
    {
#ifndef NO_PKCS11_BYPASS
double_bypass:
#endif
	/*
	 * unwrap pms out of the incoming buffer
	 * Note: CKM_SSL3_MASTER_KEY_DERIVE is NOT the mechanism used to do 
	 *	the unwrap.  Rather, it is the mechanism with which the 
	 *      unwrapped pms will be used.
	 */
	pms = PK11_PubUnwrapSymKey(serverKey, &enc_pms,
				   CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0);
	if (pms != NULL) {
	    PRINT_BUF(60, (ss, "decrypted premaster secret:",
			   PK11_GetKeyData(pms)->data,
			   PK11_GetKeyData(pms)->len));
	} else {
	    /* unwrap failed. Generate a bogus PMS and carry on. */
	    PK11SlotInfo *  slot   = PK11_GetSlotFromPrivateKey(serverKey);

	    ssl_GetSpecWriteLock(ss);
	    pms = ssl3_GenerateRSAPMS(ss, ss->ssl3.prSpec, slot);
	    ssl_ReleaseSpecWriteLock(ss);
	    PK11_FreeSlot(slot);
	}

	if (pms == NULL) {
	    /* last gasp.  */
	    ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
	    return SECFailure;
	}

	/* This step will derive the MS from the PMS, among other things. */
	rv = ssl3_InitPendingCipherSpec(ss,  pms);
	PK11_FreeSymKey(pms);
    }

    if (rv != SECSuccess) {
	SEND_ALERT
	return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
    }
    return SECSuccess;
}


/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
 * ssl3 ClientKeyExchange message from the remote client
 * Caller must hold Handshake and RecvBuf locks.
 */
static SECStatus
ssl3_HandleClientKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
    SECKEYPrivateKey *serverKey         = NULL;
    SECStatus         rv;
    const ssl3KEADef *kea_def;
    ssl3KeyPair     *serverKeyPair      = NULL;
#ifdef NSS_ENABLE_ECC
    SECKEYPublicKey *serverPubKey       = NULL;
#endif /* NSS_ENABLE_ECC */

    SSL_TRC(3, ("%d: SSL3[%d]: handle client_key_exchange handshake",
		SSL_GETPID(), ss->fd));

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

    if (ss->ssl3.hs.ws != wait_client_key) {
	SSL3_SendAlert(ss, alert_fatal, unexpected_message);
    	PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH);
	return SECFailure;
    }

    kea_def   = ss->ssl3.hs.kea_def;

    if (ss->ssl3.hs.usedStepDownKey) {
	 PORT_Assert(kea_def->is_limited /* XXX OR cert is signing only */
		 && kea_def->exchKeyType == kt_rsa 
		 && ss->stepDownKeyPair != NULL);
	 if (!kea_def->is_limited  ||
	      kea_def->exchKeyType != kt_rsa ||
	      ss->stepDownKeyPair == NULL) {
	 	/* shouldn't happen, don't use step down if it does */
		goto skip;
	 }
    	serverKeyPair = ss->stepDownKeyPair;
	ss->sec.keaKeyBits = EXPORT_RSA_KEY_LENGTH * BPB;
    } else 
skip:
#ifdef NSS_ENABLE_ECC
    /* XXX Using SSLKEAType to index server certifiates
     * does not work for (EC)DHE ciphers. Until we have
     * an indexing mechanism general enough for all key
     * exchange algorithms, we'll need to deal with each
     * one seprately.
     */
    if ((kea_def->kea == kea_ecdhe_rsa) ||
               (kea_def->kea == kea_ecdhe_ecdsa)) {
	if (ss->ephemeralECDHKeyPair != NULL) {
	   serverKeyPair = ss->ephemeralECDHKeyPair;
	   if (serverKeyPair->pubKey) {
		ss->sec.keaKeyBits = 
		    SECKEY_PublicKeyStrengthInBits(serverKeyPair->pubKey);
	   }
	}
    } else 
#endif
    {
	sslServerCerts * sc = ss->serverCerts + kea_def->exchKeyType;
	serverKeyPair = sc->serverKeyPair;
	ss->sec.keaKeyBits = sc->serverKeyBits;
    }

    if (serverKeyPair) {
	serverKey = serverKeyPair->privKey;
    }

    if (serverKey == NULL) {
    	SEND_ALERT
	PORT_SetError(SSL_ERROR_NO_SERVER_KEY_FOR_ALG);
	return SECFailure;
    }

    ss->sec.keaType    = kea_def->exchKeyType;

    switch (kea_def->exchKeyType) {
    case kt_rsa:
	rv = ssl3_HandleRSAClientKeyExchange(ss, b, length, serverKey);
	if (rv != SECSuccess) {
	    SEND_ALERT
	    return SECFailure;	/* error code set */
	}
	break;


#ifdef NSS_ENABLE_ECC
    case kt_ecdh:
	/* XXX We really ought to be able to store multiple
	 * EC certs (a requirement if we wish to support both
	 * ECDH-RSA and ECDH-ECDSA key exchanges concurrently).
	 * When we make that change, we'll need an index other
	 * than kt_ecdh to pick the right EC certificate.
	 */
	if (serverKeyPair) {
	    serverPubKey = serverKeyPair->pubKey;
        }
	if (serverPubKey == NULL) {
	    /* XXX Is this the right error code? */
	    PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
	    return SECFailure;
	}
	rv = ssl3_HandleECDHClientKeyExchange(ss, b, length, 
					      serverPubKey, serverKey);
	if (rv != SECSuccess) {
	    return SECFailure;	/* error code set */
	}
	break;
#endif /* NSS_ENABLE_ECC */

    default:
	(void) ssl3_HandshakeFailure(ss);
	PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
	return SECFailure;
    }
    ss->ssl3.hs.ws = ss->sec.peerCert ? wait_cert_verify : wait_change_cipher;
    return SECSuccess;

}

/* This is TLS's equivalent of sending a no_certificate alert. */
static SECStatus
ssl3_SendEmptyCertificate(sslSocket *ss)
{
    SECStatus            rv;

    rv = ssl3_AppendHandshakeHeader(ss, certificate, 3);
    if (rv == SECSuccess) {
	rv = ssl3_AppendHandshakeNumber(ss, 0, 3);
    }
    return rv;	/* error, if any, set by functions called above. */
}

SECStatus
ssl3_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
    SECStatus rv;
    SECItem ticketData;

    SSL_TRC(3, ("%d: SSL3[%d]: handle session_ticket handshake",
		SSL_GETPID(), ss->fd));

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

    PORT_Assert(!ss->ssl3.hs.newSessionTicket.ticket.data);
    PORT_Assert(!ss->ssl3.hs.receivedNewSessionTicket);

    if (ss->ssl3.hs.ws != wait_new_session_ticket) {
	SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	PORT_SetError(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET);
	return SECFailure;
    }

    /* RFC5077 Section 3.3: "The client MUST NOT treat the ticket as valid
     * until it has verified the server's Finished message." See the comment in
     * ssl3_FinishHandshake for more details.
     */
    ss->ssl3.hs.newSessionTicket.received_timestamp = ssl_Time();
    if (length < 4) {
	(void)SSL3_SendAlert(ss, alert_fatal, decode_error);
	PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
	return SECFailure;
    }
    ss->ssl3.hs.newSessionTicket.ticket_lifetime_hint =
	(PRUint32)ssl3_ConsumeHandshakeNumber(ss, 4, &b, &length);

    rv = ssl3_ConsumeHandshakeVariable(ss, &ticketData, 2, &b, &length);
    if (length != 0 || rv != SECSuccess) {
	(void)SSL3_SendAlert(ss, alert_fatal, decode_error);
	PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
	return SECFailure;  /* malformed */
    }
    rv = SECITEM_CopyItem(NULL, &ss->ssl3.hs.newSessionTicket.ticket,
			  &ticketData);
    if (rv != SECSuccess) {
	return rv;
    }
    ss->ssl3.hs.receivedNewSessionTicket = PR_TRUE;

    ss->ssl3.hs.ws = wait_change_cipher;
    return SECSuccess;
}

#ifdef NISCC_TEST
static PRInt32 connNum = 0;

static SECStatus 
get_fake_cert(SECItem *pCertItem, int *pIndex)
{
    PRFileDesc *cf;
    char *      testdir;
    char *      startat;
    char *      stopat;
    const char *extension;
    int         fileNum;
    PRInt32     numBytes   = 0;
    PRStatus    prStatus;
    PRFileInfo  info;
    char        cfn[100];

    pCertItem->data = 0;
    if ((testdir = PR_GetEnv("NISCC_TEST")) == NULL) {
	return SECSuccess;
    }
    *pIndex   = (NULL != strstr(testdir, "root"));
    extension = (strstr(testdir, "simple") ? "" : ".der");
    fileNum     = PR_ATOMIC_INCREMENT(&connNum) - 1;
    if ((startat = PR_GetEnv("START_AT")) != NULL) {
	fileNum += atoi(startat);
    }
    if ((stopat = PR_GetEnv("STOP_AT")) != NULL && 
	fileNum >= atoi(stopat)) {
	*pIndex = -1;
	return SECSuccess;
    }
    sprintf(cfn, "%s/%08d%s", testdir, fileNum, extension);
    cf = PR_Open(cfn, PR_RDONLY, 0);
    if (!cf) {
	goto loser;
    }
    prStatus = PR_GetOpenFileInfo(cf, &info);
    if (prStatus != PR_SUCCESS) {
	PR_Close(cf);
	goto loser;
    }
    pCertItem = SECITEM_AllocItem(NULL, pCertItem, info.size);
    if (pCertItem) {
	numBytes = PR_Read(cf, pCertItem->data, info.size);
    }
    PR_Close(cf);
    if (numBytes != info.size) {
	SECITEM_FreeItem(pCertItem, PR_FALSE);
	PORT_SetError(SEC_ERROR_IO);
	goto loser;
    }
    fprintf(stderr, "using %s\n", cfn);
    return SECSuccess;

loser:
    fprintf(stderr, "failed to use %s\n", cfn);
    *pIndex = -1;
    return SECFailure;
}
#endif

/*
 * Used by both client and server.
 * Called from HandleServerHelloDone and from SendServerHelloSequence.
 */
static SECStatus
ssl3_SendCertificate(sslSocket *ss)
{
    SECStatus            rv;
    CERTCertificateList *certChain;
    int                  len 		= 0;
    int                  i;
    SSL3KEAType          certIndex;
#ifdef NISCC_TEST
    SECItem              fakeCert;
    int                  ndex           = -1;
#endif

    SSL_TRC(3, ("%d: SSL3[%d]: send certificate handshake",
		SSL_GETPID(), ss->fd));

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

    if (ss->sec.localCert)
    	CERT_DestroyCertificate(ss->sec.localCert);
    if (ss->sec.isServer) {
	sslServerCerts * sc = NULL;

	/* XXX SSLKEAType isn't really a good choice for 
	 * indexing certificates (it breaks when we deal
	 * with (EC)DHE-* cipher suites. This hack ensures
	 * the RSA cert is picked for (EC)DHE-RSA.
	 * Revisit this when we add server side support
	 * for ECDHE-ECDSA or client-side authentication
	 * using EC certificates.
	 */
	if ((ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) ||
	    (ss->ssl3.hs.kea_def->kea == kea_dhe_rsa)) {
	    certIndex = kt_rsa;
	} else {
	    certIndex = ss->ssl3.hs.kea_def->exchKeyType;
	}
	sc                    = ss->serverCerts + certIndex;
	certChain             = sc->serverCertChain;
	ss->sec.authKeyBits   = sc->serverKeyBits;
	ss->sec.authAlgorithm = ss->ssl3.hs.kea_def->signKeyType;
	ss->sec.localCert     = CERT_DupCertificate(sc->serverCert);
    } else {
	certChain          = ss->ssl3.clientCertChain;
	ss->sec.localCert = CERT_DupCertificate(ss->ssl3.clientCertificate);
    }

#ifdef NISCC_TEST
    rv = get_fake_cert(&fakeCert, &ndex);
#endif

    if (certChain) {
	for (i = 0; i < certChain->len; i++) {
#ifdef NISCC_TEST
	    if (fakeCert.len > 0 && i == ndex) {
		len += fakeCert.len + 3;
	    } else {
		len += certChain->certs[i].len + 3;
	    }
#else
	    len += certChain->certs[i].len + 3;
#endif
	}
    }

    rv = ssl3_AppendHandshakeHeader(ss, certificate, len + 3);
    if (rv != SECSuccess) {
	return rv; 		/* err set by AppendHandshake. */
    }
    rv = ssl3_AppendHandshakeNumber(ss, len, 3);
    if (rv != SECSuccess) {
	return rv; 		/* err set by AppendHandshake. */
    }
    if (certChain) {
        for (i = 0; i < certChain->len; i++) {
#ifdef NISCC_TEST
            if (fakeCert.len > 0 && i == ndex) {
                rv = ssl3_AppendHandshakeVariable(ss, fakeCert.data,
                                                  fakeCert.len, 3);
                SECITEM_FreeItem(&fakeCert, PR_FALSE);
            } else {
                rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data,
                                                  certChain->certs[i].len, 3);
            }
#else
            rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data,
                                              certChain->certs[i].len, 3);
#endif
            if (rv != SECSuccess) {
                return rv; 		/* err set by AppendHandshake. */
            }
        }
    }

    return SECSuccess;
}

/*
 * Used by server only.
 * single-stapling, send only a single cert status
 */
static SECStatus
ssl3_SendCertificateStatus(sslSocket *ss)
{
    SECStatus rv;
    int len = 0;
    SECItemArray *statusToSend = NULL;
    SSL3KEAType certIndex;

    SSL_TRC(3, ("%d: SSL3[%d]: send certificate status handshake",
		SSL_GETPID(), ss->fd));

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

    if (!ssl3_ExtensionNegotiated(ss, ssl_cert_status_xtn))
	return SECSuccess;

    /* Use certStatus based on the cert being used. */
    if ((ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) ||
	(ss->ssl3.hs.kea_def->kea == kea_dhe_rsa)) {
	certIndex = kt_rsa;
    } else {
	certIndex = ss->ssl3.hs.kea_def->exchKeyType;
    }
    if (ss->certStatusArray[certIndex] && ss->certStatusArray[certIndex]->len) {
	statusToSend = ss->certStatusArray[certIndex];
    }
    if (!statusToSend)
	return SECSuccess;

    /* Use the array's first item only (single stapling) */
    len = 1 + statusToSend->items[0].len + 3;

    rv = ssl3_AppendHandshakeHeader(ss, certificate_status, len);
    if (rv != SECSuccess) {
	return rv; 		/* err set by AppendHandshake. */
    }
    rv = ssl3_AppendHandshakeNumber(ss, 1 /*ocsp*/, 1);
    if (rv != SECSuccess)
	return rv; 		/* err set by AppendHandshake. */

    rv = ssl3_AppendHandshakeVariable(ss,
				      statusToSend->items[0].data,
				      statusToSend->items[0].len,
				      3);
    if (rv != SECSuccess)
	return rv; 		/* err set by AppendHandshake. */

    return SECSuccess;
}

/* This is used to delete the CA certificates in the peer certificate chain
 * from the cert database after they've been validated.
 */
static void
ssl3_CleanupPeerCerts(sslSocket *ss)
{
    PLArenaPool * arena = ss->ssl3.peerCertArena;
    ssl3CertNode *certs = (ssl3CertNode *)ss->ssl3.peerCertChain;

    for (; certs; certs = certs->next) {
	CERT_DestroyCertificate(certs->cert);
    }
    if (arena) PORT_FreeArena(arena, PR_FALSE);
    ss->ssl3.peerCertArena = NULL;
    ss->ssl3.peerCertChain = NULL;
}

static void
ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid)
{
    PLArenaPool *arena;
    ssl3CertNode *lastCert = NULL;
    ssl3CertNode *certs = NULL;
    int i;

    if (!sid->peerCertChain[0])
	return;
    PORT_Assert(!ss->ssl3.peerCertArena);
    PORT_Assert(!ss->ssl3.peerCertChain);
    ss->ssl3.peerCertArena = arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    for (i = 0; i < MAX_PEER_CERT_CHAIN_SIZE && sid->peerCertChain[i]; i++) {
	ssl3CertNode *c = PORT_ArenaNew(arena, ssl3CertNode);
	c->cert = CERT_DupCertificate(sid->peerCertChain[i]);
	c->next = NULL;
	if (lastCert) {
	    lastCert->next = c;
	} else {
	    certs = c;
	}
	lastCert = c;
    }
    ss->ssl3.peerCertChain = certs;
}

static void
ssl3_CopyPeerCertsToSID(ssl3CertNode *certs, sslSessionID *sid)
{
    int i = 0;
    ssl3CertNode *c = certs;
    for (; i < MAX_PEER_CERT_CHAIN_SIZE && c; i++, c = c->next) {
	PORT_Assert(!sid->peerCertChain[i]);
	sid->peerCertChain[i] = CERT_DupCertificate(c->cert);
    }
}

/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
 * ssl3 CertificateStatus message.
 * Caller must hold Handshake and RecvBuf locks.
 * This is always called before ssl3_HandleCertificate, even if the Certificate
 * message is sent first.
 */
static SECStatus
ssl3_HandleCertificateStatus(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
    PRInt32 status, len;

    if (ss->ssl3.hs.ws != wait_certificate_status) {
        (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
        PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_STATUS);
        return SECFailure;
    }

    PORT_Assert(!ss->sec.isServer);

    /* Consume the CertificateStatusType enum */
    status = ssl3_ConsumeHandshakeNumber(ss, 1, &b, &length);
    if (status != 1 /* ocsp */) {
       goto format_loser;
    }

    len = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
    if (len != length) {
       goto format_loser;
    }

#define MAX_CERTSTATUS_LEN 0x1ffff   /* 128k - 1 */
    if (length > MAX_CERTSTATUS_LEN)
       goto format_loser;
#undef MAX_CERTSTATUS_LEN

    /* Array size 1, because we currently implement single-stapling only */
    SECITEM_AllocArray(NULL, &ss->sec.ci.sid->peerCertStatus, 1);
    if (!ss->sec.ci.sid->peerCertStatus.items)
       return SECFailure;

    ss->sec.ci.sid->peerCertStatus.items[0].data = PORT_Alloc(length);

    if (!ss->sec.ci.sid->peerCertStatus.items[0].data) {
        SECITEM_FreeArray(&ss->sec.ci.sid->peerCertStatus, PR_FALSE);
        return SECFailure;
    }

    PORT_Memcpy(ss->sec.ci.sid->peerCertStatus.items[0].data, b, length);
    ss->sec.ci.sid->peerCertStatus.items[0].len = length;
    ss->sec.ci.sid->peerCertStatus.items[0].type = siBuffer;

    return ssl3_AuthCertificate(ss);

format_loser:
    return ssl3_DecodeError(ss);
}

/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
 * ssl3 Certificate message.
 * Caller must hold Handshake and RecvBuf locks.
 */
static SECStatus
ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
    ssl3CertNode *   c;
    ssl3CertNode *   lastCert 	= NULL;
    PRInt32          remaining  = 0;
    PRInt32          size;
    SECStatus        rv;
    PRBool           isServer	= (PRBool)(!!ss->sec.isServer);
    PRBool           isTLS;
    SSL3AlertDescription desc;
    int              errCode    = SSL_ERROR_RX_MALFORMED_CERTIFICATE;
    SECItem          certItem;

    SSL_TRC(3, ("%d: SSL3[%d]: handle certificate handshake",
		SSL_GETPID(), ss->fd));
    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );

    if ((ss->ssl3.hs.ws != wait_server_cert) &&
	(ss->ssl3.hs.ws != wait_client_cert)) {
	desc    = unexpected_message;
	errCode = SSL_ERROR_RX_UNEXPECTED_CERTIFICATE;
	goto alert_loser;
    }

    if (ss->sec.peerCert != NULL) {
	if (ss->sec.peerKey) {
	    SECKEY_DestroyPublicKey(ss->sec.peerKey);
	    ss->sec.peerKey = NULL;
	}
	CERT_DestroyCertificate(ss->sec.peerCert);
	ss->sec.peerCert = NULL;
    }

    ssl3_CleanupPeerCerts(ss);
    isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);

    /* It is reported that some TLS client sends a Certificate message
    ** with a zero-length message body.  We'll treat that case like a
    ** normal no_certificates message to maximize interoperability.
    */
    if (length) {
	remaining = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
	if (remaining < 0)
	    goto loser;	/* fatal alert already sent by ConsumeHandshake. */
	if ((PRUint32)remaining > length)
	    goto decode_loser;
    }

    if (!remaining) {
	if (!(isTLS && isServer)) {
	    desc = bad_certificate;
	    goto alert_loser;
	}
    	/* This is TLS's version of a no_certificate alert. */
    	/* I'm a server. I've requested a client cert. He hasn't got one. */
	rv = ssl3_HandleNoCertificate(ss);
	if (rv != SECSuccess) {
	    errCode = PORT_GetError();
	    goto loser;
	}
       ss->ssl3.hs.ws = wait_client_key;
       return SECSuccess;
    }

    ss->ssl3.peerCertArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (ss->ssl3.peerCertArena == NULL) {
	goto loser;	/* don't send alerts on memory errors */
    }

    /* First get the peer cert. */
    remaining -= 3;
    if (remaining < 0)
	goto decode_loser;

    size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
    if (size <= 0)
	goto loser;	/* fatal alert already sent by ConsumeHandshake. */

    if (remaining < size)
	goto decode_loser;

    certItem.data = b;
    certItem.len = size;
    b      += size;
    length -= size;
    remaining -= size;

    ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
                                            PR_FALSE, PR_TRUE);
    if (ss->sec.peerCert == NULL) {
	/* We should report an alert if the cert was bad, but not if the
	 * problem was just some local problem, like memory error.
	 */
	goto ambiguous_err;
    }

    /* Now get all of the CA certs. */
    while (remaining > 0) {
	remaining -= 3;
	if (remaining < 0)
	    goto decode_loser;

	size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
	if (size <= 0)
	    goto loser;	/* fatal alert already sent by ConsumeHandshake. */

	if (remaining < size)
	    goto decode_loser;

	certItem.data = b;
	certItem.len = size;
	b      += size;
	length -= size;
	remaining -= size;

	c = PORT_ArenaNew(ss->ssl3.peerCertArena, ssl3CertNode);
	if (c == NULL) {
	    goto loser;	/* don't send alerts on memory errors */
	}

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

	c->next = NULL;
	if (lastCert) {
	    lastCert->next = c;
	} else {
	    ss->ssl3.peerCertChain = c;
	}
	lastCert = c;
    }

    if (remaining != 0)
        goto decode_loser;

    SECKEY_UpdateCertPQG(ss->sec.peerCert);

    if (!isServer && ssl3_ExtensionNegotiated(ss, ssl_cert_status_xtn)) {
       ss->ssl3.hs.ws = wait_certificate_status;
       rv = SECSuccess;
    } else {
       rv = ssl3_AuthCertificate(ss); /* sets ss->ssl3.hs.ws */
    }

    return rv;

ambiguous_err:
    errCode = PORT_GetError();
    switch (errCode) {
    case PR_OUT_OF_MEMORY_ERROR:
    case SEC_ERROR_BAD_DATABASE:
    case SEC_ERROR_NO_MEMORY:
       if (isTLS) {
           desc = internal_error;
           goto alert_loser;
       }
       goto loser;
    }
    ssl3_SendAlertForCertError(ss, errCode);
    goto loser;

decode_loser:
    desc = isTLS ? decode_error : bad_certificate;

alert_loser:
    (void)SSL3_SendAlert(ss, alert_fatal, desc);

loser:
    (void)ssl_MapLowLevelError(errCode);
    return SECFailure;
}

static SECStatus
ssl3_AuthCertificate(sslSocket *ss)
{
    SECStatus        rv;
    PRBool           isServer   = (PRBool)(!!ss->sec.isServer);
    int              errCode;

    ss->ssl3.hs.authCertificatePending = PR_FALSE;

    /*
     * Ask caller-supplied callback function to validate cert chain.
     */
    rv = (SECStatus)(*ss->authCertificate)(ss->authCertificateArg, ss->fd,
					   PR_TRUE, isServer);
    if (rv) {
	errCode = PORT_GetError();
	if (rv != SECWouldBlock) {
	    if (ss->handleBadCert) {
		rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd);
	    }
	}

	if (rv == SECWouldBlock) {
	    if (ss->sec.isServer) {
		errCode = SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS;
		rv = SECFailure;
		goto loser;
	    }

	    ss->ssl3.hs.authCertificatePending = PR_TRUE;
	    rv = SECSuccess;
	}

	if (rv != SECSuccess) {
	    ssl3_SendAlertForCertError(ss, errCode);
	    goto loser;
	}
    }

    ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
    ssl3_CopyPeerCertsToSID(ss->ssl3.peerCertChain, ss->sec.ci.sid);

    if (!ss->sec.isServer) {
        CERTCertificate *cert = ss->sec.peerCert;

	/* set the server authentication and key exchange types and sizes
	** from the value in the cert.  If the key exchange key is different,
	** it will get fixed when we handle the server key exchange message.
	*/
	SECKEYPublicKey * pubKey  = CERT_ExtractPublicKey(cert);
	ss->sec.authAlgorithm = ss->ssl3.hs.kea_def->signKeyType;
	ss->sec.keaType       = ss->ssl3.hs.kea_def->exchKeyType;
	if (pubKey) {
	    ss->sec.keaKeyBits = ss->sec.authKeyBits =
		SECKEY_PublicKeyStrengthInBits(pubKey);
#ifdef NSS_ENABLE_ECC
	    if (ss->sec.keaType == kt_ecdh) {
		/* Get authKeyBits from signing key.
		 * XXX The code below uses a quick approximation of
		 * key size based on cert->signatureWrap.signature.data
		 * (which contains the DER encoded signature). The field
		 * cert->signatureWrap.signature.len contains the
		 * length of the encoded signature in bits.
		 */
		if (ss->ssl3.hs.kea_def->kea == kea_ecdh_ecdsa) {
		    ss->sec.authKeyBits = 
			cert->signatureWrap.signature.data[3]*8;
		    if (cert->signatureWrap.signature.data[4] == 0x00)
			    ss->sec.authKeyBits -= 8;
		    /* 
		     * XXX: if cert is not signed by ecdsa we should
		     * destroy pubKey and goto bad_cert
		     */
		} else if (ss->ssl3.hs.kea_def->kea == kea_ecdh_rsa) {
		    ss->sec.authKeyBits = cert->signatureWrap.signature.len;
		    /* 
		     * XXX: if cert is not signed by rsa we should
		     * destroy pubKey and goto bad_cert
		     */
		}
	    }
#endif /* NSS_ENABLE_ECC */
	    SECKEY_DestroyPublicKey(pubKey); 
	    pubKey = NULL;
    	}

	ss->ssl3.hs.ws = wait_cert_request; /* disallow server_key_exchange */
	if (ss->ssl3.hs.kea_def->is_limited ||
	    /* XXX OR server cert is signing only. */
#ifdef NSS_ENABLE_ECC
	    ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
	    ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa ||
#endif /* NSS_ENABLE_ECC */
	    ss->ssl3.hs.kea_def->exchKeyType == kt_dh) {
	    ss->ssl3.hs.ws = wait_server_key; /* allow server_key_exchange */
	}
    } else {
	ss->ssl3.hs.ws = wait_client_key;
    }

    PORT_Assert(rv == SECSuccess);
    if (rv != SECSuccess) {
	errCode = SEC_ERROR_LIBRARY_FAILURE;
	rv = SECFailure;
	goto loser;
    }

    return rv;

loser:
    (void)ssl_MapLowLevelError(errCode);
    return SECFailure;
}

static SECStatus ssl3_FinishHandshake(sslSocket *ss);

static SECStatus
ssl3_AlwaysFail(sslSocket * ss)
{
    PORT_SetError(PR_INVALID_STATE_ERROR);
    return SECFailure;
}

/* Caller must hold 1stHandshakeLock.
*/
SECStatus
ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error)
{
    SECStatus rv;

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

    if (ss->sec.isServer) {
	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS);
	return SECFailure;
    }

    ssl_GetRecvBufLock(ss);
    ssl_GetSSL3HandshakeLock(ss);

    if (!ss->ssl3.hs.authCertificatePending) {
	PORT_SetError(PR_INVALID_STATE_ERROR);
	rv = SECFailure;
	goto done;
    }

    ss->ssl3.hs.authCertificatePending = PR_FALSE;

    if (error != 0) {
	ss->ssl3.hs.restartTarget = ssl3_AlwaysFail;
	ssl3_SendAlertForCertError(ss, error);
	rv = SECSuccess;
    } else if (ss->ssl3.hs.restartTarget != NULL) {
	sslRestartTarget target = ss->ssl3.hs.restartTarget;
	ss->ssl3.hs.restartTarget = NULL;

	if (target == ssl3_FinishHandshake) {
	    SSL_TRC(3,("%d: SSL3[%p]: certificate authentication lost the race"
		       " with peer's finished message", SSL_GETPID(), ss->fd));
	}

	rv = target(ss);
	/* Even if we blocked here, we have accomplished enough to claim
	 * success. Any remaining work will be taken care of by subsequent
	 * calls to SSL_ForceHandshake/PR_Send/PR_Read/etc. 
	 */
	if (rv == SECWouldBlock) {
	    rv = SECSuccess;
	}
    } else {
	SSL_TRC(3, ("%d: SSL3[%p]: certificate authentication won the race with"
        	    " peer's finished message", SSL_GETPID(), ss->fd));

	PORT_Assert(!ss->ssl3.hs.isResuming);
	PORT_Assert(ss->ssl3.hs.ws != idle_handshake);

	if (ss->opt.enableFalseStart &&
	    !ss->firstHsDone &&
	    !ss->ssl3.hs.isResuming &&
	    ssl3_WaitingForStartOfServerSecondRound(ss)) {
	    /* ssl3_SendClientSecondRound deferred the false start check because
	     * certificate authentication was pending, so we do it now if we still
	     * haven't received any of the server's second round yet.
	     */
	    rv = ssl3_CheckFalseStart(ss);
	} else {
	    rv = SECSuccess;
	}
    }

done:
    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_ReleaseRecvBufLock(ss);

    return rv;
}

static SECStatus
ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
			PRBool          isServer,
                const   SSL3Hashes   *  hashes,
                        TLSFinished  *  tlsFinished)
{
    const char * label;
    unsigned int len;
    SECStatus    rv;

    label = isServer ? "server finished" : "client finished";
    len   = 15;

    rv = ssl3_TLSPRFWithMasterSecret(spec, label, len, hashes->u.raw,
	hashes->len, tlsFinished->verify_data,
	sizeof tlsFinished->verify_data);

    return rv;
}

/* The calling function must acquire and release the appropriate
 * lock (e.g., ssl_GetSpecReadLock / ssl_ReleaseSpecReadLock for
 * ss->ssl3.crSpec).
 */
SECStatus
ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, const char *label,
    unsigned int labelLen, const unsigned char *val, unsigned int valLen,
    unsigned char *out, unsigned int outLen)
{
    SECStatus rv = SECSuccess;

    if (spec->master_secret && !spec->bypassCiphers) {
	SECItem param = {siBuffer, NULL, 0};
	CK_MECHANISM_TYPE mech = CKM_TLS_PRF_GENERAL;
	PK11Context *prf_context;
	unsigned int retLen;

	if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
	    mech = CKM_NSS_TLS_PRF_GENERAL_SHA256;
	}
	prf_context = PK11_CreateContextBySymKey(mech, CKA_SIGN,
						 spec->master_secret, &param);
	if (!prf_context)
	    return SECFailure;

	rv  = PK11_DigestBegin(prf_context);
	rv |= PK11_DigestOp(prf_context, (unsigned char *) label, labelLen);
	rv |= PK11_DigestOp(prf_context, val, valLen);
	rv |= PK11_DigestFinal(prf_context, out, &retLen, outLen);
	PORT_Assert(rv != SECSuccess || retLen == outLen);

	PK11_DestroyContext(prf_context, PR_TRUE);
    } else {
	/* bypass PKCS11 */
#ifdef NO_PKCS11_BYPASS
	PORT_Assert(spec->master_secret);
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	rv = SECFailure;
#else
	SECItem inData  = { siBuffer, };
	SECItem outData = { siBuffer, };
	PRBool isFIPS   = PR_FALSE;

	inData.data  = (unsigned char *) val;
	inData.len   = valLen;
	outData.data = out;
	outData.len  = outLen;
	if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
	    rv = TLS_P_hash(HASH_AlgSHA256, &spec->msItem, label, &inData,
			    &outData, isFIPS);
	} else {
	    rv = TLS_PRF(&spec->msItem, label, &inData, &outData, isFIPS);
	}
	PORT_Assert(rv != SECSuccess || outData.len == outLen);
#endif
    }
    return rv;
}

/* called from ssl3_SendClientSecondRound
 *             ssl3_HandleFinished
 */
static SECStatus
ssl3_SendNextProto(sslSocket *ss)
{
    SECStatus rv;
    int padding_len;
    static const unsigned char padding[32] = {0};

    if (ss->ssl3.nextProto.len == 0 ||
	ss->ssl3.nextProtoState == SSL_NEXT_PROTO_SELECTED) {
	return SECSuccess;
    }

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

    padding_len = 32 - ((ss->ssl3.nextProto.len + 2) % 32);

    rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->ssl3.nextProto.len +
						    2 + padding_len);
    if (rv != SECSuccess) {
	return rv;	/* error code set by AppendHandshakeHeader */
    }
    rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data,
				      ss->ssl3.nextProto.len, 1);
    if (rv != SECSuccess) {
	return rv;	/* error code set by AppendHandshake */
    }
    rv = ssl3_AppendHandshakeVariable(ss, padding, padding_len, 1);
    if (rv != SECSuccess) {
	return rv;	/* error code set by AppendHandshake */
    }
    return rv;
}

/* called from ssl3_SendFinished
 *
 * This function is simply a debugging aid and therefore does not return a
 * SECStatus. */
static void
ssl3_RecordKeyLog(sslSocket *ss)
{
    SECStatus rv;
    SECItem *keyData;
    char buf[14 /* "CLIENT_RANDOM " */ +
	     SSL3_RANDOM_LENGTH*2 /* client_random */ +
	     1 /* " " */ +
	     48*2 /* master secret */ +
             1 /* new line */];
    unsigned int j;

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

    if (!ssl_keylog_iob)
	return;

    rv = PK11_ExtractKeyValue(ss->ssl3.cwSpec->master_secret);
    if (rv != SECSuccess)
	return;

    ssl_GetSpecReadLock(ss);

    /* keyData does not need to be freed. */
    keyData = PK11_GetKeyData(ss->ssl3.cwSpec->master_secret);
    if (!keyData || !keyData->data || keyData->len != 48) {
	ssl_ReleaseSpecReadLock(ss);
	return;
    }

    /* https://developer.mozilla.org/en/NSS_Key_Log_Format */

    /* There could be multiple, concurrent writers to the
     * keylog, so we have to do everything in a single call to
     * fwrite. */

    memcpy(buf, "CLIENT_RANDOM ", 14);
    j = 14;
    hexEncode(buf + j, ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
    j += SSL3_RANDOM_LENGTH*2;
    buf[j++] = ' ';
    hexEncode(buf + j, keyData->data, 48);
    j += 48*2;
    buf[j++] = '\n';

    PORT_Assert(j == sizeof(buf));

    ssl_ReleaseSpecReadLock(ss);

    if (fwrite(buf, sizeof(buf), 1, ssl_keylog_iob) != 1)
        return;
    fflush(ssl_keylog_iob);
    return;
}

/* called from ssl3_SendClientSecondRound
 *	     ssl3_HandleFinished
 */
static SECStatus
ssl3_SendEncryptedExtensions(sslSocket *ss)
{
    static const char CHANNEL_ID_MAGIC[] = "TLS Channel ID signature";
    static const char CHANNEL_ID_RESUMPTION_MAGIC[] = "Resumption";
    /* This is the ASN.1 prefix for a P-256 public key. Specifically it's:
     * SEQUENCE
     *   SEQUENCE
     *     OID id-ecPublicKey
     *     OID prime256v1
     *   BIT STRING, length 66, 0 trailing bits: 0x04
     *
     * The 0x04 in the BIT STRING is the prefix for an uncompressed, X9.62
     * public key. Following that are the two field elements as 32-byte,
     * big-endian numbers, as required by the Channel ID. */
    static const unsigned char P256_SPKI_PREFIX[] = {
	0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
	0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
	0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
	0x42, 0x00, 0x04
    };
    /* ChannelIDs are always 128 bytes long: 64 bytes of P-256 public key and 64
     * bytes of ECDSA signature. */
    static const int CHANNEL_ID_PUBLIC_KEY_LENGTH = 64;
    static const int CHANNEL_ID_LENGTH = 128;

    SECStatus rv = SECFailure;
    SECItem *spki = NULL;
    SSL3Hashes hashes;
    const unsigned char *pub_bytes;
    unsigned char signed_data[sizeof(CHANNEL_ID_MAGIC) +
                              sizeof(CHANNEL_ID_RESUMPTION_MAGIC) +
                              sizeof(SSL3Hashes)*2];
    size_t signed_data_len;
    unsigned char digest[SHA256_LENGTH];
    SECItem digest_item;
    unsigned char signature[64];
    SECItem signature_item;

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

    if (ss->ssl3.channelID == NULL)
	return SECSuccess;

    PORT_Assert(ssl3_ExtensionNegotiated(ss, ssl_channel_id_xtn));

    if (SECKEY_GetPrivateKeyType(ss->ssl3.channelID) != ecKey ||
	PK11_SignatureLen(ss->ssl3.channelID) != sizeof(signature)) {
	PORT_SetError(SSL_ERROR_INVALID_CHANNEL_ID_KEY);
	rv = SECFailure;
	goto loser;
    }

    ssl_GetSpecReadLock(ss);
    rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.cwSpec, &hashes, 0);
    ssl_ReleaseSpecReadLock(ss);

    if (rv != SECSuccess)
	goto loser;

    rv = ssl3_AppendHandshakeHeader(ss, encrypted_extensions,
				    2 + 2 + CHANNEL_ID_LENGTH);
    if (rv != SECSuccess)
	goto loser;	/* error code set by AppendHandshakeHeader */
    rv = ssl3_AppendHandshakeNumber(ss, ssl_channel_id_xtn, 2);
    if (rv != SECSuccess)
	goto loser;	/* error code set by AppendHandshake */
    rv = ssl3_AppendHandshakeNumber(ss, CHANNEL_ID_LENGTH, 2);
    if (rv != SECSuccess)
	goto loser;	/* error code set by AppendHandshake */

    spki = SECKEY_EncodeDERSubjectPublicKeyInfo(ss->ssl3.channelIDPub);

    if (spki->len != sizeof(P256_SPKI_PREFIX) + CHANNEL_ID_PUBLIC_KEY_LENGTH ||
	memcmp(spki->data, P256_SPKI_PREFIX, sizeof(P256_SPKI_PREFIX)) != 0) {
	PORT_SetError(SSL_ERROR_INVALID_CHANNEL_ID_KEY);
	rv = SECFailure;
	goto loser;
    }

    pub_bytes = spki->data + sizeof(P256_SPKI_PREFIX);

    signed_data_len = 0;
    memcpy(signed_data + signed_data_len, CHANNEL_ID_MAGIC,
           sizeof(CHANNEL_ID_MAGIC));
    signed_data_len += sizeof(CHANNEL_ID_MAGIC);
    if (ss->ssl3.hs.isResuming) {
        SECItem *originalHandshakeHash =
            &ss->sec.ci.sid->u.ssl3.originalHandshakeHash;
        PORT_Assert(originalHandshakeHash->len > 0);

        memcpy(signed_data + signed_data_len, CHANNEL_ID_RESUMPTION_MAGIC,
               sizeof(CHANNEL_ID_RESUMPTION_MAGIC));
        signed_data_len += sizeof(CHANNEL_ID_RESUMPTION_MAGIC);
        memcpy(signed_data + signed_data_len, originalHandshakeHash->data,
               originalHandshakeHash->len);
        signed_data_len += originalHandshakeHash->len;
    }
    memcpy(signed_data + signed_data_len, hashes.u.raw, hashes.len);
    signed_data_len += hashes.len;

    rv = PK11_HashBuf(SEC_OID_SHA256, digest, signed_data, signed_data_len);
    if (rv != SECSuccess)
	goto loser;

    digest_item.data = digest;
    digest_item.len = sizeof(digest);

    signature_item.data = signature;
    signature_item.len = sizeof(signature);

    rv = PK11_Sign(ss->ssl3.channelID, &signature_item, &digest_item);
    if (rv != SECSuccess)
	goto loser;

    rv = ssl3_AppendHandshake(ss, pub_bytes, CHANNEL_ID_PUBLIC_KEY_LENGTH);
    if (rv != SECSuccess)
	goto loser;
    rv = ssl3_AppendHandshake(ss, signature, sizeof(signature));

loser:
    if (spki)
	SECITEM_FreeItem(spki, PR_TRUE);
    if (ss->ssl3.channelID) {
	SECKEY_DestroyPrivateKey(ss->ssl3.channelID);
	ss->ssl3.channelID = NULL;
    }
    if (ss->ssl3.channelIDPub) {
	SECKEY_DestroyPublicKey(ss->ssl3.channelIDPub);
	ss->ssl3.channelIDPub = NULL;
    }

    return rv;
}

/* ssl3_RestartHandshakeAfterChannelIDReq is called to restart a handshake
 * after a ChannelID callback returned SECWouldBlock. At this point we have
 * processed the server's ServerHello but not yet any further messages. We will
 * always get a message from the server after a ServerHello so either they are
 * waiting in the buffer or we'll get network I/O. */
SECStatus
ssl3_RestartHandshakeAfterChannelIDReq(sslSocket *ss,
				       SECKEYPublicKey *channelIDPub,
				       SECKEYPrivateKey *channelID)
{
    if (ss->handshake == 0) {
	SECKEY_DestroyPublicKey(channelIDPub);
	SECKEY_DestroyPrivateKey(channelID);
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	return SECFailure;
    }

    if (channelIDPub == NULL ||
	channelID == NULL) {
	if (channelIDPub)
	    SECKEY_DestroyPublicKey(channelIDPub);
	if (channelID)
	    SECKEY_DestroyPrivateKey(channelID);
	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
	return SECFailure;
    }

    if (ss->ssl3.channelID)
	SECKEY_DestroyPrivateKey(ss->ssl3.channelID);
    if (ss->ssl3.channelIDPub)
	SECKEY_DestroyPublicKey(ss->ssl3.channelIDPub);

    ss->handshake = ssl_GatherRecord1stHandshake;
    ss->ssl3.channelID = channelID;
    ss->ssl3.channelIDPub = channelIDPub;

    return SECSuccess;
}

/* called from ssl3_SendClientSecondRound
 *             ssl3_HandleClientHello
 *             ssl3_HandleFinished
 */
static SECStatus
ssl3_SendFinished(sslSocket *ss, PRInt32 flags)
{
    ssl3CipherSpec *cwSpec;
    PRBool          isTLS;
    PRBool          isServer = ss->sec.isServer;
    SECStatus       rv;
    SSL3Sender      sender = isServer ? sender_server : sender_client;
    SSL3Hashes      hashes;
    TLSFinished     tlsFinished;

    SSL_TRC(3, ("%d: SSL3[%d]: send finished handshake", SSL_GETPID(), ss->fd));

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

    ssl_GetSpecReadLock(ss);
    cwSpec = ss->ssl3.cwSpec;
    isTLS = (PRBool)(cwSpec->version > SSL_LIBRARY_VERSION_3_0);
    rv = ssl3_ComputeHandshakeHashes(ss, cwSpec, &hashes, sender);
    if (isTLS && rv == SECSuccess) {
	rv = ssl3_ComputeTLSFinished(cwSpec, isServer, &hashes, &tlsFinished);
    }
    ssl_ReleaseSpecReadLock(ss);
    if (rv != SECSuccess) {
	goto fail;	/* err code was set by ssl3_ComputeHandshakeHashes */
    }

    if (isTLS) {
	if (isServer)
	    ss->ssl3.hs.finishedMsgs.tFinished[1] = tlsFinished;
	else
	    ss->ssl3.hs.finishedMsgs.tFinished[0] = tlsFinished;
	ss->ssl3.hs.finishedBytes = sizeof tlsFinished;
	rv = ssl3_AppendHandshakeHeader(ss, finished, sizeof tlsFinished);
	if (rv != SECSuccess) 
	    goto fail; 		/* err set by AppendHandshake. */
	rv = ssl3_AppendHandshake(ss, &tlsFinished, sizeof tlsFinished);
	if (rv != SECSuccess) 
	    goto fail; 		/* err set by AppendHandshake. */
    } else {
	if (isServer)
	    ss->ssl3.hs.finishedMsgs.sFinished[1] = hashes.u.s;
	else
	    ss->ssl3.hs.finishedMsgs.sFinished[0] = hashes.u.s;
	PORT_Assert(hashes.len == sizeof hashes.u.s);
	ss->ssl3.hs.finishedBytes = sizeof hashes.u.s;
	rv = ssl3_AppendHandshakeHeader(ss, finished, sizeof hashes.u.s);
	if (rv != SECSuccess) 
	    goto fail; 		/* err set by AppendHandshake. */
	rv = ssl3_AppendHandshake(ss, &hashes.u.s, sizeof hashes.u.s);
	if (rv != SECSuccess) 
	    goto fail; 		/* err set by AppendHandshake. */
    }
    rv = ssl3_FlushHandshake(ss, flags);
    if (rv != SECSuccess) {
	goto fail;	/* error code set by ssl3_FlushHandshake */
    }

    ssl3_RecordKeyLog(ss);

    return SECSuccess;

fail:
    return rv;
}

/* wrap the master secret, and put it into the SID.
 * Caller holds the Spec read lock.
 */
SECStatus
ssl3_CacheWrappedMasterSecret(sslSocket *ss, sslSessionID *sid,
    ssl3CipherSpec *spec, SSL3KEAType effectiveExchKeyType)
{
    PK11SymKey *      wrappingKey  = NULL;
    PK11SlotInfo *    symKeySlot;
    void *            pwArg        = ss->pkcs11PinArg;
    SECStatus         rv           = SECFailure;
    PRBool            isServer     = ss->sec.isServer;
    CK_MECHANISM_TYPE mechanism    = CKM_INVALID_MECHANISM;
    symKeySlot = PK11_GetSlotFromKey(spec->master_secret);
    if (!isServer) {
	int  wrapKeyIndex;
	int  incarnation;

	/* these next few functions are mere accessors and don't fail. */
	sid->u.ssl3.masterWrapIndex  = wrapKeyIndex =
				       PK11_GetCurrentWrapIndex(symKeySlot);
	PORT_Assert(wrapKeyIndex == 0);	/* array has only one entry! */

	sid->u.ssl3.masterWrapSeries = incarnation =
				       PK11_GetSlotSeries(symKeySlot);
	sid->u.ssl3.masterSlotID   = PK11_GetSlotID(symKeySlot);
	sid->u.ssl3.masterModuleID = PK11_GetModuleID(symKeySlot);
	sid->u.ssl3.masterValid    = PR_TRUE;
	/* Get the default wrapping key, for wrapping the master secret before
	 * placing it in the SID cache entry. */
	wrappingKey = PK11_GetWrapKey(symKeySlot, wrapKeyIndex,
				      CKM_INVALID_MECHANISM, incarnation,
				      pwArg);
	if (wrappingKey) {
	    mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */
	} else {
	    int keyLength;
	    /* if the wrappingKey doesn't exist, attempt to create it.
	     * Note: we intentionally ignore errors here.  If we cannot
	     * generate a wrapping key, it is not fatal to this SSL connection,
	     * but we will not be able to restart this session.
	     */
	    mechanism = PK11_GetBestWrapMechanism(symKeySlot);
	    keyLength = PK11_GetBestKeyLength(symKeySlot, mechanism);
	    /* Zero length means fixed key length algorithm, or error.
	     * It's ambiguous.
	     */
	    wrappingKey = PK11_KeyGen(symKeySlot, mechanism, NULL,
				      keyLength, pwArg);
	    if (wrappingKey) {
		PK11_SetWrapKey(symKeySlot, wrapKeyIndex, wrappingKey);
	    }
	}
    } else {
	/* server socket using session cache. */
	mechanism = PK11_GetBestWrapMechanism(symKeySlot);
	if (mechanism != CKM_INVALID_MECHANISM) {
	    wrappingKey =
		getWrappingKey(ss, symKeySlot, effectiveExchKeyType,
			       mechanism, pwArg);
	    if (wrappingKey) {
		mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */
	    }
	}
    }

    sid->u.ssl3.masterWrapMech = mechanism;
    PK11_FreeSlot(symKeySlot);

    if (wrappingKey) {
	SECItem wmsItem;

	wmsItem.data = sid->u.ssl3.keys.wrapped_master_secret;
	wmsItem.len  = sizeof sid->u.ssl3.keys.wrapped_master_secret;
	rv = PK11_WrapSymKey(mechanism, NULL, wrappingKey,
			     spec->master_secret, &wmsItem);
	/* rv is examined below. */
	sid->u.ssl3.keys.wrapped_master_secret_len = wmsItem.len;
	PK11_FreeSymKey(wrappingKey);
    }
    return rv;
}

/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
 * ssl3 Finished message from the peer.
 * Caller must hold Handshake and RecvBuf locks.
 */
static SECStatus
ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
		    const SSL3Hashes *hashes)
{
    sslSessionID *    sid	   = ss->sec.ci.sid;
    SECStatus         rv           = SECSuccess;
    PRBool            isServer     = ss->sec.isServer;
    PRBool            isTLS;
    SSL3KEAType       effectiveExchKeyType;

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

    SSL_TRC(3, ("%d: SSL3[%d]: handle finished handshake",
    	SSL_GETPID(), ss->fd));

    if (ss->ssl3.hs.ws != wait_finished) {
	SSL3_SendAlert(ss, alert_fatal, unexpected_message);
    	PORT_SetError(SSL_ERROR_RX_UNEXPECTED_FINISHED);
	return SECFailure;
    }

    isTLS = (PRBool)(ss->ssl3.crSpec->version > SSL_LIBRARY_VERSION_3_0);
    if (isTLS) {
	TLSFinished tlsFinished;

	if (length != sizeof tlsFinished) {
	    (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
	    PORT_SetError(SSL_ERROR_RX_MALFORMED_FINISHED);
	    return SECFailure;
	}
	rv = ssl3_ComputeTLSFinished(ss->ssl3.crSpec, !isServer, 
	                             hashes, &tlsFinished);
	if (!isServer)
	    ss->ssl3.hs.finishedMsgs.tFinished[1] = tlsFinished;
	else
	    ss->ssl3.hs.finishedMsgs.tFinished[0] = tlsFinished;
	ss->ssl3.hs.finishedBytes = sizeof tlsFinished;
	if (rv != SECSuccess ||
	    0 != NSS_SecureMemcmp(&tlsFinished, b, length)) {
	    (void)SSL3_SendAlert(ss, alert_fatal, decrypt_error);
	    PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
	    return SECFailure;
	}
    } else {
	if (length != sizeof(SSL3Finished)) {
	    (void)ssl3_IllegalParameter(ss);
	    PORT_SetError(SSL_ERROR_RX_MALFORMED_FINISHED);
	    return SECFailure;
	}

	if (!isServer)
	    ss->ssl3.hs.finishedMsgs.sFinished[1] = hashes->u.s;
	else
	    ss->ssl3.hs.finishedMsgs.sFinished[0] = hashes->u.s;
	PORT_Assert(hashes->len == sizeof hashes->u.s);
	ss->ssl3.hs.finishedBytes = sizeof hashes->u.s;
	if (0 != NSS_SecureMemcmp(&hashes->u.s, b, length)) {
	    (void)ssl3_HandshakeFailure(ss);
	    PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
	    return SECFailure;
	}
    }

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

    if ((isServer && !ss->ssl3.hs.isResuming) ||
	(!isServer && ss->ssl3.hs.isResuming)) {
	PRInt32 flags = 0;

	/* Send a NewSessionTicket message if the client sent us
	 * either an empty session ticket, or one that did not verify.
	 * (Note that if either of these conditions was met, then the
	 * server has sent a SessionTicket extension in the
	 * ServerHello message.)
	 */
	if (isServer && !ss->ssl3.hs.isResuming &&
	    ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn)) {
	    /* RFC 5077 Section 3.3: "In the case of a full handshake, the
	     * server MUST verify the client's Finished message before sending
	     * the ticket." Presumably, this also means that the client's
	     * certificate, if any, must be verified beforehand too.
	     */
	    rv = ssl3_SendNewSessionTicket(ss);
	    if (rv != SECSuccess) {
		goto xmit_loser;
	    }
	}

	rv = ssl3_SendChangeCipherSpecs(ss);
	if (rv != SECSuccess) {
	    goto xmit_loser;	/* err is set. */
	}
	/* If this thread is in SSL_SecureSend (trying to write some data) 
	** then set the ssl_SEND_FLAG_FORCE_INTO_BUFFER flag, so that the 
	** last two handshake messages (change cipher spec and finished) 
	** will be sent in the same send/write call as the application data.
	*/
	if (ss->writerThread == PR_GetCurrentThread()) {
	    flags = ssl_SEND_FLAG_FORCE_INTO_BUFFER;
	}

	if (!isServer) {
	    if (!ss->firstHsDone) {
		rv = ssl3_SendNextProto(ss);
		if (rv != SECSuccess) {
		    goto xmit_loser; /* err code was set. */
		}
	    }
	    rv = ssl3_SendEncryptedExtensions(ss);
	    if (rv != SECSuccess)
		goto xmit_loser; /* err code was set. */
	}

	if (IS_DTLS(ss)) {
	    flags |= ssl_SEND_FLAG_NO_RETRANSMIT;
	}

	rv = ssl3_SendFinished(ss, flags);
	if (rv != SECSuccess) {
	    goto xmit_loser;	/* err is set. */
	}
    }

xmit_loser:
    ssl_ReleaseXmitBufLock(ss);	/*************************************/
    if (rv != SECSuccess) {
        return rv;
    }

    if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) {
	effectiveExchKeyType = kt_rsa;
    } else {
	effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
    }

    if (sid->cached == never_cached && !ss->opt.noCache && ss->sec.cache) {
	/* fill in the sid */
	sid->u.ssl3.cipherSuite = ss->ssl3.hs.cipher_suite;
	sid->u.ssl3.compression = ss->ssl3.hs.compression;
	sid->u.ssl3.policy      = ss->ssl3.policy;
#ifdef NSS_ENABLE_ECC
	sid->u.ssl3.negotiatedECCurves = ss->ssl3.hs.negotiatedECCurves;
#endif
	sid->u.ssl3.exchKeyType = effectiveExchKeyType;
	sid->version            = ss->version;
	sid->authAlgorithm      = ss->sec.authAlgorithm;
	sid->authKeyBits        = ss->sec.authKeyBits;
	sid->keaType            = ss->sec.keaType;
	sid->keaKeyBits         = ss->sec.keaKeyBits;
	sid->lastAccessTime     = sid->creationTime = ssl_Time();
	sid->expirationTime     = sid->creationTime + ssl3_sid_timeout;
	sid->localCert          = CERT_DupCertificate(ss->sec.localCert);

	ssl_GetSpecReadLock(ss);	/*************************************/

	/* Copy the master secret (wrapped or unwrapped) into the sid */
	if (ss->ssl3.crSpec->msItem.len && ss->ssl3.crSpec->msItem.data) {
	    sid->u.ssl3.keys.wrapped_master_secret_len = 
			    ss->ssl3.crSpec->msItem.len;
	    memcpy(sid->u.ssl3.keys.wrapped_master_secret, 
		   ss->ssl3.crSpec->msItem.data, ss->ssl3.crSpec->msItem.len);
	    sid->u.ssl3.masterValid    = PR_TRUE;
	    sid->u.ssl3.keys.msIsWrapped = PR_FALSE;
	    rv = SECSuccess;
	} else {
	    rv = ssl3_CacheWrappedMasterSecret(ss, ss->sec.ci.sid,
					       ss->ssl3.crSpec,
					       effectiveExchKeyType);
	    sid->u.ssl3.keys.msIsWrapped = PR_TRUE;
	}
	ssl_ReleaseSpecReadLock(ss);  /*************************************/

	/* If the wrap failed, we don't cache the sid.
	 * The connection continues normally however.
	 */
	ss->ssl3.hs.cacheSID = rv == SECSuccess;
    }

    if (ss->ssl3.hs.authCertificatePending) {
	if (ss->ssl3.hs.restartTarget) {
	    PR_NOT_REACHED("ssl3_HandleFinished: unexpected restartTarget");
	    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	    return SECFailure;
	}

	ss->ssl3.hs.restartTarget = ssl3_FinishHandshake;
	return SECWouldBlock;
    }

    rv = ssl3_FinishHandshake(ss);
    return rv;
}

/* The return type is SECStatus instead of void because this function needs
 * to have type sslRestartTarget.
 */
SECStatus
ssl3_FinishHandshake(sslSocket * ss)
{
    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
    PORT_Assert( ss->ssl3.hs.restartTarget == NULL );

    /* The first handshake is now completed. */
    ss->handshake           = NULL;

    /* RFC 5077 Section 3.3: "The client MUST NOT treat the ticket as valid
     * until it has verified the server's Finished message." When the server
     * sends a NewSessionTicket in a resumption handshake, we must wait until
     * the handshake is finished (we have verified the server's Finished
     * AND the server's certificate) before we update the ticket in the sid.
     *
     * This must be done before we call (*ss->sec.cache)(ss->sec.ci.sid)
     * because CacheSID requires the session ticket to already be set, and also
     * because of the lazy lock creation scheme used by CacheSID and
     * ssl3_SetSIDSessionTicket.
     */
    if (ss->ssl3.hs.receivedNewSessionTicket) {
	PORT_Assert(!ss->sec.isServer);
	ssl3_SetSIDSessionTicket(ss->sec.ci.sid, &ss->ssl3.hs.newSessionTicket);
	/* The sid took over the ticket data */
	PORT_Assert(!ss->ssl3.hs.newSessionTicket.ticket.data);
        ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE;
    }

    if (ss->ssl3.hs.cacheSID && ss->sec.isServer) {
	PORT_Assert(ss->sec.ci.sid->cached == never_cached);
	(*ss->sec.cache)(ss->sec.ci.sid);
	ss->ssl3.hs.cacheSID = PR_FALSE;
    }

    ss->ssl3.hs.canFalseStart = PR_FALSE; /* False Start phase is complete */
    ss->ssl3.hs.ws = idle_handshake;

    ssl_FinishHandshake(ss);

    return SECSuccess;
}

/* Called from ssl3_HandleHandshake() when it has gathered a complete ssl3
 * hanshake message.
 * Caller must hold Handshake and RecvBuf locks.
 */
SECStatus
ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
    SECStatus         rv 	= SECSuccess;
    SSL3HandshakeType type 	= ss->ssl3.hs.msg_type;
    SSL3Hashes        hashes;	/* computed hashes are put here. */
    PRUint8           hdr[4];
    PRUint8           dtlsData[8];

    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
    /*
     * We have to compute the hashes before we update them with the
     * current message.
     */
    ssl_GetSpecReadLock(ss);	/************************************/
    if((type == finished) || (type == certificate_verify)) {
	SSL3Sender      sender = (SSL3Sender)0;
	ssl3CipherSpec *rSpec  = ss->ssl3.prSpec;

	if (type == finished) {
	    sender = ss->sec.isServer ? sender_client : sender_server;
	    rSpec  = ss->ssl3.crSpec;
	}
	rv = ssl3_ComputeHandshakeHashes(ss, rSpec, &hashes, sender);
    }
    ssl_ReleaseSpecReadLock(ss); /************************************/
    if (rv != SECSuccess) {
	return rv;	/* error code was set by ssl3_ComputeHandshakeHashes*/
    }
    SSL_TRC(30,("%d: SSL3[%d]: handle handshake message: %s", SSL_GETPID(),
		ss->fd, ssl3_DecodeHandshakeType(ss->ssl3.hs.msg_type)));

    hdr[0] = (PRUint8)ss->ssl3.hs.msg_type;
    hdr[1] = (PRUint8)(length >> 16);
    hdr[2] = (PRUint8)(length >>  8);
    hdr[3] = (PRUint8)(length      );

    /* Start new handshake hashes when we start a new handshake */
    if (ss->ssl3.hs.msg_type == client_hello) {
	rv = ssl3_RestartHandshakeHashes(ss);
	if (rv != SECSuccess) {
	    return rv;
	}
    }
    /* We should not include hello_request and hello_verify_request messages
     * in the handshake hashes */
    if ((ss->ssl3.hs.msg_type != hello_request) &&
	(ss->ssl3.hs.msg_type != hello_verify_request)) {
	rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char*) hdr, 4);
	if (rv != SECSuccess) return rv;	/* err code already set. */

	/* Extra data to simulate a complete DTLS handshake fragment */
	if (IS_DTLS(ss)) {
	    /* Sequence number */
	    dtlsData[0] = MSB(ss->ssl3.hs.recvMessageSeq);
	    dtlsData[1] = LSB(ss->ssl3.hs.recvMessageSeq);

	    /* Fragment offset */
	    dtlsData[2] = 0;
	    dtlsData[3] = 0;
	    dtlsData[4] = 0;

	    /* Fragment length */
	    dtlsData[5] = (PRUint8)(length >> 16);
	    dtlsData[6] = (PRUint8)(length >>  8);
	    dtlsData[7] = (PRUint8)(length      );

	    rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char*) dtlsData,
					    sizeof(dtlsData));
	    if (rv != SECSuccess) return rv;	/* err code already set. */
	}

	/* The message body */
	rv = ssl3_UpdateHandshakeHashes(ss, b, length);
	if (rv != SECSuccess) return rv;	/* err code already set. */
    }

    PORT_SetError(0);	/* each message starts with no error. */

    if (ss->ssl3.hs.ws == wait_certificate_status &&
        ss->ssl3.hs.msg_type != certificate_status) {
        /* If we negotiated the certificate_status extension then we deferred
         * certificate validation until we get the CertificateStatus messsage.
         * But the CertificateStatus message is optional. If the server did
         * not send it then we need to validate the certificate now. If the
         * server does send the CertificateStatus message then we will
         * authenticate the certificate in ssl3_HandleCertificateStatus.
         */
        rv = ssl3_AuthCertificate(ss); /* sets ss->ssl3.hs.ws */
        PORT_Assert(rv != SECWouldBlock);
        if (rv != SECSuccess) {
            return rv;
        }
    }

    switch (ss->ssl3.hs.msg_type) {
    case hello_request:
	if (length != 0) {
	    (void)ssl3_DecodeError(ss);
	    PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST);
	    return SECFailure;
	}
	if (ss->sec.isServer) {
	    (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	    PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST);
	    return SECFailure;
	}
	rv = ssl3_HandleHelloRequest(ss);
	break;
    case client_hello:
	if (!ss->sec.isServer) {
	    (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	    PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO);
	    return SECFailure;
	}
	rv = ssl3_HandleClientHello(ss, b, length);
	break;
    case server_hello:
	if (ss->sec.isServer) {
	    (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	    PORT_SetError(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO);
	    return SECFailure;
	}
	rv = ssl3_HandleServerHello(ss, b, length);
	break;
    case hello_verify_request:
	if (!IS_DTLS(ss) || ss->sec.isServer) {
	    (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	    PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST);
	    return SECFailure;
	}
	rv = dtls_HandleHelloVerifyRequest(ss, b, length);
	break;
    case certificate:
	rv = ssl3_HandleCertificate(ss, b, length);
	break;
    case certificate_status:
	rv = ssl3_HandleCertificateStatus(ss, b, length);
	break;
    case server_key_exchange:
	if (ss->sec.isServer) {
	    (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	    PORT_SetError(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH);
	    return SECFailure;
	}
	rv = ssl3_HandleServerKeyExchange(ss, b, length);
	break;
    case certificate_request:
	if (ss->sec.isServer) {
	    (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	    PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST);
	    return SECFailure;
	}
	rv = ssl3_HandleCertificateRequest(ss, b, length);
	break;
    case server_hello_done:
	if (length != 0) {
	    (void)ssl3_DecodeError(ss);
	    PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_DONE);
	    return SECFailure;
	}
	if (ss->sec.isServer) {
	    (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	    PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE);
	    return SECFailure;
	}
	rv = ssl3_HandleServerHelloDone(ss);
	break;
    case certificate_verify:
	if (!ss->sec.isServer) {
	    (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	    PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY);
	    return SECFailure;
	}
	rv = ssl3_HandleCertificateVerify(ss, b, length, &hashes);
	break;
    case client_key_exchange:
	if (!ss->sec.isServer) {
	    (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	    PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH);
	    return SECFailure;
	}
	rv = ssl3_HandleClientKeyExchange(ss, b, length);
	break;
    case new_session_ticket:
	if (ss->sec.isServer) {
	    (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	    PORT_SetError(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET);
	    return SECFailure;
	}
	rv = ssl3_HandleNewSessionTicket(ss, b, length);
	break;
    case finished:
        rv = ssl3_HandleFinished(ss, b, length, &hashes);
	break;
    default:
	(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	PORT_SetError(SSL_ERROR_RX_UNKNOWN_HANDSHAKE);
	rv = SECFailure;
    }

    if (IS_DTLS(ss) && (rv != SECFailure)) {
	/* Increment the expected sequence number */
	ss->ssl3.hs.recvMessageSeq++;
    }

    return rv;
}

/* Called only from ssl3_HandleRecord, for each (deciphered) ssl3 record.
 * origBuf is the decrypted ssl record content.
 * Caller must hold the handshake and RecvBuf locks.
 */
static SECStatus
ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
{
    /*
     * There may be a partial handshake message already in the handshake
     * state. The incoming buffer may contain another portion, or a
     * complete message or several messages followed by another portion.
     *
     * Each message is made contiguous before being passed to the actual
     * message parser.
     */
    sslBuffer *buf = &ss->ssl3.hs.msgState; /* do not lose the original buffer pointer */
    SECStatus rv;

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

    if (buf->buf == NULL) {
	*buf = *origBuf;
    }
    while (buf->len > 0) {
	if (ss->ssl3.hs.header_bytes < 4) {
	    PRUint8 t;
	    t = *(buf->buf++);
	    buf->len--;
	    if (ss->ssl3.hs.header_bytes++ == 0)
		ss->ssl3.hs.msg_type = (SSL3HandshakeType)t;
	    else
		ss->ssl3.hs.msg_len = (ss->ssl3.hs.msg_len << 8) + t;
	    if (ss->ssl3.hs.header_bytes < 4)
	    	continue;

#define MAX_HANDSHAKE_MSG_LEN 0x1ffff	/* 128k - 1 */
	    if (ss->ssl3.hs.msg_len > MAX_HANDSHAKE_MSG_LEN) {
		(void)ssl3_DecodeError(ss);
		PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
		return SECFailure;
	    }
#undef MAX_HANDSHAKE_MSG_LEN

	    /* If msg_len is zero, be sure we fall through, 
	    ** even if buf->len is zero. 
	    */
	    if (ss->ssl3.hs.msg_len > 0) 
	    	continue;
	}

	/*
	 * Header has been gathered and there is at least one byte of new
	 * data available for this message. If it can be done right out
	 * of the original buffer, then use it from there.
	 */
	if (ss->ssl3.hs.msg_body.len == 0 && buf->len >= ss->ssl3.hs.msg_len) {
	    /* handle it from input buffer */
	    rv = ssl3_HandleHandshakeMessage(ss, buf->buf, ss->ssl3.hs.msg_len);
	    if (rv == SECFailure) {
		/* This test wants to fall through on either
		 * SECSuccess or SECWouldBlock.
		 * ssl3_HandleHandshakeMessage MUST set the error code.
		 */
		return rv;
	    }
	    buf->buf += ss->ssl3.hs.msg_len;
	    buf->len -= ss->ssl3.hs.msg_len;
	    ss->ssl3.hs.msg_len = 0;
	    ss->ssl3.hs.header_bytes = 0;
	    if (rv != SECSuccess) { /* return if SECWouldBlock. */
		return rv;
	    }
	} else {
	    /* must be copied to msg_body and dealt with from there */
	    unsigned int bytes;

	    PORT_Assert(ss->ssl3.hs.msg_body.len < ss->ssl3.hs.msg_len);
	    bytes = PR_MIN(buf->len, ss->ssl3.hs.msg_len - ss->ssl3.hs.msg_body.len);

	    /* Grow the buffer if needed */
	    rv = sslBuffer_Grow(&ss->ssl3.hs.msg_body, ss->ssl3.hs.msg_len);
	    if (rv != SECSuccess) {
		/* sslBuffer_Grow has set a memory error code. */
		return SECFailure;
	    }

	    PORT_Memcpy(ss->ssl3.hs.msg_body.buf + ss->ssl3.hs.msg_body.len,
		        buf->buf, bytes);
	    ss->ssl3.hs.msg_body.len += bytes;
	    buf->buf += bytes;
	    buf->len -= bytes;

	    PORT_Assert(ss->ssl3.hs.msg_body.len <= ss->ssl3.hs.msg_len);

	    /* if we have a whole message, do it */
	    if (ss->ssl3.hs.msg_body.len == ss->ssl3.hs.msg_len) {
		rv = ssl3_HandleHandshakeMessage(
		    ss, ss->ssl3.hs.msg_body.buf, ss->ssl3.hs.msg_len);
		if (rv == SECFailure) {
		    /* This test wants to fall through on either
		     * SECSuccess or SECWouldBlock.
		     * ssl3_HandleHandshakeMessage MUST set error code.
		     */
		    return rv;
		}
		ss->ssl3.hs.msg_body.len = 0;
		ss->ssl3.hs.msg_len = 0;
		ss->ssl3.hs.header_bytes = 0;
		if (rv != SECSuccess) { /* return if SECWouldBlock. */
		    return rv;
		}
	    } else {
		PORT_Assert(buf->len == 0);
		break;
	    }
	}
    }	/* end loop */

    origBuf->len = 0;	/* So ssl3_GatherAppDataRecord will keep looping. */
    buf->buf = NULL;	/* not a leak. */
    return SECSuccess;
}

/* These macros return the given value with the MSB copied to all the other
 * bits. They use the fact that arithmetic shift shifts-in the sign bit.
 * However, this is not ensured by the C standard so you may need to replace
 * them with something else for odd compilers. */
#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) )
#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))

/* SECStatusToMask returns, in constant time, a mask value of all ones if
 * rv == SECSuccess.  Otherwise it returns zero. */
static unsigned int
SECStatusToMask(SECStatus rv)
{
    unsigned int good;
    /* rv ^ SECSuccess is zero iff rv == SECSuccess. Subtracting one results
     * in the MSB being set to one iff it was zero before. */
    good = rv ^ SECSuccess;
    good--;
    return DUPLICATE_MSB_TO_ALL(good);
}

/* ssl_ConstantTimeGE returns 0xff if a>=b and 0x00 otherwise. */
static unsigned char
ssl_ConstantTimeGE(unsigned int a, unsigned int b)
{
    a -= b;
    return DUPLICATE_MSB_TO_ALL(~a);
}

/* ssl_ConstantTimeEQ8 returns 0xff if a==b and 0x00 otherwise. */
static unsigned char
ssl_ConstantTimeEQ8(unsigned char a, unsigned char b)
{
    unsigned int c = a ^ b;
    c--;
    return DUPLICATE_MSB_TO_ALL_8(c);
}

static SECStatus
ssl_RemoveSSLv3CBCPadding(sslBuffer *plaintext,
			  unsigned int blockSize,
			  unsigned int macSize)
{
    unsigned int paddingLength, good, t;
    const unsigned int overhead = 1 /* padding length byte */ + macSize;

    /* These lengths are all public so we can test them in non-constant
     * time. */
    if (overhead > plaintext->len) {
	return SECFailure;
    }

    paddingLength = plaintext->buf[plaintext->len-1];
    /* SSLv3 padding bytes are random and cannot be checked. */
    t = plaintext->len;
    t -= paddingLength+overhead;
    /* If len >= paddingLength+overhead then the MSB of t is zero. */
    good = DUPLICATE_MSB_TO_ALL(~t);
    /* SSLv3 requires that the padding is minimal. */
    t = blockSize - (paddingLength+1);
    good &= DUPLICATE_MSB_TO_ALL(~t);
    plaintext->len -= good & (paddingLength+1);
    return (good & SECSuccess) | (~good & SECFailure);
}

static SECStatus
ssl_RemoveTLSCBCPadding(sslBuffer *plaintext, unsigned int macSize)
{
    unsigned int paddingLength, good, t, toCheck, i;
    const unsigned int overhead = 1 /* padding length byte */ + macSize;

    /* These lengths are all public so we can test them in non-constant
     * time. */
    if (overhead > plaintext->len) {
	return SECFailure;
    }

    paddingLength = plaintext->buf[plaintext->len-1];
    t = plaintext->len;
    t -= paddingLength+overhead;
    /* If len >= paddingLength+overhead then the MSB of t is zero. */
    good = DUPLICATE_MSB_TO_ALL(~t);

    /* The padding consists of a length byte at the end of the record and then
     * that many bytes of padding, all with the same value as the length byte.
     * Thus, with the length byte included, there are paddingLength+1 bytes of
     * padding.
     *
     * We can't check just |paddingLength+1| bytes because that leaks
     * decrypted information. Therefore we always have to check the maximum
     * amount of padding possible. (Again, the length of the record is
     * public information so we can use it.) */
    toCheck = 255; /* maximum amount of padding. */
    if (toCheck > plaintext->len-1) {
	toCheck = plaintext->len-1;
    }

    for (i = 0; i < toCheck; i++) {
	unsigned int t = paddingLength - i;
	/* If i <= paddingLength then the MSB of t is zero and mask is
	 * 0xff.  Otherwise, mask is 0. */
	unsigned char mask = DUPLICATE_MSB_TO_ALL(~t);
	unsigned char b = plaintext->buf[plaintext->len-1-i];
	/* The final |paddingLength+1| bytes should all have the value
	 * |paddingLength|. Therefore the XOR should be zero. */
	good &= ~(mask&(paddingLength ^ b));
    }

    /* If any of the final |paddingLength+1| bytes had the wrong value,
     * one or more of the lower eight bits of |good| will be cleared. We
     * AND the bottom 8 bits together and duplicate the result to all the
     * bits. */
    good &= good >> 4;
    good &= good >> 2;
    good &= good >> 1;
    good <<= sizeof(good)*8-1;
    good = DUPLICATE_MSB_TO_ALL(good);

    plaintext->len -= good & (paddingLength+1);
    return (good & SECSuccess) | (~good & SECFailure);
}

/* On entry:
 *   originalLength >= macSize
 *   macSize <= MAX_MAC_LENGTH
 *   plaintext->len >= macSize
 */
static void
ssl_CBCExtractMAC(sslBuffer *plaintext,
		  unsigned int originalLength,
		  SSL3Opaque* out,
		  unsigned int macSize)
{
    unsigned char rotatedMac[MAX_MAC_LENGTH];
    /* macEnd is the index of |plaintext->buf| just after the end of the
     * MAC. */
    unsigned macEnd = plaintext->len;
    unsigned macStart = macEnd - macSize;
    /* scanStart contains the number of bytes that we can ignore because
     * the MAC's position can only vary by 255 bytes. */
    unsigned scanStart = 0;
    unsigned i, j, divSpoiler;
    unsigned char rotateOffset;

    if (originalLength > macSize + 255 + 1)
	scanStart = originalLength - (macSize + 255 + 1);

    /* divSpoiler contains a multiple of macSize that is used to cause the
     * modulo operation to be constant time. Without this, the time varies
     * based on the amount of padding when running on Intel chips at least.
     *
     * The aim of right-shifting macSize is so that the compiler doesn't
     * figure out that it can remove divSpoiler as that would require it
     * to prove that macSize is always even, which I hope is beyond it. */
    divSpoiler = macSize >> 1;
    divSpoiler <<= (sizeof(divSpoiler)-1)*8;
    rotateOffset = (divSpoiler + macStart - scanStart) % macSize;

    memset(rotatedMac, 0, macSize);
    for (i = scanStart; i < originalLength;) {
	for (j = 0; j < macSize && i < originalLength; i++, j++) {
	    unsigned char macStarted = ssl_ConstantTimeGE(i, macStart);
	    unsigned char macEnded = ssl_ConstantTimeGE(i, macEnd);
	    unsigned char b = 0;
	    b = plaintext->buf[i];
	    rotatedMac[j] |= b & macStarted & ~macEnded;
	}
    }

    /* Now rotate the MAC. If we knew that the MAC fit into a CPU cache line
     * we could line-align |rotatedMac| and rotate in place. */
    memset(out, 0, macSize);
    for (i = 0; i < macSize; i++) {
	unsigned char offset =
	    (divSpoiler + macSize - rotateOffset + i) % macSize;
	for (j = 0; j < macSize; j++) {
	    out[j] |= rotatedMac[i] & ssl_ConstantTimeEQ8(j, offset);
	}
    }
}

/* if cText is non-null, then decipher, check MAC, and decompress the
 * SSL record from cText->buf (typically gs->inbuf)
 * into databuf (typically gs->buf), and any previous contents of databuf
 * is lost.  Then handle databuf according to its SSL record type,
 * unless it's an application record.
 *
 * If cText is NULL, then the ciphertext has previously been deciphered and
 * checked, and is already sitting in databuf.  It is processed as an SSL
 * Handshake message.
 *
 * DOES NOT process the decrypted/decompressed application data.
 * On return, databuf contains the decrypted/decompressed record.
 *
 * Called from ssl3_GatherCompleteHandshake
 *             ssl3_RestartHandshakeAfterCertReq
 *
 * Caller must hold the RecvBufLock.
 *
 * This function aquires and releases the SSL3Handshake Lock, holding the
 * lock around any calls to functions that handle records other than
 * Application Data records.
 */
SECStatus
ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
{
    const ssl3BulkCipherDef *cipher_def;
    ssl3CipherSpec *     crSpec;
    SECStatus            rv;
    unsigned int         hashBytes = MAX_MAC_LENGTH + 1;
    PRBool               isTLS;
    SSL3ContentType      rType;
    SSL3Opaque           hash[MAX_MAC_LENGTH];
    SSL3Opaque           givenHashBuf[MAX_MAC_LENGTH];
    SSL3Opaque          *givenHash;
    sslBuffer           *plaintext;
    sslBuffer            temp_buf;
    PRUint64             dtls_seq_num;
    unsigned int         ivLen = 0;
    unsigned int         originalLen = 0;
    unsigned int         good;
    unsigned int         minLength;
    unsigned char        header[13];
    unsigned int         headerLen;

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

    if (!ss->ssl3.initialized) {
	ssl_GetSSL3HandshakeLock(ss);
	rv = ssl3_InitState(ss);
	ssl_ReleaseSSL3HandshakeLock(ss);
	if (rv != SECSuccess) {
	    return rv;		/* ssl3_InitState has set the error code. */
    	}
    }

    /* check for Token Presence */
    if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) {
	PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
	return SECFailure;
    }

    /* cText is NULL when we're called from ssl3_RestartHandshakeAfterXXX().
     * This implies that databuf holds a previously deciphered SSL Handshake
     * message.
     */
    if (cText == NULL) {
	SSL_DBG(("%d: SSL3[%d]: HandleRecord, resuming handshake",
		 SSL_GETPID(), ss->fd));
	rType = content_handshake;
	goto process_it;
    }

    ssl_GetSpecReadLock(ss); /******************************************/

    crSpec = ss->ssl3.crSpec;
    cipher_def = crSpec->cipher_def;

    /* 
     * DTLS relevance checks:
     * Note that this code currently ignores all out-of-epoch packets,
     * which means we lose some in the case of rehandshake +
     * loss/reordering. Since DTLS is explicitly unreliable, this
     * seems like a good tradeoff for implementation effort and is
     * consistent with the guidance of RFC 6347 Sections 4.1 and 4.2.4.1
     */
    if (IS_DTLS(ss)) {
	DTLSEpoch epoch = (cText->seq_num.high >> 16) & 0xffff;
	
	if (crSpec->epoch != epoch) {
	    ssl_ReleaseSpecReadLock(ss);
	    SSL_DBG(("%d: SSL3[%d]: HandleRecord, received packet "
		     "from irrelevant epoch %d", SSL_GETPID(), ss->fd, epoch));
	    /* Silently drop the packet */
            databuf->len = 0; /* Needed to ensure data not left around */
	    return SECSuccess;
	}

	dtls_seq_num = (((PRUint64)(cText->seq_num.high & 0xffff)) << 32) |
			((PRUint64)cText->seq_num.low);

	if (dtls_RecordGetRecvd(&crSpec->recvdRecords, dtls_seq_num) != 0) {
	    ssl_ReleaseSpecReadLock(ss);
	    SSL_DBG(("%d: SSL3[%d]: HandleRecord, rejecting "
		     "potentially replayed packet", SSL_GETPID(), ss->fd));
	    /* Silently drop the packet */
            databuf->len = 0; /* Needed to ensure data not left around */
	    return SECSuccess;
	}
    }

    good = ~0U;
    minLength = crSpec->mac_size;
    if (cipher_def->type == type_block) {
	/* CBC records have a padding length byte at the end. */
	minLength++;
	if (crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
	    /* With >= TLS 1.1, CBC records have an explicit IV. */
	    minLength += cipher_def->iv_size;
	}
    } else if (cipher_def->type == type_aead) {
	minLength = cipher_def->explicit_nonce_size + cipher_def->tag_size;
    }

    /* We can perform this test in variable time because the record's total
     * length and the ciphersuite are both public knowledge. */
    if (cText->buf->len < minLength) {
	goto decrypt_loser;
    }

    if (cipher_def->type == type_block &&
	crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
	/* Consume the per-record explicit IV. RFC 4346 Section 6.2.3.2 states
	 * "The receiver decrypts the entire GenericBlockCipher structure and
	 * then discards the first cipher block corresponding to the IV
	 * component." Instead, we decrypt the first cipher block and then
	 * discard it before decrypting the rest.
	 */
	SSL3Opaque iv[MAX_IV_LENGTH];
	int decoded;

	ivLen = cipher_def->iv_size;
	if (ivLen < 8 || ivLen > sizeof(iv)) {
	    ssl_ReleaseSpecReadLock(ss);
	    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	    return SECFailure;
	}

	PRINT_BUF(80, (ss, "IV (ciphertext):", cText->buf->buf, ivLen));

	/* The decryption result is garbage, but since we just throw away
	 * the block it doesn't matter.  The decryption of the next block
	 * depends only on the ciphertext of the IV block.
	 */
	rv = crSpec->decode(crSpec->decodeContext, iv, &decoded,
			    sizeof(iv), cText->buf->buf, ivLen);

	good &= SECStatusToMask(rv);
    }

    /* If we will be decompressing the buffer we need to decrypt somewhere
     * other than into databuf */
    if (crSpec->decompressor) {
	temp_buf.buf = NULL;
	temp_buf.space = 0;
	plaintext = &temp_buf;
    } else {
	plaintext = databuf;
    }

    plaintext->len = 0; /* filled in by decode call below. */
    if (plaintext->space < MAX_FRAGMENT_LENGTH) {
	rv = sslBuffer_Grow(plaintext, MAX_FRAGMENT_LENGTH + 2048);
	if (rv != SECSuccess) {
	    ssl_ReleaseSpecReadLock(ss);
	    SSL_DBG(("%d: SSL3[%d]: HandleRecord, tried to get %d bytes",
		     SSL_GETPID(), ss->fd, MAX_FRAGMENT_LENGTH + 2048));
	    /* sslBuffer_Grow has set a memory error code. */
	    /* Perhaps we should send an alert. (but we have no memory!) */
	    return SECFailure;
	}
    }

    PRINT_BUF(80, (ss, "ciphertext:", cText->buf->buf + ivLen,
				      cText->buf->len - ivLen));

    isTLS = (PRBool)(crSpec->version > SSL_LIBRARY_VERSION_3_0);

    if (isTLS && cText->buf->len - ivLen > (MAX_FRAGMENT_LENGTH + 2048)) {
	ssl_ReleaseSpecReadLock(ss);
	SSL3_SendAlert(ss, alert_fatal, record_overflow);
	PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
	return SECFailure;
    }

    rType = cText->type;
    if (cipher_def->type == type_aead) {
	/* XXX For many AEAD ciphers, the plaintext is shorter than the
	 * ciphertext by a fixed byte count, but it is not true in general.
	 * Each AEAD cipher should provide a function that returns the
	 * plaintext length for a given ciphertext. */
	unsigned int decryptedLen =
	    cText->buf->len - cipher_def->explicit_nonce_size -
	    cipher_def->tag_size;
	headerLen = ssl3_BuildRecordPseudoHeader(
	    header, IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
	    rType, isTLS, cText->version, IS_DTLS(ss), decryptedLen);
	PORT_Assert(headerLen <= sizeof(header));
	rv = crSpec->aead(
		ss->sec.isServer ? &crSpec->client : &crSpec->server,
		PR_TRUE,                          /* do decrypt */
		plaintext->buf,                   /* out */
		(int*) &plaintext->len,           /* outlen */
		plaintext->space,                 /* maxout */
		cText->buf->buf,                  /* in */
		cText->buf->len,                  /* inlen */
		header, headerLen);
	if (rv != SECSuccess) {
	    good = 0;
	}
    } else {
	if (cipher_def->type == type_block &&
	    ((cText->buf->len - ivLen) % cipher_def->block_size) != 0) {
	    goto decrypt_loser;
	}

	/* decrypt from cText buf to plaintext. */
	rv = crSpec->decode(
	    crSpec->decodeContext, plaintext->buf, (int *)&plaintext->len,
	    plaintext->space, cText->buf->buf + ivLen, cText->buf->len - ivLen);
	if (rv != SECSuccess) {
	    goto decrypt_loser;
	}

	PRINT_BUF(80, (ss, "cleartext:", plaintext->buf, plaintext->len));

	originalLen = plaintext->len;

	/* If it's a block cipher, check and strip the padding. */
	if (cipher_def->type == type_block) {
	    const unsigned int blockSize = cipher_def->block_size;
	    const unsigned int macSize = crSpec->mac_size;

	    if (!isTLS) {
		good &= SECStatusToMask(ssl_RemoveSSLv3CBCPadding(
			    plaintext, blockSize, macSize));
	    } else {
		good &= SECStatusToMask(ssl_RemoveTLSCBCPadding(
			    plaintext, macSize));
	    }
	}

	/* compute the MAC */
	headerLen = ssl3_BuildRecordPseudoHeader(
	    header, IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
	    rType, isTLS, cText->version, IS_DTLS(ss),
	    plaintext->len - crSpec->mac_size);
	PORT_Assert(headerLen <= sizeof(header));
	if (cipher_def->type == type_block) {
	    rv = ssl3_ComputeRecordMACConstantTime(
		crSpec, (PRBool)(!ss->sec.isServer), header, headerLen,
		plaintext->buf, plaintext->len, originalLen,
		hash, &hashBytes);

	    ssl_CBCExtractMAC(plaintext, originalLen, givenHashBuf,
			      crSpec->mac_size);
	    givenHash = givenHashBuf;

	    /* plaintext->len will always have enough space to remove the MAC
	     * because in ssl_Remove{SSLv3|TLS}CBCPadding we only adjust
	     * plaintext->len if the result has enough space for the MAC and we
	     * tested the unadjusted size against minLength, above. */
	    plaintext->len -= crSpec->mac_size;
	} else {
	    /* This is safe because we checked the minLength above. */
	    plaintext->len -= crSpec->mac_size;

	    rv = ssl3_ComputeRecordMAC(
		crSpec, (PRBool)(!ss->sec.isServer), header, headerLen,
		plaintext->buf, plaintext->len, hash, &hashBytes);

	    /* We can read the MAC directly from the record because its location
	     * is public when a stream cipher is used. */
	    givenHash = plaintext->buf + plaintext->len;
	}

	good &= SECStatusToMask(rv);

	if (hashBytes != (unsigned)crSpec->mac_size ||
	    NSS_SecureMemcmp(givenHash, hash, crSpec->mac_size) != 0) {
	    /* We're allowed to leak whether or not the MAC check was correct */
	    good = 0;
	}
    }

    if (good == 0) {
decrypt_loser:
	/* must not hold spec lock when calling SSL3_SendAlert. */
	ssl_ReleaseSpecReadLock(ss);

	SSL_DBG(("%d: SSL3[%d]: decryption failed", SSL_GETPID(), ss->fd));

	if (!IS_DTLS(ss)) {
	    SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
	    /* always log mac error, in case attacker can read server logs. */
	    PORT_SetError(SSL_ERROR_BAD_MAC_READ);
	    return SECFailure;
	} else {
	    /* Silently drop the packet */
            databuf->len = 0; /* Needed to ensure data not left around */
	    return SECSuccess;
	}
    }

    if (!IS_DTLS(ss)) {
	ssl3_BumpSequenceNumber(&crSpec->read_seq_num);
    } else {
	dtls_RecordSetRecvd(&crSpec->recvdRecords, dtls_seq_num);
    }

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

    /*
     * The decrypted data is now in plaintext.
     */

    /* possibly decompress the record. If we aren't using compression then
     * plaintext == databuf and so the uncompressed data is already in
     * databuf. */
    if (crSpec->decompressor) {
	if (databuf->space < plaintext->len + SSL3_COMPRESSION_MAX_EXPANSION) {
	    rv = sslBuffer_Grow(
	        databuf, plaintext->len + SSL3_COMPRESSION_MAX_EXPANSION);
	    if (rv != SECSuccess) {
		SSL_DBG(("%d: SSL3[%d]: HandleRecord, tried to get %d bytes",
			 SSL_GETPID(), ss->fd,
			 plaintext->len + SSL3_COMPRESSION_MAX_EXPANSION));
		/* sslBuffer_Grow has set a memory error code. */
		/* Perhaps we should send an alert. (but we have no memory!) */
		PORT_Free(plaintext->buf);
		return SECFailure;
	    }
	}

	rv = crSpec->decompressor(crSpec->decompressContext,
				  databuf->buf,
				  (int*) &databuf->len,
				  databuf->space,
				  plaintext->buf,
				  plaintext->len);

	if (rv != SECSuccess) {
	    int err = ssl_MapLowLevelError(SSL_ERROR_DECOMPRESSION_FAILURE);
	    SSL3_SendAlert(ss, alert_fatal,
			   isTLS ? decompression_failure : bad_record_mac);

	    /* There appears to be a bug with (at least) Apache + OpenSSL where
	     * resumed SSLv3 connections don't actually use compression. See
	     * comments 93-95 of
	     * https://bugzilla.mozilla.org/show_bug.cgi?id=275744
	     *
	     * So, if we get a decompression error, and the record appears to
	     * be already uncompressed, then we return a more specific error
	     * code to hopefully save somebody some debugging time in the
	     * future.
	     */
	    if (plaintext->len >= 4) {
		unsigned int len = ((unsigned int) plaintext->buf[1] << 16) |
		                   ((unsigned int) plaintext->buf[2] << 8) |
		                   (unsigned int) plaintext->buf[3];
		if (len == plaintext->len - 4) {
		    /* This appears to be uncompressed already */
		    err = SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD;
		}
	    }

	    PORT_Free(plaintext->buf);
	    PORT_SetError(err);
	    return SECFailure;
	}

	PORT_Free(plaintext->buf);
    }

    /*
    ** Having completed the decompression, check the length again. 
    */
    if (isTLS && databuf->len > (MAX_FRAGMENT_LENGTH + 1024)) {
	SSL3_SendAlert(ss, alert_fatal, record_overflow);
	PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
	return SECFailure;
    }

    /* Application data records are processed by the caller of this
    ** function, not by this function.
    */
    if (rType == content_application_data) {
	if (ss->firstHsDone)
	    return SECSuccess;
	(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
	PORT_SetError(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA);
	return SECFailure;
    }

    /* It's a record that must be handled by ssl itself, not the application.
    */
process_it:
    /* XXX  Get the xmit lock here.  Odds are very high that we'll be xmiting
     * data ang getting the xmit lock here prevents deadlocks.
     */
    ssl_GetSSL3HandshakeLock(ss);

    /* All the functions called in this switch MUST set error code if
    ** they return SECFailure or SECWouldBlock.
    */
    switch (rType) {
    case content_change_cipher_spec:
	rv = ssl3_HandleChangeCipherSpecs(ss, databuf);
	break;
    case content_alert:
	rv = ssl3_HandleAlert(ss, databuf);
	break;
    case content_handshake:
	if (!IS_DTLS(ss)) {
	    rv = ssl3_HandleHandshake(ss, databuf);
	} else {
	    rv = dtls_HandleHandshake(ss, databuf);
	}
	break;
    /*
    case content_application_data is handled before this switch
    */
    default:
	SSL_DBG(("%d: SSL3[%d]: bogus content type=%d",
		 SSL_GETPID(), ss->fd, cText->type));
	/* XXX Send an alert ???  */
	PORT_SetError(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE);
	rv = SECFailure;
	break;
    }

    ssl_ReleaseSSL3HandshakeLock(ss);
    return rv;
}

/*
 * Initialization functions
 */

/* Called from ssl3_InitState, immediately below. */
/* Caller must hold the SpecWriteLock. */
static void
ssl3_InitCipherSpec(sslSocket *ss, ssl3CipherSpec *spec)
{
    spec->cipher_def               = &bulk_cipher_defs[cipher_null];
    PORT_Assert(spec->cipher_def->cipher == cipher_null);
    spec->mac_def                  = &mac_defs[mac_null];
    PORT_Assert(spec->mac_def->mac == mac_null);
    spec->encode                   = Null_Cipher;
    spec->decode                   = Null_Cipher;
    spec->destroy                  = NULL;
    spec->compressor               = NULL;
    spec->decompressor             = NULL;
    spec->destroyCompressContext   = NULL;
    spec->destroyDecompressContext = NULL;
    spec->mac_size                 = 0;
    spec->master_secret            = NULL;
    spec->bypassCiphers            = PR_FALSE;

    spec->msItem.data              = NULL;
    spec->msItem.len               = 0;

    spec->client.write_key         = NULL;
    spec->client.write_mac_key     = NULL;
    spec->client.write_mac_context = NULL;

    spec->server.write_key         = NULL;
    spec->server.write_mac_key     = NULL;
    spec->server.write_mac_context = NULL;

    spec->write_seq_num.high       = 0;
    spec->write_seq_num.low        = 0;

    spec->read_seq_num.high        = 0;
    spec->read_seq_num.low         = 0;

    spec->epoch                    = 0;
    dtls_InitRecvdRecords(&spec->recvdRecords);

    spec->version                  = ss->vrange.max;
}

/* Called from:	ssl3_SendRecord
**		ssl3_StartHandshakeHash() <- ssl2_BeginClientHandshake()
**		ssl3_SendClientHello()
**		ssl3_HandleV2ClientHello()
**		ssl3_HandleRecord()
**
** This function should perhaps acquire and release the SpecWriteLock.
**
**
*/
static SECStatus
ssl3_InitState(sslSocket *ss)
{
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    if (ss->ssl3.initialized)
    	return SECSuccess;	/* Function should be idempotent */

    ss->ssl3.policy = SSL_ALLOWED;

    ssl_GetSpecWriteLock(ss);
    ss->ssl3.crSpec = ss->ssl3.cwSpec = &ss->ssl3.specs[0];
    ss->ssl3.prSpec = ss->ssl3.pwSpec = &ss->ssl3.specs[1];
    ss->ssl3.hs.sendingSCSV = PR_FALSE;
    ssl3_InitCipherSpec(ss, ss->ssl3.crSpec);
    ssl3_InitCipherSpec(ss, ss->ssl3.prSpec);

    ss->ssl3.hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello;
#ifdef NSS_ENABLE_ECC
    ss->ssl3.hs.negotiatedECCurves = ssl3_GetSupportedECCurveMask(ss);
#endif
    ssl_ReleaseSpecWriteLock(ss);

    PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));

    if (IS_DTLS(ss)) {
	ss->ssl3.hs.sendMessageSeq = 0;
	ss->ssl3.hs.recvMessageSeq = 0;
	ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
	ss->ssl3.hs.rtRetries = 0;
	ss->ssl3.hs.recvdHighWater = -1;
	PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight);
	dtls_SetMTU(ss, 0); /* Set the MTU to the highest plateau */
    }

    PORT_Assert(!ss->ssl3.hs.messages.buf && !ss->ssl3.hs.messages.space);
    ss->ssl3.hs.messages.buf = NULL;
    ss->ssl3.hs.messages.space = 0;

    ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE;
    PORT_Memset(&ss->ssl3.hs.newSessionTicket, 0,
		sizeof(ss->ssl3.hs.newSessionTicket));

    ss->ssl3.initialized = PR_TRUE;
    return SECSuccess;
}

/* Returns a reference counted object that contains a key pair.
 * Or NULL on failure.  Initial ref count is 1.
 * Uses the keys in the pair as input.
 */
ssl3KeyPair *
ssl3_NewKeyPair( SECKEYPrivateKey * privKey, SECKEYPublicKey * pubKey)
{
    ssl3KeyPair * pair;

    if (!privKey || !pubKey) {
	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
    	return NULL;
    }
    pair = PORT_ZNew(ssl3KeyPair);
    if (!pair)
    	return NULL;			/* error code is set. */
    pair->refCount = 1;
    pair->privKey  = privKey;
    pair->pubKey   = pubKey;
    return pair;			/* success */
}

ssl3KeyPair *
ssl3_GetKeyPairRef(ssl3KeyPair * keyPair)
{
    PR_ATOMIC_INCREMENT(&keyPair->refCount);
    return keyPair;
}

void
ssl3_FreeKeyPair(ssl3KeyPair * keyPair)
{
    PRInt32 newCount =  PR_ATOMIC_DECREMENT(&keyPair->refCount);
    if (!newCount) {
	if (keyPair->privKey)
	    SECKEY_DestroyPrivateKey(keyPair->privKey);
	if (keyPair->pubKey)
	    SECKEY_DestroyPublicKey( keyPair->pubKey);
    	PORT_Free(keyPair);
    }
}



/*
 * Creates the public and private RSA keys for SSL Step down.
 * Called from SSL_ConfigSecureServer in sslsecur.c
 */
SECStatus
ssl3_CreateRSAStepDownKeys(sslSocket *ss)
{
    SECStatus             rv  	 = SECSuccess;
    SECKEYPrivateKey *    privKey;		/* RSA step down key */
    SECKEYPublicKey *     pubKey;		/* RSA step down key */

    if (ss->stepDownKeyPair)
	ssl3_FreeKeyPair(ss->stepDownKeyPair);
    ss->stepDownKeyPair = NULL;
#ifndef HACKED_EXPORT_SERVER
    /* Sigh, should have a get key strength call for private keys */
    if (PK11_GetPrivateModulusLen(ss->serverCerts[kt_rsa].SERVERKEY) >
                                                     EXPORT_RSA_KEY_LENGTH) {
	/* need to ask for the key size in bits */
	privKey = SECKEY_CreateRSAPrivateKey(EXPORT_RSA_KEY_LENGTH * BPB,
					     &pubKey, NULL);
    	if (!privKey || !pubKey ||
	    !(ss->stepDownKeyPair = ssl3_NewKeyPair(privKey, pubKey))) {
	    ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
	    rv = SECFailure;
	}
    }
#endif
    return rv;
}


/* record the export policy for this cipher suite */
SECStatus
ssl3_SetPolicy(ssl3CipherSuite which, int policy)
{
    ssl3CipherSuiteCfg *suite;

    suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
    if (suite == NULL) {
	return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
    }
    suite->policy = policy;

    return SECSuccess;
}

SECStatus
ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *oPolicy)
{
    ssl3CipherSuiteCfg *suite;
    PRInt32             policy;
    SECStatus           rv;

    suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
    if (suite) {
    	policy = suite->policy;
	rv     = SECSuccess;
    } else {
    	policy = SSL_NOT_ALLOWED;
	rv     = SECFailure;	/* err code was set by Lookup. */
    }
    *oPolicy = policy;
    return rv;
}

/* record the user preference for this suite */
SECStatus
ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool enabled)
{
    ssl3CipherSuiteCfg *suite;

    suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
    if (suite == NULL) {
	return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
    }
    suite->enabled = enabled;
    return SECSuccess;
}

/* return the user preference for this suite */
SECStatus
ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *enabled)
{
    ssl3CipherSuiteCfg *suite;
    PRBool              pref;
    SECStatus           rv;

    suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
    if (suite) {
    	pref   = suite->enabled;
	rv     = SECSuccess;
    } else {
    	pref   = SSL_NOT_ALLOWED;
	rv     = SECFailure;	/* err code was set by Lookup. */
    }
    *enabled = pref;
    return rv;
}

SECStatus
ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool enabled)
{
    ssl3CipherSuiteCfg *suite;

    suite = ssl_LookupCipherSuiteCfg(which, ss->cipherSuites);
    if (suite == NULL) {
	return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
    }
    suite->enabled = enabled;
    return SECSuccess;
}

SECStatus
ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *enabled)
{
    ssl3CipherSuiteCfg *suite;
    PRBool              pref;
    SECStatus           rv;

    suite = ssl_LookupCipherSuiteCfg(which, ss->cipherSuites);
    if (suite) {
    	pref   = suite->enabled;
	rv     = SECSuccess;
    } else {
    	pref   = SSL_NOT_ALLOWED;
	rv     = SECFailure;	/* err code was set by Lookup. */
    }
    *enabled = pref;
    return rv;
}

SECStatus
ssl3_CipherOrderSet(sslSocket *ss, const ssl3CipherSuite *ciphers, unsigned int len)
{
    /* |i| iterates over |ciphers| while |done| and |j| iterate over
     * |ss->cipherSuites|. */
    unsigned int i, done;

    for (i = done = 0; i < len; i++) {
	PRUint16 id = ciphers[i];
	unsigned int existingIndex, j;
	PRBool found = PR_FALSE;

	for (j = done; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
	    if (ss->cipherSuites[j].cipher_suite == id) {
		existingIndex = j;
		found = PR_TRUE;
		break;
	    }
	}

	if (!found) {
	    continue;
	}

	if (existingIndex != done) {
	    const ssl3CipherSuiteCfg temp = ss->cipherSuites[done];
	    ss->cipherSuites[done] = ss->cipherSuites[existingIndex];
	    ss->cipherSuites[existingIndex] = temp;
	}
	done++;
    }

    /* Disable all cipher suites that weren't included. */
    for (; done < ssl_V3_SUITES_IMPLEMENTED; done++) {
	ss->cipherSuites[done].enabled = 0;
    }

    return SECSuccess;
}

/* copy global default policy into socket. */
void
ssl3_InitSocketPolicy(sslSocket *ss)
{
    PORT_Memcpy(ss->cipherSuites, cipherSuites, sizeof cipherSuites);
}

SECStatus
ssl3_GetTLSUniqueChannelBinding(sslSocket *ss,
				unsigned char *out,
				unsigned int *outLen,
				unsigned int outLenMax) {
    PRBool       isTLS;
    int          index = 0;
    unsigned int len;
    SECStatus    rv = SECFailure;

    *outLen = 0;

    ssl_GetSSL3HandshakeLock(ss);

    ssl_GetSpecReadLock(ss);
    isTLS = (PRBool)(ss->ssl3.cwSpec->version > SSL_LIBRARY_VERSION_3_0);
    ssl_ReleaseSpecReadLock(ss);

    /* The tls-unique channel binding is the first Finished structure in the
     * handshake. In the case of a resumption, that's the server's Finished.
     * Otherwise, it's the client's Finished. */
    len = ss->ssl3.hs.finishedBytes;

    /* Sending or receiving a Finished message will set finishedBytes to a
     * non-zero value. */
    if (len == 0) {
	PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
	goto loser;
    }

    /* If we are in the middle of a renegotiation then the channel binding
     * value is poorly defined and depends on the direction that it will be
     * used on. Therefore we simply return an error in this case. */
    if (ss->firstHsDone && ss->ssl3.hs.ws != idle_handshake) {
	PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED);
	goto loser;
    }

    /* If resuming, then we want the second Finished value in the array, which
     * is the server's */
    if (ss->ssl3.hs.isResuming)
	index = 1;

    *outLen = len;
    if (outLenMax < len) {
	PORT_SetError(SEC_ERROR_OUTPUT_LEN);
	goto loser;
    }

    if (isTLS) {
	memcpy(out, &ss->ssl3.hs.finishedMsgs.tFinished[index], len);
    } else {
	memcpy(out, &ss->ssl3.hs.finishedMsgs.sFinished[index], len);
    }

    rv = SECSuccess;

loser:
    ssl_ReleaseSSL3HandshakeLock(ss);
    return rv;
}

/* ssl3_config_match_init must have already been called by
 * the caller of this function.
 */
SECStatus
ssl3_ConstructV2CipherSpecsHack(sslSocket *ss, unsigned char *cs, int *size)
{
    int i, count = 0;

    PORT_Assert(ss != 0);
    if (!ss) {
	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
	return SECFailure;
    }
    if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
    	*size = 0;
	return SECSuccess;
    }
    if (cs == NULL) {
	*size = count_cipher_suites(ss, SSL_ALLOWED, PR_TRUE);
	return SECSuccess;
    }

    /* ssl3_config_match_init was called by the caller of this function. */
    for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
	ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
	if (config_match(suite, SSL_ALLOWED, PR_TRUE, &ss->vrange)) {
	    if (cs != NULL) {
		*cs++ = 0x00;
		*cs++ = (suite->cipher_suite >> 8) & 0xFF;
		*cs++ =  suite->cipher_suite       & 0xFF;
	    }
	    count++;
	}
    }
    *size = count;
    return SECSuccess;
}

/*
** If ssl3 socket has completed the first handshake, and is in idle state, 
** then start a new handshake.
** If flushCache is true, the SID cache will be flushed first, forcing a
** "Full" handshake (not a session restart handshake), to be done.
**
** called from SSL_RedoHandshake(), which already holds the handshake locks.
*/
SECStatus
ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache)
{
    sslSessionID *   sid = ss->sec.ci.sid;
    SECStatus        rv;

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

    if (!ss->firstHsDone ||
        ((ss->version >= SSL_LIBRARY_VERSION_3_0) &&
	 ss->ssl3.initialized && 
	 (ss->ssl3.hs.ws != idle_handshake))) {
	PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
	return SECFailure;
    }

    if (IS_DTLS(ss)) {
	dtls_RehandshakeCleanup(ss);
    }

    if (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) {
	PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED);
	return SECFailure;
    }
    if (sid && flushCache) {
        if (ss->sec.uncache)
            ss->sec.uncache(sid); /* remove it from whichever cache it's in. */
	ssl_FreeSID(sid);	/* dec ref count and free if zero. */
	ss->sec.ci.sid = NULL;
    }

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

    /* start off a new handshake. */
    rv = (ss->sec.isServer) ? ssl3_SendHelloRequest(ss)
                            : ssl3_SendClientHello(ss, PR_FALSE);

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

/* Called from ssl_DestroySocketContents() in sslsock.c */
void
ssl3_DestroySSL3Info(sslSocket *ss)
{

    if (ss->ssl3.clientCertificate != NULL)
	CERT_DestroyCertificate(ss->ssl3.clientCertificate);

    if (ss->ssl3.clientPrivateKey != NULL)
	SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
#ifdef NSS_PLATFORM_CLIENT_AUTH
    if (ss->ssl3.platformClientKey)
	ssl_FreePlatformKey(ss->ssl3.platformClientKey);
#endif /* NSS_PLATFORM_CLIENT_AUTH */

    if (ss->ssl3.channelID)
	SECKEY_DestroyPrivateKey(ss->ssl3.channelID);
    if (ss->ssl3.channelIDPub)
	SECKEY_DestroyPublicKey(ss->ssl3.channelIDPub);

    if (ss->ssl3.peerCertArena != NULL)
	ssl3_CleanupPeerCerts(ss);

    if (ss->ssl3.clientCertChain != NULL) {
       CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
       ss->ssl3.clientCertChain = NULL;
    }

    /* clean up handshake */
#ifndef NO_PKCS11_BYPASS
    if (ss->opt.bypassPKCS11) {
	if (ss->ssl3.hs.hashType == handshake_hash_combo) {
	    SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE);
	    MD5_DestroyContext((MD5Context *)ss->ssl3.hs.md5_cx, PR_FALSE);
	} else if (ss->ssl3.hs.hashType == handshake_hash_single) {
	    ss->ssl3.hs.sha_obj->destroy(ss->ssl3.hs.sha_cx, PR_FALSE);
	}
    } 
#endif
    if (ss->ssl3.hs.md5) {
	PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE);
    }
    if (ss->ssl3.hs.sha) {
	PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE);
    }
    if (ss->ssl3.hs.clientSigAndHash) {
	PORT_Free(ss->ssl3.hs.clientSigAndHash);
    }
    if (ss->ssl3.hs.messages.buf) {
    	PORT_Free(ss->ssl3.hs.messages.buf);
	ss->ssl3.hs.messages.buf = NULL;
	ss->ssl3.hs.messages.len = 0;
	ss->ssl3.hs.messages.space = 0;
    }

    /* free the SSL3Buffer (msg_body) */
    PORT_Free(ss->ssl3.hs.msg_body.buf);

    SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE);

    /* free up the CipherSpecs */
    ssl3_DestroyCipherSpec(&ss->ssl3.specs[0], PR_TRUE/*freeSrvName*/);
    ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE/*freeSrvName*/);

    /* Destroy the DTLS data */
    if (IS_DTLS(ss)) {
	dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
	if (ss->ssl3.hs.recvdFragments.buf) {
	    PORT_Free(ss->ssl3.hs.recvdFragments.buf);
	}
    }

    ss->ssl3.initialized = PR_FALSE;

    SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
}

/* End of ssl3con.c */
