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