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