Commit c20ede00bb for openssl.org
commit c20ede00bb3c7df49110484380382326be005f84
Author: Bob Beck <beck@openssl.org>
Date: Wed Jan 21 11:47:37 2026 -0700
Ensure current_crl always points to the crl we are considering
As mentioned by Viktor Dukhovni, the desired behaviour is:
The current_crl is NULL when the running callback invocation is about errors
unrelated to validation failures via a particular CRL a user may want to
report the issuer of.
The current_crl is (whenever possible) not NULL when reporting errors
specifically related to that CRL.
The problem with this happens when we call check_crl with something that
is not what current_crl is set to. We can potentially enter the time check
code, and we then need to call the callback with the certificate that
failed the time check which is not current_crl.
Correct this by removing the dance in the time check code, and always
setting current_crl whenver we call check_crl.
This means that when we are considering a delta crl, we report the
correct crl to the callback, instead of possibly handing them NULL
(if they get called after a failing time check clobbers it), or the
non-delta crl (because we are looking at a delta while having
current_crl set to crl - which was why we had the dance in the time code
to begin with. We don't need to change current_crl in the time check
code if we always have current_crl set to the thing we are evaluting.
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
MergeDate: Tue Feb 3 08:50:52 2026
(Merged from https://github.com/openssl/openssl/pull/29679)
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index a789ec6f91..4b4a319d2e 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -1369,7 +1369,7 @@ static int check_cert_crl(X509_STORE_CTX *ctx)
ok = verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_GET_CRL);
goto done;
}
- ctx->current_crl = crl;
+
ok = ctx->check_crl(ctx, crl);
if (!ok)
goto done;
@@ -1437,9 +1437,6 @@ int ossl_x509_check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
if (!get_verification_time(ctx->param, &verification_time))
return 1;
- if (notify)
- ctx->current_crl = crl;
-
if (!certificate_time_to_posix(X509_CRL_get0_lastUpdate(crl),
&last_update)) {
err = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
@@ -1466,9 +1463,6 @@ int ossl_x509_check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
}
}
- if (notify)
- ctx->current_crl = NULL;
-
return 1;
}
@@ -1955,6 +1949,8 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
int cnum = ctx->error_depth;
int chnum = sk_X509_num(ctx->chain) - 1;
+ ctx->current_crl = crl;
+
/* If we have an alternative CRL issuer cert use that */
if (ctx->current_issuer != NULL) {
issuer = ctx->current_issuer;
diff --git a/doc/man3/X509_STORE_CTX_get_error.pod b/doc/man3/X509_STORE_CTX_get_error.pod
index c181b6a5a3..d0dc2aa730 100644
--- a/doc/man3/X509_STORE_CTX_get_error.pod
+++ b/doc/man3/X509_STORE_CTX_get_error.pod
@@ -6,6 +6,7 @@ X509_STORE_CTX_get_error, X509_STORE_CTX_set_error,
X509_STORE_CTX_get_error_depth, X509_STORE_CTX_set_error_depth,
X509_STORE_CTX_get_current_cert, X509_STORE_CTX_set_current_cert,
X509_STORE_CTX_get0_cert, X509_STORE_CTX_get1_chain,
+X509_STORE_CTX_get0_current_crl,
X509_verify_cert_error_string - get or set certificate verification status
information
@@ -20,8 +21,8 @@ information
X509 *X509_STORE_CTX_get_current_cert(const X509_STORE_CTX *ctx);
void X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x);
X509 *X509_STORE_CTX_get0_cert(const X509_STORE_CTX *ctx);
-
STACK_OF(X509) *X509_STORE_CTX_get1_chain(const X509_STORE_CTX *ctx);
+ X509_CRL *X509_STORE_CTX_get0_current_crl(const X509_STORE_CTX *ctx);
const char *X509_verify_cert_error_string(long n);
@@ -78,6 +79,15 @@ When it is no longer needed it should be free up using:
OSSL_STACK_OF_X509_free(chain);
+X509_STORE_CTX_get0_current_crl() returns an internal pointer to the
+possibly unverified CRL being actively considered during verification
+by the I<ctx>, or NULL. The returned value is NULL when the
+verification is not considering a specific CRL, or has finished CRL
+verification. As this pointer is an internal value used only during
+X509 verification, the values seen and order in which they are seen if
+called during the verification callback should not be relied upon to
+be consistent.
+
X509_verify_cert_error_string() returns a human readable error string for
verification error I<n>.
@@ -90,6 +100,9 @@ X509_STORE_CTX_get_error_depth() returns a nonnegative error depth.
X509_STORE_CTX_get_current_cert() returns the certificate which caused the
error or NULL if no certificate is relevant to the error.
+X509_STORE_CTX_get_current_crl() returns the CRL which caused the error
+or NULL if no CRL is relevant to the error.
+
X509_verify_cert_error_string() returns a human readable error string for
verification error I<n>.