You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2021/11/24 22:05:18 UTC
[tomcat] branch main updated: Fix bad scope handling
This is an automated email from the ASF dual-hosted git repository.
remm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/main by this push:
new 46debaa Fix bad scope handling
46debaa is described below
commit 46debaa2af3f397758d0eafd8a21878ed85f8770
Author: remm <re...@apache.org>
AuthorDate: Wed Nov 24 23:04:56 2021 +0100
Fix bad scope handling
Finally have working implicit scope for the context.
Naming all scopes "scope" was probably not a good idea, and also
figuring out what cannot be in a local confined scope is of course
tricky. Use the implicit scope for everything instead.
---
.../util/net/openssl/panama/OpenSSLContext.java | 533 ++++++++++-----------
.../util/net/openssl/panama/OpenSSLEngine.java | 4 +-
2 files changed, 262 insertions(+), 275 deletions(-)
diff --git a/modules/openssl-java17/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java b/modules/openssl-java17/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
index ad07d20..d665b57 100644
--- a/modules/openssl-java17/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
+++ b/modules/openssl-java17/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
@@ -30,8 +30,6 @@ import java.io.File;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
-import java.lang.ref.Cleaner;
-import java.lang.ref.Cleaner.Cleanable;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.SecureRandom;
@@ -149,8 +147,6 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
}
}
- private static final Cleaner cleaner = Cleaner.create();
-
private final SSLHostConfig sslHostConfig;
private final SSLHostConfigCertificate certificate;
private final boolean alpn;
@@ -171,7 +167,7 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
}
private final ContextState state;
- private final Cleanable cleanable;
+ private final ResourceScope scope;
private static String[] getCiphers(MemoryAddress sslCtx) {
MemoryAddress sk = SSL_CTX_get_ciphers(sslCtx);
@@ -202,7 +198,7 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
this.sslHostConfig = certificate.getSSLHostConfig();
this.certificate = certificate;
- ResourceScope scope = ResourceScope.newSharedScope();
+ scope = ResourceScope.newImplicitScope();
MemoryAddress sslCtx = MemoryAddress.NULL;
MemoryAddress confCtx = MemoryAddress.NULL;
@@ -339,7 +335,7 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
} catch(Exception e) {
throw new SSLException(sm.getString("openssl.errorSSLCtxInit"), e);
} finally {
- state = new ContextState(scope, sslCtx, confCtx, negotiableProtocolsBytes);
+ state = new ContextState(sslCtx, confCtx, negotiableProtocolsBytes);
/*
* When an SSLHostConfig is replaced at runtime, it is not possible to
* call destroy() on the associated OpenSSLContext since it is likely
@@ -348,11 +344,10 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
* OpenSSLSessionContext) to ensure that the OpenSSLContext remains
* ineligible for GC while those connections are alive. Once those
* connections complete, the OpenSSLContext will become eligible for GC
- * and this method will ensure that the associated native resources are
- * cleaned up.
+ * and the implicit scope will ensure that the associated native
+ * resources are cleaned up.
*/
- states.put(Long.valueOf(sslCtx.address().toRawLongValue()), state);
- cleanable = cleaner.register(this, state);
+ scope.addCloseAction(state);
if (!success) {
destroy();
@@ -372,9 +367,7 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
@Override
- public synchronized void destroy() {
- states.remove(Long.valueOf(state.sslCtx.address().toRawLongValue()));
- cleanable.clean();
+ public void destroy() {
}
@@ -561,7 +554,7 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
}
// List the ciphers that the client is permitted to negotiate
- if (SSL_CTX_set_cipher_list(state.sslCtx, CLinker.toCString(sslHostConfig.getCiphers(), state.scope)) <= 0) {
+ if (SSL_CTX_set_cipher_list(state.sslCtx, CLinker.toCString(sslHostConfig.getCiphers(), scope)) <= 0) {
log.warn(sm.getString("engine.failedCipherSuite", sslHostConfig.getCiphers()));
}
@@ -597,18 +590,18 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
// Set int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) callback
MemoryAddress openSSLCallbackVerify =
CLinker.getInstance().upcallStub(openSSLCallbackVerifyHandle,
- openSSLCallbackVerifyFunctionDescriptor, state.scope);
+ openSSLCallbackVerifyFunctionDescriptor, scope);
// Leave this just in case but in Tomcat this is always set again by the engine
SSL_CTX_set_verify(state.sslCtx, value, openSSLCallbackVerify);
// Trust and certificate verification
- var allocator = SegmentAllocator.ofScope(state.scope);
+ var allocator = SegmentAllocator.ofScope(scope);
if (tms != null) {
// Client certificate verification based on custom trust managers
state.x509TrustManager = chooseTrustManager(tms);
MemoryAddress openSSLCallbackCertVerify =
CLinker.getInstance().upcallStub(openSSLCallbackCertVerifyHandle,
- openSSLCallbackCertVerifyFunctionDescriptor, state.scope);
+ openSSLCallbackCertVerifyFunctionDescriptor, scope);
SSL_CTX_set_cert_verify_callback(state.sslCtx, openSSLCallbackCertVerify, state.sslCtx);
// Pass along the DER encoded certificates of the accepted client
@@ -634,9 +627,9 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
// SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificateFile()),
// SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificatePath()));
MemorySegment caCertificateFileNative = sslHostConfig.getCaCertificateFile() != null
- ? CLinker.toCString(SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificateFile()), state.scope) : null;
+ ? CLinker.toCString(SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificateFile()), scope) : null;
MemorySegment caCertificatePathNative = sslHostConfig.getCaCertificatePath() != null
- ? CLinker.toCString(SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificatePath()), state.scope) : null;
+ ? CLinker.toCString(SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificatePath()), scope) : null;
if (SSL_CTX_load_verify_locations(state.sslCtx,
caCertificateFileNative == null ? MemoryAddress.NULL : caCertificateFileNative,
caCertificatePathNative == null ? MemoryAddress.NULL : caCertificatePathNative) <= 0) {
@@ -664,7 +657,7 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
// MemoryAddress in, int inlen, MemoryAddress arg
MemoryAddress openSSLCallbackAlpnSelectProto =
CLinker.getInstance().upcallStub(openSSLCallbackAlpnSelectProtoHandle,
- openSSLCallbackAlpnSelectProtoFunctionDescriptor, state.scope);
+ openSSLCallbackAlpnSelectProtoFunctionDescriptor, scope);
SSL_CTX_set_alpn_select_cb(state.sslCtx, openSSLCallbackAlpnSelectProto, state.sslCtx);
// Skip NPN (annoying and likely not useful anymore)
//SSLContext.setNpnProtos(state.ctx, protocolsArray, SSL.SSL_SELECTOR_FAILURE_NO_ADVERTISE);
@@ -963,276 +956,274 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
private void addCertificate(SSLHostConfigCertificate certificate) throws Exception {
- try (var scope = ResourceScope.newConfinedScope()) {
- var allocator = SegmentAllocator.ofScope(scope);
- int index = getCertificateIndex(certificate);
- // Load Server key and certificate
- if (certificate.getCertificateFile() != null) {
- // Set certificate
- //SSLContext.setCertificate(state.ctx,
- // SSLHostConfig.adjustRelativePath(certificate.getCertificateFile()),
- // SSLHostConfig.adjustRelativePath(certificate.getCertificateKeyFile()),
- // certificate.getCertificateKeyPassword(), getCertificateIndex(certificate));
- var certificateFileNative = CLinker.toCString(SSLHostConfig.adjustRelativePath(certificate.getCertificateFile()), scope);
- var certificateKeyFileNative = (certificate.getCertificateKeyFile() == null) ? certificateFileNative
- : CLinker.toCString(SSLHostConfig.adjustRelativePath(certificate.getCertificateKeyFile()), scope);
- MemoryAddress bio;
- MemoryAddress cert = MemoryAddress.NULL;
- MemoryAddress key = MemoryAddress.NULL;
- if (certificate.getCertificateFile().endsWith(".pkcs12")) {
- // Load pkcs12
- bio = BIO_new(BIO_s_file());
- //# define BIO_read_filename(b,name)
- // (int)BIO_ctrl(b,BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_READ,(char *)(name))
- if (BIO_ctrl(bio, BIO_C_SET_FILENAME(), BIO_CLOSE() | BIO_FP_READ(), certificateFileNative) <= 0) {
- BIO_free(bio);
- log.error(sm.getString("openssl.errorLoadingCertificate", "[0]:" + certificate.getCertificateFile()));
- return;
- }
- MemoryAddress p12 = d2i_PKCS12_bio(bio, MemoryAddress.NULL);
+ var allocator = SegmentAllocator.ofScope(scope);
+ int index = getCertificateIndex(certificate);
+ // Load Server key and certificate
+ if (certificate.getCertificateFile() != null) {
+ // Set certificate
+ //SSLContext.setCertificate(state.ctx,
+ // SSLHostConfig.adjustRelativePath(certificate.getCertificateFile()),
+ // SSLHostConfig.adjustRelativePath(certificate.getCertificateKeyFile()),
+ // certificate.getCertificateKeyPassword(), getCertificateIndex(certificate));
+ var certificateFileNative = CLinker.toCString(SSLHostConfig.adjustRelativePath(certificate.getCertificateFile()), scope);
+ var certificateKeyFileNative = (certificate.getCertificateKeyFile() == null) ? certificateFileNative
+ : CLinker.toCString(SSLHostConfig.adjustRelativePath(certificate.getCertificateKeyFile()), scope);
+ MemoryAddress bio;
+ MemoryAddress cert = MemoryAddress.NULL;
+ MemoryAddress key = MemoryAddress.NULL;
+ if (certificate.getCertificateFile().endsWith(".pkcs12")) {
+ // Load pkcs12
+ bio = BIO_new(BIO_s_file());
+ //# define BIO_read_filename(b,name)
+ // (int)BIO_ctrl(b,BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_READ,(char *)(name))
+ if (BIO_ctrl(bio, BIO_C_SET_FILENAME(), BIO_CLOSE() | BIO_FP_READ(), certificateFileNative) <= 0) {
BIO_free(bio);
- if (MemoryAddress.NULL.equals(p12)) {
- log.error(sm.getString("openssl.errorLoadingCertificate", "[1]:" + certificate.getCertificateFile()));
- return;
- }
- MemoryAddress passwordAddress = MemoryAddress.NULL;
- int passwordLength = 0;
- String callbackPassword = certificate.getCertificateKeyPassword();
- if (callbackPassword != null && callbackPassword.length() > 0) {
- MemorySegment password = CLinker.toCString(callbackPassword, scope);
- passwordAddress = password.address();
- passwordLength = (int) (password.byteSize() - 1);
- }
- if (PKCS12_verify_mac(p12, passwordAddress, passwordLength) <= 0) {
- // Bad password
- log.error(sm.getString("openssl.errorLoadingCertificate", "[2]:" + certificate.getCertificateFile()));
- PKCS12_free(p12);
- return;
- }
- MemorySegment certPointer = allocator.allocate(CLinker.C_POINTER);
- MemorySegment keyPointer = allocator.allocate(CLinker.C_POINTER);
- if (PKCS12_parse(p12, passwordAddress, keyPointer, certPointer, MemoryAddress.NULL) <= 0) {
- log.error(sm.getString("openssl.errorLoadingCertificate", "[3]:" + certificate.getCertificateFile()));
- PKCS12_free(p12);
- return;
- }
+ log.error(sm.getString("openssl.errorLoadingCertificate", "[0]:" + certificate.getCertificateFile()));
+ return;
+ }
+ MemoryAddress p12 = d2i_PKCS12_bio(bio, MemoryAddress.NULL);
+ BIO_free(bio);
+ if (MemoryAddress.NULL.equals(p12)) {
+ log.error(sm.getString("openssl.errorLoadingCertificate", "[1]:" + certificate.getCertificateFile()));
+ return;
+ }
+ MemoryAddress passwordAddress = MemoryAddress.NULL;
+ int passwordLength = 0;
+ String callbackPassword = certificate.getCertificateKeyPassword();
+ if (callbackPassword != null && callbackPassword.length() > 0) {
+ MemorySegment password = CLinker.toCString(callbackPassword, scope);
+ passwordAddress = password.address();
+ passwordLength = (int) (password.byteSize() - 1);
+ }
+ if (PKCS12_verify_mac(p12, passwordAddress, passwordLength) <= 0) {
+ // Bad password
+ log.error(sm.getString("openssl.errorLoadingCertificate", "[2]:" + certificate.getCertificateFile()));
PKCS12_free(p12);
- cert = MemoryAccess.getAddress(certPointer);
- key = MemoryAccess.getAddress(keyPointer);
- } else {
- // Load key
- bio = BIO_new(BIO_s_file());
- //# define BIO_read_filename(b,name)
- // (int)BIO_ctrl(b,BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_READ,(char *)(name))
- if (BIO_ctrl(bio, BIO_C_SET_FILENAME(), BIO_CLOSE() | BIO_FP_READ(), certificateKeyFileNative) <= 0) {
- BIO_free(bio);
- log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateKeyFile()));
- return;
- }
- key = MemoryAddress.NULL;
- for (int i = 0; i < 3; i++) {
- try {
- callbackPasswordTheadLocal.set(certificate.getCertificateKeyPassword());
- key = PEM_read_bio_PrivateKey(bio, MemoryAddress.NULL, openSSLCallbackPassword, MemoryAddress.NULL);
- } finally {
- callbackPasswordTheadLocal.set(null);
- }
- if (!MemoryAddress.NULL.equals(key)) {
- break;
- }
- BIO_ctrl(bio, BIO_CTRL_RESET(), 0, MemoryAddress.NULL);
- }
+ return;
+ }
+ MemorySegment certPointer = allocator.allocate(CLinker.C_POINTER);
+ MemorySegment keyPointer = allocator.allocate(CLinker.C_POINTER);
+ if (PKCS12_parse(p12, passwordAddress, keyPointer, certPointer, MemoryAddress.NULL) <= 0) {
+ log.error(sm.getString("openssl.errorLoadingCertificate", "[3]:" + certificate.getCertificateFile()));
+ PKCS12_free(p12);
+ return;
+ }
+ PKCS12_free(p12);
+ cert = MemoryAccess.getAddress(certPointer);
+ key = MemoryAccess.getAddress(keyPointer);
+ } else {
+ // Load key
+ bio = BIO_new(BIO_s_file());
+ //# define BIO_read_filename(b,name)
+ // (int)BIO_ctrl(b,BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_READ,(char *)(name))
+ if (BIO_ctrl(bio, BIO_C_SET_FILENAME(), BIO_CLOSE() | BIO_FP_READ(), certificateKeyFileNative) <= 0) {
BIO_free(bio);
- if (MemoryAddress.NULL.equals(key)) {
- if (!MemoryAddress.NULL.equals(OpenSSLLifecycleListener.enginePointer)) {
- key = ENGINE_load_private_key(OpenSSLLifecycleListener.enginePointer, certificateKeyFileNative,
- MemoryAddress.NULL, MemoryAddress.NULL);
- }
- }
- if (MemoryAddress.NULL.equals(key)) {
- log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateKeyFile()));
- return;
- }
- // Load certificate
- bio = BIO_new(BIO_s_file());
- if (BIO_ctrl(bio, BIO_C_SET_FILENAME(), BIO_CLOSE() | BIO_FP_READ(), certificateFileNative) <= 0) {
- BIO_free(bio);
- log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateFile()));
- return;
- }
+ log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateKeyFile()));
+ return;
+ }
+ key = MemoryAddress.NULL;
+ for (int i = 0; i < 3; i++) {
try {
callbackPasswordTheadLocal.set(certificate.getCertificateKeyPassword());
- cert = PEM_read_bio_X509_AUX(bio, MemoryAddress.NULL, openSSLCallbackPassword, MemoryAddress.NULL);
+ key = PEM_read_bio_PrivateKey(bio, MemoryAddress.NULL, openSSLCallbackPassword, MemoryAddress.NULL);
} finally {
callbackPasswordTheadLocal.set(null);
}
- if (MemoryAddress.NULL.equals(cert) &&
- // Missing ERR_GET_REASON(ERR_peek_last_error())
- /*int ERR_GET_REASON(unsigned long errcode) {
- * if (ERR_SYSTEM_ERROR(errcode))
- * return errcode & ERR_SYSTEM_MASK;
- * return errcode & ERR_REASON_MASK;
- *}
- *# define ERR_SYSTEM_ERROR(errcode) (((errcode) & ERR_SYSTEM_FLAG) != 0)
- *# define ERR_SYSTEM_FLAG ((unsigned int)INT_MAX + 1)
- *# define ERR_SYSTEM_MASK ((unsigned int)INT_MAX)
- *# define ERR_REASON_MASK 0X7FFFFF
- */
- ((ERR_peek_last_error() & 0X7FFFFF) == PEM_R_NO_START_LINE())) {
- ERR_clear_error();
- BIO_ctrl(bio, BIO_CTRL_RESET(), 0, MemoryAddress.NULL);
- cert = d2i_X509_bio(bio, MemoryAddress.NULL);
+ if (!MemoryAddress.NULL.equals(key)) {
+ break;
}
- BIO_free(bio);
- if (MemoryAddress.NULL.equals(cert)) {
- log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateFile()));
- return;
+ BIO_ctrl(bio, BIO_CTRL_RESET(), 0, MemoryAddress.NULL);
+ }
+ BIO_free(bio);
+ if (MemoryAddress.NULL.equals(key)) {
+ if (!MemoryAddress.NULL.equals(OpenSSLLifecycleListener.enginePointer)) {
+ key = ENGINE_load_private_key(OpenSSLLifecycleListener.enginePointer, certificateKeyFileNative,
+ MemoryAddress.NULL, MemoryAddress.NULL);
}
}
- if (SSL_CTX_use_certificate(state.sslCtx, cert) <= 0) {
- logLastError(allocator, "openssl.errorLoadingCertificate");
+ if (MemoryAddress.NULL.equals(key)) {
+ log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateKeyFile()));
return;
}
- if (SSL_CTX_use_PrivateKey(state.sslCtx, key) <= 0) {
- logLastError(allocator, "openssl.errorLoadingPrivateKey");
+ // Load certificate
+ bio = BIO_new(BIO_s_file());
+ if (BIO_ctrl(bio, BIO_C_SET_FILENAME(), BIO_CLOSE() | BIO_FP_READ(), certificateFileNative) <= 0) {
+ BIO_free(bio);
+ log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateFile()));
return;
}
- if (SSL_CTX_check_private_key(state.sslCtx) <= 0) {
- logLastError(allocator, "openssl.errorPrivateKeyCheck");
- return;
+ try {
+ callbackPasswordTheadLocal.set(certificate.getCertificateKeyPassword());
+ cert = PEM_read_bio_X509_AUX(bio, MemoryAddress.NULL, openSSLCallbackPassword, MemoryAddress.NULL);
+ } finally {
+ callbackPasswordTheadLocal.set(null);
}
- // Try to read DH parameters from the (first) SSLCertificateFile
- if (index == SSL_AIDX_RSA) {
- bio = BIO_new_file(certificateFileNative, CLinker.toCString("r", scope));
- var dh = PEM_read_bio_DHparams(bio, MemoryAddress.NULL, MemoryAddress.NULL, MemoryAddress.NULL);
- BIO_free(bio);
- // # define SSL_CTX_set_tmp_dh(sslCtx,dh) \
- // SSL_CTX_ctrl(sslCtx,SSL_CTRL_SET_TMP_DH,0,(char *)(dh))
- if (!MemoryAddress.NULL.equals(dh)) {
- SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_TMP_DH(), 0, dh);
- DH_free(dh);
- }
+ if (MemoryAddress.NULL.equals(cert) &&
+ // Missing ERR_GET_REASON(ERR_peek_last_error())
+ /*int ERR_GET_REASON(unsigned long errcode) {
+ * if (ERR_SYSTEM_ERROR(errcode))
+ * return errcode & ERR_SYSTEM_MASK;
+ * return errcode & ERR_REASON_MASK;
+ *}
+ *# define ERR_SYSTEM_ERROR(errcode) (((errcode) & ERR_SYSTEM_FLAG) != 0)
+ *# define ERR_SYSTEM_FLAG ((unsigned int)INT_MAX + 1)
+ *# define ERR_SYSTEM_MASK ((unsigned int)INT_MAX)
+ *# define ERR_REASON_MASK 0X7FFFFF
+ */
+ ((ERR_peek_last_error() & 0X7FFFFF) == PEM_R_NO_START_LINE())) {
+ ERR_clear_error();
+ BIO_ctrl(bio, BIO_CTRL_RESET(), 0, MemoryAddress.NULL);
+ cert = d2i_X509_bio(bio, MemoryAddress.NULL);
}
- // Similarly, try to read the ECDH curve name from SSLCertificateFile...
- bio = BIO_new_file(certificateFileNative, CLinker.toCString("r", scope));
- var ecparams = PEM_read_bio_ECPKParameters(bio, MemoryAddress.NULL, MemoryAddress.NULL, MemoryAddress.NULL);
BIO_free(bio);
- if (!MemoryAddress.NULL.equals(ecparams)) {
- int nid = EC_GROUP_get_curve_name(ecparams);
- var eckey = EC_KEY_new_by_curve_name(nid);
- // # define SSL_CTX_set_tmp_ecdh(sslCtx,ecdh) \
- // SSL_CTX_ctrl(sslCtx,SSL_CTRL_SET_TMP_ECDH,0,(char *)(ecdh))
- SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_TMP_ECDH(), 0, eckey);
- EC_KEY_free(eckey);
- EC_GROUP_free(ecparams);
- }
- // Set callback for DH parameters
- MemoryAddress openSSLCallbackTmpDH = CLinker.getInstance().upcallStub(openSSLCallbackTmpDHHandle,
- openSSLCallbackTmpDHFunctionDescriptor, state.scope);
- SSL_CTX_set_tmp_dh_callback(state.sslCtx, openSSLCallbackTmpDH);
- // Set certificate chain file
- if (certificate.getCertificateChainFile() != null) {
- var certificateChainFileNative =
- CLinker.toCString(SSLHostConfig.adjustRelativePath(certificate.getCertificateChainFile()), scope);
- // SSLContext.setCertificateChainFile(state.ctx,
- // SSLHostConfig.adjustRelativePath(certificate.getCertificateChainFile()), false);
- if (SSL_CTX_use_certificate_chain_file(state.sslCtx, certificateChainFileNative) <= 0) {
- log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateChainFile()));
- }
- }
- // Set revocation
- //SSLContext.setCARevocation(state.ctx,
- // SSLHostConfig.adjustRelativePath(
- // sslHostConfig.getCertificateRevocationListFile()),
- // SSLHostConfig.adjustRelativePath(
- // sslHostConfig.getCertificateRevocationListPath()));
- MemoryAddress certificateStore = SSL_CTX_get_cert_store(state.sslCtx);
- if (sslHostConfig.getCertificateRevocationListFile() != null) {
- MemoryAddress x509Lookup = X509_STORE_add_lookup(certificateStore, X509_LOOKUP_file());
- var certificateRevocationListFileNative =
- CLinker.toCString(SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListFile()), scope);
- //X509_LOOKUP_ctrl(lookup,X509_L_FILE_LOAD,file,type,NULL)
- if (X509_LOOKUP_ctrl(x509Lookup, X509_L_FILE_LOAD(), certificateRevocationListFileNative,
- X509_FILETYPE_PEM(), MemoryAddress.NULL) <= 0) {
- log.error(sm.getString("openssl.errorLoadingCertificateRevocationList", sslHostConfig.getCertificateRevocationListFile()));
- }
- }
- if (sslHostConfig.getCertificateRevocationListPath() != null) {
- MemoryAddress x509Lookup = X509_STORE_add_lookup(certificateStore, X509_LOOKUP_hash_dir());
- var certificateRevocationListPathNative =
- CLinker.toCString(SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListPath()), scope);
- //X509_LOOKUP_ctrl(lookup,X509_L_ADD_DIR,path,type,NULL)
- if (X509_LOOKUP_ctrl(x509Lookup, X509_L_ADD_DIR(), certificateRevocationListPathNative,
- X509_FILETYPE_PEM(), MemoryAddress.NULL) <= 0) {
- log.error(sm.getString("openssl.errorLoadingCertificateRevocationList", sslHostConfig.getCertificateRevocationListPath()));
- }
+ if (MemoryAddress.NULL.equals(cert)) {
+ log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateFile()));
+ return;
}
- X509_STORE_set_flags(certificateStore, X509_V_FLAG_CRL_CHECK() | X509_V_FLAG_CRL_CHECK_ALL());
- } else {
- String alias = certificate.getCertificateKeyAlias();
- X509KeyManager x509KeyManager = certificate.getCertificateKeyManager();
- if (alias == null) {
- alias = "tomcat";
+ }
+ if (SSL_CTX_use_certificate(state.sslCtx, cert) <= 0) {
+ logLastError(allocator, "openssl.errorLoadingCertificate");
+ return;
+ }
+ if (SSL_CTX_use_PrivateKey(state.sslCtx, key) <= 0) {
+ logLastError(allocator, "openssl.errorLoadingPrivateKey");
+ return;
+ }
+ if (SSL_CTX_check_private_key(state.sslCtx) <= 0) {
+ logLastError(allocator, "openssl.errorPrivateKeyCheck");
+ return;
+ }
+ // Try to read DH parameters from the (first) SSLCertificateFile
+ if (index == SSL_AIDX_RSA) {
+ bio = BIO_new_file(certificateFileNative, CLinker.toCString("r", scope));
+ var dh = PEM_read_bio_DHparams(bio, MemoryAddress.NULL, MemoryAddress.NULL, MemoryAddress.NULL);
+ BIO_free(bio);
+ // # define SSL_CTX_set_tmp_dh(sslCtx,dh) \
+ // SSL_CTX_ctrl(sslCtx,SSL_CTRL_SET_TMP_DH,0,(char *)(dh))
+ if (!MemoryAddress.NULL.equals(dh)) {
+ SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_TMP_DH(), 0, dh);
+ DH_free(dh);
}
- X509Certificate[] chain = x509KeyManager.getCertificateChain(alias);
- if (chain == null) {
- alias = findAlias(x509KeyManager, certificate);
- chain = x509KeyManager.getCertificateChain(alias);
+ }
+ // Similarly, try to read the ECDH curve name from SSLCertificateFile...
+ bio = BIO_new_file(certificateFileNative, CLinker.toCString("r", scope));
+ var ecparams = PEM_read_bio_ECPKParameters(bio, MemoryAddress.NULL, MemoryAddress.NULL, MemoryAddress.NULL);
+ BIO_free(bio);
+ if (!MemoryAddress.NULL.equals(ecparams)) {
+ int nid = EC_GROUP_get_curve_name(ecparams);
+ var eckey = EC_KEY_new_by_curve_name(nid);
+ // # define SSL_CTX_set_tmp_ecdh(sslCtx,ecdh) \
+ // SSL_CTX_ctrl(sslCtx,SSL_CTRL_SET_TMP_ECDH,0,(char *)(ecdh))
+ SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_TMP_ECDH(), 0, eckey);
+ EC_KEY_free(eckey);
+ EC_GROUP_free(ecparams);
+ }
+ // Set callback for DH parameters
+ MemoryAddress openSSLCallbackTmpDH = CLinker.getInstance().upcallStub(openSSLCallbackTmpDHHandle,
+ openSSLCallbackTmpDHFunctionDescriptor, scope);
+ SSL_CTX_set_tmp_dh_callback(state.sslCtx, openSSLCallbackTmpDH);
+ // Set certificate chain file
+ if (certificate.getCertificateChainFile() != null) {
+ var certificateChainFileNative =
+ CLinker.toCString(SSLHostConfig.adjustRelativePath(certificate.getCertificateChainFile()), scope);
+ // SSLContext.setCertificateChainFile(state.ctx,
+ // SSLHostConfig.adjustRelativePath(certificate.getCertificateChainFile()), false);
+ if (SSL_CTX_use_certificate_chain_file(state.sslCtx, certificateChainFileNative) <= 0) {
+ log.error(sm.getString("openssl.errorLoadingCertificate", certificate.getCertificateChainFile()));
}
- PrivateKey key = x509KeyManager.getPrivateKey(alias);
- StringBuilder sb = new StringBuilder(BEGIN_KEY);
- sb.append(Base64.getMimeEncoder(64, new byte[] {'\n'}).encodeToString(key.getEncoded()));
- sb.append(END_KEY);
- //SSLContext.setCertificateRaw(state.ctx, chain[0].getEncoded(),
- // sb.toString().getBytes(StandardCharsets.US_ASCII),
- // getCertificateIndex(certificate));
- var rawCertificate = allocator.allocateArray(CLinker.C_CHAR, chain[0].getEncoded());
- var rawCertificatePointer = allocator.allocate(CLinker.C_POINTER, rawCertificate);
- var rawKey = allocator.allocateArray(CLinker.C_CHAR, sb.toString().getBytes(StandardCharsets.US_ASCII));
- var x509cert = d2i_X509(MemoryAddress.NULL, rawCertificatePointer, rawCertificate.byteSize());
- if (MemoryAddress.NULL.equals(x509cert)) {
- logLastError(allocator, "openssl.errorLoadingCertificate");
- return;
+ }
+ // Set revocation
+ //SSLContext.setCARevocation(state.ctx,
+ // SSLHostConfig.adjustRelativePath(
+ // sslHostConfig.getCertificateRevocationListFile()),
+ // SSLHostConfig.adjustRelativePath(
+ // sslHostConfig.getCertificateRevocationListPath()));
+ MemoryAddress certificateStore = SSL_CTX_get_cert_store(state.sslCtx);
+ if (sslHostConfig.getCertificateRevocationListFile() != null) {
+ MemoryAddress x509Lookup = X509_STORE_add_lookup(certificateStore, X509_LOOKUP_file());
+ var certificateRevocationListFileNative =
+ CLinker.toCString(SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListFile()), scope);
+ //X509_LOOKUP_ctrl(lookup,X509_L_FILE_LOAD,file,type,NULL)
+ if (X509_LOOKUP_ctrl(x509Lookup, X509_L_FILE_LOAD(), certificateRevocationListFileNative,
+ X509_FILETYPE_PEM(), MemoryAddress.NULL) <= 0) {
+ log.error(sm.getString("openssl.errorLoadingCertificateRevocationList", sslHostConfig.getCertificateRevocationListFile()));
}
- var bio = BIO_new(BIO_s_mem());
- BIO_write(bio, rawKey.address(), (int) rawKey.byteSize());
- MemoryAddress privateKeyAddress = PEM_read_bio_PrivateKey(bio, MemoryAddress.NULL, MemoryAddress.NULL, MemoryAddress.NULL);
- BIO_free(bio);
- if (MemoryAddress.NULL.equals(privateKeyAddress)) {
- logLastError(allocator, "openssl.errorLoadingPrivateKey");
- return;
+ }
+ if (sslHostConfig.getCertificateRevocationListPath() != null) {
+ MemoryAddress x509Lookup = X509_STORE_add_lookup(certificateStore, X509_LOOKUP_hash_dir());
+ var certificateRevocationListPathNative =
+ CLinker.toCString(SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListPath()), scope);
+ //X509_LOOKUP_ctrl(lookup,X509_L_ADD_DIR,path,type,NULL)
+ if (X509_LOOKUP_ctrl(x509Lookup, X509_L_ADD_DIR(), certificateRevocationListPathNative,
+ X509_FILETYPE_PEM(), MemoryAddress.NULL) <= 0) {
+ log.error(sm.getString("openssl.errorLoadingCertificateRevocationList", sslHostConfig.getCertificateRevocationListPath()));
}
- if (SSL_CTX_use_certificate(state.sslCtx, x509cert) <= 0) {
+ }
+ X509_STORE_set_flags(certificateStore, X509_V_FLAG_CRL_CHECK() | X509_V_FLAG_CRL_CHECK_ALL());
+ } else {
+ String alias = certificate.getCertificateKeyAlias();
+ X509KeyManager x509KeyManager = certificate.getCertificateKeyManager();
+ if (alias == null) {
+ alias = "tomcat";
+ }
+ X509Certificate[] chain = x509KeyManager.getCertificateChain(alias);
+ if (chain == null) {
+ alias = findAlias(x509KeyManager, certificate);
+ chain = x509KeyManager.getCertificateChain(alias);
+ }
+ PrivateKey key = x509KeyManager.getPrivateKey(alias);
+ StringBuilder sb = new StringBuilder(BEGIN_KEY);
+ sb.append(Base64.getMimeEncoder(64, new byte[] {'\n'}).encodeToString(key.getEncoded()));
+ sb.append(END_KEY);
+ //SSLContext.setCertificateRaw(state.ctx, chain[0].getEncoded(),
+ // sb.toString().getBytes(StandardCharsets.US_ASCII),
+ // getCertificateIndex(certificate));
+ var rawCertificate = allocator.allocateArray(CLinker.C_CHAR, chain[0].getEncoded());
+ var rawCertificatePointer = allocator.allocate(CLinker.C_POINTER, rawCertificate);
+ var rawKey = allocator.allocateArray(CLinker.C_CHAR, sb.toString().getBytes(StandardCharsets.US_ASCII));
+ var x509cert = d2i_X509(MemoryAddress.NULL, rawCertificatePointer, rawCertificate.byteSize());
+ if (MemoryAddress.NULL.equals(x509cert)) {
+ logLastError(allocator, "openssl.errorLoadingCertificate");
+ return;
+ }
+ var bio = BIO_new(BIO_s_mem());
+ BIO_write(bio, rawKey.address(), (int) rawKey.byteSize());
+ MemoryAddress privateKeyAddress = PEM_read_bio_PrivateKey(bio, MemoryAddress.NULL, MemoryAddress.NULL, MemoryAddress.NULL);
+ BIO_free(bio);
+ if (MemoryAddress.NULL.equals(privateKeyAddress)) {
+ logLastError(allocator, "openssl.errorLoadingPrivateKey");
+ return;
+ }
+ if (SSL_CTX_use_certificate(state.sslCtx, x509cert) <= 0) {
+ logLastError(allocator, "openssl.errorLoadingCertificate");
+ return;
+ }
+ if (SSL_CTX_use_PrivateKey(state.sslCtx, privateKeyAddress) <= 0) {
+ logLastError(allocator, "openssl.errorLoadingPrivateKey");
+ return;
+ }
+ if (SSL_CTX_check_private_key(state.sslCtx) <= 0) {
+ logLastError(allocator, "openssl.errorPrivateKeyCheck");
+ return;
+ }
+ // Set callback for DH parameters
+ MemoryAddress openSSLCallbackTmpDH = CLinker.getInstance().upcallStub(openSSLCallbackTmpDHHandle,
+ openSSLCallbackTmpDHFunctionDescriptor, scope);
+ SSL_CTX_set_tmp_dh_callback(state.sslCtx, openSSLCallbackTmpDH);
+ for (int i = 1; i < chain.length; i++) {
+ //SSLContext.addChainCertificateRaw(state.ctx, chain[i].getEncoded());
+ var rawCertificateChain = allocator.allocateArray(CLinker.C_CHAR, chain[i].getEncoded());
+ var rawCertificateChainPointer = allocator.allocate(CLinker.C_POINTER, rawCertificateChain);
+ var x509certChain = d2i_X509(MemoryAddress.NULL, rawCertificateChainPointer, rawCertificateChain.byteSize());
+ if (MemoryAddress.NULL.equals(x509certChain)) {
logLastError(allocator, "openssl.errorLoadingCertificate");
return;
}
- if (SSL_CTX_use_PrivateKey(state.sslCtx, privateKeyAddress) <= 0) {
- logLastError(allocator, "openssl.errorLoadingPrivateKey");
- return;
- }
- if (SSL_CTX_check_private_key(state.sslCtx) <= 0) {
- logLastError(allocator, "openssl.errorPrivateKeyCheck");
+ // # define SSL_CTX_add0_chain_cert(sslCtx,x509) SSL_CTX_ctrl(sslCtx,SSL_CTRL_CHAIN_CERT,0,(char *)(x509))
+ if (SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_CHAIN_CERT(), 0, x509certChain) <= 0) {
+ logLastError(allocator, "openssl.errorAddingCertificate");
return;
}
- // Set callback for DH parameters
- MemoryAddress openSSLCallbackTmpDH = CLinker.getInstance().upcallStub(openSSLCallbackTmpDHHandle,
- openSSLCallbackTmpDHFunctionDescriptor, state.scope);
- SSL_CTX_set_tmp_dh_callback(state.sslCtx, openSSLCallbackTmpDH);
- for (int i = 1; i < chain.length; i++) {
- //SSLContext.addChainCertificateRaw(state.ctx, chain[i].getEncoded());
- var rawCertificateChain = allocator.allocateArray(CLinker.C_CHAR, chain[i].getEncoded());
- var rawCertificateChainPointer = allocator.allocate(CLinker.C_POINTER, rawCertificateChain);
- var x509certChain = d2i_X509(MemoryAddress.NULL, rawCertificateChainPointer, rawCertificateChain.byteSize());
- if (MemoryAddress.NULL.equals(x509certChain)) {
- logLastError(allocator, "openssl.errorLoadingCertificate");
- return;
- }
- // # define SSL_CTX_add0_chain_cert(sslCtx,x509) SSL_CTX_ctrl(sslCtx,SSL_CTRL_CHAIN_CERT,0,(char *)(x509))
- if (SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_CHAIN_CERT(), 0, x509certChain) <= 0) {
- logLastError(allocator, "openssl.errorAddingCertificate");
- return;
- }
- }
}
}
}
@@ -1362,15 +1353,14 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
private static class ContextState implements Runnable {
- final ResourceScope scope;
private final MemoryAddress sslCtx;
private final MemoryAddress confCtx;
private final List<byte[]> negotiableProtocols;
private X509TrustManager x509TrustManager = null;
- private ContextState(ResourceScope scope, MemoryAddress sslCtx, MemoryAddress confCtx, List<byte[]> negotiableProtocols) {
- this.scope = scope;
+ private ContextState(MemoryAddress sslCtx, MemoryAddress confCtx, List<byte[]> negotiableProtocols) {
+ states.put(Long.valueOf(sslCtx.toRawLongValue()), this);
this.sslCtx = sslCtx;
this.confCtx = confCtx;
this.negotiableProtocols = negotiableProtocols;
@@ -1378,13 +1368,10 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
@Override
public void run() {
- try {
- SSL_CTX_free(sslCtx);
- if (!MemoryAddress.NULL.equals(confCtx)) {
- SSL_CONF_CTX_free(confCtx);
- }
- } finally {
- scope.close();
+ states.remove(Long.valueOf(sslCtx.toRawLongValue()));
+ SSL_CTX_free(sslCtx);
+ if (!MemoryAddress.NULL.equals(confCtx)) {
+ SSL_CONF_CTX_free(confCtx);
}
}
}
diff --git a/modules/openssl-java17/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java b/modules/openssl-java17/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
index 75cca5a..35dc1a8 100644
--- a/modules/openssl-java17/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
+++ b/modules/openssl-java17/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
@@ -266,7 +266,6 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn
var networkBIO = MemoryAccess.getAddress(networkBIOPointer);
SSL_set_bio(ssl, internalBIO, internalBIO);
state = new EngineState(ssl, networkBIO, certificateVerificationDepth, noOcspCheck);
- states.put(Long.valueOf(ssl.address().toRawLongValue()), state);
scope.addCloseAction(state);
this.fallbackApplicationProtocol = fallbackApplicationProtocol;
this.clientMode = clientMode;
@@ -287,7 +286,6 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn
public synchronized void shutdown() {
if (!destroyed) {
destroyed = true;
- states.remove(Long.valueOf(state.ssl.address().toRawLongValue()));
// internal errors can cause shutdown without marking the engine closed
isInboundDone = isOutboundDone = engineClosed = true;
}
@@ -1869,6 +1867,7 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn
private EngineState(MemoryAddress ssl, MemoryAddress networkBIO,
int certificateVerificationDepth, boolean noOcspCheck) {
+ states.put(Long.valueOf(ssl.toRawLongValue()), this);
this.ssl = ssl;
this.networkBIO = networkBIO;
this.certificateVerificationDepth = certificateVerificationDepth;
@@ -1877,6 +1876,7 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn
@Override
public void run() {
+ states.remove(Long.valueOf(ssl.toRawLongValue()));
BIO_free(networkBIO);
SSL_free(ssl);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org