Split out DHE CKE construction into a separate function
authorMatt Caswell <matt@openssl.org>
Fri, 8 Jul 2016 08:42:07 +0000 (09:42 +0100)
committerMatt Caswell <matt@openssl.org>
Mon, 18 Jul 2016 22:05:14 +0000 (23:05 +0100)
Continuing previous commit to break up the
tls_construct_client_key_exchange() function. This splits out the DHE
code.

Reviewed-by: Richard Levitte <levitte@openssl.org>
ssl/statem/statem_clnt.c

index c2ecd68..b297ca1 100644 (file)
@@ -2187,6 +2187,45 @@ static int tls_construct_cke_rsa(SSL *s, unsigned char **p, int *len, int *al)
 #endif
 }
 
+static int tls_construct_cke_dhe(SSL *s, unsigned char **p, int *len, int *al)
+{
+#ifndef OPENSSL_NO_DH
+    DH *dh_clnt = NULL;
+    const BIGNUM *pub_key;
+    EVP_PKEY *ckey = NULL, *skey = NULL;
+
+    skey = s->s3->peer_tmp;
+    if (skey == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
+               ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    ckey = ssl_generate_pkey(skey, NID_undef);
+    dh_clnt = EVP_PKEY_get0_DH(ckey);
+
+    if (dh_clnt == NULL || ssl_derive(s, ckey, skey) == 0) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
+               ERR_R_INTERNAL_ERROR);
+        EVP_PKEY_free(ckey);
+        return 0;
+    }
+
+    /* send off the data */
+    DH_get0_key(dh_clnt, &pub_key, NULL);
+    *len = BN_num_bytes(pub_key);
+    s2n(*len, *p);
+    BN_bn2bin(pub_key, *p);
+    *len += 2;
+    EVP_PKEY_free(ckey);
+
+    return 1;
+#else
+    SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+    *al = SSL_AD_INTERNAL_ERROR;
+    return 0;
+#endif
+}
+
 int tls_construct_client_key_exchange(SSL *s)
 {
     unsigned char *p;
@@ -2210,41 +2249,10 @@ int tls_construct_client_key_exchange(SSL *s)
     } else if (alg_k & (SSL_kRSA | SSL_kRSAPSK)) {
         if (!tls_construct_cke_rsa(s, &p, &n, &al))
             goto err;
-    }
-#ifndef OPENSSL_NO_DH
-    else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
-        DH *dh_clnt = NULL;
-        const BIGNUM *pub_key;
-        EVP_PKEY *ckey = NULL, *skey = NULL;
-
-        skey = s->s3->peer_tmp;
-        if (skey == NULL) {
-            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
-                   ERR_R_INTERNAL_ERROR);
-            goto err;
-        }
-        ckey = ssl_generate_pkey(skey, NID_undef);
-        dh_clnt = EVP_PKEY_get0_DH(ckey);
-
-        if (dh_clnt == NULL || ssl_derive(s, ckey, skey) == 0) {
-            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
-                   ERR_R_INTERNAL_ERROR);
-            EVP_PKEY_free(ckey);
+    } else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
+        if (!tls_construct_cke_dhe(s, &p, &n, &al))
             goto err;
-        }
-
-
-        /* send off the data */
-        DH_get0_key(dh_clnt, &pub_key, NULL);
-        n = BN_num_bytes(pub_key);
-        s2n(n, p);
-        BN_bn2bin(pub_key, p);
-        n += 2;
-        EVP_PKEY_free(ckey);
-        ckey = NULL;
     }
-#endif
-
 #ifndef OPENSSL_NO_EC
     else if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) {
         unsigned char *encodedPoint = NULL;