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 085efe05 CRYPTO-174: Allow override of SSL library name (#269)
085efe05 is described below

commit 085efe05852d48cdacc11175280f36a23ba0f36e
Author: sebbASF <[email protected]>
AuthorDate: Wed Nov 8 01:05:55 2023 +0000

    CRYPTO-174: Allow override of SSL library name (#269)
    
    Add code to allow override of default library name, and implement it for 
Windows builds
---
 .github/workflows/maven.yml                        | 16 ++++-----
 .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      | 39 ++++++++++++++--------
 7 files changed, 53 insertions(+), 32 deletions(-)

diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 4fe5c748..22f02cf2 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -91,22 +91,20 @@ jobs:
     - name: OpenSSL engine (windows)
       # need to override the libarary on windows
       if: ${{ matrix.os == 'windows-latest' }}
-      # e.g. ENGINESDIR: "C:\Program Files\OpenSSL\lib\engines-1_1"
-      # The code below extracts "C:\Program Files\OpenSSL\lib", as expected
-      # but this does not seem to be the correct setting to override system 
library
-      # To avoid failing tests unnecessarily, skip the check for OpenSSL in 
the library name
-      # To be resolved...
-      # N.B. This must *not* be run under the bash shell, as that changes the 
default openssl library
+      # e.g. NAME: "libcrypto-1_1-x64.dll"
+      # Not sure how to derive this automatically
       run: |
         openssl version -a
-        chcp 65001 #set code page to utf-8
-        echo ((openssl version -e) -replace ': "','=' -replace 
'\\engines-.*','') >> $env:GITHUB_ENV
+        echo "NAME=libcrypto-1_1-x64.dll" >> $env:GITHUB_ENV
         echo "CHECK_SKIP=skip" >> $env:GITHUB_ENV
     # N.B. '-V -B -ntp' is shorthand for '--show-version --batch-mode 
--no-transfer-progress'
     # 
     # The bash shell under Windows changes the openssl default library, so is 
not used for running tests
     # Unfortunately that means separate steps for Windows, as it uses a 
different syntax for referrring to
     # environment variables: $env:VARNAME instead of $VARNAME
+    # Also, note that Windows stores all the DLLs in the same directory.
+    # Instead of defining jni.library.path and jna.library.path we need to 
define
+    # jni.library.name and commons.crypto.OpenSslNativeJna to override the 
file names
     - name: Build with Maven (Windows)
       if: ${{ matrix.os == 'windows-latest' }}
       # OPENSSL_HOME is needed for Windows build to find some header files
@@ -119,7 +117,7 @@ jobs:
       env:
         OPENSSL_HOME: "C:\\Miniconda\\Library"
       run: |
-        mvn -V -B -ntp -DtrimStackTrace=false 
-D"jni.library.path=$env:ENGINESDIR" -D"jna.library.path=$env:ENGINESDIR" 
-D"commons.crypto.openssl.check=$env:CHECK_SKIP"
+        mvn -V -B -ntp -DtrimStackTrace=false -D"jni.library.name=$env:NAME" 
-D"commons.crypto.OpenSslNativeJna=$env:NAME" 
-D"commons.crypto.openssl.check=$env:CHECK_SKIP"
     - name: Build with Maven (not Windows)
       if: ${{ matrix.os != 'windows-latest' }}
       run: |
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..1f265627 100644
--- a/src/main/native/org/apache/commons/crypto/DynamicLoader.c
+++ b/src/main/native/org/apache/commons/crypto/DynamicLoader.c
@@ -44,26 +44,37 @@ HMODULE open_library(JNIEnv *env)
 #endif
 
 #ifdef WINDOWS
-    // not necessary to provide override for Windows
-    openssl = LoadLibrary(TEXT(COMMONS_CRYPTO_OPENSSL_LIBRARY));
+    openssl = LoadLibraryA(libraryPath); // use the non-generic method; assume 
libraryPath is suitable
 #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