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