Split out DHE from process CKE code
authorMatt Caswell <matt@openssl.org>
Wed, 6 Jul 2016 09:22:51 +0000 (10:22 +0100)
committerMatt Caswell <matt@openssl.org>
Mon, 18 Jul 2016 21:55:07 +0000 (22:55 +0100)
Continuing from the previous commit, this splits out the DHE code into
a separate function from the process CKE code.

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

index 51ec2a7..d2c4ed3 100644 (file)
@@ -2253,6 +2253,84 @@ static int tls_process_cke_rsa(SSL *s, PACKET *pkt, int *al)
 #endif
 }
 
+static int tls_process_cke_dhe(SSL *s, PACKET *pkt, int *al)
+{
+#ifndef OPENSSL_NO_DH
+    EVP_PKEY *skey = NULL;
+    DH *cdh;
+    unsigned int i;
+    BIGNUM *pub_key;
+    const unsigned char *data;
+    EVP_PKEY *ckey = NULL;
+    int ret = 0;
+
+    if (!PACKET_get_net_2(pkt, &i)) {
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
+               SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
+        goto err;
+    }
+    if (PACKET_remaining(pkt) != i) {
+        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
+               SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
+        goto err;
+    }
+    skey = s->s3->tmp.pkey;
+    if (skey == NULL) {
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
+               SSL_R_MISSING_TMP_DH_KEY);
+        goto err;
+    }
+
+    if (PACKET_remaining(pkt) == 0L) {
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
+               SSL_R_MISSING_TMP_DH_KEY);
+        goto err;
+    }
+    if (!PACKET_get_bytes(pkt, &data, i)) {
+        /* We already checked we have enough data */
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
+               ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    ckey = EVP_PKEY_new();
+    if (ckey == NULL || EVP_PKEY_copy_parameters(ckey, skey) == 0) {
+        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_BN_LIB);
+        goto err;
+    }
+    cdh = EVP_PKEY_get0_DH(ckey);
+    pub_key = BN_bin2bn(data, i, NULL);
+
+    if (pub_key == NULL || !DH_set0_key(cdh, pub_key, NULL)) {
+        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+        if (pub_key != NULL)
+            BN_free(pub_key);
+        goto err;
+    }
+
+    if (ssl_derive(s, skey, ckey) == 0) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    ret = 1;
+    EVP_PKEY_free(s->s3->tmp.pkey);
+    s->s3->tmp.pkey = NULL;
+ err:
+    EVP_PKEY_free(ckey);
+    return ret;
+#else
+    /* Should never happen */
+    *al = SSL_AD_INTERNAL_ERROR;
+    SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+    return 0;
+#endif
+}
+
 MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
 {
     int al = -1;
@@ -2280,81 +2358,10 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
     } else if (alg_k & (SSL_kRSA | SSL_kRSAPSK)) {
         if (!tls_process_cke_rsa(s, pkt, &al))
             goto err;
-    } else
-#ifndef OPENSSL_NO_DH
-    if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
-        EVP_PKEY *skey = NULL;
-        DH *cdh;
-        unsigned int i;
-        BIGNUM *pub_key;
-        const unsigned char *data;
-        EVP_PKEY *ckey = NULL;
-
-        if (!PACKET_get_net_2(pkt, &i)) {
-            if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
-                al = SSL_AD_HANDSHAKE_FAILURE;
-                SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
-                       SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
-                goto f_err;
-            }
-            i = 0;
-        }
-        if (PACKET_remaining(pkt) != i) {
-            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
-                   SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
-            goto err;
-        }
-        skey = s->s3->tmp.pkey;
-        if (skey == NULL) {
-            al = SSL_AD_HANDSHAKE_FAILURE;
-            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
-                   SSL_R_MISSING_TMP_DH_KEY);
-            goto f_err;
-        }
-
-        if (PACKET_remaining(pkt) == 0L) {
-            al = SSL_AD_HANDSHAKE_FAILURE;
-            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
-                   SSL_R_MISSING_TMP_DH_KEY);
-            goto f_err;
-        }
-        if (!PACKET_get_bytes(pkt, &data, i)) {
-            /* We already checked we have enough data */
-            al = SSL_AD_INTERNAL_ERROR;
-            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
-                   ERR_R_INTERNAL_ERROR);
-            goto f_err;
-        }
-        ckey = EVP_PKEY_new();
-        if (ckey == NULL || EVP_PKEY_copy_parameters(ckey, skey) == 0) {
-            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_BN_LIB);
-            EVP_PKEY_free(ckey);
-            goto err;
-        }
-        cdh = EVP_PKEY_get0_DH(ckey);
-        pub_key = BN_bin2bn(data, i, NULL);
-
-        if (pub_key == NULL || !DH_set0_key(cdh, pub_key, NULL)) {
-            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
-            if (pub_key != NULL)
-                BN_free(pub_key);
-            EVP_PKEY_free(ckey);
+    } else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
+        if (!tls_process_cke_dhe(s, pkt, &al))
             goto err;
-        }
-
-        if (ssl_derive(s, skey, ckey) == 0) {
-            al = SSL_AD_INTERNAL_ERROR;
-            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
-            EVP_PKEY_free(ckey);
-            goto f_err;
-        }
-
-        EVP_PKEY_free(ckey);
-        EVP_PKEY_free(s->s3->tmp.pkey);
-        s->s3->tmp.pkey = NULL;
-
     } else
-#endif
 
 #ifndef OPENSSL_NO_EC
     if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) {