From: Bob Beck Date: Wed, 21 Jan 2026 18:47:37 +0000 (-0700) Subject: Ensure current_crl always points to the crl we are considering X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c20ede00bb3c7df49110484380382326be005f84;p=thirdparty%2Fopenssl.git 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 Reviewed-by: David von Oheimb Reviewed-by: Tomas Mraz 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 a789ec6f914..4b4a319d2e8 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 c181b6a5a3f..d0dc2aa730a 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, 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. @@ -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.