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_128_GCM_SHA256,
    915     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
    916     TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
    917     TLS_ECDHE_ECDSA_WITH_NULL_SHA,
    918     TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
    919     0 /* end of list marker */
    920 };
    921 
    922 static const ssl3CipherSuite ecdhe_rsa_suites[] = {
    923     TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
    924     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
    925     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
    926     TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
    927     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
    928     TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
    929     TLS_ECDHE_RSA_WITH_NULL_SHA,
    930     TLS_ECDHE_RSA_WITH_RC4_128_SHA,
    931     0 /* end of list marker */
    932 };
    933 
    934 /* List of all ECC cipher suites */
    935 static const ssl3CipherSuite ecSuites[] = {
    936     TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
    937     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
    938     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
    939     TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
    940     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
    941     TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
    942     TLS_ECDHE_ECDSA_WITH_NULL_SHA,
    943     TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
    944     TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
    945     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
    946     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
    947     TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
    948     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
    949     TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
    950     TLS_ECDHE_RSA_WITH_NULL_SHA,
    951     TLS_ECDHE_RSA_WITH_RC4_128_SHA,
    952     TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
    953     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
    954     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
    955     TLS_ECDH_ECDSA_WITH_NULL_SHA,
    956     TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
    957     TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
    958     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
    959     TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
    960     TLS_ECDH_RSA_WITH_NULL_SHA,
    961     TLS_ECDH_RSA_WITH_RC4_128_SHA,
    962     0 /* end of list marker */
    963 };
    964 
    965 /* On this socket, Disable the ECC cipher suites in the argument's list */
    966 SECStatus
    967 ssl3_DisableECCSuites(sslSocket * ss, const ssl3CipherSuite * suite)
    968 {
    969     if (!suite)
    970     	suite = ecSuites;
    971     for (; *suite; ++suite) {
    972 	SECStatus rv      = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
    973 
    974 	PORT_Assert(rv == SECSuccess); /* else is coding error */
    975     }
    976     return SECSuccess;
    977 }
    978 
    979 /* Look at the server certs configured on this socket, and disable any
    980  * ECC cipher suites that are not supported by those certs.
    981  */
    982 void
    983 ssl3_FilterECCipherSuitesByServerCerts(sslSocket * ss)
    984 {
    985     CERTCertificate * svrCert;
    986 
    987     svrCert = ss->serverCerts[kt_rsa].serverCert;
    988     if (!svrCert) {
    989 	ssl3_DisableECCSuites(ss, ecdhe_rsa_suites);
    990     }
    991 
    992     svrCert = ss->serverCerts[kt_ecdh].serverCert;
    993     if (!svrCert) {
    994 	ssl3_DisableECCSuites(ss, ecdh_suites);
    995 	ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites);
    996     } else {
    997 	SECOidTag sigTag = SECOID_GetAlgorithmTag(&svrCert->signature);
    998 
    999 	switch (sigTag) {
   1000 	case SEC_OID_PKCS1_RSA_ENCRYPTION:
   1001 	case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
   1002 	case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
   1003 	case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
   1004 	case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
   1005 	case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
   1006 	case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
   1007 	case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
   1008 	case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
   1009 	    ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites);
   1010 	    break;
   1011 	case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
   1012 	case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
   1013 	case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
   1014 	case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
   1015 	case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
   1016 	case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
   1017 	case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
   1018 	    ssl3_DisableECCSuites(ss, ecdh_rsa_suites);
   1019 	    break;
   1020 	default:
   1021 	    ssl3_DisableECCSuites(ss, ecdh_suites);
   1022 	    break;
   1023 	}
   1024     }
   1025 }
   1026 
   1027 /* Ask: is ANY ECC cipher suite enabled on this socket? */
   1028 /* Order(N^2).  Yuk.  Also, this ignores export policy. */
   1029 PRBool
   1030 ssl3_IsECCEnabled(sslSocket * ss)
   1031 {
   1032     const ssl3CipherSuite * suite;
   1033     PK11SlotInfo *slot;
   1034 
   1035     /* make sure we can do ECC */
   1036     slot = PK11_GetBestSlot(CKM_ECDH1_DERIVE,  ss->pkcs11PinArg);
   1037     if (!slot) {
   1038 	return PR_FALSE;
   1039     }
   1040     PK11_FreeSlot(slot);
   1041 
   1042     /* make sure an ECC cipher is enabled */
   1043     for (suite = ecSuites; *suite; ++suite) {
   1044 	PRBool    enabled = PR_FALSE;
   1045 	SECStatus rv      = ssl3_CipherPrefGet(ss, *suite, &enabled);
   1046 
   1047 	PORT_Assert(rv == SECSuccess); /* else is coding error */
   1048 	if (rv == SECSuccess && enabled)
   1049 	    return PR_TRUE;
   1050     }
   1051     return PR_FALSE;
   1052 }
   1053 
   1054 #define BE(n) 0, n
   1055 
   1056 /* Prefabricated TLS client hello extension, Elliptic Curves List,
   1057  * offers only 3 curves, the Suite B curves, 23-25
   1058  */
   1059 static const PRUint8 suiteBECList[12] = {
   1060     BE(10),         /* Extension type */
   1061     BE( 8),         /* octets that follow ( 3 pairs + 1 length pair) */
   1062     BE( 6),         /* octets that follow ( 3 pairs) */
   1063     BE(23), BE(24), BE(25)
   1064 };
   1065 
   1066 /* Prefabricated TLS client hello extension, Elliptic Curves List,
   1067  * offers curves 1-25.
   1068  */
   1069 static const PRUint8 tlsECList[56] = {
   1070     BE(10),         /* Extension type */
   1071     BE(52),         /* octets that follow (25 pairs + 1 length pair) */
   1072     BE(50),         /* octets that follow (25 pairs) */
   1073             BE( 1), BE( 2), BE( 3), BE( 4), BE( 5), BE( 6), BE( 7),
   1074     BE( 8), BE( 9), BE(10), BE(11), BE(12), BE(13), BE(14), BE(15),
   1075     BE(16), BE(17), BE(18), BE(19), BE(20), BE(21), BE(22), BE(23),
   1076     BE(24), BE(25)
   1077 };
   1078 
   1079 static const PRUint8 ecPtFmt[6] = {
   1080     BE(11),         /* Extension type */
   1081     BE( 2),         /* octets that follow */
   1082              1,     /* octets that follow */
   1083                  0  /* uncompressed type only */
   1084 };
   1085 
   1086 /* This function already presumes we can do ECC, ssl3_IsECCEnabled must be
   1087  * called before this function. It looks to see if we have a token which
   1088  * is capable of doing smaller than SuiteB curves. If the token can, we
   1089  * presume the token can do the whole SSL suite of curves. If it can't we
   1090  * presume the token that allowed ECC to be enabled can only do suite B
   1091  * curves. */
   1092 static PRBool
   1093 ssl3_SuiteBOnly(sslSocket *ss)
   1094 {
   1095 #if 0
   1096     /* See if we can support small curves (like 163). If not, assume we can
   1097      * only support Suite-B curves (P-256, P-384, P-521). */
   1098     PK11SlotInfo *slot =
   1099 	PK11_GetBestSlotWithAttributes(CKM_ECDH1_DERIVE, 0, 163,
   1100 				       ss ? ss->pkcs11PinArg : NULL);
   1101 
   1102     if (!slot) {
   1103 	/* nope, presume we can only do suite B */
   1104 	return PR_TRUE;
   1105     }
   1106     /* we can, presume we can do all curves */
   1107     PK11_FreeSlot(slot);
   1108     return PR_FALSE;
   1109 #else
   1110     return PR_TRUE;
   1111 #endif
   1112 }
   1113 
   1114 /* Send our "canned" (precompiled) Supported Elliptic Curves extension,
   1115  * which says that we support all TLS-defined named curves.
   1116  */
   1117 PRInt32
   1118 ssl3_SendSupportedCurvesXtn(
   1119 			sslSocket * ss,
   1120 			PRBool      append,
   1121 			PRUint32    maxBytes)
   1122 {
   1123     PRInt32 ecListSize = 0;
   1124     const PRUint8 *ecList = NULL;
   1125 
   1126     if (!ss || !ssl3_IsECCEnabled(ss))
   1127     	return 0;
   1128 
   1129     if (ssl3_SuiteBOnly(ss)) {
   1130 	ecListSize = sizeof suiteBECList;
   1131 	ecList = suiteBECList;
   1132     } else {
   1133 	ecListSize = sizeof tlsECList;
   1134 	ecList = tlsECList;
   1135     }
   1136 
   1137     if (append && maxBytes >= ecListSize) {
   1138 	SECStatus rv = ssl3_AppendHandshake(ss, ecList, ecListSize);
   1139 	if (rv != SECSuccess)
   1140 	    return -1;
   1141 	if (!ss->sec.isServer) {
   1142 	    TLSExtensionData *xtnData = &ss->xtnData;
   1143 	    xtnData->advertised[xtnData->numAdvertised++] =
   1144 		ssl_elliptic_curves_xtn;
   1145 	}
   1146     }
   1147     return ecListSize;
   1148 }
   1149 
   1150 PRUint32
   1151 ssl3_GetSupportedECCurveMask(sslSocket *ss)
   1152 {
   1153     if (ssl3_SuiteBOnly(ss)) {
   1154 	return SSL3_SUITE_B_SUPPORTED_CURVES_MASK;
   1155     }
   1156     return SSL3_ALL_SUPPORTED_CURVES_MASK;
   1157 }
   1158 
   1159 /* Send our "canned" (precompiled) Supported Point Formats extension,
   1160  * which says that we only support uncompressed points.
   1161  */
   1162 PRInt32
   1163 ssl3_SendSupportedPointFormatsXtn(
   1164 			sslSocket * ss,
   1165 			PRBool      append,
   1166 			PRUint32    maxBytes)
   1167 {
   1168     if (!ss || !ssl3_IsECCEnabled(ss))
   1169     	return 0;
   1170     if (append && maxBytes >= (sizeof ecPtFmt)) {
   1171 	SECStatus rv = ssl3_AppendHandshake(ss, ecPtFmt, (sizeof ecPtFmt));
   1172 	if (rv != SECSuccess)
   1173 	    return -1;
   1174 	if (!ss->sec.isServer) {
   1175 	    TLSExtensionData *xtnData = &ss->xtnData;
   1176 	    xtnData->advertised[xtnData->numAdvertised++] =
   1177 		ssl_ec_point_formats_xtn;
   1178 	}
   1179     }
   1180     return (sizeof ecPtFmt);
   1181 }
   1182 
   1183 /* Just make sure that the remote client supports uncompressed points,
   1184  * Since that is all we support.  Disable ECC cipher suites if it doesn't.
   1185  */
   1186 SECStatus
   1187 ssl3_HandleSupportedPointFormatsXtn(sslSocket *ss, PRUint16 ex_type,
   1188                                     SECItem *data)
   1189 {
   1190     int i;
   1191 
   1192     if (data->len < 2 || data->len > 255 || !data->data ||
   1193         data->len != (unsigned int)data->data[0] + 1) {
   1194     	/* malformed */
   1195 	goto loser;
   1196     }
   1197     for (i = data->len; --i > 0; ) {
   1198     	if (data->data[i] == 0) {
   1199 	    /* indicate that we should send a reply */
   1200 	    SECStatus rv;
   1201 	    rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
   1202 			      &ssl3_SendSupportedPointFormatsXtn);
   1203 	    return rv;
   1204 	}
   1205     }
   1206 loser:
   1207     /* evil client doesn't support uncompressed */
   1208     ssl3_DisableECCSuites(ss, ecSuites);
   1209     return SECFailure;
   1210 }
   1211 
   1212 
   1213 #define SSL3_GET_SERVER_PUBLICKEY(sock, type) \
   1214     (ss->serverCerts[type].serverKeyPair ? \
   1215     ss->serverCerts[type].serverKeyPair->pubKey : NULL)
   1216 
   1217 /* Extract the TLS curve name for the public key in our EC server cert. */
   1218 ECName ssl3_GetSvrCertCurveName(sslSocket *ss)
   1219 {
   1220     SECKEYPublicKey       *srvPublicKey;
   1221     ECName		  ec_curve       = ec_noName;
   1222 
   1223     srvPublicKey = SSL3_GET_SERVER_PUBLICKEY(ss, kt_ecdh);
   1224     if (srvPublicKey) {
   1225 	ec_curve = params2ecName(&srvPublicKey->u.ec.DEREncodedParams);
   1226     }
   1227     return ec_curve;
   1228 }
   1229 
   1230 /* Ensure that the curve in our server cert is one of the ones suppored
   1231  * by the remote client, and disable all ECC cipher suites if not.
   1232  */
   1233 SECStatus
   1234 ssl3_HandleSupportedCurvesXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
   1235 {
   1236     PRInt32  list_len;
   1237     PRUint32 peerCurves   = 0;
   1238     PRUint32 mutualCurves = 0;
   1239     PRUint16 svrCertCurveName;
   1240 
   1241     if (!data->data || data->len < 4 || data->len > 65535)
   1242     	goto loser;
   1243     /* get the length of elliptic_curve_list */
   1244     list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
   1245     if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) {
   1246     	/* malformed */
   1247 	goto loser;
   1248     }
   1249     /* build bit vector of peer's supported curve names */
   1250     while (data->len) {
   1251 	PRInt32  curve_name =
   1252 		 ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
   1253 	if (curve_name > ec_noName && curve_name < ec_pastLastName) {
   1254 	    peerCurves |= (1U << curve_name);
   1255 	}
   1256     }
   1257     /* What curves do we support in common? */
   1258     mutualCurves = ss->ssl3.hs.negotiatedECCurves &= peerCurves;
   1259     if (!mutualCurves) { /* no mutually supported EC Curves */
   1260     	goto loser;
   1261     }
   1262 
   1263     /* if our ECC cert doesn't use one of these supported curves,
   1264      * disable ECC cipher suites that require an ECC cert.
   1265      */
   1266     svrCertCurveName = ssl3_GetSvrCertCurveName(ss);
   1267     if (svrCertCurveName != ec_noName &&
   1268         (mutualCurves & (1U << svrCertCurveName)) != 0) {
   1269 	return SECSuccess;
   1270     }
   1271     /* Our EC cert doesn't contain a mutually supported curve.
   1272      * Disable all ECC cipher suites that require an EC cert
   1273      */
   1274     ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites);
   1275     ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites);
   1276     return SECFailure;
   1277 
   1278 loser:
   1279     /* no common curve supported */
   1280     ssl3_DisableECCSuites(ss, ecSuites);
   1281     return SECFailure;
   1282 }
   1283 
   1284 #endif /* NSS_ENABLE_ECC */
   1285