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 ff79ab05ed Improve allocation for certificates
ff79ab05ed is described below

commit ff79ab05edb8457543dbaeca2b450d868f2e1c3e
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 95ca9edf73..ce4b38aa1b 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 cbd8a5a0d4..e5e0eb8915 100644
--- a/java/org/apache/tomcat/util/openssl/openssl_h.java
+++ b/java/org/apache/tomcat/util/openssl/openssl_h.java
@@ -5945,50 +5945,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 f30ff1bfa4..3f4fb1b0b5 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.
@@ -150,24 +149,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 272ffe597e..ee70203f09 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]

Reply via email to