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 2015/05/01 15:36:20 UTC

svn commit: r1677135 - in /tomcat/trunk: java/org/apache/coyote/http11/ java/org/apache/tomcat/util/net/ java/org/apache/tomcat/util/net/jsse/ java/org/apache/tomcat/util/net/jsse/openssl/ test/org/apache/tomcat/util/net/ webapps/docs/config/

Author: markt
Date: Fri May  1 13:36:20 2015
New Revision: 1677135

URL: http://svn.apache.org/r1677135
Log:
Move ciphers/SSLCipherSuite to SSLHostConfig

Added:
    tomcat/trunk/test/org/apache/tomcat/util/net/TestSSLHostConfig.java   (with props)
Modified:
    tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11JsseProtocol.java
    tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
    tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java
    tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.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/jsse/JSSESocketFactory.java
    tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/OpenSSLCipherConfigurationParser.java
    tomcat/trunk/webapps/docs/config/http.xml

Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11JsseProtocol.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11JsseProtocol.java?rev=1677135&r1=1677134&r2=1677135&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11JsseProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11JsseProtocol.java Fri May  1 13:36:20 2015
@@ -41,9 +41,6 @@ public abstract class AbstractHttp11Jsse
     public String getSslProtocol() { return getEndpoint().getSslProtocol();}
     public void setSslProtocol(String s) { getEndpoint().setSslProtocol(s);}
 
-    public String getCiphers() { return getEndpoint().getCiphers();}
-    public void setCiphers(String s) { getEndpoint().setCiphers(s);}
-
     public String getKeyAlias() { return getEndpoint().getKeyAlias();}
     public void setKeyAlias(String s ) { getEndpoint().setKeyAlias(s);}
 

Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java?rev=1677135&r1=1677134&r2=1677135&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java Fri May  1 13:36:20 2015
@@ -421,6 +421,16 @@ public abstract class AbstractHttp11Prot
     }
 
 
+    public void setCiphers(String ciphers) {
+        registerDefaultSSLHostConfig();
+        defaultSSLHostConfig.setCiphers(ciphers);
+    }
+    public void setSSLCipherSuite(String ciphers) {
+        registerDefaultSSLHostConfig();
+        defaultSSLHostConfig.setCiphers(ciphers);
+    }
+
+
     // ------------------------------------------------------------- Common code
 
     // Common configuration required for all new HTTP11 processors

Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java?rev=1677135&r1=1677134&r2=1677135&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java Fri May  1 13:36:20 2015
@@ -81,13 +81,6 @@ public class Http11AprProtocol extends A
 
 
     /**
-     * SSL cipher suite.
-     */
-    public String getSSLCipherSuite() { return ((AprEndpoint)getEndpoint()).getSSLCipherSuite(); }
-    public void setSSLCipherSuite(String SSLCipherSuite) { ((AprEndpoint)getEndpoint()).setSSLCipherSuite(SSLCipherSuite); }
-
-
-    /**
      * SSL certificate chain file.
      */
     public String getSSLCertificateChainFile() { return ((AprEndpoint)getEndpoint()).getSSLCertificateChainFile(); }

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=1677135&r1=1677134&r2=1677135&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java Fri May  1 13:36:20 2015
@@ -51,8 +51,6 @@ public abstract class AbstractEndpoint<S
 
     // -------------------------------------------------------------- Constants
 
-    protected static final String DEFAULT_CIPHERS = "HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA";
-
     protected static final StringManager sm = StringManager.getManager(
             AbstractEndpoint.class.getPackage().getName());
 
@@ -1000,12 +998,6 @@ public abstract class AbstractEndpoint<S
     public String getSslProtocol() { return sslProtocol;}
     public void setSslProtocol(String s) { sslProtocol = s;}
 
-    private String ciphers = DEFAULT_CIPHERS;
-    public String getCiphers() { return ciphers;}
-    public void setCiphers(String s) {
-        ciphers = s;
-    }
-
     private String keyAlias = null;
     public String getKeyAlias() { return keyAlias;}
     public void setKeyAlias(String s ) { keyAlias = s;}

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=1677135&r1=1677134&r2=1677135&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Fri May  1 13:36:20 2015
@@ -218,14 +218,6 @@ public class AprEndpoint extends Abstrac
 
 
     /**
-     * SSL cipher suite.
-     */
-    protected String SSLCipherSuite = DEFAULT_CIPHERS;
-    public String getSSLCipherSuite() { return SSLCipherSuite; }
-    public void setSSLCipherSuite(String SSLCipherSuite) { this.SSLCipherSuite = SSLCipherSuite; }
-
-
-    /**
      * SSL certificate chain file.
      */
     protected String SSLCertificateChainFile = null;
