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>.