diff options
author | Matt Caswell <matt@openssl.org> | 2016-07-06 10:22:51 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2016-07-18 22:55:07 +0100 |
commit | 642360f9a370219f53f89260078fc0ce046a322d (patch) | |
tree | 4a6f714d1982094c67dbe709fd0251ba7cbf5782 /ssl | |
parent | 0907d7105cbf8d72b267f4453f96dd636fa59621 (diff) |
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 <levitte@openssl.org>
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/statem/statem_srvr.c | 153 |
1 files changed, 80 insertions, 73 deletions
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)) { |