This is an automated email from the ASF dual-hosted git repository.

markt-asf pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.1.x by this push:
     new 68dcc40ec2 Stop OCSP checks once a cert in the trust store is reached
68dcc40ec2 is described below

commit 68dcc40ec209c81156a9832d3527c16bac290bfd
Author: Mark Thomas <[email protected]>
AuthorDate: Tue Sep 22 12:48:55 2026 +0100

    Stop OCSP checks once a cert in the trust store is reached
---
 .../util/net/openssl/panama/OpenSSLEngine.java     |  9 +++-
 java/org/apache/tomcat/util/openssl/openssl_h.java | 51 ++++++++++++++++++++++
 res/openssl/openssl-tomcat.conf                    |  1 +
 webapps/docs/changelog.xml                         |  8 ++++
 4 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java 
b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
index 3aa64aafd6..caa0cac64c 100644
--- a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
+++ b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
@@ -1234,8 +1234,13 @@ public final class OpenSSLEngine extends SSLEngine 
implements SSLUtil.ProtocolIn
             // No need to check cert->valid, because ssl_verify_OCSP() only
             // is called if OpenSSL already successfully verified the 
certificate
             // (parameter "ok" in SSL_callback_SSL_verify() must be true).
-            if (X509_check_issued(x509, x509) == X509_V_OK()) {
-                // don't do OCSP checking for valid self-issued certs
+            if (X509_check_issued(x509, x509) == X509_V_OK()
+                    || X509_STORE_CTX_get_error_depth(x509ctx) >= 
X509_STORE_CTX_get_num_untrusted(x509ctx)) {
+                // Don't do OCSP checking for valid self-issued certs, nor for 
a certificate that is itself
+                // a trust anchor (present directly in the configured trust 
store rather than supplied by the
+                // peer). A trust anchor is trusted unconditionally, so its 
own revocation status is not
+                // checked. This aligns with JSSE's PKIXRevocationChecker, 
which excludes the trust anchor
+                // of the certification path from revocation checking 
regardless of whether it is self-signed.
                 X509_STORE_CTX_set_error(x509ctx, X509_V_OK());
             } else {
                 try (var localArena = Arena.ofConfined()) {
diff --git a/java/org/apache/tomcat/util/openssl/openssl_h.java 
b/java/org/apache/tomcat/util/openssl/openssl_h.java
index 66b1a908c4..dfe65a0445 100644
--- a/java/org/apache/tomcat/util/openssl/openssl_h.java
+++ b/java/org/apache/tomcat/util/openssl/openssl_h.java
@@ -3703,6 +3703,57 @@ public class openssl_h {
         }
     }
 
+    private static class X509_STORE_CTX_get_num_untrusted {
+        public static final FunctionDescriptor DESC = 
FunctionDescriptor.of(openssl_h.C_INT, openssl_h.C_POINTER);
+
+        public static final MemorySegment ADDR = 
openssl_h.findOrThrow("X509_STORE_CTX_get_num_untrusted");
+
+        public static final MethodHandle HANDLE = 
Linker.nativeLinker().downcallHandle(ADDR, DESC);
+    }
+
+    /**
+     * Function descriptor for:
+     * {@snippet lang = c : * int 
X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx)
+     * }
+     */
+    public static FunctionDescriptor 
X509_STORE_CTX_get_num_untrusted$descriptor() {
+        return X509_STORE_CTX_get_num_untrusted.DESC;
+    }
+
+    /**
+     * Downcall method handle for:
+     * {@snippet lang = c : * int 
X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx)
+     * }
+     */
+    public static MethodHandle X509_STORE_CTX_get_num_untrusted$handle() {
+        return X509_STORE_CTX_get_num_untrusted.HANDLE;
+    }
+
+    /**
+     * Address for:
+     * {@snippet lang = c : * int 
X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx)
+     * }
+     */
+    public static MemorySegment X509_STORE_CTX_get_num_untrusted$address() {
+        return X509_STORE_CTX_get_num_untrusted.ADDR;
+    }
+
+    /**
+     * {@snippet lang = c : * int 
X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx)
+     * }
+     */
+    public static int X509_STORE_CTX_get_num_untrusted(MemorySegment ctx) {
+        var mh$ = X509_STORE_CTX_get_num_untrusted.HANDLE;
+        try {
+            if (TRACE_DOWNCALLS) {
+                traceDowncall("X509_STORE_CTX_get_num_untrusted", ctx);
+            }
+            return (int) mh$.invokeExact(ctx);
+        } catch (Throwable ex$) {
+            throw new AssertionError("should not reach here", ex$);
+        }
+    }
+
     private static class X509_STORE_CTX_get_current_cert {
         public static final FunctionDescriptor DESC = 
FunctionDescriptor.of(openssl_h.C_POINTER, openssl_h.C_POINTER);
 
diff --git a/res/openssl/openssl-tomcat.conf b/res/openssl/openssl-tomcat.conf
index e37bade4ef..921d65d944 100644
--- a/res/openssl/openssl-tomcat.conf
+++ b/res/openssl/openssl-tomcat.conf
@@ -350,6 +350,7 @@
 --include-function X509_STORE_CTX_get0_store                       # header: 
/usr/include/openssl/x509_vfy.h
 --include-function X509_STORE_CTX_get0_untrusted                   # header: 
/usr/include/openssl/x509_vfy.h
 --include-function X509_STORE_CTX_get1_issuer                      # header: 
/usr/include/openssl/x509_vfy.h
+--include-function X509_STORE_CTX_get_num_untrusted                 # header: 
/usr/include/openssl/x509_vfy.h
 --include-function X509_STORE_CTX_set_error                        # header: 
/usr/include/openssl/x509_vfy.h
 --include-function X509_STORE_set_flags                            # header: 
/usr/include/openssl/x509_vfy.h
 --include-constant X509_L_ADD_DIR                                     # 
header: /usr/include/openssl/x509_vfy.h
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 1ff8129618..be7615ad25 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -399,6 +399,14 @@
         signed <code>int</code> limitation rather than misreporting it as an
         invalid length. (michaelo)
       </fix>
+      <fix>
+        Align the OCSP checking performed by the OpenSSL/Panama based
+        implementation of <code>SSLEngine</code> with the behaviour of the
+        JSSE based implementation so that a certificate that is itself a
+        trust anchor (whether a self-signed root or a certificate trusted
+        directly via the configured trust store) is not subject to OCSP
+        checking. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to