File openssl-FIPS-Allow-SHA1-in-seclevel-2-if-rh-allow-sha1-signatures.patch of Package openssl-3

From c63599ee9708d543205a9173207ee7167315c624 Mon Sep 17 00:00:00 2001
From: Clemens Lang <cllang@redhat.com>
Date: Tue, 1 Mar 2022 15:44:18 +0100
Subject: [PATCH] Allow SHA1 in seclevel 2 if rh-allow-sha1-signatures = yes

---
 crypto/x509/x509_vfy.c        | 19 ++++++++++-
 doc/man5/config.pod           |  7 +++-
 ssl/t1_lib.c                  | 64 ++++++++++++++++++++++++++++-------
 test/recipes/25-test_verify.t |  7 ++--
 4 files changed, 79 insertions(+), 18 deletions(-)

Index: openssl-3.5.0/crypto/x509/x509_vfy.c
===================================================================
--- openssl-3.5.0.orig/crypto/x509/x509_vfy.c
+++ openssl-3.5.0/crypto/x509/x509_vfy.c
@@ -25,6 +25,7 @@
 #include <openssl/objects.h>
 #include <openssl/core_names.h>
 #include "internal/dane.h"
+#include "internal/sslconf.h"
 #include "crypto/x509.h"
 #include "x509_local.h"
 
@@ -3745,14 +3746,30 @@ static int check_sig_level(X509_STORE_CT
 {
     int secbits = -1;
     int level = ctx->param->auth_level;
+    int nid;
+    OSSL_LIB_CTX *libctx = NULL;
 
     if (level <= 0)
         return 1;
     if (level > NUM_AUTH_LEVELS)
         level = NUM_AUTH_LEVELS;
 
-    if (!X509_get_signature_info(cert, NULL, NULL, &secbits, NULL))
+    if (ctx->libctx)
+        libctx = ctx->libctx;
+    else if (cert->libctx)
+        libctx = cert->libctx;
+    else
+        libctx = OSSL_LIB_CTX_get0_global_default();
+
+    if (!X509_get_signature_info(cert, &nid, NULL, &secbits, NULL))
         return 0;
 
+    if (nid == NID_sha1
+            && ossl_ctx_legacy_digest_signatures_allowed(libctx, 0)
+            && ctx->param->auth_level < 3)
+        /* When rh-allow-sha1-signatures = yes and security level <= 2,
+         * explicitly allow SHA1 for backwards compatibility. */
+        return 1;
+
     return secbits >= minbits_table[level - 1];
 }
Index: openssl-3.5.0/ssl/t1_lib.c
===================================================================
--- openssl-3.5.0.orig/ssl/t1_lib.c
+++ openssl-3.5.0/ssl/t1_lib.c
@@ -21,6 +21,7 @@
 #include <openssl/bn.h>
 #include <openssl/provider.h>
 #include <openssl/param_build.h>
+#include "crypto/x509.h"
 #include "internal/sslconf.h"
 #include "internal/nelem.h"
 #include "internal/sizes.h"
@@ -2807,19 +2808,27 @@ int tls12_check_peer_sigalg(SSL_CONNECTI
         SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_UNKNOWN_DIGEST);
         return 0;
     }
-    /*
-     * Make sure security callback allows algorithm. For historical
-     * reasons we have to pass the sigalg as a two byte char array.
-     */
-    sigalgstr[0] = (sig >> 8) & 0xff;
-    sigalgstr[1] = sig & 0xff;
-    secbits = sigalg_security_bits(SSL_CONNECTION_GET_CTX(s), lu);
-    if (secbits == 0 ||
-        !ssl_security(s, SSL_SECOP_SIGALG_CHECK, secbits,
-                      md != NULL ? EVP_MD_get_type(md) : NID_undef,
-                      (void *)sigalgstr)) {
-        SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE);
-        return 0;
+
+    if (lu->hash == NID_sha1
+            && ossl_ctx_legacy_digest_signatures_allowed(s->session_ctx->libctx, 0)
+            && SSL_get_security_level(SSL_CONNECTION_GET_SSL(s)) < 3) {
+        /* when rh-allow-sha1-signatures = yes and security level <= 2,
+         * explicitly allow SHA1 for backwards compatibility */
+    } else {
+        /*
+         * Make sure security callback allows algorithm. For historical
+         * reasons we have to pass the sigalg as a two byte char array.
+         */
+        sigalgstr[0] = (sig >> 8) & 0xff;
+        sigalgstr[1] = sig & 0xff;
+        secbits = sigalg_security_bits(s->session_ctx, lu);
+        if (secbits == 0 ||
+            !ssl_security(s, SSL_SECOP_SIGALG_CHECK, secbits,
+                          md != NULL ? EVP_MD_get_type(md) : NID_undef,
+                          (void *)sigalgstr)) {
+            SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE);
+            return 0;
+        }
     }
     /* Store the sigalg the peer uses */
     s->s3.tmp.peer_sigalg = lu;
