Skip to content

Commit

Permalink
Merge pull request #178 from cconlon/wksKeyStoreSupport
Browse files Browse the repository at this point in the history
Add wolfJCE WKS KeyStore Support
  • Loading branch information
JacobBarthelmeh authored Jul 19, 2024
2 parents bef6379 + 855fdef commit fba6fc7
Show file tree
Hide file tree
Showing 7 changed files with 1,131 additions and 355 deletions.
100 changes: 100 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,106 @@ result in undefined behavior when the file descriptor number is larger than
`FD_SETSIZE` (defaults to 1024 on most systems). For this reason, `poll()` is
used as the default descriptor monitoring function.

### 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
37 changes: 28 additions & 9 deletions examples/provider/ClientJSSE.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,12 @@ public void run(String[] args) throws Exception {
String cipherList = null; /* default ciphersuite list */
int sslVersion = 3; /* default to TLS 1.2 */
boolean verifyPeer = true; /* verify peer by default */
boolean useEnvVar = false; /* load cert/key from enviornment variable */
boolean listSuites = false; /* list all supported cipher suites */
boolean useSysRoots = false; /* skip CA KeyStore load,
use system default roots */
boolean useEnvVar = false; /* load cert/key from enviornment
variable */
boolean listSuites = false; /* list all supported cipher
suites */
boolean listEnabledProtocols = false; /* show enabled protocols */
boolean putEnabledProtocols = false; /* set enabled protocols */
boolean sendGET = false; /* send HTTP GET */
Expand All @@ -100,6 +104,7 @@ public void run(String[] args) throws Exception {
String caJKS = "../provider/ca-server.jks";
String clientPswd = "wolfSSL test";
String caPswd = "wolfSSL test";
String keyStoreFormat = "JKS";

/* server (peer) info */
String host = "localhost";
Expand Down Expand Up @@ -187,6 +192,12 @@ public void run(String[] args) throws Exception {
} else if (arg.equals("-profile")) {
profileSleep = true;

} else if (arg.equals("-sysca")) {
useSysRoots = true;

} else if (arg.equals("-ksformat")) {
keyStoreFormat = args[++i];

} else {
printUsage();
}
Expand Down Expand Up @@ -230,14 +241,20 @@ public java.security.cert.X509Certificate[] getAcceptedIssuers() {

/* trust manager (certificates) */
if (verifyPeer) {
cert = KeyStore.getInstance("JKS");
cert.load(new FileInputStream(caJKS), caPswd.toCharArray());
tm = TrustManagerFactory.getInstance("SunX509", provider);
tm.init(cert);
if (useSysRoots) {
/* Let wolfJSSE try to find/load default system CA certs */
tm.init((KeyStore)null);
}
else {
cert = KeyStore.getInstance(keyStoreFormat);
cert.load(new FileInputStream(caJKS), caPswd.toCharArray());
tm.init(cert);
}
}

/* load private key */
pKey = KeyStore.getInstance("JKS");
pKey = KeyStore.getInstance(keyStoreFormat);
pKey.load(new FileInputStream(clientJKS), clientPswd.toCharArray());
km = KeyManagerFactory.getInstance("SunX509", provider);
km.init(pKey, clientPswd.toCharArray());
Expand Down Expand Up @@ -409,16 +426,18 @@ private void printUsage() {
System.out.println("-d\t\tDisable peer checks");
System.out.println("-g\t\tSend server HTTP GET");
System.out.println("-e\t\tGet all supported cipher suites");
System.out.println("-r\t\tResume session");
System.out.println("-sysca\t\tLoad system CA certs, ignore any passed in");
System.out.println("-getp\t\tGet enabled protocols");
System.out.println("-setp <protocols> \tSet enabled protocols " +
"e.g \"TLSv1.1 TLSv1.2\"");
System.out.println("-c <file>:<password>\tCertificate/key JKS,\t\tdefault " +
"../provider/client.jks:wolfSSL test");
"../provider/client.jks:\"wolfSSL test\"");
System.out.println("-A <file>:<password>\tCertificate/key CA JKS file,\tdefault " +
"../provider/ca-server.jks:wolfSSL test");
System.out.println("-r Resume session");
"../provider/ca-server.jks:\"wolfSSL test\"");
System.out.println("-profile\tSleep for 10 sec before/after running " +
"to allow profilers to attach");
System.out.println("-ksformat <str>\tKeyStore format (default: JKS)");
System.exit(1);
}
}
9 changes: 7 additions & 2 deletions examples/provider/ServerJSSE.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public void run(String[] args) {
String caJKS = "../provider/ca-client.jks";
String serverPswd = "wolfSSL test";
String caPswd = "wolfSSL test";
String keyStoreFormat = "JKS";

/* server (peer) info */
String host = "localhost";
Expand Down Expand Up @@ -164,6 +165,9 @@ public void run(String[] args) {
} else if (arg.equals("-profile")) {
profileSleep = true;

} else if (arg.equals("-ksformat")) {
keyStoreFormat = args[++i];

} else {
printUsage();
}
Expand Down Expand Up @@ -201,10 +205,10 @@ public void run(String[] args) {
}

/* set up keystore and truststore */
KeyStore keystore = KeyStore.getInstance("JKS");
KeyStore keystore = KeyStore.getInstance(keyStoreFormat);
keystore.load(new FileInputStream(serverJKS),
serverPswd.toCharArray());
KeyStore truststore = KeyStore.getInstance("JKS");
KeyStore truststore = KeyStore.getInstance(keyStoreFormat);
truststore.load(new FileInputStream(caJKS), caPswd.toCharArray());
TrustManagerFactory tm =
TrustManagerFactory.getInstance("SunX509", tmfProvider);
Expand Down Expand Up @@ -345,6 +349,7 @@ private void printUsage() {
"../provider/ca-client.jks:\"wolfSSL test\"");
System.out.println("-profile\tSleep for 10 sec before/after running " +
"to allow profilers to attach");
System.out.println("-ksformat <str>\tKeyStore format (default: JKS)");
System.exit(1);
}

