| |
@@ -0,0 +1,497 @@
|
| |
+ From 63beeeb2a048320e2b63eaedb95343b7bc3b011d Mon Sep 17 00:00:00 2001
|
| |
+ From: Clemens Lang <cllang@redhat.com>
|
| |
+ Date: Mon, 21 Feb 2022 17:24:44 +0100
|
| |
+ Subject: [PATCH] Allow disabling of SHA1 signatures
|
| |
+ MIME-Version: 1.0
|
| |
+ Content-Type: text/plain; charset=UTF-8
|
| |
+ Content-Transfer-Encoding: 8bit
|
| |
+
|
| |
+ NOTE: This patch is ported from CentOS 9 / RHEL 9, where it defaults to
|
| |
+ denying SHA1 signatures. On Fedora, the default is – for now – to allow
|
| |
+ SHA1 signatures.
|
| |
+
|
| |
+ In order to phase out SHA1 signatures, introduce a new configuration
|
| |
+ option in the alg_section named 'rh-allow-sha1-signatures'. This option
|
| |
+ defaults to true. If set to false, any signature creation or
|
| |
+ verification operations that involve SHA1 as digest will fail.
|
| |
+
|
| |
+ This also affects TLS, where the signature_algorithms extension of any
|
| |
+ ClientHello message sent by OpenSSL will no longer include signatures
|
| |
+ with the SHA1 digest if rh-allow-sha1-signatures is false. For servers
|
| |
+ that request a client certificate, the same also applies for
|
| |
+ CertificateRequest messages sent by them.
|
| |
+
|
| |
+ For signatures created using the EVP_PKEY API, this is a best-effort
|
| |
+ check that will deny signatures in cases where the digest algorithm is
|
| |
+ known. This means, for example, that that following steps will still
|
| |
+ work:
|
| |
+
|
| |
+ $> openssl dgst -sha1 -binary -out sha1 infile
|
| |
+ $> openssl pkeyutl -inkey key.pem -sign -in sha1 -out sha1sig
|
| |
+ $> openssl pkeyutl -inkey key.pem -verify -sigfile sha1sig -in sha1
|
| |
+
|
| |
+ whereas these will not:
|
| |
+
|
| |
+ $> openssl dgst -sha1 -binary -out sha1 infile
|
| |
+ $> openssl pkeyutl -inkey kem.pem -sign -in sha1 -out sha1sig -pkeyopt digest:sha1
|
| |
+ $> openssl pkeyutl -inkey kem.pem -verify -sigfile sha1sig -in sha1 -pkeyopt digest:sha1
|
| |
+
|
| |
+ This happens because in the first case, OpenSSL's signature
|
| |
+ implementation does not know that it is signing a SHA1 hash (it could be
|
| |
+ signing arbitrary data).
|
| |
+ ---
|
| |
+ crypto/evp/evp_cnf.c | 13 +++
|
| |
+ crypto/evp/m_sigver.c | 79 +++++++++++++++++++
|
| |
+ crypto/evp/pmeth_lib.c | 15 ++++
|
| |
+ doc/man5/config.pod | 13 +++
|
| |
+ include/internal/cryptlib.h | 3 +-
|
| |
+ include/internal/sslconf.h | 4 +
|
| |
+ providers/common/securitycheck.c | 20 +++++
|
| |
+ providers/common/securitycheck_default.c | 9 ++-
|
| |
+ providers/implementations/signature/dsa_sig.c | 11 ++-
|
| |
+ .../implementations/signature/ecdsa_sig.c | 4 +
|
| |
+ providers/implementations/signature/rsa_sig.c | 20 ++++-
|
| |
+ ssl/t1_lib.c | 8 ++
|
| |
+ util/libcrypto.num | 2 +
|
| |
+ 13 files changed, 192 insertions(+), 9 deletions(-)
|
| |
+
|
| |
+ diff --git a/crypto/evp/evp_cnf.c b/crypto/evp/evp_cnf.c
|
| |
+ index 0e7fe64cf9..b9d3b6d226 100644
|
| |
+ --- a/crypto/evp/evp_cnf.c
|
| |
+ +++ b/crypto/evp/evp_cnf.c
|
| |
+ @@ -10,6 +10,7 @@
|
| |
+ #include <stdio.h>
|
| |
+ #include <openssl/crypto.h>
|
| |
+ #include "internal/cryptlib.h"
|
| |
+ +#include "internal/sslconf.h"
|
| |
+ #include <openssl/conf.h>
|
| |
+ #include <openssl/x509.h>
|
| |
+ #include <openssl/x509v3.h>
|
| |
+ @@ -57,6 +58,18 @@ static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
|
| |
+ ERR_raise(ERR_LIB_EVP, EVP_R_SET_DEFAULT_PROPERTY_FAILURE);
|
| |
+ return 0;
|
| |
+ }
|
| |
+ + } else if (strcmp(oval->name, "rh-allow-sha1-signatures") == 0) {
|
| |
+ + int m;
|
| |
+ +
|
| |
+ + /* Detailed error already reported. */
|
| |
+ + if (!X509V3_get_value_bool(oval, &m))
|
| |
+ + return 0;
|
| |
+ +
|
| |
+ + if (!ossl_ctx_legacy_digest_signatures_allowed_set(
|
| |
+ + NCONF_get0_libctx((CONF *)cnf), m > 0, 0)) {
|
| |
+ + ERR_raise(ERR_LIB_EVP, EVP_R_SET_DEFAULT_PROPERTY_FAILURE);
|
| |
+ + return 0;
|
| |
+ + }
|
| |
+ } else {
|
| |
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_UNKNOWN_OPTION,
|
| |
+ "name=%s, value=%s", oval->name, oval->value);
|
| |
+ diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
|
| |
+ index 76a6814b42..84da25980e 100644
|
| |
+ --- a/crypto/evp/m_sigver.c
|
| |
+ +++ b/crypto/evp/m_sigver.c
|
| |
+ @@ -16,6 +16,73 @@
|
| |
+ #include "internal/numbers.h" /* includes SIZE_MAX */
|
| |
+ #include "evp_local.h"
|
| |
+
|
| |
+ +typedef struct ossl_legacy_digest_signatures_st {
|
| |
+ + int allowed;
|
| |
+ +} OSSL_LEGACY_DIGEST_SIGNATURES;
|
| |
+ +
|
| |
+ +static void ossl_ctx_legacy_digest_signatures_free(void *vldsigs)
|
| |
+ +{
|
| |
+ + OSSL_LEGACY_DIGEST_SIGNATURES *ldsigs = vldsigs;
|
| |
+ +
|
| |
+ + if (ldsigs != NULL) {
|
| |
+ + OPENSSL_free(ldsigs);
|
| |
+ + }
|
| |
+ +}
|
| |
+ +
|
| |
+ +static void *ossl_ctx_legacy_digest_signatures_new(OSSL_LIB_CTX *ctx)
|
| |
+ +{
|
| |
+ + OSSL_LEGACY_DIGEST_SIGNATURES* ldsigs = OPENSSL_zalloc(sizeof(OSSL_LEGACY_DIGEST_SIGNATURES));
|
| |
+ + /* Warning: This patch differs from the same patch in CentOS and RHEL here,
|
| |
+ + * because the default on Fedora is to allow SHA-1 and support disabling
|
| |
+ + * it, while CentOS/RHEL disable it by default and allow enabling it. */
|
| |
+ + ldsigs->allowed = 1;
|
| |
+ + return ldsigs;
|
| |
+ +}
|
| |
+ +
|
| |
+ +static const OSSL_LIB_CTX_METHOD ossl_ctx_legacy_digest_signatures_method = {
|
| |
+ + OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
|
| |
+ + ossl_ctx_legacy_digest_signatures_new,
|
| |
+ + ossl_ctx_legacy_digest_signatures_free,
|
| |
+ +};
|
| |
+ +
|
| |
+ +static OSSL_LEGACY_DIGEST_SIGNATURES *ossl_ctx_legacy_digest_signatures(
|
| |
+ + OSSL_LIB_CTX *libctx, int loadconfig)
|
| |
+ +{
|
| |
+ +#ifndef FIPS_MODULE
|
| |
+ + if (loadconfig && !OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL))
|
| |
+ + return NULL;
|
| |
+ +#endif
|
| |
+ +
|
| |
+ + return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_LEGACY_DIGEST_SIGNATURES,
|
| |
+ + &ossl_ctx_legacy_digest_signatures_method);
|
| |
+ +}
|
| |
+ +
|
| |
+ +int ossl_ctx_legacy_digest_signatures_allowed(OSSL_LIB_CTX *libctx, int loadconfig)
|
| |
+ +{
|
| |
+ + OSSL_LEGACY_DIGEST_SIGNATURES *ldsigs
|
| |
+ + = ossl_ctx_legacy_digest_signatures(libctx, loadconfig);
|
| |
+ +
|
| |
+ + /* Warning: This patch differs from the same patch in CentOS and RHEL here,
|
| |
+ + * because the default on Fedora is to allow SHA-1 and support disabling
|
| |
+ + * it, while CentOS/RHEL disable it by default and allow enabling it. */
|
| |
+ + return ldsigs != NULL ? ldsigs->allowed : 1;
|
| |
+ +}
|
| |
+ +
|
| |
+ +int ossl_ctx_legacy_digest_signatures_allowed_set(OSSL_LIB_CTX *libctx, int allow,
|
| |
+ + int loadconfig)
|
| |
+ +{
|
| |
+ + OSSL_LEGACY_DIGEST_SIGNATURES *ldsigs
|
| |
+ + = ossl_ctx_legacy_digest_signatures(libctx, loadconfig);
|
| |
+ +
|
| |
+ + if (ldsigs == NULL) {
|
| |
+ + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
|
| |
+ + return 0;
|
| |
+ + }
|
| |
+ +
|
| |
+ + ldsigs->allowed = allow;
|
| |
+ + return 1;
|
| |
+ +}
|
| |
+ +
|
| |
+ #ifndef FIPS_MODULE
|
| |
+
|
| |
+ static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen)
|
| |
+ @@ -258,6 +325,18 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
| |
+ }
|
| |
+ }
|
| |
+
|
| |
+ + if (ctx->reqdigest != NULL
|
| |
+ + && !EVP_PKEY_is_a(locpctx->pkey, SN_hmac)
|
| |
+ + && !EVP_PKEY_is_a(locpctx->pkey, SN_tls1_prf)
|
| |
+ + && !EVP_PKEY_is_a(locpctx->pkey, SN_hkdf)) {
|
| |
+ + int mdnid = EVP_MD_nid(ctx->reqdigest);
|
| |
+ + if (!ossl_ctx_legacy_digest_signatures_allowed(locpctx->libctx, 0)
|
| |
+ + && (mdnid == NID_sha1 || mdnid == NID_md5_sha1)) {
|
| |
+ + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_DIGEST);
|
| |
+ + goto err;
|
| |
+ + }
|
| |
+ + }
|
| |
+ +
|
| |
+ if (ver) {
|
| |
+ if (signature->digest_verify_init == NULL) {
|
| |
+ ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
| |
+ diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
|
| |
+ index 2b9c6c2351..3c5a1e6f5d 100644
|
| |
+ --- a/crypto/evp/pmeth_lib.c
|
| |
+ +++ b/crypto/evp/pmeth_lib.c
|
| |
+ @@ -33,6 +33,7 @@
|
| |
+ #include "internal/ffc.h"
|
| |
+ #include "internal/numbers.h"
|
| |
+ #include "internal/provider.h"
|
| |
+ +#include "internal/sslconf.h"
|
| |
+ #include "evp_local.h"
|
| |
+
|
| |
+ #ifndef FIPS_MODULE
|
| |
+ @@ -946,6 +947,20 @@ static int evp_pkey_ctx_set_md(EVP_PKEY_CTX *ctx, const EVP_MD *md,
|
| |
+ return -2;
|
| |
+ }
|
| |
+
|
| |
+ + if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
| |
+ + && md != NULL
|
| |
+ + && ctx->pkey != NULL
|
| |
+ + && !EVP_PKEY_is_a(ctx->pkey, SN_hmac)
|
| |
+ + && !EVP_PKEY_is_a(ctx->pkey, SN_tls1_prf)
|
| |
+ + && !EVP_PKEY_is_a(ctx->pkey, SN_hkdf)) {
|
| |
+ + int mdnid = EVP_MD_nid(md);
|
| |
+ + if ((mdnid == NID_sha1 || mdnid == NID_md5_sha1)
|
| |
+ + && !ossl_ctx_legacy_digest_signatures_allowed(ctx->libctx, 0)) {
|
| |
+ + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_DIGEST);
|
| |
+ + return -1;
|
| |
+ + }
|
| |
+ + }
|
| |
+ +
|
| |
+ if (fallback)
|
| |
+ return EVP_PKEY_CTX_ctrl(ctx, -1, op, ctrl, 0, (void *)(md));
|
| |
+
|
| |
+ diff --git a/doc/man5/config.pod b/doc/man5/config.pod
|
| |
+ index 77a8055e81..0c9110d28a 100644
|
| |
+ --- a/doc/man5/config.pod
|
| |
+ +++ b/doc/man5/config.pod
|
| |
+ @@ -296,6 +296,19 @@ Within the algorithm properties section, the following names have meaning:
|
| |
+ The value may be anything that is acceptable as a property query
|
| |
+ string for EVP_set_default_properties().
|
| |
+
|
| |
+ +=item B<rh-allow-sha1-signatures>
|
| |
+ +
|
| |
+ +The value is a boolean that can be B<yes> or B<no>. If the value is not set,
|
| |
+ +it behaves as if it was set to B<yes>.
|
| |
+ +
|
| |
+ +When set to B<no>, any attempt to create or verify a signature with a SHA1
|
| |
+ +digest will fail. To test whether your software will work with future versions
|
| |
+ +of OpenSSL, set this option to B<no>. 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<no>. Because TLS 1.1 or lower use MD5-SHA1 as
|
| |
+ +pseudorandom function (PRF) to derive key material, disabling
|
| |
+ +B<rh-allow-sha1-signatures> requires the use of TLS 1.2 or newer.
|
| |
+ +
|
| |
+ =item B<fips_mode> (deprecated)
|
| |
+
|
| |
+ The value is a boolean that can be B<yes> or B<no>. If the value is
|
| |
+ diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h
|
| |
+ index 1291299b6e..e234341e6a 100644
|
| |
+ --- a/include/internal/cryptlib.h
|
| |
+ +++ b/include/internal/cryptlib.h
|
| |
+ @@ -168,7 +168,8 @@ typedef struct ossl_ex_data_global_st {
|
| |
+ # define OSSL_LIB_CTX_PROVIDER_CONF_INDEX 16
|
| |
+ # define OSSL_LIB_CTX_BIO_CORE_INDEX 17
|
| |
+ # define OSSL_LIB_CTX_CHILD_PROVIDER_INDEX 18
|
| |
+ -# define OSSL_LIB_CTX_MAX_INDEXES 19
|
| |
+ +# define OSSL_LIB_CTX_LEGACY_DIGEST_SIGNATURES 19
|
| |
+ +# define OSSL_LIB_CTX_MAX_INDEXES 20
|
| |
+
|
| |
+ # define OSSL_LIB_CTX_METHOD_LOW_PRIORITY -1
|
| |
+ # define OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY 0
|
| |
+ diff --git a/include/internal/sslconf.h b/include/internal/sslconf.h
|
| |
+ index fd7f7e3331..05464b0655 100644
|
| |
+ --- a/include/internal/sslconf.h
|
| |
+ +++ b/include/internal/sslconf.h
|
| |
+ @@ -18,4 +18,8 @@ int conf_ssl_name_find(const char *name, size_t *idx);
|
| |
+ void conf_ssl_get_cmd(const SSL_CONF_CMD *cmd, size_t idx, char **cmdstr,
|
| |
+ char **arg);
|
| |
+
|
| |
+ +/* Methods to support disabling all signatures with legacy digests */
|
| |
+ +int ossl_ctx_legacy_digest_signatures_allowed(OSSL_LIB_CTX *libctx, int loadconfig);
|
| |
+ +int ossl_ctx_legacy_digest_signatures_allowed_set(OSSL_LIB_CTX *libctx, int allow,
|
| |
+ + int loadconfig);
|
| |
+ #endif
|
| |
+ diff --git a/providers/common/securitycheck.c b/providers/common/securitycheck.c
|
| |
+ index 699ada7c52..e534ad0a5f 100644
|
| |
+ --- a/providers/common/securitycheck.c
|
| |
+ +++ b/providers/common/securitycheck.c
|
| |
+ @@ -19,6 +19,7 @@
|
| |
+ #include <openssl/core_names.h>
|
| |
+ #include <openssl/obj_mac.h>
|
| |
+ #include "prov/securitycheck.h"
|
| |
+ +#include "internal/sslconf.h"
|
| |
+
|
| |
+ /*
|
| |
+ * FIPS requires a minimum security strength of 112 bits (for encryption or
|
| |
+ @@ -235,6 +236,15 @@ int ossl_digest_get_approved_nid_with_sha1(OSSL_LIB_CTX *ctx, const EVP_MD *md,
|
| |
+ mdnid = -1; /* disallowed by security checks */
|
| |
+ }
|
| |
+ # endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
|
| |
+ +
|
| |
+ +#ifndef FIPS_MODULE
|
| |
+ + if (!ossl_ctx_legacy_digest_signatures_allowed(ctx, 0))
|
| |
+ + /* SHA1 is globally disabled, check whether we want to locally allow
|
| |
+ + * it. */
|
| |
+ + if (mdnid == NID_sha1 && !sha1_allowed)
|
| |
+ + mdnid = -1;
|
| |
+ +#endif
|
| |
+ +
|
| |
+ return mdnid;
|
| |
+ }
|
| |
+
|
| |
+ @@ -244,5 +254,15 @@ int ossl_digest_is_allowed(OSSL_LIB_CTX *ctx, const EVP_MD *md)
|
| |
+ if (ossl_securitycheck_enabled(ctx))
|
| |
+ return ossl_digest_get_approved_nid(md) != NID_undef;
|
| |
+ # endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
|
| |
+ +
|
| |
+ +#ifndef FIPS_MODULE
|
| |
+ + {
|
| |
+ + int mdnid = EVP_MD_nid(md);
|
| |
+ + if ((mdnid == NID_sha1 || mdnid == NID_md5_sha1)
|
| |
+ + && !ossl_ctx_legacy_digest_signatures_allowed(ctx, 0))
|
| |
+ + return 0;
|
| |
+ + }
|
| |
+ +#endif
|
| |
+ +
|
| |
+ return 1;
|
| |
+ }
|
| |
+ diff --git a/providers/common/securitycheck_default.c b/providers/common/securitycheck_default.c
|
| |
+ index de7f0d3a0a..ce54a94fbc 100644
|
| |
+ --- a/providers/common/securitycheck_default.c
|
| |
+ +++ b/providers/common/securitycheck_default.c
|
| |
+ @@ -15,6 +15,7 @@
|
| |
+ #include <openssl/obj_mac.h>
|
| |
+ #include "prov/securitycheck.h"
|
| |
+ #include "internal/nelem.h"
|
| |
+ +#include "internal/sslconf.h"
|
| |
+
|
| |
+ /* Disable the security checks in the default provider */
|
| |
+ int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx)
|
| |
+ @@ -23,9 +24,10 @@ int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx)
|
| |
+ }
|
| |
+
|
| |
+ int ossl_digest_rsa_sign_get_md_nid(OSSL_LIB_CTX *ctx, const EVP_MD *md,
|
| |
+ - ossl_unused int sha1_allowed)
|
| |
+ + int sha1_allowed)
|
| |
+ {
|
| |
+ int mdnid;
|
| |
+ + int ldsigs_allowed;
|
| |
+
|
| |
+ static const OSSL_ITEM name_to_nid[] = {
|
| |
+ { NID_md5, OSSL_DIGEST_NAME_MD5 },
|
| |
+ @@ -36,8 +38,11 @@ int ossl_digest_rsa_sign_get_md_nid(OSSL_LIB_CTX *ctx, const EVP_MD *md,
|
| |
+ { NID_ripemd160, OSSL_DIGEST_NAME_RIPEMD160 },
|
| |
+ };
|
| |
+
|
| |
+ - mdnid = ossl_digest_get_approved_nid_with_sha1(ctx, md, 1);
|
| |
+ + ldsigs_allowed = ossl_ctx_legacy_digest_signatures_allowed(ctx, 0);
|
| |
+ + mdnid = ossl_digest_get_approved_nid_with_sha1(ctx, md, sha1_allowed || ldsigs_allowed);
|
| |
+ if (mdnid == NID_undef)
|
| |
+ mdnid = ossl_digest_md_to_nid(md, name_to_nid, OSSL_NELEM(name_to_nid));
|
| |
+ + if (mdnid == NID_md5_sha1 && !ldsigs_allowed)
|
| |
+ + mdnid = -1;
|
| |
+ return mdnid;
|
| |
+ }
|
| |
+ diff --git a/providers/implementations/signature/dsa_sig.c b/providers/implementations/signature/dsa_sig.c
|
| |
+ index 28fd7c498e..fa3822f39f 100644
|
| |
+ --- a/providers/implementations/signature/dsa_sig.c
|
| |
+ +++ b/providers/implementations/signature/dsa_sig.c
|
| |
+ @@ -124,12 +124,17 @@ static int dsa_setup_md(PROV_DSA_CTX *ctx,
|
| |
+ mdprops = ctx->propq;
|
| |
+
|
| |
+ if (mdname != NULL) {
|
| |
+ - int sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN);
|
| |
+ WPACKET pkt;
|
| |
+ EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops);
|
| |
+ - int md_nid = ossl_digest_get_approved_nid_with_sha1(ctx->libctx, md,
|
| |
+ - sha1_allowed);
|
| |
+ + int md_nid;
|
| |
+ size_t mdname_len = strlen(mdname);
|
| |
+ +#ifdef FIPS_MODULE
|
| |
+ + int sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN);
|
| |
+ +#else
|
| |
+ + int sha1_allowed = 0;
|
| |
+ +#endif
|
| |
+ + md_nid = ossl_digest_get_approved_nid_with_sha1(ctx->libctx, md,
|
| |
+ + sha1_allowed);
|
| |
+
|
| |
+ if (md == NULL || md_nid < 0) {
|
| |
+ if (md == NULL)
|
| |
+ diff --git a/providers/implementations/signature/ecdsa_sig.c b/providers/implementations/signature/ecdsa_sig.c
|
| |
+ index 865d49d100..99b228e82c 100644
|
| |
+ --- a/providers/implementations/signature/ecdsa_sig.c
|
| |
+ +++ b/providers/implementations/signature/ecdsa_sig.c
|
| |
+ @@ -237,7 +237,11 @@ static int ecdsa_setup_md(PROV_ECDSA_CTX *ctx, const char *mdname,
|
| |
+ "%s could not be fetched", mdname);
|
| |
+ return 0;
|
| |
+ }
|
| |
+ +#ifdef FIPS_MODULE
|
| |
+ sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN);
|
| |
+ +#else
|
| |
+ + sha1_allowed = 0;
|
| |
+ +#endif
|
| |
+ md_nid = ossl_digest_get_approved_nid_with_sha1(ctx->libctx, md,
|
| |
+ sha1_allowed);
|
| |
+ if (md_nid < 0) {
|
| |
+ diff --git a/providers/implementations/signature/rsa_sig.c b/providers/implementations/signature/rsa_sig.c
|
| |
+ index 325e855333..bea397f0c1 100644
|
| |
+ --- a/providers/implementations/signature/rsa_sig.c
|
| |
+ +++ b/providers/implementations/signature/rsa_sig.c
|
| |
+ @@ -26,6 +26,7 @@
|
| |
+ #include "internal/cryptlib.h"
|
| |
+ #include "internal/nelem.h"
|
| |
+ #include "internal/sizes.h"
|
| |
+ +#include "internal/sslconf.h"
|
| |
+ #include "crypto/rsa.h"
|
| |
+ #include "prov/providercommon.h"
|
| |
+ #include "prov/implementations.h"
|
| |
+ @@ -34,6 +35,7 @@
|
| |
+ #include "prov/securitycheck.h"
|
| |
+
|
| |
+ #define RSA_DEFAULT_DIGEST_NAME OSSL_DIGEST_NAME_SHA1
|
| |
+ +#define RSA_DEFAULT_DIGEST_NAME_NONLEGACY OSSL_DIGEST_NAME_SHA2_256
|
| |
+
|
| |
+ static OSSL_FUNC_signature_newctx_fn rsa_newctx;
|
| |
+ static OSSL_FUNC_signature_sign_init_fn rsa_sign_init;
|
| |
+ @@ -289,10 +291,15 @@ static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname,
|
| |
+
|
| |
+ if (mdname != NULL) {
|
| |
+ EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops);
|
| |
+ + int md_nid;
|
| |
+ + size_t mdname_len = strlen(mdname);
|
| |
+ +#ifdef FIPS_MODULE
|
| |
+ int sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN);
|
| |
+ - int md_nid = ossl_digest_rsa_sign_get_md_nid(ctx->libctx, md,
|
| |
+ +#else
|
| |
+ + int sha1_allowed = 0;
|
| |
+ +#endif
|
| |
+ + md_nid = ossl_digest_rsa_sign_get_md_nid(ctx->libctx, md,
|
| |
+ sha1_allowed);
|
| |
+ - size_t mdname_len = strlen(mdname);
|
| |
+
|
| |
+ if (md == NULL
|
| |
+ || md_nid <= 0
|
| |
+ @@ -1348,8 +1355,15 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
|
| |
+ prsactx->pad_mode = pad_mode;
|
| |
+
|
| |
+ if (prsactx->md == NULL && pmdname == NULL
|
| |
+ - && pad_mode == RSA_PKCS1_PSS_PADDING)
|
| |
+ + && pad_mode == RSA_PKCS1_PSS_PADDING) {
|
| |
+ pmdname = RSA_DEFAULT_DIGEST_NAME;
|
| |
+ +#ifndef FIPS_MODULE
|
| |
+ + if (!ossl_ctx_legacy_digest_signatures_allowed(prsactx->libctx, 0)) {
|
| |
+ + pmdname = RSA_DEFAULT_DIGEST_NAME_NONLEGACY;
|
| |
+ + }
|
| |
+ +#endif
|
| |
+ + }
|
| |
+ +
|
| |
+
|
| |
+ if (pmgf1mdname != NULL
|
| |
+ && !rsa_setup_mgf1_md(prsactx, pmgf1mdname, pmgf1mdprops))
|
| |
+ diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
|
| |
+ index 41fddf22a7..dcd487ec2e 100644
|
| |
+ --- a/ssl/t1_lib.c
|
| |
+ +++ b/ssl/t1_lib.c
|
| |
+ @@ -20,6 +20,7 @@
|
| |
+ #include <openssl/bn.h>
|
| |
+ #include <openssl/provider.h>
|
| |
+ #include <openssl/param_build.h>
|
| |
+ +#include "internal/sslconf.h"
|
| |
+ #include "internal/nelem.h"
|
| |
+ #include "internal/sizes.h"
|
| |
+ #include "internal/tlsgroups.h"
|
| |
+ @@ -1145,11 +1146,13 @@ int ssl_setup_sig_algs(SSL_CTX *ctx)
|
| |
+ = OPENSSL_malloc(sizeof(*lu) * OSSL_NELEM(sigalg_lookup_tbl));
|
| |
+ EVP_PKEY *tmpkey = EVP_PKEY_new();
|
| |
+ int ret = 0;
|
| |
+ + int ldsigs_allowed;
|
| |
+
|
| |
+ if (cache == NULL || tmpkey == NULL)
|
| |
+ goto err;
|
| |
+
|
| |
+ ERR_set_mark();
|
| |
+ + ldsigs_allowed = ossl_ctx_legacy_digest_signatures_allowed(ctx->libctx, 0);
|
| |
+ for (i = 0, lu = sigalg_lookup_tbl;
|
| |
+ i < OSSL_NELEM(sigalg_lookup_tbl); lu++, i++) {
|
| |
+ EVP_PKEY_CTX *pctx;
|
| |
+ @@ -1169,6 +1172,11 @@ int ssl_setup_sig_algs(SSL_CTX *ctx)
|
| |
+ cache[i].enabled = 0;
|
| |
+ continue;
|
| |
+ }
|
| |
+ + if ((lu->hash == NID_sha1 || lu->hash == NID_md5_sha1)
|
| |
+ + && !ldsigs_allowed) {
|
| |
+ + cache[i].enabled = 0;
|
| |
+ + continue;
|
| |
+ + }
|
| |
+
|
| |
+ if (!EVP_PKEY_set_type(tmpkey, lu->sig)) {
|
| |
+ cache[i].enabled = 0;
|
| |
+ diff --git a/util/libcrypto.num b/util/libcrypto.num
|
| |
+ index 10b4e57d79..2d3c363bb0 100644
|
| |
+ --- a/util/libcrypto.num
|
| |
+ +++ b/util/libcrypto.num
|
| |
+ @@ -5426,3 +5426,5 @@ ASN1_item_d2i_ex 5552 3_0_0 EXIST::FUNCTION:
|
| |
+ EVP_PKEY_get0_provider 5554 3_0_0 EXIST::FUNCTION:
|
| |
+ EVP_PKEY_CTX_get0_provider 5555 3_0_0 EXIST::FUNCTION:
|
| |
+ ossl_safe_getenv ? 3_0_0 EXIST::FUNCTION:
|
| |
+ +ossl_ctx_legacy_digest_signatures_allowed ? 3_0_1 EXIST::FUNCTION:
|
| |
+ +ossl_ctx_legacy_digest_signatures_allowed_set ? 3_0_1 EXIST::FUNCTION:
|
| |
+ --
|
| |
+ 2.35.1
|
| |
+
|
| |
NOTE: This patch is ported from CentOS 9 / RHEL 9, where it defaults to
denying SHA1 signatures. On Fedora, the default is – for now – to allow
SHA1 signatures.
In order to phase out SHA1 signatures, introduce a new configuration
option in the alg_section named 'rh-allow-sha1-signatures'. This option
defaults to true. If set to false, any signature creation or
verification operations that involve SHA1 as digest will fail.
This also affects TLS, where the signature_algorithms extension of any
ClientHello message sent by OpenSSL will no longer include signatures
with the SHA1 digest if rh-allow-sha1-signatures is false. For servers
that request a client certificate, the same also applies for
CertificateRequest messages sent by them.
(cherry picked from commit 05fc78f33999fb34f8ec96ee58d885a64f20643f)
Resolves: rhbz#2070977
Resolves: rhbz#2071615
Related: rhbz#2031742, rhbz#2062640
Signed-off-by: Clemens Lang cllang@redhat.com