Commit 79be685126 for openssl.org

commit 79be68512612dae7e4ec113a057733afef1ed1f6
Author: Neil Horman <nhorman@openssl.org>
Date:   Mon Feb 16 18:04:37 2026 -0500

    Use the appropriate libctx when executing CMS_SignerInfo_verify

    @beldmit found some odd fips behavior when running cms tests after
    attempting to remove the EVP_get_digestbyname call from the find routine
    in cms when doing certificate signer validation.

    It was occuring because the cms app, being an applet in openssl uses the
    app libctx to load all the provided configuration, which implies the
    fips and base providers are loaded to that ctx.  However, in the find
    routine (part of cms), it only ever fetches algorithms from the default
    libctx, leading to failed lookups, and consequently, CMS errors.

    Fix it by using the appropriate libctx, which in this case can be
    fetched from the SignerInfo data, which initializes its libctx member to
    the app libctx in all cases.

    Reviewed-by: Tomas Mraz <tomas@openssl.org>
    Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
    MergeDate: Wed Feb 18 16:28:44 2026
    (Merged from https://github.com/openssl/openssl/pull/30034)

diff --git a/CHANGES.md b/CHANGES.md
index d30b96ace3..472dd9a7c1 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -32,6 +32,14 @@ OpenSSL 4.0

 ### Changes between 3.6 and 4.0 [xx XXX xxxx]

+ * The `OSSL_ESS_check_signing_certs_ex()` call has been added.
+
+   This api call is an extention to `OSSL_ESS_check_signing_certs()` to add
+   the ability to specify a library context and property query when fetching
+   algorithms to validate a given certificate.
+
+   *Neil Horman*
+
  * FIPS self tests can now be deferred and run as needed when installing
    the fips module with the -defer_tests option.

diff --git a/crypto/cms/cms_ess.c b/crypto/cms/cms_ess.c
index 23b58dedbd..f3679392fd 100644
--- a/crypto/cms/cms_ess.c
+++ b/crypto/cms/cms_ess.c
@@ -106,7 +106,10 @@ int ossl_cms_check_signing_certs(const CMS_SignerInfo *si,
     ESS_SIGNING_CERT_V2 *ssv2 = NULL;
     int ret = ossl_cms_signerinfo_get_signing_cert(si, &ss) >= 0
         && ossl_cms_signerinfo_get_signing_cert_v2(si, &ssv2) >= 0
-        && OSSL_ESS_check_signing_certs(ss, ssv2, chain, 1) > 0;
+        && OSSL_ESS_check_signing_certs_ex(ss, ssv2, chain,
+               ossl_cms_ctx_get0_libctx(si->cms_ctx),
+               ossl_cms_ctx_get0_propq(si->cms_ctx), 1)
+            > 0;

     ESS_SIGNING_CERT_free(ss);
     ESS_SIGNING_CERT_V2_free(ssv2);
diff --git a/crypto/ess/ess_lib.c b/crypto/ess/ess_lib.c
index 03bd5a0937..0518b7a4ca 100644
--- a/crypto/ess/ess_lib.c
+++ b/crypto/ess/ess_lib.c
@@ -263,7 +263,7 @@ static int ess_issuer_serial_cmp(const ESS_ISSUER_SERIAL *is, const X509 *cert)
  * Return 0 on not found, -1 on error, else 1 + the position in |certs|.
  */
 static int find(const ESS_CERT_ID *cid, const ESS_CERT_ID_V2 *cid_v2,
-    int index, const STACK_OF(X509) *certs)
+    int index, const STACK_OF(X509) *certs, OSSL_LIB_CTX *libctx, const char *propq)
 {
     const X509 *cert;
     EVP_MD *md = NULL;
@@ -286,18 +286,11 @@ static int find(const ESS_CERT_ID *cid, const ESS_CERT_ID_V2 *cid_v2,
     else
         OBJ_obj2txt(name, sizeof(name), cid_v2->hash_alg->algorithm, 0);

-    (void)ERR_set_mark();
-    md = EVP_MD_fetch(NULL, name, NULL);
-
-    if (md == NULL)
-        md = (EVP_MD *)EVP_get_digestbyname(name);
-
+    md = EVP_MD_fetch(libctx, name, propq);
     if (md == NULL) {
-        (void)ERR_clear_last_mark();
         ERR_raise(ERR_LIB_ESS, ESS_R_ESS_DIGEST_ALG_UNKNOWN);
         goto end;
     }
-    (void)ERR_pop_to_mark();

     for (i = 0; i < sk_X509_num(certs); ++i) {
         cert = sk_X509_value(certs, i);
@@ -332,9 +325,11 @@ end:
     return ret;
 }

-int OSSL_ESS_check_signing_certs(const ESS_SIGNING_CERT *ss,
+int OSSL_ESS_check_signing_certs_ex(const ESS_SIGNING_CERT *ss,
     const ESS_SIGNING_CERT_V2 *ssv2,
     const STACK_OF(X509) *chain,
+    OSSL_LIB_CTX *libctx,
+    const char *propq,
     int require_signing_cert)
 {
     int n_v1 = ss == NULL ? -1 : sk_ESS_CERT_ID_num(ss->cert_ids);
@@ -351,14 +346,23 @@ int OSSL_ESS_check_signing_certs(const ESS_SIGNING_CERT *ss,
     }
     /* If both ss and ssv2 exist, as required evaluate them independently. */
     for (i = 0; i < n_v1; i++) {
-        ret = find(sk_ESS_CERT_ID_value(ss->cert_ids, i), NULL, i, chain);
+        ret = find(sk_ESS_CERT_ID_value(ss->cert_ids, i), NULL, i, chain, libctx, propq);
         if (ret <= 0)
             return ret;
     }
     for (i = 0; i < n_v2; i++) {
-        ret = find(NULL, sk_ESS_CERT_ID_V2_value(ssv2->cert_ids, i), i, chain);
+        ret = find(NULL, sk_ESS_CERT_ID_V2_value(ssv2->cert_ids, i), i, chain, libctx, propq);
         if (ret <= 0)
             return ret;
     }
     return 1;
 }
+
+int OSSL_ESS_check_signing_certs(const ESS_SIGNING_CERT *ss,
+    const ESS_SIGNING_CERT_V2 *ssv2,
+    const STACK_OF(X509) *chain,
+    int require_signing_cert)
+{
+    return OSSL_ESS_check_signing_certs_ex(ss, ssv2, chain, NULL,
+        NULL, require_signing_cert);
+}
diff --git a/doc/man3/OSSL_ESS_check_signing_certs.pod b/doc/man3/OSSL_ESS_check_signing_certs.pod
index 726dbc285c..11491dbae2 100644
--- a/doc/man3/OSSL_ESS_check_signing_certs.pod
+++ b/doc/man3/OSSL_ESS_check_signing_certs.pod
@@ -4,7 +4,8 @@

 OSSL_ESS_signing_cert_new_init,
 OSSL_ESS_signing_cert_v2_new_init,
-OSSL_ESS_check_signing_certs
+OSSL_ESS_check_signing_certs,
+OSSL_ESS_check_signing_certs_ex
 - Enhanced Security Services (ESS) functions

 =head1 SYNOPSIS
@@ -24,6 +25,12 @@ OSSL_ESS_check_signing_certs
                                   const STACK_OF(X509) *chain,
                                   int require_signing_cert);

+ int OSSL_ESS_check_signing_certs_ex(const ESS_SIGNING_CERT *ss,
+                                     const ESS_SIGNING_CERT_V2 *ssv2,
+                                     const STACK_OF(X509) *chain,
+                                     OSSL_LIB_CTX *libctx,
+                                     const char *propq,
+                                     int require_signing_cert);
 =head1 DESCRIPTION

 OSSL_ESS_signing_cert_new_init() generates a new B<ESS_SIGNING_CERT> structure
@@ -52,6 +59,10 @@ In addition to the checks required by RFCs 2624 and 5035,
 if the B<issuerSerial> field is included in an B<ESSCertID> or B<ESSCertIDv2>
 it must match the certificate issuer and serial number attributes.

+OSSL_ESS_check_signing_certs_ex() functions identically to OSSL_ESS_check_signing_certs(),
+but offers additional parameters, I<libctx> and I<propq>, for users who wish to specify a nondefault
+library context and property query, when the function fetches digests to validate the certs.
+
 =head1 NOTES

 ESS has been defined in RFC 2634, which has been updated in RFC 5035
@@ -63,7 +74,7 @@ This is used for TSP (RFC 3161) and CAdES-BES (informational RFC 5126).
 OSSL_ESS_signing_cert_new_init() and OSSL_ESS_signing_cert_v2_new_init()
 return a pointer to the new structure or NULL on malloc failure.

-OSSL_ESS_check_signing_certs() returns 1 on success,
+OSSL_ESS_check_signing_certs() and OSSL_ESS_check_signing_certs_ex() return 1 on success,
 0 if a required certificate cannot be found, -1 on other error.

 =head1 SEE ALSO
@@ -76,6 +87,8 @@ L<CMS_verify(3)>
 OSSL_ESS_signing_cert_new_init(), OSSL_ESS_signing_cert_v2_new_init(), and
 OSSL_ESS_check_signing_certs() were added in OpenSSL 3.0.

+OSSL_ESS_check_signing_certs_ex() was added in OpenSSL 4.0.
+
 =head1 COPYRIGHT

 Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved.
diff --git a/include/openssl/ess.h.in b/include/openssl/ess.h.in
index 62aaec1726..5d00653415 100644
--- a/include/openssl/ess.h.in
+++ b/include/openssl/ess.h.in
@@ -77,7 +77,12 @@ int OSSL_ESS_check_signing_certs(const ESS_SIGNING_CERT *ss,
     const ESS_SIGNING_CERT_V2 *ssv2,
     const STACK_OF(X509) *chain,
     int require_signing_cert);
-
+int OSSL_ESS_check_signing_certs_ex(const ESS_SIGNING_CERT *ss,
+    const ESS_SIGNING_CERT_V2 *ssv2,
+    const STACK_OF(X509) *chain,
+    OSSL_LIB_CTX *libctx,
+    const char *propq,
+    int require_signing_cert);
 #ifdef __cplusplus
 }
 #endif
diff --git a/util/libcrypto.num b/util/libcrypto.num
index b63a68952a..9cf9674b5f 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -5701,3 +5701,4 @@ EVP_MD_CTX_deserialize                  ?	4_0_0	EXIST::FUNCTION:
 OSSL_ENCODER_CTX_ctrl_string            ?	4_0_0	EXIST::FUNCTION:
 OPENSSL_sk_set_cmp_thunks               ?	4_0_0	EXIST::FUNCTION:
 ASN1_BIT_STRING_set1                    ?	4_0_0	EXIST::FUNCTION:
+OSSL_ESS_check_signing_certs_ex         ?	4_0_0	EXIST::FUNCTION: