blob: aa8b49b424c18220236cdcee2b93289944c1a913 [file] [log] [blame]
/**
* 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.camel.util.jsse;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.List;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Represents {@link SSLContext} configuration options used in instantiating an
* {@code SSLContext} instance.
*/
public class SSLContextParameters extends BaseSSLContextParameters {
protected static final String DEFAULT_SECURE_SOCKET_PROTOCOL = "TLS";
private static final Logger LOG = LoggerFactory.getLogger(SSLContextParameters.class);
/**
* The optional key manager configuration for creating the
* {@link KeyManager}s used in constructing an {@link SSLContext}.
*/
private KeyManagersParameters keyManagers;
/**
* The optional trust manager configuration for creating the
* {@link TrustManager}s used in constructing an {@link SSLContext}.
*/
private TrustManagersParameters trustManagers;
/**
* The optional secure random configuration options to use for constructing
* the {@link SecureRandom} used in the creation of an {@link SSLContext].
*/
private SecureRandomParameters secureRandom;
/**
* The optional configuration options to be applied purely to the client side settings
* of the {@link SSLContext}. Settings specified here override any duplicate settings
* provided at the overall level by this class. These parameters apply to
* {@link SSLSocketFactory}s and {@link SSLEngine}s produced by the the {@code SSLContext}
* produced from this class as well as to the {@code SSLContext} itself.
*/
private SSLContextClientParameters clientParameters;
/**
* The optional configuration options to be applied purely to the server side settings
* of the {@link SSLContext}. Settings specified here override any duplicate settings
* provided at the overall level by this class. These parameters apply to
* {@link SSLServerSocketFactory}s and {@link SSLEngine}s produced by the the {@code SSLContext}
* produced from this class as well as to the {@code SSLContext} itself.
*/
private SSLContextServerParameters serverParameters;
/**
* The optional provider identifier for the JSSE implementation to use when
* constructing an {@link SSLContext}.
*/
private String provider;
/**
* The optional protocol for the secure sockets created by the {@link SSLContext}
* represented by this instance's configuration. See Appendix A in the <a
* href="http://download.oracle.com/javase/6/docs/technotes/guides//security/jsse/JSSERefGuide.html#AppA"
* >Java Secure Socket Extension Reference Guide</a> for information about
* standard protocol names.
*/
private String secureSocketProtocol;
public KeyManagersParameters getKeyManagers() {
return keyManagers;
}
/**
* Sets the optional key manager configuration for creating the
* {@link KeyManager}s used in constructing an {@link SSLContext}.
*
* @param keyManagers the options or {@code null} to provide no
* {@code KeyManager}s
*/
public void setKeyManagers(KeyManagersParameters keyManagers) {
this.keyManagers = keyManagers;
}
public TrustManagersParameters getTrustManagers() {
return trustManagers;
}
/**
* Sets the optional trust manager configuration for creating the
* {@link TrustManager}s used in constructing an {@link SSLContext}.
*
* @param trustManagers the options or {@code null} to provide no
* {@code TrustManager}s
*/
public void setTrustManagers(TrustManagersParameters trustManagers) {
this.trustManagers = trustManagers;
}
public SecureRandomParameters getSecureRandom() {
return secureRandom;
}
/**
* Sets the optional secure random configuration options to use for
* constructing the {@link SecureRandom} used in the creation of an {@link SSLContext}.
*
* @param secureRandom the options or {@code null} to use the default
*/
public void setSecureRandom(SecureRandomParameters secureRandom) {
this.secureRandom = secureRandom;
}
public SSLContextClientParameters getClientParameters() {
return clientParameters;
}
/**
* The optional configuration options to be applied purely to the client side settings
* of the {@link SSLContext}. Settings specified here override any duplicate settings
* provided at the overall level by this class. These parameters apply to
* {@link SSLSocketFactory}s and {@link SSLEngine}s produced by the the {@code SSLContext}
* produced from this class as well as to the {@code SSLContext} itself.
*
* @param clientParameters the optional additional client-side parameters
*/
public void setClientParameters(SSLContextClientParameters clientParameters) {
this.clientParameters = clientParameters;
}
public SSLContextServerParameters getServerParameters() {
return serverParameters;
}
/**
* The optional configuration options to be applied purely to the server side settings
* of the {@link SSLContext}. Settings specified here override any duplicate settings
* provided at the overall level by this class. These parameters apply to
* {@link SSLServerSocketFactory}s and {@link SSLEngine}s produced by the the {@code SSLContext}
* produced from this class as well as to the {@code SSLContext} itself.
*
* @param serverParameters the optional additional client-side parameters
*/
public void setServerParameters(SSLContextServerParameters serverParameters) {
this.serverParameters = serverParameters;
}
public String getProvider() {
return provider;
}
/**
* Sets the optional provider identifier to use when constructing an
* {@link SSLContext}.
*
* @param provider the identifier (from the list of available providers
* returned by {@link Security#getProviders()}) or {@code null}
* to use the highest priority provider implementing the secure
* socket protocol
*
* @see Security#getProviders(java.util.Map)
* @see #setSecureSocketProtocol(String)
*/
public void setProvider(String provider) {
this.provider = provider;
}
public String getSecureSocketProtocol() {
if (this.secureSocketProtocol == null) {
return DEFAULT_SECURE_SOCKET_PROTOCOL;
}
return this.secureSocketProtocol;
}
/**
* Sets the optional protocol for the secure sockets created by the
* {@link SSLContext} represented by this instance's configuration. Defaults
* to TLS. See Appendix A in the <a href=
* "http://download.oracle.com/javase/6/docs/technotes/guides//security/jsse/JSSERefGuide.html#AppA"
* >Java Secure Socket Extension Reference Guide</a> for information about
* standard protocol names.
*
* @param secureSocketProtocol the name of the protocol or {@code null} to
* use the default (TLS)
*/
public void setSecureSocketProtocol(String secureSocketProtocol) {
this.secureSocketProtocol = secureSocketProtocol;
}
////////////////////////////////////////////
/**
* Creates an {@link SSLContext} based on the related configuration options
* of this instance. Namely, {@link #keyManagers}, {@link #trustManagers}, and
* {@link #secureRandom}, but also respecting the chosen provider and secure
* socket protocol as well.
*
* @return a newly configured instance
*
* @throws GeneralSecurityException if there is a problem in this instances
* configuration or that of its nested configuration options
* @throws IOException if there is an error reading a key/trust store
*/
public SSLContext createSSLContext() throws GeneralSecurityException, IOException {
LOG.trace("Creating SSLContext from SSLContextParameters [{}].", this);
LOG.info("Available providers: {}.", Security.getProviders());
KeyManager[] keyManagers = this.keyManagers == null ? null : this.keyManagers.createKeyManagers();
TrustManager[] trustManagers = this.trustManagers == null ? null : this.trustManagers.createTrustManagers();
SecureRandom secureRandom = this.secureRandom == null ? null : this.secureRandom.createSecureRandom();
SSLContext context;
if (this.getProvider() == null) {
context = SSLContext.getInstance(this.parsePropertyValue(this.getSecureSocketProtocol()));
} else {
context = SSLContext.getInstance(this.parsePropertyValue(this.getSecureSocketProtocol()),
this.parsePropertyValue(this.getProvider()));
}
LOG.debug("SSLContext [{}], initialized from [{}], is using provider [{}], protocol [{}], key managers {}, trust managers {}, and secure random [{}].",
new Object[] {context, this, context.getProvider(), context.getProtocol(), keyManagers, trustManagers, secureRandom});
context.init(keyManagers, trustManagers, secureRandom);
this.configureSSLContext(context);
// Decorate the context.
context = new SSLContextDecorator(
new SSLContextSpiDecorator(
context,
this.getSSLEngineConfigurers(context),
this.getSSLSocketFactoryConfigurers(context),
this.getSSLServerSocketFactoryConfigurers(context)));
return context;
}
@Override
protected void configureSSLContext(SSLContext context) throws GeneralSecurityException {
LOG.trace("Configuring client and server side SSLContext parameters on SSLContext [{}]...", context);
super.configureSSLContext(context);
if (this.getClientParameters() != null) {
LOG.trace("Overriding client-side SSLContext parameters on SSLContext [{}] with configured client parameters.",
context);
this.getClientParameters().configureSSLContext(context);
}
if (this.getServerParameters() != null) {
LOG.trace("Overriding server-side SSLContext parameters on SSLContext [{}] with configured server parameters.",
context);
this.getServerParameters().configureSSLContext(context);
}
LOG.trace("Configured client and server side SSLContext parameters on SSLContext [{}].", context);
}
@Override
protected List<Configurer<SSLEngine>> getSSLEngineConfigurers(SSLContext context) {
LOG.trace("Collecting client and server side SSLEngine configurers on SSLContext [{}]...", context);
List<Configurer<SSLEngine>> configurers = super.getSSLEngineConfigurers(context);
if (this.getClientParameters() != null) {
LOG.trace("Augmenting SSLEngine configurers with configurers from client parameters on SSLContext [{}].",
context);
configurers.addAll(this.getClientParameters().getSSLEngineConfigurers(context));
}
if (this.getServerParameters() != null) {
LOG.trace("Augmenting SSLEngine configurers with configurers from server parameters on SSLContext [{}].",
context);
configurers.addAll(this.getServerParameters().getSSLEngineConfigurers(context));
}
LOG.trace("Collected client and server side SSLEngine configurers on SSLContext [{}].", context);
return configurers;
}
@Override
protected List<Configurer<SSLSocketFactory>> getSSLSocketFactoryConfigurers(SSLContext context) {
LOG.trace("Collecting SSLSocketFactory configurers on SSLContext [{}]...", context);
List<Configurer<SSLSocketFactory>> configurers = super.getSSLSocketFactoryConfigurers(context);
if (this.getClientParameters() != null) {
LOG.trace("Augmenting SSLSocketFactory configurers with configurers from client parameters on SSLContext [{}].",
context);
configurers.addAll(this.getClientParameters().getSSLSocketFactoryConfigurers(context));
}
LOG.trace("Collected SSLSocketFactory configurers on SSLContext [{}].", context);
return configurers;
}
@Override
protected List<Configurer<SSLServerSocketFactory>> getSSLServerSocketFactoryConfigurers(SSLContext context) {
LOG.trace("Collecting SSLServerSocketFactory configurers for SSLContext [{}]...", context);
List<Configurer<SSLServerSocketFactory>> configurers = super.getSSLServerSocketFactoryConfigurers(context);
if (this.getServerParameters() != null) {
LOG.trace("Augmenting SSLServerSocketFactory configurers with configurers from server parameters for SSLContext [{}].",
context);
configurers.addAll(this.getServerParameters().getSSLServerSocketFactoryConfigurers(context));
}
LOG.trace("Collected client and server side SSLServerSocketFactory configurers for SSLContext [{}].", context);
return configurers;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("SSLContextParameters [keyManagers=");
builder.append(keyManagers);
builder.append(", trustManagers=");
builder.append(trustManagers);
builder.append(", secureRandom=");
builder.append(secureRandom);
builder.append(", clientParameters=");
builder.append(clientParameters);
builder.append(", serverParameters=");
builder.append(serverParameters);
builder.append(", provider=");
builder.append(provider);
builder.append(", secureSocketProtocol=");
builder.append(secureSocketProtocol);
builder.append(", getCipherSuites()=");
builder.append(getCipherSuites());
builder.append(", getCipherSuitesFilter()=");
builder.append(getCipherSuitesFilter());
builder.append(", getSecureSocketProtocols()=");
builder.append(getSecureSocketProtocols());
builder.append(", getSecureSocketProtocolsFilter()=");
builder.append(getSecureSocketProtocolsFilter());
builder.append(", getSessionTimeout()=");
builder.append(getSessionTimeout());
builder.append(", getContext()=");
builder.append(getCamelContext());
builder.append("]");
return builder.toString();
}
}