From 3f7702534a377e0a3b33a6681df0af8a57adbc57 Mon Sep 17 00:00:00 2001 From: jsing <> Date: Fri, 7 Jan 2022 15:46:30 +0000 Subject: Convert legacy server to tls_key_share. This requires a few more additions to the DHE key share code - we need to be able to either set the DHE parameters or specify the number of key bits for use with auto DHE parameters. Additionally, we need to be able to serialise the DHE parameters to send to the client. This removes the infamous 'tmp' struct from ssl3_state_internal_st. ok inoguchi@ tb@ --- src/lib/libssl/ssl_srvr.c | 242 ++++++++-------------------------------------- 1 file changed, 40 insertions(+), 202 deletions(-) (limited to 'src/lib/libssl/ssl_srvr.c') diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c index 0496985351..b66a2c108d 100644 --- a/src/lib/libssl/ssl_srvr.c +++ b/src/lib/libssl/ssl_srvr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_srvr.c,v 1.130 2022/01/04 12:53:31 jsing Exp $ */ +/* $OpenBSD: ssl_srvr.c,v 1.131 2022/01/07 15:46:30 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1309,23 +1309,23 @@ ssl3_send_server_done(SSL *s) static int ssl3_send_server_kex_dhe(SSL *s, CBB *cbb) { - DH *dh = NULL; - int al; + int nid = NID_dhKeyAgreement; - if ((dh = DH_new()) == NULL) + tls_key_share_free(S3I(s)->hs.key_share); + if ((S3I(s)->hs.key_share = tls_key_share_new_nid(nid)) == NULL) goto err; if (s->cert->dh_tmp_auto != 0) { size_t key_bits; if ((key_bits = ssl_dhe_params_auto_key_bits(s)) == 0) { - al = SSL_AD_INTERNAL_ERROR; SSLerror(s, ERR_R_INTERNAL_ERROR); - goto fatal_err; - } - - if (!ssl_kex_generate_dhe_params_auto(dh, key_bits)) + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_INTERNAL_ERROR); goto err; + } + tls_key_share_set_key_bits(S3I(s)->hs.key_share, + key_bits); } else { DH *dh_params = s->cert->dh_tmp; @@ -1334,157 +1334,69 @@ ssl3_send_server_kex_dhe(SSL *s, CBB *cbb) SSL_C_PKEYLENGTH(S3I(s)->hs.cipher)); if (dh_params == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; SSLerror(s, SSL_R_MISSING_TMP_DH_KEY); - goto fatal_err; + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_HANDSHAKE_FAILURE); + goto err; } - if (!ssl_kex_generate_dhe(dh, dh_params)) + if (!tls_key_share_set_dh_params(S3I(s)->hs.key_share, dh_params)) goto err; } - if (!ssl_kex_params_dhe(dh, cbb)) - goto err; - if (!ssl_kex_public_dhe(dh, cbb)) + if (!tls_key_share_generate(S3I(s)->hs.key_share)) goto err; - if (S3I(s)->tmp.dh != NULL) { - SSLerror(s, ERR_R_INTERNAL_ERROR); + if (!tls_key_share_params(S3I(s)->hs.key_share, cbb)) + goto err; + if (!tls_key_share_public(S3I(s)->hs.key_share, cbb)) goto err; - } - S3I(s)->tmp.dh = dh; return 1; - fatal_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); err: - DH_free(dh); - return 0; } static int -ssl3_send_server_kex_ecdhe_ecp(SSL *s, int nid, CBB *cbb) +ssl3_send_server_kex_ecdhe(SSL *s, CBB *cbb) { - uint16_t curve_id; - EC_KEY *ecdh; - CBB ecpoint; - int al; + CBB public; + int nid; - /* - * Only named curves are supported in ECDH ephemeral key exchanges. - * For supported named curves, curve_id is non-zero. - */ - if ((curve_id = tls1_ec_nid2curve_id(nid)) == 0) { + if ((nid = tls1_get_shared_curve(s)) == NID_undef) { SSLerror(s, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); goto err; } - if (S3I(s)->tmp.ecdh != NULL) { - SSLerror(s, ERR_R_INTERNAL_ERROR); + tls_key_share_free(S3I(s)->hs.key_share); + if ((S3I(s)->hs.key_share = tls_key_share_new_nid(nid)) == NULL) goto err; - } - if ((S3I(s)->tmp.ecdh = EC_KEY_new()) == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerror(s, SSL_R_MISSING_TMP_ECDH_KEY); - goto fatal_err; - } - S3I(s)->tmp.ecdh_nid = nid; - ecdh = S3I(s)->tmp.ecdh; - - if (!ssl_kex_generate_ecdhe_ecp(ecdh, nid)) + if (!tls_key_share_generate(S3I(s)->hs.key_share)) goto err; /* - * Encode the public key. - * - * Only named curves are supported in ECDH ephemeral key exchanges. - * In this case the ServerKeyExchange message has: - * [1 byte CurveType], [2 byte CurveName] - * [1 byte length of encoded point], followed by - * the actual encoded point itself. + * ECC key exchange - see RFC 8422, section 5.4. */ if (!CBB_add_u8(cbb, NAMED_CURVE_TYPE)) goto err; - if (!CBB_add_u16(cbb, curve_id)) + if (!CBB_add_u16(cbb, tls_key_share_group(S3I(s)->hs.key_share))) goto err; - if (!CBB_add_u8_length_prefixed(cbb, &ecpoint)) + if (!CBB_add_u8_length_prefixed(cbb, &public)) goto err; - if (!ssl_kex_public_ecdhe_ecp(ecdh, &ecpoint)) + if (!tls_key_share_public(S3I(s)->hs.key_share, &public)) goto err; if (!CBB_flush(cbb)) goto err; return 1; - fatal_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); err: return 0; } -static int -ssl3_send_server_kex_ecdhe_ecx(SSL *s, int nid, CBB *cbb) -{ - uint8_t *public_key = NULL, *private_key = NULL; - uint16_t curve_id; - CBB ecpoint; - int ret = 0; - - /* Generate an X25519 key pair. */ - if (S3I(s)->tmp.x25519 != NULL) { - SSLerror(s, ERR_R_INTERNAL_ERROR); - goto err; - } - if ((private_key = malloc(X25519_KEY_LENGTH)) == NULL) - goto err; - if ((public_key = malloc(X25519_KEY_LENGTH)) == NULL) - goto err; - X25519_keypair(public_key, private_key); - - /* Serialize public key. */ - if ((curve_id = tls1_ec_nid2curve_id(nid)) == 0) { - SSLerror(s, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); - goto err; - } - - if (!CBB_add_u8(cbb, NAMED_CURVE_TYPE)) - goto err; - if (!CBB_add_u16(cbb, curve_id)) - goto err; - if (!CBB_add_u8_length_prefixed(cbb, &ecpoint)) - goto err; - if (!CBB_add_bytes(&ecpoint, public_key, X25519_KEY_LENGTH)) - goto err; - if (!CBB_flush(cbb)) - goto err; - - S3I(s)->tmp.x25519 = private_key; - private_key = NULL; - ret = 1; - - err: - free(public_key); - freezero(private_key, X25519_KEY_LENGTH); - - return ret; -} - -static int -ssl3_send_server_kex_ecdhe(SSL *s, CBB *cbb) -{ - int nid; - - nid = tls1_get_shared_curve(s); - - if (nid == NID_X25519) - return ssl3_send_server_kex_ecdhe_ecx(s, nid, cbb); - - return ssl3_send_server_kex_ecdhe_ecp(s, nid, cbb); -} - int ssl3_send_server_key_exchange(SSL *s) { @@ -1791,147 +1703,73 @@ ssl3_get_client_kex_rsa(SSL *s, CBS *cbs) static int ssl3_get_client_kex_dhe(SSL *s, CBS *cbs) { - DH *dh_clnt = NULL; - DH *dh_srvr; - int invalid_key; uint8_t *key = NULL; size_t key_len = 0; + int invalid_key; int ret = 0; - if ((dh_srvr = S3I(s)->tmp.dh) == NULL) { + if (S3I(s)->hs.key_share == NULL) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); SSLerror(s, SSL_R_MISSING_TMP_DH_KEY); goto err; } - if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) - goto err; - - if (!ssl_kex_peer_public_dhe(dh_clnt, cbs, &invalid_key)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerror(s, SSL_R_BAD_PACKET_LENGTH); + if (!tls_key_share_peer_public(S3I(s)->hs.key_share, cbs, + &invalid_key)) goto err; - } if (invalid_key) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); SSLerror(s, SSL_R_BAD_DH_PUB_KEY_LENGTH); goto err; } - if (!ssl_kex_derive_dhe(dh_srvr, dh_clnt, &key, &key_len)) + if (!tls_key_share_derive(S3I(s)->hs.key_share, &key, &key_len)) goto err; if (!tls12_derive_master_secret(s, key, key_len)) goto err; - DH_free(S3I(s)->tmp.dh); - S3I(s)->tmp.dh = NULL; - ret = 1; err: freezero(key, key_len); - DH_free(dh_clnt); return ret; } static int -ssl3_get_client_kex_ecdhe_ecp(SSL *s, CBS *cbs) +ssl3_get_client_kex_ecdhe(SSL *s, CBS *cbs) { uint8_t *key = NULL; size_t key_len = 0; - EC_KEY *ecdh_peer = NULL; - EC_KEY *ecdh; CBS public; int ret = 0; - /* - * Use the ephemeral values we saved when generating the - * ServerKeyExchange message. - */ - if ((ecdh = S3I(s)->tmp.ecdh) == NULL) { - SSLerror(s, ERR_R_INTERNAL_ERROR); + if (S3I(s)->hs.key_share == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + SSLerror(s, SSL_R_MISSING_TMP_DH_KEY); goto err; } - /* - * Get client's public key from encoded point in the ClientKeyExchange - * message. - */ if (!CBS_get_u8_length_prefixed(cbs, &public)) goto err; - if (CBS_len(cbs) != 0) + if (!tls_key_share_peer_public(S3I(s)->hs.key_share, &public, NULL)) goto err; - if ((ecdh_peer = EC_KEY_new()) == NULL) + if (!tls_key_share_derive(S3I(s)->hs.key_share, &key, &key_len)) goto err; - if (!ssl_kex_peer_public_ecdhe_ecp(ecdh_peer, S3I(s)->tmp.ecdh_nid, - &public)) - goto err; - - /* Derive the shared secret and compute master secret. */ - if (!ssl_kex_derive_ecdhe_ecp(ecdh, ecdh_peer, &key, &key_len)) - goto err; if (!tls12_derive_master_secret(s, key, key_len)) goto err; - EC_KEY_free(S3I(s)->tmp.ecdh); - S3I(s)->tmp.ecdh = NULL; - S3I(s)->tmp.ecdh_nid = NID_undef; - ret = 1; err: freezero(key, key_len); - EC_KEY_free(ecdh_peer); return ret; } -static int -ssl3_get_client_kex_ecdhe_ecx(SSL *s, CBS *cbs) -{ - uint8_t *shared_key = NULL; - CBS ecpoint; - int ret = 0; - - if (!CBS_get_u8_length_prefixed(cbs, &ecpoint)) - goto err; - if (CBS_len(cbs) != 0) - goto err; - if (CBS_len(&ecpoint) != X25519_KEY_LENGTH) - goto err; - - if ((shared_key = malloc(X25519_KEY_LENGTH)) == NULL) - goto err; - if (!X25519(shared_key, S3I(s)->tmp.x25519, CBS_data(&ecpoint))) - goto err; - - freezero(S3I(s)->tmp.x25519, X25519_KEY_LENGTH); - S3I(s)->tmp.x25519 = NULL; - - if (!tls12_derive_master_secret(s, shared_key, X25519_KEY_LENGTH)) - goto err; - - ret = 1; - - err: - freezero(shared_key, X25519_KEY_LENGTH); - - return ret; -} - -static int -ssl3_get_client_kex_ecdhe(SSL *s, CBS *cbs) -{ - if (S3I(s)->tmp.x25519 != NULL) - return ssl3_get_client_kex_ecdhe_ecx(s, cbs); - - return ssl3_get_client_kex_ecdhe_ecp(s, cbs); -} - static int ssl3_get_client_kex_gost(SSL *s, CBS *cbs) { -- cgit v1.2.3-55-g6feb