ssl: do not choose auto DH groups that are weaker than the security level
authorPauli <pauli@openssl.org>
Sat, 19 Jun 2021 06:16:36 +0000 (16:16 +1000)
committerPauli <pauli@openssl.org>
Thu, 8 Jul 2021 11:55:00 +0000 (21:55 +1000)
manual merge from https://github.com/openssl/openssl/pull/15818
id d7b5c648d682b499b71320a03747602a6ba4dec3

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

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

index 5d3e83f328974c73788557d2d9f3a5cdace43bb7..c10247386485f797305e6c5f613b55544ab9f06b 100644 (file)
@@ -876,18 +876,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.
@@ -896,9 +914,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 a357d4d950549b1fb1c0cddbc66c0f87c415fa55..f92472117a1b7716786bca0a00813367bf24a672 100644 (file)
@@ -2305,6 +2305,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 48d46f8a48bdc6a393a0aab5876162efb3e896d2..93228ec183d0e2c5bf469da5b68c422995edb611 100644 (file)
@@ -2441,7 +2441,8 @@ DH *ssl_get_auto_dh(SSL *s)
 {
     DH *dhp = NULL;
     BIGNUM *p = NULL, *g = NULL;
-    int dh_secbits = 80;
+    int dh_secbits = 80, sec_level_bits;
+
     if (s->cert->dh_tmp_auto != 2) {
         if (s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) {
             if (s->s3->tmp.new_cipher->strength_bits == 256)
@@ -2464,6 +2465,12 @@ DH *ssl_get_auto_dh(SSL *s)
         BN_free(g);
         return NULL;
     }
+
+    /* 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)