You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2018/10/09 17:23:49 UTC

svn commit: r1843314 - in /tomcat/trunk: java/org/apache/tomcat/jni/ java/org/apache/tomcat/util/net/ java/org/apache/tomcat/util/net/jsse/ java/org/apache/tomcat/util/net/openssl/ webapps/docs/ webapps/docs/config/

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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org