Avoid the use of a DH object in tls_construct_cke_dhe()
[openssl.git] / ssl / statem / statem_clnt.c
index d0c99a176e1bc51ba9f348b9c67b0b9a78ba3f26..5b7b7cd5f5e190a9c4100dec0f8f999069e68444 100644 (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)
 {
-#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)