From 7b13a4b42c5b015de70a062dcb200430e058a364 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Wed, 9 Oct 2024 15:48:44 -0600 Subject: [PATCH] JSSE: add Security property to disable Java client session cache: wolfjsse.clientSessionCache.disabled --- README.md | 11 + .../provider/jsse/WolfSSLEngineHelper.java | 7 +- .../wolfssl/provider/jsse/WolfSSLUtil.java | 22 + .../provider/jsse/test/WolfSSLEngineTest.java | 101 +++-- .../jsse/test/WolfSSLSessionContextTest.java | 392 ++++++++++-------- .../provider/jsse/test/WolfSSLSocketTest.java | 317 ++++++++++---- 6 files changed, 539 insertions(+), 311 deletions(-) diff --git a/README.md b/README.md index 4ff4683e..ca1da561 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java b/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java index f3bd769d..f3c9b9cd 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java @@ -1407,7 +1407,12 @@ protected synchronized int saveSession() { * maintains session cache at native level. */ 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; diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLUtil.java b/src/java/com/wolfssl/provider/jsse/WolfSSLUtil.java index d3714ebf..aa0eabcf 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLUtil.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLUtil.java @@ -247,6 +247,28 @@ protected static String getRequiredKeyStoreType() { 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. diff --git a/src/test/com/wolfssl/provider/jsse/test/WolfSSLEngineTest.java b/src/test/com/wolfssl/provider/jsse/test/WolfSSLEngineTest.java index 8eada479..2b958c64 100644 --- a/src/test/com/wolfssl/provider/jsse/test/WolfSSLEngineTest.java +++ b/src/test/com/wolfssl/provider/jsse/test/WolfSSLEngineTest.java @@ -981,55 +981,72 @@ public void testReuseSession() SSLEngine client; int ret; - /* create new SSLEngine */ System.out.print("\tSession reuse"); - this.ctx = tf.createSSLContext("TLS", engineProvider); - server = this.ctx.createSSLEngine(); - client = this.ctx.createSSLEngine("wolfSSL client test", 11111); - - 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"); - } + /* 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 { - /* test close connection */ - tf.CloseConnection(server, client, false); - } catch (SSLException ex) { - error("\t\t\t... failed"); - fail("failed to create engine"); - } + /* create new SSLEngine */ + this.ctx = tf.createSSLContext("TLS", engineProvider); + server = this.ctx.createSSLEngine(); + client = this.ctx.createSSLEngine("wolfSSL client test", 11111); - 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"); - } + 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"); + } - if (client.getEnableSessionCreation() || - !server.getEnableSessionCreation()) { - error("\t\t\t... failed"); - fail("bad enabled session creation"); + try { + /* test close connection */ + tf.CloseConnection(server, client, false); + } 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"); } /** diff --git a/src/test/com/wolfssl/provider/jsse/test/WolfSSLSessionContextTest.java b/src/test/com/wolfssl/provider/jsse/test/WolfSSLSessionContextTest.java index 29fdde77..169372ea 100644 --- a/src/test/com/wolfssl/provider/jsse/test/WolfSSLSessionContextTest.java +++ b/src/test/com/wolfssl/provider/jsse/test/WolfSSLSessionContextTest.java @@ -266,111 +266,129 @@ public void testSessionIDsTLS13() /* create new SSLEngine */ System.out.print("\tTesting SessionIDs with TLSv1.3"); - this.ctx = tf.createSSLContext("TLS", engineProvider); - server = this.ctx.createSSLEngine(); - client = this.ctx.createSSLEngine("wolfSSL begin handshake test", 11111); - - server.setUseClientMode(false); - server.setNeedClientAuth(false); - client.setUseClientMode(true); + /* 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 { - String s[] = server.getEnabledProtocols(); - if (Arrays.asList(s).contains("TLSv1.3") == false) { - pass("\t... skipped"); - return; + this.ctx = tf.createSSLContext("TLS", engineProvider); + server = this.ctx.createSSLEngine(); + client = this.ctx.createSSLEngine( + "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); - client.setEnabledProtocols(proto); - } catch (Exception e) { - e.printStackTrace(); - error("\t... failed"); - } + try { + server.beginHandshake(); + client.beginHandshake(); + } catch (SSLException e) { + 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"); + } - 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"); + } - 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; + } + } - 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) { + error("\t... failed"); + fail("did not find session id in global context list"); } - } - 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"); + } - 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"); + } - /* 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; + } + } - 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"); } - } - 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"); - try { - tf.CloseConnection(server, client, false); - } catch (SSLException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - error("\t... failed"); - fail("session close failed"); + } finally { + if (originalProp != null && !originalProp.isEmpty()) { + Security.setProperty( + "wolfjsse.clientSessionCache.disabled", originalProp); + } } - pass("\t... passed"); } @Test @@ -388,115 +406,133 @@ public void testSessionIDs() /* create new SSLEngine */ System.out.print("\tTesting SessionIDs with TLSv1.2"); - this.ctx = tf.createSSLContext("TLS", engineProvider); - server = this.ctx.createSSLEngine(); - client = this.ctx.createSSLEngine("wolfSSL begin handshake test", 11111); - - server.setUseClientMode(false); - server.setNeedClientAuth(false); - client.setUseClientMode(true); + /* 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 { - String s[] = server.getEnabledProtocols(); - if (Arrays.asList(s).contains("TLSv1.2") == false) { - pass("\t... skipped"); - return; + this.ctx = tf.createSSLContext("TLS", engineProvider); + server = this.ctx.createSSLEngine(); + client = this.ctx.createSSLEngine( + "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); - client.setEnabledProtocols(proto); - } catch (Exception e) { - e.printStackTrace(); - error("\t... failed"); - } + try { + server.beginHandshake(); + client.beginHandshake(); + } catch (SSLException e) { + 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"); + } - 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"); + } - 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; + } + } - 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) { + error("\t... failed"); + fail("did not find session id in global context list"); } - } - 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"); + } - 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"); + } - /* 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; + } + } - 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"); } - } - if (!found) { - error("\t... failed"); - fail("did not find client session id in global context list"); - } + pass("\t... passed"); - pass("\t... passed"); + /* additional tests on the engines and sessions while open */ + testSetCacheSize(ses); - /* additional tests on the engines and sessions while open */ - testSetCacheSize(ses); + try { + tf.CloseConnection(server, client, false); + } catch (SSLException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + error("\t\t... failed"); + fail("session close failed"); + } - try { - tf.CloseConnection(server, client, false); - } catch (SSLException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - error("\t\t... failed"); - fail("session close failed"); + } finally { + if (originalProp != null && !originalProp.isEmpty()) { + Security.setProperty( + "wolfjsse.clientSessionCache.disabled", originalProp); + } } } diff --git a/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketTest.java b/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketTest.java index d33eaf69..616622d0 100644 --- a/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketTest.java +++ b/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketTest.java @@ -2140,70 +2140,190 @@ public void testSessionResumption() throws Exception { return; } - /* create new CTX */ - this.ctx = tf.createSSLContext(protocol, ctxProvider); + /* 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"); - /* create SSLServerSocket first to get ephemeral port */ - final SSLServerSocket ss = (SSLServerSocket)ctx.getServerSocketFactory() - .createServerSocket(0); + try { + /* create new CTX */ + 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(); - cs.connect(new InetSocketAddress(InetAddress.getLocalHost(), - ss.getLocalPort())); + SSLSocketFactory cliFactory = ctx.getSocketFactory(); - /* start server */ - ExecutorService es = Executors.newSingleThreadExecutor(); - Future serverFuture = es.submit(new Callable() { - @Override - public Void call() throws Exception { - try { - for (int i = 0; i < 2; i++) { - SSLSocket server = (SSLSocket)ss.accept(); - server.startHandshake(); - server.close(); + SSLSocket cs = (SSLSocket)cliFactory.createSocket(); + cs.connect(new InetSocketAddress(InetAddress.getLocalHost(), + ss.getLocalPort())); + + /* start server */ + ExecutorService es = Executors.newSingleThreadExecutor(); + Future serverFuture = es.submit(new Callable() { + @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; + } + }); - } 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"); fail(); } - return null; + + } 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 + 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 { - /* connection #1 */ - cs.startHandshake(); - sessionID1 = cs.getSession().getId(); - cs.close(); + /* Create new CTX */ + this.ctx = tf.createSSLContext(protocol, ctxProvider); + + /* Create SSLServerSocket first to get ephemeral port */ + final SSLServerSocket ss = + (SSLServerSocket)ctx.getServerSocketFactory() + .createServerSocket(0); - /* connection #2, should resume */ - cs = (SSLSocket)cliFactory.createSocket(); + SSLSocketFactory cliFactory = ctx.getSocketFactory(); + + SSLSocket 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 */ + /* Start server */ + ExecutorService es = Executors.newSingleThreadExecutor(); + Future serverFuture = es.submit(new Callable() { + @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(); } - } catch (SSLHandshakeException e) { - System.out.println("\t... failed"); - fail(); - } + es.shutdown(); + serverFuture.get(); + ss.close(); - es.shutdown(); - serverFuture.get(); - ss.close(); + System.out.println("\t... passed"); - System.out.println("\t... passed"); + } finally { + if (originalProp != null && !originalProp.isEmpty()) { + Security.setProperty( + "wolfjsse.clientSessionCache.disabled", originalProp); + } + } } @Test @@ -2236,72 +2356,89 @@ public void testSessionResumptionWithTicketEnabled() throws Exception { return; } - /* create new CTX */ - this.ctx = tf.createSSLContext(protocol, ctxProvider); + /* 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"); - /* create SSLServerSocket first to get ephemeral port */ - final SSLServerSocket ss = (SSLServerSocket)ctx.getServerSocketFactory() - .createServerSocket(0); + try { + /* create new CTX */ + 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); - WolfSSLSocket cs = (WolfSSLSocket)cliFactory.createSocket(); - cs.setUseSessionTickets(true); - cs.connect(new InetSocketAddress(InetAddress.getLocalHost(), - ss.getLocalPort())); + SSLSocketFactory cliFactory = ctx.getSocketFactory(); - /* start server */ - ExecutorService es = Executors.newSingleThreadExecutor(); - Future serverFuture = es.submit(new Callable() { - @Override - public Void call() throws Exception { - try { - for (int i = 0; i < 2; i++) { - SSLSocket server = (SSLSocket)ss.accept(); - server.startHandshake(); - server.close(); + WolfSSLSocket cs = (WolfSSLSocket)cliFactory.createSocket(); + cs.setUseSessionTickets(true); + cs.connect(new InetSocketAddress(InetAddress.getLocalHost(), + ss.getLocalPort())); + + /* start server */ + ExecutorService es = Executors.newSingleThreadExecutor(); + Future serverFuture = es.submit(new Callable() { + @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; + } + }); - } catch (SSLException e) { + 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(); } - 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 */ + } catch (SSLHandshakeException e) { System.out.println("\t... failed"); fail(); } - } catch (SSLHandshakeException e) { - System.out.println("\t... failed"); - fail(); - } + es.shutdown(); + serverFuture.get(); + ss.close(); - es.shutdown(); - serverFuture.get(); - ss.close(); + System.out.println("\t... passed"); - System.out.println("\t... passed"); + } finally { + if (originalProp != null && !originalProp.isEmpty()) { + Security.setProperty( + "wolfjsse.clientSessionCache.disabled", originalProp); + } + } } @Test