b85bfec
From 1fba75a6203d3ea2037d2fc2e1846f1b514c3d1d Mon Sep 17 00:00:00 2001
b85bfec
From: rpm-build <rpm-build>
b85bfec
Date: Wed, 6 Mar 2024 19:17:15 +0100
b85bfec
Subject: [PATCH 23/49] 
b85bfec
 0052-Allow-SHA1-in-seclevel-1-if-rh-allow-sha1-signatures.patch
432cfa2
b85bfec
Patch-name: 0052-Allow-SHA1-in-seclevel-1-if-rh-allow-sha1-signatures.patch
b85bfec
Patch-id: 52
b85bfec
Patch-status: |
b85bfec
    # # Support SHA1 in TLS in LEGACY crypto-policy (which is SECLEVEL=1)
b85bfec
From-dist-git-commit: 4334bc837fbc64d14890fdc51679a80770d498ce
432cfa2
---
efdb8c6
 crypto/x509/x509_vfy.c        | 20 ++++++++++-
432cfa2
 doc/man5/config.pod           |  7 ++++
efdb8c6
 ssl/t1_lib.c                  | 67 ++++++++++++++++++++++++++++-------
432cfa2
 test/recipes/25-test_verify.t |  4 +--
efdb8c6
 4 files changed, 82 insertions(+), 16 deletions(-)
432cfa2
432cfa2
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
b85bfec
index 1794c14e99..1dfbe58a4a 100644
432cfa2
--- a/crypto/x509/x509_vfy.c
432cfa2
+++ b/crypto/x509/x509_vfy.c
432cfa2
@@ -25,6 +25,7 @@
432cfa2
 #include <openssl/objects.h>
432cfa2
 #include <openssl/core_names.h>
432cfa2
 #include "internal/dane.h"
432cfa2
+#include "internal/sslconf.h"
432cfa2
 #include "crypto/x509.h"
432cfa2
 #include "x509_local.h"
432cfa2
 
b85bfec
@@ -3668,14 +3669,31 @@ static int check_sig_level(X509_STORE_CTX *ctx, X509 *cert)
432cfa2
 {
432cfa2
     int secbits = -1;
432cfa2
     int level = ctx->param->auth_level;
432cfa2
+    int nid;
432cfa2
+    OSSL_LIB_CTX *libctx = NULL;
432cfa2
 
432cfa2
     if (level <= 0)
432cfa2
         return 1;
432cfa2
     if (level > NUM_AUTH_LEVELS)
432cfa2
         level = NUM_AUTH_LEVELS;
432cfa2
 
432cfa2
-    if (!X509_get_signature_info(cert, NULL, NULL, &secbits, NULL))
432cfa2
+    if (ctx->libctx)
432cfa2
+        libctx = ctx->libctx;
432cfa2
+    else if (cert->libctx)
432cfa2
+        libctx = cert->libctx;
432cfa2
+    else
432cfa2
+        libctx = OSSL_LIB_CTX_get0_global_default();
432cfa2
+
432cfa2
+    if (!X509_get_signature_info(cert, &nid, NULL, &secbits, NULL))
432cfa2
         return 0;
432cfa2
 
efdb8c6
+    if ((nid == NID_sha1 || nid == NID_md5_sha1)
432cfa2
+            && ossl_ctx_legacy_digest_signatures_allowed(libctx, 0)
432cfa2
+            && ctx->param->auth_level < 2)
432cfa2
+        /* When rh-allow-sha1-signatures = yes and security level <= 1,
efdb8c6
+         * explicitly allow SHA1 for backwards compatibility. Also allow
efdb8c6
+         * MD5-SHA1 because TLS 1.0 is still supported, which uses it. */
432cfa2
+        return 1;
432cfa2
+
432cfa2
     return secbits >= minbits_table[level - 1];
432cfa2
 }
432cfa2
diff --git a/doc/man5/config.pod b/doc/man5/config.pod
b85bfec
index ed34ff4b9c..8ab5456c99 100644
432cfa2
--- a/doc/man5/config.pod
432cfa2
+++ b/doc/man5/config.pod
b85bfec
@@ -317,6 +317,13 @@ this option is set to B<no>.  Because TLS 1.1 or lower use MD5-SHA1 as
432cfa2
 pseudorandom function (PRF) to derive key material, disabling
432cfa2
 B<rh-allow-sha1-signatures> requires the use of TLS 1.2 or newer.
432cfa2
 
