This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push:
new e03169a907 Expand the PSK support to cover OpenSSL-FFM
e03169a907 is described below
commit e03169a907f106e313d4d24647cbde6b73e04a4e
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 76ea57c54a..0915dd5471 100644
--- a/java/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties
+++ b/java/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties
@@ -75,6 +75,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 83ba29c94c..33ff2528ef 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;
@@ -496,7 +501,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()) {
@@ -560,12 +565,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()) {
@@ -643,6 +650,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);
@@ -795,6 +819,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 dfe65a0445..e5b3d5da11 100644
--- a/java/org/apache/tomcat/util/openssl/openssl_h.java
+++ b/java/org/apache/tomcat/util/openssl/openssl_h.java
@@ -5424,6 +5424,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);
@@ -10264,5 +10315,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 921d65d944..e9ac0d0fb8 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 1a63b424c9..3d4c2bd6df 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -400,6 +400,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>
</changelog>
</subsection>
<subsection name="Jasper">
diff --git a/webapps/docs/config/http.xml b/webapps/docs/config/http.xml
index 313fa7da2f..4699b17ab7 100644
--- a/webapps/docs/config/http.xml
+++ b/webapps/docs/config/http.xml
@@ -1504,9 +1504,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>As of Tomcat 8.5, the majority of the SSL configuration attributes in the
<strong>Connector</strong> are deprecated. If specified, they will be used to
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]