File openssl-Allow-disabling-of-SHA1-signatures.patch of Package openssl-3
Index: openssl-3.5.0/crypto/context.c
===================================================================
--- openssl-3.5.0.orig/crypto/context.c
+++ openssl-3.5.0/crypto/context.c
@@ -85,6 +85,8 @@ struct ossl_lib_ctx_st {
#endif
STACK_OF(SSL_COMP) *comp_methods;
+ void *legacy_digest_signatures;
+
int ischild;
int conf_diagnostics;
};
@@ -119,6 +121,23 @@ int ossl_lib_ctx_is_child(OSSL_LIB_CTX *
return ctx->ischild;
}
+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));
+ /* Default to allow SHA-1 and support disabling it via config. */
+ ldsigs->allowed = 1;
+ return ldsigs;
+}
+
static void context_deinit_objs(OSSL_LIB_CTX *ctx);
static int context_init(OSSL_LIB_CTX *ctx)
@@ -235,6 +256,10 @@ static int context_init(OSSL_LIB_CTX *ct
goto err;
#endif
+ ctx->legacy_digest_signatures = ossl_ctx_legacy_digest_signatures_new(ctx);
+ if (ctx->legacy_digest_signatures == NULL)
+ goto err;
+
/* Low priority. */
#ifndef FIPS_MODULE
ctx->child_provider = ossl_child_prov_ctx_new(ctx);
@@ -382,6 +407,11 @@ static void context_deinit_objs(OSSL_LIB
}
#endif
+ if (ctx->legacy_digest_signatures != NULL) {
+ ossl_ctx_legacy_digest_signatures_free(ctx->legacy_digest_signatures);
+ ctx->legacy_digest_signatures = NULL;
+ }
+
/* Low priority. */
#ifndef FIPS_MODULE
if (ctx->child_provider != NULL) {
@@ -660,6 +690,9 @@ void *ossl_lib_ctx_get_data(OSSL_LIB_CTX
case OSSL_LIB_CTX_COMP_METHODS:
return (void *)&ctx->comp_methods;
+ case OSSL_LIB_CTX_LEGACY_DIGEST_SIGNATURES_INDEX:
+ return ctx->legacy_digest_signatures;
+
default:
return NULL;
}
@@ -714,3 +747,44 @@ void OSSL_LIB_CTX_set_conf_diagnostics(O
return;
libctx->conf_diagnostics = value;
}
+
+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_INDEX);
+}
+
+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);
+
+ #ifndef FIPS_MODULE
+ if (ossl_safe_getenv("OPENSSL_ENABLE_SHA1_SIGNATURES") != NULL)
+ /* This is to be used in tests if SHA-1 is disabled. */
+ return 1;
+ #endif
+
+ /* Default to allow SHA-1 and support disabling it via config. */
+ 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;
+}
Index: openssl-3.5.0/crypto/evp/evp_cnf.c
===================================================================
--- openssl-3.5.0.orig/crypto/evp/evp_cnf.c
+++ openssl-3.5.0/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
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);
Index: openssl-3.5.0/crypto/evp/m_sigver.c
===================================================================
--- openssl-3.5.0.orig/crypto/evp/m_sigver.c
+++ openssl-3.5.0/crypto/evp/m_sigver.c
@@ -15,6 +15,7 @@
#include "internal/provider.h"
#include "internal/numbers.h" /* includes SIZE_MAX */
#include "evp_local.h"
+#include "internal/sslconf.h"
static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen)
{
@@ -251,6 +252,18 @@ static int do_sigver_init(EVP_MD_CTX *ct
}
}
+ 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);
Index: openssl-3.5.0/crypto/evp/pmeth_lib.c
===================================================================
--- openssl-3.5.0.orig/crypto/evp/pmeth_lib.c
+++ openssl-3.5.0/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
@@ -954,6 +955,20 @@ static int evp_pkey_ctx_set_md(EVP_PKEY_
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));
Index: openssl-3.5.0/doc/man5/config.pod
===================================================================
--- openssl-3.5.0.orig/doc/man5/config.pod
+++ openssl-3.5.0/doc/man5/config.pod
@@ -315,6 +315,21 @@ Within the algorithm properties section,
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.
+
+This is a downstream specific option, and normally it should be set up via crypto-policies.
+
=item B<fips_mode> (deprecated)
The value is a boolean that can be B<yes> or B<no>. If the value is
Index: openssl-3.5.0/include/crypto/context.h
===================================================================
--- openssl-3.5.0.orig/include/crypto/context.h
+++ openssl-3.5.0/include/crypto/context.h
@@ -48,3 +48,11 @@ void ossl_release_default_drbg_ctx(void)
#if defined(OPENSSL_THREADS)
void ossl_threads_ctx_free(void *);
#endif
+
+#ifndef OSSL_LEGACY_DIGEST_SIGNATURES_STRUCT
+#define OSSL_LEGACY_DIGEST_SIGNATURES_STRUCT
+typedef struct ossl_legacy_digest_signatures_st {
+ int allowed;
+} OSSL_LEGACY_DIGEST_SIGNATURES;
+#endif
+
Index: openssl-3.5.0/include/internal/cryptlib.h
===================================================================
--- openssl-3.5.0.orig/include/internal/cryptlib.h
+++ openssl-3.5.0/include/internal/cryptlib.h
@@ -120,7 +120,8 @@ typedef struct ossl_ex_data_global_st {
# define OSSL_LIB_CTX_DECODER_CACHE_INDEX 20
# define OSSL_LIB_CTX_COMP_METHODS 21
# define OSSL_LIB_CTX_INDICATOR_CB_INDEX 22
-# define OSSL_LIB_CTX_MAX_INDEXES 22
+# define OSSL_LIB_CTX_LEGACY_DIGEST_SIGNATURES_INDEX 23
+# define OSSL_LIB_CTX_MAX_INDEXES 23
OSSL_LIB_CTX *ossl_lib_ctx_get_concrete(OSSL_LIB_CTX *ctx);
int ossl_lib_ctx_is_default(OSSL_LIB_CTX *ctx);
Index: openssl-3.5.0/include/internal/sslconf.h
===================================================================
--- openssl-3.5.0.orig/include/internal/sslconf.h
+++ openssl-3.5.0/include/internal/sslconf.h
@@ -18,4 +18,8 @@ int conf_ssl_name_find(const char *name,
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
Index: openssl-3.5.0/providers/common/include/prov/securitycheck.h
===================================================================
--- openssl-3.5.0.orig/providers/common/include/prov/securitycheck.h
+++ openssl-3.5.0/providers/common/include/prov/securitycheck.h
@@ -37,3 +37,5 @@ int ossl_digest_get_approved_nid(const E
/* Functions that have different implementations for the FIPS_MODULE */
int ossl_digest_rsa_sign_get_md_nid(const EVP_MD *md);
int ossl_fips_config_securitycheck_enabled(OSSL_LIB_CTX *libctx);
+
+int rh_digest_signatures_allowed(OSSL_LIB_CTX *libctx, int mdnid);
Index: openssl-3.5.0/providers/common/securitycheck.c
===================================================================
--- openssl-3.5.0.orig/providers/common/securitycheck.c
+++ openssl-3.5.0/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"
#define OSSL_FIPS_MIN_SECURITY_STRENGTH_BITS 112
@@ -220,3 +221,16 @@ int ossl_dh_check_key(const DH *dh)
return (L == 2048 && (N == 224 || N == 256));
}
#endif /* OPENSSL_NO_DH */
+
+int rh_digest_signatures_allowed(OSSL_LIB_CTX *libctx, int mdnid)
+{
+#ifndef FIPS_MODULE
+ if (!ossl_ctx_legacy_digest_signatures_allowed(libctx, 0))
+ /* SHA1 is globally disabled, check whether we want to locally allow
+ * it. */
+#endif
+ if (mdnid == NID_sha1)
+ mdnid = -1;
+
+ return mdnid;
+}
Index: openssl-3.5.0/providers/common/securitycheck_default.c
===================================================================
--- openssl-3.5.0.orig/providers/common/securitycheck_default.c
+++ openssl-3.5.0/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_fips_config_securitycheck_enabled(OSSL_LIB_CTX *libctx)
Index: openssl-3.5.0/providers/implementations/signature/dsa_sig.c
===================================================================
--- openssl-3.5.0.orig/providers/implementations/signature/dsa_sig.c
+++ openssl-3.5.0/providers/implementations/signature/dsa_sig.c
@@ -163,6 +163,7 @@ static int dsa_setup_md(PROV_DSA_CTX *ct
md = EVP_MD_fetch(ctx->libctx, mdname, mdprops);
md_nid = ossl_digest_get_approved_nid(md);
+ md_nid = rh_digest_signatures_allowed(ctx->libctx, md_nid);
if (md == NULL) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
Index: openssl-3.5.0/providers/implementations/signature/ecdsa_sig.c
===================================================================
--- openssl-3.5.0.orig/providers/implementations/signature/ecdsa_sig.c
+++ openssl-3.5.0/providers/implementations/signature/ecdsa_sig.c
@@ -197,13 +197,16 @@ static int ecdsa_setup_md(PROV_ECDSA_CTX
goto err;
}
md_nid = ossl_digest_get_approved_nid(md);
+
#ifdef FIPS_MODULE
- if (md_nid == NID_undef) {
+ md_nid = rh_digest_signatures_allowed(ctx->libctx, md_nid);
+ if (md_nid <= 0) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,
"digest=%s", mdname);
goto err;
}
#endif
+
/* XOF digests don't work */
if (EVP_MD_xof(md)) {
ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);
Index: openssl-3.5.0/providers/implementations/signature/rsa_sig.c
===================================================================
--- openssl-3.5.0.orig/providers/implementations/signature/rsa_sig.c
+++ openssl-3.5.0/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
OSSL_FUNC_signature_newctx_fn rsa_newctx;
static OSSL_FUNC_signature_sign_init_fn rsa_sign_init;
@@ -387,7 +389,8 @@ static int rsa_setup_md(PROV_RSA_CTX *ct
goto err;
}
md_nid = ossl_digest_rsa_sign_get_md_nid(md);
- if (md_nid == NID_undef) {
+ md_nid = rh_digest_signatures_allowed(ctx->libctx, md_nid);
+ if (md_nid <= 0) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,
"digest=%s", mdname);
goto err;
@@ -475,8 +478,9 @@ static int rsa_setup_mgf1_md(PROV_RSA_CT
"%s could not be fetched", mdname);
return 0;
}
- /* The default for mgf1 is SHA1 - so allow SHA1 */
+ /* The default for mgf1 is SHA1 - so check if we allow SHA1 */
if ((mdnid = ossl_digest_rsa_sign_get_md_nid(md)) <= 0
+ || (mdnid = rh_digest_signatures_allowed(ctx->libctx, mdnid)) <= 0
|| !rsa_check_padding(ctx, NULL, mdname, mdnid)) {
if (mdnid <= 0)
ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,
@@ -1765,8 +1769,13 @@ static int rsa_set_ctx_params(void *vprs
prsactx->pad_mode = pad_mode;
if (prsactx->md == NULL && pmdname == NULL
- && pad_mode == RSA_PKCS1_PSS_PADDING)
- pmdname = RSA_DEFAULT_DIGEST_NAME;
+ && pad_mode == RSA_PKCS1_PSS_PADDING) {
+ if (ossl_ctx_legacy_digest_signatures_allowed(prsactx->libctx, 0)) {
+ pmdname = RSA_DEFAULT_DIGEST_NAME;
+ } else {
+ pmdname = RSA_DEFAULT_DIGEST_NAME_NONLEGACY;
+ }
+ }
if (pmgf1mdname != NULL
&& !rsa_setup_mgf1_md(prsactx, pmgf1mdname, pmgf1mdprops))
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 "internal/sslconf.h"
#include "internal/nelem.h"
#include "internal/sizes.h"
#include "internal/tlsgroups.h"
@@ -2176,6 +2177,7 @@ int ssl_setup_sigalgs(SSL_CTX *ctx)
EVP_PKEY *tmpkey = EVP_PKEY_new();
int istls;
int ret = 0;
+ int ldsigs_allowed;
if (ctx == NULL)
goto err;
@@ -2193,6 +2195,7 @@ int ssl_setup_sigalgs(SSL_CTX *ctx)
goto err;
ERR_set_mark();
+ ldsigs_allowed = ossl_ctx_legacy_digest_signatures_allowed(ctx->libctx, 0);
/* First fill cache and tls12_sigalgs list from legacy algorithm list */
for (i = 0, lu = sigalg_lookup_tbl;
i < OSSL_NELEM(sigalg_lookup_tbl); lu++, i++) {
@@ -2213,6 +2216,11 @@ int ssl_setup_sigalgs(SSL_CTX *ctx)
cache[i].available = 0;
continue;
}
+ if ((lu->hash == NID_sha1 || lu->hash == NID_md5_sha1)
+ && !ldsigs_allowed) {
+ cache[i].available = 0;
+ continue;
+ }
if (!EVP_PKEY_set_type(tmpkey, lu->sig)) {
cache[i].available = 0;
Index: openssl-3.5.0/util/libcrypto.num
===================================================================
--- openssl-3.5.0.orig/util/libcrypto.num
+++ openssl-3.5.0/util/libcrypto.num
@@ -5925,3 +5925,5 @@ OSSL_AA_DIST_POINT_free
OSSL_AA_DIST_POINT_new 6052 3_5_0 EXIST::FUNCTION:
OSSL_AA_DIST_POINT_it 6053 3_5_0 EXIST::FUNCTION:
PEM_ASN1_write_bio_ctx 6054 3_5_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: