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 80293fe2d5 Avoid deprecated OpenSSL APIs
80293fe2d5 is described below

commit 80293fe2d556d82a2c332e1ce5291220bfdae5c0
Author: remm <r...@apache.org>
AuthorDate: Fri Sep 1 12:43:53 2023 +0200

    Avoid deprecated OpenSSL APIs
    
    Not sure if this is fully identical to the previous code. A few oddities
    to investigate (EC with keystore ? DH auto use ?).
    Based on the mod_ssl rev 1908537.
    https://svn.apache.org/viewvc?view=revision&revision=1908537
    Use @Deprecated in the generated classes to spot calls. Will be removed
    when regenerating, unfortunately.
    Since there is no rush, leave in the OpenSSL < 3.0 code for now.
    Verified with org.apache.tomcat.util.net.TestSSLHostConfigCompat
---
 .../ciphers/OpenSSLCipherConfigurationParser.java  |  11 ++-
 .../util/net/openssl/panama/OpenSSLContext.java    | 101 ++++++++++++++++-----
 .../util/net/openssl/panama/OpenSSLLibrary.java    |  22 ++---
 .../org/apache/tomcat/util/openssl/openssl_h.java  |  14 +++
 .../net/openssl/panama/LocalStrings.properties     |   2 +
 5 files changed, 113 insertions(+), 37 deletions(-)

diff --git 
a/java/org/apache/tomcat/util/net/openssl/ciphers/OpenSSLCipherConfigurationParser.java
 
b/java/org/apache/tomcat/util/net/openssl/ciphers/OpenSSLCipherConfigurationParser.java
index 13be8d5eae..90d0eaca7e 100644
--- 
a/java/org/apache/tomcat/util/net/openssl/ciphers/OpenSSLCipherConfigurationParser.java
+++ 
b/java/org/apache/tomcat/util/net/openssl/ciphers/OpenSSLCipherConfigurationParser.java
@@ -712,7 +712,16 @@ public class OpenSSLCipherConfigurationParser {
             init();
         }
         String[] elements = expression.split(SEPARATOR);
