From 0aeddcfa61250a6c474c4f8b3533772a63192f1b Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 6 Apr 2016 17:49:48 +0100 Subject: Make DH opaque Move the dh_st structure into an internal header file and provide relevant accessors for the internal fields. Reviewed-by: Richard Levitte --- ssl/statem/statem_clnt.c | 42 ++++++++++++++++++++++++++++++++---------- ssl/statem/statem_srvr.c | 15 +++++++++------ ssl/t1_lib.c | 15 +++++++++------ 3 files changed, 50 insertions(+), 22 deletions(-) (limited to 'ssl') diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index fe1cde69e1..5b53b8605d 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -1527,6 +1527,7 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) PACKET prime, generator, pub_key; DH *dh; + BIGNUM *p, *g, *bnpub_key; if (!PACKET_get_length_prefixed_2(pkt, &prime) || !PACKET_get_length_prefixed_2(pkt, &generator) @@ -1550,22 +1551,41 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) goto err; } - if ((dh->p = BN_bin2bn(PACKET_data(&prime), - PACKET_remaining(&prime), NULL)) == NULL - || (dh->g = BN_bin2bn(PACKET_data(&generator), - PACKET_remaining(&generator), NULL)) == NULL - || (dh->pub_key = - BN_bin2bn(PACKET_data(&pub_key), - PACKET_remaining(&pub_key), NULL)) == NULL) { + p = BN_bin2bn(PACKET_data(&prime), PACKET_remaining(&prime), NULL); + g = BN_bin2bn(PACKET_data(&generator), PACKET_remaining(&generator), + NULL); + bnpub_key = BN_bin2bn(PACKET_data(&pub_key), PACKET_remaining(&pub_key), + NULL); + if (p == NULL || g == NULL || bnpub_key == NULL) { SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_BN_LIB); + BN_free(p); + BN_free(g); + BN_free(bnpub_key); goto err; } - if (BN_is_zero(dh->p) || BN_is_zero(dh->g) || BN_is_zero(dh->pub_key)) { + if (BN_is_zero(p) || BN_is_zero(g) || BN_is_zero(bnpub_key)) { SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_BAD_DH_VALUE); + BN_free(p); + BN_free(g); + BN_free(bnpub_key); goto f_err; } + if (!DH_set0_pqg(dh, p, NULL, g)) { + SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_BN_LIB); + BN_free(p); + BN_free(g); + BN_free(bnpub_key); + goto err; + } + + if (!DH_set0_key(dh, bnpub_key, NULL)) { + SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_BN_LIB); + BN_free(bnpub_key); + goto err; + } + if (!ssl_security(s, SSL_SECOP_TMP_DH, DH_security_bits(dh), 0, dh)) { al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_DH_KEY_TOO_SMALL); @@ -2254,6 +2274,7 @@ psk_err: #ifndef OPENSSL_NO_DH else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) { DH *dh_clnt = NULL; + BIGNUM *pub_key; skey = s->s3->peer_tmp; if (skey == NULL) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, @@ -2271,9 +2292,10 @@ psk_err: /* send off the data */ - n = BN_num_bytes(dh_clnt->pub_key); + DH_get0_key(dh_clnt, &pub_key, NULL); + n = BN_num_bytes(pub_key); s2n(n, p); - BN_bn2bin(dh_clnt->pub_key, p); + BN_bn2bin(pub_key, p); n += 2; EVP_PKEY_free(ckey); ckey = NULL; diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 23e790356c..38fa9455ff 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -1772,9 +1772,8 @@ int tls_construct_server_key_exchange(SSL *s) EVP_PKEY_free(pkdh); pkdh = NULL; - r[0] = dh->p; - r[1] = dh->g; - r[2] = dh->pub_key; + DH_get0_pqg(dh, &r[0], NULL, &r[1]); + DH_get0_key(dh, &r[2], NULL); } else #endif #ifndef OPENSSL_NO_EC @@ -2301,6 +2300,7 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) EVP_PKEY *skey = NULL; DH *cdh; unsigned int i; + BIGNUM *pub_key; if (!PACKET_get_net_2(pkt, &i)) { if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) { @@ -2343,9 +2343,12 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) goto err; } cdh = EVP_PKEY_get0_DH(ckey); - cdh->pub_key = BN_bin2bn(data, i, NULL); - if (cdh->pub_key == NULL) { - SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_BN_LIB); + 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; } diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 6e7b5edbc4..a4cd23ab39 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -4091,17 +4091,20 @@ DH *ssl_get_auto_dh(SSL *s) if (dh_secbits >= 128) { DH *dhp = DH_new(); + BIGNUM *p, *g; if (dhp == NULL) return NULL; - dhp->g = BN_new(); - if (dhp->g != NULL) - BN_set_word(dhp->g, 2); + g = BN_new(); + if (g != NULL) + BN_set_word(g, 2); if (dh_secbits >= 192) - dhp->p = get_rfc3526_prime_8192(NULL); + p = get_rfc3526_prime_8192(NULL); else - dhp->p = get_rfc3526_prime_3072(NULL); - if (dhp->p == NULL || dhp->g == NULL) { + p = get_rfc3526_prime_3072(NULL); + if (p == NULL || g == NULL || !DH_set0_pqg(dhp, p, NULL, g)) { DH_free(dhp); + BN_free(p); + BN_free(g); return NULL; } return dhp; -- cgit v1.2.3