also zero pad DHE public key in ClientKeyExchange message for interop
@@ -3069,9 +3069,9 @@ static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt)
{
#ifndef OPENSSL_NO_DH
DH *dh_clnt = NULL;
- const BIGNUM *pub_key;
EVP_PKEY *ckey = NULL, *skey = NULL;
unsigned char *keybytes = NULL;
+ int prime_len;
skey = s->s3.peer_tmp;
if (skey == NULL) {
@@ -3101,15 +3101,19 @@ static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt)
}
/* send off the data */
- DH_get0_key(dh_clnt, &pub_key, NULL);
- if (!WPACKET_sub_allocate_bytes_u16(pkt, BN_num_bytes(pub_key),
- &keybytes)) {
+ prime_len = BN_num_bytes(DH_get0_p(dh_clnt));
+ /*
+ * 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.
+ */
+ if (!WPACKET_sub_allocate_bytes_u16(pkt, prime_len, &keybytes)
+ || BN_bn2binpad(DH_get0_pub_key(dh_clnt), keybytes, prime_len) < 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_DHE,
ERR_R_INTERNAL_ERROR);
goto err;
}
- BN_bn2bin(pub_key, keybytes);
EVP_PKEY_free(ckey);
return 1;
