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 e51a9259 CRYPTO-174: Allow override of SSL library name for Windows 
(#267)
e51a9259 is described below

commit e51a9259d3959f19b723f35c8ac95d022f081ee7
Author: sebbASF <[email protected]>
AuthorDate: Mon Nov 6 22:58:53 2023 +0000

    CRYPTO-174: Allow override of SSL library name for Windows (#267)
---
 .github/workflows/maven_adhoc.yml                  | 12 +++----
 src/changes/changes.xml                            |  1 +
 .../java/org/apache/commons/crypto/Crypto.java     |  1 +
 .../org/apache/commons/crypto/jna/OpenSslJna.java  |  1 +
 .../org/apache/commons/crypto/utils/Utils.java     | 15 ++++++--
 .../org/apache/commons/crypto/DynamicLoader.c      | 42 ++++++++++++++--------
 6 files changed, 49 insertions(+), 23 deletions(-)

diff --git a/.github/workflows/maven_adhoc.yml 
b/.github/workflows/maven_adhoc.yml
index 15a9442d..d0dfc3d0 100644
--- a/.github/workflows/maven_adhoc.yml
+++ b/.github/workflows/maven_adhoc.yml
@@ -63,18 +63,18 @@ jobs:
     - name: Build with Maven
       env:
         OPENSSL_HOME: "C:\\Miniconda\\Library"
-        LIB: "C:\\Program Files\\OpenSSL\\lib"
+        NAME: "libcrypto-1_1-x64"
       run: |
-        mvn clean test -B -V -ntp -DtrimStackTrace=false 
-D"jni.library.path=$env:LIB" -D"jna.library.path=$env:LIB" 
-D"commons.crypto.openssl.check=skip" -D"commons.crypto.debug=true"
+        mvn clean test -B -V -ntp -D"jna.debug_load=true" 
-DtrimStackTrace=false -D"jni.library.name=$env:NAME" 
-D"commons.crypto.OpenSslNativeJna=$env:NAME" 
-D"commons.crypto.openssl.check=skip" -D"commons.crypto.debug=true"
     - name: JNA test
       if: always()
       env:
-        LIB: "C:\\Program Files\\OpenSSL\\lib"
+        NAME: "crypto-1_1-x64"
       run: |
-        mvn -q exec:java 
-D"exec.mainClass=org.apache.commons.crypto.jna.OpenSslJna" 
-D"commons.crypto.debug=true" -D"jna.library.path=$env:LIB"
+        mvn -q exec:java -D"jna.debug_load=true" 
-D"exec.mainClass=org.apache.commons.crypto.jna.OpenSslJna" 
-D"commons.crypto.debug=true" -D"commons.crypto.OpenSslNativeJna=$env:NAME"
     - name: JNI test
       if: always()
       env:
-        LIB: "C:\\Program Files\\OpenSSL\\lib"
+        NAME: "libcrypto-1_1-x64"
       run: |
-        mvn -q exec:java -D"exec.mainClass=org.apache.commons.crypto.Crypto" 
-D"commons.crypto.debug=true" -D"jni.library.path=$env:LIB"
+        mvn -q exec:java -D"exec.mainClass=org.apache.commons.crypto.Crypto" 
-D"commons.crypto.debug=true" -D"jni.library.name=$env:NAME"
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index dd886728..062913db 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -95,6 +95,7 @@
       <action                    type="update" dev="ggregory" due-to="Gary 
Gregory">Bump com.sun.xml.bind:jaxb-impl from 2.3.7 to 2.3.8.</action>
       <!-- ADD -->
       <action                    type="add" dev="sebb" due-to="Ludovic 
Henry">CRYPTO-172: Add support for Linux-riscv64 #264</action>
+      <action                    type="add" dev="sebb">CRYPTO-174: Allow 
override of SSL library name for Windows</action>
     </release>
     <release version="1.2.0" date="2023-01-14" description="Minor release 
(Java 8, OpenSSL 1.1.1)">
       <!-- FIX -->
diff --git a/src/main/java/org/apache/commons/crypto/Crypto.java 
b/src/main/java/org/apache/commons/crypto/Crypto.java
index 5a082a77..1748419e 100644
--- a/src/main/java/org/apache/commons/crypto/Crypto.java
+++ b/src/main/java/org/apache/commons/crypto/Crypto.java
@@ -152,6 +152,7 @@ public final class Crypto {
     public static void main(final String[] args) throws Exception {
         quiet = args.length == 1 && args[0].equals("-q");
         info("jni.library.path=%s", System.getProperty("jni.library.path"));
+        info("jni.library.name=%s", System.getProperty("jni.library.name"));
         info("%s %s", getComponentName(), getComponentVersion());
         if (isNativeCodeLoaded()) {
             info("Native code loaded OK: %s", 
OpenSslInfoNative.NativeVersion());
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java 
b/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java
index e00de96d..a6064589 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java
@@ -99,6 +99,7 @@ public final class OpenSslJna {
         // These are used by JNA code if defined:
         info("jna.library.path=%s", System.getProperty("jna.library.path"));
         info("jna.platform.library.path=%s", 
System.getProperty("jna.platform.library.path"));
+        info("commons.crypto.OpenSslNativeJna=%s\n", 
System.getProperty("commons.crypto.OpenSslNativeJna"));
         // can set jna.debug_load=true for loading info
         info(Crypto.getComponentName() + " OpenSslJna: enabled = %s, version = 
0x%08X", isEnabled(), OpenSslNativeJna.VERSION);
         final Throwable initialisationError = initialisationError();
diff --git a/src/main/java/org/apache/commons/crypto/utils/Utils.java 
b/src/main/java/org/apache/commons/crypto/utils/Utils.java
index f02fc78c..e46c3a19 100644
--- a/src/main/java/org/apache/commons/crypto/utils/Utils.java
+++ b/src/main/java/org/apache/commons/crypto/utils/Utils.java
@@ -190,6 +190,8 @@ public final class Utils {
 
     /*
      * Override the default DLL name if jni.library.path is a valid directory
+     * If jni.library.name is defined, this overrides the default name.
+     *
      * @param name - the default name, passed from native code
      * @return the updated library path
      * This method is designed for use from the DynamicLoader native code.
@@ -197,15 +199,22 @@ public final class Utils {
      * makes maintenance easier.
      * The code is intended for use with macOS where SIP makes it hard to 
override
      * the environment variables needed to override the DLL search path. It 
also
-     * works for Linux, but is not (currently) used or needed for Windows.
+     * works for Linux.
+     * On both macOS and Linux, different versions of the library are stored 
in different directories.
+     * In each case, there is a link from the canonical name (libcrypto.xx) to 
the versioned name (libcrypto-1.2.3.xx)
+     * However on Windows, all the DLL versions seem to be stored in the same 
directory.
+     * This means that Windows code needs to be given the versioned name (e.g. 
libcrypto-1_1-x64)
+     * This is done by defining jni.library.name.
+     * 
      * Do not change the method name or its signature!
      */
     static String libraryPath(final String name) {
+        final String overridename = System.getProperty("jni.library.name", 
name);
         final String override = System.getProperty("jni.library.path");
         if (override != null && new File(override).isDirectory()) {
-            return new File(override, name).getPath();
+            return new File(override, overridename).getPath();
         }
-        return name;
+        return overridename;
     }
 
     /**
diff --git a/src/main/native/org/apache/commons/crypto/DynamicLoader.c 
b/src/main/native/org/apache/commons/crypto/DynamicLoader.c
index 1b28265e..57fff14a 100644
--- a/src/main/native/org/apache/commons/crypto/DynamicLoader.c
+++ b/src/main/native/org/apache/commons/crypto/DynamicLoader.c
@@ -44,26 +44,40 @@ HMODULE open_library(JNIEnv *env)
 #endif
 
 #ifdef WINDOWS
-    // not necessary to provide override for Windows
-    openssl = LoadLibrary(TEXT(COMMONS_CRYPTO_OPENSSL_LIBRARY));
+    size_t liblen = strlen(libraryPath) + 1;
+    wchar_t* lib = (wchar_t *)malloc(liblen);
+    mbstowcs(lib, libraryPath, liblen); // convert for Windows call
+    openssl = LoadLibrary(lib);
 #endif
 
-  }
-//   Did we succeed?
-  if (!openssl)
-  {
-      char msg[1000];
+    //   Did we succeed?
+    if (!openssl)
+    {
+        char msg[1000];
 #ifdef UNIX
-    snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", 
COMMONS_CRYPTO_OPENSSL_LIBRARY,  \
-    dlerror()); // returns char*
+        snprintf(msg, sizeof(msg), "Cannot load '%s' (%s)!", libraryPath, 
dlerror()); // returns char*
 #endif
 #ifdef WINDOWS
-    // TODO: convert to string
-    snprintf(msg, sizeof(msg), "Cannot load %s (%d)!", 
COMMONS_CRYPTO_OPENSSL_LIBRARY,  \
-    GetLastError()); // returns DWORD
+        // Crude method to convert most likely errors to string
+        DWORD lastError = GetLastError();
+        char *lastmsg;
+        if (lastError == 126)
+        {
+            lastmsg = "specified module cannot be found";
+        }
+        else if (lastError == 193)
+        {
+            lastmsg = "module is not a valid Win32 application";
+        }
+        else
+        {
+            lastmsg = "unknown error - check online Windows documentation";
+        }
+        snprintf(msg, sizeof(msg), "Cannot load '%s' (%d: %s)!", libraryPath, 
lastError, lastmsg);
 #endif
-    THROW(env, "java/lang/UnsatisfiedLinkError", msg);
-    return 0;
+        THROW(env, "java/lang/UnsatisfiedLinkError", msg);
+        return 0;
+    }
   }
   return openssl;
 }

Reply via email to