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