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 to help ensure conformance to using FIPS-validated cryptography. Other
non-wolfJCE KeyStore implementations may not use/consume FIPS validated crypto. 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, If there are other Security properties you would like to use with wolfJSSE,
please contact support@wolfssl.com. please contact support@wolfssl.com.

View File

@ -1407,7 +1407,12 @@ public class WolfSSLEngineHelper {
* maintains session cache at native level. */ * maintains session cache at native level. */
this.session.setResume(); this.session.setResume();
} }
return this.authStore.addSession(this.session); 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; return WolfSSL.SSL_FAILURE;

View File

@ -247,6 +247,28 @@ public class WolfSSLUtil {
return requiredType; 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 * Check given KeyStore against any pre-defind requirements for
* KeyStore use, including the following. * KeyStore use, including the following.

View File

@ -981,55 +981,72 @@ public class WolfSSLEngineTest {
SSLEngine client; SSLEngine client;
int ret; int ret;
/* create new SSLEngine */
System.out.print("\tSession reuse"); System.out.print("\tSession reuse");
this.ctx = tf.createSSLContext("TLS", engineProvider); /* wolfjsse.clientSessionCache.disabled could be set in users
server = this.ctx.createSSLEngine(); * java.security file which would cause this test to not work
client = this.ctx.createSSLEngine("wolfSSL client test", 11111); * properly. Save their setting here, and re-enable session
* cache for this test */
server.setUseClientMode(false); String originalProp = Security.getProperty(
server.setNeedClientAuth(false); "wolfjsse.clientSessionCache.disabled");
client.setUseClientMode(true); Security.setProperty("wolfjsse.clientSessionCache.disabled", "false");
ret = tf.testConnection(server, client, null, null, "Test reuse");
if (ret != 0) {
error("\t\t\t... failed");
fail("failed to create engine");
}
try { try {
/* test close connection */ /* create new SSLEngine */
tf.CloseConnection(server, client, false); this.ctx = tf.createSSLContext("TLS", engineProvider);
} catch (SSLException ex) { server = this.ctx.createSSLEngine();
error("\t\t\t... failed"); client = this.ctx.createSSLEngine("wolfSSL client test", 11111);
fail("failed to create engine");
}
server = this.ctx.createSSLEngine(); server.setUseClientMode(false);
client = this.ctx.createSSLEngine("wolfSSL client test", 11111); server.setNeedClientAuth(false);
client.setEnableSessionCreation(false); client.setUseClientMode(true);
server.setUseClientMode(false); ret = tf.testConnection(server, client, null, null, "Test reuse");
server.setNeedClientAuth(false); if (ret != 0) {
client.setUseClientMode(true); error("\t\t\t... failed");
ret = tf.testConnection(server, client, null, null, "Test reuse"); fail("failed to create engine");
if (ret != 0) { }
error("\t\t\t... failed");
fail("failed to create engine");
}
try {
/* test close connection */
tf.CloseConnection(server, client, false);
} catch (SSLException ex) {
error("\t\t\t... failed");
fail("failed to create engine");
}
if (client.getEnableSessionCreation() || try {
!server.getEnableSessionCreation()) { /* test close connection */
error("\t\t\t... failed"); tf.CloseConnection(server, client, false);
fail("bad enabled session creation"); } catch (SSLException ex) {
error("\t\t\t... failed");
fail("failed to create engine");
}
server = this.ctx.createSSLEngine();
client = this.ctx.createSSLEngine("wolfSSL client test", 11111);
client.setEnableSessionCreation(false);
server.setUseClientMode(false);
server.setNeedClientAuth(false);
client.setUseClientMode(true);
ret = tf.testConnection(server, client, null, null, "Test reuse");
if (ret != 0) {
error("\t\t\t... failed");
fail("failed to create engine");
}
try {
/* test close connection */
tf.CloseConnection(server, client, false);
} catch (SSLException ex) {
error("\t\t\t... failed");
fail("failed to create engine");
}
if (client.getEnableSessionCreation() ||
!server.getEnableSessionCreation()) {
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);
}
} }
pass("\t\t\t... passed");
} }
/** /**

View File

@ -266,111 +266,129 @@ public class WolfSSLSessionContextTest {
/* create new SSLEngine */ /* create new SSLEngine */
System.out.print("\tTesting SessionIDs with TLSv1.3"); System.out.print("\tTesting SessionIDs with TLSv1.3");
this.ctx = tf.createSSLContext("TLS", engineProvider); /* wolfjsse.clientSessionCache.disabled could be set in users
server = this.ctx.createSSLEngine(); * java.security file which would cause this test to not work
client = this.ctx.createSSLEngine("wolfSSL begin handshake test", 11111); * properly. Save their setting here, and re-enable session
* cache for this test */
server.setUseClientMode(false); String originalProp = Security.getProperty(
server.setNeedClientAuth(false); "wolfjsse.clientSessionCache.disabled");
client.setUseClientMode(true); Security.setProperty("wolfjsse.clientSessionCache.disabled", "false");
try { try {
String s[] = server.getEnabledProtocols(); this.ctx = tf.createSSLContext("TLS", engineProvider);
if (Arrays.asList(s).contains("TLSv1.3") == false) { server = this.ctx.createSSLEngine();
pass("\t... skipped"); client = this.ctx.createSSLEngine(
return; "wolfSSL begin handshake test", 11111);
server.setUseClientMode(false);
server.setNeedClientAuth(false);
client.setUseClientMode(true);
try {
String s[] = server.getEnabledProtocols();
if (Arrays.asList(s).contains("TLSv1.3") == false) {
pass("\t... skipped");
return;
}
server.setEnabledProtocols(proto);
client.setEnabledProtocols(proto);
} catch (Exception e) {
e.printStackTrace();
error("\t... failed");
} }
server.setEnabledProtocols(proto); try {
client.setEnabledProtocols(proto); server.beginHandshake();
} catch (Exception e) { client.beginHandshake();
e.printStackTrace(); } catch (SSLException e) {
error("\t... failed"); error("\t... failed");
} fail("failed to begin handshake");
}
try { ret = tf.testConnection(
server.beginHandshake(); server, client, null, null, "Test in/out bound");
client.beginHandshake(); if (ret != 0) {
} catch (SSLException e) { error("\t... failed");
error("\t... failed"); fail("failed to create engine");
fail("failed to begin handshake"); }
}
ret = tf.testConnection(server, client, null, null, "Test in/out bound"); ses = server.getSession(); /* get a new copy of session */
if (ret != 0) { if (ses == null) {
error("\t... failed"); error("\t... failed");
fail("failed to create engine"); fail("unable to get session after handshake");
} }
ses = server.getSession(); /* get a new copy of session */ id = ses.getId();
if (ses == null) { if (id == null) {
error("\t... failed"); error("\t... failed");
fail("unable to get session after handshake"); fail("session had no id....");
} }
found = false;
id = ses.getId(); allIds = ctx.getServerSessionContext().getIds();
if (id == null) { while (allIds.hasMoreElements()) {
error("\t... failed"); byte[] current = allIds.nextElement();
fail("session had no id...."); if (Arrays.equals(current, id) == true) {
} /* found matching session ID */
found = false; found = true;
}
}
allIds = ctx.getServerSessionContext().getIds(); if (!found) {
while (allIds.hasMoreElements()) { error("\t... failed");
byte[] current = allIds.nextElement(); fail("did not find session id in global context list");
if (Arrays.equals(current, id) == true) { }
/* found matching session ID */
found = true; if (ses.isValid() == false) {
error("\t... failed");
fail("session not valid");
}
/* now test finding client session by ID */
ses = client.getSession(); /* get a new copy of session */
if (ses == null) {
error("\t... failed");
fail("unable to get session after handshake");
}
id = ses.getId();
if (id == null) {
error("\t... failed");
fail("client session had no id....");
}
found = false;
allIds = ctx.getClientSessionContext().getIds();
while (allIds.hasMoreElements()) {
byte[] current = allIds.nextElement();
if (Arrays.equals(current, id) == true) {
/* found matching session ID */
found = true;
}
}
if (!found) {
error("\t... failed");
fail("did not find client session id in global context list");
}
try {
tf.CloseConnection(server, client, false);
} catch (SSLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
error("\t... failed");
fail("session close failed");
}
pass("\t... passed");
} finally {
if (originalProp != null && !originalProp.isEmpty()) {
Security.setProperty(
"wolfjsse.clientSessionCache.disabled", originalProp);
} }
} }
if (!found) {
error("\t... failed");
fail("did not find session id in global context list");
}
if (ses.isValid() == false) {
error("\t... failed");
fail("session not valid");
}
/* now test finding client session by ID */
ses = client.getSession(); /* get a new copy of session */
if (ses == null) {
error("\t... failed");
fail("unable to get session after handshake");
}
id = ses.getId();
if (id == null) {
error("\t... failed");
fail("client session had no id....");
}
found = false;
allIds = ctx.getClientSessionContext().getIds();
while (allIds.hasMoreElements()) {
byte[] current = allIds.nextElement();
if (Arrays.equals(current, id) == true) {
/* found matching session ID */
found = true;
}
}
if (!found) {
error("\t... failed");
fail("did not find client session id in global context list");
}
try {
tf.CloseConnection(server, client, false);
} catch (SSLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
error("\t... failed");
fail("session close failed");
}
pass("\t... passed");
} }
@Test @Test
@ -388,115 +406,133 @@ public class WolfSSLSessionContextTest {
/* create new SSLEngine */ /* create new SSLEngine */
System.out.print("\tTesting SessionIDs with TLSv1.2"); System.out.print("\tTesting SessionIDs with TLSv1.2");
this.ctx = tf.createSSLContext("TLS", engineProvider); /* wolfjsse.clientSessionCache.disabled could be set in users
server = this.ctx.createSSLEngine(); * java.security file which would cause this test to not work
client = this.ctx.createSSLEngine("wolfSSL begin handshake test", 11111); * properly. Save their setting here, and re-enable session
* cache for this test */
server.setUseClientMode(false); String originalProp = Security.getProperty(
server.setNeedClientAuth(false); "wolfjsse.clientSessionCache.disabled");
client.setUseClientMode(true); Security.setProperty("wolfjsse.clientSessionCache.disabled", "false");
try { try {
String s[] = server.getEnabledProtocols(); this.ctx = tf.createSSLContext("TLS", engineProvider);
if (Arrays.asList(s).contains("TLSv1.2") == false) { server = this.ctx.createSSLEngine();
pass("\t... skipped"); client = this.ctx.createSSLEngine(
return; "wolfSSL begin handshake test", 11111);
server.setUseClientMode(false);
server.setNeedClientAuth(false);
client.setUseClientMode(true);
try {
String s[] = server.getEnabledProtocols();
if (Arrays.asList(s).contains("TLSv1.2") == false) {
pass("\t... skipped");
return;
}
server.setEnabledProtocols(proto);
client.setEnabledProtocols(proto);
} catch (Exception e) {
e.printStackTrace();
error("\t... failed");
} }
server.setEnabledProtocols(proto); try {
client.setEnabledProtocols(proto); server.beginHandshake();
} catch (Exception e) { client.beginHandshake();
e.printStackTrace(); } catch (SSLException e) {
error("\t... failed"); error("\t... failed");
} fail("failed to begin handshake");
try {
server.beginHandshake();
client.beginHandshake();
} catch (SSLException e) {
error("\t... failed");
fail("failed to begin handshake");
}
ret = tf.testConnection(server, client, null, null, "Test in/out bound");
if (ret != 0) {
error("\t... failed");
fail("failed to create engine");
}
ses = server.getSession(); /* get a new copy of session */
if (ses == null) {
error("\t... failed");
fail("unable to get session after handshake");
}
id = ses.getId();
if (id == null) {
error("\t... failed");
fail("session had no id....");
}
found = false;
allIds = ctx.getServerSessionContext().getIds();
while (allIds.hasMoreElements()) {
byte[] current = allIds.nextElement();
if (Arrays.equals(current, id) == true) {
/* found matching session ID */
found = true;
} }
}
if (!found) { ret = tf.testConnection(
error("\t... failed"); server, client, null, null, "Test in/out bound");
fail("did not find session id in global context list"); if (ret != 0) {
} error("\t... failed");
fail("failed to create engine");
if (ses.isValid() == false) {
error("\t... failed");
fail("session not valid");
}
/* now test finding client session by ID */
ses = client.getSession(); /* get a new copy of session */
if (ses == null) {
error("\t... failed");
fail("unable to get session after handshake");
}
id = ses.getId();
if (id == null) {
error("\t... failed");
fail("client session had no id....");
}
found = false;
allIds = ctx.getClientSessionContext().getIds();
while (allIds.hasMoreElements()) {
byte[] current = allIds.nextElement();
if (Arrays.equals(current, id) == true) {
/* found matching session ID */
found = true;
} }
}
if (!found) { ses = server.getSession(); /* get a new copy of session */
error("\t... failed"); if (ses == null) {
fail("did not find client session id in global context list"); error("\t... failed");
} fail("unable to get session after handshake");
}
pass("\t... passed"); id = ses.getId();
if (id == null) {
error("\t... failed");
fail("session had no id....");
}
found = false;
/* additional tests on the engines and sessions while open */ allIds = ctx.getServerSessionContext().getIds();
testSetCacheSize(ses); while (allIds.hasMoreElements()) {
byte[] current = allIds.nextElement();
if (Arrays.equals(current, id) == true) {
/* found matching session ID */
found = true;
}
}
if (!found) {
error("\t... failed");
fail("did not find session id in global context list");
}
if (ses.isValid() == false) {
error("\t... failed");
fail("session not valid");
}
/* now test finding client session by ID */
ses = client.getSession(); /* get a new copy of session */
if (ses == null) {
error("\t... failed");
fail("unable to get session after handshake");
}
id = ses.getId();
if (id == null) {
error("\t... failed");
fail("client session had no id....");
}
found = false;
allIds = ctx.getClientSessionContext().getIds();
while (allIds.hasMoreElements()) {
byte[] current = allIds.nextElement();
if (Arrays.equals(current, id) == true) {
/* found matching session ID */
found = true;
}
}
if (!found) {
error("\t... failed");
fail("did not find client session id in global context list");
}
pass("\t... passed");
/* additional tests on the engines and sessions while open */
testSetCacheSize(ses);
try { try {
tf.CloseConnection(server, client, false); tf.CloseConnection(server, client, false);
} catch (SSLException e1) { } catch (SSLException e1) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e1.printStackTrace(); e1.printStackTrace();
error("\t\t... failed"); error("\t\t... failed");
fail("session close failed"); fail("session close failed");
}
} finally {
if (originalProp != null && !originalProp.isEmpty()) {
Security.setProperty(
"wolfjsse.clientSessionCache.disabled", originalProp);
}
} }
} }