Expand Down
56 changes: 56 additions & 0 deletions examples/provider/convert-to-wks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

if [ -z "$1" ]; then
echo "Expected provider location for wolfJCE provider JAR directory."
echo "Example \"./convert-to-wks.sh ~/wolfcryptjni/lib\""
exit 1
fi
PROVIDER_DIR="$1"

# Export library paths for Linux and Mac to find shared JNI library
export LD_LIBRARY_PATH=$PROVIDER_DIR:$LD_LIBRARY_PATH
export DYLD_LIBRARY_PATH=$PROVIDER_DIR:$DYLD_LIBRARY_PATH

convert () {
keytool -importkeystore -srckeystore ${1}.jks -destkeystore ${1}.wks -srcstoretype JKS -deststoretype WKS -srcstorepass "wolfSSL test" -deststorepass "wolfSSL test" -provider com.wolfssl.provider.jce.WolfCryptProvider --providerpath "$PROVIDER_DIR/wolfcrypt-jni.jar"

}

rm -f all.bks &> /dev/null
convert "all"

rm -f all_mixed.bks &> /dev/null
convert "all_mixed"

rm -f client.bks &> /dev/null
convert "client"

rm -f client-rsa-1024.bks &> /dev/null
convert "client-rsa-1024"

rm -f client-rsa.bks &> /dev/null
convert "client-rsa"

rm -f client-ecc.bks &> /dev/null
convert "client-ecc"

rm -f server.bks &> /dev/null
convert "server"

rm -f server-rsa-1024.bks &> /dev/null
convert "server-rsa-1024"

rm -f server-rsa.bks &> /dev/null
convert "server-rsa"

rm -f server-ecc.bks &> /dev/null
convert "server-ecc"

rm -f cacerts.bks &> /dev/null
convert "cacerts"

rm -f ca-client.bks &> /dev/null
convert "ca-client"

rm -f ca-server.bks &> /dev/null
convert "ca-server"

Loading

0 comments on commit fba6fc7

Please sign in to comment.