This is an automated email from the ASF dual-hosted git repository.
remm pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/11.0.x by this push:
new 616e88cca6 Avoid OpenSSL X509_STORE_CTX_get0_current_issuer function
616e88cca6 is described below
commit 616e88cca6e3c6b16b56593371b0e42661e6f454
Author: remm <[email protected]>
AuthorDate: Tue Oct 14 12:31:26 2025 +0200
Avoid OpenSSL X509_STORE_CTX_get0_current_issuer function
It is not documented and was then removed in BoringSSL.
Use X509_STORE_CTX_get1_issuer instead, which is documented and
available everywhere.
OCSP is different in BoringSSL, so skip it in the spot where it makes
sense to do it.
Skip one (failing) test for BoringSSL.
---
.../util/net/openssl/panama/OpenSSLEngine.java | 83 ++++++++++++----------
java/org/apache/tomcat/util/openssl/openssl_h.java | 34 ++++-----
.../tomcat/util/net/ocsp/TestOcspIntegration.java | 5 +-
webapps/docs/changelog.xml | 7 ++
4 files changed, 73 insertions(+), 56 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 b1ca5081a2..28a9879ddd 100644
--- a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
+++ b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
@@ -59,6 +59,7 @@ import org.apache.tomcat.util.buf.Asn1Parser;
import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.net.Constants;
import org.apache.tomcat.util.net.SSLUtil;
+import org.apache.tomcat.util.net.openssl.OpenSSLStatus;
import
org.apache.tomcat.util.net.openssl.ciphers.OpenSSLCipherConfigurationParser;
import org.apache.tomcat.util.openssl.SSL_CTX_set_verify$callback;
import org.apache.tomcat.util.openssl.SSL_set_info_callback$cb;
@@ -1200,46 +1201,53 @@ public final class OpenSSLEngine extends SSLEngine
implements SSLUtil.ProtocolIn
// don't do OCSP checking for valid self-issued certs
X509_STORE_CTX_set_error(x509ctx, X509_V_OK());
} else {
- // If we can't get the issuer, we cannot perform OCSP
verification
- MemorySegment issuer =
X509_STORE_CTX_get0_current_issuer(x509ctx);
- if (!MemorySegment.NULL.equals(issuer)) {
- // sslutils.c ssl_ocsp_request(x509, issuer, x509ctx);
- int nid = X509_get_ext_by_NID(x509, NID_info_access(), -1);
- if (nid >= 0) {
- try (var localArenal = Arena.ofConfined()) {
- MemorySegment ext = X509_get_ext(x509, nid);
- MemorySegment os = X509_EXTENSION_get_data(ext);
- int length = ASN1_STRING_length(os);
- MemorySegment data = ASN1_STRING_get0_data(os);
- // ocsp_urls = decode_OCSP_url(os);
- byte[] asn1String =
- data.reinterpret(length, localArenal,
null).toArray(ValueLayout.JAVA_BYTE);
- Asn1Parser parser = new Asn1Parser(asn1String);
- // Parse the byte sequence
- ArrayList<String> urls = new ArrayList<>();
- try {
- parseOCSPURLs(parser, urls);
- } catch (Exception e) {
-
log.error(sm.getString("engine.ocspParseError"), e);
- }
- if (!urls.isEmpty()) {
- // Use OpenSSL to build OCSP request
- for (String urlString : urls) {
- try {
- URL url = (new URI(urlString)).toURL();
- ocspResponse = processOCSPRequest(url,
issuer, x509, x509ctx, localArenal);
- if (log.isDebugEnabled()) {
-
log.debug(sm.getString("engine.ocspResponse", urlString,
-
Integer.toString(ocspResponse)));
+ try (var localArena = Arena.ofConfined()) {
+ // If we can't get the issuer, we cannot perform OCSP
verification
+ MemorySegment x509IssuerPointer =
localArena.allocateFrom(ValueLayout.ADDRESS, MemorySegment.NULL);
+ int res = X509_STORE_CTX_get1_issuer(x509IssuerPointer,
x509ctx, x509);
+ if (res > 0) {
+ MemorySegment issuer = MemorySegment.NULL;
+ try {
+ issuer =
x509IssuerPointer.get(ValueLayout.ADDRESS, 0);
+ // sslutils.c ssl_ocsp_request(x509, issuer,
x509ctx);
+ int nid = X509_get_ext_by_NID(x509,
NID_info_access(), -1);
+ if (nid >= 0) {
+ MemorySegment ext = X509_get_ext(x509, nid);
+ MemorySegment os =
X509_EXTENSION_get_data(ext);
+ int length = ASN1_STRING_length(os);
+ MemorySegment data = ASN1_STRING_get0_data(os);
+ // ocsp_urls = decode_OCSP_url(os);
+ byte[] asn1String =
+ data.reinterpret(length, localArena,
null).toArray(ValueLayout.JAVA_BYTE);
+ Asn1Parser parser = new Asn1Parser(asn1String);
+ // Parse the byte sequence
+ ArrayList<String> urls = new ArrayList<>();
+ try {
+ parseOCSPURLs(parser, urls);
+ } catch (Exception e) {
+
log.error(sm.getString("engine.ocspParseError"), e);
+ }
+ if (!urls.isEmpty()) {
+ // Use OpenSSL to build OCSP request
+ for (String urlString : urls) {
+ try {
+ URL url = (new
URI(urlString)).toURL();
+ ocspResponse =
processOCSPRequest(url, issuer, x509, x509ctx, localArena);
+ if (log.isDebugEnabled()) {
+
log.debug(sm.getString("engine.ocspResponse", urlString,
+
Integer.toString(ocspResponse)));
+ }
+ } catch (MalformedURLException |
URISyntaxException e) {
+
log.warn(sm.getString("engine.invalidOCSPURL", urlString));
+ }
+ if (ocspResponse !=
V_OCSP_CERTSTATUS_UNKNOWN()) {
+ break;
}
- } catch (MalformedURLException |
URISyntaxException e) {
-
log.warn(sm.getString("engine.invalidOCSPURL", urlString));
- }
- if (ocspResponse !=
V_OCSP_CERTSTATUS_UNKNOWN()) {
- break;
}
}
}
+ } finally {
+ X509_free(issuer);
}
}
}
@@ -1279,6 +1287,9 @@ public final class OpenSSLEngine extends SSLEngine
implements SSLUtil.ProtocolIn
private static int processOCSPRequest(URL url, MemorySegment issuer,
MemorySegment x509,
MemorySegment /* X509_STORE_CTX */ x509ctx, Arena localArena) {
+ if (OpenSSLStatus.Name.BORINGSSL.equals(OpenSSLStatus.getName())) {
+ return V_OCSP_CERTSTATUS_UNKNOWN();
+ }
MemorySegment ocspRequest = MemorySegment.NULL;
MemorySegment ocspResponse = MemorySegment.NULL;
MemorySegment id;
diff --git a/java/org/apache/tomcat/util/openssl/openssl_h.java
b/java/org/apache/tomcat/util/openssl/openssl_h.java
index 039126f12d..44edd4521d 100644
--- a/java/org/apache/tomcat/util/openssl/openssl_h.java
+++ b/java/org/apache/tomcat/util/openssl/openssl_h.java
@@ -3604,52 +3604,52 @@ public class openssl_h {
}
}
- private static class X509_STORE_CTX_get0_current_issuer {
- public static final FunctionDescriptor DESC =
FunctionDescriptor.of(openssl_h.C_POINTER, openssl_h.C_POINTER);
+ private static class X509_STORE_CTX_get1_issuer {
+ public static final FunctionDescriptor DESC =
FunctionDescriptor.of(openssl_h.C_INT, openssl_h.C_POINTER,
openssl_h.C_POINTER, openssl_h.C_POINTER);
- public static final MemorySegment ADDR =
openssl_h.findOrThrow("X509_STORE_CTX_get0_current_issuer");
+ public static final MemorySegment ADDR =
openssl_h.findOrThrow("X509_STORE_CTX_get1_issuer");
public static final MethodHandle HANDLE =
Linker.nativeLinker().downcallHandle(ADDR, DESC);
}
/**
* Function descriptor for:
- * {@snippet lang = c : * X509 *X509_STORE_CTX_get0_current_issuer(const
X509_STORE_CTX *ctx)
+ * {@snippet lang = c : * int X509_STORE_CTX_get1_issuer(X509 **issuer,
X509_STORE_CTX *ctx, X509 *x)
* }
*/
- public static FunctionDescriptor
X509_STORE_CTX_get0_current_issuer$descriptor() {
- return X509_STORE_CTX_get0_current_issuer.DESC;
+ public static FunctionDescriptor X509_STORE_CTX_get1_issuer$descriptor() {
+ return X509_STORE_CTX_get1_issuer.DESC;
}
/**
* Downcall method handle for:
- * {@snippet lang = c : * X509 *X509_STORE_CTX_get0_current_issuer(const
X509_STORE_CTX *ctx)
+ * {@snippet lang = c : * int X509_STORE_CTX_get1_issuer(X509 **issuer,
X509_STORE_CTX *ctx, X509 *x)
* }
*/
- public static MethodHandle X509_STORE_CTX_get0_current_issuer$handle() {
- return X509_STORE_CTX_get0_current_issuer.HANDLE;
+ public static MethodHandle X509_STORE_CTX_get1_issuer$handle() {
+ return X509_STORE_CTX_get1_issuer.HANDLE;
}
/**
* Address for:
- * {@snippet lang = c : * X509 *X509_STORE_CTX_get0_current_issuer(const
X509_STORE_CTX *ctx)
+ * {@snippet lang = c : * int X509_STORE_CTX_get1_issuer(X509 **issuer,
X509_STORE_CTX *ctx, X509 *x)
* }
*/
- public static MemorySegment X509_STORE_CTX_get0_current_issuer$address() {
- return X509_STORE_CTX_get0_current_issuer.ADDR;
+ public static MemorySegment X509_STORE_CTX_get1_issuer$address() {
+ return X509_STORE_CTX_get1_issuer.ADDR;
}
/**
- * {@snippet lang = c : * X509 *X509_STORE_CTX_get0_current_issuer(const
X509_STORE_CTX *ctx)
+ * {@snippet lang = c : * int X509_STORE_CTX_get1_issuer(X509 **issuer,
X509_STORE_CTX *ctx, X509 *x)
* }
*/
- public static MemorySegment
X509_STORE_CTX_get0_current_issuer(MemorySegment ctx) {
- var mh$ = X509_STORE_CTX_get0_current_issuer.HANDLE;
+ public static int X509_STORE_CTX_get1_issuer(MemorySegment issuer,
MemorySegment ctx, MemorySegment x) {
+ var mh$ = X509_STORE_CTX_get1_issuer.HANDLE;
try {
if (TRACE_DOWNCALLS) {
- traceDowncall("X509_STORE_CTX_get0_current_issuer", ctx);
+ traceDowncall("X509_STORE_CTX_get1_issuer", issuer, ctx, x);
}
- return (MemorySegment) mh$.invokeExact(ctx);
+ return (int) mh$.invokeExact(issuer, ctx, x);
} catch (Throwable ex$) {
throw new AssertionError("should not reach here", ex$);
}
diff --git a/test/org/apache/tomcat/util/net/ocsp/TestOcspIntegration.java
b/test/org/apache/tomcat/util/net/ocsp/TestOcspIntegration.java
index 33793d99e3..9012d7196a 100644
--- a/test/org/apache/tomcat/util/net/ocsp/TestOcspIntegration.java
+++ b/test/org/apache/tomcat/util/net/ocsp/TestOcspIntegration.java
@@ -164,6 +164,8 @@ public class TestOcspIntegration extends TomcatBaseTest {
@Test(expected = SSLHandshakeException.class)
public void testOcspRevoked_ServerVerifiesClientCertificateOnly() throws
Exception {
+ Assume.assumeFalse("BoringSSL does not support OCSP in a compatible
way",
+ TesterSupport.isOpenSSLVariant(sslImplementationName,
OpenSSLStatus.Name.BORINGSSL));
testOCSPWithClientResponder(OCSP_CLIENT_CERT_REVOKED_RESPONSE,
() -> testOCSP(OCSP_SERVER_CERT_GOOD_RESPONSE, true, false));
}
@@ -228,9 +230,6 @@ public class TestOcspIntegration extends TomcatBaseTest {
String sslImplementationName, boolean
useOpenSSL)
throws Exception {
- Assume.assumeFalse("BoringSSL does not allow supporting OCSP",
- TesterSupport.isOpenSSLVariant(sslImplementationName,
OpenSSLStatus.Name.BORINGSSL));
-
File certificateFile = new File(getPath(SERVER_CERTIFICATE_PATH));
File certificateKeyFile = new
File(getPath(SERVER_CERTIFICATE_KEY_PATH));
File certificateChainFile = new File(getPath(CA_CERTIFICATE_PATH));
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 986e8bb34b..986c5b7c31 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -114,6 +114,13 @@
</fix>
</changelog>
</subsection>
+ <subsection name="Coyote">
+ <changelog>
+ <fix>
+ Graceful failure for OCSP on BoringSSL in the FFM code. (remm)
+ </fix>
+ </changelog>
+ </subsection>
<subsection name="Other">
<changelog>
<update>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]