JSSE: add DTLSv1.3 tests to SSLEngine JUnit test class

pull/254/head
Chris Conlon 2025-02-10 16:50:38 -07:00
parent bda5d81afc
commit 8dfd9aebf8
5 changed files with 1138 additions and 823 deletions

View File

@ -25,6 +25,7 @@ import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.net.ssl.SSLParameters;
import com.wolfssl.provider.jsse.WolfSSLJDK8Helper;
/**
* WolfSSLParametersHelper class

View File

@ -96,31 +96,33 @@ public class WolfSSLContextTest {
fail("Failed to get proper wolfJSSE provider name");
}
/* populate enabledProtocols */
for (int i = 0; i < allProtocols.length; i++) {
try {
SSLContext ctx = SSLContext.getInstance(allProtocols[i],
ctxProvider);
if (WolfSSLTestFactory.securityPropContains(
"jdk.tls.disabledAlgorithms", allProtocols[i])) {
/* skip adding, protocol has been disabled */
continue;
}
enabledProtocols.add(allProtocols[i]);
} catch (NoSuchAlgorithmException e) {
/* protocol not enabled */
}
}
try {
tf = new WolfSSLTestFactory();
} catch (WolfSSLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/* populate enabledProtocols */
synchronized (WolfSSLTestFactory.jdkTlsDisabledAlgorithmsLock) {
for (int i = 0; i < allProtocols.length; i++) {
try {
SSLContext ctx = SSLContext.getInstance(allProtocols[i],
ctxProvider);
if (WolfSSLTestFactory.securityPropContains(
"jdk.tls.disabledAlgorithms", allProtocols[i])) {
/* skip adding, protocol has been disabled */
continue;
}
enabledProtocols.add(allProtocols[i]);
} catch (NoSuchAlgorithmException e) {
/* protocol not enabled */
}
}
} /* jdkTlsDisabledAlgorithmsLock */
}
@Test
@ -414,7 +416,7 @@ public class WolfSSLContextTest {
/* already sorted highest to lowest (ie TLSv1.3, ..., TLSv1.1) */
List<?> enabledNativeProtocols = Arrays.asList(WolfSSL.getProtocols());
if (ctxProtocol == "TLS") {
if (ctxProtocol.equals("TLS")) {
if (enabledNativeProtocols.contains("TLSv1.3")) {
expected.add("TLSv1.3");
}
@ -429,7 +431,7 @@ public class WolfSSLContextTest {
}
}
else if (ctxProtocol == "TLSv1.3") {
else if (ctxProtocol.equals("TLSv1.3")) {
if (enabledNativeProtocols.contains("TLSv1.3")) {
expected.add("TLSv1.3");
}
@ -444,7 +446,7 @@ public class WolfSSLContextTest {
}
}
else if (ctxProtocol == "TLSv1.2") {
else if (ctxProtocol.equals("TLSv1.2")) {
if (enabledNativeProtocols.contains("TLSv1.2")) {
expected.add("TLSv1.2");
}
@ -456,7 +458,7 @@ public class WolfSSLContextTest {
}
}
else if (ctxProtocol == "TLSv1.1") {
else if (ctxProtocol.equals("TLSv1.1")) {
if (enabledNativeProtocols.contains("TLSv1.1")) {
expected.add("TLSv1.1");
}
@ -465,7 +467,7 @@ public class WolfSSLContextTest {
}
}
else if (ctxProtocol == "TLSv1") {
else if (ctxProtocol.equals("TLSv1")) {
if (enabledNativeProtocols.contains("TLSv1")) {
expected.add("TLSv1");
}
@ -496,68 +498,121 @@ public class WolfSSLContextTest {
fail("WolfSSL.getProtocols() returned null");
}
/* Save original property value to reset after test */
String originalProperty =
Security.getProperty("jdk.tls.disabledAlgorithms");
if (originalProperty == null) {
/* Default back to empty string, otherwise we may get a NullPointerException when
* trying to restore this back to the original value later */
originalProperty = "";
}
/* Test with no protocols disabled */
Security.setProperty("jdk.tls.disabledAlgorithms", "");
for (int i = 0; i < allProtocols.length; i++) {
if (!enabledNativeProtocols.contains(allProtocols[i])) {
/* protocol not available in native library, skip */
continue;
synchronized (WolfSSLTestFactory.jdkTlsDisabledAlgorithmsLock) {
/* Save original property value to reset after test */
String originalProperty =
Security.getProperty("jdk.tls.disabledAlgorithms");
if (originalProperty == null) {
/* Default back to empty string, otherwise we may get a
* NullPointerException when trying to restore this back to
* the original value later */
originalProperty = "";
}
ctx = SSLContext.getInstance(allProtocols[i]);
ctx.init(null, null, null);
/* Test with no protocols disabled */
Security.setProperty("jdk.tls.disabledAlgorithms", "");
for (int i = 0; i < allProtocols.length; i++) {
expectedList = buildExpectedDefaultProtocolList(allProtocols[i]);
defaultSSLContextProtocols =
ctx.getDefaultSSLParameters().getProtocols();
if (!Arrays.equals(defaultSSLContextProtocols,
expectedList.toArray(new String[expectedList.size()]))) {
System.out.print("\t... failed");
fail("Default SSLContext protocol list did not " +
"match expected");
}
/* Also test SSLSocket.getEnabledProtocols() */
sf = ctx.getSocketFactory();
sock = (SSLSocket)sf.createSocket();
String[] sockEnabledProtocols = sock.getEnabledProtocols();
if (!Arrays.equals(sockEnabledProtocols,
expectedList.toArray(new String[expectedList.size()]))) {
System.out.print("\t... failed");
fail("Default SSLSocket protocol list did not " +
"match expected");
}
}
/* Test with each allProtocol disabled individually */
for (int i = 0; i < allProtocols.length; i++) {
Security.setProperty("jdk.tls.disabledAlgorithms", allProtocols[i]);
for (int j = 0; j < allProtocols.length; j++) {
if (!enabledNativeProtocols.contains(allProtocols[j])) {
if (!enabledNativeProtocols.contains(allProtocols[i])) {
/* protocol not available in native library, skip */
continue;
}
ctx = SSLContext.getInstance(allProtocols[j]);
ctx = SSLContext.getInstance(allProtocols[i]);
ctx.init(null, null, null);
expectedList =
buildExpectedDefaultProtocolList(allProtocols[j]);
/* remove protocol under test */
expectedList.remove(allProtocols[i]);
buildExpectedDefaultProtocolList(allProtocols[i]);
defaultSSLContextProtocols =
ctx.getDefaultSSLParameters().getProtocols();
if (!Arrays.equals(defaultSSLContextProtocols,
expectedList.toArray(
new String[expectedList.size()]))) {
System.out.print("\t... failed");
fail("Default SSLContext(" + allProtocols[i] +
") protocol list did not match " +
"expected. Got: " +
Arrays.toString(defaultSSLContextProtocols) +
" Expected: " + Arrays.toString(expectedList.toArray(
new String[expectedList.size()])));
}
/* Also test SSLSocket.getEnabledProtocols() */
sf = ctx.getSocketFactory();
sock = (SSLSocket)sf.createSocket();
String[] sockEnabledProtocols = sock.getEnabledProtocols();
if (!Arrays.equals(sockEnabledProtocols,
expectedList.toArray(
new String[expectedList.size()]))) {
System.out.print("\t... failed");
fail("Default SSLSocket protocol list did not " +
"match expected");
}
}
/* Test with each allProtocol disabled individually */
for (int i = 0; i < allProtocols.length; i++) {
Security.setProperty("jdk.tls.disabledAlgorithms",
allProtocols[i]);
for (int j = 0; j < allProtocols.length; j++) {
if (!enabledNativeProtocols.contains(allProtocols[j])) {
/* protocol not available in native library, skip */
continue;
}
ctx = SSLContext.getInstance(allProtocols[j]);
ctx.init(null, null, null);
expectedList =
buildExpectedDefaultProtocolList(allProtocols[j]);
/* remove protocol under test */
expectedList.remove(allProtocols[i]);
defaultSSLContextProtocols =
ctx.getDefaultSSLParameters().getProtocols();
if (!Arrays.equals(defaultSSLContextProtocols,
expectedList.toArray(
new String[expectedList.size()]))) {
System.out.print("\t... failed");
fail("Default SSLContext protocol list did not " +
"match expected");
}
/* Also test SSLSocket.getEnabledProtocols() */
sf = ctx.getSocketFactory();
sock = (SSLSocket)sf.createSocket();
String[] sockEnabledProtocols = sock.getEnabledProtocols();
if (!Arrays.equals(sockEnabledProtocols,
expectedList.toArray(
new String[expectedList.size()]))) {
System.out.print("\t... failed");
fail("Default SSLSocket protocol list did not " +
"match expected");
}
}
}
/* Test with TLSv1, TLSv1.1 protocols disabled */
Security.setProperty("jdk.tls.disabledAlgorithms",
"TLSv1, TLSv1.1");
for (int i = 0; i < allProtocols.length; i++) {
if (!enabledNativeProtocols.contains(allProtocols[i])) {
/* protocol not available in native library, skip */
continue;
}
ctx = SSLContext.getInstance(allProtocols[i]);
ctx.init(null, null, null);
expectedList =
buildExpectedDefaultProtocolList(allProtocols[i]);
expectedList.remove("TLSv1");
expectedList.remove("TLSv1.1");
defaultSSLContextProtocols =
ctx.getDefaultSSLParameters().getProtocols();
@ -582,88 +637,53 @@ public class WolfSSLContextTest {
"match expected");
}
}
}
/* Test with TLSv1, TLSv1.1 protocols disabled */
Security.setProperty("jdk.tls.disabledAlgorithms", "TLSv1, TLSv1.1");
for (int i = 0; i < allProtocols.length; i++) {
/* Test with TLSv1.1, TLSv1.2 protocols disabled */
Security.setProperty("jdk.tls.disabledAlgorithms",
"TLSv1.1, TLSv1.2");
for (int i = 0; i < allProtocols.length; i++) {
if (!enabledNativeProtocols.contains(allProtocols[i])) {
/* protocol not available in native library, skip */
continue;
if (!enabledNativeProtocols.contains(allProtocols[i])) {
/* protocol not available in native library, skip */
continue;
}
ctx = SSLContext.getInstance(allProtocols[i]);
ctx.init(null, null, null);
expectedList =
buildExpectedDefaultProtocolList(allProtocols[i]);
expectedList.remove("TLSv1.1");
expectedList.remove("TLSv1.2");
defaultSSLContextProtocols =
ctx.getDefaultSSLParameters().getProtocols();
if (!Arrays.equals(defaultSSLContextProtocols,
expectedList.toArray(
new String[expectedList.size()]))) {
System.out.print("\t... failed");
fail("Default SSLContext protocol list did not " +
"match expected");
}
/* Also test SSLSocket.getEnabledProtocols() */
sf = ctx.getSocketFactory();
sock = (SSLSocket)sf.createSocket();
String[] sockEnabledProtocols = sock.getEnabledProtocols();
if (!Arrays.equals(sockEnabledProtocols,
expectedList.toArray(
new String[expectedList.size()]))) {
System.out.print("\t... failed");
fail("Default SSLSocket protocol list did not " +
"match expected");
}
}
ctx = SSLContext.getInstance(allProtocols[i]);
ctx.init(null, null, null);
expectedList = buildExpectedDefaultProtocolList(allProtocols[i]);
expectedList.remove("TLSv1");
expectedList.remove("TLSv1.1");
defaultSSLContextProtocols =
ctx.getDefaultSSLParameters().getProtocols();
if (!Arrays.equals(defaultSSLContextProtocols,
expectedList.toArray(new String[expectedList.size()]))) {
System.out.print("\t... failed");
fail("Default SSLContext protocol list did not " +
"match expected");
}
/* Also test SSLSocket.getEnabledProtocols() */
sf = ctx.getSocketFactory();
sock = (SSLSocket)sf.createSocket();
String[] sockEnabledProtocols = sock.getEnabledProtocols();
if (!Arrays.equals(sockEnabledProtocols,
expectedList.toArray(
new String[expectedList.size()]))) {
System.out.print("\t... failed");
fail("Default SSLSocket protocol list did not " +
"match expected");
}
}
/* Test with TLSv1.1, TLSv1.2 protocols disabled */
Security.setProperty("jdk.tls.disabledAlgorithms", "TLSv1.1, TLSv1.2");
for (int i = 0; i < allProtocols.length; i++) {
if (!enabledNativeProtocols.contains(allProtocols[i])) {
/* protocol not available in native library, skip */
continue;
}
ctx = SSLContext.getInstance(allProtocols[i]);
ctx.init(null, null, null);
expectedList = buildExpectedDefaultProtocolList(allProtocols[i]);
expectedList.remove("TLSv1.1");
expectedList.remove("TLSv1.2");
defaultSSLContextProtocols =
ctx.getDefaultSSLParameters().getProtocols();
if (!Arrays.equals(defaultSSLContextProtocols,
expectedList.toArray(new String[expectedList.size()]))) {
System.out.print("\t... failed");
fail("Default SSLContext protocol list did not " +
"match expected");
}
/* Also test SSLSocket.getEnabledProtocols() */
sf = ctx.getSocketFactory();
sock = (SSLSocket)sf.createSocket();
String[] sockEnabledProtocols = sock.getEnabledProtocols();
if (!Arrays.equals(sockEnabledProtocols,
expectedList.toArray(
new String[expectedList.size()]))) {
System.out.print("\t... failed");
fail("Default SSLSocket protocol list did not " +
"match expected");
}
}
/* Restore original system property value */
Security.setProperty("jdk.tls.disabledAlgorithms", originalProperty);
/* Restore original system property value */
Security.setProperty("jdk.tls.disabledAlgorithms",
originalProperty);
} /* jdkTlsDisabledAlgorithmsLock */
System.out.println("\t... passed");
}

File diff suppressed because it is too large Load Diff

View File

@ -414,47 +414,54 @@ public class WolfSSLSocketTest {
/* test that removing protocols with jdk.tls.disabledAlgorithms
* behaves as expected */
String originalProperty =
Security.getProperty("jdk.tls.disabledAlgorithms");
synchronized (WolfSSLTestFactory.jdkTlsDisabledAlgorithmsLock) {
String originalProperty =
Security.getProperty("jdk.tls.disabledAlgorithms");
try {
Security.setProperty("jdk.tls.disabledAlgorithms", "TLSv1");
s.setEnabledProtocols(new String[] {"TLSv1"});
System.out.println("\t\t... failed");
fail("SSLSocket.setEnabledProtocols() failed");
} catch (IllegalArgumentException e) {
/* expected */
try {
Security.setProperty(
"jdk.tls.disabledAlgorithms", "TLSv1");
s.setEnabledProtocols(new String[] {"TLSv1"});
System.out.println("\t\t... failed");
fail("SSLSocket.setEnabledProtocols() failed");
} catch (IllegalArgumentException e) {
/* expected */
}
try {
Security.setProperty(
"jdk.tls.disabledAlgorithms", "TLSv1.1");
s.setEnabledProtocols(new String[] {"TLSv1.1"});
System.out.println("\t\t... failed");
fail("SSLSocket.setEnabledProtocols() failed");
} catch (IllegalArgumentException e) {
/* expected */
}
try {
Security.setProperty(
"jdk.tls.disabledAlgorithms", "TLSv1.2");
s.setEnabledProtocols(new String[] {"TLSv1.2"});
System.out.println("\t\t... failed");
fail("SSLSocket.setEnabledProtocols() failed");
} catch (IllegalArgumentException e) {
/* expected */
}
try {
Security.setProperty(
"jdk.tls.disabledAlgorithms", "TLSv1.3");
s.setEnabledProtocols(new String[] {"TLSv1.3"});
System.out.println("\t\t... failed");
fail("SSLSocket.setEnabledProtocols() failed");
} catch (IllegalArgumentException e) {
/* expected */
}
/* restore original property value */
Security.setProperty("jdk.tls.disabledAlgorithms",
originalProperty);
}
try {
Security.setProperty("jdk.tls.disabledAlgorithms", "TLSv1.1");
s.setEnabledProtocols(new String[] {"TLSv1.1"});
System.out.println("\t\t... failed");
fail("SSLSocket.setEnabledProtocols() failed");
} catch (IllegalArgumentException e) {
/* expected */
}
try {
Security.setProperty("jdk.tls.disabledAlgorithms", "TLSv1.2");
s.setEnabledProtocols(new String[] {"TLSv1.2"});
System.out.println("\t\t... failed");
fail("SSLSocket.setEnabledProtocols() failed");
} catch (IllegalArgumentException e) {
/* expected */
}
try {
Security.setProperty("jdk.tls.disabledAlgorithms", "TLSv1.3");
s.setEnabledProtocols(new String[] {"TLSv1.3"});
System.out.println("\t\t... failed");
fail("SSLSocket.setEnabledProtocols() failed");
} catch (IllegalArgumentException e) {
/* expected */
}
/* restore original property value */
System.setProperty("jdk.tls.disabledAlgorithms", originalProperty);
}
System.out.println("\t... passed");
@ -1857,17 +1864,20 @@ public class WolfSSLSocketTest {
/* reset disabledAlgorithms property to test TLS 1.0 which is
* disabled by default */
String originalProperty =
Security.getProperty("jdk.tls.disabledAlgorithms");
Security.setProperty("jdk.tls.disabledAlgorithms", "");
synchronized (WolfSSLTestFactory.jdkTlsDisabledAlgorithmsLock) {
String originalProperty =
Security.getProperty("jdk.tls.disabledAlgorithms");
Security.setProperty("jdk.tls.disabledAlgorithms", "");
protocolConnectionTest("TLSv1");
protocolConnectionTest("TLSv1");
System.out.print("\tTLS 1.0 extended Socket test");
protocolConnectionTestExtendedSocket("TLSv1");
System.out.print("\tTLS 1.0 extended Socket test");
protocolConnectionTestExtendedSocket("TLSv1");
/* restore system property */
Security.setProperty("jdk.tls.disabledAlgorithms", originalProperty);
/* restore system property */
Security.setProperty(
"jdk.tls.disabledAlgorithms", originalProperty);
}
}
@Test
@ -1883,17 +1893,20 @@ public class WolfSSLSocketTest {
/* reset disabledAlgorithms property to test TLS 1.1 which is
* disabled by default */
String originalProperty =
Security.getProperty("jdk.tls.disabledAlgorithms");
Security.setProperty("jdk.tls.disabledAlgorithms", "");
synchronized (WolfSSLTestFactory.jdkTlsDisabledAlgorithmsLock) {
String originalProperty =
Security.getProperty("jdk.tls.disabledAlgorithms");
Security.setProperty("jdk.tls.disabledAlgorithms", "");
protocolConnectionTest("TLSv1.1");
protocolConnectionTest("TLSv1.1");
System.out.print("\tTLS 1.1 extended Socket test");
protocolConnectionTestExtendedSocket("TLSv1.1");
System.out.print("\tTLS 1.1 extended Socket test");
protocolConnectionTestExtendedSocket("TLSv1.1");
/* restore system property */
Security.setProperty("jdk.tls.disabledAlgorithms", originalProperty);
/* restore system property */
Security.setProperty(
"jdk.tls.disabledAlgorithms", originalProperty);
}
}
@Test
@ -1902,17 +1915,19 @@ public class WolfSSLSocketTest {
System.out.print("\tTLS 1.2 connection test");
/* skip if TLS 1.2 is not compiled in at native level */
if (WolfSSL.TLSv12Enabled() == false ||
WolfSSLTestFactory.securityPropContains(
"jdk.tls.disabledAlgorithms", "TLSv1.2")) {
System.out.println("\t\t... skipped");
return;
synchronized (WolfSSLTestFactory.jdkTlsDisabledAlgorithmsLock) {
if (WolfSSL.TLSv12Enabled() == false ||
WolfSSLTestFactory.securityPropContains(
"jdk.tls.disabledAlgorithms", "TLSv1.2")) {
System.out.println("\t\t... skipped");
return;
}
protocolConnectionTest("TLSv1.2");
System.out.print("\tTLS 1.2 extended Socket test");
protocolConnectionTestExtendedSocket("TLSv1.2");
}
protocolConnectionTest("TLSv1.2");
System.out.print("\tTLS 1.2 extended Socket test");
protocolConnectionTestExtendedSocket("TLSv1.2");
}
@Test
@ -1921,17 +1936,19 @@ public class WolfSSLSocketTest {
System.out.print("\tTLS 1.3 connection test");
/* skip if TLS 1.3 is not compiled in at native level */
if (WolfSSL.TLSv13Enabled() == false ||
WolfSSLTestFactory.securityPropContains(
"jdk.tls.disabledAlgorithms", "TLSv1.3")) {
System.out.println("\t\t... skipped");
return;
synchronized (WolfSSLTestFactory.jdkTlsDisabledAlgorithmsLock) {
if (WolfSSL.TLSv13Enabled() == false ||
WolfSSLTestFactory.securityPropContains(
"jdk.tls.disabledAlgorithms", "TLSv1.3")) {
System.out.println("\t\t... skipped");
return;
}
protocolConnectionTest("TLSv1.3");
System.out.print("\tTLS 1.3 extended Socket test");
protocolConnectionTestExtendedSocket("TLSv1.3");
}
protocolConnectionTest("TLSv1.3");
System.out.print("\tTLS 1.3 extended Socket test");
protocolConnectionTestExtendedSocket("TLSv1.3");
}
private void protocolConnectionTest(String protocol) throws Exception {
@ -2119,48 +2136,52 @@ public class WolfSSLSocketTest {
this.ctx = tf.createSSLContext("TLS", ctxProvider);
/* save current system property value */
String originalProperty =
Security.getProperty("jdk.tls.disabledAlgorithms");
synchronized (WolfSSLTestFactory.jdkTlsDisabledAlgorithmsLock) {
String originalProperty =
Security.getProperty("jdk.tls.disabledAlgorithms");
for (int i = 0; i < enabledProtocols.size(); i++) {
for (int i = 0; i < enabledProtocols.size(); i++) {
/* skip generic "TLS" */
if (enabledProtocols.get(i).equals("TLS")) {
continue;
/* skip generic "TLS" */
if (enabledProtocols.get(i).equals("TLS")) {
continue;
}
/* create SSLServerSocket first to get ephemeral port */
SSLServerSocket ss =
(SSLServerSocket)ctx.getServerSocketFactory()
.createServerSocket(0);
SSLSocket cs = (SSLSocket)ctx.getSocketFactory().createSocket();
/* restrict to single protocol that is being disabled */
cs.setEnabledProtocols(new String[] {enabledProtocols.get(i)});
/* disable protocol after socket setup, should fail conn */
Security.setProperty("jdk.tls.disabledAlgorithms",
enabledProtocols.get(i));
/* don't need server since should throw exception before */
cs.connect(new InetSocketAddress(ss.getLocalPort()));
try {
cs.startHandshake();
System.out.println("\t... failed");
fail();
} catch (SSLException e) {
/* expected, should fail with
* "No protocols enabled or available" */
}
cs.close();
ss.close();
}
/* create SSLServerSocket first to get ephemeral port */
SSLServerSocket ss = (SSLServerSocket)ctx.getServerSocketFactory()
.createServerSocket(0);
SSLSocket cs = (SSLSocket)ctx.getSocketFactory().createSocket();
/* restrict to single protocol that is being disabled */
cs.setEnabledProtocols(new String[] {enabledProtocols.get(i)});
/* disable protocol after socket setup, should fail connection */
Security.setProperty("jdk.tls.disabledAlgorithms",
enabledProtocols.get(i));
/* don't need server since should throw exception before */
cs.connect(new InetSocketAddress(ss.getLocalPort()));
try {
cs.startHandshake();
System.out.println("\t... failed");
fail();
} catch (SSLException e) {
/* expected, should fail with
* "No protocols enabled or available" */
}
cs.close();
ss.close();
/* restore system property */
Security.setProperty(
"jdk.tls.disabledAlgorithms", originalProperty);
}
/* restore system property */
Security.setProperty("jdk.tls.disabledAlgorithms", originalProperty);
System.out.println("\t... passed");
}

View File

@ -27,7 +27,6 @@ import java.time.Duration;
import java.math.BigInteger;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
@ -44,13 +43,10 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.util.List;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
@ -98,6 +94,12 @@ class WolfSSLTestFactory {
protected String keyStoreType = "JKS";
private boolean extraDebug = false;
/**
* Shared lock for synchronization around tests that modify or use the Java
* Security property: jdk.tls.disabledAlgorithms
*/
public static final Object jdkTlsDisabledAlgorithmsLock = new Object();
protected WolfSSLTestFactory() throws WolfSSLException {
/* wolfJSSE example Java KeyStore files, containing:
* all.jks All certs
@ -585,166 +587,200 @@ class WolfSSLTestFactory {
*/
}
/**
* Run SSLEngine delegated tasks.
*
* wolfJSSE doesn't use delegated tasks, but we use this for
* compatibility so tests can be switched and run against different
* providers.
*/
private void runDelegatedTasks(SSLEngine engine) {
Runnable run;
while ((run = engine.getDelegatedTask()) != null) {
run.run();
}
}
/**
* Engine connection. Makes server/client handshake in memory
* Helper method to verify received data, called by testConnection().
*/
private boolean verifyReceivedData(ByteBuffer buf, String expected) {
buf.flip();
byte[] b = new byte[buf.remaining()];
buf.get(b);
String received = new String(b, StandardCharsets.UTF_8).trim();
return expected.equals(received);
}
/**
* Does SSL/TLS handshake between two SSLEngine objects, then
* sends application data from client to server and vice versa.
* Application data received by client/server is compared to
* original sent as a sanity check.
*
* @param server SSLEngine for server side of connection
* @param client SSLEngine for client side of connection
* @param cipherSuites cipher suites to use can be null
* @param cipherSuites cipher suites to use, can be null
* @param protocols TLS protocols to use i.e. TLSv1.2, can be null
* @param appData message to send after handshake, can be null
* @return
* @param appData message to send after handshake, can be null to not
* send any data.
*
* @return 0 on success, -1 on error. Any exceptions thrown
* inside the body of this method are caught and converted into
* a -1 return.
*/
protected int testConnection(SSLEngine server, SSLEngine client,
String[] cipherSuites, String[] protocols, String appData) {
ByteBuffer serToCli = ByteBuffer.allocateDirect(server.getSession().getPacketBufferSize());
ByteBuffer cliToSer = ByteBuffer.allocateDirect(client.getSession().getPacketBufferSize());
String[] cipherSuites, String[] protocols, String appData) {
/* Max loop protection against infinite loops */
int loops = 0;
int maxLoops = 50;
boolean handshakeComplete = false;
/* Allocate buffers large enough for protocol packets */
ByteBuffer serToCli = ByteBuffer.allocateDirect(
server.getSession().getPacketBufferSize());
ByteBuffer cliToSer = ByteBuffer.allocateDirect(
client.getSession().getPacketBufferSize());
/* Application data buffers */
ByteBuffer toSendCli = ByteBuffer.wrap(appData.getBytes());
ByteBuffer toSendSer = ByteBuffer.wrap(appData.getBytes());
ByteBuffer serPlain = ByteBuffer.allocate(server.getSession().getApplicationBufferSize());
ByteBuffer cliPlain = ByteBuffer.allocate(client.getSession().getApplicationBufferSize());
boolean done = false;
ByteBuffer serPlain = ByteBuffer.allocate(
server.getSession().getApplicationBufferSize());
ByteBuffer cliPlain = ByteBuffer.allocate(
client.getSession().getApplicationBufferSize());
/* Configure protocols and cipher suites if specified */
if (cipherSuites != null) {
server.setEnabledCipherSuites(cipherSuites);
client.setEnabledCipherSuites(cipherSuites);
}
if (protocols != null) {
server.setEnabledProtocols(protocols);
client.setEnabledProtocols(protocols);
}
while (!done) {
while (!handshakeComplete && loops++ < maxLoops) {
try {
Runnable run;
SSLEngineResult result;
HandshakeStatus s;
HandshakeStatus clientStatus = client.getHandshakeStatus();
HandshakeStatus serverStatus = server.getHandshakeStatus();
result = client.wrap(toSendCli, cliToSer);
if (extraDebug) {
System.out.println("[client wrap] consumed = " + result.bytesConsumed() +
" produced = " + result.bytesProduced() +
" status = " + result.getStatus().name());
// + " sequence # = " + result.sequenceNumber());
}
while ((run = client.getDelegatedTask()) != null) {
run.run();
/* client wrap() */
if (clientStatus == HandshakeStatus.NEED_WRAP ||
(clientStatus == HandshakeStatus.NOT_HANDSHAKING &&
toSendCli.hasRemaining())) {
SSLEngineResult result = client.wrap(toSendCli, cliToSer);
runDelegatedTasks(client);
if (result.getStatus() ==
SSLEngineResult.Status.BUFFER_OVERFLOW) {
return -1;
}
if (extraDebug) {
System.out.println("[client wrap] " + result);
}
}
result = server.wrap(toSendSer, serToCli);
if (extraDebug) {
System.out.println("[server wrap] consumed = " + result.bytesConsumed() +
" produced = " + result.bytesProduced() +
" status = " + result.getStatus().name());
}
while ((run = server.getDelegatedTask()) != null) {
run.run();
}
if (extraDebug) {
s = client.getHandshakeStatus();
System.out.println("client status = " + s.toString());
s = server.getHandshakeStatus();
System.out.println("server status = " + s.toString());
/* server wrap() */
if (serverStatus == HandshakeStatus.NEED_WRAP ||
(serverStatus == HandshakeStatus.NOT_HANDSHAKING &&
toSendSer.hasRemaining())) {
SSLEngineResult result = server.wrap(toSendSer, serToCli);
runDelegatedTasks(server);
if (result.getStatus() ==
SSLEngineResult.Status.BUFFER_OVERFLOW) {
return -1;
}
if (extraDebug) {
System.out.println("[server wrap] " + result);
}
}
/* flip buffers for unwrap() */
cliToSer.flip();
serToCli.flip();
if (extraDebug) {
if (cliToSer.remaining() > 0) {
System.out.println("Client -> Server");
printHex(cliToSer);
/* client unwrap() */
if ((clientStatus == HandshakeStatus.NEED_UNWRAP ||
clientStatus == HandshakeStatus.NOT_HANDSHAKING) &&
serToCli.hasRemaining()) {
SSLEngineResult result = client.unwrap(serToCli, cliPlain);
runDelegatedTasks(client);
if (result.getStatus() ==
SSLEngineResult.Status.BUFFER_OVERFLOW) {
return -1;
}
if (serToCli.remaining() > 0) {
System.out.println("Server -> Client");
printHex(serToCli);
if (extraDebug) {
System.out.println("[client unwrap] " + result);
}
System.out.println("cliToSer remaining = " + cliToSer.remaining());
System.out.println("serToCli remaining = " + serToCli.remaining());
}
result = client.unwrap(serToCli, cliPlain);
if (extraDebug) {
System.out.println("[client unwrap] consumed = " + result.bytesConsumed() +
" produced = " + result.bytesProduced() +
" status = " + result.getStatus().name());
}
while ((run = client.getDelegatedTask()) != null) {
run.run();
}
result = server.unwrap(cliToSer, serPlain);
if (extraDebug) {
System.out.println("[server unwrap] consumed = " + result.bytesConsumed() +
" produced = " + result.bytesProduced() +
" status = " + result.getStatus().name());
}
while ((run = server.getDelegatedTask()) != null) {
run.run();
/* server unwrap() */
if ((serverStatus == HandshakeStatus.NEED_UNWRAP ||
serverStatus == HandshakeStatus.NOT_HANDSHAKING) &&
cliToSer.hasRemaining()) {
SSLEngineResult result = server.unwrap(cliToSer, serPlain);
runDelegatedTasks(server);
if (result.getStatus() ==
SSLEngineResult.Status.BUFFER_OVERFLOW) {
return -1;
}
if (extraDebug) {
System.out.println("[server unwrap] " + result);
}
}
/* compact network buffers */
cliToSer.compact();
serToCli.compact();
if (extraDebug) {
s = client.getHandshakeStatus();
System.out.println("client status = " + s.toString());
s = server.getHandshakeStatus();
System.out.println("server status = " + s.toString());
}
/* Check if handshake is complete and data exchanged */
if (!toSendCli.hasRemaining() && !toSendSer.hasRemaining() &&
client.getHandshakeStatus() ==
HandshakeStatus.NOT_HANDSHAKING &&
server.getHandshakeStatus() ==
HandshakeStatus.NOT_HANDSHAKING) {
if (toSendCli.remaining() == 0 && toSendSer.remaining() == 0) {
byte[] b;
String st;
/* check what the client received */
cliPlain.rewind();
b = new byte[cliPlain.remaining()];
cliPlain.get(b);
st = new String(b, StandardCharsets.UTF_8).trim();
if (!appData.equals(st)) {
/* Verify received data matches expected */
if (!verifyReceivedData(cliPlain, appData) ||
!verifyReceivedData(serPlain, appData)) {
return -1;
}
/* check what the server received */
serPlain.rewind();
b = new byte[serPlain.remaining()];
serPlain.get(b);
st = new String(b, StandardCharsets.UTF_8).trim();
if (!appData.equals(st)) {
return -1;
}
done = true;
handshakeComplete = true;
}
} catch (SSLException ex) {
return -1;
}
}
return 0;
return handshakeComplete ? 0 : -1;
}
/**
* Close down an engine connection
* Close down an SSLEngine connection.
*
* @param server
* @param client
* @param earlyClose
* @return
*
* @return 0 on success, negative on error
*
* @throws SSLException
*/
public int CloseConnection(SSLEngine server, SSLEngine client, boolean earlyClose) throws SSLException {
ByteBuffer serToCli = ByteBuffer.allocateDirect(server.getSession().getPacketBufferSize());
ByteBuffer cliToSer = ByteBuffer.allocateDirect(client.getSession().getPacketBufferSize());
ByteBuffer empty = ByteBuffer.allocate(server.getSession().getPacketBufferSize());
public int CloseConnection(SSLEngine server, SSLEngine client,
boolean earlyClose) throws SSLException {
ByteBuffer serToCli = ByteBuffer.allocateDirect(
server.getSession().getPacketBufferSize());
ByteBuffer cliToSer = ByteBuffer.allocateDirect(
client.getSession().getPacketBufferSize());
ByteBuffer empty = ByteBuffer.allocate(
server.getSession().getPacketBufferSize());
SSLEngineResult result;
HandshakeStatus s;
boolean passed;
Runnable run;
/* Close outBound to begin process of sending close_notify alert */
client.closeOutbound();
@ -755,13 +791,13 @@ class WolfSSLTestFactory {
/* Generate close_notify alert */
result = client.wrap(empty, cliToSer);
if (extraDebug) {
System.out.println("[client wrap] consumed = " + result.bytesConsumed() +
" produced = " + result.bytesProduced() +
" status = " + result.getStatus().name());
}
while ((run = client.getDelegatedTask()) != null) {
run.run();
System.out.println(
"[client wrap] consumed = " + result.bytesConsumed() +
" produced = " + result.bytesProduced() +
" status = " + result.getStatus().name());
}
runDelegatedTasks(client);
s = client.getHandshakeStatus();
if (extraDebug) {
System.out.println("client status = " + s.toString());
@ -812,17 +848,17 @@ class WolfSSLTestFactory {
result = server.unwrap(cliToSer, empty);
cliToSer.compact();
if (extraDebug) {
System.out.println("[server unwrap] consumed = " + result.bytesConsumed() +
" produced = " + result.bytesProduced() +
" status = " + result.getStatus().name());
System.out.println(
"[server unwrap] consumed = " + result.bytesConsumed() +
" produced = " + result.bytesProduced() +
" status = " + result.getStatus().name());
}
if (result.getStatus().name().equals("CLOSED")) {
/* odd case where server tries to send "empty" if not set close */
server.closeOutbound();
}
while ((run = server.getDelegatedTask()) != null) {
run.run();
}
runDelegatedTasks(server);
s = server.getHandshakeStatus();
if (result.bytesProduced() != 0 || result.bytesConsumed() <= 0) {
throw new SSLException("Server unwrap consumed/produced error");
@ -836,13 +872,13 @@ class WolfSSLTestFactory {
result = server.wrap(empty, serToCli);
serToCli.flip();
if (extraDebug) {
System.out.println("[server wrap] consumed = " + result.bytesConsumed() +
" produced = " + result.bytesProduced() +
" status = " + result.getStatus().name());
}
while ((run = server.getDelegatedTask()) != null) {
run.run();
System.out.println(
"[server wrap] consumed = " + result.bytesConsumed() +
" produced = " + result.bytesProduced() +
" status = " + result.getStatus().name());
}
runDelegatedTasks(server);
s = server.getHandshakeStatus();
if (result.bytesProduced() <= 0 || result.bytesConsumed() != 0) {
throw new SSLException("Server wrap consumed/produced error");
@ -859,13 +895,13 @@ class WolfSSLTestFactory {
result = client.unwrap(serToCli, empty);
serToCli.compact();
if (extraDebug) {
System.out.println("[client unwrap] consumed = " + result.bytesConsumed() +
" produced = " + result.bytesProduced() +
" status = " + result.getStatus().name());
}
while ((run = client.getDelegatedTask()) != null) {
run.run();
System.out.println(
"[client unwrap] consumed = " + result.bytesConsumed() +
" produced = " + result.bytesProduced() +
" status = " + result.getStatus().name());
}
runDelegatedTasks(client);
s = client.getHandshakeStatus();
if (result.bytesProduced() != 0 || result.bytesConsumed() <= 0) {
throw new SSLException("Client unwrap consumed/produced error");