From: Matt Caswell Date: Wed, 6 Jul 2016 09:22:51 +0000 (+0100) Subject: Split out DHE from process CKE code X-Git-Tag: OpenSSL_1_1_0-pre6~190 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=642360f9a370219f53f89260078fc0ce046a322d;p=oweals%2Fopenssl.git 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: Richard Levitte --- diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 51ec2a7186..d2c4ed3cea 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -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)) {