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

commit b978d153aff7ec24b8e562bd247ddf956626d523
Author: remm <r...@apache.org>
AuthorDate: Wed Jul 3 15:08:43 2024 +0200

    Add basic LibreSSL support
    
    Client cert and similar do not appear to work ("no renegotiation" error
    seen on the client).
    Skip conf test.
    Update the MacOS default behavior using two system properties.
---
 .../util/net/openssl/panama/OpenSSLContext.java    |  35 +++----
 .../util/net/openssl/panama/OpenSSLEngine.java     |  21 +++--
 .../util/net/openssl/panama/OpenSSLLibrary.java    |   7 +-
 java/org/apache/tomcat/util/openssl/openssl_h.java |  52 +++++++++--
 .../util/openssl/openssl_h_Compatibility.java      | 101 +++++++++++++++++++++
 .../tomcat/util/net/openssl/TestOpenSSLConf.java   |   1 +
 webapps/docs/changelog.xml                         |  12 +++
 webapps/docs/config/systemprops.xml                |  13 +++
 8 files changed, 205 insertions(+), 37 deletions(-)

diff --git a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java 
b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
index 3dedf0fd22..e186586d78 100644
--- a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
+++ b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
@@ -66,6 +66,7 @@ import 
org.apache.tomcat.util.openssl.SSL_CTX_set_alpn_select_cb$cb;
 import org.apache.tomcat.util.openssl.SSL_CTX_set_cert_verify_callback$cb;
 import org.apache.tomcat.util.openssl.SSL_CTX_set_tmp_dh_callback$dh;
 import org.apache.tomcat.util.openssl.SSL_CTX_set_verify$callback;
+import org.apache.tomcat.util.openssl.openssl_h_Compatibility;
 import org.apache.tomcat.util.openssl.pem_password_cb;
 import org.apache.tomcat.util.res.StringManager;
 
