From: Matt Caswell Date: Wed, 14 Oct 2020 15:01:56 +0000 (+0100) Subject: Avoid the use of a DH object in tls_construct_cke_dhe() X-Git-Tag: openssl-3.0.0-alpha9~84 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cb5a427acf0617798099321032421d1242930402;p=thirdparty%2Fopenssl.git Avoid the use of a DH object in tls_construct_cke_dhe() There is no need for us to downgrade the EVP_PKEY into a DH object for this function so we rewrite things to avoid it. Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/13368) --- diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index d0c99a176e1..5b7b7cd5f5e 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -2893,11 +2893,12 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt) static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt) { -#ifndef OPENSSL_NO_DH - DH *dh_clnt = NULL; EVP_PKEY *ckey = NULL, *skey = NULL; unsigned char *keybytes = NULL; int prime_len; + unsigned char *encoded_pub = NULL; + size_t encoded_pub_len, pad_len; + int ret = 0; skey = s->s3.peer_tmp; if (skey == NULL) { @@ -2911,41 +2912,46 @@ static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt) goto err; } - dh_clnt = EVP_PKEY_get0_DH(ckey); - - if (dh_clnt == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - if (ssl_derive(s, ckey, skey, 0) == 0) { /* SSLfatal() already called */ goto err; } /* send off the data */ - prime_len = BN_num_bytes(DH_get0_p(dh_clnt)); + + /* Generate encoding of server key */ + encoded_pub_len = EVP_PKEY_get1_encoded_public_key(ckey, &encoded_pub); + if (encoded_pub_len == 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + EVP_PKEY_free(skey); + return EXT_RETURN_FAIL; + } + /* * For interoperability with some versions of the Microsoft TLS * stack, we need to zero pad the DHE pub key to the same length - * as the prime, so use the length of the prime here. + * as the prime. */ - if (!WPACKET_sub_allocate_bytes_u16(pkt, prime_len, &keybytes) - || BN_bn2binpad(DH_get0_pub_key(dh_clnt), keybytes, prime_len) < 0) { + prime_len = EVP_PKEY_size(ckey); + pad_len = prime_len - encoded_pub_len; + if (pad_len > 0) { + if (!WPACKET_sub_allocate_bytes_u16(pkt, pad_len, &keybytes)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + memset(keybytes, 0, pad_len); + } + + if (!WPACKET_sub_memcpy_u16(pkt, encoded_pub, encoded_pub_len)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - EVP_PKEY_free(ckey); - - return 1; + ret = 1; err: + OPENSSL_free(encoded_pub); EVP_PKEY_free(ckey); - return 0; -#else - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; -#endif + return ret; } static int tls_construct_cke_ecdhe(SSL *s, WPACKET *pkt)