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 void setCiphers(String s) { getEndpoint().setCiphers(s);}
public String[] getCiphersUsed() { return getEndpoint().getCiphersUsed();}

public String getKeyAlias() { return getEndpoint().getKeyAlias();}
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 void setSSLCipherSuite(String SSLCipherSuite) { ((AprEndpoint)getEndpoint()).setSSLCipherSuite(SSLCipherSuite); }
public String[] getCiphersUsed() { return getEndpoint().getCiphersUsed();}

/**
* 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) {
ciphers = s;
}
/**
* @return The ciphers in use by this Endpoint
*/
public abstract String[] getCiphersUsed();

private String useServerCipherSuitesOrder = "false";
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;

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

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

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

public SSLImplementation getSslImplementation() {
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 {
if (isSSLEnabled()) {
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()),
sslUtil.getTrustManagers(), null);

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


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

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

configureUseServerCipherSuitesOrder(engine);

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

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


Expand Down Expand Up @@ -123,4 +118,46 @@ private KeyManager[] wrap(KeyManager[] managers) {
}
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,
* 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.