Skip to content

Commit 3c656fb

Browse files
committed
Add wolfssl.skipLibraryLoad system property for custom native library loading
1 parent 96f1fdb commit 3c656fb

4 files changed

Lines changed: 158 additions & 26 deletions

File tree

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,34 @@ legacy behavior where SNI is automatically configured from hostname/peer informa
619619
even without explicit SSLParameters configuration. Default value is "false", where
620620
SNI is only set when explicitly configured through SSLParameters.
621621

622+
**wolfssl.skipLibraryLoad (boolean)** - When set to "true", `WolfSSL.loadLibrary()`
623+
will skip the default `System.loadLibrary()` calls for native wolfSSL and
624+
wolfSSL JNI libraries. This is useful when applications need to load the native
625+
libraries themselves using custom logic, for example when bundling the native
626+
library inside a JAR file and extracting it at runtime. The property must be set
627+
before `WolfSSL.loadLibrary()` is called, either directly or via
628+
`WolfSSLProvider()` constructor. Applications can check if library loading was
629+
skipped by calling `WolfSSL.isLibraryLoadSkipped()`.
630+
631+
Setting via command line:
632+
633+
```
634+
java -Dwolfssl.skipLibraryLoad=true ...
635+
```
636+
637+
Setting programmatically before library load:
638+
639+
```java
640+
System.setProperty("wolfssl.skipLibraryLoad", "true");
641+
642+
/* Load native libraries with custom logic here */
643+
System.load("/path/to/libwolfssl.so");
644+
System.load("/path/to/libwolfssljni.so");
645+
646+
/* Then use WolfSSL as normal */
647+
WolfSSL.loadLibrary();
648+
```
649+
622650
If there are other System properties you would like to use with wolfJSSE,
623651
please contact support@wolfssl.com.
624652

native/com_wolfssl_WolfSSLCertificate.h

Lines changed: 3 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/java/com/wolfssl/WolfSSL.java

