Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,34 @@ legacy behavior where SNI is automatically configured from hostname/peer informa
even without explicit SSLParameters configuration. Default value is "false", where
SNI is only set when explicitly configured through SSLParameters.

**wolfssl.skipLibraryLoad (boolean)** - When set to "true", `WolfSSL.loadLibrary()`
will skip the default `System.loadLibrary()` calls for native wolfSSL and
wolfSSL JNI libraries. This is useful when applications need to load the native
libraries themselves using custom logic, for example when bundling the native
library inside a JAR file and extracting it at runtime. The property must be set
before `WolfSSL.loadLibrary()` is called, either directly or via
`WolfSSLProvider()` constructor. Applications can check if library loading was
skipped by calling `WolfSSL.isLibraryLoadSkipped()`.

Setting via command line:

```
java -Dwolfssl.skipLibraryLoad=true ...
```

Setting programmatically before library load:

```java
System.setProperty("wolfssl.skipLibraryLoad", "true");

/* Load native libraries with custom logic here */
System.load("/path/to/libwolfssl.so");
System.load("/path/to/libwolfssljni.so");

/* Then use WolfSSL as normal */
WolfSSL.loadLibrary();
```

If there are other System properties you would like to use with wolfJSSE,
please contact support@wolfssl.com.

Expand Down
9 changes: 3 additions & 6 deletions native/com_wolfssl_WolfSSLCertificate.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

