From 1ee22dc26873e68b73b693ffb5d99a6e9644b45f Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 14 Oct 2020 13:41:32 +0100 Subject: Convert TLS ServerKeyExchange processing to use an EVP_PKEY Previously we were constructing a DH object and then assigning it to an EVP_PKEY. Instead we construct an EVP_PKEY directly. Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/13368) --- ssl/statem/statem_clnt.c | 72 ++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 39 deletions(-) (limited to 'ssl') diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index eb88c37c5b..d0c99a176e 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, PACKET *pkt); @@ -2010,14 +2012,13 @@ static int tls_process_ske_srp(SSL *s, PACKET *pkt, EVP_PKEY **pkey) static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) { -#ifndef OPENSSL_NO_DH PACKET prime, generator, pub_key; EVP_PKEY *peer_tmp = NULL; - - DH *dh = NULL; BIGNUM *p = NULL, *g = NULL, *bnpub_key = NULL; - - int check_bits = 0; + EVP_PKEY_CTX *pctx = NULL; + OSSL_PARAM *params = NULL; + OSSL_PARAM_BLD *tmpl = NULL; + int ret = 0; if (!PACKET_get_length_prefixed_2(pkt, &prime) || !PACKET_get_length_prefixed_2(pkt, &generator) @@ -2026,14 +2027,6 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) return 0; } - peer_tmp = EVP_PKEY_new(); - dh = DH_new(); - - if (peer_tmp == NULL || dh == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - goto err; - } - /* TODO(size_t): Convert these calls */ p = BN_bin2bn(PACKET_data(&prime), (int)PACKET_remaining(&prime), NULL); g = BN_bin2bn(PACKET_data(&generator), (int)PACKET_remaining(&generator), @@ -2045,34 +2038,36 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) goto err; } - /* test non-zero pubkey */ - if (BN_is_zero(bnpub_key)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_DH_VALUE); - goto err; - } - - if (!DH_set0_pqg(dh, p, NULL, g)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BN_LIB); + tmpl = OSSL_PARAM_BLD_new(); + if (tmpl == NULL + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p) + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g) + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY, + bnpub_key) + || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - p = g = NULL; - if (DH_check_params(dh, &check_bits) == 0 || check_bits != 0) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_DH_VALUE); + pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, "DH", s->ctx->propq); + if (pctx == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - - if (!DH_set0_key(dh, bnpub_key, NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BN_LIB); + if (EVP_PKEY_key_fromdata_init(pctx) <= 0 + || EVP_PKEY_fromdata(pctx, &peer_tmp, params) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_DH_VALUE); goto err; } - bnpub_key = NULL; - if (EVP_PKEY_assign_DH(peer_tmp, dh) == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + EVP_PKEY_CTX_free(pctx); + pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, peer_tmp, s->ctx->propq); + if (pctx == NULL + || EVP_PKEY_param_check(pctx) != 1 + || EVP_PKEY_public_check(pctx) != 1) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_DH_VALUE); goto err; } - dh = NULL; if (!ssl_security(s, SSL_SECOP_TMP_DH, EVP_PKEY_security_bits(peer_tmp), 0, peer_tmp)) { @@ -2081,6 +2076,7 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) } s->s3.peer_tmp = peer_tmp; + peer_tmp = NULL; /* * FIXME: This makes assumptions about which ciphersuites come with @@ -2090,20 +2086,18 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) *pkey = X509_get0_pubkey(s->session->peer); /* else anonymous DH, so no certificate or pkey. */ - return 1; + ret = 1; err: + OSSL_PARAM_BLD_free(tmpl); + OSSL_PARAM_BLD_free_params(params); + EVP_PKEY_free(peer_tmp); + EVP_PKEY_CTX_free(pctx); BN_free(p); BN_free(g); BN_free(bnpub_key); - DH_free(dh); - EVP_PKEY_free(peer_tmp); - return 0; -#else - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; -#endif + return ret; } static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) -- cgit v1.2.1