Lines changed: 71 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -471,9 +471,6 @@ public enum TLS_VERSION {
471471
/** Domain name qualifier NID */
472472
public static int NID_dnQualifier;
473473

474-
/* is this object active, or has it been cleaned up? */
475-
private boolean active = false;
476-
477474
/* -------------- Named Groups (from enum in ssl.h) ----------------- */
478475
/** Invalid named group */
479476
public static final int WOLFSSL_NAMED_GROUP_INVALID = 0;
@@ -567,6 +564,14 @@ public enum TLS_VERSION {
567564
* position, used for LDAPS hostname verification. */
568565
public static int WOLFSSL_LEFT_MOST_WILDCARD_ONLY = 0x40;
569566

567+
/* ------------------------ Internal state -------------------------- */
568+
569+
/* is this object active, or has it been cleaned up? */
570+
private boolean active = false;
571+
572+
/* Track if library loading was skipped via system property */
573+
private static volatile boolean libraryLoadSkipped = false;
574+
570575
/* ---------------------------- locks ------------------------------- */
571576

572577
/* lock for cleanup */
@@ -720,21 +725,45 @@ public WolfSSL() throws WolfSSLException {
720725
/* ------------------------- Java methods --------------------------- */
721726

722727
/**
723-
* Loads JNI library; must be called prior to any other calls in this class.
728+
* Loads JNI library; must be called prior to any other calls in this
729+
* class.
730+
*
731+
* The native library is expected to be called "wolfssljni", and
732+
* must be on the system library search path.
724733
*
725-
* The native library is expected to be be called "wolfssljni", and must be
726-
* on the system library search path.
734+
* "wolfssljni" links against the wolfSSL native C library
735+
* ("wolfssl"), and for Windows compatibility "wolfssl" needs to be
736+
* explicitly loaded first here.
727737
*
728-
* "wolfssljni" links against the wolfSSL native C library ("wolfssl"),
729-
* and for Windows compatibility "wolfssl" needs to be explicitly
730-
* loaded first here.
738+
* If the system property "wolfssl.skipLibraryLoad" is set to
739+
* "true", this method will skip loading the native library. This
740+
* allows applications to load the native library themselves using
741+
* custom logic (for example extracting from a JAR at runtime).
742+
* The property must be set before this method is called (either
743+
* directly or via WolfSSLProvider constructor).
744+
*
745+
* Applications can check if library loading was skipped by calling
746+
* WolfSSL.isLibraryLoadSkipped().
731747
*
732748
* @throws UnsatisfiedLinkError if the library is not found.
733749
*/
734750
public static void loadLibrary() throws UnsatisfiedLinkError {
735751

736752
int fipsLoaded = 0;
737753

754+
String skipLoad =
755+
System.getProperty("wolfssl.skipLibraryLoad");
756+
if (skipLoad != null && skipLoad.equalsIgnoreCase("true")) {
757+
/* User will load native libraries manually */
758+
libraryLoadSkipped = true;
759+
760+
WolfSSLDebug.log(WolfSSL.class, WolfSSLDebug.Component.JNI,
761+
WolfSSLDebug.INFO, () -> "skipping native library load, " +
762+
"wolfssl.skipLibraryLoad system property set to true");
763+
764+
return;
765+
}
766+
738767
WolfSSLDebug.log(WolfSSL.class, WolfSSLDebug.Component.JNI,
739768
WolfSSLDebug.INFO, () -> "loading native library: wolfssl");
740769

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

783816
/**
784-
* Loads dynamic JNI library from a specific path; must be called prior to
785-
* any other calls in this package.
817+
* Loads dynamic JNI library from a specific path; must be called
818+
* prior to any other calls in this package.
819+
*
820+
* This function gives the application more control over the exact
821+
* native library being loaded, as both WolfSSL.loadLibrary() and
822+
* WolfSSL.loadLibrary(String libName) search for a library on the
823+
* system library search path. This function allows the appliation
824+
* to specify a specific absolute path to the native library file
825+
* to load, thus guaranteeing the exact library loaded and helping
826+
* to prevent against malicious attackers from attempting to
827+
* override the library being loaded.
786828
*
787-
* This function gives the application more control over the exact native
788-
* library being loaded, as both WolfSSL.loadLibrary() and
789-
* WolfSSL.loadLibrary(String libName) search for a library on the system
790-
* library search path. This function allows the appliation to specify
791-
* a specific absolute path to the native library file to load, thus
792-
* guaranteeing the exact library loaded and helping to prevent against
793-
* malicious attackers from attempting to override the library being
794-
* loaded.
829+
* Note: this method does not check the
830+
* "wolfssl.skipLibraryLoad" system property. That property is only
831+
* respected by the no-argument {@link #loadLibrary()} method.
795832
*
796-
* @param libPath complete path name to the native dynamic JNI library
833+
* @param libPath complete path name to the native dynamic JNI
834+
* library
797835
* @throws UnsatisfiedLinkError if the library is not found.
798836
*/
799837
public static void loadLibraryAbsolute(String libPath)
@@ -805,6 +843,19 @@ public static void loadLibraryAbsolute(String libPath)
805843
System.load(libPath);
806844
}
807845

846+
/**
847+
* Check if native library loading was skipped.
848+
*
849+
* Library loading is skipped when the System property
850+
* "wolfssl.skipLibraryLoad" is set to "true" and loadLibrary() has
851+
* been called.
852+
*
853+
* @return true if library loading was skipped, false otherwise
854+
*/
855+
public static boolean isLibraryLoadSkipped() {
856+
return libraryLoadSkipped;
857+
}
858+
808859
/* ----------------- generic static helper functions ---------------- */
809860

810861
/**

src/test/com/wolfssl/test/WolfSSLTest.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ public void testWolfSSL() throws WolfSSLException {
5757
test_WolfSSL_getLibVersionHex();
5858
test_WolfSSL_getErrno();
5959
testGetCiphersAvailableIana();
60+
test_isLibraryLoadSkippedReturnsFalseByDefault();
61+
test_SystemPropertyNotSetByDefault();
62+
test_SettingPropertyAfterLoadHasNoEffect();
6063
}
6164

6265
public void test_WolfSSL_new(WolfSSL lib) {
@@ -232,5 +235,58 @@ public void test_WolfSSL_getErrno() {
232235

233236
System.out.println("\t\t\t... passed");
234237
}
238+
239+
public void test_isLibraryLoadSkippedReturnsFalseByDefault() {
240+
241+
System.out.print(
242+
"\tisLibraryLoadSkipped() default");
243+
244+
/* Library was loaded normally in @BeforeClass, so
245+
* isLibraryLoadSkipped() should return false */
246+
assertFalse(
247+
"isLibraryLoadSkipped() should be false when " +
248+
"library was loaded normally",
249+
WolfSSL.isLibraryLoadSkipped());
250+
251+
System.out.println("\t... passed");
252+
}
253+
254+
public void test_SystemPropertyNotSetByDefault() {
255+
256+
System.out.print(
257+
"\twolfssl.skipLibraryLoad not set");
258+
259+
/* Verify property is not set by default in test env */
260+
String val =
261+
System.getProperty("wolfssl.skipLibraryLoad");
262+
assertNull(
263+
"wolfssl.skipLibraryLoad should not be set " +
264+
"by default", val);
265+
266+
System.out.println("\t... passed");
267+
}
268+
269+
public void test_SettingPropertyAfterLoadHasNoEffect() {
270+
271+
System.out.print(
272+
"\tskipLibraryLoad after load");
273+
274+
/* Setting the property after library has already been
275+
* loaded should not change isLibraryLoadSkipped() */
276+
try {
277+
System.setProperty(
278+
"wolfssl.skipLibraryLoad", "true");
279+
280+
assertFalse(
281+
"isLibraryLoadSkipped() should still be " +
282+
"false after setting property post-load",
283+
WolfSSL.isLibraryLoadSkipped());
284+
285+
} finally {
286+
System.clearProperty("wolfssl.skipLibraryLoad");
287+
}
288+
289+
System.out.println("\t... passed");
290+
}
235291
}
236292

0 commit comments

Comments
 (0)