diff --git a/wolfSSL-JNI/src/chapter01.md b/wolfSSL-JNI/src/chapter01.md index 5a92dc82..3bd4df1d 100644 --- a/wolfSSL-JNI/src/chapter01.md +++ b/wolfSSL-JNI/src/chapter01.md @@ -4,6 +4,6 @@ wolfSSL JNI/JSSE is a provider implementation of the Java Secure Socket Extensio The Java Secure Socket Extension ( **JSSE** ) framework supports the installation of security providers. These providers can implement a subset of the functionality used by the Java JSSE security APIs, including SSL/TLS. -This document describes wolfSSL’s JSSE provider implementation, named “**wolfJSSE / wolfSSLProvider**”. wolfJSSE wraps the native wolfSSL SSL/TLS library. This interface gives Java applications access to all the benefits of using wolfSSL, including current SSL/TLS standards up to [TLS 1.3](https://www.wolfssl.com/tls13), [FIPS 140-2 and 140-3](https://www.wolfssl.com/license/fips/) support, performance optimizations, hardware cryptography support, [commercial support](https://www.wolfssl.com/products/support-and-maintenance/), and more! +This document describes wolfSSL’s JSSE provider implementation, named “**wolfJSSE / wolfSSLProvider**”. wolfJSSE wraps the native wolfSSL SSL/TLS library. This interface gives Java applications access to all the benefits of using wolfSSL, including current SSL/TLS standards up to [TLS 1.3](https://www.wolfssl.com/tls13), [DTLS 1.3](https://www.wolfssl.com/wolfssl-java-jsse-provider-supports-dtls-1-3/), and [FIPS 140-2 and 140-3](https://www.wolfssl.com/license/fips/) support, performance optimizations, hardware cryptography support, [commercial support](https://www.wolfssl.com/products/support-and-maintenance/), and more! wolfJSSE is distributed as part of the “ **wolfssljni** ”package. diff --git a/wolfSSL-JNI/src/chapter02.md b/wolfSSL-JNI/src/chapter02.md index fe3633b5..357b1b7c 100644 --- a/wolfSSL-JNI/src/chapter02.md +++ b/wolfSSL-JNI/src/chapter02.md @@ -10,7 +10,8 @@ on the following: + Oracle JDK + OpenJDK + Zulu JDK - + Amazon Coretto + + Amazon Corretto + + Eclipse Temurin - Mac OSX - Windows (Visual Studio) - Android Studio diff --git a/wolfSSL-JNI/src/chapter03.md b/wolfSSL-JNI/src/chapter03.md index b490d02a..3ffdd102 100644 --- a/wolfSSL-JNI/src/chapter03.md +++ b/wolfSSL-JNI/src/chapter03.md @@ -34,6 +34,27 @@ location. For example: $ ./java.sh /path/to/wolfssl/install ``` +A second optional argument specifies a custom wolfSSL library name to link +against. This is useful when wolfSSL was compiled with `--with-libsuffix`: + +``` +$ ./java.sh /usr/local wolfssljsse +``` + +The script will attempt to auto-detect `JAVA_HOME` if not set. To explicitly +specify a Java installation, set the `JAVA_HOME` environment variable before +running. + +Preset `CFLAGS` can be passed to the script via the environment: + +``` +$ CFLAGS="-DWOLFJNI_USE_IO_SELECT" ./java.sh +``` + +On Aarch64 hosts, `-fPIC` is automatically added to CFLAGS. + +## Building with ant + To compile the Java sources, `ant` is used: ``` @@ -82,6 +103,73 @@ is used: $ ant examples ``` +## Building with Maven + +wolfJSSE supports building and packaging with Maven for projects that consume +Maven packages. + +First, compile the native JNI shared library using `java.sh` as described above. +This creates the native library under `./lib`: + +``` +$ ./java.sh +``` + +Compile the Java sources (output to `./target/classes`): + +``` +$ mvn compile +``` + +Compile and run JUnit tests: + +``` +$ mvn test +``` + +Package the JAR file (runs tests, then creates `target/wolfssl-jsse-X.X.X-SNAPSHOT.jar`): + +``` +$ mvn package +``` + +Generate Javadoc API documentation (output to `./docs/apidocs`): + +``` +$ mvn javadoc:javadoc +``` + +Install the JAR to the local Maven repository: + +``` +$ mvn install +``` + +The JAR will be installed to a location similar to: + +``` +~/.m2/repository/com/wolfssl/wolfssl-jsse/X.X.X-SNAPSHOT/wolfssl-jsse-X.X.X-SNAPSHOT.jar +``` + +The native `libwolfssljni.so` (or `.dylib`) library must be installed on the +native library search path (e.g., `/usr/local/lib`) or the path can be set via +`LD_LIBRARY_PATH` (Linux) or `DYLD_LIBRARY_PATH` (macOS). + +Applications can include wolfJSSE as a Maven dependency: + +```xml + + com.wolfssl + wolfssl-jsse + 1.16.0-SNAPSHOT + +``` + +## Windows Visual Studio Build + +wolfJSSE can be compiled on Windows using Visual Studio. For detailed +instructions, see the `IDE/WIN/README.md` file in the wolfssljni package. + ## Android Studio Build An example Android Studio project is located in the directory `IDE/Android`. diff --git a/wolfSSL-JNI/src/chapter04.md b/wolfSSL-JNI/src/chapter04.md index eae2e0d8..0a84a853 100644 --- a/wolfSSL-JNI/src/chapter04.md +++ b/wolfSSL-JNI/src/chapter04.md @@ -48,6 +48,39 @@ for (Provider prov:providers) { } ``` +### Java Module System (JPMS) Support + +wolfJSSE includes Java ServiceLoader support for compatibility with the Java +Module System (JPMS). This allows the wolfJSSE provider to be automatically +discovered and loaded when the JAR is on the module path. + +The wolfJSSE JAR contains a `META-INF/services/java.security.Provider` file +that registers `com.wolfssl.provider.jsse.WolfSSLProvider` for automatic +discovery. Applications can discover and load the provider using the standard +Java ServiceLoader API: + +``` +import java.security.Provider; +import java.security.Security; +import java.util.ServiceLoader; + +ServiceLoader loader = ServiceLoader.load(Provider.class); +for (Provider provider : loader) { + if (provider.getName().equals("wolfJSSE")) { + Security.addProvider(provider); + break; + } +} +``` + +For modular applications, wolfJSSE can be used as an automatic module or +included as a dependency in your `module-info.java`. + +**Note:** ServiceLoader-based provider discovery relies on the +`META-INF/services` mechanism which is a JAR/module system feature. On Android, +applications should register the provider directly using +`Security.addProvider(new WolfSSLProvider())` instead. + ## Installation at OS / System Level ### Unix/Linux diff --git a/wolfSSL-JNI/src/chapter05.md b/wolfSSL-JNI/src/chapter05.md index c9f37a45..7e74d601 100644 --- a/wolfSSL-JNI/src/chapter05.md +++ b/wolfSSL-JNI/src/chapter05.md @@ -9,22 +9,25 @@ wolfJSSE / wolfSSL JNI package structure: ``` wolfssljni/ - build.xml ant build script + build.xml ant build script + pom.xml Maven build configuration COPYING - docs/ Javadocs - examples/ Example apps - IDE/ Example IDE project, Android Studio - java.sh Script to build native C JNI sources + docs/ Javadocs + examples/ Example apps + IDE/ IDE projects + Android/ Android Studio + WIN/ Windows Visual Studio + java.sh Script to build native C JNI sources LICENSING Makefile - lib/ Output directory for compiled library - native/ Native C JNI binding source files - platform/ Android AOSP build files + lib/ Output directory for compiled library + native/ Native C JNI binding source files + platform/ Android AOSP build files README.md - rpm/ rpm spec files + rpm/ rpm spec files src/ - java/ Java source files - test/ Test source files + java/ Java source files + test/ Test source files ``` The **wolfJSSE** provider source code is located in the diff --git a/wolfSSL-JNI/src/chapter06.md b/wolfSSL-JNI/src/chapter06.md index 77d7cd70..c843d06b 100644 --- a/wolfSSL-JNI/src/chapter06.md +++ b/wolfSSL-JNI/src/chapter06.md @@ -3,7 +3,7 @@ wolfJSSE extends or implements the following JSSE classes: javax.net.ssl.SSLContextSpi - SSL, TLS, DEFAULT, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3 + SSL, TLS, DEFAULT, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3, DTLSv1.3 javax.net.ssl.KeyManagerFactorySpi PKIX, X509, SunX509 javax.net.ssl.TrustManagerFactorySpi @@ -20,3 +20,16 @@ wolfJSSE extends or implements the following JSSE classes: java.security.cert.X509Certificate javax.security.cert.X509Certificate +**Note:** `DTLSv1.3` is only supported through the `SSLEngine` interface. + +## Secure Renegotiation + +wolfJSSE supports secure renegotiation when the underlying native wolfSSL +library has been compiled with secure renegotiation support: + +``` +$ ./configure --enable-secure-renegotiation +``` + +Or by defining `HAVE_SECURE_RENEGOTIATION`. + diff --git a/wolfSSL-JNI/src/chapter07.md b/wolfSSL-JNI/src/chapter07.md index c339ef52..d985e102 100644 --- a/wolfSSL-JNI/src/chapter07.md +++ b/wolfSSL-JNI/src/chapter07.md @@ -2,12 +2,210 @@ For usage, please follow the Oracle/OpenJDK Javadocs for the classes specified in the previous chapter. Note that you will need to explicitly request the -“wolfJSSE” provider if it has been set lower in precedence than other providers +"wolfJSSE" provider if it has been set lower in precedence than other providers that offer the same algorithm in the `java.security` file. For example, to use the wolfJSSE provider with the SSLContext class for TLS 1.2 an application would create a SSLContext object like so: ``` -SSLContext ctx = SSLContext.getInstance(“TLSv1.2”, “wolfJSSE”); +SSLContext ctx = SSLContext.getInstance("TLSv1.2", "wolfJSSE"); ``` + +## Security Properties + +wolfJSSE supports configuration through the `java.security` file using both +standard Java Security properties and wolfJSSE-specific properties. + +### Standard Java Security Properties + +The following standard Java Security properties are supported by wolfJSSE: + +| Property | Default | Description | +| --- | --- | --- | +| `keystore.type` | JKS | Default KeyStore type | +| `jdk.tls.disabledAlgorithms` | | Disable algorithms, protocols, key lengths (partial support) | + +Example `jdk.tls.disabledAlgorithms` usage: + +``` +jdk.tls.disabledAlgorithms=SSLv3, TLSv1.1, DH keySize < 1024, EC keySize < 224, RSA keySize < 1024 +``` + +### wolfJSSE-Specific Security Properties + +The following Security properties are specific to wolfJSSE: + +| Property | Default | Description | +| --- | --- | --- | +| `wolfjsse.enabledCipherSuites` | | Restrict enabled cipher suites | +| `wolfjsse.enabledSupportedCurves` | | Restrict enabled ECC curves | +| `wolfjsse.enabledSignatureAlgorithms` | | Restrict enabled signature algorithms | +| `wolfjsse.keystore.type.required` | | Require specific KeyStore type | +| `wolfjsse.clientSessionCache.disabled` | "false" | Disable client session cache | +| `wolfjsse.X509KeyManager.disableCache` | "false" | Disable X509KeyManager caching | + +Example cipher suite restriction: + +``` +wolfjsse.enabledCipherSuites=TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 +``` + +Example ECC curve restriction: + +``` +wolfjsse.enabledSupportedCurves=secp256r1, secp521r1 +``` + +Example signature algorithm restriction: + +``` +wolfjsse.enabledSignatureAlgorithms=RSA+SHA256:ECDSA+SHA256 +``` + +## System Properties + +wolfJSSE supports both standard Java System properties and wolfJSSE-specific +System properties. + +### Standard Java System Properties + +The following standard Java System properties are supported by wolfJSSE: + +| Property | Description | +| --- | --- | +| `javax.net.ssl.keyStore` | KeyStore file for KeyManager | +| `javax.net.ssl.keyStoreType` | KeyStore type for KeyManager | +| `javax.net.ssl.keyStorePassword` | KeyStore password for KeyManager | +| `javax.net.ssl.trustStore` | KeyStore file for TrustManager | +| `javax.net.ssl.trustStoreType` | KeyStore type for TrustManager | +| `javax.net.ssl.trustStorePassword` | KeyStore password for TrustManager | +| `jdk.tls.client.enableSessionTicketExtension` | Enable session tickets (Java 13+) | +| `jdk.tls.client.SignatureSchemes` | Client signature algorithms (partial support) | +| `jdk.tls.server.SignatureSchemes` | Server signature algorithms (partial support) | +| `jdk.tls.useExtendedMasterSecret` | Enable/disable Extended Master Secret | + +### wolfJSSE-Specific System Properties + +wolfJSSE supports several System properties: + +| System Property | Default | To Enable | Description | +| --- | --- | --- | --- | +| `wolfssl.debug` | "false" | "true" | Native wolfSSL debug logging | +| `wolfssljni.debug` | "false" | "true" | wolfJNI debug logging | +| `wolfjsse.debug` | "false" | "true" | wolfJSSE debug logging | +| `wolfjsse.debugFormat` | | "JSON" | Output debug logs in JSON format | +| `wolfsslengine.debug` | "false" | "true" | SSLEngine debug logging | +| `wolfsslengine.io.debug` | "false" | "true" | SSLEngine I/O bytes logging | +| `wolfjsse.autoSNI` | "false" | Auto-set SNI from hostname | + +## Debugging + +Native wolfSSL logging (`wolfssl.debug`) only outputs messages if native wolfSSL +was compiled with `--enable-debug`. + +These properties can be set at runtime: + +``` +java -Dwolfjsse.debug=true App +``` + +Or programmatically: + +```java +System.setProperty("wolfjsse.debug", "true"); +``` + +If properties are changed after `WolfSSLDebug` has been initialized, call +`WolfSSLDebug.refreshDebugFlags()` to refresh the values. + +JDK debug logging can be enabled with `-Djavax.net.debug=all`. + +### JSON Log Format + +Debug messages can be output in JSON format for tools like DataDog: + +``` +java -Dwolfjsse.debug=true -Dwolfjsse.debugFormat=JSON App +``` + +## Native File Descriptor Events + +wolfJSSE monitors native file descriptors for read/write events using either +`poll()` or `select()`. + +By default, `poll()` is used unless: + +- `WOLFJNI_USE_IO_SELECT` is defined when compiling the native JNI sources +- Running on Windows, which defaults to `select()` + +The `poll()` function is preferred because `select()` has undefined behavior +when file descriptor numbers exceed `FD_SETSIZE` (typically 1024). + +## ALPN Support + +Application-Layer Protocol Negotiation (ALPN) is supported through both +`SSLSocket` and `SSLEngine`. + +To get the negotiated protocol after handshake: + +```java +String protocol = sslSocket.getApplicationProtocol(); +``` + +wolfJSSE supports non-ASCII protocol names in ALPN. + +## SNI Support + +Server Name Indication (SNI) is supported on both client and server sides. + +On the client, SNI can be configured through `SSLParameters`: + +```java +SSLParameters params = sslSocket.getSSLParameters(); +params.setServerNames(Arrays.asList(new SNIHostName("example.com"))); +sslSocket.setSSLParameters(params); +``` + +The `wolfjsse.autoSNI` Security property can enable automatic SNI configuration +from the hostname for `HttpsURLConnection`. + +On the server, `SSLSession.getRequestedServerNames()` returns the SNI requested +by the client, and SNI matcher logic can be used with `WolfSSLSocket`. + +## DTLS 1.3 Usage + +DTLS 1.3 is supported through the `SSLEngine` interface only: + +```java +SSLContext ctx = SSLContext.getInstance("DTLSv1.3", "wolfJSSE"); +SSLEngine engine = ctx.createSSLEngine(); +``` + +DTLS Connection ID (CID) is also supported through the native wolfSSL APIs +wrapped at the JNI level. + +## Android Usage + +### Application-Level + +Register wolfJSSE programmatically in your application: + +```java +import com.wolfssl.provider.jsse.WolfSSLProvider; + +// Add as lowest priority +Security.addProvider(new WolfSSLProvider()); + +// Or insert as highest priority +Security.insertProviderAt(new WolfSSLProvider(), 1); +``` + +On Android, the `AndroidCAStore` KeyStore is used when available for loading +system CA certificates. + +### System-Level (AOSP) + +wolfJSSE can be installed as a system provider in Android AOSP. See the +`platform/android_aosp` directory and the document "Installing a JSSE Provider +in Android OSP" for details. diff --git a/wolfSSL-JNI/src/chapter08.md b/wolfSSL-JNI/src/chapter08.md index be2dc81e..832ed289 100644 --- a/wolfSSL-JNI/src/chapter08.md +++ b/wolfSSL-JNI/src/chapter08.md @@ -10,6 +10,13 @@ Examples should be run from the package root directory, and using the provided wrapper scripts. The wrapper scripts set up the correct environment variables for use with the wolfjni jar included in the wolfssljni package. +To build examples run: +``` +$ ./java.sh +$ ant +$ ant examples +``` + ## Notes on Debug and Logging wolfJSSE debug logging can be enabled by using `-Dwolfjsse.debug=true` at @@ -59,16 +66,6 @@ $ ./examples/provider/ServerJSSE.sh $ ./examples/provider/ClientJSSE.sh ``` -## Notes on Debug and Logging - -wolfJSSE debug logging can be enabled by using `-Dwolfjsse.debug=true` at -runtime. - -wolfSSL native debug logging can be enabled by using `-Dwolfssl.debug=true` at -runtime, if native wolfSSL has been compiled with `--enable-debug`. - -JDK debug logging can be enabled using the `-Djavax.net.debug=all` option. - ## wolfJSSE Example Client and Server Example client/server applications that use wolfJSSE along with the SSLSocket @@ -188,3 +185,40 @@ Example usage: ``` $ ./examples/provider/ThreadedSSLSocketClientServer.sh ``` + +## DtlsClientEngine.java and DtlsServerEngine.java + +Example client/server applications that demonstrate how to use SSLEngine with DTLS 1.3. + +**DtlsServerEngine.java** - Example DTLS 1.3 server using SSLEngine +**DtlsClientEngine.java** - Example DTLS 1.3 client using SSLEngine + +These examples show how to implement DTLS 1.3 with SSLEngine for datagram-based +secure communication. Unlike the TCP-based examples, these use DatagramSocket for +UDP transport and handle the complexities of DTLS, including session tickets +and handshake state management. + +Run the examples with the provided bash scripts: + +``` +$ ./examples/provider/DtlsServerEngine.sh +$ ./examples/provider/DtlsClientEngine.sh +``` + +The client connects to the server, sends a message, and receives the echoed response. +Both examples support various command-line options that can be viewed with the -? flag. + +## Java Remote Method Invocation (RMI) Example + +Example client, server, and remote interface applications for Java Remote +Method Invocation implementation in wolfJSSE. + +**RmiServer.java** - Example server, implements `RmiRemoteInterface` with methods `getMessage()`, `sendMessage()`, `getByteArray()`, `sendByteArray()`, and `getRegistryPorts()`. Creates one or more RMI registries over TLS/SSL using wolfJSSE. + +**RmiClient.java** - Example client, gets an object stub from the remote registry, and makes remote method invocations including `getMessage()`, `sendMessage()`, `getByteArray()`, `sendByteArray()`, and `getRegistryPorts()`. Supports multiple concurrent client connections. + +Start the server and client: +``` +$ ./examples/provider/rmi/RmiServer.sh +$ ./examples/provider/rmi/RmiClient.sh +``` \ No newline at end of file