432cfa2
+Note that enabling B<rh-allow-sha1-signatures> will allow TLS signature
432cfa2
+algorithms that use SHA1 in security level 1, despite the definition of
efdb8c6
+security level 1 of 80 bits of security, which SHA1 and MD5-SHA1 do not meet.
efdb8c6
+This allows using SHA1 and MD5-SHA1 in TLS in the LEGACY crypto-policy on
efdb8c6
+Fedora without requiring to set the security level to 0, which would include
efdb8c6
+further insecure algorithms, and thus restores support for TLS 1.0 and 1.1.
432cfa2
+
432cfa2
 =item B<fips_mode> (deprecated)
432cfa2
 
432cfa2
 The value is a boolean that can be B<yes> or B<no>.  If the value is
432cfa2
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
b85bfec
index 05dd7c5595..056aae3863 100644
432cfa2
--- a/ssl/t1_lib.c
432cfa2
+++ b/ssl/t1_lib.c
432cfa2
@@ -20,6 +20,7 @@
432cfa2
 #include <openssl/bn.h>
432cfa2
 #include <openssl/provider.h>
432cfa2
 #include <openssl/param_build.h>
432cfa2
+#include "crypto/x509.h"
432cfa2
 #include "internal/sslconf.h"
432cfa2
 #include "internal/nelem.h"
432cfa2
 #include "internal/sizes.h"
b85bfec
@@ -1977,19 +1978,28 @@ int tls12_check_peer_sigalg(SSL_CONNECTION *s, uint16_t sig, EVP_PKEY *pkey)
432cfa2
         SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_UNKNOWN_DIGEST);
432cfa2
         return 0;
432cfa2
     }
432cfa2
-    /*
432cfa2
-     * Make sure security callback allows algorithm. For historical
432cfa2
-     * reasons we have to pass the sigalg as a two byte char array.
432cfa2
-     */
432cfa2
-    sigalgstr[0] = (sig >> 8) & 0xff;
432cfa2
-    sigalgstr[1] = sig & 0xff;
f4c397c
-    secbits = sigalg_security_bits(SSL_CONNECTION_GET_CTX(s), lu);
432cfa2
-    if (secbits == 0 ||
432cfa2
-        !ssl_security(s, SSL_SECOP_SIGALG_CHECK, secbits,
432cfa2
-                      md != NULL ? EVP_MD_get_type(md) : NID_undef,
432cfa2
-                      (void *)sigalgstr)) {
432cfa2
-        SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE);
432cfa2
-        return 0;
432cfa2
+
efdb8c6
+    if ((lu->hash == NID_sha1 || lu->hash == NID_md5_sha1)
f4c397c
+            && ossl_ctx_legacy_digest_signatures_allowed(s->session_ctx->libctx, 0)
f4c397c
+            && SSL_get_security_level(SSL_CONNECTION_GET_SSL(s)) < 2) {
efdb8c6
+        /* When rh-allow-sha1-signatures = yes and security level <= 1,
efdb8c6
+         * explicitly allow SHA1 for backwards compatibility. Also allow
efdb8c6
+         * MD5-SHA1 because TLS 1.0 is still supported, which uses it. */
432cfa2
+    } else {
432cfa2
+        /*
432cfa2
+         * Make sure security callback allows algorithm. For historical
432cfa2
+         * reasons we have to pass the sigalg as a two byte char array.
432cfa2
+         */
432cfa2
+        sigalgstr[0] = (sig >> 8) & 0xff;
432cfa2
+        sigalgstr[1] = sig & 0xff;
f4c397c
+        secbits = sigalg_security_bits(s->session_ctx, lu);
432cfa2
+        if (secbits == 0 ||
432cfa2
+            !ssl_security(s, SSL_SECOP_SIGALG_CHECK, secbits,
432cfa2
+                          md != NULL ? EVP_MD_get_type(md) : NID_undef,
432cfa2
+                          (void *)sigalgstr)) {
432cfa2
+            SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE);
432cfa2
+            return 0;
432cfa2
+        }
432cfa2
     }
432cfa2
     /* Store the sigalg the peer uses */
432cfa2
     s->s3.tmp.peer_sigalg = lu;
b85bfec
@@ -2563,6 +2573,15 @@ static int tls12_sigalg_allowed(const SSL_CONNECTION *s, int op,
432cfa2
         }
432cfa2
     }
432cfa2
 
