JSSE: add Security property to disable Java client session cache: wolfjsse.clientSessionCache.disabled

pull/225/head
Chris Conlon 2024-10-09 15:48:44 -06:00
parent cfbc118cc7
commit 7b13a4b42c
6 changed files with 562 additions and 334 deletions

View File

@ -437,6 +437,17 @@ 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.
**wolfjsse.clientSessionCache.disabled (String)** - Can be used to disable
the Java client session cache. Disabling this will cause client-side session
resumption to no longer resume, making all connections fall back to a full
handshake. This should be set to the String "true" if you want to disable
the Java client session cache. This does not need to be set to "enable" the
cache. The Java client cache is enabled by default.
```
wolfjsse.clientSessionCache.disabled=true
```
If there are other Security properties you would like to use with wolfJSSE,
please contact support@wolfssl.com.

View File

@ -1407,8 +1407,13 @@ public class WolfSSLEngineHelper {
* maintains session cache at native level. */
this.session.setResume();
}
if (WolfSSLUtil.sessionCacheDisabled()) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"not storing session in cache, cache has been disabled");
} else {
return this.authStore.addSession(this.session);
}
}
return WolfSSL.SSL_FAILURE;
}

View File

@ -247,6 +247,28 @@ public class WolfSSLUtil {
return requiredType;
}
/**
* Return if session cache has been disabled in java.security
* with 'wolfjsse.clientSessionCache.disabled' Security property.
*
* @return true if disabled, otherwise false
*/
protected static boolean sessionCacheDisabled() {
String disabled =
Security.getProperty("wolfjsse.clientSessionCache.disabled");
if (disabled == null || disabled.isEmpty()) {
return false;
}
if (disabled.equalsIgnoreCase("true")) {
return true;
}
return false;
}
/**
* Check given KeyStore against any pre-defind requirements for
* KeyStore use, including the following.

View File

@ -981,9 +981,18 @@ public class WolfSSLEngineTest {
SSLEngine client;
int ret;
/* create new SSLEngine */
System.out.print("\tSession reuse");
/* wolfjsse.clientSessionCache.disabled could be set in users
* java.security file which would cause this test to not work
* properly. Save their setting here, and re-enable session
* cache for this test */
String originalProp = Security.getProperty(
"wolfjsse.clientSessionCache.disabled");
Security.setProperty("wolfjsse.clientSessionCache.disabled", "false");
try {
/* create new SSLEngine */
this.ctx = tf.createSSLContext("TLS", engineProvider);
server = this.ctx.createSSLEngine();
client = this.ctx.createSSLEngine("wolfSSL client test", 11111);
@ -1029,7 +1038,15 @@ public class WolfSSLEngineTest {
error("\t\t\t... failed");
fail("bad enabled session creation");
}
pass("\t\t\t... passed");
} finally {
if (originalProp != null && !originalProp.isEmpty()) {
Security.setProperty(
"wolfjsse.clientSessionCache.disabled", originalProp);
}
}
}
/**

View File

@ -266,9 +266,19 @@ public class WolfSSLSessionContextTest {
/* create new SSLEngine */
System.out.print("\tTesting SessionIDs with TLSv1.3");
/* wolfjsse.clientSessionCache.disabled could be set in users
* java.security file which would cause this test to not work
* properly. Save their setting here, and re-enable session
* cache for this test */
String originalProp = Security.getProperty(
"wolfjsse.clientSessionCache.disabled");
Security.setProperty("wolfjsse.clientSessionCache.disabled", "false");
try {
this.ctx = tf.createSSLContext("TLS", engineProvider);
server = this.ctx.createSSLEngine();
client = this.ctx.createSSLEngine("wolfSSL begin handshake test", 11111);
client = this.ctx.createSSLEngine(
"wolfSSL begin handshake test", 11111);
server.setUseClientMode(false);
server.setNeedClientAuth(false);
@ -296,7 +306,8 @@ public class WolfSSLSessionContextTest {
fail("failed to begin handshake");
}
ret = tf.testConnection(server, client, null, null, "Test in/out bound");
ret = tf.testConnection(
server, client, null, null, "Test in/out bound");
if (ret != 0) {
error("\t... failed");
fail("failed to create engine");
@ -371,6 +382,13 @@ public class WolfSSLSessionContextTest {
fail("session close failed");
}
pass("\t... passed");
} finally {
if (originalProp != null && !originalProp.isEmpty()) {
Security.setProperty(
"wolfjsse.clientSessionCache.disabled", originalProp);
}
}
}
@Test
@ -388,9 +406,19 @@ public class WolfSSLSessionContextTest {
/* create new SSLEngine */
System.out.print("\tTesting SessionIDs with TLSv1.2");
/* wolfjsse.clientSessionCache.disabled could be set in users
* java.security file which would cause this test to not work
* properly. Save their setting here, and re-enable session
* cache for this test */
String originalProp = Security.getProperty(
"wolfjsse.clientSessionCache.disabled");
Security.setProperty("wolfjsse.clientSessionCache.disabled", "false");
try {
this.ctx = tf.createSSLContext("TLS", engineProvider);
server = this.ctx.createSSLEngine();
client = this.ctx.createSSLEngine("wolfSSL begin handshake test", 11111);
client = this.ctx.createSSLEngine(
"wolfSSL begin handshake test", 11111);
server.setUseClientMode(false);
server.setNeedClientAuth(false);
@ -418,7 +446,8 @@ public class WolfSSLSessionContextTest {
fail("failed to begin handshake");
}
ret = tf.testConnection(server, client, null, null, "Test in/out bound");
ret = tf.testConnection(
server, client, null, null, "Test in/out bound");
if (ret != 0) {
error("\t... failed");
fail("failed to create engine");
@ -498,6 +527,13 @@ public class WolfSSLSessionContextTest {
error("\t\t... failed");
fail("session close failed");
}
} finally {
if (originalProp != null && !originalProp.isEmpty()) {
Security.setProperty(
"wolfjsse.clientSessionCache.disabled", originalProp);
}
}
}
private void pass(String msg) {

View File

@ -2140,11 +2140,21 @@ public class WolfSSLSocketTest {
return;
}
/* wolfjsse.clientSessionCache.disabled could be set in users
* java.security file which would cause this test to not work
* properly. Save their setting here, and re-enable session
* cache for this test */
String originalProp = Security.getProperty(
"wolfjsse.clientSessionCache.disabled");
Security.setProperty("wolfjsse.clientSessionCache.disabled", "false");
try {
/* create new CTX */
this.ctx = tf.createSSLContext(protocol, ctxProvider);
/* create SSLServerSocket first to get ephemeral port */
final SSLServerSocket ss = (SSLServerSocket)ctx.getServerSocketFactory()
final SSLServerSocket ss =
(SSLServerSocket)ctx.getServerSocketFactory()
.createServerSocket(0);
SSLSocketFactory cliFactory = ctx.getSocketFactory();
@ -2204,6 +2214,116 @@ public class WolfSSLSocketTest {
ss.close();
System.out.println("\t... passed");
} finally {
if (originalProp != null && !originalProp.isEmpty()) {
Security.setProperty(
"wolfjsse.clientSessionCache.disabled", originalProp);
}
}
}
@Test
public void testSessionResumptionSysPropDisabled() throws Exception {
byte[] sessionID1 = null;
byte[] sessionID2 = null;
String protocol = null;
System.out.print("\tDisabling client session cache");
/* Use TLS 1.2, else 1.1, else 1.0, else skip */
if (WolfSSL.TLSv12Enabled()) {
protocol = "TLSv1.2";
} else if (WolfSSL.TLSv11Enabled()) {
protocol = "TLSv1.1";
} else if (WolfSSL.TLSv1Enabled()) {
protocol = "TLSv1.0";
} else {
System.out.println("\t\t... skipped");
return;
}
/* Save original Security property value */
String originalProp = Security.getProperty(
"wolfjsse.clientSessionCache.disabled");
/* Disable client session cache */
Security.setProperty("wolfjsse.clientSessionCache.disabled", "true");
try {
/* Create new CTX */
this.ctx = tf.createSSLContext(protocol, ctxProvider);
/* Create SSLServerSocket first to get ephemeral port */
final SSLServerSocket ss =
(SSLServerSocket)ctx.getServerSocketFactory()
.createServerSocket(0);
SSLSocketFactory cliFactory = ctx.getSocketFactory();
SSLSocket cs = (SSLSocket)cliFactory.createSocket();
cs.connect(new InetSocketAddress(InetAddress.getLocalHost(),
ss.getLocalPort()));
/* Start server */
ExecutorService es = Executors.newSingleThreadExecutor();
Future<Void> serverFuture = es.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
try {
for (int i = 0; i < 2; i++) {
SSLSocket server = (SSLSocket)ss.accept();
server.startHandshake();
server.close();
}
} catch (SSLException e) {
System.out.println("\t... failed");
fail();
}
return null;
}
});
try {
/* connection #1 */
cs.startHandshake();
sessionID1 = cs.getSession().getId();
cs.close();
/* connection #2, should NOT resume */
cs = (SSLSocket)cliFactory.createSocket();
cs.connect(new InetSocketAddress(InetAddress.getLocalHost(),
ss.getLocalPort()));
cs.startHandshake();
sessionID2 = cs.getSession().getId();
cs.close();
if (Arrays.equals(sessionID1, sessionID2)) {
/* session resumed, but should not */
System.out.println("\t... failed");
fail();
}
} catch (SSLHandshakeException e) {
System.out.println("\t... failed");
fail();
}
es.shutdown();
serverFuture.get();
ss.close();
System.out.println("\t... passed");
} finally {
if (originalProp != null && !originalProp.isEmpty()) {
Security.setProperty(
"wolfjsse.clientSessionCache.disabled", originalProp);
}
}
}
@Test
@ -2236,11 +2356,21 @@ public class WolfSSLSocketTest {
return;
}
/* wolfjsse.clientSessionCache.disabled could be set in users
* java.security file which would cause this test to not work
* properly. Save their setting here, and re-enable session
* cache for this test */
String originalProp = Security.getProperty(
"wolfjsse.clientSessionCache.disabled");
Security.setProperty("wolfjsse.clientSessionCache.disabled", "false");
try {
/* create new CTX */
this.ctx = tf.createSSLContext(protocol, ctxProvider);
/* create SSLServerSocket first to get ephemeral port */
final SSLServerSocket ss = (SSLServerSocket)ctx.getServerSocketFactory()
final SSLServerSocket ss =
(SSLServerSocket)ctx.getServerSocketFactory()
.createServerSocket(0);
SSLSocketFactory cliFactory = ctx.getSocketFactory();
@ -2302,6 +2432,13 @@ public class WolfSSLSocketTest {
ss.close();
System.out.println("\t... passed");
} finally {
if (originalProp != null && !originalProp.isEmpty()) {
Security.setProperty(
"wolfjsse.clientSessionCache.disabled", originalProp);
}
}
}
@Test