Skip to content

Commit

Permalink
CRYPTO-174: Allow override of SSL library name for Windows (#267)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebbASF committed Nov 6, 2023
1 parent 950bf17 commit e51a925
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 23 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/maven_adhoc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
1 change: 1 addition & 0 deletions src/changes/changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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 -->
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/apache/commons/crypto/Crypto.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ public static boolean isNativeCodeLoaded() {
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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ public static void main(final String[] args) throws Throwable {
// 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();
Expand Down
15 changes: 12 additions & 3 deletions src/main/java/org/apache/commons/crypto/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -190,22 +190,31 @@ public static Properties getProperties(final Properties newProp) {

/*
* 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.
* Although it could all be implemented in native code, this hook method
* 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;
}

/**
Expand Down
42 changes: 28 additions & 14 deletions src/main/native/org/apache/commons/crypto/DynamicLoader.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down

0 comments on commit e51a925

Please sign in to comment.