diff -Naur a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c --- a/crypto/x509/x509_vfy.c 2023-10-24 19:48:41.000000000 +0600 +++ b/crypto/x509/x509_vfy.c 2023-10-25 11:17:41.786759438 +0600 @@ -25,6 +25,7 @@ #include #include #include "internal/dane.h" +#include "internal/sslconf.h" #include "crypto/x509.h" #include "x509_local.h" @@ -3438,14 +3439,30 @@ { 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]; } diff -Naur a/doc/man5/config.pod b/doc/man5/config.pod --- a/doc/man5/config.pod 2023-10-25 11:12:49.090752061 +0600 +++ b/doc/man5/config.pod 2023-10-25 11:18:46.694761076 +0600 @@ -313,7 +313,12 @@ digest will fail. For compatibility with older versions of OpenSSL, set this option to B. This setting also affects TLS, where signature algorithms that use SHA1 as digest will no longer be supported if this option is set to -B. +B. Note that enabling B will allow TLS signature +algorithms that use SHA1 in security level 2, despite the definition of +security level 2 of 112 bits of security, which SHA1 does not meet. Because +TLS 1.1 or lower use MD5-SHA1 as pseudorandom function (PRF) to derive key +material, disabling B requires the use of TLS 1.2 or +newer. =item B (deprecated) diff -Naur a/ssl/t1_lib.c b/ssl/t1_lib.c --- a/ssl/t1_lib.c 2023-10-25 11:12:49.095752061 +0600 +++ b/ssl/t1_lib.c 2023-10-25 11:22:27.990766654 +0600 @@ -20,6 +20,7 @@ #include #include #include +#include "crypto/x509.h" #include "internal/sslconf.h" #include "internal/nelem.h" #include "internal/sizes.h" @@ -1588,19 +1589,27 @@ 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(s->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; + + if (lu->hash == NID_sha1 + && ossl_ctx_legacy_digest_signatures_allowed(s->ctx->libctx, 0) + && SSL_get_security_level(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->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; @@ -2138,6 +2147,14 @@ } } + if (lu->hash == NID_sha1 + && ossl_ctx_legacy_digest_signatures_allowed(s->ctx->libctx, 0) + && SSL_get_security_level(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(s->ctx, lu); sigalgstr[0] = (lu->sigalg >> 8) & 0xff; @@ -3007,6 +3024,8 @@ { /* 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) return 1; @@ -3015,6 +3034,25 @@ /* 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->ctx && s->ctx->libctx) + libctx = s->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(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) return ssl_security(s, op, secbits, nid, x); else diff -Naur a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t --- a/test/recipes/25-test_verify.t 2023-10-24 19:48:41.000000000 +0600 +++ b/test/recipes/25-test_verify.t 2023-10-25 11:23:32.020768269 +0600 @@ -29,7 +29,7 @@ run(app([@args])); } -plan tests => 166; +plan tests => 164; # Canonical success ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]), @@ -413,8 +413,9 @@ "Name constraints bad othername name constraint"); }); -ok(verify("ee-pss-sha1-cert", "", ["root-cert"], ["ca-cert"], "-auth_level", "0"), - "Accept PSS signature using SHA1 at auth level 0"); +## 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"], ), "CA with PSS signature using SHA256");