Skip to content

Commit

Permalink
JSSE: add wolfjsse.keystore.type.required Security property support t…
Browse files Browse the repository at this point in the history
…o enforce KeyStore type used in KeyManager and TrustManager objects
  • Loading branch information
cconlon committed Jul 3, 2024
1 parent e5c85f0 commit 911dc34
Show file tree
Hide file tree
Showing 4 changed files with 305 additions and 28 deletions.
100 changes: 100 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,106 @@ $ ./configure --enable-secure-renegotiation

Or by defining `-DHAVE_SECURE_RENEGOTIATION`.

### Security Property Support

wolfJSSE allows for some customization through the `java.security` file
and use of Security properties.

Support is included for the following pre-existing Java Security properties.

**keystore.type (String)** - Specifies the default KeyStore type. This defaults
to JKS, but could be set to something else if desired.

**jdk.tls.disabledAlgorithms (String)** - Can be used to disable algorithms,
TLS protocol versions, and key lengths, among other things. This should be a
comma-delimited String. wolfJSSE includes partial support for this property,
with supported items including disabling SSL/TLS protocol versions and setting
minimum RSA/ECC/DH key sizes. An example of potential use:

```
jdk.tls.disabledAlgorithms=SSLv3, TLSv1.1, DH keySize < 1024, EC keySize < 224, RSA keySize < 1024
```

The following custom wolfJSSE-specific Security property settings are supported.
These can be placed into the `java.security` file and will be parsed and used
by wolfJSSE.

**wolfjsse.enabledCipherSuites (String)** - Allows restriction of the enabled
cipher suiets to those listed in this Security property. When set, applications
wil not be able to override or add additional suites at runtime without
changing this property. This should be a comma-delimited String. Example use:

```
wolfjsse.enabledCipherSuites=TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
```

**wolfjsse.enabledSupportedCurves (String)** - Allows setting of specific ECC
curves to be enabled for SSL/TLS connections. This propogates down to the native
wolfSSL API `wolfSSL_UseSupportedCurve()`. If invalid/bad values are found
when processing this property, connection establishment will fail with an
SSLException. This should be a comma-delimited String. Example use:

```
wolfjsse.enabledSupportedCurves=secp256r1, secp521r1
```

**wolfjsse.enabledSignatureAlgorithms (String)** - Allows restriction of the
signature algorithms sent in the TLS ClientHello Signature Algorithms
Extension. By using/setting this property, native wolfSSL will not populate
the extension with default values, which are based on what algorithms have been
compiled into the native wolfSSL library. This should be a comma-delimited
String of signature algorithm + MAC combinations. Example use:

```
wolfjsse.enabledSignatureAlgorithms=RSA+SHA256:ECDSA+SHA256
```

**wolfjsse.keystore.type.required (String)** - Can be used to specify a KeyStore
type that is required to be used. If this is set, wolfJSSE will not allow use
of any KeyStore instances that are not of this type. One use of this option
is when using wolfCrypt FIPS 140-2/3 with wolfJCE registered as a JCE provider.
This option can be used to restrict use of the wolfJCE "WKS" KeyStore type
to help ensure conformance to using FIPS-validated cryptography. Other
non-wolfJCE KeyStore implementations may not use/consume FIPS validated crypto.

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

### System Property Support

wolfJSSE allows some customization through the use of System properties. Since
these are **System** properties and not **Security** properties, they will not
get picked up if placed in the `java.security` file. That file is only used
with/for Security properties (see section above).

**javax.net.ssl.keyStore (String)** - Can be used to specify the KeyStore file
to use for KeyManager objects. An alternative to passing in the KeyStore file
programatically at runtime.

**javax.net.ssl.keyStoreType (String)** - Can be used to specify the KeyStore
type to use when getting KeyStore instances inside KeyManager objects.

**javax.net.ssl.keyStorePassword (String)** - Can be used to specify the
KeyStore password to use for initializing KeyManager instances.

**javax.net.ssl.trustStore (String)** - Can be used to specify the KeyStore
file to use with TrustManager objects. An alternative to passing in the
KeyStore file programatically at runtime.