View File

@ -2140,70 +2140,190 @@ public class WolfSSLSocketTest {
return; return;
} }
/* create new CTX */ /* wolfjsse.clientSessionCache.disabled could be set in users
this.ctx = tf.createSSLContext(protocol, ctxProvider); * 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");
/* create SSLServerSocket first to get ephemeral port */ try {
final SSLServerSocket ss = (SSLServerSocket)ctx.getServerSocketFactory() /* create new CTX */
.createServerSocket(0); this.ctx = tf.createSSLContext(protocol, ctxProvider);
SSLSocketFactory cliFactory = ctx.getSocketFactory(); /* create SSLServerSocket first to get ephemeral port */
final SSLServerSocket ss =
(SSLServerSocket)ctx.getServerSocketFactory()
.createServerSocket(0);
SSLSocket cs = (SSLSocket)cliFactory.createSocket(); SSLSocketFactory cliFactory = ctx.getSocketFactory();
cs.connect(new InetSocketAddress(InetAddress.getLocalHost(),
ss.getLocalPort()));
/* start server */ SSLSocket cs = (SSLSocket)cliFactory.createSocket();
ExecutorService es = Executors.newSingleThreadExecutor(); cs.connect(new InetSocketAddress(InetAddress.getLocalHost(),
Future<Void> serverFuture = es.submit(new Callable<Void>() { ss.getLocalPort()));
@Override
public Void call() throws Exception { /* start server */
try { ExecutorService es = Executors.newSingleThreadExecutor();
for (int i = 0; i < 2; i++) { Future<Void> serverFuture = es.submit(new Callable<Void>() {
SSLSocket server = (SSLSocket)ss.accept(); @Override
server.startHandshake(); public Void call() throws Exception {
server.close(); 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;
}
});
} catch (SSLException e) { try {
/* connection #1 */
cs.startHandshake();
sessionID1 = cs.getSession().getId();
cs.close();
/* connection #2, should 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 not resumed */
System.out.println("\t... failed"); System.out.println("\t... failed");
fail(); fail();
} }
return null;
}
});
try { } catch (SSLHandshakeException e) {
/* connection #1 */
cs.startHandshake();
sessionID1 = cs.getSession().getId();
cs.close();
/* connection #2, should 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 not resumed */
System.out.println("\t... failed"); System.out.println("\t... failed");
fail(); fail();
} }
} catch (SSLHandshakeException e) {
System.out.println("\t... failed"); es.shutdown();
fail(); serverFuture.get();
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");
es.shutdown(); /* Disable client session cache */
serverFuture.get(); Security.setProperty("wolfjsse.clientSessionCache.disabled", "true");
ss.close();
System.out.println("\t... passed"); 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 @Test
@ -2236,72 +2356,89 @@ public class WolfSSLSocketTest {
return; return;
} }
/* create new CTX */ /* wolfjsse.clientSessionCache.disabled could be set in users
this.ctx = tf.createSSLContext(protocol, ctxProvider); * java.security file which would cause this test to not work
* properly. Save their setting here, and re-enable session
/* create SSLServerSocket first to get ephemeral port */ * cache for this test */
final SSLServerSocket ss = (SSLServerSocket)ctx.getServerSocketFactory() String originalProp = Security.getProperty(
.createServerSocket(0); "wolfjsse.clientSessionCache.disabled");
Security.setProperty("wolfjsse.clientSessionCache.disabled", "false");
SSLSocketFactory cliFactory = ctx.getSocketFactory();
WolfSSLSocket cs = (WolfSSLSocket)cliFactory.createSocket();
cs.setUseSessionTickets(true);
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 { try {
/* connection #1 */ /* create new CTX */
cs.startHandshake(); this.ctx = tf.createSSLContext(protocol, ctxProvider);
sessionID1 = cs.getSession().getId();
cs.close();
/* connection #2, should resume */ /* create SSLServerSocket first to get ephemeral port */
cs = (WolfSSLSocket)cliFactory.createSocket(); final SSLServerSocket ss =
(SSLServerSocket)ctx.getServerSocketFactory()
.createServerSocket(0);
SSLSocketFactory cliFactory = ctx.getSocketFactory();
WolfSSLSocket cs = (WolfSSLSocket)cliFactory.createSocket();
cs.setUseSessionTickets(true); cs.setUseSessionTickets(true);
cs.connect(new InetSocketAddress(InetAddress.getLocalHost(), cs.connect(new InetSocketAddress(InetAddress.getLocalHost(),
ss.getLocalPort())); ss.getLocalPort()));
cs.startHandshake();
sessionID2 = cs.getSession().getId();
cs.close();
if (!Arrays.equals(sessionID1, sessionID2)) { /* start server */
/* session not resumed */ 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 resume */
cs = (WolfSSLSocket)cliFactory.createSocket();
cs.setUseSessionTickets(true);
cs.connect(new InetSocketAddress(InetAddress.getLocalHost(),
ss.getLocalPort()));
cs.startHandshake();
sessionID2 = cs.getSession().getId();
cs.close();
if (!Arrays.equals(sessionID1, sessionID2)) {
/* session not resumed */
System.out.println("\t... failed");
fail();
}
} catch (SSLHandshakeException e) {
System.out.println("\t... failed"); System.out.println("\t... failed");
fail(); fail();
} }
} catch (SSLHandshakeException e) {
System.out.println("\t... failed"); es.shutdown();
fail(); serverFuture.get();
ss.close();
System.out.println("\t... passed");
} finally {
if (originalProp != null && !originalProp.isEmpty()) {
Security.setProperty(
"wolfjsse.clientSessionCache.disabled", originalProp);
}
} }
es.shutdown();
serverFuture.get();
ss.close();
System.out.println("\t... passed");
} }
@Test @Test