You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2018/10/05 15:16:55 UTC
[cxf] 02/03: CXF-7865 - Enable default ciphersuites exclusion filter
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch 3.2.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git
commit d31bbade6b05dea0b02a3f2ed3d8b5a714f2a5e9
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Fri Oct 5 14:09:59 2018 +0100
CXF-7865 - Enable default ciphersuites exclusion filter
(cherry picked from commit e60e8ab5d7414a0dc581c5666873e1ab0413b107)
# Conflicts:
# core/src/main/java/org/apache/cxf/configuration/jsse/SSLUtils.java
---
.../apache/cxf/configuration/jsse/SSLUtils.java | 58 +++++++++++++++-------
.../https/ciphersuites/CipherSuitesTest.java | 54 ++++++++++++++++++++
2 files changed, 93 insertions(+), 19 deletions(-)
diff --git a/core/src/main/java/org/apache/cxf/configuration/jsse/SSLUtils.java b/core/src/main/java/org/apache/cxf/configuration/jsse/SSLUtils.java
index 62c660b..ad616e7 100644
--- a/core/src/main/java/org/apache/cxf/configuration/jsse/SSLUtils.java
+++ b/core/src/main/java/org/apache/cxf/configuration/jsse/SSLUtils.java
@@ -31,12 +31,12 @@ import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
@@ -68,13 +68,12 @@ public final class SSLUtils {
private static final String HTTPS_CIPHER_SUITES = "https.cipherSuites";
/**
- * By default, exclude NULL, anon, EXPORT, DES ciphersuites
+ * By default, exclude NULL, anon and EXPORT ciphersuites
*/
private static final List<String> DEFAULT_CIPHERSUITE_FILTERS_EXCLUDE =
- Arrays.asList(new String[] {".*_NULL_.*",
- ".*_anon_.*",
- ".*_EXPORT_.*",
- ".*_DES_.*"});
+ Arrays.asList(new String[] {".*NULL.*",
+ ".*anon.*",
+ ".*EXPORT.*"});
private static volatile KeyManager[] defaultManagers;
@@ -400,16 +399,27 @@ public final class SSLUtils {
String[] supportedCipherSuites,
Logger log, boolean exclude) {
// We have explicit filters, so use the "include/exclude" cipherSuiteFilter configuration
+ List<Pattern> includes = new ArrayList<>();
+ List<Pattern> excludes = new ArrayList<>();
+
+ if (filters != null) {
+ // We must have an inclusion pattern specified or no ciphersuites are filtered
+ compileRegexPatterns(includes, filters.getInclude(), true, log);
+
+ if (filters.isSetExclude()) {
+ // If we have specified excludes, then the default excludes are ignored
+ compileRegexPatterns(excludes, filters.getExclude(), false, log);
+ } else {
+ // Otherwise use the default excludes, but remove from the default excludes any
+ // ciphersuites explicitly matched by the inclusion filters
+ List<String> filteredExcludes =
+ filterDefaultExcludes(filters.getInclude(), DEFAULT_CIPHERSUITE_FILTERS_EXCLUDE);
+ compileRegexPatterns(excludes, filteredExcludes, false, log);
+ }
+ }
+
List<String> filteredCipherSuites = new ArrayList<>();
List<String> excludedCipherSuites = new ArrayList<>();
- List<Pattern> includes =
- filters != null
- ? compileRegexPatterns(filters.getInclude(), true, log)
- : Collections.emptyList();
- List<Pattern> excludes =
- filters != null
- ? compileRegexPatterns(filters.getExclude(), false, log)
- : compileRegexPatterns(DEFAULT_CIPHERSUITE_FILTERS_EXCLUDE, true, log);
for (int i = 0; i < supportedCipherSuites.length; i++) {
if (matchesOneOf(supportedCipherSuites[i], includes)
&& !matchesOneOf(supportedCipherSuites[i], excludes)) {
@@ -440,6 +450,19 @@ public final class SSLUtils {
return getCiphersFromList(filteredCipherSuites, log, exclude);
}
+ private static List<String> filterDefaultExcludes(List<String> includes, List<String> defaultExcludes) {
+ if (includes != null && !includes.isEmpty()) {
+ // Filter the default exclusion filters to remove any that explicitly match the inclusion filters
+ // e.g. if the user wants the NULL ciphersuite then remove it from the default excludes
+ return defaultExcludes.stream()
+ .filter(ex -> !includes.stream()
+ .anyMatch(inc -> inc.matches(ex)))
+ .collect(Collectors.toList());
+ }
+
+ return defaultExcludes;
+ }
+
private static String[] getSystemCiphersuites(Logger log) {
String jvmCipherSuites = System.getProperty(HTTPS_CIPHER_SUITES);
if ((jvmCipherSuites != null) && (!jvmCipherSuites.isEmpty())) {
@@ -450,10 +473,8 @@ public final class SSLUtils {
}
- private static List<Pattern> compileRegexPatterns(List<String> regexes,
- boolean include,
- Logger log) {
- List<Pattern> patterns = new ArrayList<>();
+ private static void compileRegexPatterns(List<Pattern> patterns, List<String> regexes,
+ boolean include, Logger log) {
if (regexes != null) {
String msg = include
? "CIPHERSUITE_INCLUDE_FILTER"
@@ -463,7 +484,6 @@ public final class SSLUtils {
patterns.add(Pattern.compile(s));
}
}
- return patterns;
}
private static boolean matchesOneOf(String s, List<Pattern> patterns) {
diff --git a/systests/transports/src/test/java/org/apache/cxf/systest/https/ciphersuites/CipherSuitesTest.java b/systests/transports/src/test/java/org/apache/cxf/systest/https/ciphersuites/CipherSuitesTest.java
index 382e21a..2564e35 100644
--- a/systests/transports/src/test/java/org/apache/cxf/systest/https/ciphersuites/CipherSuitesTest.java
+++ b/systests/transports/src/test/java/org/apache/cxf/systest/https/ciphersuites/CipherSuitesTest.java
@@ -22,11 +22,13 @@ package org.apache.cxf.systest.https.ciphersuites;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import java.util.Arrays;
import java.util.Collections;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
+import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.xml.ws.BindingProvider;
@@ -34,7 +36,10 @@ import javax.xml.ws.BindingProvider;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.configuration.jsse.SSLUtils;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
+import org.apache.cxf.configuration.security.FiltersType;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
@@ -593,6 +598,55 @@ public class CipherSuitesTest extends AbstractBusClientServerTestBase {
bus.shutdown(true);
}
+ @org.junit.Test
+ public void testDefaultCipherSuitesFilterExcluded() throws Exception {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, null, new java.security.SecureRandom());
+
+ FiltersType filtersType = new FiltersType();
+ filtersType.getInclude().add(".*_AES_.*");
+ String[] supportedCipherSuites = sslContext.getSocketFactory().getSupportedCipherSuites();
+ String[] filteredCipherSuites = SSLUtils.getFilteredCiphersuites(filtersType, supportedCipherSuites,
+ LogUtils.getL7dLogger(CipherSuitesTest.class), false);
+
+ // Check we have no anon/EXPORT/NULL/etc ciphersuites
+ assertFalse(Arrays.stream(
+ filteredCipherSuites).anyMatch(c -> c.matches(".*NULL|anon|EXPORT.*")));
+ }
+
+ @org.junit.Test
+ public void testExclusionFilter() throws Exception {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, null, new java.security.SecureRandom());
+
+ FiltersType filtersType = new FiltersType();
+ filtersType.getInclude().add(".*_AES_.*");
+ filtersType.getExclude().add(".*anon.*");
+ String[] supportedCipherSuites = sslContext.getSocketFactory().getSupportedCipherSuites();
+ String[] filteredCipherSuites = SSLUtils.getFilteredCiphersuites(filtersType, supportedCipherSuites,
+ LogUtils.getL7dLogger(CipherSuitesTest.class), false);
+
+ // Check we have no anon ciphersuites
+ assertFalse(Arrays.stream(
+ filteredCipherSuites).anyMatch(c -> c.matches(".*anon.*")));
+ }
+
+ @org.junit.Test
+ public void testInclusionFilter() throws Exception {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, null, new java.security.SecureRandom());
+
+ FiltersType filtersType = new FiltersType();
+ filtersType.getInclude().add(".*anon.*");
+ String[] supportedCipherSuites = sslContext.getSocketFactory().getSupportedCipherSuites();
+ String[] filteredCipherSuites = SSLUtils.getFilteredCiphersuites(filtersType, supportedCipherSuites,
+ LogUtils.getL7dLogger(CipherSuitesTest.class), false);
+
+ // Check we have anon ciphersuites
+ assertTrue(Arrays.stream(
+ filteredCipherSuites).anyMatch(c -> c.matches(".*anon.*")));
+ }
+
private static class NoOpX509TrustManager implements X509TrustManager {
NoOpX509TrustManager() {