**javax.net.ssl.trustStoreType (String)** - Can be used to specify the KeyStore
type to use when loading KeyStore inside TrustManager objects.

**javax.net.ssl.trustStorePassword (String)** - Can be used to specify the
KeyStore password to use when loading KeyStore inside TrustManager objects.

**jdk.tls.client.enableSessionTicketExtension (boolean)** - Session tickets
are enabled in different ways depending on the JDK implementation. For
Oracle/OpenJDK and variants, this System property enables session tickets and
was added in Java 13. Should be set to "true" to enable.

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

## Release Notes

Release notes can be found in [ChangeLog.md](./ChangeLog.md).
Expand Down
40 changes: 35 additions & 5 deletions src/java/com/wolfssl/provider/jsse/WolfSSLKeyManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,17 @@ public WolfSSLKeyManager() { }
* 3. Using BKS type if on Android
* 4. Using JKS type if above all fail
*
* @param requiredType KeyStore type required by user through
* java.security if wolfjsse.keystore.type.required property
* has been set.
*
* @return new KeyStore object that has been created and loaded using
* details specified in System properties.
*
* @throws KeyStoreException if javax.net.ssl.keyStore property is
* set but KeyStore fails to load
*/
private KeyStore LoadKeyStoreFromSystemProperties()
private KeyStore LoadKeyStoreFromSystemProperties(String requiredType)
throws KeyStoreException {

KeyStore sysStore = null;
Expand Down Expand Up @@ -100,27 +104,37 @@ private KeyStore LoadKeyStoreFromSystemProperties()
if (type != null && !type.trim().isEmpty()) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"javax.net.ssl.keyStoreType set: " + type);

if (requiredType != null && !requiredType.equals(type)) {
throw new KeyStoreException(
"javax.net.ssl.keyStoreType conflicts with required " +
"KeyStore type from wolfjsse.keystore.type.required");
}

sysStore = WolfSSLUtil.LoadKeyStoreFileByType(
file, this.pswd, type);
}
else {
/* Try with wolfJCE WKS type first, in case wolfCrypt
* FIPS is being used */
if (wksAvailable) {
if (wksAvailable &&
(requiredType == null || requiredType.equals("WKS"))) {
sysStore = WolfSSLUtil.LoadKeyStoreFileByType(
file, this.pswd, "WKS");
}

/* Try with BKS, if we're running on Android */
if ((sysStore == null) && WolfSSLUtil.isAndroid()) {
if ((sysStore == null) && WolfSSLUtil.isAndroid() &&
(requiredType == null || requiredType.equals("BKS"))) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"Detected Android VM, trying BKS KeyStore type");
sysStore = WolfSSLUtil.LoadKeyStoreFileByType(
file, this.pswd, "BKS");
}

/* Try falling back to JKS */
if (sysStore == null) {
if (sysStore == null &&
(requiredType == null || requiredType.equals("JKS"))) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"javax.net.ssl.keyStoreType system property not set, " +
"trying type: JKS");
Expand Down Expand Up @@ -150,10 +164,19 @@ protected void engineInit(KeyStore store, char[] password)

this.pswd = password;
KeyStore certs = store;
String requiredType = null;

WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"entering engineInit(KeyStore store, char[] password)");

requiredType = WolfSSLUtil.getRequiredKeyStoreType();
if (requiredType != null) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"java.security has restricted KeyStore type");
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"wolfjsse.keystore.type.required = " + requiredType);
}

/* If no KeyStore passed in, try to load from system property values
* if they have been set */
if (store == null) {
Expand All @@ -162,13 +185,20 @@ protected void engineInit(KeyStore store, char[] password)
"input KeyStore null, trying to load KeyStore from " +
"system properties");

certs = LoadKeyStoreFromSystemProperties();
certs = LoadKeyStoreFromSystemProperties(requiredType);
}
else {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"input KeyStore provided, using inside KeyManager");
}

/* Verify KeyStore we got matches our requirements, for example
* type may be restricted by users trying to conform to FIPS
* requirements */
if (certs != null) {
WolfSSLUtil.checkKeyStoreRequirements(certs);
}

this.store = certs;
this.initialized = true;
}
Expand Down
Loading

0 comments on commit 911dc34

Please sign in to comment.