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

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

commit ec6fe19322da755bb79f503dcb13a7151a84964d
Author: Sebb <s...@apache.org>
AuthorDate: Sun Nov 26 23:26:22 2023 +0000

    CRYPTO-179 - avoid crash on macOS
---
 .../java/org/apache/commons/crypto/Crypto.java     |  5 +++
 .../apache/commons/crypto/jna/OpenSslMacOS.java    | 49 ++++++++++++++++++++++
 .../commons/crypto/jna/OpenSslNativeJna.java       | 14 +++++++
 .../org/apache/commons/crypto/DynamicLoader.c      | 12 ++++++
 4 files changed, 80 insertions(+)

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..eea05c3b 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java
@@ -23,6 +23,7 @@ import java.nio.ByteBuffer;
 import org.apache.commons.crypto.Crypto;
 
 import com.sun.jna.Function;
+import com.sun.jna.Native;
 import com.sun.jna.NativeLibrary;
 import com.sun.jna.NativeLong;
 import com.sun.jna.ptr.PointerByReference;
@@ -55,6 +56,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