@@ -135,13 +136,13 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
 
     private static String[] getCiphers(MemorySegment sslCtx) {
         MemorySegment sk = SSL_CTX_get_ciphers(sslCtx);
-        int len = OPENSSL_sk_num(sk);
+        int len = openssl_h_Compatibility.OPENSSL_sk_num(sk);
         if (len <= 0) {
             return null;
         }
         ArrayList<String> ciphers = new ArrayList<>(len);
         for (int i = 0; i < len; i++) {
-            MemorySegment cipher = OPENSSL_sk_value(sk, i);
+            MemorySegment cipher = 
openssl_h_Compatibility.OPENSSL_sk_value(sk, i);
             MemorySegment cipherName = SSL_CIPHER_get_name(cipher);
             ciphers.add(cipherName.getString(0));
         }
@@ -243,14 +244,14 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
             SSL_CTX_set_min_proto_version(sslCtx, prot);
 
             // Disable compression, usually unsafe
-            SSL_CTX_set_options(sslCtx, SSL_OP_NO_COMPRESSION());
+            openssl_h_Compatibility.SSL_CTX_set_options(sslCtx, 
SSL_OP_NO_COMPRESSION());
 
             // Disallow a session from being resumed during a renegotiation,
             // so that an acceptable cipher suite can be negotiated.
-            SSL_CTX_set_options(sslCtx, 
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION());
+            openssl_h_Compatibility.SSL_CTX_set_options(sslCtx, 
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION());
 
-            SSL_CTX_set_options(sslCtx, SSL_OP_SINGLE_DH_USE());
-            SSL_CTX_set_options(sslCtx, SSL_OP_SINGLE_ECDH_USE());
+            openssl_h_Compatibility.SSL_CTX_set_options(sslCtx, 
SSL_OP_SINGLE_DH_USE());
+            openssl_h_Compatibility.SSL_CTX_set_options(sslCtx, 
SSL_OP_SINGLE_ECDH_USE());
 
             // Default session context id and cache size
             SSL_CTX_sess_set_cache_size(sslCtx, 256);
@@ -463,31 +464,31 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
         boolean success = true;
         try (var localArena = Arena.ofConfined()) {
             if (sslHostConfig.getInsecureRenegotiation()) {
-                SSL_CTX_set_options(state.sslCtx, 
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION());
+                openssl_h_Compatibility.SSL_CTX_set_options(state.sslCtx, 
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION());
             } else {
-                SSL_CTX_clear_options(state.sslCtx, 
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION());
+                openssl_h_Compatibility.SSL_CTX_clear_options(state.sslCtx, 
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION());
             }
 
             // Use server's preference order for ciphers (rather than
             // client's)
             if (sslHostConfig.getHonorCipherOrder()) {
-                SSL_CTX_set_options(state.sslCtx, 
SSL_OP_CIPHER_SERVER_PREFERENCE());
+                openssl_h_Compatibility.SSL_CTX_set_options(state.sslCtx, 
SSL_OP_CIPHER_SERVER_PREFERENCE());
             } else {
-                SSL_CTX_clear_options(state.sslCtx, 
SSL_OP_CIPHER_SERVER_PREFERENCE());
+                openssl_h_Compatibility.SSL_CTX_clear_options(state.sslCtx, 
SSL_OP_CIPHER_SERVER_PREFERENCE());
             }
 
             // Disable compression if requested
             if (sslHostConfig.getDisableCompression()) {
-                SSL_CTX_set_options(state.sslCtx, SSL_OP_NO_COMPRESSION());
+                openssl_h_Compatibility.SSL_CTX_set_options(state.sslCtx, 
SSL_OP_NO_COMPRESSION());
             } else {
-                SSL_CTX_clear_options(state.sslCtx, SSL_OP_NO_COMPRESSION());
+                openssl_h_Compatibility.SSL_CTX_clear_options(state.sslCtx, 
SSL_OP_NO_COMPRESSION());
             }
 
             // Disable TLS Session Tickets (RFC4507) to protect perfect 
forward secrecy
             if (sslHostConfig.getDisableSessionTickets()) {
-                SSL_CTX_set_options(state.sslCtx, SSL_OP_NO_TICKET());
+                openssl_h_Compatibility.SSL_CTX_set_options(state.sslCtx, 
SSL_OP_NO_TICKET());
             } else {
-                SSL_CTX_clear_options(state.sslCtx, SSL_OP_NO_TICKET());
+                openssl_h_Compatibility.SSL_CTX_clear_options(state.sslCtx, 
SSL_OP_NO_TICKET());
             }
 
             // List the ciphers that the client is permitted to negotiate
@@ -622,7 +623,7 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
                     log.error(sm.getString("openssl.errApplyConf"), e);
                 }
                 // Reconfigure the enabled protocols
-                long opts = SSL_CTX_get_options(state.sslCtx);
+                long opts = 
openssl_h_Compatibility.SSL_CTX_get_options(state.sslCtx);
                 List<String> enabled = new ArrayList<>();
                 // Seems like there is no way to explicitly disable SSLv2Hello
                 // in OpenSSL so it is always enabled
@@ -757,11 +758,11 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
             }
             MemorySegment ssl = X509_STORE_CTX_get_ex_data(x509_ctx, 
SSL_get_ex_data_X509_STORE_CTX_idx());
             MemorySegment /*STACK_OF(X509)*/ sk = 
