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 <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13368)
This commit is contained in:
Matt Caswell 2020-10-14 16:01:56 +01:00
parent 1b2b475517
commit cb5a427acf

View File

@ -2893,11 +2893,12 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt)
static int tls_construct_cke_dhe(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; EVP_PKEY *ckey = NULL, *skey = NULL;
unsigned char *keybytes = NULL; unsigned char *keybytes = NULL;
int prime_len; int prime_len;
unsigned char *encoded_pub = NULL;
size_t encoded_pub_len, pad_len;
int ret = 0;
skey = s->s3.peer_tmp; skey = s->s3.peer_tmp;
if (skey == NULL) { if (skey == NULL) {
@ -2911,41 +2912,46 @@ static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt)
goto err; 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) { if (ssl_derive(s, ckey, skey, 0) == 0) {
/* SSLfatal() already called */ /* SSLfatal() already called */
goto err; goto err;
} }
/* send off the data */ /* 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 * For interoperability with some versions of the Microsoft TLS
* stack, we need to zero pad the DHE pub key to the same length * 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) prime_len = EVP_PKEY_size(ckey);
|| BN_bn2binpad(DH_get0_pub_key(dh_clnt), keybytes, prime_len) < 0) { 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); SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err; goto err;
} }
EVP_PKEY_free(ckey); ret = 1;
return 1;
err: err:
OPENSSL_free(encoded_pub);
EVP_PKEY_free(ckey); EVP_PKEY_free(ckey);
return 0; return ret;
#else
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
#endif
} }
static int tls_construct_cke_ecdhe(SSL *s, WPACKET *pkt) static int tls_construct_cke_ecdhe(SSL *s, WPACKET *pkt)