This is an automated email from the ASF dual-hosted git repository. markt-asf pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 2ad4b3d7efad045746277de04cb079622f0dab19 Author: Mark Thomas <[email protected]> AuthorDate: Tue Sep 22 13:52:58 2026 +0100 Expand the PSK support to cover OpenSSL-FFM Co-authored-by: GitHub Copilot (GPT-5.6 Sol) <[email protected]> --- .../net/openssl/panama/LocalStrings.properties | 1 + .../util/net/openssl/panama/OpenSSLContext.java | 125 ++++++++++++- .../util/net/openssl/panama/OpenSSLUtil.java | 3 + .../util/openssl/SSL_psk_find_session_cb_func.java | 63 +++++++ .../util/openssl/SSL_psk_server_cb_func.java | 63 +++++++ java/org/apache/tomcat/util/openssl/openssl_h.java | 202 ++++++++++++++++++++- res/openssl/openssl-tomcat.conf | 11 ++ webapps/docs/changelog.xml | 4 + webapps/docs/config/http.xml | 5 +- 9 files changed, 467 insertions(+), 10 deletions(-) diff --git a/java/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties b/java/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties index 758130a0c8..ad24091af1 100644 --- a/java/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties +++ b/java/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties @@ -70,6 +70,7 @@ openssl.noCACerts=No CA certificates were configured openssl.nonJsseCertificate=The certificate [{0}] or its private key [{1}] could not be processed using a JSSE key manager and will be given directly to OpenSSL openssl.nonJsseChain=The certificate chain [{0}] was not specified or was not valid and JSSE requires a valid certificate chain so attempting to use OpenSSL directly openssl.passwordTooLong=The certificate password is too long +openssl.pskTls13Unsupported=The OpenSSL implementation does not support TLS 1.3 pre-shared keys openssl.setCustomDHParameters=Setting custom DH parameters ([{0}] bits) for the key [{1}] openssl.setECDHCurve=Setting ECDH curve ([{0}]) for the key [{1}] openssl.trustManagerMissing=No trust manager found 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 48e4296632..26358d4d24 100644 --- a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java +++ b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java @@ -36,6 +36,7 @@ import java.util.Arrays; import java.util.Base64; import java.util.Iterator; import java.util.List; +import java.util.Set; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLEngine; @@ -60,9 +61,11 @@ import org.apache.tomcat.util.net.SSLHostConfig; import org.apache.tomcat.util.net.SSLHostConfig.CertificateVerification; import org.apache.tomcat.util.net.SSLHostConfigCertificate; import org.apache.tomcat.util.net.SSLHostConfigCertificate.Type; +import org.apache.tomcat.util.net.SSLHostConfigPreSharedKey; import org.apache.tomcat.util.net.SSLUtilBase; import org.apache.tomcat.util.net.openssl.OpenSSLConf; import org.apache.tomcat.util.net.openssl.OpenSSLConfCmd; +import org.apache.tomcat.util.net.openssl.OpenSSLPreSharedKeySelector; import org.apache.tomcat.util.net.openssl.OpenSSLStatus; import org.apache.tomcat.util.net.openssl.OpenSSLUtil; import org.apache.tomcat.util.net.openssl.ciphers.Group; @@ -70,6 +73,8 @@ 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.SSL_psk_find_session_cb_func; +import org.apache.tomcat.util.openssl.SSL_psk_server_cb_func; import org.apache.tomcat.util.openssl.openssl_h; import org.apache.tomcat.util.openssl.openssl_h_Compatibility; import org.apache.tomcat.util.openssl.pem_password_cb; @@ -493,7 +498,7 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext { log.warn(sm.getString("openssl.doubleInit")); return; } - boolean success; + boolean success = true; Exception cause = null; try (var localArena = Arena.ofConfined()) { if (sslHostConfig.getInsecureRenegotiation()) { @@ -557,12 +562,14 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext { } } - // If there is no certificate file must be using a KeyStore so a KeyManager is required. - // If there is a certificate file a KeyManager is helpful but not strictly necessary. - certificate.setCertificateKeyManager( - OpenSSLUtil.chooseKeyManager(kms, certificate.getCertificateFile() == null)); + if (!sslHostConfig.isPreSharedKeyOnly()) { + // If there is no certificate file must be using a KeyStore so a KeyManager is required. + // If there is a certificate file a KeyManager is helpful but not strictly necessary. + certificate.setCertificateKeyManager( + OpenSSLUtil.chooseKeyManager(kms, certificate.getCertificateFile() == null)); - success = addCertificate(certificate, localArena); + success = addCertificate(certificate, localArena); + } // Client certificate verification int value = switch (sslHostConfig.getCertificateVerification()) { @@ -640,6 +647,23 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext { } } + Set<SSLHostConfigPreSharedKey> psks = sslHostConfig.getPreSharedKeys(); + if (!psks.isEmpty()) { + OpenSSLPreSharedKeySelector selector = new OpenSSLPreSharedKeySelector(psks); + for (String protocol : sslHostConfig.getEnabledProtocols()) { + if (Constants.SSL_PROTO_TLSv1_2.equals(protocol)) { + SSL_CTX_set_psk_server_callback(state.sslCtx, SSL_psk_server_cb_func + .allocate(new PskServerCallback(selector), contextArena)); + } else if (Constants.SSL_PROTO_TLSv1_3.equals(protocol)) { + if (openssl_h_Compatibility.LIBRESSL) { + throw new SSLException(sm.getString("openssl.pskTls13Unsupported")); + } + SSL_CTX_set_psk_find_session_callback(state.sslCtx, SSL_psk_find_session_cb_func + .allocate(new PskFindSessionCallback(selector), contextArena)); + } + } + } + if (negotiableProtocols != null && !negotiableProtocols.isEmpty()) { SSL_CTX_set_alpn_select_cb(state.sslCtx, SSL_CTX_set_alpn_select_cb$cb .allocate(new ALPNSelectCallback(negotiableProtocols), contextArena), state.sslCtx); @@ -792,6 +816,95 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext { } } + private static class PskServerCallback implements SSL_psk_server_cb_func.Function { + + private final OpenSSLPreSharedKeySelector selector; + + PskServerCallback(OpenSSLPreSharedKeySelector selector) { + this.selector = selector; + } + + @Override + public int apply(MemorySegment ssl, MemorySegment identity, MemorySegment psk, int maxPskLength) { + if (MemorySegment.NULL.equals(identity)) { + return 0; + } + byte[] key = selector.select(ssl.address(), identity.getString(0)); + if (key == null || key.length == 0 || key.length > maxPskLength) { + return 0; + } + try (var localArena = Arena.ofConfined()) { + psk.reinterpret(key.length, localArena, null).copyFrom(MemorySegment.ofArray(key)); + } + return key.length; + } + } + + private static class PskFindSessionCallback implements SSL_psk_find_session_cb_func.Function { + + private final OpenSSLPreSharedKeySelector selector; + + PskFindSessionCallback(OpenSSLPreSharedKeySelector selector) { + this.selector = selector; + } + + @Override + public int apply(MemorySegment ssl, MemorySegment identity, long identityLength, MemorySegment sessionPointer) { + try (var localArena = Arena.ofConfined()) { + MemorySegment sessionPointerSegment = + sessionPointer.reinterpret(ValueLayout.ADDRESS.byteSize(), localArena, null); + sessionPointerSegment.set(ValueLayout.ADDRESS, 0, MemorySegment.NULL); + if (MemorySegment.NULL.equals(identity) || identityLength < 0 || identityLength > Integer.MAX_VALUE) { + return 0; + } + + byte[] identityBytes = + identity.reinterpret(identityLength, localArena, null).toArray(ValueLayout.JAVA_BYTE); + int[] cipherSuite = new int[1]; + byte[] key = selector.select(ssl.address(), identityBytes, cipherSuite); + if (key == null) { + return 1; + } + if (key.length == 0 || cipherSuite[0] <= 0 || cipherSuite[0] > 0xFFFF) { + return 0; + } + + byte[] cipherId = new byte[] { (byte) (cipherSuite[0] >> 8), (byte) cipherSuite[0] }; + MemorySegment cipher = + SSL_CIPHER_find(ssl, localArena.allocateFrom(ValueLayout.JAVA_BYTE, cipherId)); + if (MemorySegment.NULL.equals(cipher) + || !Constants.SSL_PROTO_TLSv1_3.equals(SSL_CIPHER_get_version(cipher).getString(0))) { + return 0; + } + + MemorySegment session = SSL_SESSION_new(); + if (MemorySegment.NULL.equals(session)) { + return 0; + } + boolean success = false; + try { + MemorySegment keySegment = localArena.allocateFrom(ValueLayout.JAVA_BYTE, key); + try { + if (SSL_SESSION_set1_master_key(session, keySegment, key.length) == 0 || + SSL_SESSION_set_cipher(session, cipher) == 0 || + SSL_SESSION_set_protocol_version(session, TLS1_3_VERSION()) == 0) { + return 0; + } + } finally { + keySegment.fill((byte) 0); + } + sessionPointerSegment.set(ValueLayout.ADDRESS, 0, session); + success = true; + return 1; + } finally { + if (!success) { + SSL_SESSION_free(session); + } + } + } + } + } + private static class CertVerifyCallback implements SSL_CTX_set_cert_verify_callback$cb.Function { private final X509TrustManager x509TrustManager; diff --git a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLUtil.java b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLUtil.java index ba26f0c758..16e46081e6 100644 --- a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLUtil.java +++ b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLUtil.java @@ -76,6 +76,9 @@ public class OpenSSLUtil extends SSLUtilBase { @Override public KeyManager[] getKeyManagers() throws Exception { + if (sslHostConfig.isPreSharedKeyOnly()) { + return null; + } try { return super.getKeyManagers(); } catch (IllegalArgumentException e) { diff --git a/java/org/apache/tomcat/util/openssl/SSL_psk_find_session_cb_func.java b/java/org/apache/tomcat/util/openssl/SSL_psk_find_session_cb_func.java new file mode 100644 index 0000000000..efee3fea8d --- /dev/null +++ b/java/org/apache/tomcat/util/openssl/SSL_psk_find_session_cb_func.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by jextract + +package org.apache.tomcat.util.openssl; + +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemorySegment; +import java.lang.invoke.MethodHandle; + +/** + * {@snippet lang = c : * SSL_psk_find_session_cb_func cb + * } + */ +@SuppressWarnings("javadoc") +public class SSL_psk_find_session_cb_func { + + public interface Function { + int apply(MemorySegment ssl, MemorySegment identity, long identityLength, MemorySegment session); + } + + private static final FunctionDescriptor $DESC = FunctionDescriptor.of(openssl_h.C_INT, openssl_h.C_POINTER, + openssl_h.C_POINTER, openssl_h.C_LONG, openssl_h.C_POINTER); + + public static FunctionDescriptor descriptor() { + return $DESC; + } + + private static final MethodHandle UP$MH = + openssl_h.upcallHandle(SSL_psk_find_session_cb_func.Function.class, "apply", $DESC); + + public static MemorySegment allocate(SSL_psk_find_session_cb_func.Function fi, Arena scope) { + return Linker.nativeLinker().upcallStub(UP$MH.bindTo(fi), $DESC, scope); + } + + private static final MethodHandle DOWN$MH = Linker.nativeLinker().downcallHandle($DESC); + + public static int invoke(MemorySegment funcPtr, MemorySegment ssl, MemorySegment identity, long identityLength, + MemorySegment session) { + try { + return (int) DOWN$MH.invokeExact(funcPtr, ssl, identity, identityLength, session); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } +} diff --git a/java/org/apache/tomcat/util/openssl/SSL_psk_server_cb_func.java b/java/org/apache/tomcat/util/openssl/SSL_psk_server_cb_func.java new file mode 100644 index 0000000000..a7eaf9585d --- /dev/null +++ b/java/org/apache/tomcat/util/openssl/SSL_psk_server_cb_func.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by jextract + +package org.apache.tomcat.util.openssl; + +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemorySegment; +import java.lang.invoke.MethodHandle; + +/** + * {@snippet lang = c : * SSL_psk_server_cb_func cb + * } + */ +@SuppressWarnings("javadoc") +public class SSL_psk_server_cb_func { + + public interface Function { + int apply(MemorySegment ssl, MemorySegment identity, MemorySegment psk, int maxPskLength); + } + + private static final FunctionDescriptor $DESC = FunctionDescriptor.of(openssl_h.C_INT, openssl_h.C_POINTER, + openssl_h.C_POINTER, openssl_h.C_POINTER, openssl_h.C_INT); + + public static FunctionDescriptor descriptor() { + return $DESC; + } + + private static final MethodHandle UP$MH = + openssl_h.upcallHandle(SSL_psk_server_cb_func.Function.class, "apply", $DESC); + + public static MemorySegment allocate(SSL_psk_server_cb_func.Function fi, Arena scope) { + return Linker.nativeLinker().upcallStub(UP$MH.bindTo(fi), $DESC, scope); + } + + private static final MethodHandle DOWN$MH = Linker.nativeLinker().downcallHandle($DESC); + + public static int invoke(MemorySegment funcPtr, MemorySegment ssl, MemorySegment identity, MemorySegment psk, + int maxPskLength) { + try { + return (int) DOWN$MH.invokeExact(funcPtr, ssl, identity, psk, maxPskLength); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } +} diff --git a/java/org/apache/tomcat/util/openssl/openssl_h.java b/java/org/apache/tomcat/util/openssl/openssl_h.java index 518bd7fb58..41bc06b18c 100644 --- a/java/org/apache/tomcat/util/openssl/openssl_h.java +++ b/java/org/apache/tomcat/util/openssl/openssl_h.java @@ -5373,6 +5373,57 @@ public class openssl_h { } } + private static class SSL_CIPHER_get_version { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(openssl_h.C_POINTER, openssl_h.C_POINTER); + + public static final MemorySegment ADDR = openssl_h.findOrThrow("SSL_CIPHER_get_version"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang = c : * const char *SSL_CIPHER_get_version(const SSL_CIPHER *c) + * } + */ + public static FunctionDescriptor SSL_CIPHER_get_version$descriptor() { + return SSL_CIPHER_get_version.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang = c : * const char *SSL_CIPHER_get_version(const SSL_CIPHER *c) + * } + */ + public static MethodHandle SSL_CIPHER_get_version$handle() { + return SSL_CIPHER_get_version.HANDLE; + } + + /** + * Address for: + * {@snippet lang = c : * const char *SSL_CIPHER_get_version(const SSL_CIPHER *c) + * } + */ + public static MemorySegment SSL_CIPHER_get_version$address() { + return SSL_CIPHER_get_version.ADDR; + } + + /** + * {@snippet lang = c : * const char *SSL_CIPHER_get_version(const SSL_CIPHER *c) + * } + */ + public static MemorySegment SSL_CIPHER_get_version(MemorySegment c) { + var mh$ = SSL_CIPHER_get_version.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("SSL_CIPHER_get_version", c); + } + return (MemorySegment) mh$.invokeExact(c); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + private static class SSL_CIPHER_get_kx_nid { public static final FunctionDescriptor DESC = FunctionDescriptor.of(openssl_h.C_INT, openssl_h.C_POINTER); @@ -10213,5 +10264,154 @@ public class openssl_h { public static long SSL_OP_ALL() { return SSL_OP_ALL; } -} + private static class SSL_CIPHER_find { + public static final FunctionDescriptor DESC = + FunctionDescriptor.of(openssl_h.C_POINTER, openssl_h.C_POINTER, openssl_h.C_POINTER); + public static final MemorySegment ADDR = openssl_h.findOrThrow("SSL_CIPHER_find"); + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + public static MemorySegment SSL_CIPHER_find(MemorySegment ssl, MemorySegment ptr) { + var mh$ = SSL_CIPHER_find.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("SSL_CIPHER_find", ssl, ptr); + } + return (MemorySegment) mh$.invokeExact(ssl, ptr); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class SSL_CTX_set_psk_server_callback { + public static final FunctionDescriptor DESC = + FunctionDescriptor.ofVoid(openssl_h.C_POINTER, openssl_h.C_POINTER); + public static final MemorySegment ADDR = openssl_h.findOrThrow("SSL_CTX_set_psk_server_callback"); + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + public static void SSL_CTX_set_psk_server_callback(MemorySegment ctx, MemorySegment callback) { + var mh$ = SSL_CTX_set_psk_server_callback.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("SSL_CTX_set_psk_server_callback", ctx, callback); + } + mh$.invokeExact(ctx, callback); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class SSL_CTX_set_psk_find_session_callback { + public static final FunctionDescriptor DESC = + FunctionDescriptor.ofVoid(openssl_h.C_POINTER, openssl_h.C_POINTER); + public static final MemorySegment ADDR = openssl_h.findOrThrow("SSL_CTX_set_psk_find_session_callback"); + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + public static void SSL_CTX_set_psk_find_session_callback(MemorySegment ctx, MemorySegment callback) { + var mh$ = SSL_CTX_set_psk_find_session_callback.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("SSL_CTX_set_psk_find_session_callback", ctx, callback); + } + mh$.invokeExact(ctx, callback); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class SSL_SESSION_new { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(openssl_h.C_POINTER); + public static final MemorySegment ADDR = openssl_h.findOrThrow("SSL_SESSION_new"); + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + public static MemorySegment SSL_SESSION_new() { + var mh$ = SSL_SESSION_new.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("SSL_SESSION_new"); + } + return (MemorySegment) mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class SSL_SESSION_free { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid(openssl_h.C_POINTER); + public static final MemorySegment ADDR = openssl_h.findOrThrow("SSL_SESSION_free"); + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + public static void SSL_SESSION_free(MemorySegment session) { + var mh$ = SSL_SESSION_free.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("SSL_SESSION_free", session); + } + mh$.invokeExact(session); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class SSL_SESSION_set1_master_key { + public static final FunctionDescriptor DESC = FunctionDescriptor.of(openssl_h.C_INT, openssl_h.C_POINTER, + openssl_h.C_POINTER, openssl_h.C_LONG); + public static final MemorySegment ADDR = openssl_h.findOrThrow("SSL_SESSION_set1_master_key"); + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + public static int SSL_SESSION_set1_master_key(MemorySegment session, MemorySegment key, long keyLength) { + var mh$ = SSL_SESSION_set1_master_key.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("SSL_SESSION_set1_master_key", session, key, keyLength); + } + return (int) mh$.invokeExact(session, key, keyLength); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class SSL_SESSION_set_cipher { + public static final FunctionDescriptor DESC = + FunctionDescriptor.of(openssl_h.C_INT, openssl_h.C_POINTER, openssl_h.C_POINTER); + public static final MemorySegment ADDR = openssl_h.findOrThrow("SSL_SESSION_set_cipher"); + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + public static int SSL_SESSION_set_cipher(MemorySegment session, MemorySegment cipher) { + var mh$ = SSL_SESSION_set_cipher.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("SSL_SESSION_set_cipher", session, cipher); + } + return (int) mh$.invokeExact(session, cipher); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class SSL_SESSION_set_protocol_version { + public static final FunctionDescriptor DESC = + FunctionDescriptor.of(openssl_h.C_INT, openssl_h.C_POINTER, openssl_h.C_INT); + public static final MemorySegment ADDR = openssl_h.findOrThrow("SSL_SESSION_set_protocol_version"); + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + public static int SSL_SESSION_set_protocol_version(MemorySegment session, int version) { + var mh$ = SSL_SESSION_set_protocol_version.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("SSL_SESSION_set_protocol_version", session, version); + } + return (int) mh$.invokeExact(session, version); + } 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 e37bade4ef..ce3b0f853a 100644 --- a/res/openssl/openssl-tomcat.conf +++ b/res/openssl/openssl-tomcat.conf @@ -166,10 +166,14 @@ #### Extracted from: /usr/include/openssl/ssl.h +--include-typedef SSL_psk_find_session_cb_func +--include-typedef SSL_psk_server_cb_func --include-function OPENSSL_init_ssl # header: /usr/include/openssl/ssl.h --include-function SSL_CIPHER_get_auth_nid # header: /usr/include/openssl/ssl.h +--include-function SSL_CIPHER_find # header: /usr/include/openssl/ssl.h --include-function SSL_CIPHER_get_kx_nid # header: /usr/include/openssl/ssl.h --include-function SSL_CIPHER_get_name # header: /usr/include/openssl/ssl.h +--include-function SSL_CIPHER_get_version # header: /usr/include/openssl/ssl.h --include-function SSL_CONF_CTX_finish # header: /usr/include/openssl/ssl.h --include-function SSL_CONF_CTX_free # header: /usr/include/openssl/ssl.h --include-function SSL_CONF_CTX_new # header: /usr/include/openssl/ssl.h @@ -197,6 +201,8 @@ --include-function SSL_CTX_set_default_passwd_cb # header: /usr/include/openssl/ssl.h --include-function SSL_CTX_set_default_verify_paths # header: /usr/include/openssl/ssl.h --include-function SSL_CTX_set_options # header: /usr/include/openssl/ssl.h +--include-function SSL_CTX_set_psk_find_session_callback # header: /usr/include/openssl/ssl.h +--include-function SSL_CTX_set_psk_server_callback # header: /usr/include/openssl/ssl.h --include-function SSL_CTX_set_session_id_context # header: /usr/include/openssl/ssl.h --include-function SSL_CTX_set_timeout # header: /usr/include/openssl/ssl.h --include-function SSL_CTX_set_tmp_dh_callback # deprecated header: /usr/include/openssl/ssl.h @@ -207,6 +213,11 @@ --include-function SSL_CTX_use_PrivateKey # header: /usr/include/openssl/ssl.h --include-function SSL_SESSION_get_id # header: /usr/include/openssl/ssl.h --include-function SSL_SESSION_get_time # header: /usr/include/openssl/ssl.h +--include-function SSL_SESSION_free # header: /usr/include/openssl/ssl.h +--include-function SSL_SESSION_new # header: /usr/include/openssl/ssl.h +--include-function SSL_SESSION_set1_master_key # header: /usr/include/openssl/ssl.h +--include-function SSL_SESSION_set_cipher # header: /usr/include/openssl/ssl.h +--include-function SSL_SESSION_set_protocol_version # header: /usr/include/openssl/ssl.h --include-function SSL_add_file_cert_subjects_to_stack # header: /usr/include/openssl/ssl.h --include-function SSL_do_handshake # header: /usr/include/openssl/ssl.h --include-function SSL_free # header: /usr/include/openssl/ssl.h diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index d7ff714eb2..0a5343b1dd 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -137,6 +137,10 @@ Add support for configuring TLS pre-shared keys under an <code>SSLHostConfig</code>. (markt) </add> + <add> + Add TLS pre-shared key support to the OpenSSL FFM implementation. + (markt) + </add> <add> Add the Jakarta EE 12 XML schemas. (markt) </add> diff --git a/webapps/docs/config/http.xml b/webapps/docs/config/http.xml index 3c7512b4aa..434d35aadc 100644 --- a/webapps/docs/config/http.xml +++ b/webapps/docs/config/http.xml @@ -1254,9 +1254,8 @@ <p>Each <strong>SSLHostConfig</strong> must in turn define at least one <strong>Certificate</strong> or <strong>PreSharedKey</strong>. A configuration - with no <strong>Certificate</strong> requires the Tomcat Native OpenSSL - implementation. The types of the <strong>Certificate</strong>s must be - unique.</p> + with no <strong>Certificate</strong> requires an OpenSSL-based implementation. + The types of the <strong>Certificate</strong>s must be unique.</p> <p>In addition to the standard TLS related request attributes defined in section 3.10 of the Servlet specification, Tomcat supports a number of --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