@@ -3391,6 +3400,14 @@ static int tls12_sigalg_allowed(const SS
         }
     }
 
+    if (lu->hash == NID_sha1
+            && ossl_ctx_legacy_digest_signatures_allowed(s->session_ctx->libctx, 0)
+            && SSL_get_security_level(SSL_CONNECTION_GET_SSL(s)) < 3) {
+        /* when rh-allow-sha1-signatures = yes and security level <= 2,
+         * explicitly allow SHA1 for backwards compatibility */
+        return 1;
+    }
+
     /* Finally see if security callback allows it */
     secbits = sigalg_security_bits(SSL_CONNECTION_GET_CTX(s), lu);
     sigalgstr[0] = (lu->sigalg >> 8) & 0xff;
@@ -4381,6 +4398,8 @@ static int ssl_security_cert_sig(SSL_CON
 {
     /* Lookup signature algorithm digest */
     int secbits, nid, pknid;
+    OSSL_LIB_CTX *libctx = NULL;
+
 
     /* Don't check signature if self signed */
     if ((X509_get_extension_flags(x) & EXFLAG_SS) != 0)
@@ -4390,6 +4409,25 @@ static int ssl_security_cert_sig(SSL_CON
     /* If digest NID not defined use signature NID */
     if (nid == NID_undef)
         nid = pknid;
+
+    if (x && x->libctx)
+        libctx = x->libctx;
+    else if (ctx && ctx->libctx)
+        libctx = ctx->libctx;
+    else if (s && s->session_ctx && s->session_ctx->libctx)
+        libctx = s->session_ctx->libctx;
+    else
+        libctx = OSSL_LIB_CTX_get0_global_default();
+
+    if (nid == NID_sha1
+            && ossl_ctx_legacy_digest_signatures_allowed(libctx, 0)
+            && ((s != NULL && SSL_get_security_level(SSL_CONNECTION_GET_SSL(s)) < 3)
+                || (ctx != NULL && SSL_CTX_get_security_level(ctx) < 3)
+            ))
+        /* When rh-allow-sha1-signatures = yes and security level <= 2,
+         * explicitly allow SHA1 for backwards compatibility. */
+        return 1;
+
     if (s != NULL)
         return ssl_security(s, op, secbits, nid, x);
     else
Index: openssl-3.5.0/test/recipes/25-test_verify.t
===================================================================
--- openssl-3.5.0.orig/test/recipes/25-test_verify.t
+++ openssl-3.5.0/test/recipes/25-test_verify.t
@@ -29,7 +29,7 @@ sub verify {
     run(app([@args]));
 }
 
-plan tests => 194;
+plan tests => 193;
 
 # Canonical success
 ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
@@ -484,8 +484,9 @@ ok(verify("ee-pss-sha1-cert", "", ["root
 ok(verify("ee-pss-sha256-cert", "", ["root-cert"], ["ca-cert"], ),
     "CA with PSS signature using SHA256");
 
-ok(!verify("ee-pss-sha1-cert", "", ["root-cert"], ["ca-cert"], "-auth_level", "1"),
-    "Reject PSS signature using SHA1 and auth level 1");
+## rh-allow-sha1-signatures=yes allows this to pass despite -auth_level 1
+#ok(!verify("ee-pss-sha1-cert", "", ["root-cert"], ["ca-cert"], "-auth_level", "1"),
+#    "Reject PSS signature using SHA1 and auth level 1");
 
 ok(verify("ee-pss-sha256-cert", "", ["root-cert"], ["ca-cert"], "-auth_level", "2"),
     "PSS signature using SHA256 and auth level 2");
openSUSE Build Service is sponsored by