Home | History | Annotate | Download | only in ssl
      1 /*
      2  * SSL3 Protocol
      3  *
      4  * This Source Code Form is subject to the terms of the Mozilla Public
      5  * License, v. 2.0. If a copy of the MPL was not distributed with this
      6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      7 
      8 /* ECC code moved here from ssl3con.c */
      9 
     10 #include "nss.h"
     11 #include "cert.h"
     12 #include "ssl.h"
     13 #include "cryptohi.h"	/* for DSAU_ stuff */
     14 #include "keyhi.h"
     15 #include "secder.h"
     16 #include "secitem.h"
     17 
     18 #include "sslimpl.h"
     19 #include "sslproto.h"
     20 #include "sslerr.h"
     21 #include "prtime.h"
     22 #include "prinrval.h"
     23 #include "prerror.h"
     24 #include "pratom.h"
     25 #include "prthread.h"
     26 #include "prinit.h"
     27 
     28 #include "pk11func.h"
     29 #include "secmod.h"
     30 
     31 #include <stdio.h>
     32 
     33 /* This is a bodge to allow this code to be compiled against older NSS headers
     34  * that don't contain the TLS 1.2 changes. */
     35 #ifndef CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256
     36 #define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24)
     37 #endif
     38 
     39 #ifdef NSS_ENABLE_ECC
     40 
     41 /*
     42  * In NSS 3.13.2 the definition of the EC_POINT_FORM_UNCOMPRESSED macro
     43  * was moved from the internal header ec.h to the public header blapit.h.
     44  * Define the macro here when compiling against older system NSS headers.
     45  */
     46 #ifndef EC_POINT_FORM_UNCOMPRESSED
     47 #define EC_POINT_FORM_UNCOMPRESSED 0x04
     48 #endif
     49 
     50 #ifndef PK11_SETATTRS
     51 #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
     52 		(x)->pValue=(v); (x)->ulValueLen = (l);
     53 #endif
     54 
     55 #define SSL_GET_SERVER_PUBLIC_KEY(sock, type) \
     56     (ss->serverCerts[type].serverKeyPair ? \
     57     ss->serverCerts[type].serverKeyPair->pubKey : NULL)
     58 
     59 #define SSL_IS_CURVE_NEGOTIATED(curvemsk, curveName) \
     60     ((curveName > ec_noName) && \
     61      (curveName < ec_pastLastName) && \
     62      ((1UL << curveName) & curvemsk) != 0)
     63 
     64 
     65 
     66 static SECStatus ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve);
     67 
     68 #define supportedCurve(x) (((x) > ec_noName) && ((x) < ec_pastLastName))
     69 
     70 /* Table containing OID tags for elliptic curves named in the
     71  * ECC-TLS IETF draft.
     72  */
     73 static const SECOidTag ecName2OIDTag[] = {
     74 	0,
     75 	SEC_OID_SECG_EC_SECT163K1,  /*  1 */
     76 	SEC_OID_SECG_EC_SECT163R1,  /*  2 */
     77 	SEC_OID_SECG_EC_SECT163R2,  /*  3 */
     78 	SEC_OID_SECG_EC_SECT193R1,  /*  4 */
     79 	SEC_OID_SECG_EC_SECT193R2,  /*  5 */
     80 	SEC_OID_SECG_EC_SECT233K1,  /*  6 */
     81 	SEC_OID_SECG_EC_SECT233R1,  /*  7 */
     82 	SEC_OID_SECG_EC_SECT239K1,  /*  8 */
     83 	SEC_OID_SECG_EC_SECT283K1,  /*  9 */
     84 	SEC_OID_SECG_EC_SECT283R1,  /* 10 */
     85 	SEC_OID_SECG_EC_SECT409K1,  /* 11 */
     86 	SEC_OID_SECG_EC_SECT409R1,  /* 12 */
     87 	SEC_OID_SECG_EC_SECT571K1,  /* 13 */
     88 	SEC_OID_SECG_EC_SECT571R1,  /* 14 */
     89 	SEC_OID_SECG_EC_SECP160K1,  /* 15 */
     90 	SEC_OID_SECG_EC_SECP160R1,  /* 16 */
     91 	SEC_OID_SECG_EC_SECP160R2,  /* 17 */
     92 	SEC_OID_SECG_EC_SECP192K1,  /* 18 */
     93 	SEC_OID_SECG_EC_SECP192R1,  /* 19 */
     94 	SEC_OID_SECG_EC_SECP224K1,  /* 20 */
     95 	SEC_OID_SECG_EC_SECP224R1,  /* 21 */
     96 	SEC_OID_SECG_EC_SECP256K1,  /* 22 */
     97 	SEC_OID_SECG_EC_SECP256R1,  /* 23 */
     98 	SEC_OID_SECG_EC_SECP384R1,  /* 24 */
     99 	SEC_OID_SECG_EC_SECP521R1,  /* 25 */
    100 };
    101 
    102 static const PRUint16 curve2bits[] = {
    103 	  0, /*  ec_noName     = 0,   */
    104 	163, /*  ec_sect163k1  = 1,   */
    105 	163, /*  ec_sect163r1  = 2,   */
    106 	163, /*  ec_sect163r2  = 3,   */
    107 	193, /*  ec_sect193r1  = 4,   */
    108 	193, /*  ec_sect193r2  = 5,   */
    109 	233, /*  ec_sect233k1  = 6,   */
    110 	233, /*  ec_sect233r1  = 7,   */
    111 	239, /*  ec_sect239k1  = 8,   */
    112 	283, /*  ec_sect283k1  = 9,   */
    113 	283, /*  ec_sect283r1  = 10,  */
    114 	409, /*  ec_sect409k1  = 11,  */
    115 	409, /*  ec_sect409r1  = 12,  */
    116 	571, /*  ec_sect571k1  = 13,  */
    117 	571, /*  ec_sect571r1  = 14,  */
    118 	160, /*  ec_secp160k1  = 15,  */
    119 	160, /*  ec_secp160r1  = 16,  */
    120 	160, /*  ec_secp160r2  = 17,  */
    121 	192, /*  ec_secp192k1  = 18,  */
    122 	192, /*  ec_secp192r1  = 19,  */
    123 	224, /*  ec_secp224k1  = 20,  */
    124 	224, /*  ec_secp224r1  = 21,  */
    125 	256, /*  ec_secp256k1  = 22,  */
    126 	256, /*  ec_secp256r1  = 23,  */
    127 	384, /*  ec_secp384r1  = 24,  */
    128 	521, /*  ec_secp521r1  = 25,  */
    129       65535  /*  ec_pastLastName      */
    130 };
    131 
    132 typedef struct Bits2CurveStr {
    133     PRUint16    bits;
    134     ECName      curve;
    135 } Bits2Curve;
    136 
    137 static const Bits2Curve bits2curve [] = {
    138    {	192,     ec_secp192r1    /*  = 19,  fast */  },
    139    {	160,     ec_secp160r2    /*  = 17,  fast */  },
    140    {	160,     ec_secp160k1    /*  = 15,  */       },
    141    {	160,     ec_secp160r1    /*  = 16,  */       },
    142    {	163,     ec_sect163k1    /*  = 1,   */       },
    143    {	163,     ec_sect163r1    /*  = 2,   */       },
    144    {	163,     ec_sect163r2    /*  = 3,   */       },
    145    {	192,     ec_secp192k1    /*  = 18,  */       },
    146    {	193,     ec_sect193r1    /*  = 4,   */       },
    147    {	193,     ec_sect193r2    /*  = 5,   */       },
    148    {	224,     ec_secp224r1    /*  = 21,  fast */  },
    149    {	224,     ec_secp224k1    /*  = 20,  */       },
    150    {	233,     ec_sect233k1    /*  = 6,   */       },
    151    {	233,     ec_sect233r1    /*  = 7,   */       },
    152    {	239,     ec_sect239k1    /*  = 8,   */       },
    153    {	256,     ec_secp256r1    /*  = 23,  fast */  },
    154    {	256,     ec_secp256k1    /*  = 22,  */       },
    155    {	283,     ec_sect283k1    /*  = 9,   */       },
    156    {	283,     ec_sect283r1    /*  = 10,  */       },
    157    {	384,     ec_secp384r1    /*  = 24,  fast */  },
    158    {	409,     ec_sect409k1    /*  = 11,  */       },
    159    {	409,     ec_sect409r1    /*  = 12,  */       },
    160    {	521,     ec_secp521r1    /*  = 25,  fast */  },
    161    {	571,     ec_sect571k1    /*  = 13,  */       },
    162    {	571,     ec_sect571r1    /*  = 14,  */       },
    163    {  65535,     ec_noName    }
    164 };
    165 
    166 typedef struct ECDHEKeyPairStr {
    167     ssl3KeyPair *  pair;
    168     int            error;  /* error code of the call-once function */
    169     PRCallOnceType once;
    170 } ECDHEKeyPair;
    171 
    172 /* arrays of ECDHE KeyPairs */
    173 static ECDHEKeyPair gECDHEKeyPairs[ec_pastLastName];
    174 
    175 SECStatus
    176 ssl3_ECName2Params(PLArenaPool * arena, ECName curve, SECKEYECParams * params)
    177 {
    178     SECOidData *oidData = NULL;
    179 
    180     if ((curve <= ec_noName) || (curve >= ec_pastLastName) ||
    181 	((oidData = SECOID_FindOIDByTag(ecName2OIDTag[curve])) == NULL)) {
    182         PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
    183 	return SECFailure;
    184     }
    185 
    186     SECITEM_AllocItem(arena, params, (2 + oidData->oid.len));
    187     /*
    188      * params->data needs to contain the ASN encoding of an object ID (OID)
    189      * representing the named curve. The actual OID is in
    190      * oidData->oid.data so we simply prepend 0x06 and OID length
    191      */
    192     params->data[0] = SEC_ASN1_OBJECT_ID;
    193     params->data[1] = oidData->oid.len;
    194     memcpy(params->data + 2, oidData->oid.data, oidData->oid.len);
    195 
    196     return SECSuccess;
    197 }
    198 
    199 static ECName
    200 params2ecName(SECKEYECParams * params)
    201 {
    202     SECItem oid = { siBuffer, NULL, 0};
    203     SECOidData *oidData = NULL;
    204     ECName i;
    205 
    206     /*
    207      * params->data needs to contain the ASN encoding of an object ID (OID)
    208      * representing a named curve. Here, we strip away everything
    209      * before the actual OID and use the OID to look up a named curve.
    210      */
    211     if (params->data[0] != SEC_ASN1_OBJECT_ID) return ec_noName;
    212     oid.len = params->len - 2;
    213     oid.data = params->data + 2;
    214     if ((oidData = SECOID_FindOID(&oid)) == NULL) return ec_noName;
    215     for (i = ec_noName + 1; i < ec_pastLastName; i++) {
    216 	if (ecName2OIDTag[i] == oidData->offset)
    217 	    return i;
    218     }
    219 
    220     return ec_noName;
    221 }
    222 
    223 /* Caller must set hiLevel error code. */
    224 static SECStatus
    225 ssl3_ComputeECDHKeyHash(SECOidTag hashAlg,
    226 			SECItem ec_params, SECItem server_ecpoint,
    227 			SSL3Random *client_rand, SSL3Random *server_rand,
    228 			SSL3Hashes *hashes, PRBool bypassPKCS11)
    229 {
    230     PRUint8     * hashBuf;
    231     PRUint8     * pBuf;
    232     SECStatus     rv 		= SECSuccess;
    233     unsigned int  bufLen;
    234     /*
    235      * XXX For now, we only support named curves (the appropriate
    236      * checks are made before this method is called) so ec_params
    237      * takes up only two bytes. ECPoint needs to fit in 256 bytes
    238      * (because the spec says the length must fit in one byte)
    239      */
    240     PRUint8       buf[2*SSL3_RANDOM_LENGTH + 2 + 1 + 256];
    241 
    242     bufLen = 2*SSL3_RANDOM_LENGTH + ec_params.len + 1 + server_ecpoint.len;
    243     if (bufLen <= sizeof buf) {
    244     	hashBuf = buf;
    245     } else {
    246     	hashBuf = PORT_Alloc(bufLen);
    247 	if (!hashBuf) {
    248 	    return SECFailure;
    249 	}
    250     }
    251 
    252     memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
    253     	pBuf = hashBuf + SSL3_RANDOM_LENGTH;
    254     memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
    255     	pBuf += SSL3_RANDOM_LENGTH;
    256     memcpy(pBuf, ec_params.data, ec_params.len);
    257     	pBuf += ec_params.len;
    258     pBuf[0] = (PRUint8)(server_ecpoint.len);
    259     pBuf += 1;
    260     memcpy(pBuf, server_ecpoint.data, server_ecpoint.len);
    261     	pBuf += server_ecpoint.len;
    262     PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
    263 
    264     rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes,
    265 				   bypassPKCS11);
    266 
    267     PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen));
    268     PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result",
    269 	      hashes->u.s.md5, MD5_LENGTH));
    270     PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result",
    271 	      hashes->u.s.sha, SHA1_LENGTH));
    272 
    273     if (hashBuf != buf)
    274     	PORT_Free(hashBuf);
    275     return rv;
    276 }
    277 
    278 
    279 /* Called from ssl3_SendClientKeyExchange(). */
    280 SECStatus
    281 ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
    282 {
    283     PK11SymKey *	pms 		= NULL;
    284     SECStatus           rv    		= SECFailure;
    285     PRBool              isTLS, isTLS12;
    286     CK_MECHANISM_TYPE	target;
    287     SECKEYPublicKey	*pubKey = NULL;		/* Ephemeral ECDH key */
    288     SECKEYPrivateKey	*privKey = NULL;	/* Ephemeral ECDH key */
    289 
    290     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
    291     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
    292 
    293     isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
    294     isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
    295 
    296     /* Generate ephemeral EC keypair */
    297     if (svrPubKey->keyType != ecKey) {
    298 	PORT_SetError(SEC_ERROR_BAD_KEY);
    299 	goto loser;
    300     }
    301     /* XXX SHOULD CALL ssl3_CreateECDHEphemeralKeys here, instead! */
    302     privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams,
    303 	                                &pubKey, ss->pkcs11PinArg);
    304     if (!privKey || !pubKey) {
    305 	    ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
    306 	    rv = SECFailure;
    307 	    goto loser;
    308     }
    309     PRINT_BUF(50, (ss, "ECDH public value:",
    310 					pubKey->u.ec.publicValue.data,
    311 					pubKey->u.ec.publicValue.len));
    312 
    313     if (isTLS12) {
    314 	target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256;
    315     } else if (isTLS) {
    316 	target = CKM_TLS_MASTER_KEY_DERIVE_DH;
    317     } else {
    318 	target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
    319     }
    320 
    321     /*  Determine the PMS */
    322     pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL,
    323 			    CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
    324 			    CKD_NULL, NULL, NULL);
    325 
    326     if (pms == NULL) {
    327 	SSL3AlertDescription desc  = illegal_parameter;
    328 	(void)SSL3_SendAlert(ss, alert_fatal, desc);
    329 	ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
    330 	goto loser;
    331     }
    332 
    333     SECKEY_DestroyPrivateKey(privKey);
    334     privKey = NULL;
    335 
    336     rv = ssl3_InitPendingCipherSpec(ss,  pms);
    337     PK11_FreeSymKey(pms); pms = NULL;
    338 
    339     if (rv != SECSuccess) {
    340 	ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
    341 	goto loser;
    342     }
    343 
    344     rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
    345 					pubKey->u.ec.publicValue.len + 1);
    346     if (rv != SECSuccess) {
    347         goto loser;	/* err set by ssl3_AppendHandshake* */
    348     }
    349 
    350     rv = ssl3_AppendHandshakeVariable(ss,
    351 					pubKey->u.ec.publicValue.data,
    352 					pubKey->u.ec.publicValue.len, 1);
    353     SECKEY_DestroyPublicKey(pubKey);
    354     pubKey = NULL;
    355 
    356     if (rv != SECSuccess) {
    357         goto loser;	/* err set by ssl3_AppendHandshake* */
    358     }
    359 
    360     rv = SECSuccess;
    361 
    362 loser:
    363     if(pms) PK11_FreeSymKey(pms);
    364     if(privKey) SECKEY_DestroyPrivateKey(privKey);
    365     if(pubKey) SECKEY_DestroyPublicKey(pubKey);
    366     return rv;
    367 }
    368 
    369 
    370 /*
    371 ** Called from ssl3_HandleClientKeyExchange()
    372 */
    373 SECStatus
    374 ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
    375 				     PRUint32 length,
    376                                      SECKEYPublicKey *srvrPubKey,
    377                                      SECKEYPrivateKey *srvrPrivKey)
    378 {
    379     PK11SymKey *      pms;
    380     SECStatus         rv;
    381     SECKEYPublicKey   clntPubKey;
    382     CK_MECHANISM_TYPE	target;
    383     PRBool isTLS, isTLS12;
    384 
    385     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    386     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
    387 
    388     clntPubKey.keyType = ecKey;
    389     clntPubKey.u.ec.DEREncodedParams.len =
    390 	srvrPubKey->u.ec.DEREncodedParams.len;
    391     clntPubKey.u.ec.DEREncodedParams.data =
    392 	srvrPubKey->u.ec.DEREncodedParams.data;
    393 
    394     rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue,
    395 	                               1, &b, &length);
    396     if (rv != SECSuccess) {
    397 	SEND_ALERT
    398 	return SECFailure;	/* XXX Who sets the error code?? */
    399     }
    400 
    401     isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
    402     isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
    403 
    404     if (isTLS12) {
    405 	target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256;
    406     } else if (isTLS) {
    407 	target = CKM_TLS_MASTER_KEY_DERIVE_DH;
    408     } else {
    409 	target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
    410     }
    411 
    412     /*  Determine the PMS */
    413     pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL,
    414 			    CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
    415 			    CKD_NULL, NULL, NULL);
    416 
    417     if (pms == NULL) {
    418 	/* last gasp.  */
    419 	ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
    420 	return SECFailure;
    421     }
    422 
    423     rv = ssl3_InitPendingCipherSpec(ss,  pms);
    424     PK11_FreeSymKey(pms);
    425     if (rv != SECSuccess) {
    426 	SEND_ALERT
    427 	return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
    428     }
    429     return SECSuccess;
    430 }
    431 
    432 ECName
    433 ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits)
    434 {
    435     int    i;
    436 
    437     for ( i = 0; bits2curve[i].curve != ec_noName; i++) {
    438 	if (bits2curve[i].bits < requiredECCbits)
    439 	    continue;
    440     	if (SSL_IS_CURVE_NEGOTIATED(curvemsk, bits2curve[i].curve)) {
    441 	    return bits2curve[i].curve;
    442 	}
    443     }
    444     PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
    445     return ec_noName;
    446 }
    447 
    448 /* find the "weakest link".  Get strength of signature key and of sym key.
    449  * choose curve for the weakest of those two.
    450  */
    451 ECName
    452 ssl3_GetCurveNameForServerSocket(sslSocket *ss)
    453 {
    454     SECKEYPublicKey * svrPublicKey = NULL;
    455     ECName ec_curve = ec_noName;
    456     int    signatureKeyStrength = 521;
    457     int    requiredECCbits = ss->sec.secretKeyBits * 2;
    458 
    459     if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa) {
    460 	svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_ecdh);
    461 	if (svrPublicKey)
    462 	    ec_curve = params2ecName(&svrPublicKey->u.ec.DEREncodedParams);
    463 	if (!SSL_IS_CURVE_NEGOTIATED(ss->ssl3.hs.negotiatedECCurves, ec_curve)) {
    464 	    PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
    465 	    return ec_noName;
    466 	}
    467 	signatureKeyStrength = curve2bits[ ec_curve ];
    468     } else {
    469         /* RSA is our signing cert */
    470         int serverKeyStrengthInBits;
    471 
    472         svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_rsa);
    473         if (!svrPublicKey) {
    474             PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
    475             return ec_noName;
    476         }
    477 
    478         /* currently strength in bytes */
    479         serverKeyStrengthInBits = svrPublicKey->u.rsa.modulus.len;
    480         if (svrPublicKey->u.rsa.modulus.data[0] == 0) {
    481             serverKeyStrengthInBits--;
    482         }
    483         /* convert to strength in bits */
    484         serverKeyStrengthInBits *= BPB;
    485 
    486         signatureKeyStrength =
    487 	    SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits);
    488     }
    489     if ( requiredECCbits > signatureKeyStrength )
    490          requiredECCbits = signatureKeyStrength;
    491 
    492     return ssl3_GetCurveWithECKeyStrength(ss->ssl3.hs.negotiatedECCurves,
    493 					  requiredECCbits);
    494 }
    495 
    496 /* function to clear out the lists */
    497 static SECStatus
    498 ssl3_ShutdownECDHECurves(void *appData, void *nssData)
    499 {
    500     int i;
    501     ECDHEKeyPair *keyPair = &gECDHEKeyPairs[0];
    502 
    503     for (i=0; i < ec_pastLastName; i++, keyPair++) {
    504 	if (keyPair->pair) {
    505 	    ssl3_FreeKeyPair(keyPair->pair);
    506 	}
    507     }
    508     memset(gECDHEKeyPairs, 0, sizeof gECDHEKeyPairs);
    509     return SECSuccess;
    510 }
    511 
    512 static PRStatus
    513 ssl3_ECRegister(void)
    514 {
    515     SECStatus rv;
    516     rv = NSS_RegisterShutdown(ssl3_ShutdownECDHECurves, gECDHEKeyPairs);
    517     if (rv != SECSuccess) {
    518 	gECDHEKeyPairs[ec_noName].error = PORT_GetError();
    519     }
    520     return (PRStatus)rv;
    521 }
    522 
    523 /* CallOnce function, called once for each named curve. */
    524 static PRStatus
    525 ssl3_CreateECDHEphemeralKeyPair(void * arg)
    526 {
    527     SECKEYPrivateKey *    privKey  = NULL;
    528     SECKEYPublicKey *     pubKey   = NULL;
    529     ssl3KeyPair *	  keyPair  = NULL;
    530     ECName                ec_curve = (ECName)arg;
    531     SECKEYECParams        ecParams = { siBuffer, NULL, 0 };
    532 
    533     PORT_Assert(gECDHEKeyPairs[ec_curve].pair == NULL);
    534 
    535     /* ok, no one has generated a global key for this curve yet, do so */
    536     if (ssl3_ECName2Params(NULL, ec_curve, &ecParams) != SECSuccess) {
    537 	gECDHEKeyPairs[ec_curve].error = PORT_GetError();
    538 	return PR_FAILURE;
    539     }
    540 
    541     privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL);
    542     SECITEM_FreeItem(&ecParams, PR_FALSE);
    543 
    544     if (!privKey || !pubKey || !(keyPair = ssl3_NewKeyPair(privKey, pubKey))) {
    545 	if (privKey) {
    546 	    SECKEY_DestroyPrivateKey(privKey);
    547 	}
    548 	if (pubKey) {
    549 	    SECKEY_DestroyPublicKey(pubKey);
    550 	}
    551 	ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
    552 	gECDHEKeyPairs[ec_curve].error = PORT_GetError();
    553 	return PR_FAILURE;
    554     }
    555 
    556     gECDHEKeyPairs[ec_curve].pair = keyPair;
    557     return PR_SUCCESS;
    558 }
    559 
    560 /*
    561  * Creates the ephemeral public and private ECDH keys used by
    562  * server in ECDHE_RSA and ECDHE_ECDSA handshakes.
    563  * For now, the elliptic curve is chosen to be the same
    564  * strength as the signing certificate (ECC or RSA).
    565  * We need an API to specify the curve. This won't be a real
    566  * issue until we further develop server-side support for ECC
    567  * cipher suites.
    568  */
    569 static SECStatus
    570 ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve)
    571 {
    572     ssl3KeyPair *	  keyPair        = NULL;
    573 
    574     /* if there's no global key for this curve, make one. */
    575     if (gECDHEKeyPairs[ec_curve].pair == NULL) {
    576 	PRStatus status;
    577 
    578 	status = PR_CallOnce(&gECDHEKeyPairs[ec_noName].once, ssl3_ECRegister);
    579         if (status != PR_SUCCESS) {
    580 	    PORT_SetError(gECDHEKeyPairs[ec_noName].error);
    581 	    return SECFailure;
    582     	}
    583 	status = PR_CallOnceWithArg(&gECDHEKeyPairs[ec_curve].once,
    584 	                            ssl3_CreateECDHEphemeralKeyPair,
    585 				    (void *)ec_curve);
    586         if (status != PR_SUCCESS) {
    587 	    PORT_SetError(gECDHEKeyPairs[ec_curve].error);
    588 	    return SECFailure;
    589     	}
    590     }
    591 
    592     keyPair = gECDHEKeyPairs[ec_curve].pair;
    593     PORT_Assert(keyPair != NULL);
    594     if (!keyPair)
    595     	return SECFailure;
    596     ss->ephemeralECDHKeyPair = ssl3_GetKeyPairRef(keyPair);
    597 
    598     return SECSuccess;
    599 }
    600 
    601 SECStatus
    602 ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
    603 {
    604     PLArenaPool *    arena     = NULL;
    605     SECKEYPublicKey *peerKey   = NULL;
    606     PRBool           isTLS, isTLS12;
    607     SECStatus        rv;
    608     int              errCode   = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
    609     SSL3AlertDescription desc  = illegal_parameter;
    610     SSL3Hashes       hashes;
    611     SECItem          signature = {siBuffer, NULL, 0};
    612 
    613     SECItem          ec_params = {siBuffer, NULL, 0};
    614     SECItem          ec_point  = {siBuffer, NULL, 0};
    615     unsigned char    paramBuf[3]; /* only for curve_type == named_curve */
    616     SSL3SignatureAndHashAlgorithm sigAndHash;
    617 
    618     sigAndHash.hashAlg = SEC_OID_UNKNOWN;
    619 
    620     isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
    621     isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
    622 
    623     /* XXX This works only for named curves, revisit this when
    624      * we support generic curves.
    625      */
    626     ec_params.len  = sizeof paramBuf;
    627     ec_params.data = paramBuf;
    628     rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length);
    629     if (rv != SECSuccess) {
    630 	goto loser;		/* malformed. */
    631     }
    632 
    633     /* Fail if the curve is not a named curve */
    634     if ((ec_params.data[0] != ec_type_named) ||
    635 	(ec_params.data[1] != 0) ||
    636 	!supportedCurve(ec_params.data[2])) {
    637 	    errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
    638 	    desc = handshake_failure;
    639 	    goto alert_loser;
    640     }
    641 
    642     rv = ssl3_ConsumeHandshakeVariable(ss, &ec_point, 1, &b, &length);
    643     if (rv != SECSuccess) {
    644 	goto loser;		/* malformed. */
    645     }
    646     /* Fail if the ec point uses compressed representation */
    647     if (ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
    648 	    errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM;
    649 	    desc = handshake_failure;
    650 	    goto alert_loser;
    651     }
    652 
    653     if (isTLS12) {
    654 	rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length,
    655 						   &sigAndHash);
    656 	if (rv != SECSuccess) {
    657 	    goto loser;		/* malformed or unsupported. */
    658 	}
    659 	rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(
    660 		&sigAndHash, ss->sec.peerCert);
    661 	if (rv != SECSuccess) {
    662 	    goto loser;
    663 	}
    664     }
    665 
    666     rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
    667     if (rv != SECSuccess) {
    668 	goto loser;		/* malformed. */
    669     }
    670 
    671     if (length != 0) {
    672 	if (isTLS)
    673 	    desc = decode_error;
    674 	goto alert_loser;		/* malformed. */
    675     }
    676 
    677     PRINT_BUF(60, (NULL, "Server EC params", ec_params.data,
    678 	ec_params.len));
    679     PRINT_BUF(60, (NULL, "Server EC point", ec_point.data, ec_point.len));
    680 
    681     /* failures after this point are not malformed handshakes. */
    682     /* TLS: send decrypt_error if signature failed. */
    683     desc = isTLS ? decrypt_error : handshake_failure;
    684 
    685     /*
    686      *  check to make sure the hash is signed by right guy
    687      */
    688     rv = ssl3_ComputeECDHKeyHash(sigAndHash.hashAlg, ec_params, ec_point,
    689 				 &ss->ssl3.hs.client_random,
    690 				 &ss->ssl3.hs.server_random,
    691 				 &hashes, ss->opt.bypassPKCS11);
    692 
    693     if (rv != SECSuccess) {
    694 	errCode =
    695 	    ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
    696 	goto alert_loser;
    697     }
    698     rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
    699 				isTLS, ss->pkcs11PinArg);
    700     if (rv != SECSuccess)  {
    701 	errCode =
    702 	    ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
    703 	goto alert_loser;
    704     }
    705 
    706     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    707     if (arena == NULL) {
    708 	goto no_memory;
    709     }
    710 
    711     ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
    712     if (peerKey == NULL) {
    713 	goto no_memory;
    714     }
    715 
    716     peerKey->arena                 = arena;
    717     peerKey->keyType               = ecKey;
    718 
    719     /* set up EC parameters in peerKey */
    720     if (ssl3_ECName2Params(arena, ec_params.data[2],
    721 	    &peerKey->u.ec.DEREncodedParams) != SECSuccess) {
    722 	/* we should never get here since we already
    723 	 * checked that we are dealing with a supported curve
    724 	 */
    725 	errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
    726 	goto alert_loser;
    727     }
    728 
    729     /* copy publicValue in peerKey */
    730     if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue,  &ec_point))
    731     {
    732 	PORT_FreeArena(arena, PR_FALSE);
    733 	goto no_memory;
    734     }
    735     peerKey->pkcs11Slot         = NULL;
    736     peerKey->pkcs11ID           = CK_INVALID_HANDLE;
    737 
    738     ss->sec.peerKey = peerKey;
    739     ss->ssl3.hs.ws = wait_cert_request;
    740 
    741     return SECSuccess;
    742 
    743 alert_loser:
    744     (void)SSL3_SendAlert(ss, alert_fatal, desc);
    745 loser:
    746     PORT_SetError( errCode );
    747     return SECFailure;
    748 
    749 no_memory:	/* no-memory error has already been set. */
    750     ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
    751     return SECFailure;
    752 }
    753 
    754 SECStatus
    755 ssl3_SendECDHServerKeyExchange(
    756     sslSocket *ss,
    757     const SSL3SignatureAndHashAlgorithm *sigAndHash)
    758 {
    759     const ssl3KEADef * kea_def     = ss->ssl3.hs.kea_def;
    760     SECStatus          rv          = SECFailure;
    761     int                length;
    762     PRBool             isTLS, isTLS12;
    763     SECItem            signed_hash = {siBuffer, NULL, 0};
    764     SSL3Hashes         hashes;
    765 
    766     SECKEYPublicKey *  ecdhePub;
    767     SECItem            ec_params = {siBuffer, NULL, 0};
    768     unsigned char      paramBuf[3];
    769     ECName             curve;
    770     SSL3KEAType        certIndex;
    771 
    772     /* Generate ephemeral ECDH key pair and send the public key */
    773     curve = ssl3_GetCurveNameForServerSocket(ss);
    774     if (curve == ec_noName) {
    775     	goto loser;
    776     }
    777     rv = ssl3_CreateECDHEphemeralKeys(ss, curve);
    778     if (rv != SECSuccess) {
    779 	goto loser; 	/* err set by AppendHandshake. */
    780     }
    781     ecdhePub = ss->ephemeralECDHKeyPair->pubKey;
    782     PORT_Assert(ecdhePub != NULL);
    783     if (!ecdhePub) {
    784 	PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
    785 	return SECFailure;
    786     }
    787 
    788     ec_params.len  = sizeof paramBuf;
    789     ec_params.data = paramBuf;
    790     curve = params2ecName(&ecdhePub->u.ec.DEREncodedParams);
    791     if (curve != ec_noName) {
    792 	ec_params.data[0] = ec_type_named;
    793 	ec_params.data[1] = 0x00;
    794 	ec_params.data[2] = curve;
    795     } else {
    796 	PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
    797 	goto loser;
    798     }
    799 
    800     rv = ssl3_ComputeECDHKeyHash(sigAndHash->hashAlg,
    801 				 ec_params,
    802 				 ecdhePub->u.ec.publicValue,
    803 				 &ss->ssl3.hs.client_random,
    804 				 &ss->ssl3.hs.server_random,
    805 				 &hashes, ss->opt.bypassPKCS11);
    806     if (rv != SECSuccess) {
    807 	ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
    808 	goto loser;
    809     }
    810 
    811     isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
    812     isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
    813 
    814     /* XXX SSLKEAType isn't really a good choice for
    815      * indexing certificates but that's all we have
    816      * for now.
    817      */
    818     if (kea_def->kea == kea_ecdhe_rsa)
    819 	certIndex = kt_rsa;
    820     else /* kea_def->kea == kea_ecdhe_ecdsa */
    821 	certIndex = kt_ecdh;
    822 
    823     rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].SERVERKEY,
    824 			 &signed_hash, isTLS);
    825     if (rv != SECSuccess) {
    826 	goto loser;		/* ssl3_SignHashes has set err. */
    827     }
    828     if (signed_hash.data == NULL) {
    829 	/* how can this happen and rv == SECSuccess ?? */
    830 	PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
    831 	goto loser;
    832     }
    833 
    834     length = ec_params.len +
    835 	     1 + ecdhePub->u.ec.publicValue.len +
    836 	     (isTLS12 ? 2 : 0) + 2 + signed_hash.len;
    837 
    838     rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
    839     if (rv != SECSuccess) {
    840 	goto loser; 	/* err set by AppendHandshake. */
    841     }
    842 
    843     rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len);
    844     if (rv != SECSuccess) {
    845 	goto loser; 	/* err set by AppendHandshake. */
    846     }
    847 
    848     rv = ssl3_AppendHandshakeVariable(ss, ecdhePub->u.ec.publicValue.data,
    849 				      ecdhePub->u.ec.publicValue.len, 1);
    850     if (rv != SECSuccess) {
    851 	goto loser; 	/* err set by AppendHandshake. */
    852     }
    853 
    854     if (isTLS12) {
    855 	rv = ssl3_AppendSignatureAndHashAlgorithm(ss, sigAndHash);
    856 	if (rv != SECSuccess) {
    857 	    goto loser; 	/* err set by AppendHandshake. */
    858 	}
    859     }
    860 
    861     rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
    862 				      signed_hash.len, 2);
    863     if (rv != SECSuccess) {
    864 	goto loser; 	/* err set by AppendHandshake. */
    865     }
    866 
    867     PORT_Free(signed_hash.data);
    868     return SECSuccess;
    869 
    870 loser:
    871     if (signed_hash.data != NULL)
    872     	PORT_Free(signed_hash.data);
    873     return SECFailure;
    874 }
    875 
    876 /* Lists of ECC cipher suites for searching and disabling. */
    877 
    878 static const ssl3CipherSuite ecdh_suites[] = {
    879     TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
    880     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
    881     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
    882     TLS_ECDH_ECDSA_WITH_NULL_SHA,
    883     TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
    884     TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
    885     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
    886     TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
    887     TLS_ECDH_RSA_WITH_NULL_SHA,
    888     TLS_ECDH_RSA_WITH_RC4_128_SHA,
    889     0 /* end of list marker */
    890 };
    891 
    892 static const ssl3CipherSuite ecdh_ecdsa_suites[] = {
    893     TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
    894     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
    895     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
    896     TLS_ECDH_ECDSA_WITH_NULL_SHA,
    897     TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
    898     0 /* end of list marker */
    899 };
    900 
    901 static const ssl3CipherSuite ecdh_rsa_suites[] = {
    902     TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
    903     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
    904     TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
    905     TLS_ECDH_RSA_WITH_NULL_SHA,
    906     TLS_ECDH_RSA_WITH_RC4_128_SHA,
    907     0 /* end of list marker */
    908 };
    909 
    910 static const ssl3CipherSuite ecdhe_ecdsa_suites[] = {
    911     TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
    912     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
    913     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
    914     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
    915     TLS_ECDHE_ECDSA_WITH_NULL_SHA,
    916     TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
    917     0 /* end of list marker */
    918 };
    919 
    920 static const ssl3CipherSuite ecdhe_rsa_suites[] = {
    921     TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
    922     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
    923     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
    924     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
    925     TLS_ECDHE_RSA_WITH_NULL_SHA,
    926     TLS_ECDHE_RSA_WITH_RC4_128_SHA,
    927     0 /* end of list marker */
    928 };
    929 
    930 /* List of all ECC cipher suites */
    931 static const ssl3CipherSuite ecSuites[] = {
    932     TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
    933     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
    934     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
    935     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
    936     TLS_ECDHE_ECDSA_WITH_NULL_SHA,
    937     TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
    938     TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
    939     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
    940     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
    941     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
    942     TLS_ECDHE_RSA_WITH_NULL_SHA,
    943     TLS_ECDHE_RSA_WITH_RC4_128_SHA,
    944     TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
    945     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
    946     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
    947     TLS_ECDH_ECDSA_WITH_NULL_SHA,
    948     TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
    949     TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
    950     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
    951     TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
    952     TLS_ECDH_RSA_WITH_NULL_SHA,
    953     TLS_ECDH_RSA_WITH_RC4_128_SHA,
    954     0 /* end of list marker */
    955 };
    956 
    957 /* On this socket, Disable the ECC cipher suites in the argument's list */
    958 SECStatus
    959 ssl3_DisableECCSuites(sslSocket * ss, const ssl3CipherSuite * suite)
    960 {
    961     if (!suite)
    962     	suite = ecSuites;
    963     for (; *suite; ++suite) {
    964 	SECStatus rv      = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
    965 
    966 	PORT_Assert(rv == SECSuccess); /* else is coding error */
    967     }
    968     return SECSuccess;
    969 }
    970 
    971 /* Look at the server certs configured on this socket, and disable any
    972  * ECC cipher suites that are not supported by those certs.
    973  */
    974 void
    975 ssl3_FilterECCipherSuitesByServerCerts(sslSocket * ss)
    976 {
    977     CERTCertificate * svrCert;
    978 
    979     svrCert = ss->serverCerts[kt_rsa].serverCert;
    980     if (!svrCert) {
    981 	ssl3_DisableECCSuites(ss, ecdhe_rsa_suites);
    982     }
    983 
    984     svrCert = ss->serverCerts[kt_ecdh].serverCert;
    985     if (!svrCert) {
    986 	ssl3_DisableECCSuites(ss, ecdh_suites);
    987 	ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites);
    988     } else {
    989 	SECOidTag sigTag = SECOID_GetAlgorithmTag(&svrCert->signature);
    990 
    991 	switch (sigTag) {
    992 	case SEC_OID_PKCS1_RSA_ENCRYPTION:
    993 	case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
    994 	case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
    995 	case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
    996 	case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
    997 	case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
    998 	case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
    999 	case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
   1000 	case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
   1001 	    ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites);
   1002 	    break;
   1003 	case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
   1004 	case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
   1005 	case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
   1006 	case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
   1007 	case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
   1008 	case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
   1009 	case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
   1010 	    ssl3_DisableECCSuites(ss, ecdh_rsa_suites);
   1011 	    break;
   1012 	default:
   1013 	    ssl3_DisableECCSuites(ss, ecdh_suites);
   1014 	    break;
   1015 	}
   1016     }
   1017 }
   1018 
   1019 /* Ask: is ANY ECC cipher suite enabled on this socket? */
   1020 /* Order(N^2).  Yuk.  Also, this ignores export policy. */
   1021 PRBool
   1022 ssl3_IsECCEnabled(sslSocket * ss)
   1023 {
   1024     const ssl3CipherSuite * suite;
   1025     PK11SlotInfo *slot;
   1026 
   1027     /* make sure we can do ECC */
   1028     slot = PK11_GetBestSlot(CKM_ECDH1_DERIVE,  ss->pkcs11PinArg);
   1029     if (!slot) {
   1030 	return PR_FALSE;
   1031     }
   1032     PK11_FreeSlot(slot);
   1033 
   1034     /* make sure an ECC cipher is enabled */
   1035     for (suite = ecSuites; *suite; ++suite) {
   1036 	PRBool    enabled = PR_FALSE;
   1037 	SECStatus rv      = ssl3_CipherPrefGet(ss, *suite, &enabled);
   1038 
   1039 	PORT_Assert(rv == SECSuccess); /* else is coding error */
   1040 	if (rv == SECSuccess && enabled)
   1041 	    return PR_TRUE;
   1042     }
   1043     return PR_FALSE;
   1044 }
   1045 
   1046 #define BE(n) 0, n
   1047 
   1048 /* Prefabricated TLS client hello extension, Elliptic Curves List,
   1049  * offers only 3 curves, the Suite B curves, 23-25
   1050  */
   1051 static const PRUint8 suiteBECList[12] = {
   1052     BE(10),         /* Extension type */
   1053     BE( 8),         /* octets that follow ( 3 pairs + 1 length pair) */
   1054     BE( 6),         /* octets that follow ( 3 pairs) */
   1055     BE(23), BE(24), BE(25)
   1056 };
   1057 
   1058 /* Prefabricated TLS client hello extension, Elliptic Curves List,
   1059  * offers curves 1-25.
   1060  */
   1061 static const PRUint8 tlsECList[56] = {
   1062     BE(10),         /* Extension type */
   1063     BE(52),         /* octets that follow (25 pairs + 1 length pair) */
   1064     BE(50),         /* octets that follow (25 pairs) */
   1065             BE( 1), BE( 2), BE( 3), BE( 4), BE( 5), BE( 6), BE( 7),
   1066     BE( 8), BE( 9), BE(10), BE(11), BE(12), BE(13), BE(14), BE(15),
   1067     BE(16), BE(17), BE(18), BE(19), BE(20), BE(21), BE(22), BE(23),
   1068     BE(24), BE(25)
   1069 };
   1070 
   1071 static const PRUint8 ecPtFmt[6] = {
   1072     BE(11),         /* Extension type */
   1073     BE( 2),         /* octets that follow */
   1074              1,     /* octets that follow */
   1075                  0  /* uncompressed type only */
   1076 };
   1077 
   1078 /* This function already presumes we can do ECC, ssl3_IsECCEnabled must be
   1079  * called before this function. It looks to see if we have a token which
   1080  * is capable of doing smaller than SuiteB curves. If the token can, we
   1081  * presume the token can do the whole SSL suite of curves. If it can't we
   1082  * presume the token that allowed ECC to be enabled can only do suite B
   1083  * curves. */
   1084 static PRBool
   1085 ssl3_SuiteBOnly(sslSocket *ss)
   1086 {
   1087 #if 0
   1088     /* See if we can support small curves (like 163). If not, assume we can
   1089      * only support Suite-B curves (P-256, P-384, P-521). */
   1090     PK11SlotInfo *slot =
   1091 	PK11_GetBestSlotWithAttributes(CKM_ECDH1_DERIVE, 0, 163,
   1092 				       ss ? ss->pkcs11PinArg : NULL);
   1093 
   1094     if (!slot) {
   1095 	/* nope, presume we can only do suite B */
   1096 	return PR_TRUE;
   1097     }
   1098     /* we can, presume we can do all curves */
   1099     PK11_FreeSlot(slot);
   1100     return PR_FALSE;
   1101 #else
   1102     return PR_TRUE;
   1103 #endif
   1104 }
   1105 
   1106 /* Send our "canned" (precompiled) Supported Elliptic Curves extension,
   1107  * which says that we support all TLS-defined named curves.
   1108  */
   1109 PRInt32
   1110 ssl3_SendSupportedCurvesXtn(
   1111 			sslSocket * ss,
   1112 			PRBool      append,
   1113 			PRUint32    maxBytes)
   1114 {
   1115     PRInt32 ecListSize = 0;
   1116     const PRUint8 *ecList = NULL;
   1117 
   1118     if (!ss || !ssl3_IsECCEnabled(ss))
   1119     	return 0;
   1120 
   1121     if (ssl3_SuiteBOnly(ss)) {
   1122 	ecListSize = sizeof suiteBECList;
   1123 	ecList = suiteBECList;
   1124     } else {
   1125 	ecListSize = sizeof tlsECList;
   1126 	ecList = tlsECList;
   1127     }
   1128 
   1129     if (append && maxBytes >= ecListSize) {
   1130 	SECStatus rv = ssl3_AppendHandshake(ss, ecList, ecListSize);
   1131 	if (rv != SECSuccess)
   1132 	    return -1;
   1133 	if (!ss->sec.isServer) {
   1134 	    TLSExtensionData *xtnData = &ss->xtnData;
   1135 	    xtnData->advertised[xtnData->numAdvertised++] =
   1136 		ssl_elliptic_curves_xtn;
   1137 	}
   1138     }
   1139     return ecListSize;
   1140 }
   1141 
   1142 PRUint32
   1143 ssl3_GetSupportedECCurveMask(sslSocket *ss)
   1144 {
   1145     if (ssl3_SuiteBOnly(ss)) {
   1146 	return SSL3_SUITE_B_SUPPORTED_CURVES_MASK;
   1147     }
   1148     return SSL3_ALL_SUPPORTED_CURVES_MASK;
   1149 }
   1150 
   1151 /* Send our "canned" (precompiled) Supported Point Formats extension,
   1152  * which says that we only support uncompressed points.
   1153  */
   1154 PRInt32
   1155 ssl3_SendSupportedPointFormatsXtn(
   1156 			sslSocket * ss,
   1157 			PRBool      append,
   1158 			PRUint32    maxBytes)
   1159 {
   1160     if (!ss || !ssl3_IsECCEnabled(ss))
   1161     	return 0;
   1162     if (append && maxBytes >= (sizeof ecPtFmt)) {
   1163 	SECStatus rv = ssl3_AppendHandshake(ss, ecPtFmt, (sizeof ecPtFmt));
   1164 	if (rv != SECSuccess)
   1165 	    return -1;
   1166 	if (!ss->sec.isServer) {
   1167 	    TLSExtensionData *xtnData = &ss->xtnData;
   1168 	    xtnData->advertised[xtnData->numAdvertised++] =
   1169 		ssl_ec_point_formats_xtn;
   1170 	}
   1171     }
   1172     return (sizeof ecPtFmt);
   1173 }
   1174 
   1175 /* Just make sure that the remote client supports uncompressed points,
   1176  * Since that is all we support.  Disable ECC cipher suites if it doesn't.
   1177  */
   1178 SECStatus
   1179 ssl3_HandleSupportedPointFormatsXtn(sslSocket *ss, PRUint16 ex_type,
   1180                                     SECItem *data)
   1181 {
   1182     int i;
   1183 
   1184     if (data->len < 2 || data->len > 255 || !data->data ||
   1185         data->len != (unsigned int)data->data[0] + 1) {
   1186     	/* malformed */
   1187 	goto loser;
   1188     }
   1189     for (i = data->len; --i > 0; ) {
   1190     	if (data->data[i] == 0) {
   1191 	    /* indicate that we should send a reply */
   1192 	    SECStatus rv;
   1193 	    rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
   1194 			      &ssl3_SendSupportedPointFormatsXtn);
   1195 	    return rv;
   1196 	}
   1197     }
   1198 loser:
   1199     /* evil client doesn't support uncompressed */
   1200     ssl3_DisableECCSuites(ss, ecSuites);
   1201     return SECFailure;
   1202 }
   1203 
   1204 
   1205 #define SSL3_GET_SERVER_PUBLICKEY(sock, type) \
   1206     (ss->serverCerts[type].serverKeyPair ? \
   1207     ss->serverCerts[type].serverKeyPair->pubKey : NULL)
   1208 
   1209 /* Extract the TLS curve name for the public key in our EC server cert. */
   1210 ECName ssl3_GetSvrCertCurveName(sslSocket *ss)
   1211 {
   1212     SECKEYPublicKey       *srvPublicKey;
   1213     ECName		  ec_curve       = ec_noName;
   1214 
   1215     srvPublicKey = SSL3_GET_SERVER_PUBLICKEY(ss, kt_ecdh);
   1216     if (srvPublicKey) {
   1217 	ec_curve = params2ecName(&srvPublicKey->u.ec.DEREncodedParams);
   1218     }
   1219     return ec_curve;
   1220 }
   1221 
   1222 /* Ensure that the curve in our server cert is one of the ones suppored
   1223  * by the remote client, and disable all ECC cipher suites if not.
   1224  */
   1225 SECStatus
   1226 ssl3_HandleSupportedCurvesXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
   1227 {
   1228     PRInt32  list_len;
   1229     PRUint32 peerCurves   = 0;
   1230     PRUint32 mutualCurves = 0;
   1231     PRUint16 svrCertCurveName;
   1232 
   1233     if (!data->data || data->len < 4 || data->len > 65535)
   1234     	goto loser;
   1235     /* get the length of elliptic_curve_list */
   1236     list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
   1237     if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) {
   1238     	/* malformed */
   1239 	goto loser;
   1240     }
   1241     /* build bit vector of peer's supported curve names */
   1242     while (data->len) {
   1243 	PRInt32  curve_name =
   1244 		 ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
   1245 	if (curve_name > ec_noName && curve_name < ec_pastLastName) {
   1246 	    peerCurves |= (1U << curve_name);
   1247 	}
   1248     }
   1249     /* What curves do we support in common? */
   1250     mutualCurves = ss->ssl3.hs.negotiatedECCurves &= peerCurves;
   1251     if (!mutualCurves) { /* no mutually supported EC Curves */
   1252     	goto loser;
   1253     }
   1254 
   1255     /* if our ECC cert doesn't use one of these supported curves,
   1256      * disable ECC cipher suites that require an ECC cert.
   1257      */
   1258     svrCertCurveName = ssl3_GetSvrCertCurveName(ss);
   1259     if (svrCertCurveName != ec_noName &&
   1260         (mutualCurves & (1U << svrCertCurveName)) != 0) {
   1261 	return SECSuccess;
   1262     }
   1263     /* Our EC cert doesn't contain a mutually supported curve.
   1264      * Disable all ECC cipher suites that require an EC cert
   1265      */
   1266     ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites);
   1267     ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites);
   1268     return SECFailure;
   1269 
   1270 loser:
   1271     /* no common curve supported */
   1272     ssl3_DisableECCSuites(ss, ecSuites);
   1273     return SECFailure;
   1274 }
   1275 
   1276 #endif /* NSS_ENABLE_ECC */
   1277