/* -*- 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++;
    }

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

    /* 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 */
