summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmilia Kasper <emilia@openssl.org>2015-05-19 12:05:22 +0200
committerEmilia Kasper <emilia@openssl.org>2015-05-20 15:01:36 +0200
commit63830384e90d9b36d2793d4891501ec024827433 (patch)
treeda5b03f61bba408107d21065c4cbf78b81187e14
parentff4de7dde90d15b366abe4664b904f22539969c9 (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--CHANGES3
-rw-r--r--ssl/s3_clnt.c22
-rw-r--r--ssl/ssl.h1
-rw-r--r--ssl/ssl_err.c1
4 files changed, 20 insertions, 7 deletions
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"},