Skip to content

Commit

Permalink
Crypto 179 - Crash on macOS with default crypto library (#282)
Browse files Browse the repository at this point in the history
* CRYPTO-179 Crash on macOS with default crypto lib

[skip ci]
  • Loading branch information
sebbASF authored Nov 26, 2023
1 parent 896a4cb commit 96b3d0d
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/changes/changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/org/apache/commons/crypto/Crypto.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ private static Properties getComponentProperties() {

/** 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;

Expand Down
49 changes: 49 additions & 0 deletions src/main/java/org/apache/commons/crypto/jna/OpenSslMacOS.java
Original file line number Diff line number Diff line change
@@ -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();
}

}
13 changes: 13 additions & 0 deletions src/main/java/org/apache/commons/crypto/jna/OpenSslNativeJna.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
12 changes: 12 additions & 0 deletions src/main/native/org/apache/commons/crypto/DynamicLoader.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 96b3d0d

Please sign in to comment.