efdb8c6
+    if ((lu->hash == NID_sha1 || lu->hash == NID_md5_sha1)
f4c397c
+            && ossl_ctx_legacy_digest_signatures_allowed(s->session_ctx->libctx, 0)
f4c397c
+            && SSL_get_security_level(SSL_CONNECTION_GET_SSL(s)) < 2) {
efdb8c6
+        /* When rh-allow-sha1-signatures = yes and security level <= 1,
efdb8c6
+         * explicitly allow SHA1 for backwards compatibility. Also allow
efdb8c6
+         * MD5-SHA1 because TLS 1.0 is still supported, which uses it. */
432cfa2
+        return 1;
432cfa2
+    }
432cfa2
+
432cfa2
     /* Finally see if security callback allows it */
f4c397c
     secbits = sigalg_security_bits(SSL_CONNECTION_GET_CTX(s), lu);
432cfa2
     sigalgstr[0] = (lu->sigalg >> 8) & 0xff;
b85bfec
@@ -3467,6 +3486,8 @@ static int ssl_security_cert_sig(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x,
432cfa2
 {
432cfa2
     /* Lookup signature algorithm digest */
432cfa2
     int secbits, nid, pknid;
432cfa2
+    OSSL_LIB_CTX *libctx = NULL;
432cfa2
+
b85bfec
 
432cfa2
     /* Don't check signature if self signed */
432cfa2
     if ((X509_get_extension_flags(x) & EXFLAG_SS) != 0)
b85bfec
@@ -3476,6 +3497,26 @@ static int ssl_security_cert_sig(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x,
432cfa2
     /* If digest NID not defined use signature NID */
432cfa2
     if (nid == NID_undef)
432cfa2
         nid = pknid;
432cfa2
+
432cfa2
+    if (x && x->libctx)
432cfa2
+        libctx = x->libctx;
432cfa2
+    else if (ctx && ctx->libctx)
432cfa2
+        libctx = ctx->libctx;
f4c397c
+    else if (s && s->session_ctx && s->session_ctx->libctx)
f4c397c
+        libctx = s->session_ctx->libctx;
432cfa2
+    else
432cfa2
+        libctx = OSSL_LIB_CTX_get0_global_default();
432cfa2
+
efdb8c6
+    if ((nid == NID_sha1 || nid == NID_md5_sha1)
432cfa2
+            && ossl_ctx_legacy_digest_signatures_allowed(libctx, 0)
f4c397c
+            && ((s != NULL && SSL_get_security_level(SSL_CONNECTION_GET_SSL(s)) < 2)
432cfa2
+                || (ctx != NULL && SSL_CTX_get_security_level(ctx) < 2)
432cfa2
+            ))
432cfa2
+        /* When rh-allow-sha1-signatures = yes and security level <= 1,
efdb8c6
+         * explicitly allow SHA1 for backwards compatibility. Also allow
efdb8c6
+         * MD5-SHA1 because TLS 1.0 is still supported, which uses it. */
432cfa2
+        return 1;
432cfa2
+
f4c397c
     if (s != NULL)
432cfa2
         return ssl_security(s, op, secbits, nid, x);
432cfa2
     else
432cfa2
diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t
b85bfec
index 1c8fce86fd..a584629062 100644
432cfa2
--- a/test/recipes/25-test_verify.t
432cfa2
+++ b/test/recipes/25-test_verify.t
b85bfec
@@ -481,8 +481,8 @@ ok(verify("ee-pss-sha1-cert", "", ["root-cert"], ["ca-cert"], "-auth_level", "0"
432cfa2
 ok(verify("ee-pss-sha256-cert", "", ["root-cert"], ["ca-cert"], ),
432cfa2
     "CA with PSS signature using SHA256");
432cfa2
 
432cfa2
-ok(!verify("ee-pss-sha1-cert", "", ["root-cert"], ["ca-cert"], "-auth_level", "1"),
432cfa2
-    "Reject PSS signature using SHA1 and auth level 1");
432cfa2
+ok(!verify("ee-pss-sha1-cert", "", ["root-cert"], ["ca-cert"], "-auth_level", "2"),
432cfa2
+    "Reject PSS signature using SHA1 and auth level 2");
432cfa2
 
432cfa2
 ok(verify("ee-pss-sha256-cert", "", ["root-cert"], ["ca-cert"], "-auth_level", "2"),
432cfa2
     "PSS signature using SHA256 and auth level 2");
432cfa2
-- 
b85bfec
2.44.0
432cfa2