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

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

commit f648cc1a12ec017cee3c50c5033293e012a60a68
Author: Mark Thomas <[email protected]>
AuthorDate: Tue Mar 24 11:00:32 2026 +0000

    Align behaviour (but not implementation) with Tomcat Native
---
 .../util/net/openssl/panama/OpenSSLEngine.java     |   7 ++
 .../net/ocsp/TestOcspSoftFailInternalError.java    | 110 +++++++++++++++++++++
 .../tomcat/util/net/ocsp/TesterOcspResponder.java  |   3 +-
 .../util/net/ocsp/TesterOcspResponderServlet.java  |   2 +
 4 files changed, 121 insertions(+), 1 deletion(-)

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 cd529e0fb4..9662da658d 100644
--- a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
+++ b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
@@ -1305,6 +1305,7 @@ public final class OpenSSLEngine extends SSLEngine 
implements SSLUtil.ProtocolIn
     private static int processOCSPRequest(EngineState state, URL url, 
MemorySegment issuer, MemorySegment x509,
             MemorySegment /* X509_STORE_CTX */ x509ctx, Arena localArena) {
         if (openssl_h_Compatibility.BORINGSSL || 
openssl_h_Compatibility.isLibreSSLPre35()) {
+            X509_STORE_CTX_set_error(x509ctx, X509_V_ERR_UNABLE_TO_GET_CRL());
             return V_OCSP_CERTSTATUS_UNKNOWN();
         }
         MemorySegment ocspRequest = MemorySegment.NULL;
@@ -1317,20 +1318,24 @@ public final class OpenSSLEngine extends SSLEngine 
implements SSLUtil.ProtocolIn
         try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
             ocspRequest = OCSP_REQUEST_new();
             if (MemorySegment.NULL.equals(ocspRequest)) {
+                X509_STORE_CTX_set_error(x509ctx, 
X509_V_ERR_UNABLE_TO_GET_CRL());
                 return V_OCSP_CERTSTATUS_UNKNOWN();
             }
             id = OCSP_cert_to_id(MemorySegment.NULL, x509, issuer);
             if (MemorySegment.NULL.equals(id)) {
+                X509_STORE_CTX_set_error(x509ctx, 
X509_V_ERR_UNABLE_TO_GET_CRL());
                 return V_OCSP_CERTSTATUS_UNKNOWN();
             }
             ocspOneReq = OCSP_request_add0_id(ocspRequest, id);
             if (MemorySegment.NULL.equals(ocspOneReq)) {
+                X509_STORE_CTX_set_error(x509ctx, 
X509_V_ERR_UNABLE_TO_GET_CRL());
                 return V_OCSP_CERTSTATUS_UNKNOWN();
             }
             OCSP_request_add1_nonce(ocspRequest, (char) 0, -1);
             MemorySegment bufPointer = 
localArena.allocateFrom(ValueLayout.ADDRESS, MemorySegment.NULL);
             int requestLength = i2d_OCSP_REQUEST(ocspRequest, bufPointer);
             if (requestLength <= 0) {
+                X509_STORE_CTX_set_error(x509ctx, 
X509_V_ERR_UNABLE_TO_GET_CRL());
                 return V_OCSP_CERTSTATUS_UNKNOWN();
             }
             MemorySegment buf = bufPointer.get(ValueLayout.ADDRESS, 0);
@@ -1352,6 +1357,7 @@ public final class OpenSSLEngine extends SSLEngine 
implements SSLUtil.ProtocolIn
             connection.getOutputStream().write(ocspRequestData);
             int responseCode = connection.getResponseCode();
             if (responseCode != HttpURLConnection.HTTP_OK) {
+                X509_STORE_CTX_set_error(x509ctx, 
X509_V_ERR_UNABLE_TO_GET_CRL());
                 return V_OCSP_CERTSTATUS_UNKNOWN();
             }
             InputStream is = connection.getInputStream();
@@ -1359,6 +1365,7 @@ public final class OpenSSLEngine extends SSLEngine 
implements SSLUtil.ProtocolIn
             byte[] responseBuf = new byte[1024];
             while ((read = is.read(responseBuf)) > 0) {
                 if (baos.size() > OCSP_MAX_RESPONSE_SIZE) {
+                    X509_STORE_CTX_set_error(x509ctx, 
X509_V_ERR_UNABLE_TO_GET_CRL());
                     return V_OCSP_CERTSTATUS_UNKNOWN();
                 }
                 baos.write(responseBuf, 0, read);
diff --git 
a/test/org/apache/tomcat/util/net/ocsp/TestOcspSoftFailInternalError.java 
b/test/org/apache/tomcat/util/net/ocsp/TestOcspSoftFailInternalError.java
new file mode 100644
index 0000000000..ff44881cdc
--- /dev/null
+++ b/test/org/apache/tomcat/util/net/ocsp/TestOcspSoftFailInternalError.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net.ocsp;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.net.ssl.SSLHandshakeException;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import org.apache.tomcat.util.net.ocsp.TesterOcspResponder.OcspResponse;
+
+@RunWith(Parameterized.class)
+public class TestOcspSoftFailInternalError extends OcspBaseTest {
+
+    private static TesterOcspResponder ocspResponder;
+
+    @BeforeClass
+    public static void startOcspResponder() {
+        ocspResponder = new TesterOcspResponder();
+        ocspResponder.setFixedResponse(OcspResponse.INTERNAL_ERROR);
+        try {
+            ocspResponder.start();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    @AfterClass
+    public static void stopOcspResponder() {
+        if (ocspResponder != null) {
+            ocspResponder.stop();
+            ocspResponder = null;
+        }
+    }
+
+
+    @Parameters(name = "{0} with OpenSSL trust {2}: softFail {4}, clientOk 
{5}")
+    public static Collection<Object[]> parameters() {
+        List<Object[]> parameterSets = new ArrayList<>();
+        Collection<Object[]> baseData = OcspBaseTest.parameters();
+
+        for (Object[] base : baseData) {
+            for (Boolean softFail : booleans) {
+                for (Boolean clientCertValid : booleans) {
+                    Boolean handshakeFailureExpected;
+
+                    if (softFail.booleanValue()) {
+                        handshakeFailureExpected = Boolean.FALSE;
+                    } else {
+                        handshakeFailureExpected = Boolean.TRUE;
+                    }
+
+                    parameterSets.add(new Object[] { base[0], base[1], 
base[2], base[3], softFail, clientCertValid,
+                            handshakeFailureExpected});
+                }
+            }
+        }
+        return parameterSets;
+    }
+
+    @Parameter(4)
+    public Boolean softFail;
+
+    @Parameter(5)
+    public boolean clientCertValid;
+
+    @Parameter(6)
+    public boolean handshakeFailureExpected;
+
+    @Test
+    public void test() throws Exception {
+        Assume.assumeNotNull(ocspResponder);
+        try {
+            doTest(clientCertValid, true, 
ClientCertificateVerification.ENABLED, false, softFail);
+            if (handshakeFailureExpected) {
+                Assert.fail("Handshake did not fail when expected to do so.");
+            }
+        } catch (SSLHandshakeException e) {
+            if (!handshakeFailureExpected) {
+                Assert.fail("Handshake failed when not expected to do so.");
+            }
+        }
+    }
+}
diff --git a/test/org/apache/tomcat/util/net/ocsp/TesterOcspResponder.java 
b/test/org/apache/tomcat/util/net/ocsp/TesterOcspResponder.java
index cc97773d52..2902109cc9 100644
--- a/test/org/apache/tomcat/util/net/ocsp/TesterOcspResponder.java
+++ b/test/org/apache/tomcat/util/net/ocsp/TesterOcspResponder.java
@@ -106,6 +106,7 @@ public class TesterOcspResponder {
         OK,
         REVOKED,
         UNKNOWN,
-        TRY_LATER
+        TRY_LATER,
+        INTERNAL_ERROR
     }
 }
diff --git 
a/test/org/apache/tomcat/util/net/ocsp/TesterOcspResponderServlet.java 
b/test/org/apache/tomcat/util/net/ocsp/TesterOcspResponderServlet.java
index e97639133e..0b39c206cf 100644
--- a/test/org/apache/tomcat/util/net/ocsp/TesterOcspResponderServlet.java
+++ b/test/org/apache/tomcat/util/net/ocsp/TesterOcspResponderServlet.java
@@ -247,6 +247,8 @@ public class TesterOcspResponderServlet extends HttpServlet 
{
                     case UNKNOWN:
                         responseBuilder.addResponse(certificateID, new 
UnknownStatus());
                         break;
+                    case INTERNAL_ERROR:
+                        throw new ServletException("Internal error");
                 }
             }
         }


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

Reply via email to