@@ -571,7 +563,7 @@ public class AprEndpoint extends Abstrac
                 }
 
                 // List the ciphers that the client is permitted to negotiate
-                SSLContext.setCipherSuite(ctx, SSLCipherSuite);
+                SSLContext.setCipherSuite(ctx, sslHostConfig.getCiphers());
                 // Load Server key and certificate
                 SSLContext.setCertificate(ctx, sslHostConfig.getCertificateFile(),
                         sslHostConfig.getCertificateKeyFile(), SSLPassword, SSL.SSL_AIDX_RSA);

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=1677135&r1=1677134&r2=1677135&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java Fri May  1 13:36:20 2015
@@ -25,6 +25,7 @@ import javax.net.ssl.KeyManagerFactory;
 
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.net.jsse.openssl.OpenSSLCipherConfigurationParser;
 import org.apache.tomcat.util.res.StringManager;
 
 public class SSLHostConfig {
@@ -46,6 +47,7 @@ public class SSLHostConfig {
     // Common
     private CertificateVerification certificateVerification = CertificateVerification.NONE;
     private int certificateVerificationDepth = 10;
+    private String ciphers = "HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA";
     private boolean honorCipherOrder = false;
 
     private Set<String> protocols = new HashSet<>();
@@ -123,6 +125,40 @@ public class SSLHostConfig {
     }
 
 
+    public void setCiphers(String ciphersList) {
+        // Ciphers is stored in OpenSSL format. Convert the provided value if
+        // necessary.
+        if (ciphersList != null && !ciphersList.contains(":")) {
+            StringBuilder sb = new StringBuilder();
+            // Not obviously in OpenSSL format. May be a single OpenSSL or JSSE
+            // cipher name. May be a comma separated list of cipher names
+            String ciphers[] = ciphersList.split(",");
+            for (String cipher : ciphers) {
+                String trimmed = cipher.trim();
+                if (trimmed.length() > 0) {
+                    String openSSLName = OpenSSLCipherConfigurationParser.jsseToOpenSSL(trimmed);
+                    if (openSSLName == null) {
+                        // Not a JSSE name. Maybe an OpenSSL name or alias
+                        openSSLName = trimmed;
+                    }
+                    if (sb.length() > 0) {
+                        sb.append(':');
+                    }
+                    sb.append(openSSLName);
+                }
+            }
+            this.ciphers = sb.toString();
+        } else {
+            this.ciphers = ciphersList;
+        }
+    }
+
+
+    public String getCiphers() {
+        return ciphers;
+    }
+
+
     public void setHonorCipherOrder(boolean honorCipherOrder) {
         this.honorCipherOrder = honorCipherOrder;
     }

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java?rev=1677135&r1=1677134&r2=1677135&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java Fri May  1 13:36:20 2015
@@ -88,14 +88,12 @@ public class JSSESocketFactory implement
         = System.getProperty("user.home") + "/.keystore";
     private static final int defaultSessionCacheSize = 0;
     private static final int defaultSessionTimeout = 86400;
-    private static final String ALLOW_ALL_SUPPORTED_CIPHERS = "ALL";
     public static final String DEFAULT_KEY_PASS = "changeit";
 
     private final AbstractEndpoint<?> endpoint;
     private final SSLHostConfig sslHostConfig;
 
     private final String[] defaultServerProtocols;
-    private final String[] defaultServerCipherSuites;
 
 
     public JSSESocketFactory (AbstractEndpoint<?> endpoint, SSLHostConfig sslHostConfig) {
@@ -127,20 +125,12 @@ public class JSSESocketFactory implement
             // This is very likely to be fatal but there is a slim chance that
             // the JSSE implementation just doesn't like creating unbound
             // sockets so allow the code to proceed.
-            defaultServerCipherSuites = new String[0];
             defaultServerProtocols = new String[0];
-            log.warn(sm.getString("jsse.noDefaultCiphers", endpoint.getName()));
             log.warn(sm.getString("jsse.noDefaultProtocols", endpoint.getName()));
             return;
         }
 
         try {
-            defaultServerCipherSuites = socket.getEnabledCipherSuites();
-            if (defaultServerCipherSuites.length == 0) {
-                log.warn(sm.getString("jsse.noDefaultCiphers",
-                        endpoint.getName()));
-            }
-
             // Filter out all the SSL protocols (SSLv2 and SSLv3) from the
             // defaults
             // since they are no longer considered secure
@@ -171,33 +161,13 @@ public class JSSESocketFactory implement
 
     @Override
     public String[] getEnableableCiphers(SSLContext context) {
-        String requestedCiphersStr = endpoint.getCiphers();
+        String requestedCiphersStr = sslHostConfig.getCiphers();
 
-        if (ALLOW_ALL_SUPPORTED_CIPHERS.equals(requestedCiphersStr)) {
-            return context.getSupportedSSLParameters().getCipherSuites();
-        }
-        if ((requestedCiphersStr == null)
-                || (requestedCiphersStr.trim().length() == 0)) {
-            return defaultServerCipherSuites;
-        }
+        List<String> requestedCiphers =
+                OpenSSLCipherConfigurationParser.parseExpression(requestedCiphersStr);
 
-        List<String> requestedCiphers = new ArrayList<>();
-        if (requestedCiphersStr.indexOf(':') != -1) {
-            requestedCiphers = OpenSSLCipherConfigurationParser.parseExpression(requestedCiphersStr);
-        } else {
-            for (String rc : requestedCiphersStr.split(",")) {
-                final String cipher = rc.trim();
-                if (cipher.length() > 0) {
-                    requestedCiphers.add(cipher);
-                }
-            }
-        }
-        if (requestedCiphers.isEmpty()) {
-            return defaultServerCipherSuites;
-        }
         List<String> ciphers = new ArrayList<>(requestedCiphers);
-        ciphers.retainAll(Arrays.asList(context.getSupportedSSLParameters()
-                .getCipherSuites()));
+        ciphers.retainAll(Arrays.asList(context.getSupportedSSLParameters().getCipherSuites()));
 
         if (ciphers.isEmpty()) {
             log.warn(sm.getString("jsse.requested_ciphers_not_supported",

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/OpenSSLCipherConfigurationParser.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/OpenSSLCipherConfigurationParser.java?rev=1677135&r1=1677134&r2=1677135&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/OpenSSLCipherConfigurationParser.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/OpenSSLCipherConfigurationParser.java Fri May  1 13:36:20 2015
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
@@ -373,6 +374,8 @@ public class OpenSSLCipherConfigurationP
     private static final String ALL = "ALL";
     private static final String COMPLEMENTOFALL = "COMPLEMENTOFALL";
 
+    private static final Map<String,String> jsseToOpenSSL = new HashMap<>();
+
     private static final void init() {
 
         for (Cipher cipher : Cipher.values()) {
@@ -385,6 +388,12 @@ public class OpenSSLCipherConfigurationP
                 aliases.put(alias, list);
             }
             aliases.put(cipher.name(), Collections.singletonList(cipher));
+
+            jsseToOpenSSL.put(cipher.name(), cipher.getOpenSSLAlias());
+            Set<String> jsseNames = cipher.getJsseNames();
+            for (String jsseName : jsseNames) {
+                jsseToOpenSSL.put(jsseName, cipher.getOpenSSLAlias());
+            }
         }
         List<Cipher> allCiphersList = Arrays.asList(Cipher.values());
         Collections.reverse(allCiphersList);
@@ -703,6 +712,13 @@ public class OpenSSLCipherConfigurationP
         return convertForJSSE(parse(expression));
     }
 
+    public static String jsseToOpenSSL(String cipher) {
+        if (!initialized) {
+            init();
+        }
+        return jsseToOpenSSL.get(cipher);
+    }
+
     static String displayResult(Collection<Cipher> ciphers, boolean useJSSEFormat, String separator) {
         if (ciphers.isEmpty()) {
             return "";

Added: tomcat/trunk/test/org/apache/tomcat/util/net/TestSSLHostConfig.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/net/TestSSLHostConfig.java?rev=1677135&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/util/net/TestSSLHostConfig.java (added)
+++ tomcat/trunk/test/org/apache/tomcat/util/net/TestSSLHostConfig.java Fri May  1 13:36:20 2015
@@ -0,0 +1,68 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.tomcat.util.net;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.tomcat.util.net.jsse.openssl.Cipher;
+
+public class TestSSLHostConfig {
+
+    @Test
+    public void testCipher01() {
+        SSLHostConfig hc = new SSLHostConfig();
+        Cipher c = Cipher.TLS_RSA_WITH_NULL_MD5;
+
+        // Single JSSE name
+        hc.setCiphers(c.getJsseNames().iterator().next());
+        Assert.assertEquals(c.getOpenSSLAlias(), hc.getCiphers());
+    }
+
+
+    @Test
+    public void testCipher02() {
+        SSLHostConfig hc = new SSLHostConfig();
+        Cipher c1 = Cipher.TLS_RSA_WITH_NULL_MD5;
+        Cipher c2 = Cipher.TLS_RSA_WITH_NULL_SHA;
+
+        // Two JSSE names
+        hc.setCiphers(c1.getJsseNames().iterator().next() + "," +
+                c2.getJsseNames().iterator().next());
+        Assert.assertEquals(c1.getOpenSSLAlias() + ":" + c2.getOpenSSLAlias(), hc.getCiphers());
+    }
+
+
+    @Test
+    public void testCipher03() {
+        SSLHostConfig hc = new SSLHostConfig();
+        // Single OpenSSL alias
+        hc.setCiphers("ALL");
+        Assert.assertEquals("ALL", hc.getCiphers());
+    }
+
+
+    @Test
+    public void testCipher04() {
+        SSLHostConfig hc = new SSLHostConfig();
+        Cipher c = Cipher.TLS_RSA_WITH_NULL_MD5;
+
+        // Single OpenSSLName name
+        hc.setCiphers(c.getOpenSSLAlias());
+        Assert.assertEquals(c.getOpenSSLAlias(), hc.getCiphers());
+    }
+}

Propchange: tomcat/trunk/test/org/apache/tomcat/util/net/TestSSLHostConfig.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tomcat/trunk/test/org/apache/tomcat/util/net/TestSSLHostConfig.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: tomcat/trunk/webapps/docs/config/http.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/http.xml?rev=1677135&r1=1677134&r2=1677135&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/http.xml (original)
+++ tomcat/trunk/webapps/docs/config/http.xml Fri May  1 13:36:20 2015
@@ -1085,6 +1085,22 @@
       of 10 will be used.</p>
     </attribute>
 
+    <attribute name="ciphers" required="false">
+      <p>The ciphers to enable using the OpenSSL syntax. (See the OpenSSL
+      documentation for the list of ciphers supported and the syntax).
+      Alternatively, a comma separated list of ciphers using with the standard
+      OpenSSL cipher names or the standard JSSE cipher names may be used.</p>
+      <p>When converting from OpenSSL syntax to JSSE ciphers for JSSE based
+      connectors, the behaviour of the OpenSSL syntax parsing is kept aligned
+      with the behaviour of the OpenSSL 1.1.0 development branch.</p>
+      <p>Only the ciphers that are supported by the SSL implementation will be
+      used.</p>
+      <p>If not specified, a default (using the OpenSSL notation) of
+      <code>HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5</code> will be used.</p>
+      <p>Note that, by default, the order in which ciphers are defined is not
+      trreated as an order of preference. See <code>honorCipherOrder</code>.</p>
+    </attribute>
+
     <attribute name="honorCipherOrder" required="false">
       <p>Set to <code>true</code> to enforce the server's cipher order
       (from the <code>ciphers</code> setting) instead of allowing
@@ -1145,27 +1161,14 @@
   <attributes>
 
     <attribute name="algorithm" required="false">
-      <p>This is an alias for the <code>keyManagerAlgorithm</code> attribute of the
-      default <a href="#SSL_Support_-_SSLHostConfig">SSLHostConfig</a>
+      <p>This is an alias for the <code>keyManagerAlgorithm</code> attribute of
+      the default <a href="#SSL_Support_-_SSLHostConfig">SSLHostConfig</a>
       element.</p>
     </attribute>
 
     <attribute name="ciphers" required="false">
-      <p>If specified and using ',' as a separator, only the ciphers that are
-      listed and supported by the SSL implementation will be used.
-      The ciphers are specified using the JSSE cipher naming convention. The
-      special value of <code>ALL</code> will enable all supported ciphers. This
-      will include many that are not secure. <code>ALL</code> is intended for
-      testing purposes only.</p>
-      <p>The list can also use ':' as a separator, in that case
-      it will use the OpenSSL syntax (see OpenSSL documentation for the list
-      of ciphers supported and the syntax). The behaviour of this filtering is
-      kept aligned with the behaviour of the OpenSSL 1.1.0 development
-      branch.</p>
-      <p>If not specified, a default (using the OpenSSL notation) of
-      <code>HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5</code> will be used.</p>
-      <p>Note that Java does not treat the order in which ciphers are defined as
-      an order of preference. See <code>useServerCipherSuitesOrder</code>.</p>
+      <p>This is an alias for the <code>ciphers</code> attribute of the default
+      <a href="#SSL_Support_-_SSLHostConfig">SSLHostConfig</a> element.</p>
     </attribute>
 
     <attribute name="clientAuth" required="false">
@@ -1416,9 +1419,8 @@
     </attribute>
 
     <attribute name="SSLCipherSuite" required="false">
-      <p>Ciphers which may be used for communicating with clients. The default
-      is <code>HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5</code>. See the OpenSSL
-      documentation for details of the syntax for this attribute.</p>
+      <p>This is an alias for the <code>ciphers</code> attribute of the default
+      <a href="#SSL_Support_-_SSLHostConfig">SSLHostConfig</a> element.</p>
     </attribute>
 
     <attribute name="SSLDisableCompression" required="false">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org