ssl: do not choose auto DH groups that are weaker than the security level
authorPauli <pauli@openssl.org>
Fri, 18 Jun 2021 02:54:24 +0000 (12:54 +1000)
committerPauli <pauli@openssl.org>
Sat, 19 Jun 2021 05:49:46 +0000 (15:49 +1000)
Fixes #15808

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15818)

ssl/ssl_cert.c
ssl/ssl_local.h
ssl/t1_lib.c

index f78cb99c18d1685e7669c451438fc8094a14d5ee..4f3c2f8ee7814e1540550d4e034e2a3f2efb95dd 100644 (file)
@@ -960,18 +960,36 @@ int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref)
     return 1;
 }
 
+int ssl_get_security_level_bits(const SSL *s, const SSL_CTX *ctx, int *levelp)
+{
+    int level;
+    static const int minbits_table[5 + 1] = { 0, 80, 112, 128, 192, 256 };
+
+    if (ctx != NULL)
+        level = SSL_CTX_get_security_level(ctx);
+    else
+        level = SSL_get_security_level(s);
+
+    if (level > 5)
+        level = 5;
+    else if (level < 0)
+        level = 0;
+
+    if (levelp != NULL)
+        *levelp = level;
+
+    return minbits_table[level];
+}
+
 static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx,
                                          int op, int bits, int nid, void *other,
                                          void *ex)
 {
     int level, minbits;
-    static const int minbits_table[5] = { 80, 112, 128, 192, 256 };
-    if (ctx)
-        level = SSL_CTX_get_security_level(ctx);
-    else
-        level = SSL_get_security_level(s);
 
-    if (level <= 0) {
+    minbits = ssl_get_security_level_bits(s, ctx, &level);
+
+    if (level == 0) {
         /*
          * No EDH keys weaker than 1024-bits even at level 0, otherwise,
          * anything goes.
@@ -980,9 +998,6 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx,
             return 0;
         return 1;
     }
-    if (level > 5)
-        level = 5;
-    minbits = minbits_table[level - 1];
     switch (op) {
     case SSL_SECOP_CIPHER_SUPPORTED:
     case SSL_SECOP_CIPHER_SHARED:
index def53739a10367a48df29b74509d179598dd21e4..dd8231460208ce03b9deb4979f446a7c9a069c62 100644 (file)
@@ -2436,6 +2436,7 @@ __owur int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain,
 __owur int ssl_security(const SSL *s, int op, int bits, int nid, void *other);
 __owur int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid,
                             void *other);
+int ssl_get_security_level_bits(const SSL *s, const SSL_CTX *ctx, int *levelp);
 
 __owur int ssl_cert_lookup_by_nid(int nid, size_t *pidx);
 __owur const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk,
index 3bc424acefe5db8d1252b9a820467bb3086152f9..2ee97c2ae62dbad70fc931147e8ec2c4a642b3df 100644 (file)
@@ -2884,7 +2884,7 @@ EVP_PKEY *ssl_get_auto_dh(SSL *s)
 {
     EVP_PKEY *dhp = NULL;
     BIGNUM *p;
-    int dh_secbits = 80;
+    int dh_secbits = 80, sec_level_bits;
     EVP_PKEY_CTX *pctx = NULL;
     OSSL_PARAM_BLD *tmpl = NULL;
     OSSL_PARAM *params = NULL;
@@ -2902,6 +2902,11 @@ EVP_PKEY *ssl_get_auto_dh(SSL *s)
         }
     }
 
+    /* Do not pick a prime that is too weak for the current security level */
+    sec_level_bits = ssl_get_security_level_bits(s, NULL, NULL);
+    if (dh_secbits < sec_level_bits)
+        dh_secbits = sec_level_bits;
+
     if (dh_secbits >= 192)
         p = BN_get_rfc3526_prime_8192(NULL);
     else if (dh_secbits >= 152)