diff options
author | Emilia Kasper <emilia@openssl.org> | 2015-05-19 12:05:22 +0200 |
---|---|---|
committer | Emilia Kasper <emilia@openssl.org> | 2015-05-20 15:01:36 +0200 |
commit | 63830384e90d9b36d2793d4891501ec024827433 (patch) | |
tree | da5b03f61bba408107d21065c4cbf78b81187e14 | |
parent | ff4de7dde90d15b366abe4664b904f22539969c9 (diff) |
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 <kurt@openssl.org>
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | ssl/s3_clnt.c | 22 | ||||
-rw-r--r-- | ssl/ssl.h | 1 | ||||
-rw-r--r-- | ssl/ssl_err.c | 1 |
4 files changed, 20 insertions, 7 deletions
@@ -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 @@ -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"}, |