This is an automated email from the ASF dual-hosted git repository.

sebb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-crypto.git


The following commit(s) were added to refs/heads/master by this push:
     new 96b3d0d6 Crypto 179 - Crash on macOS with default crypto library (#282)
96b3d0d6 is described below

commit 96b3d0d6c6d86e140bebdb6b6cd96d2925097e23
Author: Sebb <sebb...@users.noreply.github.com>
AuthorDate: Sun Nov 26 23:56:52 2023 +0000

    Crypto 179 - Crash on macOS with default crypto library (#282)
    
    * CRYPTO-179 Crash on macOS with default crypto lib
    
    [skip ci]
---
 src/changes/changes.xml                            |  1 +
 .../java/org/apache/commons/crypto/Crypto.java     |  5 +++
 .../apache/commons/crypto/jna/OpenSslMacOS.java    | 49 ++++++++++++++++++++++
 .../commons/crypto/jna/OpenSslNativeJna.java       | 13 ++++++
 .../org/apache/commons/crypto/DynamicLoader.c      | 12 ++++++
 5 files changed, 80 insertions(+)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 25959d4a..e426c788 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -65,6 +65,7 @@
   <body>
     <release version="1.2.1" date="202X-MM-DD" description="Minor release 
(Java 8, OpenSSL 1.1.1)">
       <!-- FIX -->
+      <action issue="CRYPTO-179" type="fix" dev="sebb">Crash on macOS with 
default crypto library</action>
       <action issue="CRYPTO-166" type="fix" dev="sebb">Library is reloaded 
multiple times</action>
       <action issue="CRYPTO-175" type="fix" dev="sebb">JNA tests rely on JNI 
code</action>
       <action issue="CRYPTO-178" type="fix" 
dev="sebb">OpenSslCryptoRandom.isNativeCodeEnabled() throws if library cannot 
be loaded</action>
diff --git a/src/main/java/org/apache/commons/crypto/Crypto.java 
b/src/main/java/org/apache/commons/crypto/Crypto.java
index e8d08295..5aca20ad 100644
--- a/src/main/java/org/apache/commons/crypto/Crypto.java
+++ b/src/main/java/org/apache/commons/crypto/Crypto.java
@@ -106,6 +106,11 @@ public final class Crypto {
 
     /** Default name for loading SSL crypto library using JNA */
     public static final String JNA_LIBRARY_NAME_DEFAULT = "crypto";
+    /**
+     * Name for loading SSL crypto library using dlopen on macOS
+     * JNA automatically adds prefix and suffix; dlopen does not 
+     */
+    public static final String MACOS_LIBRARY_NAME_DEFAULT = "libcrypto.dylib";
 
     private static boolean quiet;
 
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpenSslMacOS.java 
b/src/main/java/org/apache/commons/crypto/jna/OpenSslMacOS.java
new file mode 100644
index 00000000..b4165de7
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSslMacOS.java
@@ -0,0 +1,49 @@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.crypto.jna;
+
+import com.sun.jna.Native;
+
+/*
+ * Get access to dlopen_preflight from JNA code
+ * For use on macOS only - CRYPTO-179
+ */
+class OpenSslMacOS {
+
+    static native boolean dlopen_preflight(String path);
+
+    static native String dlerror();
+
+    static {
+        Native.register((String)null);
+    }
+
+    /**
+     * Check if can load library OK
+     * @param path
+     * @return null if OK, else error message
+     */
+    public static String checkLibrary(String path) {
+        if (dlopen_preflight(path)){
+            return null;
+        }
+        return dlerror();
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java 
b/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java
index 8662b026..c4b1d1e3 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java
@@ -55,6 +55,19 @@ final class OpenSslNativeJna {
         OpenSslJna.debug("OpenSslNativeJna static init start");
         final String libraryName = System.getProperty(Crypto.JNA_LIBRARY_NAME, 
Crypto.JNA_LIBRARY_NAME_DEFAULT);
         OpenSslJna.debug("OpenSslNativeJna NativeLibrary.getInstance('%s')", 
libraryName);
+        // CRYPTO-179 - avoid crash
+        if ("Mac OS X".equals(System.getProperty("os.name"))
+            && System.getProperty(Crypto.JNA_LIBRARY_NAME, "").isEmpty()
+            && System.getProperty(Crypto.JNA_LIBRARY_PATH, "").isEmpty()
+        ) {
+            String ret = 
OpenSslMacOS.checkLibrary(Crypto.MACOS_LIBRARY_NAME_DEFAULT);
+            if (ret != null) {
+                throw new UnsatisfiedLinkError(
+                    String.format("Cannot load default library '%s'; need 
jni.library.path! (%s)",
+                        Crypto.MACOS_LIBRARY_NAME_DEFAULT, ret));
+            }
+        }
+            System.err.println("Lib check4" );
         @SuppressWarnings("resource") // NativeLibrary.getInstance returns a 
singleton
         final NativeLibrary crypto = NativeLibrary.getInstance(libraryName);
         OpenSslJna.debug("OpenSslNativeJna NativeLibrary.getInstance('%s') -> 
%s", libraryName, crypto);
diff --git a/src/main/native/org/apache/commons/crypto/DynamicLoader.c 
b/src/main/native/org/apache/commons/crypto/DynamicLoader.c
index 1f265627..68b731a3 100644
--- a/src/main/native/org/apache/commons/crypto/DynamicLoader.c
+++ b/src/main/native/org/apache/commons/crypto/DynamicLoader.c
@@ -39,6 +39,18 @@ HMODULE open_library(JNIEnv *env)
             }
         }
     }
+#ifdef MAC_OS
+    #include <string.h>
+    if (0 == strncmp(COMMONS_CRYPTO_OPENSSL_LIBRARY,libraryPath, 
sizeof(COMMONS_CRYPTO_OPENSSL_LIBRARY))) {
+        bool ret = dlopen_preflight(libraryPath);
+        if (!ret) {
+            char msg[1000];
+            snprintf(msg, sizeof(msg), "Cannot load default library '%s'; need 
jni.library.path! (%s)", libraryPath, dlerror());
+            THROW(env, "java/lang/UnsatisfiedLinkError", msg);
+            return 0;
+        }
+    }
+#endif
 #ifdef UNIX
     openssl = dlopen(libraryPath, RTLD_LAZY | RTLD_GLOBAL);
 #endif

Reply via email to