This is an automated email from the ASF dual-hosted git repository.
remm pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push:
new f8113f143d Avoid OpenSSL X509_STORE_CTX_get0_current_issuer function
f8113f143d is described below
commit f8113f143d2123c609f2112bbcb4f1773f23c016
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 d400570079..60f9c61524 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 ad57e51fd1..dfef9e2e2c 100644
--- a/test/org/apache/tomcat/util/net/ocsp/TestOcspIntegration.java
+++ b/test/org/apache/tomcat/util/net/ocsp/TestOcspIntegration.java
@@ -163,6 +163,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));
}
@@ -232,9 +234,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 8a1f106c6f..8340d5a134 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]