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