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