935 lines
35 KiB
Java
935 lines
35 KiB
Java
/* WolfSSLContextTest.java
|
|
*
|
|
* Copyright (C) 2006-2025 wolfSSL Inc.
|
|
*
|
|
* This file is part of wolfSSL.
|
|
*
|
|
* wolfSSL is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* wolfSSL is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
|
*/
|
|
|
|
package com.wolfssl.provider.jsse.test;
|
|
|
|
import org.junit.Test;
|
|
import org.junit.BeforeClass;
|
|
import static org.junit.Assert.*;
|
|
|
|
import java.util.List;
|
|
import java.util.Arrays;
|
|
import java.util.ArrayList;
|
|
|
|
import com.wolfssl.WolfSSLException;
|
|
|
|
import java.io.FileInputStream;
|
|
import javax.net.SocketFactory;
|
|
import javax.net.ssl.SSLSocket;
|
|
import javax.net.ssl.SSLContext;
|
|
import javax.net.ssl.SSLSocketFactory;
|
|
import javax.net.ssl.KeyManagerFactory;
|
|
import javax.net.ssl.TrustManagerFactory;
|
|
import javax.net.ssl.SSLSessionContext;
|
|
import javax.net.ssl.SSLParameters;
|
|
import java.security.Security;
|
|
import java.security.Provider;
|
|
import java.security.KeyStore;
|
|
import java.security.SecureRandom;
|
|
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.FileNotFoundException;
|
|
import java.security.KeyStoreException;
|
|
import java.security.KeyManagementException;
|
|
import java.security.NoSuchProviderException;
|
|
import java.security.NoSuchAlgorithmException;
|
|
|
|
import com.wolfssl.WolfSSL;
|
|
import com.wolfssl.provider.jsse.WolfSSLProvider;
|
|
|
|
public class WolfSSLContextTest {
|
|
|
|
private static WolfSSLTestFactory tf;
|
|
private static final char[] jksPass = "wolfSSL test".toCharArray();
|
|
private static final String ctxProvider = "wolfJSSE";
|
|
|
|
private static String[] allProtocols = {
|
|
"TLSv1",
|
|
"TLSv1.1",
|
|
"TLSv1.2",
|
|
"TLSv1.3",
|
|
"TLS"
|
|
};
|
|
|
|
private static ArrayList<String> enabledProtocols =
|
|
new ArrayList<String>();
|
|
|
|
@BeforeClass
|
|
public static void testProviderInstallationAtRuntime()
|
|
throws NoSuchProviderException {
|
|
|
|
System.out.println("WolfSSLContext Class");
|
|
|
|
/* install wolfJSSE provider at runtime */
|
|
Security.insertProviderAt(new WolfSSLProvider(), 1);
|
|
|
|
Provider p = Security.getProvider("wolfJSSE");
|
|
assertNotNull(p);
|
|
|
|
System.out.print("\tGetting provider name");
|
|
if (p.getName().contains("wolfJSSE")) {
|
|
System.out.println("\t\t... passed");
|
|
} else {
|
|
System.out.println("\t\t... failed");
|
|
fail("Failed to get proper wolfJSSE provider name");
|
|
}
|
|
|
|
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
|
|
public void testGetSSLContextFromProvider()
|
|
throws NoSuchProviderException, NoSuchAlgorithmException {
|
|
|
|
SSLContext ctx;
|
|
|
|
System.out.print("\tTesting protocol support");
|
|
|
|
/* try to get all available protocols we expect to have */
|
|
for (int i = 0; i < enabledProtocols.size(); i++) {
|
|
ctx = SSLContext.getInstance(enabledProtocols.get(i),
|
|
ctxProvider);
|
|
}
|
|
|
|
/* getting a garbage protocol should throw an exception */
|
|
try {
|
|
ctx = SSLContext.getInstance("NotValid", ctxProvider);
|
|
|
|
System.out.println("\t... failed");
|
|
fail("SSLContext.getInstance should throw " +
|
|
"NoSuchAlgorithmException when given bad protocol");
|
|
|
|
} catch (NoSuchAlgorithmException nsae) {
|
|
System.out.println("\t... passed");
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testGetSocketFactory() throws NoSuchProviderException,
|
|
NoSuchAlgorithmException, IllegalStateException,
|
|
KeyManagementException, Exception {
|
|
|
|
SSLContext ctx;
|
|
KeyManagerFactory km;
|
|
TrustManagerFactory tm;
|
|
KeyStore pKey, cert;
|
|
SSLSocketFactory ssf;
|
|
|
|
System.out.print("\tgetSocketFactory()");
|
|
|
|
try {
|
|
/* set up KeyStore */
|
|
InputStream stream = new FileInputStream(tf.clientJKS);
|
|
pKey = KeyStore.getInstance(tf.keyStoreType);
|
|
pKey.load(stream, jksPass);
|
|
stream.close();
|
|
|
|
stream = new FileInputStream(tf.clientJKS);
|
|
cert = KeyStore.getInstance(tf.keyStoreType);
|
|
cert.load(stream, jksPass);
|
|
stream.close();
|
|
|
|
/* trust manager (certificates) */
|
|
tm = TrustManagerFactory.getInstance("SunX509");
|
|
tm.init(cert);
|
|
|
|
/* load private key */
|
|
km = KeyManagerFactory.getInstance("SunX509");
|
|
km.init(pKey, jksPass);
|
|
|
|
} catch (KeyStoreException kse) {
|
|
throw new Exception(kse);
|
|
} catch (FileNotFoundException fnfe) {
|
|
throw new Exception(fnfe);
|
|
} catch (IOException ioe) {
|
|
throw new Exception(ioe);
|
|
}
|
|
|
|
for (int i = 0; i < enabledProtocols.size(); i++) {
|
|
ctx = SSLContext.getInstance(enabledProtocols.get(i),
|
|
ctxProvider);
|
|
|
|
ctx.init(km.getKeyManagers(), tm.getTrustManagers(), null);
|
|
|
|
ssf = ctx.getSocketFactory();
|
|
assertNotNull(ssf);
|
|
}
|
|
|
|
System.out.println("\t\t... passed");
|
|
}
|
|
|
|
@Test
|
|
public void testInit() throws NoSuchProviderException,
|
|
NoSuchAlgorithmException, IllegalStateException,
|
|
KeyManagementException {
|
|
|
|
System.out.print("\tinit()");
|
|
|
|
SecureRandom rand = new SecureRandom();
|
|
SSLContext ctx = null;
|
|
|
|
/* test with null TrustManagerFactory and KeyManagerFactory */
|
|
for (int i = 0; i < enabledProtocols.size(); i++) {
|
|
|
|
try {
|
|
ctx = SSLContext.getInstance(enabledProtocols.get(i),
|
|
ctxProvider);
|
|
ctx.init(null, null, rand);
|
|
} catch (Exception e) {
|
|
System.out.println("\t\t\t\t... failed");
|
|
e.printStackTrace();
|
|
fail("Failed to initialize SSLContext with null params");
|
|
}
|
|
}
|
|
|
|
/* test with null TrustManagerFactory, KeyManagerFactory, random */
|
|
for (int i = 0; i < enabledProtocols.size(); i++) {
|
|
|
|
try {
|
|
ctx = SSLContext.getInstance(enabledProtocols.get(i),
|
|
ctxProvider);
|
|
ctx.init(null, null, null);
|
|
} catch (Exception e) {
|
|
System.out.println("\t\t\t\t... failed");
|
|
fail("Failed to initialize SSLContext with null params");
|
|
}
|
|
}
|
|
|
|
System.out.println("\t\t\t\t... passed");
|
|
}
|
|
|
|
@Test
|
|
public void testGetSessionContext() throws NoSuchProviderException,
|
|
NoSuchAlgorithmException, IllegalStateException,
|
|
KeyManagementException {
|
|
|
|
System.out.print("\tgetSessionContext()");
|
|
|
|
SSLContext ctx = null;
|
|
|
|
for (int i = 0; i < enabledProtocols.size(); i++) {
|
|
|
|
try {
|
|
ctx = SSLContext.getInstance(enabledProtocols.get(i),
|
|
ctxProvider);
|
|
ctx.init(null, null, null);
|
|
} catch (Exception e) {
|
|
System.out.println("\t\t... failed");
|
|
fail("Failed to init SSLContext");
|
|
return;
|
|
}
|
|
|
|
/* test for getting session context @TODO additional tests */
|
|
try {
|
|
SSLSessionContext sess = ctx.getServerSessionContext();
|
|
assertNotNull(sess);
|
|
} catch (UnsupportedOperationException e) {
|
|
System.out.println("\t\t... failed");
|
|
fail("Failed to get SSLSessionContext");
|
|
}
|
|
|
|
/* test for getting client session context @TODO additional tests */
|
|
try {
|
|
SSLSessionContext sess = ctx.getClientSessionContext();
|
|
assertNotNull(sess);
|
|
} catch (UnsupportedOperationException e) {
|
|
System.out.println("\t\t... failed");
|
|
fail("Failed to return client SSLSessionContext");
|
|
}
|
|
}
|
|
System.out.println("\t\t... passed");
|
|
}
|
|
|
|
@Test
|
|
public void testGetSupportedSSLParameters() throws NoSuchProviderException,
|
|
NoSuchAlgorithmException, IllegalStateException,
|
|
KeyManagementException {
|
|
|
|
System.out.print("\tgetSupportedSSLParameters()");
|
|
|
|
SSLContext ctx = null;
|
|
|
|
for (int i = 0; i < enabledProtocols.size(); i++) {
|
|
|
|
try {
|
|
ctx = SSLContext.getInstance(enabledProtocols.get(i),
|
|
ctxProvider);
|
|
ctx.init(null, null, null);
|
|
} catch (Exception e) {
|
|
System.out.println("\t\t... failed");
|
|
fail("Failed to init SSLContext");
|
|
return;
|
|
}
|
|
|
|
/* test for UnsupportedOperationException */
|
|
try {
|
|
SSLParameters params = ctx.getSupportedSSLParameters();
|
|
if (params == null) {
|
|
System.out.println("\t... failed");
|
|
fail("Failed to valid supported SSLParameters");
|
|
}
|
|
|
|
/* make sure protocol list is not null */
|
|
String[] protocols = params.getProtocols();
|
|
if (protocols == null || protocols.length == 0) {
|
|
System.out.println("\t... failed");
|
|
fail("SSLParameters.getProtocols() returned null");
|
|
}
|
|
|
|
/* make sure cipher suite list is not null */
|
|
String[] ciphers = params.getCipherSuites();
|
|
if (ciphers == null || ciphers.length == 0) {
|
|
System.out.println("\t... failed");
|
|
fail("SSLParameters.getCipherSuites() returned null");
|
|
}
|
|
|
|
} catch (UnsupportedOperationException e) {
|
|
System.out.println("\t... failed");
|
|
fail("UnsupportedOperationException thrown but not expected");
|
|
}
|
|
}
|
|
System.out.println("\t... passed");
|
|
}
|
|
|
|
@Test
|
|
public void testGetDefaultSSLParameters() throws NoSuchProviderException,
|
|
NoSuchAlgorithmException, IllegalStateException,
|
|
KeyManagementException {
|
|
|
|
System.out.print("\tgetDefaultSSLParameters()");
|
|
|
|
SSLContext ctx = null;
|
|
|
|
for (int i = 0; i < enabledProtocols.size(); i++) {
|
|
|
|
try {
|
|
ctx = SSLContext.getInstance(enabledProtocols.get(i),
|
|
ctxProvider);
|
|
ctx.init(null, null, null);
|
|
} catch (Exception e) {
|
|
System.out.println("\t\t... failed");
|
|
fail("Failed to init SSLContext");
|
|
return;
|
|
}
|
|
|
|
/* test for UnsupportedOperationException */
|
|
try {
|
|
SSLParameters params = ctx.getDefaultSSLParameters();
|
|
if (params == null) {
|
|
System.out.println("\t... failed");
|
|
fail("Failed to valid default SSLParameters");
|
|
}
|
|
|
|
/* make sure protocol list is not null */
|
|
String[] protocols = params.getProtocols();
|
|
if (protocols == null || protocols.length == 0) {
|
|
System.out.println("\t... failed");
|
|
fail("SSLParameters.getProtocols() returned null");
|
|
}
|
|
|
|
/* make sure cipher suite list is not null */
|
|
String[] ciphers = params.getCipherSuites();
|
|
if (ciphers == null || ciphers.length == 0) {
|
|
System.out.println("\t... failed");
|
|
fail("SSLParameters.getCipherSuites() returned null");
|
|
}
|
|
|
|
/* needClientAuth should default to false */
|
|
boolean needClientAuth = params.getNeedClientAuth();
|
|
if (needClientAuth == true) {
|
|
System.out.println("\t... failed");
|
|
fail("SSLParameters.getNeedClientAuth() should default " +
|
|
"to false");
|
|
}
|
|
|
|
/* wantClientAuth should default to false */
|
|
boolean wantClientAuth = params.getWantClientAuth();
|
|
if (wantClientAuth == true) {
|
|
System.out.println("\t... failed");
|
|
fail("SSLParameters.getWantClientAuth() should default " +
|
|
"to false");
|
|
}
|
|
|
|
} catch (UnsupportedOperationException e) {
|
|
System.out.println("\t... failed");
|
|
fail("UnsupportedOperationException thrown but not expected");
|
|
}
|
|
}
|
|
|
|
System.out.println("\t... passed");
|
|
}
|
|
|
|
/* Returns ArrayList of expected default SSLcontext protocols, assuming
|
|
* none have been disabled at the system level via system/security
|
|
* properties. The order of items in the list should also match expected
|
|
* order. */
|
|
private ArrayList<String> buildExpectedDefaultProtocolList(
|
|
String ctxProtocol) {
|
|
|
|
ArrayList<String> expected = new ArrayList<String>();
|
|
|
|
/* already sorted highest to lowest (ie TLSv1.3, ..., TLSv1.1) */
|
|
List<?> enabledNativeProtocols = Arrays.asList(WolfSSL.getProtocols());
|
|
|
|
if (ctxProtocol.equals("TLS")) {
|
|
if (enabledNativeProtocols.contains("TLSv1.3")) {
|
|
expected.add("TLSv1.3");
|
|
}
|
|
if (enabledNativeProtocols.contains("TLSv1.2")) {
|
|
expected.add("TLSv1.2");
|
|
}
|
|
if (enabledNativeProtocols.contains("TLSv1.1")) {
|
|
expected.add("TLSv1.1");
|
|
}
|
|
if (enabledNativeProtocols.contains("TLSv1")) {
|
|
expected.add("TLSv1");
|
|
}
|
|
}
|
|
|
|
else if (ctxProtocol.equals("TLSv1.3")) {
|
|
if (enabledNativeProtocols.contains("TLSv1.3")) {
|
|
expected.add("TLSv1.3");
|
|
}
|
|
if (enabledNativeProtocols.contains("TLSv1.2")) {
|
|
expected.add("TLSv1.2");
|
|
}
|
|
if (enabledNativeProtocols.contains("TLSv1.1")) {
|
|
expected.add("TLSv1.1");
|
|
}
|
|
if (enabledNativeProtocols.contains("TLSv1")) {
|
|
expected.add("TLSv1");
|
|
}
|
|
}
|
|
|
|
else if (ctxProtocol.equals("TLSv1.2")) {
|
|
if (enabledNativeProtocols.contains("TLSv1.2")) {
|
|
expected.add("TLSv1.2");
|
|
}
|
|
if (enabledNativeProtocols.contains("TLSv1.1")) {
|
|
expected.add("TLSv1.1");
|
|
}
|
|
if (enabledNativeProtocols.contains("TLSv1")) {
|
|
expected.add("TLSv1");
|
|
}
|
|
}
|
|
|
|
else if (ctxProtocol.equals("TLSv1.1")) {
|
|
if (enabledNativeProtocols.contains("TLSv1.1")) {
|
|
expected.add("TLSv1.1");
|
|
}
|
|
if (enabledNativeProtocols.contains("TLSv1")) {
|
|
expected.add("TLSv1");
|
|
}
|
|
}
|
|
|
|
else if (ctxProtocol.equals("TLSv1")) {
|
|
if (enabledNativeProtocols.contains("TLSv1")) {
|
|
expected.add("TLSv1");
|
|
}
|
|
}
|
|
|
|
return expected;
|
|
}
|
|
|
|
/* Tests that disabling protocols using the system property
|
|
* 'jdk.tls.disabledAlgorithms' works as expected.
|
|
*/
|
|
@Test
|
|
public void testJdkTlsDisabledAlgorithms() throws NoSuchProviderException,
|
|
NoSuchAlgorithmException, IllegalStateException,
|
|
KeyManagementException, IOException {
|
|
|
|
SSLContext ctx = null;
|
|
SocketFactory sf = null;
|
|
SSLSocket sock = null;
|
|
String[] defaultSSLContextProtocols = null;
|
|
ArrayList<String> expectedList = null;
|
|
|
|
System.out.print("\tjdk.tls.disabledAlgorithms");
|
|
|
|
List<?> enabledNativeProtocols = Arrays.asList(WolfSSL.getProtocols());
|
|
if (enabledNativeProtocols == null) {
|
|
System.out.println("\t... failed");
|
|
fail("WolfSSL.getProtocols() returned null");
|
|
}
|
|
|
|
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 = "";
|
|
}
|
|
|
|
/* 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;
|
|
}
|
|
|
|
ctx = SSLContext.getInstance(allProtocols[i]);
|
|
ctx.init(null, null, null);
|
|
|
|
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(" + 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();
|
|
|
|
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);
|
|
} /* jdkTlsDisabledAlgorithmsLock */
|
|
|
|
System.out.println("\t... passed");
|
|
}
|
|
|
|
/** Helper method for testWolfJSSEEnabledCipherSuites() */
|
|
private WolfSSL.TLS_VERSION getWolfSSLTLSVersion(String version) {
|
|
|
|
WolfSSL.TLS_VERSION verEnum = WolfSSL.TLS_VERSION.INVALID;
|
|
|
|
switch (version) {
|
|
case "TLSv1":
|
|
verEnum = WolfSSL.TLS_VERSION.TLSv1;
|
|
break;
|
|
case "TLSv1.1":
|
|
verEnum = WolfSSL.TLS_VERSION.TLSv1_1;
|
|
break;
|
|
case "TLSv1.2":
|
|
verEnum = WolfSSL.TLS_VERSION.TLSv1_2;
|
|
break;
|
|
case "TLSv1.3":
|
|
verEnum = WolfSSL.TLS_VERSION.TLSv1_3;
|
|
break;
|
|
case "TLS":
|
|
verEnum = WolfSSL.TLS_VERSION.SSLv23;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return verEnum;
|
|
}
|
|
|
|
/* Tests that setting/restricting TLS cipher suites with the
|
|
* 'wolfjsse.enabledCipherSuites' system Security property works as
|
|
* expected.
|
|
*/
|
|
@Test
|
|
public void testWolfJSSEEnabledCipherSuites()
|
|
throws NoSuchProviderException, NoSuchAlgorithmException,
|
|
IllegalStateException, KeyManagementException, IOException {
|
|
|
|
SSLContext ctx = null;
|
|
SocketFactory sf = null;
|
|
SSLSocket sock = null;
|
|
String[] nativeSuites = null;
|
|
String[] defaultSSLContextSuites = null;
|
|
WolfSSL.TLS_VERSION version = WolfSSL.TLS_VERSION.INVALID;
|
|
|
|
System.out.print("\twolfjsse.enabledCipherSuites");
|
|
|
|
List<?> enabledNativeProtocols = Arrays.asList(WolfSSL.getProtocols());
|
|
if (enabledNativeProtocols == null) {
|
|
System.out.println("\t... failed");
|
|
fail("WolfSSL.getProtocols() returned null");
|
|
}
|
|
|
|
/* Save original property value to reset after test */
|
|
String originalProperty =
|
|
Security.getProperty("wolfjsse.enabledCipherSuites");
|
|
|
|
/* Test all enabled protocols */
|
|
for (int i = 0; i < allProtocols.length; i++) {
|
|
|
|
if (!enabledNativeProtocols.contains(allProtocols[i])) {
|
|
/* protocol not available in native library, skip */
|
|
continue;
|
|
}
|
|
|
|
/* get TLS_VERSION enum value from protocol version */
|
|
version = getWolfSSLTLSVersion(allProtocols[i]);
|
|
if (version == WolfSSL.TLS_VERSION.INVALID) {
|
|
System.out.print("\t... failed");
|
|
fail("Invalid TLS version");
|
|
}
|
|
|
|
/* String[] of all available native wolfSSL suites for version */
|
|
nativeSuites = WolfSSL.getCiphersAvailableIana(version);
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
/* Test with no cipher suites restricted, make sure SSLContext
|
|
* gives back the expected/full list of cipher suites. */
|
|
Security.setProperty("wolfjsse.enabledCipherSuites", "");
|
|
|
|
ctx = SSLContext.getInstance(allProtocols[i]);
|
|
ctx.init(null, null, null);
|
|
|
|
defaultSSLContextSuites =
|
|
ctx.getDefaultSSLParameters().getCipherSuites();
|
|
|
|
if (!Arrays.equals(defaultSSLContextSuites, nativeSuites)) {
|
|
System.out.print("\t... failed");
|
|
fail("Default SSLContext cipher list did not " +
|
|
"match expected");
|
|
}
|
|
|
|
sf = ctx.getSocketFactory();
|
|
sock = (SSLSocket)sf.createSocket();
|
|
|
|
/* Test SSLSocket.getEnabledCipherSuites() */
|
|
String[] sockEnabledSuites = sock.getEnabledCipherSuites();
|
|
|
|
if (!Arrays.equals(sockEnabledSuites, nativeSuites)) {
|
|
System.out.print("\t... failed");
|
|
fail("SSLSocket enabled cipher list did not " +
|
|
"match expected");
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
/* Set first default cipher suite as the only suite enabled,
|
|
* then make sure only that suite is available after
|
|
* SSLContext creation */
|
|
Security.setProperty("wolfjsse.enabledCipherSuites",
|
|
nativeSuites[0]);
|
|
|
|
ctx = SSLContext.getInstance(allProtocols[i]);
|
|
ctx.init(null, null, null);
|
|
|
|
defaultSSLContextSuites =
|
|
ctx.getDefaultSSLParameters().getCipherSuites();
|
|
|
|
if (!Arrays.equals(defaultSSLContextSuites,
|
|
new String[] { nativeSuites[0] } )) {
|
|
System.out.print("\t... failed");
|
|
fail("Default SSLContext cipher list did not " +
|
|
"match expected single suite");
|
|
}
|
|
|
|
sf = ctx.getSocketFactory();
|
|
sock = (SSLSocket)sf.createSocket();
|
|
|
|
/* Test SSLSocket.getEnabledCipherSuites() */
|
|
sockEnabledSuites = sock.getEnabledCipherSuites();
|
|
if (!Arrays.equals(sockEnabledSuites,
|
|
new String[] { nativeSuites[0] } )) {
|
|
System.out.print("\t... failed");
|
|
fail("SSLSocket enabled cipher list did not " +
|
|
"match expected single suite");
|
|
}
|
|
|
|
/* Test SSLSocket.getSupportedCipherSuites() */
|
|
sockEnabledSuites = sock.getSupportedCipherSuites();
|
|
if (!Arrays.equals(sockEnabledSuites,
|
|
new String[] { nativeSuites[0] } )) {
|
|
System.out.print("\t... failed");
|
|
fail("SSLSocket supported cipher list did not " +
|
|
"match expected single suite");
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
/* Set first two default cipher suites as the only suite enabled,
|
|
* then make sure only those suites are available after
|
|
* SSLContext creation. Tests property with multiple values. */
|
|
|
|
if (nativeSuites.length >= 2) {
|
|
Security.setProperty("wolfjsse.enabledCipherSuites",
|
|
nativeSuites[0] + ", " + nativeSuites[1]);
|
|
|
|
ctx = SSLContext.getInstance(allProtocols[i]);
|
|
ctx.init(null, null, null);
|
|
|
|
defaultSSLContextSuites =
|
|
ctx.getDefaultSSLParameters().getCipherSuites();
|
|
|
|
if (!Arrays.equals(defaultSSLContextSuites,
|
|
new String[] { nativeSuites[0], nativeSuites[1] } )) {
|
|
System.out.print("\t... failed");
|
|
fail("Default SSLContext cipher list did not " +
|
|
"match expected single suite");
|
|
}
|
|
|
|
sf = ctx.getSocketFactory();
|
|
sock = (SSLSocket)sf.createSocket();
|
|
|
|
/* Test SSLSocket.getEnabledCipherSuites() */
|
|
sockEnabledSuites = sock.getEnabledCipherSuites();
|
|
if (!Arrays.equals(sockEnabledSuites,
|
|
new String[] { nativeSuites[0], nativeSuites[1] } )) {
|
|
System.out.print("\t... failed");
|
|
fail("SSLSocket enabled cipher list did not " +
|
|
"match expected single suite");
|
|
}
|
|
|
|
/* Test SSLSocket.getSupportedCipherSuites(), may have
|
|
* different order based on native sorting */
|
|
sockEnabledSuites = sock.getSupportedCipherSuites();
|
|
if (!Arrays.asList(sockEnabledSuites)
|
|
.containsAll(Arrays.asList(
|
|
new String[] {
|
|
nativeSuites[0], nativeSuites[1] }))) {
|
|
System.out.print("\t... failed");
|
|
fail("SSLSocket supported cipher list did not " +
|
|
"match expected single suite");
|
|
}
|
|
}
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
/* Set first default cipher suite as the only suite enabled,
|
|
* then make sure we get an exception when we try to set
|
|
* another/different suite on the SSLSocket */
|
|
|
|
if (nativeSuites.length >= 2) {
|
|
Security.setProperty("wolfjsse.enabledCipherSuites",
|
|
nativeSuites[0]);
|
|
|
|
ctx = SSLContext.getInstance(allProtocols[i]);
|
|
ctx.init(null, null, null);
|
|
|
|
sf = ctx.getSocketFactory();
|
|
sock = (SSLSocket)sf.createSocket();
|
|
|
|
try {
|
|
/* set enabled suites as second available suite
|
|
* (shouldn't work), should throw exception */
|
|
sock.setEnabledCipherSuites(
|
|
new String[] { nativeSuites[1] });
|
|
} catch (IllegalArgumentException e) {
|
|
/* expected */
|
|
}
|
|
|
|
sockEnabledSuites = sock.getEnabledCipherSuites();
|
|
|
|
if (!Arrays.equals(sockEnabledSuites,
|
|
new String[] { nativeSuites[0] } )) {
|
|
System.out.print("\t... failed");
|
|
fail("Default SSLSocket cipher list did not " +
|
|
"match expected single suite");
|
|
}
|
|
}
|
|
|
|
} /* protocol for loop */
|
|
|
|
/* Restore original system property value */
|
|
if (originalProperty != null) {
|
|
Security.setProperty("wolfjsse.enabledCipherSuites",
|
|
originalProperty);
|
|
}
|
|
else {
|
|
Security.setProperty("wolfjsse.enabledCipherSuites", "");
|
|
}
|
|
|
|
System.out.println("\t... passed");
|
|
}
|
|
}
|
|
|