Commit 403dbe58ca for openssl.org
commit 403dbe58caa08b30ed2c63dca42db5d952a6ae32
Author: Bob Beck <beck@openssl.org>
Date: Thu Sep 3 17:28:44 2026 -0600
Compute X509_get_signature_info() on demand, not in the cache
The signature info was computed once by ossl_x509v3_cache_extensions()
and stored in X509::siginf. Its security bits depend on a digest fetch
under the certificate's libctx/propq, so the cached answer was frozen
to the context the certificate was parsed in.
Compute it in X509_get_signature_info() instead. The siginf field and
ossl_x509_init_sig_info() are removed.
Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Merge-date: Thu Sep 17 16:44:34 2026
Merged-from: https://github.com/openssl/openssl/pull/32686
diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c
index 8e685103c5..e49ac312f5 100644
--- a/crypto/x509/v3_purp.c
+++ b/crypto/x509/v3_purp.c
@@ -519,7 +519,6 @@ static void scan_ext_flags(const X509 *x509, uint32_t *flags)
* Cache info on various X.509v3 extensions and further derived information,
* e.g., if cert 'x' is self-issued, in x->ex_flags and other internal fields.
* x->fingerprint is filled in, or else EXFLAG_NO_FINGERPRINT is set in x->flags.
- * X509_SIG_INFO_VALID is set in x->flags if x->siginf was filled successfully.
* Set EXFLAG_INVALID and return 0 in case the certificate is invalid.
*
* This is usually called by side-effect on objects, and forces us to keep
@@ -548,7 +547,6 @@ int ossl_x509v3_cache_extensions(const X509 *const_x)
STACK_OF(GENERAL_NAME) *tmp_altname;
NAME_CONSTRAINTS *tmp_nc;
STACK_OF(DIST_POINT) *tmp_crldp = NULL;
- X509_SIG_INFO tmp_siginf;
#ifdef tsan_ld_acq
/* Fast lock-free check, see end of the function for details. */
@@ -751,9 +749,6 @@ int ossl_x509v3_cache_extensions(const X509 *const_x)
scan_ext_flags(const_x, &tmp_ex_flags);
- /* Set x->siginf, ignoring errors due to unsupported algos */
- (void)ossl_x509_init_sig_info(const_x, &tmp_siginf);
-
tmp_ex_flags |= EXFLAG_SET; /* Indicate that cert has been processed */
ERR_pop_to_mark();
@@ -790,7 +785,6 @@ int ossl_x509v3_cache_extensions(const X509 *const_x)
ASIdentifiers_free(((X509 *)const_x)->rfc3779_asid);
((X509 *)const_x)->rfc3779_asid = tmp_rfc3779_asid;
#endif
- ((X509 *)const_x)->siginf = tmp_siginf;
#ifdef tsan_st_rel
tsan_st_rel((TSAN_QUALIFIER int *)&const_x->ex_cached, 1);
diff --git a/crypto/x509/x509_set.c b/crypto/x509/x509_set.c
index 8b36ea6bd7..9096c0915d 100644
--- a/crypto/x509/x509_set.c
+++ b/crypto/x509/x509_set.c
@@ -202,13 +202,6 @@ void X509_SIG_INFO_set(X509_SIG_INFO *siginf, int mdnid, int pknid,
siginf->flags = flags;
}
-int X509_get_signature_info(const X509 *x, int *mdnid, int *pknid, int *secbits,
- uint32_t *flags)
-{
- X509_check_purpose(x, -1, -1);
- return X509_SIG_INFO_get(&x->siginf, mdnid, pknid, secbits, flags);
-}
-
/* Modify *siginf according to alg and sig. Return 1 on success, else 0. */
static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
const ASN1_STRING *sig, const EVP_PKEY *pubkey,
@@ -312,9 +305,18 @@ static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
return 1;
}
-/* Returns 1 on success, 0 on failure */
-int ossl_x509_init_sig_info(const X509 *x, X509_SIG_INFO *info)
+int X509_get_signature_info(const X509 *x, int *mdnid, int *pknid, int *secbits,
+ uint32_t *flags)
{
- return x509_sig_info_init(info, &x->sig_alg, &x->signature,
+ X509_SIG_INFO siginf;
+
+ if (x == NULL) {
+ ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ ERR_set_mark();
+ (void)x509_sig_info_init(&siginf, &x->sig_alg, &x->signature,
X509_PUBKEY_get0(x->cert_info.key), x->libctx, x->propq);
+ ERR_pop_to_mark();
+ return X509_SIG_INFO_get(&siginf, mdnid, pknid, secbits, flags);
}
diff --git a/doc/internal/man3/x509v3_cache_extensions.pod b/doc/internal/man3/x509v3_cache_extensions.pod
index 8f3dffc859..ecd7818f17 100644
--- a/doc/internal/man3/x509v3_cache_extensions.pod
+++ b/doc/internal/man3/x509v3_cache_extensions.pod
@@ -23,8 +23,6 @@ and stores the result in x->fingerprint;
on failure (the certificate cannot be DER encoded, for instance because it is
still under construction, or memory allocation failed) it sets
B<EXFLAG_NO_FINGERPRINT> in x->flags instead.
-It sets B<X509_SIG_INFO_VALID> in x->flags if x->siginf was filled successfully,
-which may not be possible if a referenced algorithm is unknown or not available.
Many OpenSSL functions that use an X509 object call this function implicitly.
=head1 RETURN VALUES
diff --git a/include/crypto/x509.h b/include/crypto/x509.h
index bb575b57a5..515ea15530 100644
--- a/include/crypto/x509.h
+++ b/include/crypto/x509.h
@@ -178,7 +178,6 @@ struct x509_st {
X509_CINF cert_info;
X509_ALGOR sig_alg;
ASN1_BIT_STRING signature;
- X509_SIG_INFO siginf;
CRYPTO_REF_COUNT references;
CRYPTO_EX_DATA ex_data;
/* These contain copies of various extension values */
@@ -318,7 +317,6 @@ int ossl_a2i_ipadd(unsigned char *ipout, const char *ipasc);
int ossl_x509_set1_time(int *modified, ASN1_TIME **ptm, const ASN1_TIME *tm);
int ossl_x509_print_ex_brief(BIO *bio, const X509 *cert, unsigned long neg_cflags);
int ossl_x509v3_cache_extensions(const X509 *x);
-int ossl_x509_init_sig_info(const X509 *x, X509_SIG_INFO *info);
/**
* @brief Compute the internal-use fingerprint of a DER-encodable object.