| Index: net/third_party/nss/ssl/ssl3ecc.c | 
| diff --git a/net/third_party/nss/ssl/ssl3ecc.c b/net/third_party/nss/ssl/ssl3ecc.c | 
| deleted file mode 100644 | 
| index c8e9d06b5879ba425c2e4df70fd695d2a82a27bd..0000000000000000000000000000000000000000 | 
| --- a/net/third_party/nss/ssl/ssl3ecc.c | 
| +++ /dev/null | 
| @@ -1,1481 +0,0 @@ | 
| -/* -*- 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/. */ | 
| - | 
| -/* ECC code moved here from ssl3con.c */ | 
| - | 
| -#include "nss.h" | 
| -#include "cert.h" | 
| -#include "ssl.h" | 
| -#include "cryptohi.h" /* for DSAU_ stuff */ | 
| -#include "keyhi.h" | 
| -#include "secder.h" | 
| -#include "secitem.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 "prinit.h" | 
| - | 
| -#include "pk11func.h" | 
| -#include "secmod.h" | 
| - | 
| -#include <stdio.h> | 
| - | 
| -#ifndef NSS_DISABLE_ECC | 
| - | 
| -#ifndef PK11_SETATTRS | 
| -#define PK11_SETATTRS(x, id, v, l) \ | 
| -    (x)->type = (id);              \ | 
| -    (x)->pValue = (v);             \ | 
| -    (x)->ulValueLen = (l); | 
| -#endif | 
| - | 
| -#define SSL_GET_SERVER_PUBLIC_KEY(sock, type)                                          \ | 
| -    (ss->serverCerts[type].serverKeyPair ? ss->serverCerts[type].serverKeyPair->pubKey \ | 
| -                                         : NULL) | 
| - | 
| -#define SSL_IS_CURVE_NEGOTIATED(curvemsk, curveName) \ | 
| -    ((curveName > ec_noName) &&                      \ | 
| -     (curveName < ec_pastLastName) &&                \ | 
| -     ((1UL << curveName) & curvemsk) != 0) | 
| - | 
| -static SECStatus ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve); | 
| - | 
| -#define supportedCurve(x) (((x) > ec_noName) && ((x) < ec_pastLastName)) | 
| - | 
| -/* Table containing OID tags for elliptic curves named in the | 
| - * ECC-TLS IETF draft. | 
| - */ | 
| -static const SECOidTag ecName2OIDTag[] = { | 
| -    0, | 
| -    SEC_OID_SECG_EC_SECT163K1, /*  1 */ | 
| -    SEC_OID_SECG_EC_SECT163R1, /*  2 */ | 
| -    SEC_OID_SECG_EC_SECT163R2, /*  3 */ | 
| -    SEC_OID_SECG_EC_SECT193R1, /*  4 */ | 
| -    SEC_OID_SECG_EC_SECT193R2, /*  5 */ | 
| -    SEC_OID_SECG_EC_SECT233K1, /*  6 */ | 
| -    SEC_OID_SECG_EC_SECT233R1, /*  7 */ | 
| -    SEC_OID_SECG_EC_SECT239K1, /*  8 */ | 
| -    SEC_OID_SECG_EC_SECT283K1, /*  9 */ | 
| -    SEC_OID_SECG_EC_SECT283R1, /* 10 */ | 
| -    SEC_OID_SECG_EC_SECT409K1, /* 11 */ | 
| -    SEC_OID_SECG_EC_SECT409R1, /* 12 */ | 
| -    SEC_OID_SECG_EC_SECT571K1, /* 13 */ | 
| -    SEC_OID_SECG_EC_SECT571R1, /* 14 */ | 
| -    SEC_OID_SECG_EC_SECP160K1, /* 15 */ | 
| -    SEC_OID_SECG_EC_SECP160R1, /* 16 */ | 
| -    SEC_OID_SECG_EC_SECP160R2, /* 17 */ | 
| -    SEC_OID_SECG_EC_SECP192K1, /* 18 */ | 
| -    SEC_OID_SECG_EC_SECP192R1, /* 19 */ | 
| -    SEC_OID_SECG_EC_SECP224K1, /* 20 */ | 
| -    SEC_OID_SECG_EC_SECP224R1, /* 21 */ | 
| -    SEC_OID_SECG_EC_SECP256K1, /* 22 */ | 
| -    SEC_OID_SECG_EC_SECP256R1, /* 23 */ | 
| -    SEC_OID_SECG_EC_SECP384R1, /* 24 */ | 
| -    SEC_OID_SECG_EC_SECP521R1, /* 25 */ | 
| -}; | 
| - | 
| -static const PRUint16 curve2bits[] = { | 
| -    0,    /*  ec_noName     = 0,   */ | 
| -    163,  /*  ec_sect163k1  = 1,   */ | 
| -    163,  /*  ec_sect163r1  = 2,   */ | 
| -    163,  /*  ec_sect163r2  = 3,   */ | 
| -    193,  /*  ec_sect193r1  = 4,   */ | 
| -    193,  /*  ec_sect193r2  = 5,   */ | 
| -    233,  /*  ec_sect233k1  = 6,   */ | 
| -    233,  /*  ec_sect233r1  = 7,   */ | 
| -    239,  /*  ec_sect239k1  = 8,   */ | 
| -    283,  /*  ec_sect283k1  = 9,   */ | 
| -    283,  /*  ec_sect283r1  = 10,  */ | 
| -    409,  /*  ec_sect409k1  = 11,  */ | 
| -    409,  /*  ec_sect409r1  = 12,  */ | 
| -    571,  /*  ec_sect571k1  = 13,  */ | 
| -    571,  /*  ec_sect571r1  = 14,  */ | 
| -    160,  /*  ec_secp160k1  = 15,  */ | 
| -    160,  /*  ec_secp160r1  = 16,  */ | 
| -    160,  /*  ec_secp160r2  = 17,  */ | 
| -    192,  /*  ec_secp192k1  = 18,  */ | 
| -    192,  /*  ec_secp192r1  = 19,  */ | 
| -    224,  /*  ec_secp224k1  = 20,  */ | 
| -    224,  /*  ec_secp224r1  = 21,  */ | 
| -    256,  /*  ec_secp256k1  = 22,  */ | 
| -    256,  /*  ec_secp256r1  = 23,  */ | 
| -    384,  /*  ec_secp384r1  = 24,  */ | 
| -    521,  /*  ec_secp521r1  = 25,  */ | 
| -    65535 /*  ec_pastLastName      */ | 
| -}; | 
| - | 
| -typedef struct Bits2CurveStr { | 
| -    PRUint16 bits; | 
| -    ECName curve; | 
| -} Bits2Curve; | 
| - | 
| -static const Bits2Curve bits2curve[] = { | 
| -    { 192, ec_secp192r1 /*  = 19,  fast */ }, | 
| -    { 160, ec_secp160r2 /*  = 17,  fast */ }, | 
| -    { 160, ec_secp160k1 /*  = 15,  */ }, | 
| -    { 160, ec_secp160r1 /*  = 16,  */ }, | 
| -    { 163, ec_sect163k1 /*  = 1,   */ }, | 
| -    { 163, ec_sect163r1 /*  = 2,   */ }, | 
| -    { 163, ec_sect163r2 /*  = 3,   */ }, | 
| -    { 192, ec_secp192k1 /*  = 18,  */ }, | 
| -    { 193, ec_sect193r1 /*  = 4,   */ }, | 
| -    { 193, ec_sect193r2 /*  = 5,   */ }, | 
| -    { 224, ec_secp224r1 /*  = 21,  fast */ }, | 
| -    { 224, ec_secp224k1 /*  = 20,  */ }, | 
| -    { 233, ec_sect233k1 /*  = 6,   */ }, | 
| -    { 233, ec_sect233r1 /*  = 7,   */ }, | 
| -    { 239, ec_sect239k1 /*  = 8,   */ }, | 
| -    { 256, ec_secp256r1 /*  = 23,  fast */ }, | 
| -    { 256, ec_secp256k1 /*  = 22,  */ }, | 
| -    { 283, ec_sect283k1 /*  = 9,   */ }, | 
| -    { 283, ec_sect283r1 /*  = 10,  */ }, | 
| -    { 384, ec_secp384r1 /*  = 24,  fast */ }, | 
| -    { 409, ec_sect409k1 /*  = 11,  */ }, | 
| -    { 409, ec_sect409r1 /*  = 12,  */ }, | 
| -    { 521, ec_secp521r1 /*  = 25,  fast */ }, | 
| -    { 571, ec_sect571k1 /*  = 13,  */ }, | 
| -    { 571, ec_sect571r1 /*  = 14,  */ }, | 
| -    { 65535, ec_noName } | 
| -}; | 
| - | 
| -typedef struct ECDHEKeyPairStr { | 
| -    ssl3KeyPair *pair; | 
| -    int error; /* error code of the call-once function */ | 
| -    PRCallOnceType once; | 
| -} ECDHEKeyPair; | 
| - | 
| -/* arrays of ECDHE KeyPairs */ | 
| -static ECDHEKeyPair gECDHEKeyPairs[ec_pastLastName]; | 
| - | 
| -SECStatus | 
| -ssl3_ECName2Params(PLArenaPool *arena, ECName curve, SECKEYECParams *params) | 
| -{ | 
| -    SECOidData *oidData = NULL; | 
| -    PRUint32 policyFlags = 0; | 
| - | 
| -    if ((curve <= ec_noName) || (curve >= ec_pastLastName) || | 
| -        ((oidData = SECOID_FindOIDByTag(ecName2OIDTag[curve])) == NULL)) { | 
| -        PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); | 
| -        return SECFailure; | 
| -    } | 
| - | 
| -    if ((NSS_GetAlgorithmPolicy(ecName2OIDTag[curve], &policyFlags) == | 
| -         SECSuccess) && | 
| -        !(policyFlags & NSS_USE_ALG_IN_SSL_KX)) { | 
| -        PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); | 
| -        return SECFailure; | 
| -    } | 
| - | 
| -    SECITEM_AllocItem(arena, params, (2 + oidData->oid.len)); | 
| -    /* | 
| -     * params->data needs to contain the ASN encoding of an object ID (OID) | 
| -     * representing the named curve. The actual OID is in | 
| -     * oidData->oid.data so we simply prepend 0x06 and OID length | 
| -     */ | 
| -    params->data[0] = SEC_ASN1_OBJECT_ID; | 
| -    params->data[1] = oidData->oid.len; | 
| -    memcpy(params->data + 2, oidData->oid.data, oidData->oid.len); | 
| - | 
| -    return SECSuccess; | 
| -} | 
| - | 
| -ECName | 
| -ssl3_PubKey2ECName(SECKEYPublicKey *pubKey) | 
| -{ | 
| -    SECItem oid = { siBuffer, NULL, 0 }; | 
| -    SECOidData *oidData = NULL; | 
| -    PRUint32 policyFlags = 0; | 
| -    ECName i; | 
| -    SECKEYECParams *params; | 
| - | 
| -    if (pubKey->keyType != ecKey) { | 
| -        PORT_Assert(0); | 
| -        return ec_noName; | 
| -    } | 
| - | 
| -    params = &pubKey->u.ec.DEREncodedParams; | 
| - | 
| -    /* | 
| -     * params->data needs to contain the ASN encoding of an object ID (OID) | 
| -     * representing a named curve. Here, we strip away everything | 
| -     * before the actual OID and use the OID to look up a named curve. | 
| -     */ | 
| -    if (params->data[0] != SEC_ASN1_OBJECT_ID) | 
| -        return ec_noName; | 
| -    oid.len = params->len - 2; | 
| -    oid.data = params->data + 2; | 
| -    if ((oidData = SECOID_FindOID(&oid)) == NULL) | 
| -        return ec_noName; | 
| -    if ((NSS_GetAlgorithmPolicy(oidData->offset, &policyFlags) == | 
| -         SECSuccess) && | 
| -        !(policyFlags & NSS_USE_ALG_IN_SSL_KX)) { | 
| -        return ec_noName; | 
| -    } | 
| -    for (i = ec_noName + 1; i < ec_pastLastName; i++) { | 
| -        if (ecName2OIDTag[i] == oidData->offset) | 
| -            return i; | 
| -    } | 
| - | 
| -    return ec_noName; | 
| -} | 
| - | 
| -/* Caller must set hiLevel error code. */ | 
| -static SECStatus | 
| -ssl3_ComputeECDHKeyHash(SSLHashType hashAlg, | 
| -                        SECItem ec_params, SECItem server_ecpoint, | 
| -                        SSL3Random *client_rand, SSL3Random *server_rand, | 
| -                        SSL3Hashes *hashes, PRBool bypassPKCS11) | 
| -{ | 
| -    PRUint8 *hashBuf; | 
| -    PRUint8 *pBuf; | 
| -    SECStatus rv = SECSuccess; | 
| -    unsigned int bufLen; | 
| -    /* | 
| -     * XXX For now, we only support named curves (the appropriate | 
| -     * checks are made before this method is called) so ec_params | 
| -     * takes up only two bytes. ECPoint needs to fit in 256 bytes | 
| -     * (because the spec says the length must fit in one byte) | 
| -     */ | 
| -    PRUint8 buf[2 * SSL3_RANDOM_LENGTH + 2 + 1 + 256]; | 
| - | 
| -    bufLen = 2 * SSL3_RANDOM_LENGTH + ec_params.len + 1 + server_ecpoint.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; | 
| -    memcpy(pBuf, ec_params.data, ec_params.len); | 
| -    pBuf += ec_params.len; | 
| -    pBuf[0] = (PRUint8)(server_ecpoint.len); | 
| -    pBuf += 1; | 
| -    memcpy(pBuf, server_ecpoint.data, server_ecpoint.len); | 
| -    pBuf += server_ecpoint.len; | 
| -    PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen); | 
| - | 
| -    rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes, | 
| -                                   bypassPKCS11); | 
| - | 
| -    PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen)); | 
| -    PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result", | 
| -                   hashes->u.s.md5, MD5_LENGTH)); | 
| -    PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result", | 
| -                   hashes->u.s.sha, SHA1_LENGTH)); | 
| - | 
| -    if (hashBuf != buf) | 
| -        PORT_Free(hashBuf); | 
| -    return rv; | 
| -} | 
| - | 
| -/* Called from ssl3_SendClientKeyExchange(). */ | 
| -SECStatus | 
| -ssl3_SendECDHClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey) | 
| -{ | 
| -    PK11SymKey *pms = NULL; | 
| -    SECStatus rv = SECFailure; | 
| -    PRBool isTLS, isTLS12; | 
| -    CK_MECHANISM_TYPE target; | 
| -    SECKEYPublicKey *pubKey = NULL;   /* Ephemeral ECDH key */ | 
| -    SECKEYPrivateKey *privKey = NULL; /* Ephemeral ECDH 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); | 
| -    isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); | 
| - | 
| -    /* Generate ephemeral EC keypair */ | 
| -    if (svrPubKey->keyType != ecKey) { | 
| -        PORT_SetError(SEC_ERROR_BAD_KEY); | 
| -        goto loser; | 
| -    } | 
| -    /* XXX SHOULD CALL ssl3_CreateECDHEphemeralKeys here, instead! */ | 
| -    privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams, | 
| -                                        &pubKey, ss->pkcs11PinArg); | 
| -    if (!privKey || !pubKey) { | 
| -        ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); | 
| -        rv = SECFailure; | 
| -        goto loser; | 
| -    } | 
| -    PRINT_BUF(50, (ss, "ECDH public value:", | 
| -                   pubKey->u.ec.publicValue.data, | 
| -                   pubKey->u.ec.publicValue.len)); | 
| - | 
| -    if (isTLS12) { | 
| -        target = CKM_TLS12_MASTER_KEY_DERIVE_DH; | 
| -    } else if (isTLS) { | 
| -        target = CKM_TLS_MASTER_KEY_DERIVE_DH; | 
| -    } else { | 
| -        target = CKM_SSL3_MASTER_KEY_DERIVE_DH; | 
| -    } | 
| - | 
| -    /*  Determine the PMS */ | 
| -    pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL, | 
| -                                CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, | 
| -                                CKD_NULL, NULL, NULL); | 
| - | 
| -    if (pms == NULL) { | 
| -        SSL3AlertDescription desc = illegal_parameter; | 
| -        (void)SSL3_SendAlert(ss, alert_fatal, desc); | 
| -        ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); | 
| -        goto loser; | 
| -    } | 
| - | 
| -    SECKEY_DestroyPrivateKey(privKey); | 
| -    privKey = NULL; | 
| - | 
| -    rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, | 
| -                                    pubKey->u.ec.publicValue.len + 1); | 
| -    if (rv != SECSuccess) { | 
| -        goto loser; /* err set by ssl3_AppendHandshake* */ | 
| -    } | 
| - | 
| -    rv = ssl3_AppendHandshakeVariable(ss, | 
| -                                      pubKey->u.ec.publicValue.data, | 
| -                                      pubKey->u.ec.publicValue.len, 1); | 
| -    SECKEY_DestroyPublicKey(pubKey); | 
| -    pubKey = NULL; | 
| - | 
| -    if (rv != SECSuccess) { | 
| -        goto loser; /* err set by ssl3_AppendHandshake* */ | 
| -    } | 
| - | 
| -    rv = ssl3_InitPendingCipherSpec(ss, pms); | 
| -    PK11_FreeSymKey(pms); | 
| -    pms = NULL; | 
| - | 
| -    if (rv != SECSuccess) { | 
| -        ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); | 
| -        goto loser; | 
| -    } | 
| - | 
| -    rv = SECSuccess; | 
| - | 
| -loser: | 
| -    if (pms) | 
| -        PK11_FreeSymKey(pms); | 
| -    if (privKey) | 
| -        SECKEY_DestroyPrivateKey(privKey); | 
| -    if (pubKey) | 
| -        SECKEY_DestroyPublicKey(pubKey); | 
| -    return rv; | 
| -} | 
| - | 
| -ECName | 
| -tls13_GroupForECDHEKeyShare(ssl3KeyPair *pair) | 
| -{ | 
| -    return ssl3_PubKey2ECName(pair->pubKey); | 
| -} | 
| - | 
| -/* This function returns the size of the key_exchange field in | 
| - * the KeyShareEntry structure. */ | 
| -unsigned int | 
| -tls13_SizeOfECDHEKeyShareKEX(ssl3KeyPair *pair) | 
| -{ | 
| -    return 1 + /* Length */ | 
| -           pair->pubKey->u.ec.publicValue.len; | 
| -} | 
| - | 
| -/* This function encodes the key_exchange field in | 
| - * the KeyShareEntry structure. */ | 
| -SECStatus | 
| -tls13_EncodeECDHEKeyShareKEX(sslSocket *ss, ssl3KeyPair *pair) | 
| -{ | 
| -    const SECItem *publicValue; | 
| - | 
| -    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | 
| -    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); | 
| - | 
| -    publicValue = &pair->pubKey->u.ec.publicValue; | 
| - | 
| -    return ssl3_AppendHandshakeVariable(ss, publicValue->data, | 
| -                                        publicValue->len, 1); | 
| -} | 
| - | 
| -/* | 
| -** Called from ssl3_HandleClientKeyExchange() | 
| -*/ | 
| -SECStatus | 
| -ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b, | 
| -                                 PRUint32 length, | 
| -                                 SECKEYPublicKey *srvrPubKey, | 
| -                                 SECKEYPrivateKey *srvrPrivKey) | 
| -{ | 
| -    PK11SymKey *pms; | 
| -    SECStatus rv; | 
| -    SECKEYPublicKey clntPubKey; | 
| -    CK_MECHANISM_TYPE target; | 
| -    PRBool isTLS, isTLS12; | 
| - | 
| -    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); | 
| -    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | 
| - | 
| -    clntPubKey.keyType = ecKey; | 
| -    clntPubKey.u.ec.DEREncodedParams.len = | 
| -        srvrPubKey->u.ec.DEREncodedParams.len; | 
| -    clntPubKey.u.ec.DEREncodedParams.data = | 
| -        srvrPubKey->u.ec.DEREncodedParams.data; | 
| - | 
| -    rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue, | 
| -                                       1, &b, &length); | 
| -    if (rv != SECSuccess) { | 
| -        SEND_ALERT | 
| -        return SECFailure; /* XXX Who sets the error code?? */ | 
| -    } | 
| - | 
| -    isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); | 
| -    isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); | 
| - | 
| -    if (isTLS12) { | 
| -        target = CKM_TLS12_MASTER_KEY_DERIVE_DH; | 
| -    } else if (isTLS) { | 
| -        target = CKM_TLS_MASTER_KEY_DERIVE_DH; | 
| -    } else { | 
| -        target = CKM_SSL3_MASTER_KEY_DERIVE_DH; | 
| -    } | 
| - | 
| -    /*  Determine the PMS */ | 
| -    pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL, | 
| -                                CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, | 
| -                                CKD_NULL, NULL, NULL); | 
| - | 
| -    if (pms == NULL) { | 
| -        /* last gasp.  */ | 
| -        ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); | 
| -        return SECFailure; | 
| -    } | 
| - | 
| -    rv = ssl3_InitPendingCipherSpec(ss, pms); | 
| -    PK11_FreeSymKey(pms); | 
| -    if (rv != SECSuccess) { | 
| -        SEND_ALERT | 
| -        return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */ | 
| -    } | 
| -    return SECSuccess; | 
| -} | 
| - | 
| -/* | 
| -** Take an encoded key share and make a public key out of it. | 
| -** returns NULL on error. | 
| -*/ | 
| -SECKEYPublicKey * | 
| -tls13_ImportECDHKeyShare(sslSocket *ss, SSL3Opaque *b, | 
| -                         PRUint32 length, ECName curve) | 
| -{ | 
| -    PLArenaPool *arena = NULL; | 
| -    SECKEYPublicKey *peerKey = NULL; | 
| -    SECStatus rv; | 
| -    SECItem ecPoint = { siBuffer, NULL, 0 }; | 
| - | 
| -    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); | 
| -    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | 
| - | 
| -    rv = ssl3_ConsumeHandshakeVariable(ss, &ecPoint, 1, &b, &length); | 
| -    if (rv != SECSuccess) { | 
| -        tls13_FatalError(ss, SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE, | 
| -                         illegal_parameter); | 
| -        return NULL; | 
| -    } | 
| -    if (length || !ecPoint.len) { | 
| -        tls13_FatalError(ss, SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE, | 
| -                         illegal_parameter); | 
| -        return NULL; | 
| -    } | 
| - | 
| -    /* Fail if the ec point uses compressed representation */ | 
| -    if (ecPoint.data[0] != EC_POINT_FORM_UNCOMPRESSED) { | 
| -        tls13_FatalError(ss, SEC_ERROR_UNSUPPORTED_EC_POINT_FORM, | 
| -                         illegal_parameter); | 
| -        return NULL; | 
| -    } | 
| - | 
| -    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 
| -    if (arena == NULL) { | 
| -        goto no_memory; | 
| -    } | 
| - | 
| -    peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey); | 
| -    if (peerKey == NULL) { | 
| -        goto no_memory; | 
| -    } | 
| - | 
| -    peerKey->arena = arena; | 
| -    peerKey->keyType = ecKey; | 
| -    /* Set up the encoded params */ | 
| -    rv = ssl3_ECName2Params(arena, curve, &peerKey->u.ec.DEREncodedParams); | 
| -    if (rv != SECSuccess) { | 
| -        goto no_memory; | 
| -    } | 
| - | 
| -    /* copy publicValue in peerKey */ | 
| -    if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue, &ecPoint) != | 
| -        SECSuccess) { | 
| -        goto no_memory; | 
| -    } | 
| -    peerKey->pkcs11Slot = NULL; | 
| -    peerKey->pkcs11ID = CK_INVALID_HANDLE; | 
| - | 
| -    return peerKey; | 
| - | 
| -no_memory: /* no-memory error has already been set. */ | 
| -    PORT_FreeArena(arena, PR_FALSE); | 
| -    ssl_MapLowLevelError(SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE); | 
| -    return NULL; | 
| -} | 
| - | 
| -PK11SymKey * | 
| -tls13_ComputeECDHSharedKey(sslSocket *ss, | 
| -                           SECKEYPrivateKey *myPrivKey, | 
| -                           SECKEYPublicKey *peerKey) | 
| -{ | 
| -    PK11SymKey *shared; | 
| - | 
| -    /* Determine the PMS */ | 
| -    shared = PK11_PubDeriveWithKDF(myPrivKey, peerKey, PR_FALSE, NULL, NULL, | 
| -                                   CKM_ECDH1_DERIVE, | 
| -                                   tls13_GetHkdfMechanism(ss), CKA_DERIVE, 0, | 
| -                                   CKD_NULL, NULL, NULL); | 
| - | 
| -    if (!shared) { | 
| -        ssl_MapLowLevelError(SSL_ERROR_KEY_EXCHANGE_FAILURE); | 
| -        return NULL; | 
| -    } | 
| - | 
| -    return shared; | 
| -} | 
| - | 
| -ECName | 
| -ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits) | 
| -{ | 
| -    int i; | 
| - | 
| -    for (i = 0; bits2curve[i].curve != ec_noName; i++) { | 
| -        if (bits2curve[i].bits < requiredECCbits) | 
| -            continue; | 
| -        if (SSL_IS_CURVE_NEGOTIATED(curvemsk, bits2curve[i].curve)) { | 
| -            return bits2curve[i].curve; | 
| -        } | 
| -    } | 
| -    PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); | 
| -    return ec_noName; | 
| -} | 
| - | 
| -/* find the "weakest link".  Get strength of signature key and of sym key. | 
| - * choose curve for the weakest of those two. | 
| - */ | 
| -ECName | 
| -ssl3_GetCurveNameForServerSocket(sslSocket *ss) | 
| -{ | 
| -    SECKEYPublicKey *svrPublicKey = NULL; | 
| -    ECName ec_curve = ec_noName; | 
| -    int signatureKeyStrength = 521; | 
| -    int requiredECCbits = ss->sec.secretKeyBits * 2; | 
| - | 
| -    if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa) { | 
| -        svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_ecdh); | 
| -        if (svrPublicKey) | 
| -            ec_curve = ssl3_PubKey2ECName(svrPublicKey); | 
| -        if (!SSL_IS_CURVE_NEGOTIATED(ss->ssl3.hs.negotiatedECCurves, ec_curve)) { | 
| -            PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); | 
| -            return ec_noName; | 
| -        } | 
| -        signatureKeyStrength = curve2bits[ec_curve]; | 
| -    } else { | 
| -        /* RSA is our signing cert */ | 
| -        int serverKeyStrengthInBits; | 
| - | 
| -        svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_rsa); | 
| -        if (!svrPublicKey) { | 
| -            PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); | 
| -            return ec_noName; | 
| -        } | 
| - | 
| -        /* currently strength in bytes */ | 
| -        serverKeyStrengthInBits = svrPublicKey->u.rsa.modulus.len; | 
| -        if (svrPublicKey->u.rsa.modulus.data[0] == 0) { | 
| -            serverKeyStrengthInBits--; | 
| -        } | 
| -        /* convert to strength in bits */ | 
| -        serverKeyStrengthInBits *= BPB; | 
| - | 
| -        signatureKeyStrength = | 
| -            SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits); | 
| -    } | 
| -    if (requiredECCbits > signatureKeyStrength) | 
| -        requiredECCbits = signatureKeyStrength; | 
| - | 
| -    return ssl3_GetCurveWithECKeyStrength(ss->ssl3.hs.negotiatedECCurves, | 
| -                                          requiredECCbits); | 
| -} | 
| - | 
| -/* function to clear out the lists */ | 
| -static SECStatus | 
| -ssl3_ShutdownECDHECurves(void *appData, void *nssData) | 
| -{ | 
| -    int i; | 
| -    ECDHEKeyPair *keyPair = &gECDHEKeyPairs[0]; | 
| - | 
| -    for (i = 0; i < ec_pastLastName; i++, keyPair++) { | 
| -        if (keyPair->pair) { | 
| -            ssl3_FreeKeyPair(keyPair->pair); | 
| -        } | 
| -    } | 
| -    memset(gECDHEKeyPairs, 0, sizeof gECDHEKeyPairs); | 
| -    return SECSuccess; | 
| -} | 
| - | 
| -static PRStatus | 
| -ssl3_ECRegister(void) | 
| -{ | 
| -    SECStatus rv; | 
| -    rv = NSS_RegisterShutdown(ssl3_ShutdownECDHECurves, gECDHEKeyPairs); | 
| -    if (rv != SECSuccess) { | 
| -        gECDHEKeyPairs[ec_noName].error = PORT_GetError(); | 
| -    } | 
| -    return (PRStatus)rv; | 
| -} | 
| - | 
| -/* Create an ECDHE key pair for a given curve */ | 
| -SECStatus | 
| -ssl3_CreateECDHEphemeralKeyPair(ECName ec_curve, ssl3KeyPair **keyPair) | 
| -{ | 
| -    SECKEYPrivateKey *privKey = NULL; | 
| -    SECKEYPublicKey *pubKey = NULL; | 
| -    SECKEYECParams ecParams = { siBuffer, NULL, 0 }; | 
| - | 
| -    if (ssl3_ECName2Params(NULL, ec_curve, &ecParams) != SECSuccess) { | 
| -        return SECFailure; | 
| -    } | 
| -    privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL); | 
| -    SECITEM_FreeItem(&ecParams, PR_FALSE); | 
| - | 
| -    if (!privKey || !pubKey || !(*keyPair = ssl3_NewKeyPair(privKey, pubKey))) { | 
| -        if (privKey) { | 
| -            SECKEY_DestroyPrivateKey(privKey); | 
| -        } | 
| -        if (pubKey) { | 
| -            SECKEY_DestroyPublicKey(pubKey); | 
| -        } | 
| -        ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); | 
| -        return SECFailure; | 
| -    } | 
| - | 
| -    return SECSuccess; | 
| -} | 
| - | 
| -/* CallOnce function, called once for each named curve. */ | 
| -static PRStatus | 
| -ssl3_CreateECDHEphemeralKeyPairOnce(void *arg) | 
| -{ | 
| -    ECName ec_curve = (ECName)arg; | 
| -    ssl3KeyPair *keyPair = NULL; | 
| - | 
| -    PORT_Assert(gECDHEKeyPairs[ec_curve].pair == NULL); | 
| - | 
| -    /* ok, no one has generated a global key for this curve yet, do so */ | 
| -    if (ssl3_CreateECDHEphemeralKeyPair(ec_curve, &keyPair) != SECSuccess) { | 
| -        gECDHEKeyPairs[ec_curve].error = PORT_GetError(); | 
| -        return PR_FAILURE; | 
| -    } | 
| - | 
| -    gECDHEKeyPairs[ec_curve].pair = keyPair; | 
| -    return PR_SUCCESS; | 
| -} | 
| - | 
| -/* | 
| - * Creates the ephemeral public and private ECDH keys used by | 
| - * server in ECDHE_RSA and ECDHE_ECDSA handshakes. | 
| - * For now, the elliptic curve is chosen to be the same | 
| - * strength as the signing certificate (ECC or RSA). | 
| - * We need an API to specify the curve. This won't be a real | 
| - * issue until we further develop server-side support for ECC | 
| - * cipher suites. | 
| - */ | 
| -static SECStatus | 
| -ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve) | 
| -{ | 
| -    ssl3KeyPair *keyPair = NULL; | 
| - | 
| -    /* if there's no global key for this curve, make one. */ | 
| -    if (gECDHEKeyPairs[ec_curve].pair == NULL) { | 
| -        PRStatus status; | 
| - | 
| -        status = PR_CallOnce(&gECDHEKeyPairs[ec_noName].once, ssl3_ECRegister); | 
| -        if (status != PR_SUCCESS) { | 
| -            PORT_SetError(gECDHEKeyPairs[ec_noName].error); | 
| -            return SECFailure; | 
| -        } | 
| -        status = PR_CallOnceWithArg(&gECDHEKeyPairs[ec_curve].once, | 
| -                                    ssl3_CreateECDHEphemeralKeyPairOnce, | 
| -                                    (void *)ec_curve); | 
| -        if (status != PR_SUCCESS) { | 
| -            PORT_SetError(gECDHEKeyPairs[ec_curve].error); | 
| -            return SECFailure; | 
| -        } | 
| -    } | 
| - | 
| -    keyPair = gECDHEKeyPairs[ec_curve].pair; | 
| -    PORT_Assert(keyPair != NULL); | 
| -    if (!keyPair) | 
| -        return SECFailure; | 
| -    ss->ephemeralECDHKeyPair = ssl3_GetKeyPairRef(keyPair); | 
| - | 
| -    return SECSuccess; | 
| -} | 
| - | 
| -SECStatus | 
| -ssl3_HandleECDHServerKeyExchange(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 }; | 
| - | 
| -    SECItem ec_params = { siBuffer, NULL, 0 }; | 
| -    SECItem ec_point = { siBuffer, NULL, 0 }; | 
| -    unsigned char paramBuf[3]; /* only for curve_type == named_curve */ | 
| -    SSLSignatureAndHashAlg sigAndHash; | 
| - | 
| -    sigAndHash.hashAlg = ssl_hash_none; | 
| - | 
| -    isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); | 
| -    isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); | 
| - | 
| -    /* XXX This works only for named curves, revisit this when | 
| -     * we support generic curves. | 
| -     */ | 
| -    ec_params.len = sizeof paramBuf; | 
| -    ec_params.data = paramBuf; | 
| -    rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length); | 
| -    if (rv != SECSuccess) { | 
| -        goto loser; /* malformed. */ | 
| -    } | 
| - | 
| -    /* Fail if the curve is not a named curve */ | 
| -    if ((ec_params.data[0] != ec_type_named) || | 
| -        (ec_params.data[1] != 0) || | 
| -        !supportedCurve(ec_params.data[2])) { | 
| -        errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE; | 
| -        desc = handshake_failure; | 
| -        goto alert_loser; | 
| -    } | 
| - | 
| -    rv = ssl3_ConsumeHandshakeVariable(ss, &ec_point, 1, &b, &length); | 
| -    if (rv != SECSuccess) { | 
| -        goto loser; /* malformed. */ | 
| -    } | 
| -    /* Fail if the ec point uses compressed representation */ | 
| -    if (ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) { | 
| -        errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM; | 
| -        desc = handshake_failure; | 
| -        goto alert_loser; | 
| -    } | 
| - | 
| -    if (isTLS12) { | 
| -        rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length, | 
| -                                                   &sigAndHash); | 
| -        if (rv != SECSuccess) { | 
| -            goto loser; /* malformed or unsupported. */ | 
| -        } | 
| -        rv = ssl3_CheckSignatureAndHashAlgorithmConsistency( | 
| -            ss, &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 EC params", ec_params.data, | 
| -                   ec_params.len)); | 
| -    PRINT_BUF(60, (NULL, "Server EC point", ec_point.data, ec_point.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_ComputeECDHKeyHash(sigAndHash.hashAlg, ec_params, ec_point, | 
| -                                 &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; | 
| -    } | 
| - | 
| -    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 
| -    if (arena == NULL) { | 
| -        goto no_memory; | 
| -    } | 
| - | 
| -    peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey); | 
| -    if (peerKey == NULL) { | 
| -        goto no_memory; | 
| -    } | 
| - | 
| -    peerKey->arena = arena; | 
| -    peerKey->keyType = ecKey; | 
| - | 
| -    /* set up EC parameters in peerKey */ | 
| -    if (ssl3_ECName2Params(arena, ec_params.data[2], | 
| -                           &peerKey->u.ec.DEREncodedParams) != | 
| -        SECSuccess) { | 
| -        /* we should never get here since we already | 
| -         * checked that we are dealing with a supported curve | 
| -         */ | 
| -        errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE; | 
| -        goto alert_loser; | 
| -    } | 
| - | 
| -    /* copy publicValue in peerKey */ | 
| -    if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue, &ec_point)) { | 
| -        goto no_memory; | 
| -    } | 
| -    peerKey->pkcs11Slot = NULL; | 
| -    peerKey->pkcs11ID = CK_INVALID_HANDLE; | 
| - | 
| -    ss->sec.peerKey = peerKey; | 
| -    ss->ssl3.hs.ws = wait_cert_request; | 
| - | 
| -    return SECSuccess; | 
| - | 
| -alert_loser: | 
| -    (void)SSL3_SendAlert(ss, alert_fatal, desc); | 
| -loser: | 
| -    if (arena) { | 
| -        PORT_FreeArena(arena, PR_FALSE); | 
| -    } | 
| -    PORT_SetError(errCode); | 
| -    return SECFailure; | 
| - | 
| -no_memory: /* no-memory error has already been set. */ | 
| -    if (arena) { | 
| -        PORT_FreeArena(arena, PR_FALSE); | 
| -    } | 
| -    ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | 
| -    return SECFailure; | 
| -} | 
| - | 
| -SECStatus | 
| -ssl3_SendECDHServerKeyExchange( | 
| -    sslSocket *ss, | 
| -    const SSLSignatureAndHashAlg *sigAndHash) | 
| -{ | 
| -    const ssl3KEADef *kea_def = ss->ssl3.hs.kea_def; | 
| -    SECStatus rv = SECFailure; | 
| -    int length; | 
| -    PRBool isTLS, isTLS12; | 
| -    SECItem signed_hash = { siBuffer, NULL, 0 }; | 
| -    SSL3Hashes hashes; | 
| - | 
| -    SECKEYPublicKey *ecdhePub; | 
| -    SECItem ec_params = { siBuffer, NULL, 0 }; | 
| -    unsigned char paramBuf[3]; | 
| -    ECName curve; | 
| -    SSL3KEAType certIndex; | 
| - | 
| -    /* Generate ephemeral ECDH key pair and send the public key */ | 
| -    curve = ssl3_GetCurveNameForServerSocket(ss); | 
| -    if (curve == ec_noName) { | 
| -        goto loser; | 
| -    } | 
| - | 
| -    if (ss->opt.reuseServerECDHEKey) { | 
| -        rv = ssl3_CreateECDHEphemeralKeys(ss, curve); | 
| -    } else { | 
| -        rv = ssl3_CreateECDHEphemeralKeyPair(curve, &ss->ephemeralECDHKeyPair); | 
| -    } | 
| -    if (rv != SECSuccess) { | 
| -        goto loser; | 
| -    } | 
| - | 
| -    ecdhePub = ss->ephemeralECDHKeyPair->pubKey; | 
| -    PORT_Assert(ecdhePub != NULL); | 
| -    if (!ecdhePub) { | 
| -        PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | 
| -        return SECFailure; | 
| -    } | 
| - | 
| -    ec_params.len = sizeof paramBuf; | 
| -    ec_params.data = paramBuf; | 
| -    curve = ssl3_PubKey2ECName(ecdhePub); | 
| -    if (curve != ec_noName) { | 
| -        ec_params.data[0] = ec_type_named; | 
| -        ec_params.data[1] = 0x00; | 
| -        ec_params.data[2] = curve; | 
| -    } else { | 
| -        PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); | 
| -        goto loser; | 
| -    } | 
| - | 
| -    rv = ssl3_ComputeECDHKeyHash(sigAndHash->hashAlg, | 
| -                                 ec_params, | 
| -                                 ecdhePub->u.ec.publicValue, | 
| -                                 &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); | 
| -        goto loser; | 
| -    } | 
| - | 
| -    isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); | 
| -    isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); | 
| - | 
| -    /* XXX SSLKEAType isn't really a good choice for | 
| -     * indexing certificates but that's all we have | 
| -     * for now. | 
| -     */ | 
| -    if (kea_def->kea == kea_ecdhe_rsa) | 
| -        certIndex = kt_rsa; | 
| -    else /* kea_def->kea == kea_ecdhe_ecdsa */ | 
| -        certIndex = kt_ecdh; | 
| - | 
| -    rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].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 = ec_params.len + | 
| -             1 + ecdhePub->u.ec.publicValue.len + | 
| -             (isTLS12 ? 2 : 0) + 2 + signed_hash.len; | 
| - | 
| -    rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length); | 
| -    if (rv != SECSuccess) { | 
| -        goto loser; /* err set by AppendHandshake. */ | 
| -    } | 
| - | 
| -    rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len); | 
| -    if (rv != SECSuccess) { | 
| -        goto loser; /* err set by AppendHandshake. */ | 
| -    } | 
| - | 
| -    rv = ssl3_AppendHandshakeVariable(ss, ecdhePub->u.ec.publicValue.data, | 
| -                                      ecdhePub->u.ec.publicValue.len, 1); | 
| -    if (rv != SECSuccess) { | 
| -        goto loser; /* err set by AppendHandshake. */ | 
| -    } | 
| - | 
| -    if (isTLS12) { | 
| -        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; | 
| - | 
| -loser: | 
| -    if (signed_hash.data != NULL) | 
| -        PORT_Free(signed_hash.data); | 
| -    return SECFailure; | 
| -} | 
| - | 
| -/* Lists of ECC cipher suites for searching and disabling. */ | 
| - | 
| -static const ssl3CipherSuite ecdh_suites[] = { | 
| -    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, | 
| -    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, | 
| -    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, | 
| -    TLS_ECDH_ECDSA_WITH_NULL_SHA, | 
| -    TLS_ECDH_ECDSA_WITH_RC4_128_SHA, | 
| -    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, | 
| -    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, | 
| -    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, | 
| -    TLS_ECDH_RSA_WITH_NULL_SHA, | 
| -    TLS_ECDH_RSA_WITH_RC4_128_SHA, | 
| -    0 /* end of list marker */ | 
| -}; | 
| - | 
| -static const ssl3CipherSuite ecdh_ecdsa_suites[] = { | 
| -    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, | 
| -    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, | 
| -    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, | 
| -    TLS_ECDH_ECDSA_WITH_NULL_SHA, | 
| -    TLS_ECDH_ECDSA_WITH_RC4_128_SHA, | 
| -    0 /* end of list marker */ | 
| -}; | 
| - | 
| -static const ssl3CipherSuite ecdh_rsa_suites[] = { | 
| -    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, | 
| -    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, | 
| -    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, | 
| -    TLS_ECDH_RSA_WITH_NULL_SHA, | 
| -    TLS_ECDH_RSA_WITH_RC4_128_SHA, | 
| -    0 /* end of list marker */ | 
| -}; | 
| - | 
| -static const ssl3CipherSuite ecdhe_ecdsa_suites[] = { | 
| -    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, | 
| -    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, | 
| -    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, | 
| -    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, | 
| -    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, | 
| -    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, | 
| -    TLS_ECDHE_ECDSA_WITH_NULL_SHA, | 
| -    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, | 
| -    0 /* end of list marker */ | 
| -}; | 
| - | 
| -static const ssl3CipherSuite ecdhe_rsa_suites[] = { | 
| -    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, | 
| -    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, | 
| -    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, | 
| -    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, | 
| -    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, | 
| -    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, | 
| -    TLS_ECDHE_RSA_WITH_NULL_SHA, | 
| -    TLS_ECDHE_RSA_WITH_RC4_128_SHA, | 
| -    0 /* end of list marker */ | 
| -}; | 
| - | 
| -/* List of all ECC cipher suites */ | 
| -static const ssl3CipherSuite ecSuites[] = { | 
| -    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, | 
| -    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, | 
| -    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, | 
| -    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, | 
| -    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, | 
| -    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, | 
| -    TLS_ECDHE_ECDSA_WITH_NULL_SHA, | 
| -    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, | 
| -    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, | 
| -    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, | 
| -    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, | 
| -    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, | 
| -    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, | 
| -    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, | 
| -    TLS_ECDHE_RSA_WITH_NULL_SHA, | 
| -    TLS_ECDHE_RSA_WITH_RC4_128_SHA, | 
| -    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, | 
| -    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, | 
| -    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, | 
| -    TLS_ECDH_ECDSA_WITH_NULL_SHA, | 
| -    TLS_ECDH_ECDSA_WITH_RC4_128_SHA, | 
| -    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, | 
| -    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, | 
| -    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, | 
| -    TLS_ECDH_RSA_WITH_NULL_SHA, | 
| -    TLS_ECDH_RSA_WITH_RC4_128_SHA, | 
| -    0 /* end of list marker */ | 
| -}; | 
| - | 
| -/* On this socket, Disable the ECC cipher suites in the argument's list */ | 
| -SECStatus | 
| -ssl3_DisableECCSuites(sslSocket *ss, const ssl3CipherSuite *suite) | 
| -{ | 
| -    if (!suite) | 
| -        suite = ecSuites; | 
| -    for (; *suite; ++suite) { | 
| -        PORT_CheckSuccess(ssl3_CipherPrefSet(ss, *suite, PR_FALSE)); | 
| -    } | 
| -    return SECSuccess; | 
| -} | 
| - | 
| -/* Look at the server certs configured on this socket, and disable any | 
| - * ECC cipher suites that are not supported by those certs. | 
| - */ | 
| -void | 
| -ssl3_FilterECCipherSuitesByServerCerts(sslSocket *ss) | 
| -{ | 
| -    CERTCertificate *svrCert; | 
| - | 
| -    svrCert = ss->serverCerts[kt_rsa].serverCert; | 
| -    if (!svrCert) { | 
| -        ssl3_DisableECCSuites(ss, ecdhe_rsa_suites); | 
| -    } | 
| - | 
| -    svrCert = ss->serverCerts[kt_ecdh].serverCert; | 
| -    if (!svrCert) { | 
| -        ssl3_DisableECCSuites(ss, ecdh_suites); | 
| -        ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites); | 
| -    } else { | 
| -        SECOidTag sigTag = SECOID_GetAlgorithmTag(&svrCert->signature); | 
| - | 
| -        switch (sigTag) { | 
| -            case SEC_OID_PKCS1_RSA_ENCRYPTION: | 
| -            case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: | 
| -            case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: | 
| -            case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: | 
| -            case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: | 
| -            case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION: | 
| -            case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: | 
| -            case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: | 
| -            case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: | 
| -                ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites); | 
| -                break; | 
| -            case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: | 
| -            case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: | 
| -            case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: | 
| -            case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: | 
| -            case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: | 
| -            case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST: | 
| -            case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST: | 
| -                ssl3_DisableECCSuites(ss, ecdh_rsa_suites); | 
| -                break; | 
| -            default: | 
| -                ssl3_DisableECCSuites(ss, ecdh_suites); | 
| -                break; | 
| -        } | 
| -    } | 
| -} | 
| - | 
| -/* Ask: is ANY ECC cipher suite enabled on this socket? */ | 
| -/* Order(N^2).  Yuk.  Also, this ignores export policy. */ | 
| -PRBool | 
| -ssl3_IsECCEnabled(sslSocket *ss) | 
| -{ | 
| -    const ssl3CipherSuite *suite; | 
| -    PK11SlotInfo *slot; | 
| - | 
| -    /* make sure we can do ECC */ | 
| -    slot = PK11_GetBestSlot(CKM_ECDH1_DERIVE, ss->pkcs11PinArg); | 
| -    if (!slot) { | 
| -        return PR_FALSE; | 
| -    } | 
| -    PK11_FreeSlot(slot); | 
| - | 
| -    /* make sure an ECC cipher is enabled */ | 
| -    for (suite = ecSuites; *suite; ++suite) { | 
| -        PRBool enabled = PR_FALSE; | 
| -        SECStatus rv = ssl3_CipherPrefGet(ss, *suite, &enabled); | 
| - | 
| -        PORT_Assert(rv == SECSuccess); /* else is coding error */ | 
| -        if (rv == SECSuccess && enabled) | 
| -            return PR_TRUE; | 
| -    } | 
| -    return PR_FALSE; | 
| -} | 
| - | 
| -#define BE(n) 0, n | 
| - | 
| -/* Prefabricated TLS client hello extension, Elliptic Curves List, | 
| - * offers only 3 curves, the Suite B curves, 23-25 | 
| - */ | 
| -static const PRUint8 suiteBECList[] = { | 
| -    23, 24, 25 | 
| -}; | 
| - | 
| -/* Prefabricated TLS client hello extension, Elliptic Curves List, | 
| - * offers curves 1-25. | 
| - */ | 
| -/* clang-format off */ | 
| -static const PRUint8 tlsECList[] = { | 
| -     1,  2,  3,  4,  5,  6,  7,  8, | 
| -     9, 10, 11, 12, 13, 14, 15, 16, | 
| -    17, 18, 19, 20, 21, 22, 23, 24, | 
| -    25 | 
| -}; | 
| -/* clang-format on */ | 
| - | 
| -static const PRUint8 ecPtFmt[6] = { | 
| -    BE(11), /* Extension type */ | 
| -    BE(2),  /* octets that follow */ | 
| -    1,      /* octets that follow */ | 
| -    0       /* uncompressed type only */ | 
| -}; | 
| - | 
| -/* This function already presumes we can do ECC, ssl3_IsECCEnabled must be | 
| - * called before this function. It looks to see if we have a token which | 
| - * is capable of doing smaller than SuiteB curves. If the token can, we | 
| - * presume the token can do the whole SSL suite of curves. If it can't we | 
| - * presume the token that allowed ECC to be enabled can only do suite B | 
| - * curves. */ | 
| -static PRBool | 
| -ssl3_SuiteBOnly(sslSocket *ss) | 
| -{ | 
| -    /* See if we can support small curves (like 163). If not, assume we can | 
| -     * only support Suite-B curves (P-256, P-384, P-521). */ | 
| -    PK11SlotInfo *slot = | 
| -        PK11_GetBestSlotWithAttributes(CKM_ECDH1_DERIVE, 0, 163, | 
| -                                       ss ? ss->pkcs11PinArg : NULL); | 
| - | 
| -    if (!slot) { | 
| -        /* nope, presume we can only do suite B */ | 
| -        return PR_TRUE; | 
| -    } | 
| -    /* we can, presume we can do all curves */ | 
| -    PK11_FreeSlot(slot); | 
| -    return PR_FALSE; | 
| -} | 
| - | 
| -#define APPEND_CURVE(CURVE_ID)                                       \ | 
| -    if ((NSS_GetAlgorithmPolicy(ecName2OIDTag[CURVE_ID], &policy) == \ | 
| -         SECFailure) ||                                              \ | 
| -        (policy & NSS_USE_ALG_IN_SSL_KX)) {                          \ | 
| -        enabledCurves[pos++] = 0;                                    \ | 
| -        enabledCurves[pos++] = CURVE_ID;                             \ | 
| -    } | 
| - | 
| -/* Send our "canned" (precompiled) Supported Elliptic Curves extension, | 
| - * which says that we support all TLS-defined named curves. | 
| - */ | 
| -PRInt32 | 
| -ssl3_SendSupportedCurvesXtn( | 
| -    sslSocket *ss, | 
| -    PRBool append, | 
| -    PRUint32 maxBytes) | 
| -{ | 
| -    unsigned char enabledCurves[64]; | 
| -    PRUint32 policy; | 
| -    PRInt32 extension_length; | 
| -    PRInt32 ecListSize = 0; | 
| -    unsigned int pos = 0; | 
| -    unsigned int i; | 
| - | 
| -    if (!ss || !ssl3_IsECCEnabled(ss)) | 
| -        return 0; | 
| - | 
| -    PORT_Assert(sizeof(enabledCurves) > sizeof(tlsECList) * 2); | 
| -    if (ssl3_SuiteBOnly(ss)) { | 
| -        for (i = 0; i < sizeof(suiteBECList); i++) { | 
| -            APPEND_CURVE(suiteBECList[i]); | 
| -        } | 
| -        ecListSize = pos; | 
| -    } else { | 
| -        for (i = 0; i < sizeof(tlsECList); i++) { | 
| -            APPEND_CURVE(tlsECList[i]); | 
| -        } | 
| -        ecListSize = pos; | 
| -    } | 
| -    extension_length = | 
| -        2 /* extension type */ + | 
| -        2 /* extension length */ + | 
| -        2 /* elliptic curves length */ + | 
| -        ecListSize; | 
| - | 
| -    if (maxBytes < (PRUint32)extension_length) { | 
| -        return 0; | 
| -    } | 
| - | 
| -    if (append) { | 
| -        SECStatus rv; | 
| -        rv = ssl3_AppendHandshakeNumber(ss, ssl_elliptic_curves_xtn, 2); | 
| -        if (rv != SECSuccess) | 
| -            return -1; | 
| -        rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); | 
| -        if (rv != SECSuccess) | 
| -            return -1; | 
| -        rv = ssl3_AppendHandshakeVariable(ss, enabledCurves, ecListSize, 2); | 
| -        if (rv != SECSuccess) | 
| -            return -1; | 
| -        if (!ss->sec.isServer) { | 
| -            TLSExtensionData *xtnData = &ss->xtnData; | 
| -            xtnData->advertised[xtnData->numAdvertised++] = | 
| -                ssl_elliptic_curves_xtn; | 
| -        } | 
| -    } | 
| -    return extension_length; | 
| -} | 
| - | 
| -PRUint32 | 
| -ssl3_GetSupportedECCurveMask(sslSocket *ss) | 
| -{ | 
| -    int i; | 
| -    PRUint32 curves = 0; | 
| -    PRUint32 policyFlags = 0; | 
| - | 
| -    PORT_Assert(ec_pastLastName < sizeof(PRUint32) * 8); | 
| - | 
| -    if (ssl3_SuiteBOnly(ss)) { | 
| -        curves = SSL3_SUITE_B_SUPPORTED_CURVES_MASK; | 
| -    } else { | 
| -        curves = SSL3_ALL_SUPPORTED_CURVES_MASK; | 
| -    } | 
| - | 
| -    for (i = ec_noName + 1; i < ec_pastLastName; i++) { | 
| -        PRUint32 curve_bit = (1U << i); | 
| -        if ((curves & curve_bit) && | 
| -            (NSS_GetAlgorithmPolicy(ecName2OIDTag[i], &policyFlags) == | 
| -             SECSuccess) && | 
| -            !(policyFlags & NSS_USE_ALG_IN_SSL_KX)) { | 
| -            curves &= ~curve_bit; | 
| -        } | 
| -    } | 
| -    return curves; | 
| -} | 
| - | 
| -/* Send our "canned" (precompiled) Supported Point Formats extension, | 
| - * which says that we only support uncompressed points. | 
| - */ | 
| -PRInt32 | 
| -ssl3_SendSupportedPointFormatsXtn( | 
| -    sslSocket *ss, | 
| -    PRBool append, | 
| -    PRUint32 maxBytes) | 
| -{ | 
| -    if (!ss || !ssl3_IsECCEnabled(ss)) | 
| -        return 0; | 
| -    if (append && maxBytes >= (sizeof ecPtFmt)) { | 
| -        SECStatus rv = ssl3_AppendHandshake(ss, ecPtFmt, (sizeof ecPtFmt)); | 
| -        if (rv != SECSuccess) | 
| -            return -1; | 
| -        if (!ss->sec.isServer) { | 
| -            TLSExtensionData *xtnData = &ss->xtnData; | 
| -            xtnData->advertised[xtnData->numAdvertised++] = | 
| -                ssl_ec_point_formats_xtn; | 
| -        } | 
| -    } | 
| -    return (sizeof ecPtFmt); | 
| -} | 
| - | 
| -/* Just make sure that the remote client supports uncompressed points, | 
| - * Since that is all we support.  Disable ECC cipher suites if it doesn't. | 
| - */ | 
| -SECStatus | 
| -ssl3_HandleSupportedPointFormatsXtn(sslSocket *ss, PRUint16 ex_type, | 
| -                                    SECItem *data) | 
| -{ | 
| -    int i; | 
| - | 
| -    if (data->len < 2 || data->len > 255 || !data->data || | 
| -        data->len != (unsigned int)data->data[0] + 1) { | 
| -        return ssl3_DecodeError(ss); | 
| -    } | 
| -    for (i = data->len; --i > 0;) { | 
| -        if (data->data[i] == 0) { | 
| -            /* indicate that we should send a reply */ | 
| -            SECStatus rv; | 
| -            rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, | 
| -                                                         &ssl3_SendSupportedPointFormatsXtn); | 
| -            return rv; | 
| -        } | 
| -    } | 
| - | 
| -    /* evil client doesn't support uncompressed */ | 
| -    ssl3_DisableECCSuites(ss, ecSuites); | 
| -    return SECSuccess; | 
| -} | 
| - | 
| -#define SSL3_GET_SERVER_PUBLICKEY(sock, type)                                          \ | 
| -    (ss->serverCerts[type].serverKeyPair ? ss->serverCerts[type].serverKeyPair->pubKey \ | 
| -                                         : NULL) | 
| - | 
| -/* Extract the TLS curve name for the public key in our EC server cert. */ | 
| -ECName | 
| -ssl3_GetSvrCertCurveName(sslSocket *ss) | 
| -{ | 
| -    SECKEYPublicKey *srvPublicKey; | 
| -    ECName ec_curve = ec_noName; | 
| - | 
| -    srvPublicKey = SSL3_GET_SERVER_PUBLICKEY(ss, kt_ecdh); | 
| -    if (srvPublicKey) { | 
| -        ec_curve = ssl3_PubKey2ECName(srvPublicKey); | 
| -    } | 
| -    return ec_curve; | 
| -} | 
| - | 
| -/* Ensure that the curve in our server cert is one of the ones supported | 
| - * by the remote client, and disable all ECC cipher suites if not. | 
| - */ | 
| -SECStatus | 
| -ssl3_HandleSupportedCurvesXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) | 
| -{ | 
| -    PRInt32 list_len; | 
| -    PRUint32 peerCurves = 0; | 
| -    PRUint32 mutualCurves = 0; | 
| -    PRUint16 svrCertCurveName; | 
| - | 
| -    if (!data->data || data->len < 4) { | 
| -        (void)ssl3_DecodeError(ss); | 
| -        return SECFailure; | 
| -    } | 
| - | 
| -    /* get the length of elliptic_curve_list */ | 
| -    list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); | 
| -    if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) { | 
| -        (void)ssl3_DecodeError(ss); | 
| -        return SECFailure; | 
| -    } | 
| -    /* build bit vector of peer's supported curve names */ | 
| -    while (data->len) { | 
| -        PRInt32 curve_name = | 
| -            ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); | 
| -        if (curve_name < 0) { | 
| -            return SECFailure; /* fatal alert already sent */ | 
| -        } | 
| -        if (curve_name > ec_noName && curve_name < ec_pastLastName) { | 
| -            peerCurves |= (1U << curve_name); | 
| -        } | 
| -    } | 
| -    /* What curves do we support in common? */ | 
| -    mutualCurves = ss->ssl3.hs.negotiatedECCurves &= peerCurves; | 
| -    if (!mutualCurves) { | 
| -        /* no mutually supported EC Curves, disable ECC */ | 
| -        ssl3_DisableECCSuites(ss, ecSuites); | 
| -        return SECSuccess; | 
| -    } | 
| - | 
| -    /* if our ECC cert doesn't use one of these supported curves, | 
| -     * disable ECC cipher suites that require an ECC cert. | 
| -     */ | 
| -    svrCertCurveName = ssl3_GetSvrCertCurveName(ss); | 
| -    if (svrCertCurveName != ec_noName && | 
| -        (mutualCurves & (1U << svrCertCurveName)) != 0) { | 
| -        return SECSuccess; | 
| -    } | 
| -    /* Our EC cert doesn't contain a mutually supported curve. | 
| -     * Disable all ECC cipher suites that require an EC cert | 
| -     */ | 
| -    ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites); | 
| -    ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites); | 
| -    return SECSuccess; | 
| -} | 
| - | 
| -#endif /* NSS_DISABLE_ECC */ | 
|  |