Commit 642360f9 authored by Matt Caswell's avatar Matt Caswell
Browse files

Split out DHE from process CKE code



Continuing from the previous commit, this splits out the DHE code into
a separate function from the process CKE code.

Reviewed-by: default avatarRichard Levitte <levitte@openssl.org>
parent 0907d710
Loading
Loading
Loading
Loading
+80 −73
Original line number Diff line number Diff line
@@ -2253,51 +2253,22 @@ static int tls_process_cke_rsa(SSL *s, PACKET *pkt, int *al)
#endif
}

MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
static int tls_process_cke_dhe(SSL *s, PACKET *pkt, int *al)
{
    int al = -1;
    unsigned long alg_k;

    alg_k = s->s3->tmp.new_cipher->algorithm_mkey;

    /* For PSK parse and retrieve identity, obtain PSK key */
    if ((alg_k & SSL_PSK) && !tls_process_cke_psk_preamble(s, pkt, &al))
        goto err;

    if (alg_k & SSL_kPSK) {
        /* Identity extracted earlier: should be nothing left */
        if (PACKET_remaining(pkt) != 0) {
            al = SSL_AD_HANDSHAKE_FAILURE;
            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
            goto f_err;
        }
        /* PSK handled by ssl_generate_master_secret */
        if (!ssl_generate_master_secret(s, NULL, 0, 0)) {
            al = SSL_AD_INTERNAL_ERROR;
            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
            goto f_err;
        }
    } 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;
    int ret = 0;

    if (!PACKET_get_net_2(pkt, &i)) {
            if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
                al = SSL_AD_HANDSHAKE_FAILURE;
        *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;
        goto err;
    }
    if (PACKET_remaining(pkt) != i) {
        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
@@ -2306,29 +2277,28 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
    }
    skey = s->s3->tmp.pkey;
    if (skey == NULL) {
            al = SSL_AD_HANDSHAKE_FAILURE;
        *al = SSL_AD_HANDSHAKE_FAILURE;
        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
               SSL_R_MISSING_TMP_DH_KEY);
            goto f_err;
        goto err;
    }

    if (PACKET_remaining(pkt) == 0L) {
            al = SSL_AD_HANDSHAKE_FAILURE;
        *al = SSL_AD_HANDSHAKE_FAILURE;
        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
               SSL_R_MISSING_TMP_DH_KEY);
            goto f_err;
        goto err;
    }
    if (!PACKET_get_bytes(pkt, &data, i)) {
        /* We already checked we have enough data */
            al = SSL_AD_INTERNAL_ERROR;
        *al = SSL_AD_INTERNAL_ERROR;
        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
               ERR_R_INTERNAL_ERROR);
            goto f_err;
        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);
            EVP_PKEY_free(ckey);
        goto err;
    }
    cdh = EVP_PKEY_get0_DH(ckey);
@@ -2338,23 +2308,60 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
        if (pub_key != NULL)
            BN_free(pub_key);
            EVP_PKEY_free(ckey);
        goto err;
    }

    if (ssl_derive(s, skey, ckey) == 0) {
            al = SSL_AD_INTERNAL_ERROR;
        *al = SSL_AD_INTERNAL_ERROR;
        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
            EVP_PKEY_free(ckey);
            goto f_err;
        goto err;
    }

        EVP_PKEY_free(ckey);
    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;
    unsigned long alg_k;

    alg_k = s->s3->tmp.new_cipher->algorithm_mkey;

    /* For PSK parse and retrieve identity, obtain PSK key */
    if ((alg_k & SSL_PSK) && !tls_process_cke_psk_preamble(s, pkt, &al))
        goto err;

    if (alg_k & SSL_kPSK) {
        /* Identity extracted earlier: should be nothing left */
        if (PACKET_remaining(pkt) != 0) {
            al = SSL_AD_HANDSHAKE_FAILURE;
            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
            goto f_err;
        }
        /* PSK handled by ssl_generate_master_secret */
        if (!ssl_generate_master_secret(s, NULL, 0, 0)) {
            al = SSL_AD_INTERNAL_ERROR;
            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
            goto f_err;
        }
    } else if (alg_k & (SSL_kRSA | SSL_kRSAPSK)) {
        if (!tls_process_cke_rsa(s, pkt, &al))
            goto err;
    } else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
        if (!tls_process_cke_dhe(s, pkt, &al))
            goto err;
    } else
#endif

#ifndef OPENSSL_NO_EC
    if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) {