This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/master by this push: new 4aac8d4 Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=63650 4aac8d4 is described below commit 4aac8d4b06bcf5a0ff5246d54d4fa4e00372f743 Author: Mark Thomas <ma...@apache.org> AuthorDate: Thu Aug 8 14:39:07 2019 +0100 Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=63650 Refactor initialisation for JSSE based TLS connectors to enable custom JSSE providers that provide custom cipher suites to be used. --- java/org/apache/tomcat/util/net/jsse/JSSEUtil.java | 121 +++++++++++---------- webapps/docs/changelog.xml | 5 + 2 files changed, 71 insertions(+), 55 deletions(-) diff --git a/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java b/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java index c30dac2..5f662de 100644 --- a/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java +++ b/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java @@ -27,7 +27,6 @@ import java.util.Set; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.compat.JreVendor; -import org.apache.tomcat.util.net.Constants; import org.apache.tomcat.util.net.SSLContext; import org.apache.tomcat.util.net.SSLHostConfigCertificate; import org.apache.tomcat.util.net.SSLUtilBase; @@ -47,61 +46,10 @@ public class JSSEUtil extends SSLUtilBase { private static final Log log = LogFactory.getLog(JSSEUtil.class); private static final StringManager sm = StringManager.getManager(JSSEUtil.class); - private static final Set<String> implementedProtocols; - private static final Set<String> implementedCiphers; - - static { - SSLContext context; - try { - context = new JSSESSLContext(Constants.SSL_PROTO_TLS); - context.init(null, null, null); - } catch (NoSuchAlgorithmException | KeyManagementException e) { - // This is fatal for the connector so throw an exception to prevent - // it from starting - throw new IllegalArgumentException(e); - } + private volatile boolean initialized = false; - String[] implementedProtocolsArray = context.getSupportedSSLParameters().getProtocols(); - implementedProtocols = new HashSet<>(implementedProtocolsArray.length); - - // Filter out SSLv2 from the list of implemented protocols (just in case - // we are running on a JVM that supports it) since it is no longer - // considered secure but allow SSLv2Hello. - // Note SSLv3 is allowed despite known insecurities because some users - // still have a requirement for it. - for (String protocol : implementedProtocolsArray) { - String protocolUpper = protocol.toUpperCase(Locale.ENGLISH); - if (!"SSLV2HELLO".equals(protocolUpper) && !"SSLV3".equals(protocolUpper)) { - if (protocolUpper.contains("SSL")) { - log.debug(sm.getString("jsse.excludeProtocol", protocol)); - continue; - } - } - implementedProtocols.add(protocol); - } - - if (implementedProtocols.size() == 0) { - log.warn(sm.getString("jsse.noDefaultProtocols")); - } - - String[] implementedCipherSuiteArray = context.getSupportedSSLParameters().getCipherSuites(); - // The IBM JRE will accept cipher suites names SSL_xxx or TLS_xxx but - // only returns the SSL_xxx form for supported cipher suites. Therefore - // need to filter the requested cipher suites using both forms with an - // IBM JRE. - if (JreVendor.IS_IBM_JVM) { - implementedCiphers = new HashSet<>(implementedCipherSuiteArray.length * 2); - for (String name : implementedCipherSuiteArray) { - implementedCiphers.add(name); - if (name.startsWith("SSL")) { - implementedCiphers.add("TLS" + name.substring(3)); - } - } - } else { - implementedCiphers = new HashSet<>(implementedCipherSuiteArray.length); - implementedCiphers.addAll(Arrays.asList(implementedCipherSuiteArray)); - } - } + private volatile Set<String> implementedProtocols; + private volatile Set<String> implementedCiphers; public JSSEUtil (SSLHostConfigCertificate certificate) { @@ -122,12 +70,14 @@ public class JSSEUtil extends SSLUtilBase { @Override protected Set<String> getImplementedProtocols() { + initialise(); return implementedProtocols; } @Override protected Set<String> getImplementedCiphers() { + initialise(); return implementedCiphers; } @@ -144,4 +94,65 @@ public class JSSEUtil extends SSLUtilBase { throws NoSuchAlgorithmException { return new JSSESSLContext(sslHostConfig.getSslProtocol()); } + + + private void initialise() { + if (!initialized) { + synchronized (this) { + if (!initialized) { + SSLContext context; + try { + context = new JSSESSLContext(sslHostConfig.getSslProtocol()); + context.init(null, null, null); + } catch (NoSuchAlgorithmException | KeyManagementException e) { + // This is fatal for the connector so throw an exception to prevent + // it from starting + throw new IllegalArgumentException(e); + } + + String[] implementedProtocolsArray = context.getSupportedSSLParameters().getProtocols(); + implementedProtocols = new HashSet<>(implementedProtocolsArray.length); + + // Filter out SSLv2 from the list of implemented protocols (just in case + // we are running on a JVM that supports it) since it is no longer + // considered secure but allow SSLv2Hello. + // Note SSLv3 is allowed despite known insecurities because some users + // still have a requirement for it. + for (String protocol : implementedProtocolsArray) { + String protocolUpper = protocol.toUpperCase(Locale.ENGLISH); + if (!"SSLV2HELLO".equals(protocolUpper) && !"SSLV3".equals(protocolUpper)) { + if (protocolUpper.contains("SSL")) { + log.debug(sm.getString("jsse.excludeProtocol", protocol)); + continue; + } + } + implementedProtocols.add(protocol); + } + + if (implementedProtocols.size() == 0) { + log.warn(sm.getString("jsse.noDefaultProtocols")); + } + + String[] implementedCipherSuiteArray = context.getSupportedSSLParameters().getCipherSuites(); + // The IBM JRE will accept cipher suites names SSL_xxx or TLS_xxx but + // only returns the SSL_xxx form for supported cipher suites. Therefore + // need to filter the requested cipher suites using both forms with an + // IBM JRE. + if (JreVendor.IS_IBM_JVM) { + implementedCiphers = new HashSet<>(implementedCipherSuiteArray.length * 2); + for (String name : implementedCipherSuiteArray) { + implementedCiphers.add(name); + if (name.startsWith("SSL")) { + implementedCiphers.add("TLS" + name.substring(3)); + } + } + } else { + implementedCiphers = new HashSet<>(implementedCipherSuiteArray.length); + implementedCiphers.addAll(Arrays.asList(implementedCipherSuiteArray)); + } + initialized = true; + } + } + } + } } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index c2419a7..15a5af4 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -141,6 +141,11 @@ Timeouts for HTTP/2 connections were not always correctly handled leaving some connections open for longer than expected. (markt) </fix> + <fix> + <bug>63650</bug>: Refactor initialisation for JSSE based TLS connectors + to enable custom JSSE providers that provide custom cipher suites to be + used. (markt) + </fix> </changelog> </subsection> <subsection name="Cluster"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org