| OLD | NEW |
| 1 /* | 1 /* |
| 2 * SSL3 Protocol | 2 * SSL3 Protocol |
| 3 * | 3 * |
| 4 * This Source Code Form is subject to the terms of the Mozilla Public | 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 | 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/. */ | 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 7 | 7 |
| 8 /* ECC code moved here from ssl3con.c */ | 8 /* ECC code moved here from ssl3con.c */ |
| 9 /* $Id$ */ | 9 /* $Id$ */ |
| 10 | 10 |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 for (i = ec_noName + 1; i < ec_pastLastName; i++) { | 210 for (i = ec_noName + 1; i < ec_pastLastName; i++) { |
| 211 if (ecName2OIDTag[i] == oidData->offset) | 211 if (ecName2OIDTag[i] == oidData->offset) |
| 212 return i; | 212 return i; |
| 213 } | 213 } |
| 214 | 214 |
| 215 return ec_noName; | 215 return ec_noName; |
| 216 } | 216 } |
| 217 | 217 |
| 218 /* Caller must set hiLevel error code. */ | 218 /* Caller must set hiLevel error code. */ |
| 219 static SECStatus | 219 static SECStatus |
| 220 ssl3_ComputeECDHKeyHash(SECItem ec_params, SECItem server_ecpoint, | 220 ssl3_ComputeECDHKeyHash(SECOidTag hashAlg, |
| 221 » » » SSL3Random *client_rand, SSL3Random *server_rand, | 221 » » » SECItem ec_params, SECItem server_ecpoint, |
| 222 » » » SSL3Hashes *hashes, PRBool bypassPKCS11) | 222 » » » SSL3Random *client_rand, SSL3Random *server_rand, |
| 223 » » » SSL3Hashes *hashes, PRBool bypassPKCS11) |
| 223 { | 224 { |
| 224 PRUint8 * hashBuf; | 225 PRUint8 * hashBuf; |
| 225 PRUint8 * pBuf; | 226 PRUint8 * pBuf; |
| 226 SECStatus rv = SECSuccess; | 227 SECStatus rv = SECSuccess; |
| 227 unsigned int bufLen; | 228 unsigned int bufLen; |
| 228 /* | 229 /* |
| 229 * XXX For now, we only support named curves (the appropriate | 230 * XXX For now, we only support named curves (the appropriate |
| 230 * checks are made before this method is called) so ec_params | 231 * 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 * 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 * (because the spec says the length must fit in one byte) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 248 memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH); | 249 memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH); |
| 249 pBuf += SSL3_RANDOM_LENGTH; | 250 pBuf += SSL3_RANDOM_LENGTH; |
| 250 memcpy(pBuf, ec_params.data, ec_params.len); | 251 memcpy(pBuf, ec_params.data, ec_params.len); |
| 251 pBuf += ec_params.len; | 252 pBuf += ec_params.len; |
| 252 pBuf[0] = (PRUint8)(server_ecpoint.len); | 253 pBuf[0] = (PRUint8)(server_ecpoint.len); |
| 253 pBuf += 1; | 254 pBuf += 1; |
| 254 memcpy(pBuf, server_ecpoint.data, server_ecpoint.len); | 255 memcpy(pBuf, server_ecpoint.data, server_ecpoint.len); |
| 255 pBuf += server_ecpoint.len; | 256 pBuf += server_ecpoint.len; |
| 256 PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen); | 257 PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen); |
| 257 | 258 |
| 258 rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11); | 259 rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes, bypassPKCS1
1); |
| 259 | 260 |
| 260 PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen)); | 261 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: MD5 result", hashes->u.s.md5, MD5_LENGTH
)); |
| 262 PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result", hashes->sha, SHA1_LENGTH))
; | 263 PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result", hashes->u.s.sha, SHA1_LENG
TH)); |
| 263 | 264 |
| 264 if (hashBuf != buf) | 265 if (hashBuf != buf) |
| 265 PORT_Free(hashBuf); | 266 PORT_Free(hashBuf); |
| 266 return rv; | 267 return rv; |
| 267 } | 268 } |
| 268 | 269 |
| 269 | 270 |
| 270 /* Called from ssl3_SendClientKeyExchange(). */ | 271 /* Called from ssl3_SendClientKeyExchange(). */ |
| 271 SECStatus | 272 SECStatus |
| 272 ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) | 273 ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) |
| 273 { | 274 { |
| 274 PK11SymKey * pms = NULL; | 275 PK11SymKey * pms = NULL; |
| 275 SECStatus rv = SECFailure; | 276 SECStatus rv = SECFailure; |
| 276 PRBool isTLS; | 277 PRBool isTLS, isTLS12; |
| 277 CK_MECHANISM_TYPE target; | 278 CK_MECHANISM_TYPE target; |
| 278 SECKEYPublicKey *pubKey = NULL; /* Ephemeral ECDH key */ | 279 SECKEYPublicKey *pubKey = NULL; /* Ephemeral ECDH key */ |
| 279 SECKEYPrivateKey *privKey = NULL; /* Ephemeral ECDH key */ | 280 SECKEYPrivateKey *privKey = NULL; /* Ephemeral ECDH key */ |
| 280 | 281 |
| 281 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); | 282 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 282 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); | 283 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
| 283 | 284 |
| 284 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); | 285 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); |
| 286 isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); |
| 285 | 287 |
| 286 /* Generate ephemeral EC keypair */ | 288 /* Generate ephemeral EC keypair */ |
| 287 if (svrPubKey->keyType != ecKey) { | 289 if (svrPubKey->keyType != ecKey) { |
| 288 PORT_SetError(SEC_ERROR_BAD_KEY); | 290 PORT_SetError(SEC_ERROR_BAD_KEY); |
| 289 goto loser; | 291 goto loser; |
| 290 } | 292 } |
| 291 /* XXX SHOULD CALL ssl3_CreateECDHEphemeralKeys here, instead! */ | 293 /* XXX SHOULD CALL ssl3_CreateECDHEphemeralKeys here, instead! */ |
| 292 privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams, | 294 privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams, |
| 293 &pubKey, ss->pkcs11PinArg); | 295 &pubKey, ss->pkcs11PinArg); |
| 294 if (!privKey || !pubKey) { | 296 if (!privKey || !pubKey) { |
| 295 ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); | 297 ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); |
| 296 rv = SECFailure; | 298 rv = SECFailure; |
| 297 goto loser; | 299 goto loser; |
| 298 } | 300 } |
| 299 PRINT_BUF(50, (ss, "ECDH public value:", | 301 PRINT_BUF(50, (ss, "ECDH public value:", |
| 300 pubKey->u.ec.publicValue.data, | 302 pubKey->u.ec.publicValue.data, |
| 301 pubKey->u.ec.publicValue.len)); | 303 pubKey->u.ec.publicValue.len)); |
| 302 | 304 |
| 303 if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH; | 305 if (isTLS12) { |
| 304 else target = CKM_SSL3_MASTER_KEY_DERIVE_DH; | 306 » target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256; |
| 307 } else if (isTLS) { |
| 308 » target = CKM_TLS_MASTER_KEY_DERIVE_DH; |
| 309 } else { |
| 310 » target = CKM_SSL3_MASTER_KEY_DERIVE_DH; |
| 311 } |
| 305 | 312 |
| 306 /* Determine the PMS */ | 313 /* Determine the PMS */ |
| 307 pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL, | 314 pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL, |
| 308 CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, | 315 CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, |
| 309 CKD_NULL, NULL, NULL); | 316 CKD_NULL, NULL, NULL); |
| 310 | 317 |
| 311 if (pms == NULL) { | 318 if (pms == NULL) { |
| 312 SSL3AlertDescription desc = illegal_parameter; | 319 SSL3AlertDescription desc = illegal_parameter; |
| 313 (void)SSL3_SendAlert(ss, alert_fatal, desc); | 320 (void)SSL3_SendAlert(ss, alert_fatal, desc); |
| 314 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); | 321 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 SECStatus | 365 SECStatus |
| 359 ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b, | 366 ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b, |
| 360 PRUint32 length, | 367 PRUint32 length, |
| 361 SECKEYPublicKey *srvrPubKey, | 368 SECKEYPublicKey *srvrPubKey, |
| 362 SECKEYPrivateKey *srvrPrivKey) | 369 SECKEYPrivateKey *srvrPrivKey) |
| 363 { | 370 { |
| 364 PK11SymKey * pms; | 371 PK11SymKey * pms; |
| 365 SECStatus rv; | 372 SECStatus rv; |
| 366 SECKEYPublicKey clntPubKey; | 373 SECKEYPublicKey clntPubKey; |
| 367 CK_MECHANISM_TYPE target; | 374 CK_MECHANISM_TYPE target; |
| 368 PRBool isTLS; | 375 PRBool isTLS, isTLS12; |
| 369 | 376 |
| 370 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); | 377 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
| 371 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); | 378 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 372 | 379 |
| 373 clntPubKey.keyType = ecKey; | 380 clntPubKey.keyType = ecKey; |
| 374 clntPubKey.u.ec.DEREncodedParams.len = | 381 clntPubKey.u.ec.DEREncodedParams.len = |
| 375 srvrPubKey->u.ec.DEREncodedParams.len; | 382 srvrPubKey->u.ec.DEREncodedParams.len; |
| 376 clntPubKey.u.ec.DEREncodedParams.data = | 383 clntPubKey.u.ec.DEREncodedParams.data = |
| 377 srvrPubKey->u.ec.DEREncodedParams.data; | 384 srvrPubKey->u.ec.DEREncodedParams.data; |
| 378 | 385 |
| 379 rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue, | 386 rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue, |
| 380 1, &b, &length); | 387 1, &b, &length); |
| 381 if (rv != SECSuccess) { | 388 if (rv != SECSuccess) { |
| 382 SEND_ALERT | 389 SEND_ALERT |
| 383 return SECFailure; /* XXX Who sets the error code?? */ | 390 return SECFailure; /* XXX Who sets the error code?? */ |
| 384 } | 391 } |
| 385 | 392 |
| 386 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); | 393 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); |
| 394 isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); |
| 387 | 395 |
| 388 if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH; | 396 if (isTLS12) { |
| 389 else target = CKM_SSL3_MASTER_KEY_DERIVE_DH; | 397 » target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256; |
| 398 } else if (isTLS) { |
| 399 » target = CKM_TLS_MASTER_KEY_DERIVE_DH; |
| 400 } else { |
| 401 » target = CKM_SSL3_MASTER_KEY_DERIVE_DH; |
| 402 } |
| 390 | 403 |
| 391 /* Determine the PMS */ | 404 /* Determine the PMS */ |
| 392 pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL, | 405 pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL, |
| 393 CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, | 406 CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, |
| 394 CKD_NULL, NULL, NULL); | 407 CKD_NULL, NULL, NULL); |
| 395 | 408 |
| 396 if (pms == NULL) { | 409 if (pms == NULL) { |
| 397 /* last gasp. */ | 410 /* last gasp. */ |
| 398 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); | 411 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
| 399 return SECFailure; | 412 return SECFailure; |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 PRBool isTLS; | 598 PRBool isTLS; |
| 586 SECStatus rv; | 599 SECStatus rv; |
| 587 int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH; | 600 int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH; |
| 588 SSL3AlertDescription desc = illegal_parameter; | 601 SSL3AlertDescription desc = illegal_parameter; |
| 589 SSL3Hashes hashes; | 602 SSL3Hashes hashes; |
| 590 SECItem signature = {siBuffer, NULL, 0}; | 603 SECItem signature = {siBuffer, NULL, 0}; |
| 591 | 604 |
| 592 SECItem ec_params = {siBuffer, NULL, 0}; | 605 SECItem ec_params = {siBuffer, NULL, 0}; |
| 593 SECItem ec_point = {siBuffer, NULL, 0}; | 606 SECItem ec_point = {siBuffer, NULL, 0}; |
| 594 unsigned char paramBuf[3]; /* only for curve_type == named_curve */ | 607 unsigned char paramBuf[3]; /* only for curve_type == named_curve */ |
| 608 SSL3SignatureAndHashAlgorithm sigAndHash; |
| 609 |
| 610 sigAndHash.hashAlg = SEC_OID_UNKNOWN; |
| 595 | 611 |
| 596 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); | 612 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); |
| 597 | 613 |
| 598 /* XXX This works only for named curves, revisit this when | 614 /* XXX This works only for named curves, revisit this when |
| 599 * we support generic curves. | 615 * we support generic curves. |
| 600 */ | 616 */ |
| 601 ec_params.len = sizeof paramBuf; | 617 ec_params.len = sizeof paramBuf; |
| 602 ec_params.data = paramBuf; | 618 ec_params.data = paramBuf; |
| 603 rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length); | 619 rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length); |
| 604 if (rv != SECSuccess) { | 620 if (rv != SECSuccess) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 618 if (rv != SECSuccess) { | 634 if (rv != SECSuccess) { |
| 619 goto loser; /* malformed. */ | 635 goto loser; /* malformed. */ |
| 620 } | 636 } |
| 621 /* Fail if the ec point uses compressed representation */ | 637 /* Fail if the ec point uses compressed representation */ |
| 622 if (ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) { | 638 if (ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) { |
| 623 errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM; | 639 errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM; |
| 624 desc = handshake_failure; | 640 desc = handshake_failure; |
| 625 goto alert_loser; | 641 goto alert_loser; |
| 626 } | 642 } |
| 627 | 643 |
| 644 if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) { |
| 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 |
| 628 rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length); | 657 rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length); |
| 629 if (rv != SECSuccess) { | 658 if (rv != SECSuccess) { |
| 630 goto loser; /* malformed. */ | 659 goto loser; /* malformed. */ |
| 631 } | 660 } |
| 632 | 661 |
| 633 if (length != 0) { | 662 if (length != 0) { |
| 634 if (isTLS) | 663 if (isTLS) |
| 635 desc = decode_error; | 664 desc = decode_error; |
| 636 goto alert_loser; /* malformed. */ | 665 goto alert_loser; /* malformed. */ |
| 637 } | 666 } |
| 638 | 667 |
| 639 PRINT_BUF(60, (NULL, "Server EC params", ec_params.data, | 668 PRINT_BUF(60, (NULL, "Server EC params", ec_params.data, |
| 640 ec_params.len)); | 669 ec_params.len)); |
| 641 PRINT_BUF(60, (NULL, "Server EC point", ec_point.data, ec_point.len)); | 670 PRINT_BUF(60, (NULL, "Server EC point", ec_point.data, ec_point.len)); |
| 642 | 671 |
| 643 /* failures after this point are not malformed handshakes. */ | 672 /* failures after this point are not malformed handshakes. */ |
| 644 /* TLS: send decrypt_error if signature failed. */ | 673 /* TLS: send decrypt_error if signature failed. */ |
| 645 desc = isTLS ? decrypt_error : handshake_failure; | 674 desc = isTLS ? decrypt_error : handshake_failure; |
| 646 | 675 |
| 647 /* | 676 /* |
| 648 * check to make sure the hash is signed by right guy | 677 * check to make sure the hash is signed by right guy |
| 649 */ | 678 */ |
| 650 rv = ssl3_ComputeECDHKeyHash(ec_params, ec_point, | 679 rv = ssl3_ComputeECDHKeyHash(sigAndHash.hashAlg, ec_params, ec_point, |
| 651 » » » » &ss->ssl3.hs.client_random, | 680 » » » » &ss->ssl3.hs.client_random, |
| 652 » » » » &ss->ssl3.hs.server_random, | 681 » » » » &ss->ssl3.hs.server_random, |
| 653 » » » » &hashes, ss->opt.bypassPKCS11); | 682 » » » » &hashes, ss->opt.bypassPKCS11); |
| 654 | 683 |
| 655 if (rv != SECSuccess) { | 684 if (rv != SECSuccess) { |
| 656 errCode = | 685 errCode = |
| 657 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | 686 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
| 658 goto alert_loser; | 687 goto alert_loser; |
| 659 } | 688 } |
| 660 rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature, | 689 rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature, |
| 661 isTLS, ss->pkcs11PinArg); | 690 isTLS, ss->pkcs11PinArg); |
| 662 if (rv != SECSuccess) { | 691 if (rv != SECSuccess) { |
| 663 errCode = | 692 errCode = |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 709 return SECFailure; | 738 return SECFailure; |
| 710 | 739 |
| 711 no_memory: /* no-memory error has already been set. */ | 740 no_memory: /* no-memory error has already been set. */ |
| 712 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | 741 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
| 713 return SECFailure; | 742 return SECFailure; |
| 714 } | 743 } |
| 715 | 744 |
| 716 SECStatus | 745 SECStatus |
| 717 ssl3_SendECDHServerKeyExchange(sslSocket *ss) | 746 ssl3_SendECDHServerKeyExchange(sslSocket *ss) |
| 718 { | 747 { |
| 719 const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; | 748 const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; |
| 720 SECStatus rv = SECFailure; | 749 SECStatus rv = SECFailure; |
| 721 int length; | 750 int length; |
| 722 PRBool isTLS; | 751 PRBool isTLS; |
| 723 SECItem signed_hash = {siBuffer, NULL, 0}; | 752 SECItem signed_hash = {siBuffer, NULL, 0}; |
| 724 SSL3Hashes hashes; | 753 SSL3Hashes hashes; |
| 725 | 754 |
| 726 SECKEYPublicKey * ecdhePub; | 755 SECKEYPublicKey * ecdhePub; |
| 727 SECItem ec_params = {siBuffer, NULL, 0}; | 756 SECItem ec_params = {siBuffer, NULL, 0}; |
| 728 unsigned char paramBuf[3]; | 757 unsigned char paramBuf[3]; |
| 729 ECName curve; | 758 ECName curve; |
| 730 SSL3KEAType certIndex; | 759 SSL3KEAType certIndex; |
| 760 SSL3SignatureAndHashAlgorithm sigAndHash; |
| 731 | 761 |
| 762 if (SECSuccess != ssl3_PickSignatureHashFunction(ss, &sigAndHash)) { |
| 763 PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_FUNCTION); |
| 764 return SECFailure; |
| 765 } |
| 732 | 766 |
| 733 /* Generate ephemeral ECDH key pair and send the public key */ | 767 /* Generate ephemeral ECDH key pair and send the public key */ |
| 734 curve = ssl3_GetCurveNameForServerSocket(ss); | 768 curve = ssl3_GetCurveNameForServerSocket(ss); |
| 735 if (curve == ec_noName) { | 769 if (curve == ec_noName) { |
| 736 goto loser; | 770 goto loser; |
| 737 } | 771 } |
| 738 rv = ssl3_CreateECDHEphemeralKeys(ss, curve); | 772 rv = ssl3_CreateECDHEphemeralKeys(ss, curve); |
| 739 if (rv != SECSuccess) { | 773 if (rv != SECSuccess) { |
| 740 goto loser; /* err set by AppendHandshake. */ | 774 goto loser; /* err set by AppendHandshake. */ |
| 741 } | 775 } |
| 742 ecdhePub = ss->ephemeralECDHKeyPair->pubKey; | 776 ecdhePub = ss->ephemeralECDHKeyPair->pubKey; |
| 743 PORT_Assert(ecdhePub != NULL); | 777 PORT_Assert(ecdhePub != NULL); |
| 744 if (!ecdhePub) { | 778 if (!ecdhePub) { |
| 745 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | 779 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
| 746 return SECFailure; | 780 return SECFailure; |
| 747 } | 781 } |
| 748 | 782 |
| 749 ec_params.len = sizeof paramBuf; | 783 ec_params.len = sizeof paramBuf; |
| 750 ec_params.data = paramBuf; | 784 ec_params.data = paramBuf; |
| 751 curve = params2ecName(&ecdhePub->u.ec.DEREncodedParams); | 785 curve = params2ecName(&ecdhePub->u.ec.DEREncodedParams); |
| 752 if (curve != ec_noName) { | 786 if (curve != ec_noName) { |
| 753 ec_params.data[0] = ec_type_named; | 787 ec_params.data[0] = ec_type_named; |
| 754 ec_params.data[1] = 0x00; | 788 ec_params.data[1] = 0x00; |
| 755 ec_params.data[2] = curve; | 789 ec_params.data[2] = curve; |
| 756 } else { | 790 } else { |
| 757 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); | 791 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); |
| 758 goto loser; | 792 goto loser; |
| 759 } | 793 } |
| 760 | 794 |
| 761 rv = ssl3_ComputeECDHKeyHash(ec_params, ecdhePub->u.ec.publicValue, | 795 rv = ssl3_ComputeECDHKeyHash(sigAndHash.hashAlg, |
| 762 » » » » &ss->ssl3.hs.client_random, | 796 » » » » ec_params, |
| 763 » » » » &ss->ssl3.hs.server_random, | 797 » » » » ecdhePub->u.ec.publicValue, |
| 764 » » » » &hashes, ss->opt.bypassPKCS11); | 798 » » » » &ss->ssl3.hs.client_random, |
| 799 » » » » &ss->ssl3.hs.server_random, |
| 800 » » » » &hashes, ss->opt.bypassPKCS11); |
| 765 if (rv != SECSuccess) { | 801 if (rv != SECSuccess) { |
| 766 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | 802 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
| 767 goto loser; | 803 goto loser; |
| 768 } | 804 } |
| 769 | 805 |
| 770 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); | 806 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); |
| 771 | 807 |
| 772 /* XXX SSLKEAType isn't really a good choice for | 808 /* XXX SSLKEAType isn't really a good choice for |
| 773 * indexing certificates but that's all we have | 809 * indexing certificates but that's all we have |
| 774 * for now. | 810 * for now. |
| 775 */ | 811 */ |
| 776 if (kea_def->kea == kea_ecdhe_rsa) | 812 if (kea_def->kea == kea_ecdhe_rsa) |
| 777 certIndex = kt_rsa; | 813 certIndex = kt_rsa; |
| 778 else /* kea_def->kea == kea_ecdhe_ecdsa */ | 814 else /* kea_def->kea == kea_ecdhe_ecdsa */ |
| 779 certIndex = kt_ecdh; | 815 certIndex = kt_ecdh; |
| 780 | 816 |
| 781 rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].SERVERKEY, | 817 rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].SERVERKEY, |
| 782 &signed_hash, isTLS); | 818 &signed_hash, isTLS); |
| 783 if (rv != SECSuccess) { | 819 if (rv != SECSuccess) { |
| 784 goto loser; /* ssl3_SignHashes has set err. */ | 820 goto loser; /* ssl3_SignHashes has set err. */ |
| 785 } | 821 } |
| 786 if (signed_hash.data == NULL) { | 822 if (signed_hash.data == NULL) { |
| 787 /* how can this happen and rv == SECSuccess ?? */ | 823 /* how can this happen and rv == SECSuccess ?? */ |
| 788 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | 824 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
| 789 goto loser; | 825 goto loser; |
| 790 } | 826 } |
| 791 | 827 |
| 792 length = ec_params.len + | 828 length = ec_params.len + |
| 793 1 + ecdhePub->u.ec.publicValue.len + | 829 1 + ecdhePub->u.ec.publicValue.len + |
| 830 (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2 ? 2 : 0) + |
| 794 2 + signed_hash.len; | 831 2 + signed_hash.len; |
| 795 | 832 |
| 796 rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length); | 833 rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length); |
| 797 if (rv != SECSuccess) { | 834 if (rv != SECSuccess) { |
| 798 goto loser; /* err set by AppendHandshake. */ | 835 goto loser; /* err set by AppendHandshake. */ |
| 799 } | 836 } |
| 800 | 837 |
| 801 rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len); | 838 rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len); |
| 802 if (rv != SECSuccess) { | 839 if (rv != SECSuccess) { |
| 803 goto loser; /* err set by AppendHandshake. */ | 840 goto loser; /* err set by AppendHandshake. */ |
| 804 } | 841 } |
| 805 | 842 |
| 806 rv = ssl3_AppendHandshakeVariable(ss, ecdhePub->u.ec.publicValue.data, | 843 rv = ssl3_AppendHandshakeVariable(ss, ecdhePub->u.ec.publicValue.data, |
| 807 ecdhePub->u.ec.publicValue.len, 1); | 844 ecdhePub->u.ec.publicValue.len, 1); |
| 808 if (rv != SECSuccess) { | 845 if (rv != SECSuccess) { |
| 809 goto loser; /* err set by AppendHandshake. */ | 846 goto loser; /* err set by AppendHandshake. */ |
| 810 } | 847 } |
| 811 | 848 |
| 849 if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) { |
| 850 rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); |
| 851 if (rv != SECSuccess) { |
| 852 goto loser; /* err set by AppendHandshake. */ |
| 853 } |
| 854 } |
| 855 |
| 812 rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data, | 856 rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data, |
| 813 signed_hash.len, 2); | 857 signed_hash.len, 2); |
| 814 if (rv != SECSuccess) { | 858 if (rv != SECSuccess) { |
| 815 goto loser; /* err set by AppendHandshake. */ | 859 goto loser; /* err set by AppendHandshake. */ |
| 816 } | 860 } |
| 817 | 861 |
| 818 PORT_Free(signed_hash.data); | 862 PORT_Free(signed_hash.data); |
| 819 return SECSuccess; | 863 return SECSuccess; |
| 820 | 864 |
| 821 loser: | 865 loser: |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1213 ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites); | 1257 ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites); |
| 1214 return SECFailure; | 1258 return SECFailure; |
| 1215 | 1259 |
| 1216 loser: | 1260 loser: |
| 1217 /* no common curve supported */ | 1261 /* no common curve supported */ |
| 1218 ssl3_DisableECCSuites(ss, ecSuites); | 1262 ssl3_DisableECCSuites(ss, ecSuites); |
| 1219 return SECFailure; | 1263 return SECFailure; |
| 1220 } | 1264 } |
| 1221 | 1265 |
| 1222 #endif /* NSS_ENABLE_ECC */ | 1266 #endif /* NSS_ENABLE_ECC */ |
| OLD | NEW |