-        // TODO: Handle PROFILE= using OpenSSL (if present, otherwise warn), 
then replace elements with that
+        // Handle PROFILE= using OpenSSL (if present, otherwise warn), then 
replace elements with that
+        if (elements.length == 1 && elements[0].startsWith("PROFILE=")) {
+            // Only use with Panama and if OpenSSL has been successfully 
loaded before
+            /* FIXME: Merge OpenSSL code first
+            if (JreCompat.isJre22Available() && 
OpenSSLStatus.isLibraryInitialized()) {
+                List<String> cipherList = 
OpenSSLLibrary.findCiphers(elements[0]);
+                // Replace the original list with the profile contents
+                elements = cipherList.toArray(new String[0]);
+            }*/
+        }
         LinkedHashSet<Cipher> ciphers = new LinkedHashSet<>();
         Set<Cipher> removedCiphers = new HashSet<>();
         for (String element : elements) {
diff --git 
a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
 
b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
index c482025a79..343efb13a1 100644
--- 
a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
+++ 
b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
@@ -22,6 +22,7 @@ import java.lang.foreign.FunctionDescriptor;
 import java.lang.foreign.Linker;
 import java.lang.foreign.MemorySegment;
 import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.SymbolLookup;
 import java.lang.foreign.ValueLayout;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
@@ -1113,32 +1114,65 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
             // Try to read DH parameters from the (first) SSLCertificateFile
             if (index == SSL_AIDX_RSA) {
                 bio = BIO_new_file(certificateFileNative, 
localArena.allocateFrom("r"));
-                var dh = PEM_read_bio_DHparams(bio, MemorySegment.NULL, 
MemorySegment.NULL, MemorySegment.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 (!MemorySegment.NULL.equals(dh)) {
-                    SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_TMP_DH(), 0, dh);
-                    DH_free(dh);
+                if (OpenSSL_version_num() < 0x3000000fL) {
+                    var dh = PEM_read_bio_DHparams(bio, MemorySegment.NULL, 
MemorySegment.NULL, MemorySegment.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 (!MemorySegment.NULL.equals(dh)) {
+                        SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_TMP_DH(), 0, 
dh);
+                        DH_free(dh);
+                    }
+                } else {
+                    var pkey = PEM_read_bio_Parameters(bio, 
MemorySegment.NULL);
+                    if (!MemorySegment.NULL.equals(pkey)) {
+                        int numBits = EVP_PKEY_get_bits(pkey);
+                        if (SSL_CTX_set0_tmp_dh_pkey(state.sslCtx, pkey) <= 0) 
{
+                            EVP_PKEY_free(pkey);
+                        } else {
+                            
log.debug(sm.getString("openssl.setCustomDHParameters", numBits, 
certificate.getCertificateFile()));
+                        }
+                    } else {
+                        SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_DH_AUTO(), 1, 
MemorySegment.NULL);
+                    }
                 }
             }
             // Similarly, try to read the ECDH curve name from 
SSLCertificateFile...
             bio = BIO_new_file(certificateFileNative, 
localArena.allocateFrom("r"));
-            var ecparams = PEM_read_bio_ECPKParameters(bio, 
MemorySegment.NULL, MemorySegment.NULL, MemorySegment.NULL);
-            BIO_free(bio);
-            if (!MemorySegment.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);
+            if (OpenSSL_version_num() < 0x3000000fL) {
+                var ecparams = PEM_read_bio_ECPKParameters(bio, 
MemorySegment.NULL, MemorySegment.NULL, MemorySegment.NULL);
+                BIO_free(bio);
+                if (!MemorySegment.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
+                var openSSLCallbackTmpDH = 
Linker.nativeLinker().upcallStub(openSSLCallbackTmpDHHandle,
+                        openSSLCallbackTmpDHFunctionDescriptor, contextArena);
+                SSL_CTX_set_tmp_dh_callback(state.sslCtx, 
openSSLCallbackTmpDH);
+            } else {
+                var d2i_ECPKParameters = 
SymbolLookup.loaderLookup().find("d2i_ECPKParameters").get();
+                var ecparams = PEM_ASN1_read_bio(d2i_ECPKParameters,
+                        PEM_STRING_ECPARAMETERS(), bio, MemorySegment.NULL, 
MemorySegment.NULL, MemorySegment.NULL);
+                BIO_free(bio);
+                if (!MemorySegment.NULL.equals(ecparams)) {
+                    int curveNid = EC_GROUP_get_curve_name(ecparams);
+                    var curveNidAddress = 
localArena.allocateFrom(ValueLayout.JAVA_INT, curveNid);
+                    // SSL_CTX_set1_curves(state.sslCtx, &curveNid, 1)
+                    if (SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_GROUPS(), 1, 
curveNidAddress) <= 0) {
+                        curveNid = 0;
+                    }
+                    if (log.isDebugEnabled()) {
+                        log.debug(sm.getString("openssl.setECDHCurve", 
curveNid, certificate.getCertificateFile()));
+                    }
+                    EC_GROUP_free(ecparams);
+                }
             }
-            // Set callback for DH parameters
-            var openSSLCallbackTmpDH = 
Linker.nativeLinker().upcallStub(openSSLCallbackTmpDHHandle,
-                    openSSLCallbackTmpDHFunctionDescriptor, contextArena);
-            SSL_CTX_set_tmp_dh_callback(state.sslCtx, openSSLCallbackTmpDH);
             // Set certificate chain file
             if (certificate.getCertificateChainFile() != null) {
                 var certificateChainFileNative =
@@ -1223,10 +1257,27 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
                 logLastError(localArena, "openssl.errorPrivateKeyCheck");
                 return;
             }
-            // Set callback for DH parameters
-            var openSSLCallbackTmpDH = 
Linker.nativeLinker().upcallStub(openSSLCallbackTmpDHHandle,
-                    openSSLCallbackTmpDHFunctionDescriptor, contextArena);
-            SSL_CTX_set_tmp_dh_callback(state.sslCtx, openSSLCallbackTmpDH);
+            if (OpenSSL_version_num() < 0x3000000fL) {
+                // Set callback for DH parameters
+                var openSSLCallbackTmpDH = 
Linker.nativeLinker().upcallStub(openSSLCallbackTmpDHHandle,
+                        openSSLCallbackTmpDHFunctionDescriptor, contextArena);
+                SSL_CTX_set_tmp_dh_callback(state.sslCtx, 
openSSLCallbackTmpDH);
+            } else {
+                bio = BIO_new(BIO_s_mem());
+                BIO_write(bio, rawKey, (int) rawKey.byteSize());
+                var pkey = PEM_read_bio_Parameters(bio, MemorySegment.NULL);
+                if (!MemorySegment.NULL.equals(pkey)) {
+                    int numBits = EVP_PKEY_get_bits(pkey);
+                    if (SSL_CTX_set0_tmp_dh_pkey(state.sslCtx, pkey) <= 0) {
+                        EVP_PKEY_free(pkey);
+                    } else {
+                        
log.debug(sm.getString("openssl.setCustomDHParameters", numBits, 
certificate.getCertificateFile()));
+                    }
+                } else {
+                    SSL_CTX_ctrl(state.sslCtx, SSL_CTRL_SET_DH_AUTO(), 1, 
MemorySegment.NULL);
+                }
+                BIO_free(bio);
+            }
             for (int i = 1; i < chain.length; i++) {
                 //SSLContext.addChainCertificateRaw(state.ctx, 
chain[i].getEncoded());
                 var rawCertificateChain = 
localArena.allocateFrom(ValueLayout.JAVA_BYTE, chain[i].getEncoded());
diff --git 
a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java
 
b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java
index 43da3c13c9..ba3a1007ff 100644
--- 
a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java
+++ 
b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java
@@ -39,8 +39,6 @@ import org.apache.tomcat.util.res.StringManager;
  * configuration parameters.
  * Using this from a listener is completely optional, but is needed for
  * configuration and full cleanup of a few native memory allocations.
- * FIXME: OpenSSL 3 deprecation resolutions for the equivalent code:
- * https://svn.apache.org/viewvc?view=revision&revision=1908537
  */
 public class OpenSSLLibrary {
 
@@ -178,9 +176,12 @@ public class OpenSSLLibrary {
                 // Main library init
                 initLibrary();
 
+                // OpenSSL 3 onwards uses providers
+                boolean usingProviders = (OpenSSL_version_num() >= 
0x3000000fL);
+
                 // Setup engine
                 String engineName = "on".equalsIgnoreCase(SSLEngine) ? null : 
SSLEngine;
-                if (engineName != null) {
+                if (!usingProviders && engineName != null) {
                     if ("auto".equals(engineName)) {
                         ENGINE_register_all_complete();
                     } else {
@@ -224,10 +225,9 @@ public class OpenSSLLibrary {
                     
RAND_seed(memorySession.allocateFrom(ValueLayout.JAVA_BYTE, randomBytes), 128);
                 }
 
-                initDHParameters();
-
-                // OpenSSL 3 onwards uses providers
-                boolean usingProviders = (OpenSSL_version_num() >= 
0x3000000fL);
+                if (!usingProviders) {
+                    initDHParameters();
+                }
 
                 if (usingProviders || !(null == FIPSMode || 
"off".equalsIgnoreCase(FIPSMode))) {
                     fipsModeActive = false;
@@ -335,11 +335,11 @@ public class OpenSSLLibrary {
             OpenSSLStatus.setAvailable(false);
 
             try {
-                freeDHParameters();
-                if (!MemorySegment.NULL.equals(enginePointer)) {
-                    ENGINE_free(enginePointer);
-                }
                 if (OpenSSL_version_num() < 0x3000000fL) {
+                    freeDHParameters();
+                    if (!MemorySegment.NULL.equals(enginePointer)) {
+                        ENGINE_free(enginePointer);
+                    }
                     FIPS_mode_set(0);
                 }
             } finally {
diff --git 
a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/openssl/openssl_h.java
 
b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/openssl/openssl_h.java
index 978e7551c4..fc5ad10d81 100644
--- 
a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/openssl/openssl_h.java
+++ 
b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/openssl/openssl_h.java
@@ -1226,6 +1226,7 @@ public class openssl_h  {
      * EC_KEY* EC_KEY_new_by_curve_name(int nid);
      * }
      */
+    @Deprecated
     public static MemorySegment EC_KEY_new_by_curve_name(int nid) {
         var mh$ = EC_KEY_new_by_curve_name$MH();
         try {
@@ -1242,6 +1243,7 @@ public class openssl_h  {
      * void EC_KEY_free(EC_KEY* key);
      * }
      */
+    @Deprecated
     public static void EC_KEY_free(MemorySegment key) {
         var mh$ = EC_KEY_free$MH();
         try {
@@ -1258,6 +1260,7 @@ public class openssl_h  {
      * DH* DH_new();
      * }
      */
+    @Deprecated
     public static MemorySegment DH_new() {
         var mh$ = DH_new$MH();
         try {
@@ -1274,6 +1277,7 @@ public class openssl_h  {
      * void DH_free(DH* dh);
      * }
      */
+    @Deprecated
     public static void DH_free(MemorySegment dh) {
         var mh$ = DH_free$MH();
         try {
@@ -1290,6 +1294,7 @@ public class openssl_h  {
      * int DH_set0_pqg(DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g);
      * }
      */
+    @Deprecated
     public static int DH_set0_pqg(MemorySegment dh, MemorySegment p, 
MemorySegment q, MemorySegment g) {
         var mh$ = DH_set0_pqg$MH();
         try {
@@ -1642,6 +1647,7 @@ public class openssl_h  {
      * EC_GROUP* PEM_read_bio_ECPKParameters(BIO* out, EC_GROUP** x, 
pem_password_cb* cb, void* u);
      * }
      */
+    @Deprecated
     public static MemorySegment PEM_read_bio_ECPKParameters(MemorySegment out, 
MemorySegment x, MemorySegment cb, MemorySegment u) {
         var mh$ = PEM_read_bio_ECPKParameters$MH();
         try {
@@ -1658,6 +1664,7 @@ public class openssl_h  {
      * DH* PEM_read_bio_DHparams(BIO* out, DH** x, pem_password_cb* cb, void* 
u);
      * }
      */
+    @Deprecated
     public static MemorySegment PEM_read_bio_DHparams(MemorySegment out, 
MemorySegment x, MemorySegment cb, MemorySegment u) {
         var mh$ = PEM_read_bio_DHparams$MH();
         try {
@@ -2746,6 +2753,7 @@ public class openssl_h  {
      * void SSL_CTX_set_tmp_dh_callback(SSL_CTX* ctx, DH* (*dh)(SSL*,int,int));
      * }
      */
+    @Deprecated
     public static void SSL_CTX_set_tmp_dh_callback(MemorySegment ctx, 
MemorySegment dh) {
         var mh$ = SSL_CTX_set_tmp_dh_callback$MH();
         try {
@@ -3066,6 +3074,7 @@ public class openssl_h  {
      * ENGINE* ENGINE_by_id(char* id);
      * }
      */
+    @Deprecated
     public static MemorySegment ENGINE_by_id(MemorySegment id) {
         var mh$ = ENGINE_by_id$MH();
         try {
@@ -3082,6 +3091,7 @@ public class openssl_h  {
      * int ENGINE_register_all_complete();
      * }
      */
+    @Deprecated
     public static int ENGINE_register_all_complete() {
         var mh$ = ENGINE_register_all_complete$MH();
         try {
@@ -3098,6 +3108,7 @@ public class openssl_h  {
      * int ENGINE_ctrl_cmd_string(ENGINE* e, char* cmd_name, char* arg, int 
cmd_optional);
      * }
      */
+    @Deprecated
     public static int ENGINE_ctrl_cmd_string(MemorySegment e, MemorySegment 
cmd_name, MemorySegment arg, int cmd_optional) {
         var mh$ = ENGINE_ctrl_cmd_string$MH();
         try {
@@ -3114,6 +3125,7 @@ public class openssl_h  {
      * int ENGINE_free(ENGINE* e);
      * }
      */
+    @Deprecated
     public static int ENGINE_free(MemorySegment e) {
         var mh$ = ENGINE_free$MH();
         try {
@@ -3130,6 +3142,7 @@ public class openssl_h  {
      * EVP_PKEY* ENGINE_load_private_key(ENGINE* e, char* key_id, UI_METHOD* 
ui_method, void* callback_data);
      * }
      */
+    @Deprecated
     public static MemorySegment ENGINE_load_private_key(MemorySegment e, 
MemorySegment key_id, MemorySegment ui_method, MemorySegment callback_data) {
         var mh$ = ENGINE_load_private_key$MH();
         try {
@@ -3146,6 +3159,7 @@ public class openssl_h  {
      * int ENGINE_set_default(ENGINE* e, unsigned int flags);
      * }
      */
+    @Deprecated
     public static int ENGINE_set_default(MemorySegment e, int flags) {
         var mh$ = ENGINE_set_default$MH();
         try {
diff --git 
a/modules/openssl-foreign/src/main/resources/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties
 
b/modules/openssl-foreign/src/main/resources/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties
index b8b108272b..f1bff0a31a 100644
--- 
a/modules/openssl-foreign/src/main/resources/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties
+++ 
b/modules/openssl-foreign/src/main/resources/org/apache/tomcat/util/net/openssl/panama/LocalStrings.properties
@@ -61,6 +61,8 @@ 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.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
 
 opensslconf.applyCommand=OpenSSLConf applying command (name [{0}], value [{1}])


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

Reply via email to