This is an automated email from the ASF dual-hosted git repository.
remm 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 175cdf4bb1 Avoid OpenSSL X509_STORE_CTX_get0_current_issuer function
175cdf4bb1 is described below
commit 175cdf4bb133fdd3e559738e7ac43c4ba9b0158b
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 b1e7855530..a2cab51f1d 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 f7395be35f..44bcad84db 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 ee2bbb5cd8..221f0ea15c 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]