Skip to content

Commit

Permalink
Remove getCiphersUsed from endpoint since it will now vary by SSL host
Browse files Browse the repository at this point in the history
config
Create a Map (currently only populated with a single default) for SNI
host names to SSLContexts.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1673407 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
markt-asf committed Apr 14, 2015
1 parent c1a1cd8 commit bfa5b89
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 35 deletions.
Expand Up @@ -52,7 +52,6 @@ public void setKeystoreProvider(String s ) {


public String getCiphers() { return getEndpoint().getCiphers();} public String getCiphers() { return getEndpoint().getCiphers();}
public void setCiphers(String s) { getEndpoint().setCiphers(s);} public void setCiphers(String s) { getEndpoint().setCiphers(s);}
public String[] getCiphersUsed() { return getEndpoint().getCiphersUsed();}


public String getKeyAlias() { return getEndpoint().getKeyAlias();} public String getKeyAlias() { return getEndpoint().getKeyAlias();}
public void setKeyAlias(String s ) { getEndpoint().setKeyAlias(s);} public void setKeyAlias(String s ) { getEndpoint().setKeyAlias(s);}
Expand Down
1 change: 0 additions & 1 deletion java/org/apache/coyote/http11/Http11AprProtocol.java
Expand Up @@ -92,7 +92,6 @@ public boolean isAprRequired() {
*/ */
public String getSSLCipherSuite() { return ((AprEndpoint)getEndpoint()).getSSLCipherSuite(); } public String getSSLCipherSuite() { return ((AprEndpoint)getEndpoint()).getSSLCipherSuite(); }
public void setSSLCipherSuite(String SSLCipherSuite) { ((AprEndpoint)getEndpoint()).setSSLCipherSuite(SSLCipherSuite); } public void setSSLCipherSuite(String SSLCipherSuite) { ((AprEndpoint)getEndpoint()).setSSLCipherSuite(SSLCipherSuite); }
public String[] getCiphersUsed() { return getEndpoint().getCiphersUsed();}


/** /**
* SSL honor cipher order. * SSL honor cipher order.
Expand Down
4 changes: 0 additions & 4 deletions java/org/apache/tomcat/util/net/AbstractEndpoint.java
Expand Up @@ -963,10 +963,6 @@ public void setKeystoreFile(String s ) {
public void setCiphers(String s) { public void setCiphers(String s) {
ciphers = s; ciphers = s;
} }
/**
* @return The ciphers in use by this Endpoint
*/
public abstract String[] getCiphersUsed();


private String useServerCipherSuitesOrder = "false"; private String useServerCipherSuitesOrder = "false";
public String getUseServerCipherSuitesOrder() { return useServerCipherSuitesOrder;} public String getUseServerCipherSuitesOrder() { return useServerCipherSuitesOrder;}
Expand Down
79 changes: 58 additions & 21 deletions java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java
Expand Up @@ -16,6 +16,9 @@
*/ */
package org.apache.tomcat.util.net; package org.apache.tomcat.util.net;


import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
Expand All @@ -28,29 +31,20 @@
public abstract class AbstractJsseEndpoint<S> extends AbstractEndpoint<S> { public abstract class AbstractJsseEndpoint<S> extends AbstractEndpoint<S> {


private SSLImplementation sslImplementation = null; private SSLImplementation sslImplementation = null;
private Map<String,SSLContextWrapper> sslContexts = new HashMap<>();

public SSLImplementation getSslImplementation() { public SSLImplementation getSslImplementation() {
return sslImplementation; return sslImplementation;
} }


private String[] enabledCiphers;
@Override
public String[] getCiphersUsed() {
return enabledCiphers;
}

private String[] enabledProtocols;

private SSLContext sslContext = null;
public SSLContext getSSLContext() { return sslContext;}
public void setSSLContext(SSLContext c) { sslContext = c;}



protected void initialiseSsl() throws Exception { protected void initialiseSsl() throws Exception {
if (isSSLEnabled()) { if (isSSLEnabled()) {
sslImplementation = SSLImplementation.getInstance(getSslImplementationName()); sslImplementation = SSLImplementation.getInstance(getSslImplementationName());
SSLUtil sslUtil = sslImplementation.getSSLUtil(this);


sslContext = sslUtil.createSSLContext(); // TODO: Create multiple SSLContexts based on SSLHostConfig(s)
SSLUtil sslUtil = sslImplementation.getSSLUtil(this);
SSLContext sslContext = sslUtil.createSSLContext();
sslContext.init(wrap(sslUtil.getKeyManagers()), sslContext.init(wrap(sslUtil.getKeyManagers()),
sslUtil.getTrustManagers(), null); sslUtil.getTrustManagers(), null);


Expand All @@ -59,15 +53,16 @@ protected void initialiseSsl() throws Exception {
if (sessionContext != null) { if (sessionContext != null) {
sslUtil.configureSessionContext(sessionContext); sslUtil.configureSessionContext(sessionContext);
} }
// Determine which cipher suites and protocols to enable SSLContextWrapper sslContextWrapper = new SSLContextWrapper(sslContext, sslUtil);
enabledCiphers = sslUtil.getEnableableCiphers(sslContext); sslContexts.put(SSLHostConfig.DEFAULT_SSL_HOST_NAME, sslContextWrapper);
enabledProtocols = sslUtil.getEnableableProtocols(sslContext);
} }
} }




protected SSLEngine createSSLEngine(String sniHostName) { protected SSLEngine createSSLEngine(String sniHostName) {
SSLEngine engine = sslContext.createSSLEngine(); SSLContextWrapper sslContextWrapper = getSSLContextWrapper(sniHostName);

SSLEngine engine = sslContextWrapper.getSSLContext().createSSLEngine();
if ("false".equals(getClientAuth())) { if ("false".equals(getClientAuth())) {
engine.setNeedClientAuth(false); engine.setNeedClientAuth(false);
engine.setWantClientAuth(false); engine.setWantClientAuth(false);
Expand All @@ -77,8 +72,8 @@ protected SSLEngine createSSLEngine(String sniHostName) {
engine.setWantClientAuth(true); engine.setWantClientAuth(true);
} }
engine.setUseClientMode(false); engine.setUseClientMode(false);
engine.setEnabledCipherSuites(enabledCiphers); engine.setEnabledCipherSuites(sslContextWrapper.getEnabledCiphers());
engine.setEnabledProtocols(enabledProtocols); engine.setEnabledProtocols(sslContextWrapper.getEnabledProtocols());


configureUseServerCipherSuitesOrder(engine); configureUseServerCipherSuitesOrder(engine);


Expand All @@ -89,7 +84,7 @@ protected SSLEngine createSSLEngine(String sniHostName) {


@Override @Override
public void unbind() throws Exception { public void unbind() throws Exception {
sslContext = null; sslContexts.clear();
} }




Expand Down Expand Up @@ -123,4 +118,46 @@ private KeyManager[] wrap(KeyManager[] managers) {
} }
return result; return result;
} }


private SSLContextWrapper getSSLContextWrapper(String sniHostName) {
// First choice - direct match
SSLContextWrapper result = sslContexts.get(sniHostName);
if (result != null) {
return result;
}
// Second choice, wildcard match
int indexOfDot = sniHostName.indexOf('.');
if (indexOfDot > -1) {
result = sslContexts.get("*" + sniHostName.substring(indexOfDot));
}
// Fall-back. Use the default
if (result == null) {
result = sslContexts.get(SSLHostConfig.DEFAULT_SSL_HOST_NAME);
}
if (result == null) {
// Should never happen.
throw new IllegalStateException();
}
return result;
}


private static class SSLContextWrapper {

private final SSLContext sslContext;
private final String[] enabledCiphers;
private final String[] enabledProtocols;

public SSLContextWrapper(SSLContext sslContext, SSLUtil sslUtil) {
this.sslContext = sslContext;
// Determine which cipher suites and protocols to enable
enabledCiphers = sslUtil.getEnableableCiphers(sslContext);
enabledProtocols = sslUtil.getEnableableProtocols(sslContext);
}

public SSLContext getSSLContext() { return sslContext;}
public String[] getEnabledCiphers() { return enabledCiphers; }
public String[] getEnabledProtocols() { return enabledProtocols; }
}
} }
8 changes: 0 additions & 8 deletions java/org/apache/tomcat/util/net/AprEndpoint.java
Expand Up @@ -353,14 +353,6 @@ public int getLocalPort() {
} }




@Override
public String[] getCiphersUsed() {
// TODO : Investigate if it is possible to extract the current list of
// available ciphers. Native code changes will be required.
return new String[] { getSSLCipherSuite() };
}


/** /**
* This endpoint does not support <code>-1</code> for unlimited connections, * This endpoint does not support <code>-1</code> for unlimited connections,
* nor does it support setting this attribute while the endpoint is running. * nor does it support setting this attribute while the endpoint is running.
Expand Down
22 changes: 22 additions & 0 deletions java/org/apache/tomcat/util/net/SSLHostConfig.java
@@ -0,0 +1,22 @@
/*
* 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;

public class SSLHostConfig {

static final String DEFAULT_SSL_HOST_NAME = "*DEFAULT*";
}

0 comments on commit bfa5b89

Please sign in to comment.