From 428369896db1656af748a67bb36fba039e7b39ad Mon Sep 17 00:00:00 2001 From: Clemens Lang Date: Mon, 25 Apr 2022 15:21:46 +0200 Subject: [PATCH] Instrument SHA-1 signatures with USDT probes In order to discover remaining uses of SHA-1 in signatures without forcefully breaking the code paths, add USDT probes that can be queried with systemtap at runtime. This should allow identifying components that still use SHA-1 signatures in production so that they can be transitioned to more modern hash algorithms. --- crypto/evp/m_sigver.c | 13 +++++++++---- crypto/evp/pmeth_lib.c | 13 +++++++++---- crypto/x509/x509_vfy.c | 6 +++++- providers/common/securitycheck.c | 22 +++++++++++++++------- providers/common/securitycheck_default.c | 13 +++++++++++-- ssl/t1_lib.c | 8 +++++++- 6 files changed, 56 insertions(+), 19 deletions(-) diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c index 8da2183ce0..c17cdfa5d5 100644 --- a/crypto/evp/m_sigver.c +++ b/crypto/evp/m_sigver.c @@ -16,6 +16,8 @@ #include "internal/numbers.h" /* includes SIZE_MAX */ #include "evp_local.h" +#include + typedef struct ossl_legacy_digest_signatures_st { int allowed; } OSSL_LEGACY_DIGEST_SIGNATURES; @@ -336,10 +338,13 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, && !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 (mdnid == NID_sha1 || mdnid == NID_md5_sha1) { + if (!ossl_ctx_legacy_digest_signatures_allowed(locpctx->libctx, 0)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_DIGEST); + goto err; + } else { + DTRACE_PROBE1(libcrypto, fedora_do_sigver_init_1, mdnid); + } } } diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index b96f148c0d..54fcf24945 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -37,6 +37,8 @@ #include "internal/sslconf.h" #include "evp_local.h" +#include + #ifndef FIPS_MODULE static int evp_pkey_ctx_store_cached_data(EVP_PKEY_CTX *ctx, @@ -956,10 +958,13 @@ static int evp_pkey_ctx_set_md(EVP_PKEY_CTX *ctx, const EVP_MD *md, && !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 (mdnid == NID_sha1 || mdnid == NID_md5_sha1) { + if (!ossl_ctx_legacy_digest_signatures_allowed(ctx->libctx, 0)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_DIGEST); + return -1; + } else { + DTRACE_PROBE1(libcrypto, fedora_evp_pkey_ctx_set_md_1, mdnid); + } } } diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index bf0c608839..78638ce80e 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -29,6 +29,8 @@ #include "crypto/x509.h" #include "x509_local.h" +#include + /* CRL score values */ #define CRL_SCORE_NOCRITICAL 0x100 /* No unhandled critical extensions */ @@ -3462,11 +3464,13 @@ static int check_sig_level(X509_STORE_CTX *ctx, X509 *cert) if ((nid == NID_sha1 || nid == NID_md5_sha1) && ossl_ctx_legacy_digest_signatures_allowed(libctx, 0) - && ctx->param->auth_level < 2) + && ctx->param->auth_level < 2) { + DTRACE_PROBE1(libcrypto, fedora_check_sig_level_1, nid); /* When rh-allow-sha1-signatures = yes and security level <= 1, * explicitly allow SHA1 for backwards compatibility. Also allow * MD5-SHA1 because TLS 1.0 is still supported, which uses it. */ return 1; + } return secbits >= minbits_table[level - 1]; } diff --git a/providers/common/securitycheck.c b/providers/common/securitycheck.c index e534ad0a5f..bf496450cf 100644 --- a/providers/common/securitycheck.c +++ b/providers/common/securitycheck.c @@ -21,6 +21,8 @@ #include "prov/securitycheck.h" #include "internal/sslconf.h" +#include + /* * FIPS requires a minimum security strength of 112 bits (for encryption or * signing), and for legacy purposes 80 bits (for decryption or verifying). @@ -238,11 +240,14 @@ int ossl_digest_get_approved_nid_with_sha1(OSSL_LIB_CTX *ctx, const EVP_MD *md, # 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) + if (mdnid == NID_sha1 && !sha1_allowed) { + if (!ossl_ctx_legacy_digest_signatures_allowed(ctx, 0)) + /* SHA1 is globally disabled, check whether we want to locally allow + * it. */ mdnid = -1; + else + DTRACE_PROBE1(libcrypto, fedora_ossl_digest_get_approved_nid_with_sha1_1, mdnid); + } #endif return mdnid; @@ -258,9 +263,12 @@ int ossl_digest_is_allowed(OSSL_LIB_CTX *ctx, const EVP_MD *md) #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; + if (mdnid == NID_sha1 || mdnid == NID_md5_sha1) { + if (!ossl_ctx_legacy_digest_signatures_allowed(ctx, 0)) + return 0; + else + DTRACE_PROBE1(libcrypto, fedora_ossl_digest_is_allowed_1, mdnid); + } } #endif diff --git a/providers/common/securitycheck_default.c b/providers/common/securitycheck_default.c index ce54a94fbc..2d21e4a7df 100644 --- a/providers/common/securitycheck_default.c +++ b/providers/common/securitycheck_default.c @@ -17,6 +17,8 @@ #include "internal/nelem.h" #include "internal/sslconf.h" +#include + /* Disable the security checks in the default provider */ int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx) { @@ -40,9 +42,16 @@ int ossl_digest_rsa_sign_get_md_nid(OSSL_LIB_CTX *ctx, const EVP_MD *md, 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_sha1) + /* This will only happen if SHA1 is allowed, otherwise mdnid is -1. */ + DTRACE_PROBE1(libcrypto, fedora_ossl_digest_rsa_sign_get_md_nid_1, mdnid); 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; + if (mdnid == NID_md5_sha1) { + if (ldsigs_allowed) + DTRACE_PROBE1(libcrypto, fedora_ossl_digest_rsa_sign_get_md_nid_2, mdnid); + else + mdnid = -1; + } return mdnid; } diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 0b50266b69..d05e696a28 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -28,6 +28,8 @@ #include "ssl_local.h" #include +#include + static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey); static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu); @@ -1569,6 +1571,7 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) /* When rh-allow-sha1-signatures = yes and security level <= 1, * explicitly allow SHA1 for backwards compatibility. Also allow * MD5-SHA1 because TLS 1.0 is still supported, which uses it. */ + DTRACE_PROBE1(libssl, fedora_tls12_check_peer_sigalg_1, lu->hash); } else { /* * Make sure security callback allows algorithm. For historical @@ -2122,6 +2125,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) /* When rh-allow-sha1-signatures = yes and security level <= 1, * explicitly allow SHA1 for backwards compatibility. Also allow * MD5-SHA1 because TLS 1.0 is still supported, which uses it. */ + DTRACE_PROBE1(libssl, fedora_tls12_sigalg_allowed_1, lu->hash); return 1; } @@ -3020,11 +3024,13 @@ static int ssl_security_cert_sig(SSL *s, SSL_CTX *ctx, X509 *x, int op) && ossl_ctx_legacy_digest_signatures_allowed(libctx, 0) && ((s != NULL && SSL_get_security_level(s) < 2) || (ctx != NULL && SSL_CTX_get_security_level(ctx) < 2) - )) + )) { /* When rh-allow-sha1-signatures = yes and security level <= 1, * explicitly allow SHA1 for backwards compatibility. Also allow * MD5-SHA1 because TLS 1.0 is still supported, which uses it. */ + DTRACE_PROBE1(libssl, fedora_ssl_security_cert_sig_1, nid); return 1; + } if (s) return ssl_security(s, op, secbits, nid, x); -- 2.35.1