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 a61a49d64e Improve allocation for certificates
a61a49d64e is described below
commit a61a49d64e8ca115a612828bff157115df5742c1
Author: remm <[email protected]>
AuthorDate: Mon Feb 23 15:08:49 2026 +0100
Improve allocation for certificates
Using SSL_get0_peer_certificate seems preferable for OpenSSL 3.
Also call free if getting the bytes from the certificate somehow fails
(PR 951 submitted by Chenjp).
---
.../util/net/openssl/panama/OpenSSLEngine.java | 12 ++++++--
java/org/apache/tomcat/util/openssl/openssl_h.java | 30 ++++++++++----------
.../util/openssl/openssl_h_Compatibility.java | 32 ++++++++++------------
res/openssl/openssl-tomcat.conf | 2 +-
webapps/docs/changelog.xml | 5 ++++
5 files changed, 46 insertions(+), 35 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 b940185aa0..1d5175b3c0 100644
--- a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
+++ b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
@@ -830,15 +830,23 @@ public final class OpenSSLEngine extends SSLEngine
implements SSLUtil.ProtocolIn
private byte[] getPeerCertificate() {
try (var localArena = Arena.ofConfined()) {
- MemorySegment/* (X509*) */ x509 =
openssl_h_Compatibility.SSL_get_peer_certificate(state.ssl);
+ // Use the new SSL_get0_peer_certificate call for OpenSSL 3+ to
avoid having to call free
+ MemorySegment/* (X509*) */ x509 =
+ (openssl_h_Compatibility.OPENSSL3) ?
SSL_get0_peer_certificate(state.ssl)
+ :
openssl_h_Compatibility.SSL_get_peer_certificate(state.ssl);
MemorySegment bufPointer =
localArena.allocateFrom(ValueLayout.ADDRESS, MemorySegment.NULL);
int length = i2d_X509(x509, bufPointer);
if (length <= 0) {
+ if (!openssl_h_Compatibility.OPENSSL3) {
+ X509_free(x509);
+ }
return null;
}
MemorySegment buf = bufPointer.get(ValueLayout.ADDRESS, 0);
byte[] certificate = buf.reinterpret(length, localArena,
null).toArray(ValueLayout.JAVA_BYTE);
- X509_free(x509);
+ if (!openssl_h_Compatibility.OPENSSL3) {
+ X509_free(x509);
+ }
OPENSSL_free(buf);
return certificate;
}
diff --git a/java/org/apache/tomcat/util/openssl/openssl_h.java
b/java/org/apache/tomcat/util/openssl/openssl_h.java
index e7fc063889..6d1ac8f98a 100644
--- a/java/org/apache/tomcat/util/openssl/openssl_h.java
+++ b/java/org/apache/tomcat/util/openssl/openssl_h.java
@@ -5946,50 +5946,50 @@ public class openssl_h {
}
}
- private static class SSL_get1_peer_certificate {
+ private static class SSL_get0_peer_certificate {
public static final FunctionDescriptor DESC =
FunctionDescriptor.of(openssl_h.C_POINTER, openssl_h.C_POINTER);
- public static final MemorySegment ADDR =
openssl_h.findOrThrow("SSL_get1_peer_certificate");
+ public static final MemorySegment ADDR =
openssl_h.findOrThrow("SSL_get0_peer_certificate");
public static final MethodHandle HANDLE =
Linker.nativeLinker().downcallHandle(ADDR, DESC);
}
/**
* Function descriptor for:
- * {@snippet lang = c : * X509 *SSL_get1_peer_certificate(const SSL *s)
+ * {@snippet lang = c : * X509 *SSL_get0_peer_certificate(const SSL *s)
* }
*/
- public static FunctionDescriptor SSL_get1_peer_certificate$descriptor() {
- return SSL_get1_peer_certificate.DESC;
+ public static FunctionDescriptor SSL_get0_peer_certificate$descriptor() {
+ return SSL_get0_peer_certificate.DESC;
}
/**
* Downcall method handle for:
- * {@snippet lang = c : * X509 *SSL_get1_peer_certificate(const SSL *s)
+ * {@snippet lang = c : * X509 *SSL_get0_peer_certificate(const SSL *s)
* }
*/
- public static MethodHandle SSL_get1_peer_certificate$handle() {
- return SSL_get1_peer_certificate.HANDLE;
+ public static MethodHandle SSL_get0_peer_certificate$handle() {
+ return SSL_get0_peer_certificate.HANDLE;
}
/**
* Address for:
- * {@snippet lang = c : * X509 *SSL_get1_peer_certificate(const SSL *s)
+ * {@snippet lang = c : * X509 *SSL_get0_peer_certificate(const SSL *s)
* }
*/
- public static MemorySegment SSL_get1_peer_certificate$address() {
- return SSL_get1_peer_certificate.ADDR;
+ public static MemorySegment SSL_get0_peer_certificate$address() {
+ return SSL_get0_peer_certificate.ADDR;
}
/**
- * {@snippet lang = c : * X509 *SSL_get1_peer_certificate(const SSL *s)
+ * {@snippet lang = c : * X509 *SSL_get0_peer_certificate(const SSL *s)
* }
*/
- public static MemorySegment SSL_get1_peer_certificate(MemorySegment s) {
- var mh$ = SSL_get1_peer_certificate.HANDLE;
+ public static MemorySegment SSL_get0_peer_certificate(MemorySegment s) {
+ var mh$ = SSL_get0_peer_certificate.HANDLE;
try {
if (TRACE_DOWNCALLS) {
- traceDowncall("SSL_get1_peer_certificate", s);
+ traceDowncall("SSL_get0_peer_certificate", s);
}
return (MemorySegment) mh$.invokeExact(s);
} catch (Throwable ex$) {
diff --git a/java/org/apache/tomcat/util/openssl/openssl_h_Compatibility.java
b/java/org/apache/tomcat/util/openssl/openssl_h_Compatibility.java
index 8711b4c697..dfb231836d 100644
--- a/java/org/apache/tomcat/util/openssl/openssl_h_Compatibility.java
+++ b/java/org/apache/tomcat/util/openssl/openssl_h_Compatibility.java
@@ -22,7 +22,6 @@ import java.lang.foreign.*;
import static java.lang.foreign.ValueLayout.*;
import static org.apache.tomcat.util.openssl.openssl_h.OpenSSL_version;
import static org.apache.tomcat.util.openssl.openssl_h.OpenSSL_version_num;
-import static
org.apache.tomcat.util.openssl.openssl_h.SSL_get1_peer_certificate;
/**
* Methods used present in older OpenSSL versions but not in the current major
version or OpenSSL derivatives.
@@ -151,24 +150,23 @@ public class openssl_h_Compatibility {
// OpenSSL 1.1 SSL_get_peer_certificate
public static MemorySegment SSL_get_peer_certificate(MemorySegment s) {
if (OPENSSL3) {
- // This could be using SSL_get0_peer_certificate instead, but all
the other implementations
+ // This could be using SSL_get1_peer_certificate instead, as all
the other implementations
// use SSL_get_peer_certificate which is equivalent to
SSL_get1_peer_certificate
- return SSL_get1_peer_certificate(s);
- } else {
- class Holder {
- static final String NAME = "SSL_get_peer_certificate";
- static final FunctionDescriptor DESC =
FunctionDescriptor.of(openssl_h.C_POINTER, openssl_h.C_POINTER);
- static final MethodHandle MH =
Linker.nativeLinker().downcallHandle(openssl_h.findOrThrow(NAME), DESC);
- }
- var mh$ = Holder.MH;
- try {
- if (openssl_h.TRACE_DOWNCALLS) {
- openssl_h.traceDowncall(Holder.NAME, s);
- }
- return (java.lang.foreign.MemorySegment) mh$.invokeExact(s);
- } catch (Throwable ex$) {
- throw new AssertionError("should not reach here", ex$);
+ return MemorySegment.NULL;
+ }
+ class Holder {
+ static final String NAME = "SSL_get_peer_certificate";
+ static final FunctionDescriptor DESC =
FunctionDescriptor.of(openssl_h.C_POINTER, openssl_h.C_POINTER);
+ static final MethodHandle MH =
Linker.nativeLinker().downcallHandle(openssl_h.findOrThrow(NAME), DESC);
+ }
+ var mh$ = Holder.MH;
+ try {
+ if (openssl_h.TRACE_DOWNCALLS) {
+ openssl_h.traceDowncall(Holder.NAME, s);
}
+ return (java.lang.foreign.MemorySegment) mh$.invokeExact(s);
+ } catch (Throwable ex$) {
+ throw new AssertionError("should not reach here", ex$);
}
}
diff --git a/res/openssl/openssl-tomcat.conf b/res/openssl/openssl-tomcat.conf
index 337e7a831e..e37bade4ef 100644
--- a/res/openssl/openssl-tomcat.conf
+++ b/res/openssl/openssl-tomcat.conf
@@ -220,7 +220,7 @@
--include-function SSL_get_shutdown # header:
/usr/include/openssl/ssl.h
--include-function SSL_get_version # header:
/usr/include/openssl/ssl.h
--include-function SSL_get0_alpn_selected # header:
/usr/include/openssl/ssl.h
---include-function SSL_get1_peer_certificate # header:
/usr/include/openssl/ssl.h
+--include-function SSL_get0_peer_certificate # header:
/usr/include/openssl/ssl.h
--include-function SSL_in_init # header:
/usr/include/openssl/ssl.h
--include-function SSL_load_client_CA_file # header:
/usr/include/openssl/ssl.h
--include-function SSL_new # header:
/usr/include/openssl/ssl.h
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index c55a5adf3b..b03ea79eb5 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -153,6 +153,11 @@
following the addition of TLS 1.3 specific cipher configuration.
TLS 1.3 ciphers will always be first in the list. (remm)
</fix>
+ <fix>
+ Free the x509 object in the FFM code when getting the peer certificate
+ if getting the bytes from the certificate somehow fails.
+ Pull request <pr>951</pr> provided by Chenjp. (remm)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]