summaryrefslogtreecommitdiff
path: root/src/lib/libssl/s3_lib.c
diff options
context:
space:
mode:
authorjsing <>2014-09-30 15:40:09 +0000
committerjsing <>2014-09-30 15:40:09 +0000
commit4196588ba36e0ba5fa0fcb814fd943e5e3e60b62 (patch)
treed873b0b07130bc5a612941a794bb70a5fe3fa790 /src/lib/libssl/s3_lib.c
parent1941d182bb9d2e71dc7619fd201822ed48b85d33 (diff)
downloadopenbsd-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.c157
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))
2394SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, 2395SSL_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;