]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Ensure current_crl always points to the crl we are considering
authorBob Beck <beck@openssl.org>
Wed, 21 Jan 2026 18:47:37 +0000 (11:47 -0700)
committerTomas Mraz <tomas@openssl.org>
Tue, 3 Feb 2026 08:50:50 +0000 (09:50 +0100)
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)

crypto/x509/x509_vfy.c
doc/man3/X509_STORE_CTX_get_error.pod

index a789ec6f9141e208bc317087076c811a5218eab4..4b4a319d2e8af68aba3feaa8ec78ab587cc6579f 100644 (file)
@@ -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;
index c181b6a5a3fd2b1e0e84eba133ab322f656d10fd..d0dc2aa730a2ad9aa470f4663ff6ce57a5c6ae61 100644 (file)
@@ -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>.