X509_STORE_CTX_get0_untrusted(x509_ctx);
-            int len = OPENSSL_sk_num(sk);
+            int len = openssl_h_Compatibility.OPENSSL_sk_num(sk);
             byte[][] certificateChain = new byte[len][];
             try (var localArena = Arena.ofConfined()) {
                 for (int i = 0; i < len; i++) {
-                    MemorySegment/*(X509*)*/ x509 = OPENSSL_sk_value(sk, i);
+                    MemorySegment/*(X509*)*/ x509 = 
openssl_h_Compatibility.OPENSSL_sk_value(sk, i);
                     MemorySegment bufPointer = 
localArena.allocateFrom(ValueLayout.ADDRESS, MemorySegment.NULL);
                     int length = i2d_X509(x509, bufPointer);
                     if (length < 0) {
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 5d3f5b0e8a..053d4747cf 100644
--- a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
+++ b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
@@ -64,6 +64,7 @@ import 
org.apache.tomcat.util.net.openssl.ciphers.OpenSSLCipherConfigurationPars
 import org.apache.tomcat.util.openssl.SSL_CTX_set_verify$callback;
 import org.apache.tomcat.util.openssl.SSL_set_info_callback$cb;
 import org.apache.tomcat.util.openssl.SSL_set_verify$callback;
+import org.apache.tomcat.util.openssl.openssl_h_Compatibility;
 import org.apache.tomcat.util.res.StringManager;
 
 /**
@@ -719,7 +720,7 @@ public final class OpenSSLEngine extends SSLEngine 
implements SSLUtil.ProtocolIn
         List<String> enabled = new ArrayList<>();
         // Seems like there is no way to explicitly disable SSLv2Hello in 
OpenSSL so it is always enabled
         enabled.add(Constants.SSL_PROTO_SSLv2Hello);
-        long opts = SSL_get_options(state.ssl);
+        long opts = openssl_h_Compatibility.SSL_get_options(state.ssl);
         if ((opts & SSL_OP_NO_TLSv1()) == 0) {
             enabled.add(Constants.SSL_PROTO_TLSv1);
         }
@@ -783,25 +784,25 @@ public final class OpenSSLEngine extends SSLEngine 
implements SSLUtil.ProtocolIn
             }
         }
         // Enable all and then disable what we not want
-        SSL_set_options(state.ssl, SSL_OP_ALL());
+        openssl_h_Compatibility.SSL_set_options(state.ssl, SSL_OP_ALL());
 
         if (!sslv2) {
-            SSL_set_options(state.ssl, SSL_OP_NO_SSLv2());
+            openssl_h_Compatibility.SSL_set_options(state.ssl, 
SSL_OP_NO_SSLv2());
         }
         if (!sslv3) {
-            SSL_set_options(state.ssl, SSL_OP_NO_SSLv3());
+            openssl_h_Compatibility.SSL_set_options(state.ssl, 
SSL_OP_NO_SSLv3());
         }
         if (!tlsv1) {
-            SSL_set_options(state.ssl, SSL_OP_NO_TLSv1());
+            openssl_h_Compatibility.SSL_set_options(state.ssl, 
SSL_OP_NO_TLSv1());
         }
         if (!tlsv1_1) {
-            SSL_set_options(state.ssl, SSL_OP_NO_TLSv1_1());
+            openssl_h_Compatibility.SSL_set_options(state.ssl, 
SSL_OP_NO_TLSv1_1());
         }
         if (!tlsv1_2) {
-            SSL_set_options(state.ssl, SSL_OP_NO_TLSv1_2());
+            openssl_h_Compatibility.SSL_set_options(state.ssl, 
SSL_OP_NO_TLSv1_2());
         }
         if (!tlsv1_3) {
-            SSL_set_options(state.ssl, SSL_OP_NO_TLSv1_3());
+            openssl_h_Compatibility.SSL_set_options(state.ssl, 
SSL_OP_NO_TLSv1_3());
         }
     }
 
@@ -853,14 +854,14 @@ public final class OpenSSLEngine extends SSLEngine 
implements SSLUtil.ProtocolIn
 
     private byte[][] getPeerCertChain() {
         MemorySegment/*STACK_OF(X509)*/ sk = 
SSL_get_peer_cert_chain(state.ssl);
-        int len = OPENSSL_sk_num(sk);
+        int len = openssl_h_Compatibility.OPENSSL_sk_num(sk);
         if (len <= 0) {
             return null;
         }
         byte[][] certificateChain = new byte[len][];
         try (var localArena = Arena.ofConfined()) {
             for (int i = 0; i < len; i++) {
-                MemorySegment/*(X509*)*/ x509 = OPENSSL_sk_value(sk, i);
+                MemorySegment/*(X509*)*/ x509 = 
openssl_h_Compatibility.OPENSSL_sk_value(sk, i);
                 MemorySegment bufPointer = 
localArena.allocateFrom(ValueLayout.ADDRESS, MemorySegment.NULL);
                 int length = i2d_X509(x509, bufPointer);
                 if (length < 0) {
diff --git a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java 
b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java
index 8ca86e68e2..37f313e628 100644
--- a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java
+++ b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java
@@ -30,6 +30,7 @@ import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.net.openssl.OpenSSLStatus;
 import 
org.apache.tomcat.util.net.openssl.ciphers.OpenSSLCipherConfigurationParser;
+import org.apache.tomcat.util.openssl.openssl_h_Compatibility;
 import org.apache.tomcat.util.res.StringManager;
 
 
@@ -421,7 +422,7 @@ public class OpenSSLLibrary {
             initLibrary();
             var sslCtx = SSL_CTX_new(TLS_server_method());
             try {
-                SSL_CTX_set_options(sslCtx, SSL_OP_ALL());
+                openssl_h_Compatibility.SSL_CTX_set_options(sslCtx, 
SSL_OP_ALL());
                 SSL_CTX_set_cipher_list(sslCtx, 
localArena.allocateFrom(ciphers));
                 var ssl = SSL_new(sslCtx);
                 SSL_set_accept_state(ssl);
@@ -447,13 +448,13 @@ public class OpenSSLLibrary {
 
     static String[] getCiphers(MemorySegment ssl) {
         MemorySegment sk = SSL_get_ciphers(ssl);
-        int len = OPENSSL_sk_num(sk);
+        int len = openssl_h_Compatibility.OPENSSL_sk_num(sk);
         if (len <= 0) {
             return null;
         }
         ArrayList<String> ciphers = new ArrayList<>(len);
         for (int i = 0; i < len; i++) {
-            MemorySegment cipher = OPENSSL_sk_value(sk, i);
+            MemorySegment cipher = 
openssl_h_Compatibility.OPENSSL_sk_value(sk, i);
             MemorySegment cipherName = SSL_CIPHER_get_name(cipher);
             ciphers.add(cipherName.getString(0));
         }
diff --git a/java/org/apache/tomcat/util/openssl/openssl_h.java 
b/java/org/apache/tomcat/util/openssl/openssl_h.java
index d3290392a9..c05333b953 100644
--- a/java/org/apache/tomcat/util/openssl/openssl_h.java
+++ b/java/org/apache/tomcat/util/openssl/openssl_h.java
@@ -32,6 +32,14 @@ import static java.lang.foreign.ValueLayout.*;
 @SuppressWarnings({"javadoc", "boxing"})
 public class openssl_h {
 
+    /*
+     * On Mac OS SymbolLookup.libraryLookup() appears to ignore 
java.library.path which means the LibreSSL
+     * library will be found which will then fail. Therefore, skip that lookup 
on Mac OS.
+     */
+    public static final boolean USE_SYSTEM_LOAD_LIBRARY = 
Boolean.getBoolean("org.apache.tomcat.util.openssl.USE_SYSTEM_LOAD_LIBRARY");
+    public static final String LIBRARY_NAME = 
System.getProperty("org.apache.tomcat.util.openssl.LIBRARY_NAME",
+            (JrePlatform.IS_MAC_OS) ? "ssl.48" : "ssl");
+
     openssl_h() {
         // Suppresses public default constructor, ensuring non-instantiability,
         // but allows generated subclasses in same package.
@@ -52,15 +60,11 @@ public class openssl_h {
     static final boolean TRACE_DOWNCALLS = 
Boolean.getBoolean("jextract.trace.downcalls");
     static final SymbolLookup SYMBOL_LOOKUP;
     static {
-        if (JrePlatform.IS_MAC_OS) {
-            /*
-             * On Mac OS SymbolLookup.libraryLookup() appears to ignore 
java.library.path which means the LibreSSL
-             * library will be found which will then fail. Therefore, skip 
that lookup on Mac OS.
-             */
-            System.loadLibrary("ssl");
+        if (USE_SYSTEM_LOAD_LIBRARY) {
+            System.loadLibrary(LIBRARY_NAME);
             SYMBOL_LOOKUP = 
SymbolLookup.loaderLookup().or(Linker.nativeLinker().defaultLookup());
         } else {
-            SYMBOL_LOOKUP = 
SymbolLookup.libraryLookup(System.mapLibraryName("ssl"), LIBRARY_ARENA)
+            SYMBOL_LOOKUP = 
SymbolLookup.libraryLookup(System.mapLibraryName(LIBRARY_NAME), LIBRARY_ARENA)
                     .or(SymbolLookup.loaderLookup())
                     .or(Linker.nativeLinker().defaultLookup());
         }
@@ -4262,6 +4266,40 @@ public class openssl_h {
         }
     }
 
+    private static MethodHandle SSL_ctrl$MH() {
+        class Holder {
+            static final FunctionDescriptor DESC = FunctionDescriptor.of(
+                openssl_h.C_LONG,
+                openssl_h.C_POINTER,
+                openssl_h.C_INT,
+                openssl_h.C_LONG,
+                openssl_h.C_POINTER
+            );
+
+            static final MethodHandle MH = 
Linker.nativeLinker().downcallHandle(
+                    openssl_h.findOrThrow("SSL_ctrl"),
+                    DESC);
+        }
+        return Holder.MH;
+    }
+
+    /**
+     * {@snippet lang=c :
+     * long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg)
+     * }
+     */
+    public static long SSL_ctrl(MemorySegment ssl, int cmd, long larg, 
MemorySegment parg) {
+        var mh$ = SSL_ctrl$MH();
+        try {
+            if (TRACE_DOWNCALLS) {
+                traceDowncall("SSL_ctrl", ssl, cmd, larg, parg);
+            }
+            return (long) mh$.invokeExact(ssl, cmd, larg, parg);
+        } catch (Throwable ex$) {
+           throw new AssertionError("should not reach here", ex$);
+        }
+    }
+
     private static MethodHandle SSL_get_version$MH() {
         class Holder {
             static final FunctionDescriptor DESC = FunctionDescriptor.of(
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 df2709ff6f..07513af8be 100644
--- a/java/org/apache/tomcat/util/openssl/openssl_h_Compatibility.java
+++ b/java/org/apache/tomcat/util/openssl/openssl_h_Compatibility.java
@@ -20,12 +20,18 @@ package org.apache.tomcat.util.openssl;
 import java.lang.invoke.MethodHandle;
 import java.lang.foreign.*;
 import static java.lang.foreign.ValueLayout.*;
+import static org.apache.tomcat.util.openssl.openssl_h.OpenSSL_version;
 
 /**
  * Methods used present in older OpenSSL versions but not in the current major 
version.
  */
 public class openssl_h_Compatibility {
 
+    public static final boolean LIBRESSL;
+    static {
+        LIBRESSL = OpenSSL_version(0).getString(0).contains("LibreSSL");
+    }
+
     // OpenSSL 1.1 FIPS_mode
     public static int FIPS_mode() {
         class Holder {
@@ -116,5 +122,100 @@ public class openssl_h_Compatibility {
         }
     }
 
+    // LibreSSL SSL_CTRL_OPTIONS
+    public static final int SSL_CTRL_OPTIONS = 32;
+
+    // LibreSSL SSL_CTX_get_options
+    public static long SSL_CTX_get_options(MemorySegment ctx) {
+        if (LIBRESSL) {
+            return openssl_h.SSL_CTX_ctrl(ctx, SSL_CTRL_OPTIONS, 0, 
MemorySegment.NULL);
+        } else {
+            return openssl_h.SSL_CTX_get_options(ctx);
+        }
+    }
+
+    // LibreSSL SSL_CTX_set_options
+    public static long SSL_CTX_set_options(MemorySegment ctx, long op) {
+        if (LIBRESSL) {
+            return openssl_h.SSL_CTX_ctrl(ctx, SSL_CTRL_OPTIONS, op, 
MemorySegment.NULL);
+        } else {
+            return openssl_h.SSL_CTX_set_options(ctx, op);
+        }
+    }
+
+    // LibreSSL SSL_get_options
+    public static long SSL_get_options(MemorySegment s) {
+        if (LIBRESSL) {
+            return openssl_h.SSL_ctrl(s, SSL_CTRL_OPTIONS, 0, 
MemorySegment.NULL);
+        } else {
+            return openssl_h.SSL_get_options(s);
+        }
+    }
+
+    // LibreSSL SSL_set_options
+    public static long SSL_set_options(MemorySegment s, long op) {
+        if (LIBRESSL) {
+            return openssl_h.SSL_ctrl(s, SSL_CTRL_OPTIONS, op, 
MemorySegment.NULL);
+        } else {
+            return openssl_h.SSL_set_options(s, op);
+        }
+    }
+
+    // LibreSSL SSL_CTRL_CLEAR_OPTIONS
+    public static final int SSL_CTRL_CLEAR_OPTIONS = 77;
+
+    // LibreSSL SSL_CTX_set_options
+    public static long SSL_CTX_clear_options(MemorySegment ctx, long op) {
+        if (LIBRESSL) {
+            return openssl_h.SSL_CTX_ctrl(ctx, SSL_CTRL_CLEAR_OPTIONS, op, 
MemorySegment.NULL);
+        } else {
+            return openssl_h.SSL_CTX_clear_options(ctx, op);
+        }
+    }
+
+    // LibreSSL OPENSSL_sk_num
+    public static int OPENSSL_sk_num(MemorySegment x0) {
+        if (LIBRESSL) {
+            class Holder {
+                static final String NAME = "sk_num";
+                static final FunctionDescriptor DESC = 
FunctionDescriptor.of(openssl_h.C_INT, 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, x0);
+                }
+                return (int) mh$.invokeExact(x0);
+            } catch (Throwable ex$) {
+                throw new AssertionError("should not reach here", ex$);
+            }
+        } else {
+            return openssl_h.OPENSSL_sk_num(x0);
+        }
+    }
+
+    // LibreSSL OPENSSL_sk_value
+    public static MemorySegment OPENSSL_sk_value(MemorySegment x0, int x1) {
+        if (LIBRESSL) {
+            class Holder {
+                static final String NAME = "sk_value";
+                static final FunctionDescriptor DESC = 
FunctionDescriptor.of(openssl_h.C_POINTER, openssl_h.C_POINTER, 
openssl_h.C_INT);
+                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, x0, x1);
+                }
+                return (MemorySegment) mh$.invokeExact(x0, x1);
+            } catch (Throwable ex$) {
+                throw new AssertionError("should not reach here", ex$);
+            }
+        } else {
+            return openssl_h.OPENSSL_sk_value(x0, x1);
+        }
+    }
+
 }
 
diff --git a/test/org/apache/tomcat/util/net/openssl/TestOpenSSLConf.java 
b/test/org/apache/tomcat/util/net/openssl/TestOpenSSLConf.java
index cbf957d195..3bd32e6956 100644
--- a/test/org/apache/tomcat/util/net/openssl/TestOpenSSLConf.java
+++ b/test/org/apache/tomcat/util/net/openssl/TestOpenSSLConf.java
@@ -96,6 +96,7 @@ public class TestOpenSSLConf extends TomcatBaseTest {
         } else if 
("org.apache.tomcat.util.net.openssl.panama.OpenSSLImplementation".equals(sslImplementationName))
 {
             LifecycleListener listener = new OpenSSLLifecycleListener();
             Assume.assumeTrue(OpenSSLLifecycleListener.isAvailable());
+            
Assume.assumeFalse(Class.forName("org.apache.tomcat.util.openssl.openssl_h_Compatibility").getField("LIBRESSL").getBoolean(null));
             StandardServer server = (StandardServer) tomcat.getServer();
             server.addLifecycleListener(listener);
         }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 60aaa9187a..51599f3f65 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -157,6 +157,18 @@
         Fix search for OpenSSL library for FFM on Mac OS so that
         <code>java.library.path</code> is searched. (markt)
       </fix>
+      <update>
+        Add FFM compatibility methods for LibreSSL support. Renegotiation is
+        not supported at the moment. (remm)
+      </update>
+      <update>
+        Add <code>org.apache.tomcat.util.openssl.LIBRARY_NAME</code> (specifies
+        the name of the library to load) and
+        <code>org.apache.tomcat.util.openssl.USE_SYSTEM_LOAD_LIBRARY</code>
+        (set to <code>true</code> to use <code>System.loadLibrary</code> rather
+        than the FFM library loading code) to configure the OpenSSL library
+        loading using FFM. (remm)
+      </update>
     </changelog>
   </subsection>
   <subsection name="Jasper">
diff --git a/webapps/docs/config/systemprops.xml 
b/webapps/docs/config/systemprops.xml
index 11e4cb2524..4b463410b4 100644
--- a/webapps/docs/config/systemprops.xml
+++ b/webapps/docs/config/systemprops.xml
@@ -357,6 +357,19 @@
       <p>If not specified, the default value of <code>1000</code> will be 
used.</p>
     </property>
 
+    <property name="org.apache.tomcat.util.openssl.LIBRARY_NAME">
+      <p>Specify the library name of OpenSSL.</p>
+      <p>If not specified, the default value of <code>ssl</code> will be used,
+      except on MacOS where a dylib versioned name will be used, in the form of
+      <code>ssl.v</code> where v is a version number.</p>
+    </property>
+
+    <property name="org.apache.tomcat.util.openssl.USE_SYSTEM_LOAD_LIBRARY">
+      <p>Use <code>System.loadLibrary</code> to load OpenSSL rather than
+      the FFM library loading code.</p>
+      <p>If not specified, the default value of <code>false</code> will be 
used.</p>
+    </property>
+
     <property name="org.apache.catalina.startup. EXIT_ON_INIT_FAILURE">
       <p>If <code>true</code>, the server will exit if an exception happens
       during the server initialization phase. To support this feature, this


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to