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