From: Emilia Kasper Date: Tue, 19 May 2015 10:05:22 +0000 (+0200) Subject: client: reject handshakes with DH parameters < 768 bits. X-Git-Tag: OpenSSL_1_0_1n~54 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=63830384e90d9b36d2793d4891501ec024827433;p=oweals%2Fopenssl.git client: reject handshakes with DH parameters < 768 bits. Since the client has no way of communicating her supported parameter range to the server, connections to servers that choose weak DH will simply fail. Reviewed-by: Kurt Roeckx --- diff --git a/CHANGES b/CHANGES index 11bdbbd692..9d2f9f9fa8 100644 --- a/CHANGES +++ b/CHANGES @@ -4,7 +4,8 @@ Changes between 1.0.1m and 1.0.1n [xx XXX xxxx] - *) + *) Reject DH handshakes with parameters shorter than 768 bits. + [Kurt Roeckx and Emilia Kasper] Changes between 1.0.1l and 1.0.1m [19 Mar 2015] diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index a521d56fe4..780a03f1e6 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -3295,23 +3295,33 @@ int ssl3_check_cert_and_algorithm(SSL *s) } #endif #ifndef OPENSSL_NO_DH - if ((alg_k & SSL_kEDH) && - !(has_bits(i, EVP_PK_DH | EVP_PKT_EXCH) || (dh != NULL))) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_MISSING_DH_KEY); + if ((alg_k & SSL_kEDH) && dh == NULL) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); goto f_err; - } else if ((alg_k & SSL_kDHr) && !has_bits(i, EVP_PK_DH | EVP_PKS_RSA)) { + } + if ((alg_k & SSL_kDHr) && !has_bits(i, EVP_PK_DH | EVP_PKS_RSA)) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_MISSING_DH_RSA_CERT); goto f_err; } # ifndef OPENSSL_NO_DSA - else if ((alg_k & SSL_kDHd) && !has_bits(i, EVP_PK_DH | EVP_PKS_DSA)) { + if ((alg_k & SSL_kDHd) && !has_bits(i, EVP_PK_DH | EVP_PKS_DSA)) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_MISSING_DH_DSA_CERT); goto f_err; } # endif -#endif + + /* Check DHE only: static DH not implemented. */ + if (alg_k & SSL_kEDH) { + int dh_size = BN_num_bits(dh->p); + if ((!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 768) + || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 512)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_DH_KEY_TOO_SMALL); + goto f_err; + } + } +#endif /* !OPENSSL_NO_DH */ if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i, EVP_PKT_EXP)) { #ifndef OPENSSL_NO_RSA diff --git a/ssl/ssl.h b/ssl/ssl.h index 62472a1e3c..32e27c6fbf 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -2524,6 +2524,7 @@ void ERR_load_SSL_strings(void); # define SSL_R_DATA_LENGTH_TOO_LONG 146 # define SSL_R_DECRYPTION_FAILED 147 # define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281 +# define SSL_R_DH_KEY_TOO_SMALL 372 # define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 # define SSL_R_DIGEST_CHECK_FAILED 149 # define SSL_R_DTLS_MESSAGE_TOO_BIG 334 diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 835b43ce67..fef324d462 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -441,6 +441,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = { {ERR_REASON(SSL_R_DECRYPTION_FAILED), "decryption failed"}, {ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC), "decryption failed or bad record mac"}, + {ERR_REASON(SSL_R_DH_KEY_TOO_SMALL), "dh key too small"}, {ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG), "dh public value length is wrong"}, {ERR_REASON(SSL_R_DIGEST_CHECK_FAILED), "digest check failed"},