Commit 2de7a90e7f for openssl.org
commit 2de7a90e7ff07f975de83618b216d6f94763c4a8
Author: Bob Beck <beck@openssl.org>
Date: Thu Oct 8 11:50:28 2026 -0600
Verify an OCSP signer's chain in the signer's library context
The OCSP signature is checked in the signer's library context, but the
signer's chain was verified in the default one. Create the
X509_STORE_CTX in the signer's library context too.
This was a pre-existing issue, but surfaced by these changes.
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Merge-date: Mon Oct 26 19:04:41 2026
Merged-from: https://github.com/openssl/openssl/pull/32690
diff --git a/crypto/ocsp/ocsp_vfy.c b/crypto/ocsp/ocsp_vfy.c
index e6dd9e4bb6..458710d1e3 100644
--- a/crypto/ocsp/ocsp_vfy.c
+++ b/crypto/ocsp/ocsp_vfy.c
@@ -31,11 +31,15 @@ static int ocsp_verify_signer(X509 *signer, int response,
X509_STORE *st, unsigned long flags,
STACK_OF(X509) *untrusted, STACK_OF(X509) **chain)
{
- X509_STORE_CTX *ctx = X509_STORE_CTX_new();
+ OSSL_LIB_CTX *libctx;
+ const char *propq;
+ X509_STORE_CTX *ctx;
X509_VERIFY_PARAM *vp;
int ret = -1;
- if (ctx == NULL) {
+ /* The chain is verified in the signer's library context, as the signature is */
+ ossl_x509_get0_libctx(signer, &libctx, &propq);
+ if ((ctx = X509_STORE_CTX_new_ex(libctx, propq)) == NULL) {
ERR_raise(ERR_LIB_OCSP, ERR_R_X509_LIB);
goto end;
}
diff --git a/test/ocspapitest.c b/test/ocspapitest.c
index 4e9861e5ed..2444b85b05 100644
--- a/test/ocspapitest.c
+++ b/test/ocspapitest.c
@@ -15,11 +15,16 @@
#include <openssl/x509.h>
#include <openssl/asn1.h>
#include <openssl/pem.h>
+#include <openssl/provider.h>
+#include <openssl/evp.h>
#include "testutil.h"
static const char *certstr;
static const char *privkeystr;
+static const char *eecertstr;
+static const char *eekeystr;
+static const char *cacertstr;
#ifndef OPENSSL_NO_OCSP
static int get_cert_and_key(X509 **cert_out, EVP_PKEY **key_out)
@@ -213,9 +218,47 @@ err:
return ret;
}
+/*
+ * A request whose signer and issuer are decoded in their own library
+ * context verifies while the default library context can fetch nothing.
+ */
+static int test_req_verify_signer_libctx(void)
+{
+ OSSL_LIB_CTX *libctx = NULL;
+ OSSL_PROVIDER *prov = NULL;
+ X509 *signer = NULL, *ca = NULL;
+ EVP_PKEY *key = NULL;
+ X509_STORE *store = NULL;
+ OCSP_REQUEST *req = NULL;
+ int ret = 0;
+
+ if (!TEST_ptr(libctx = OSSL_LIB_CTX_new())
+ || !TEST_ptr(prov = OSSL_PROVIDER_load(libctx, "default"))
+ || !TEST_ptr(signer = load_cert_pem(eecertstr, libctx))
+ || !TEST_ptr(ca = load_cert_pem(cacertstr, libctx))
+ || !TEST_ptr(key = load_pkey_pem(eekeystr, libctx))
+ || !TEST_ptr(store = X509_STORE_new())
+ || !TEST_true(X509_STORE_add_cert(store, ca))
+ || !TEST_ptr(req = OCSP_REQUEST_new())
+ || !TEST_true(OCSP_request_sign(req, signer, key, EVP_sha256(), NULL, 0))
+ || !TEST_true(EVP_set_default_properties(NULL, "provider=absent")))
+ goto end;
+ ret = TEST_int_gt(OCSP_request_verify(req, NULL, store, OCSP_PARTIAL_CHAIN), 0);
+ EVP_set_default_properties(NULL, "");
+end:
+ OCSP_REQUEST_free(req);
+ X509_STORE_free(store);
+ EVP_PKEY_free(key);
+ X509_free(ca);
+ X509_free(signer);
+ OSSL_PROVIDER_unload(prov);
+ OSSL_LIB_CTX_free(libctx);
+ return ret;
+}
+
#endif /* OPENSSL_NO_OCSP */
-OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n")
+OPT_TEST_DECLARE_USAGE("certfile privkeyfile eecertfile eekeyfile cacertfile\n")
int setup_tests(void)
{
@@ -225,12 +268,16 @@ int setup_tests(void)
}
if (!TEST_ptr(certstr = test_get_argument(0))
- || !TEST_ptr(privkeystr = test_get_argument(1)))
+ || !TEST_ptr(privkeystr = test_get_argument(1))
+ || !TEST_ptr(eecertstr = test_get_argument(2))
+ || !TEST_ptr(eekeystr = test_get_argument(3))
+ || !TEST_ptr(cacertstr = test_get_argument(4)))
return 0;
#ifndef OPENSSL_NO_OCSP
ADD_TEST(test_resp_signer);
ADD_ALL_TESTS(test_access_description, 3);
ADD_TEST(test_ocsp_url_svcloc_new);
+ ADD_TEST(test_req_verify_signer_libctx);
#endif
return 1;
}
diff --git a/test/recipes/80-test_ocsp.t b/test/recipes/80-test_ocsp.t
index fc7f6971d8..82c3c4d98d 100644
--- a/test/recipes/80-test_ocsp.t
+++ b/test/recipes/80-test_ocsp.t
@@ -15,7 +15,7 @@ use File::Spec::Functions qw/devnull catfile/;
use File::Basename;
use File::Copy;
use File::Compare qw/compare/;
-use OpenSSL::Test qw/:DEFAULT with pipe srctop_dir data_file/;
+use OpenSSL::Test qw/:DEFAULT with pipe srctop_dir srctop_file data_file/;
use OpenSSL::Test::Utils;
setup("test_ocsp");
@@ -259,7 +259,10 @@ my $key = data_file("key.pem");
subtest "=== OCSP API TESTS===" => sub {
plan tests => 1;
- ok(run(test(["ocspapitest", $cert, $key])),
+ ok(run(test(["ocspapitest", $cert, $key,
+ srctop_file("test", "certs", "ee-cert.pem"),
+ srctop_file("test", "certs", "ee-key.pem"),
+ srctop_file("test", "certs", "ca-cert.pem")])),
"running ocspapitest");
};