diff options
author | jsing <> | 2014-09-30 15:40:09 +0000 |
---|---|---|
committer | jsing <> | 2014-09-30 15:40:09 +0000 |
commit | 4196588ba36e0ba5fa0fcb814fd943e5e3e60b62 (patch) | |
tree | d873b0b07130bc5a612941a794bb70a5fe3fa790 /src/lib/libssl/s3_lib.c | |
parent | 1941d182bb9d2e71dc7619fd201822ed48b85d33 (diff) | |
download | openbsd-4196588ba36e0ba5fa0fcb814fd943e5e3e60b62.tar.gz openbsd-4196588ba36e0ba5fa0fcb814fd943e5e3e60b62.tar.bz2 openbsd-4196588ba36e0ba5fa0fcb814fd943e5e3e60b62.zip |
Clean up EC cipher handling in ssl3_choose_cipher().
The existing code reaches around into various internals of EC, which it
should not know anything about. Replace this with a set of functions that
that can correctly extract the necessary details and handle the
comparisions.
Based on a commit to OpenSSL, with some inspiration from boringssl.
ok miod@
Diffstat (limited to 'src/lib/libssl/s3_lib.c')
-rw-r--r-- | src/lib/libssl/s3_lib.c | 157 |
1 files changed, 16 insertions, 141 deletions
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c index d8b923afd4..246aa6f23d 100644 --- a/src/lib/libssl/s3_lib.c +++ b/src/lib/libssl/s3_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: s3_lib.c,v 1.80 2014/09/07 12:16:23 jsing Exp $ */ | 1 | /* $OpenBSD: s3_lib.c,v 1.81 2014/09/30 15:40:09 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -149,11 +149,12 @@ | |||
149 | */ | 149 | */ |
150 | 150 | ||
151 | #include <stdio.h> | 151 | #include <stdio.h> |
152 | |||
153 | #include <openssl/dh.h> | ||
154 | #include <openssl/md5.h> | ||
152 | #include <openssl/objects.h> | 155 | #include <openssl/objects.h> |
156 | |||
153 | #include "ssl_locl.h" | 157 | #include "ssl_locl.h" |
154 | #include "../crypto/ec/ec_lcl.h" | ||
155 | #include <openssl/md5.h> | ||
156 | #include <openssl/dh.h> | ||
157 | 158 | ||
158 | #define SSL3_NUM_CIPHERS (sizeof(ssl3_ciphers) / sizeof(SSL_CIPHER)) | 159 | #define SSL3_NUM_CIPHERS (sizeof(ssl3_ciphers) / sizeof(SSL_CIPHER)) |
159 | 160 | ||
@@ -2394,14 +2395,11 @@ ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void)) | |||
2394 | SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, | 2395 | SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, |
2395 | STACK_OF(SSL_CIPHER) *srvr) | 2396 | STACK_OF(SSL_CIPHER) *srvr) |
2396 | { | 2397 | { |
2397 | SSL_CIPHER *c, *ret = NULL; | ||
2398 | STACK_OF(SSL_CIPHER) *prio, *allow; | ||
2399 | int i, ii, ok; | ||
2400 | unsigned int j; | ||
2401 | int ec_ok, ec_nid; | ||
2402 | unsigned char ec_search1 = 0, ec_search2 = 0; | ||
2403 | CERT *cert; | ||
2404 | unsigned long alg_k, alg_a, mask_k, mask_a; | 2398 | unsigned long alg_k, alg_a, mask_k, mask_a; |
2399 | STACK_OF(SSL_CIPHER) *prio, *allow; | ||
2400 | SSL_CIPHER *c, *ret = NULL; | ||
2401 | int i, ii, ok; | ||
2402 | CERT *cert; | ||
2405 | 2403 | ||
2406 | /* Let's see which ciphers we can support */ | 2404 | /* Let's see which ciphers we can support */ |
2407 | cert = s->cert; | 2405 | cert = s->cert; |
@@ -2439,141 +2437,18 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, | |||
2439 | 2437 | ||
2440 | ok = (alg_k & mask_k) && (alg_a & mask_a); | 2438 | ok = (alg_k & mask_k) && (alg_a & mask_a); |
2441 | 2439 | ||
2442 | if ( | ||
2443 | /* | ||
2444 | * if we are considering an ECC cipher suite that uses our | ||
2445 | * certificate | ||
2446 | */ | ||
2447 | (alg_a & SSL_aECDSA || alg_a & SSL_aECDH) | ||
2448 | /* and we have an ECC certificate */ | ||
2449 | && (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL) | ||
2450 | /* | ||
2451 | * and the client specified a Supported Point Formats | ||
2452 | * extension | ||
2453 | */ | ||
2454 | && ((s->session->tlsext_ecpointformatlist_length > 0) && | ||
2455 | (s->session->tlsext_ecpointformatlist != NULL)) | ||
2456 | /* and our certificate's point is compressed */ | ||
2457 | && ( | ||
2458 | (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info != NULL) | ||
2459 | && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key != NULL) | ||
2460 | && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key != NULL) | ||
2461 | && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data != NULL) | ||
2462 | && ( | ||
2463 | (*(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data) == POINT_CONVERSION_COMPRESSED) | ||
2464 | || (*(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data) == POINT_CONVERSION_COMPRESSED + 1) | ||
2465 | ) | ||
2466 | ) | ||
2467 | ) { | ||
2468 | ec_ok = 0; | ||
2469 | /* | ||
2470 | * If our certificate's curve is over a field type | ||
2471 | * that the client does not support then do not allow | ||
2472 | * this cipher suite to be negotiated | ||
2473 | */ | ||
2474 | if ( | ||
2475 | (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL) | ||
2476 | && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group != NULL) | ||
2477 | && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth != NULL) | ||
2478 | && (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_prime_field) | ||
2479 | ) { | ||
2480 | for (j = 0; j < s->session->tlsext_ecpointformatlist_length; j++) { | ||
2481 | if (s->session->tlsext_ecpointformatlist[j] == TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime) { | ||
2482 | ec_ok = 1; | ||
2483 | break; | ||
2484 | } | ||
2485 | } | ||
2486 | } else if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_characteristic_two_field) { | ||
2487 | for (j = 0; j < s->session->tlsext_ecpointformatlist_length; j++) { | ||
2488 | if (s->session->tlsext_ecpointformatlist[j] == TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2) { | ||
2489 | ec_ok = 1; | ||
2490 | break; | ||
2491 | } | ||
2492 | } | ||
2493 | } | ||
2494 | ok = ok && ec_ok; | ||
2495 | } | ||
2496 | if ( | ||
2497 | /* | 2440 | /* |
2498 | * If we are considering an ECC cipher suite that uses our | 2441 | * If we are considering an ECC cipher suite that uses our |
2499 | * certificate | 2442 | * certificate check it. |
2500 | */ | 2443 | */ |
2501 | (alg_a & SSL_aECDSA || alg_a & SSL_aECDH) | 2444 | if (alg_a & (SSL_aECDSA|SSL_aECDH)) |
2502 | /* and we have an ECC certificate */ | 2445 | ok = ok && tls1_check_ec_server_key(s); |
2503 | && (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL) | ||
2504 | /* and the client specified an EllipticCurves extension */ | ||
2505 | && ((s->session->tlsext_ellipticcurvelist_length > 0) && (s->session->tlsext_ellipticcurvelist != NULL)) | ||
2506 | ) { | ||
2507 | ec_ok = 0; | ||
2508 | if ( | ||
2509 | (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL) | ||
2510 | && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group != NULL) | ||
2511 | ) { | ||
2512 | ec_nid = EC_GROUP_get_curve_name(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group); | ||
2513 | if ((ec_nid == 0) | ||
2514 | && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth != NULL) | ||
2515 | ) { | ||
2516 | if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_prime_field) { | ||
2517 | ec_search1 = 0xFF; | ||
2518 | ec_search2 = 0x01; | ||
2519 | } else if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_characteristic_two_field) { | ||
2520 | ec_search1 = 0xFF; | ||
2521 | ec_search2 = 0x02; | ||
2522 | } | ||
2523 | } else { | ||
2524 | ec_search1 = 0x00; | ||
2525 | ec_search2 = tls1_ec_nid2curve_id(ec_nid); | ||
2526 | } | ||
2527 | if ((ec_search1 != 0) || (ec_search2 != 0)) { | ||
2528 | for (j = 0; j < s->session->tlsext_ellipticcurvelist_length / 2; j++) { | ||
2529 | if ((s->session->tlsext_ellipticcurvelist[2*j] == ec_search1) && (s->session->tlsext_ellipticcurvelist[2*j + 1] == ec_search2)) { | ||
2530 | ec_ok = 1; | ||
2531 | break; | ||
2532 | } | ||
2533 | } | ||
2534 | } | ||
2535 | } | ||
2536 | ok = ok && ec_ok; | ||
2537 | } | ||
2538 | if ( | ||
2539 | /* | 2446 | /* |
2540 | * if we are considering an ECC cipher suite that uses an | 2447 | * If we are considering an ECC cipher suite that uses |
2541 | * ephemeral EC key | 2448 | * an ephemeral EC key check it. |
2542 | */ | 2449 | */ |
2543 | (alg_k & SSL_kECDHE) | 2450 | if (alg_k & SSL_kECDHE) |
2544 | /* and we have an ephemeral EC key */ | 2451 | ok = ok && tls1_check_ec_tmp_key(s); |
2545 | && (s->cert->ecdh_tmp != NULL) | ||
2546 | /* and the client specified an EllipticCurves extension */ | ||
2547 | && ((s->session->tlsext_ellipticcurvelist_length > 0) && (s->session->tlsext_ellipticcurvelist != NULL)) | ||
2548 | ) { | ||
2549 | ec_ok = 0; | ||
2550 | if (s->cert->ecdh_tmp->group != NULL) { | ||
2551 | ec_nid = EC_GROUP_get_curve_name(s->cert->ecdh_tmp->group); | ||
2552 | if ((ec_nid == 0) | ||
2553 | && (s->cert->ecdh_tmp->group->meth != NULL) | ||
2554 | ) { | ||
2555 | if (EC_METHOD_get_field_type(s->cert->ecdh_tmp->group->meth) == NID_X9_62_prime_field) { | ||
2556 | ec_search1 = 0xFF; | ||
2557 | ec_search2 = 0x01; | ||
2558 | } else if (EC_METHOD_get_field_type(s->cert->ecdh_tmp->group->meth) == NID_X9_62_characteristic_two_field) { | ||
2559 | ec_search1 = 0xFF; | ||
2560 | ec_search2 = 0x02; | ||
2561 | } | ||
2562 | } else { | ||
2563 | ec_search1 = 0x00; | ||
2564 | ec_search2 = tls1_ec_nid2curve_id(ec_nid); | ||
2565 | } | ||
2566 | if ((ec_search1 != 0) || (ec_search2 != 0)) { | ||
2567 | for (j = 0; j < s->session->tlsext_ellipticcurvelist_length / 2; j++) { | ||
2568 | if ((s->session->tlsext_ellipticcurvelist[2*j] == ec_search1) && (s->session->tlsext_ellipticcurvelist[2*j + 1] == ec_search2)) { | ||
2569 | ec_ok = 1; | ||
2570 | break; | ||
2571 | } | ||
2572 | } | ||
2573 | } | ||
2574 | } | ||
2575 | ok = ok && ec_ok; | ||
2576 | } | ||
2577 | 2452 | ||
2578 | if (!ok) | 2453 | if (!ok) |
2579 | continue; | 2454 | continue; |