I noticed recently that OpenSSL as a client is happy to connect to a
server that offers a trivially-crackable DH group.

You can try it out at https://demo.cmrg.net/

Other modern TLS implementations will refuse to connect to this server
because the DHE group is only 16 bits.  OpenSSL happily connects and
does not inform the user that their expected message authenticity and
confidentiality and integrity guarantees are not being met.  I consider
this a security failure in the key exchange, just as i would consider it
a failure for OpenSSL to silently accept a known-broken cipher or MAC
from its peer.

I'd like to propose that the OpenSSL client implementation reject
connections to peers that offer DH groups < 1024 bits, rather than
failing open.  The attached patch should have this effect.

Other free software TLS implementations already have limits on DH group
size below which the TLS client refuses DHE connections:

 * GnuTLS  ~760 bits
 * polarssl 512 bits
 * NSS      512 bits

Despite being stronger than OpenSSL currently is here, most of these
limits are still too weak to consider even for legacy use, according to
recent recommendations such as:

http://www.enisa.europa.eu/activities/identity-and-trust/library/deliverables/algorithms-key-sizes-and-parameters-report

P.34 there indicates that 1024 bits for DLP is the limit of
acceptability for "legacy" systems, and that for "near term" resistance,
3072 bits is recommended.

Thoughts?

        --dkg

Here's the patch, which i'll file on RT shortly:


Author: Daniel Kahn Gillmor <d...@fifthhorseman.net>
Date:   Tue Nov 5 19:37:22 2013 -0500

    require DH group of 1024 bits
    
    Reject connections to TLS servers that select DH key exchange but
    offer a weak DH group.

diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index bf1ef47..ef638c4 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -3481,6 +3481,12 @@ int ssl3_check_cert_and_algorithm(SSL *s)
                
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_RSA_CERT);
                goto f_err;
                }
+        else if ((alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) &&
+               (dh == NULL || DH_size(dh)*8 < 1024))
+               {
+               SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_WEAK_DH_GROUP);
+               goto f_err;
+               }
 #ifndef OPENSSL_NO_DSA
        else if ((alg_k & SSL_kDHd) && !SSL_USE_SIGALGS(s) &&
                !has_bits(i,EVP_PK_DH|EVP_PKS_DSA))
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 472e070..3ea316c 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -3062,6 +3062,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_R_UNSUPPORTED_SSL_VERSION                   259
 #define SSL_R_UNSUPPORTED_STATUS_TYPE                   329
 #define SSL_R_USE_SRTP_NOT_NEGOTIATED                   369
+#define SSL_R_WEAK_DH_GROUP                             371
 #define SSL_R_WRITE_BIO_NOT_SET                                 260
 #define SSL_R_WRONG_CERTIFICATE_TYPE                    383
 #define SSL_R_WRONG_CIPHER_RETURNED                     261
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 9889a27..a97b4b5 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -612,6 +612,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
 {ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION),"unsupported ssl version"},
 {ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE),"unsupported status type"},
 {ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED),"use srtp not negotiated"},
+{ERR_REASON(SSL_R_WEAK_DH_GROUP)         ,"weak dh group"},
 {ERR_REASON(SSL_R_WRITE_BIO_NOT_SET)     ,"write bio not set"},
 {ERR_REASON(SSL_R_WRONG_CERTIFICATE_TYPE),"wrong certificate type"},
 {ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED) ,"wrong cipher returned"},
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       openssl-dev@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to