Author: markt Date: Tue Oct 9 17:23:48 2018 New Revision: 1843314 URL: http://svn.apache.org/viewvc?rev=1843314&view=rev Log: Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=62748 Add TLS 1.3 support (CLIENT-CERT untested)
Modified: tomcat/trunk/java/org/apache/tomcat/jni/SSL.java tomcat/trunk/java/org/apache/tomcat/jni/SSLContext.java tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java tomcat/trunk/java/org/apache/tomcat/util/net/SSLUtilBase.java tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLUtil.java tomcat/trunk/webapps/docs/changelog.xml tomcat/trunk/webapps/docs/config/http.xml Modified: tomcat/trunk/java/org/apache/tomcat/jni/SSL.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/jni/SSL.java?rev=1843314&r1=1843313&r2=1843314&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/jni/SSL.java (original) +++ tomcat/trunk/java/org/apache/tomcat/jni/SSL.java Tue Oct 9 17:23:48 2018 @@ -73,7 +73,9 @@ public final class SSL { public static final int SSL_PROTOCOL_TLSV1 = (1<<2); public static final int SSL_PROTOCOL_TLSV1_1 = (1<<3); public static final int SSL_PROTOCOL_TLSV1_2 = (1<<4); - public static final int SSL_PROTOCOL_ALL = (SSL_PROTOCOL_TLSV1 | SSL_PROTOCOL_TLSV1_1 | SSL_PROTOCOL_TLSV1_2); + public static final int SSL_PROTOCOL_TLSV1_3 = (1<<5); + public static final int SSL_PROTOCOL_ALL = (SSL_PROTOCOL_TLSV1 | SSL_PROTOCOL_TLSV1_1 | + SSL_PROTOCOL_TLSV1_2 | SSL_PROTOCOL_TLSV1_3); /* * Define the SSL verify levels Modified: tomcat/trunk/java/org/apache/tomcat/jni/SSLContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/jni/SSLContext.java?rev=1843314&r1=1843313&r2=1843314&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/jni/SSLContext.java (original) +++ tomcat/trunk/java/org/apache/tomcat/jni/SSLContext.java Tue Oct 9 17:23:48 2018 @@ -41,6 +41,7 @@ public final class SSLContext { * {@link SSL#SSL_PROTOCOL_TLSV1} * {@link SSL#SSL_PROTOCOL_TLSV1_1} * {@link SSL#SSL_PROTOCOL_TLSV1_2} + * {@link SSL#SSL_PROTOCOL_TLSV1_3} * {@link SSL#SSL_PROTOCOL_ALL} ( == all TLS versions, no SSL) * </PRE> * @param mode SSL mode to use Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1843314&r1=1843313&r2=1843314&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Tue Oct 9 17:23:48 2018 @@ -439,6 +439,8 @@ public class AprEndpoint extends Abstrac value |= SSL.SSL_PROTOCOL_TLSV1_1; } else if (Constants.SSL_PROTO_TLSv1_2.equalsIgnoreCase(protocol)) { value |= SSL.SSL_PROTOCOL_TLSV1_2; + } else if (Constants.SSL_PROTO_TLSv1_3.equalsIgnoreCase(protocol)) { + value |= SSL.SSL_PROTOCOL_TLSV1_3; } else { // Should not happen since filtering to build // enabled protocols removes invalid values. Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java?rev=1843314&r1=1843313&r2=1843314&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java Tue Oct 9 17:23:48 2018 @@ -35,7 +35,6 @@ import javax.net.ssl.TrustManagerFactory import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; -import org.apache.tomcat.util.compat.TLS; import org.apache.tomcat.util.net.openssl.OpenSSLConf; import org.apache.tomcat.util.net.openssl.ciphers.Cipher; import org.apache.tomcat.util.net.openssl.ciphers.OpenSSLCipherConfigurationParser; @@ -62,9 +61,7 @@ public class SSLHostConfig implements Se SSL_PROTO_ALL_SET.add(Constants.SSL_PROTO_TLSv1); SSL_PROTO_ALL_SET.add(Constants.SSL_PROTO_TLSv1_1); SSL_PROTO_ALL_SET.add(Constants.SSL_PROTO_TLSv1_2); - if (TLS.isTlsv13Available()) { - SSL_PROTO_ALL_SET.add(Constants.SSL_PROTO_TLSv1_3); - } + SSL_PROTO_ALL_SET.add(Constants.SSL_PROTO_TLSv1_3); } private Type configType = null; @@ -85,6 +82,10 @@ public class SSLHostConfig implements Se private String[] enabledCiphers; private String[] enabledProtocols; private ObjectName oname; + // Need to know if TLS 1.3 has been explicitly requested as a warning needs + // to generated if it is explicitly requested for a JVM that does not + // support it. Uses a set so it is extensible for TLS 1.4 etc. + private Set<String> explicitlyRequestedProtocols = new HashSet<>(); // Nested private SSLHostConfigCertificate defaultCertificate = null; private Set<SSLHostConfigCertificate> certificates = new HashSet<>(4); @@ -443,6 +444,7 @@ public class SSLHostConfig implements Se public void setProtocols(String input) { protocols.clear(); + explicitlyRequestedProtocols.clear(); // List of protocol names, separated by ",", "+" or "-". // Semantics is adding ("+") or removing ("-") from left @@ -465,6 +467,7 @@ public class SSLHostConfig implements Se protocols.addAll(SSL_PROTO_ALL_SET); } else { protocols.add(trimmed); + explicitlyRequestedProtocols.add(trimmed); } } else if (trimmed.charAt(0) == '-') { trimmed = trimmed.substring(1).trim(); @@ -472,6 +475,7 @@ public class SSLHostConfig implements Se protocols.removeAll(SSL_PROTO_ALL_SET); } else { protocols.remove(trimmed); + explicitlyRequestedProtocols.remove(trimmed); } } else { if (trimmed.charAt(0) == ',') { @@ -485,6 +489,7 @@ public class SSLHostConfig implements Se protocols.addAll(SSL_PROTO_ALL_SET); } else { protocols.add(trimmed); + explicitlyRequestedProtocols.add(trimmed); } } } @@ -497,6 +502,11 @@ public class SSLHostConfig implements Se } + boolean isExplicitlyRequestedProtocol(String protocol) { + return explicitlyRequestedProtocols.contains(protocol); + } + + // ---------------------------------- JSSE specific configuration properties // TODO: These certificate setters can be removed once it is no longer Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SSLUtilBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SSLUtilBase.java?rev=1843314&r1=1843313&r2=1843314&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/SSLUtilBase.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/SSLUtilBase.java Tue Oct 9 17:23:48 2018 @@ -48,14 +48,25 @@ public abstract class SSLUtilBase implem protected SSLUtilBase(SSLHostConfigCertificate certificate) { + this(certificate, true); + } + + + protected SSLUtilBase(SSLHostConfigCertificate certificate, boolean warnOnSkip) { this.certificate = certificate; SSLHostConfig sslHostConfig = certificate.getSSLHostConfig(); // Calculate the enabled protocols Set<String> configuredProtocols = sslHostConfig.getProtocols(); + if (!isTls13Available() && + !sslHostConfig.isExplicitlyRequestedProtocol(Constants.SSL_PROTO_TLSv1_3)) { + // TLS 1.3 not implemented and not explicitly requested so ignore it + // if present + configuredProtocols.remove(Constants.SSL_PROTO_TLSv1_3); + } Set<String> implementedProtocols = getImplementedProtocols(); List<String> enabledProtocols = - getEnabled("protocols", getLog(), true, configuredProtocols, implementedProtocols); + getEnabled("protocols", getLog(), warnOnSkip, configuredProtocols, implementedProtocols); if (enabledProtocols.contains("SSLv3")) { log.warn(sm.getString("jsse.ssl3")); } @@ -197,4 +208,5 @@ public abstract class SSLUtilBase implem protected abstract Set<String> getImplementedProtocols(); protected abstract Set<String> getImplementedCiphers(); protected abstract Log getLog(); + protected abstract boolean isTls13Available(); } Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java?rev=1843314&r1=1843313&r2=1843314&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java Tue Oct 9 17:23:48 2018 @@ -58,6 +58,7 @@ import javax.net.ssl.X509KeyManager; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.compat.JreVendor; +import org.apache.tomcat.util.compat.TLS; import org.apache.tomcat.util.file.ConfigFileLoader; import org.apache.tomcat.util.net.Constants; import org.apache.tomcat.util.net.SSLContext; @@ -141,7 +142,12 @@ public class JSSEUtil extends SSLUtilBas public JSSEUtil (SSLHostConfigCertificate certificate) { - super(certificate); + this(certificate, true); + } + + + public JSSEUtil (SSLHostConfigCertificate certificate, boolean warnOnSkip) { + super(certificate, warnOnSkip); this.sslHostConfig = certificate.getSSLHostConfig(); } @@ -164,6 +170,12 @@ public class JSSEUtil extends SSLUtilBas } + @Override + protected boolean isTls13Available() { + return TLS.isTlsv13Available(); + } + + @Override public SSLContext createSSLContext(List<String> negotiableProtocols) throws NoSuchAlgorithmException { return new JSSESSLContext(sslHostConfig.getSslProtocol()); Modified: tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java?rev=1843314&r1=1843313&r2=1843314&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java Tue Oct 9 17:23:48 2018 @@ -153,6 +153,8 @@ public class OpenSSLContext implements o value |= SSL.SSL_PROTOCOL_TLSV1_1; } else if (Constants.SSL_PROTO_TLSv1_2.equalsIgnoreCase(protocol)) { value |= SSL.SSL_PROTOCOL_TLSV1_2; + } else if (Constants.SSL_PROTO_TLSv1_3.equalsIgnoreCase(protocol)) { + value |= SSL.SSL_PROTOCOL_TLSV1_3; } else if (Constants.SSL_PROTO_ALL.equalsIgnoreCase(protocol)) { value |= SSL.SSL_PROTOCOL_ALL; } else { Modified: tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java?rev=1843314&r1=1843313&r2=1843314&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java Tue Oct 9 17:23:48 2018 @@ -21,7 +21,6 @@ import java.nio.ReadOnlyBufferException; import java.security.Principal; import java.security.cert.Certificate; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -65,6 +64,8 @@ public final class OpenSSLEngine extends public static final Set<String> AVAILABLE_CIPHER_SUITES; + public static final Set<String> IMPLEMENTED_PROTOCOLS_SET; + static { final Set<String> availableCipherSuites = new LinkedHashSet<>(128); final long aprPool = Pool.create(0); @@ -94,6 +95,19 @@ public final class OpenSSLEngine extends Pool.destroy(aprPool); } AVAILABLE_CIPHER_SUITES = Collections.unmodifiableSet(availableCipherSuites); + + HashSet<String> protocols = new HashSet<>(); + protocols.add(Constants.SSL_PROTO_SSLv2Hello); + protocols.add(Constants.SSL_PROTO_SSLv2); + protocols.add(Constants.SSL_PROTO_SSLv3); + protocols.add(Constants.SSL_PROTO_TLSv1); + protocols.add(Constants.SSL_PROTO_TLSv1_1); + protocols.add(Constants.SSL_PROTO_TLSv1_2); + if (SSL.version() >= 0x1010100f) { + protocols.add(Constants.SSL_PROTO_TLSv1_3); + } + + IMPLEMENTED_PROTOCOLS_SET = Collections.unmodifiableSet(protocols); } private static final int MAX_PLAINTEXT_LENGTH = 16 * 1024; // 2^14 @@ -103,17 +117,6 @@ public final class OpenSSLEngine extends // Protocols static final int VERIFY_DEPTH = 10; - private static final String[] IMPLEMENTED_PROTOCOLS = { - Constants.SSL_PROTO_SSLv2Hello, - Constants.SSL_PROTO_SSLv2, - Constants.SSL_PROTO_SSLv3, - Constants.SSL_PROTO_TLSv1, - Constants.SSL_PROTO_TLSv1_1, - Constants.SSL_PROTO_TLSv1_2 - }; - public static final Set<String> IMPLEMENTED_PROTOCOLS_SET = - Collections.unmodifiableSet(new HashSet<>(Arrays.asList(IMPLEMENTED_PROTOCOLS))); - // Header (5) + Data (2^14) + Compression (1024) + Encryption (1024) + MAC (20) + Padding (256) static final int MAX_ENCRYPTED_PACKET_LENGTH = MAX_CIPHERTEXT_LENGTH + 5 + 20 + 256; @@ -760,7 +763,7 @@ public final class OpenSSLEngine extends @Override public String[] getSupportedProtocols() { - return IMPLEMENTED_PROTOCOLS.clone(); + return IMPLEMENTED_PROTOCOLS_SET.toArray(new String[IMPLEMENTED_PROTOCOLS_SET.size()]); } @Override Modified: tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLUtil.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLUtil.java?rev=1843314&r1=1843313&r2=1843314&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLUtil.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLUtil.java Tue Oct 9 17:23:48 2018 @@ -25,6 +25,7 @@ import javax.net.ssl.TrustManager; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; +import org.apache.tomcat.jni.SSL; import org.apache.tomcat.util.net.SSLContext; import org.apache.tomcat.util.net.SSLHostConfig; import org.apache.tomcat.util.net.SSLHostConfigCertificate; @@ -42,7 +43,8 @@ public class OpenSSLUtil extends SSLUtil if (certificate.getCertificateFile() == null) { // Using JSSE configuration for keystore and truststore - jsseUtil = new JSSEUtil(certificate); + // Missing protocols not a concern so don't warn on skip + jsseUtil = new JSSEUtil(certificate, false); } else { // Use OpenSSL configuration for certificates jsseUtil = null; @@ -68,6 +70,12 @@ public class OpenSSLUtil extends SSLUtil } + @Override + protected boolean isTls13Available() { + return SSL.version() >= 0x1010100f; + } + + @Override public SSLContext createSSLContext(List<String> negotiableProtocols) throws Exception { return new OpenSSLContext(certificate, negotiableProtocols); Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1843314&r1=1843313&r2=1843314&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Tue Oct 9 17:23:48 2018 @@ -118,6 +118,10 @@ Such requests are unusual but not invalid. Patch provided by Michael Orr. (markt) </fix> + <add> + <bug>62748</bug>: Add TLS 1.3 support for the Tomcat Native connector. + (schultz/markt) + </add> <fix> <bug>62791</bug>: Remove an unnecessary check in the NIO TLS implementation that prevented from secure WebSocket connections from Modified: tomcat/trunk/webapps/docs/config/http.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/http.xml?rev=1843314&r1=1843313&r2=1843314&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/http.xml (original) +++ tomcat/trunk/webapps/docs/config/http.xml Tue Oct 9 17:23:48 2018 @@ -1294,8 +1294,8 @@ an empty list.</p> <p>The token <code>all</code> is an alias for <code>SSLv2Hello,TLSv1,TLSv1.1,TLSv1.2,TLSv1.3</code>.</p> - <p>Note that <code>TLSv1.3</code> is only supported for JSSE and JVMs - that implement <code>TLSv1.3</code>.</p> + <p>Note that <code>TLSv1.3</code> is only supported for JSSE when using a + JVM that implements <code>TLSv1.3</code>.</p> <p>Note that <code>SSLv2Hello</code> will be ignored for OpenSSL based secure connectors. If more than one protocol is specified for an OpenSSL based secure connector it will always support <code>SSLv2Hello</code>. If a --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org