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) {
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)