91 changes: 71 additions & 20 deletions src/java/com/wolfssl/WolfSSL.java
Original file line number Diff line number Diff line change
Expand Up @@ -471,9 +471,6 @@ public enum TLS_VERSION {
/** Domain name qualifier NID */
public static int NID_dnQualifier;

/* is this object active, or has it been cleaned up? */
private boolean active = false;

/* -------------- Named Groups (from enum in ssl.h) ----------------- */
/** Invalid named group */
public static final int WOLFSSL_NAMED_GROUP_INVALID = 0;
Expand Down Expand Up @@ -567,6 +564,14 @@ public enum TLS_VERSION {
* position, used for LDAPS hostname verification. */
public static int WOLFSSL_LEFT_MOST_WILDCARD_ONLY = 0x40;

/* ------------------------ Internal state -------------------------- */

/* is this object active, or has it been cleaned up? */
private boolean active = false;

/* Track if library loading was skipped via system property */
private static volatile boolean libraryLoadSkipped = false;

/* ---------------------------- locks ------------------------------- */

/* lock for cleanup */
Expand Down Expand Up @@ -720,21 +725,45 @@ public WolfSSL() throws WolfSSLException {
/* ------------------------- Java methods --------------------------- */

/**
* Loads JNI library; must be called prior to any other calls in this class.
* Loads JNI library; must be called prior to any other calls in this
* class.
*
* The native library is expected to be called "wolfssljni", and
* must be on the system library search path.
*
* The native library is expected to be be called "wolfssljni", and must be
* on the system library search path.
* "wolfssljni" links against the wolfSSL native C library
* ("wolfssl"), and for Windows compatibility "wolfssl" needs to be
* explicitly loaded first here.
*
* "wolfssljni" links against the wolfSSL native C library ("wolfssl"),
* and for Windows compatibility "wolfssl" needs to be explicitly
* loaded first here.
* If the system property "wolfssl.skipLibraryLoad" is set to
* "true", this method will skip loading the native library. This
* allows applications to load the native library themselves using
* custom logic (for example extracting from a JAR at runtime).
* The property must be set before this method is called (either
* directly or via WolfSSLProvider constructor).
*
* Applications can check if library loading was skipped by calling
* WolfSSL.isLibraryLoadSkipped().
*
* @throws UnsatisfiedLinkError if the library is not found.
*/
public static void loadLibrary() throws UnsatisfiedLinkError {

int fipsLoaded = 0;

String skipLoad =
System.getProperty("wolfssl.skipLibraryLoad");
if (skipLoad != null && skipLoad.equalsIgnoreCase("true")) {
/* User will load native libraries manually */
libraryLoadSkipped = true;

WolfSSLDebug.log(WolfSSL.class, WolfSSLDebug.Component.JNI,
WolfSSLDebug.INFO, () -> "skipping native library load, " +
"wolfssl.skipLibraryLoad system property set to true");

return;
}
Comment thread
cconlon marked this conversation as resolved.

WolfSSLDebug.log(WolfSSL.class, WolfSSLDebug.Component.JNI,
WolfSSLDebug.INFO, () -> "loading native library: wolfssl");

Expand Down Expand Up @@ -769,6 +798,10 @@ public static void loadLibrary() throws UnsatisfiedLinkError {
* The native library needs to be located on the system library search
* path.
*
* Note: this method does not check the
* "wolfssl.skipLibraryLoad" system property. That property is only
* respected by the no-argument {@link #loadLibrary()} method.
*
* @param libName name of native JNI library
* @throws UnsatisfiedLinkError if the library is not found.
*/
Expand All @@ -781,19 +814,24 @@ public static void loadLibrary(String libName) throws UnsatisfiedLinkError {
}

/**
* Loads dynamic JNI library from a specific path; must be called prior to
* any other calls in this package.
* Loads dynamic JNI library from a specific path; must be called
* prior to any other calls in this package.
*
* This function gives the application more control over the exact
* native library being loaded, as both WolfSSL.loadLibrary() and
* WolfSSL.loadLibrary(String libName) search for a library on the
* system library search path. This function allows the appliation
* to specify a specific absolute path to the native library file
* to load, thus guaranteeing the exact library loaded and helping
* to prevent against malicious attackers from attempting to
* override the library being loaded.
*
* This function gives the application more control over the exact native
* library being loaded, as both WolfSSL.loadLibrary() and
* WolfSSL.loadLibrary(String libName) search for a library on the system
* library search path. This function allows the appliation to specify
* a specific absolute path to the native library file to load, thus
* guaranteeing the exact library loaded and helping to prevent against
* malicious attackers from attempting to override the library being
* loaded.
* Note: this method does not check the
* "wolfssl.skipLibraryLoad" system property. That property is only
* respected by the no-argument {@link #loadLibrary()} method.
*
* @param libPath complete path name to the native dynamic JNI library
* @param libPath complete path name to the native dynamic JNI
* library
* @throws UnsatisfiedLinkError if the library is not found.
*/
public static void loadLibraryAbsolute(String libPath)
Expand All @@ -805,6 +843,19 @@ public static void loadLibraryAbsolute(String libPath)
System.load(libPath);
}

/**
* Check if native library loading was skipped.
*
* Library loading is skipped when the System property
* "wolfssl.skipLibraryLoad" is set to "true" and loadLibrary() has
* been called.
*
* @return true if library loading was skipped, false otherwise
*/
public static boolean isLibraryLoadSkipped() {
return libraryLoadSkipped;
}

/* ----------------- generic static helper functions ---------------- */

/**
Expand Down
56 changes: 56 additions & 0 deletions src/test/com/wolfssl/test/WolfSSLTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ public void testWolfSSL() throws WolfSSLException {
test_WolfSSL_getLibVersionHex();
test_WolfSSL_getErrno();
testGetCiphersAvailableIana();
test_isLibraryLoadSkippedReturnsFalseByDefault();
test_SystemPropertyNotSetByDefault();
test_SettingPropertyAfterLoadHasNoEffect();
}

public void test_WolfSSL_new(WolfSSL lib) {
Expand Down Expand Up @@ -232,5 +235,58 @@ public void test_WolfSSL_getErrno() {

System.out.println("\t\t\t... passed");
}

public void test_isLibraryLoadSkippedReturnsFalseByDefault() {

System.out.print(
"\tisLibraryLoadSkipped() default");

/* Library was loaded normally in @BeforeClass, so
* isLibraryLoadSkipped() should return false */
assertFalse(
"isLibraryLoadSkipped() should be false when " +
"library was loaded normally",
WolfSSL.isLibraryLoadSkipped());

System.out.println("\t... passed");
}

public void test_SystemPropertyNotSetByDefault() {

System.out.print(
"\twolfssl.skipLibraryLoad not set");

/* Verify property is not set by default in test env */
String val =
System.getProperty("wolfssl.skipLibraryLoad");
assertNull(
"wolfssl.skipLibraryLoad should not be set " +
"by default", val);

System.out.println("\t... passed");
}

public void test_SettingPropertyAfterLoadHasNoEffect() {

System.out.print(
"\tskipLibraryLoad after load");

/* Setting the property after library has already been
* loaded should not change isLibraryLoadSkipped() */
try {
System.setProperty(
"wolfssl.skipLibraryLoad", "true");

assertFalse(
"isLibraryLoadSkipped() should still be " +
"false after setting property post-load",
WolfSSL.isLibraryLoadSkipped());

} finally {
System.clearProperty("wolfssl.skipLibraryLoad");
}

System.out.println("\t... passed");
}
}

Loading