Polish SslOptions usage

Change getter methods to return arrays, as this is how most client
library usages need the options.

See gh-34814
pull/35165/head
Scott Frederick 2 years ago
parent 226c3005d4
commit 428434c873

@ -160,8 +160,8 @@ public class CassandraAutoConfiguration {
private void configureSsl(CqlSessionBuilder builder, SslBundle sslBundle) {
SslOptions options = sslBundle.getOptions();
Assert.state(options.getEnabledProtocols() == null, "SSL protocol options cannot be specified with Cassandra");
String[] ciphers = SslOptions.toArray(options.getCiphers());
builder.withSslEngineFactory(new ProgrammaticSslEngineFactory(sslBundle.createSslContext(), ciphers));
builder
.withSslEngineFactory(new ProgrammaticSslEngineFactory(sslBundle.createSslContext(), options.getCiphers()));
}
@Bean(destroyMethod = "")

@ -119,8 +119,8 @@ class JedisConnectionConfiguration extends RedisConnectionConfiguration {
SslOptions sslOptions = sslBundle.getOptions();
SSLParameters sslParameters = new SSLParameters();
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
map.from(SslOptions.toArray(sslOptions.getCiphers())).to(sslParameters::setCipherSuites);
map.from(SslOptions.toArray(sslOptions.getEnabledProtocols())).to(sslParameters::setProtocols);
map.from(sslOptions.getCiphers()).to(sslParameters::setCipherSuites);
map.from(sslOptions.getEnabledProtocols()).to(sslParameters::setProtocols);
sslBuilder.sslParameters(sslParameters);
}
}

@ -151,13 +151,12 @@ class LettuceConnectionConfiguration extends RedisConnectionConfiguration {
io.lettuce.core.SslOptions.Builder sslOptionsBuilder = io.lettuce.core.SslOptions.builder();
sslOptionsBuilder.keyManager(sslBundle.getManagers().getKeyManagerFactory());
sslOptionsBuilder.trustManager(sslBundle.getManagers().getTrustManagerFactory());
String[] ciphers = SslOptions.toArray(sslBundle.getOptions().getCiphers());
if (ciphers != null) {
sslOptionsBuilder.cipherSuites(ciphers);
SslOptions sslOptions = sslBundle.getOptions();
if (sslOptions.getCiphers() != null) {
sslOptionsBuilder.cipherSuites(sslOptions.getCiphers());
}
String[] protocols = SslOptions.toArray(sslBundle.getOptions().getEnabledProtocols());
if (protocols != null) {
sslOptionsBuilder.protocols(protocols);
if (sslOptions.getEnabledProtocols() != null) {
sslOptionsBuilder.protocols(sslOptions.getEnabledProtocols());
}
builder.sslOptions(sslOptionsBuilder.build());
}

@ -116,10 +116,8 @@ class ElasticsearchRestClientConfigurations {
private void configureSsl(HttpAsyncClientBuilder httpClientBuilder, SslBundle sslBundle) {
SSLContext sslcontext = sslBundle.createSslContext();
SslOptions sslOptions = sslBundle.getOptions();
String[] enabledProtocols = SslOptions.toArray(sslOptions.getEnabledProtocols());
String[] ciphers = SslOptions.toArray(sslOptions.getCiphers());
httpClientBuilder.setSSLStrategy(
new SSLIOSessionStrategy(sslcontext, enabledProtocols, ciphers, (HostnameVerifier) null));
httpClientBuilder.setSSLStrategy(new SSLIOSessionStrategy(sslcontext, sslOptions.getEnabledProtocols(),
sslOptions.getCiphers(), (HostnameVerifier) null));
}
}

@ -59,9 +59,8 @@ public final class PropertiesSslBundle implements SslBundle {
return (key != null) ? SslBundleKey.of(key.getPassword(), key.getAlias()) : SslBundleKey.NONE;
}
private static SslOptions asSslOptions(SslBundleProperties.Options properties) {
return (properties != null) ? SslOptions.of(properties.getCiphers(), properties.getEnabledProtocols())
: SslOptions.NONE;
private static SslOptions asSslOptions(SslBundleProperties.Options options) {
return (options != null) ? SslOptions.of(options.getCiphers(), options.getEnabledProtocols()) : SslOptions.NONE;
}
@Override

@ -17,17 +17,13 @@
package org.springframework.boot.autoconfigure.web.reactive.function.client;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
import org.apache.hc.client5.http.nio.AsyncClientConnectionManager;
import org.apache.hc.core5.http.nio.ssl.BasicClientTlsStrategy;
import org.apache.hc.core5.net.NamedEndpoint;
import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
import org.apache.hc.core5.reactor.ssl.TlsDetails;
import org.springframework.boot.ssl.SslBundle;
import org.springframework.boot.ssl.SslOptions;
@ -47,19 +43,14 @@ class HttpComponentsClientHttpConnectorFactory
if (sslBundle != null) {
SslOptions options = sslBundle.getOptions();
SSLContext sslContext = sslBundle.createSslContext();
SSLSessionVerifier sessionVerifier = new SSLSessionVerifier() {
@Override
public TlsDetails verify(NamedEndpoint endpoint, SSLEngine sslEngine) throws SSLException {
SSLSessionVerifier sessionVerifier = (endpoint, sslEngine) -> {
if (options.getCiphers() != null) {
sslEngine.setEnabledCipherSuites(SslOptions.toArray(options.getCiphers()));
sslEngine.setEnabledCipherSuites(options.getCiphers());
}
if (options.getEnabledProtocols() != null) {
sslEngine.setEnabledProtocols(SslOptions.toArray(options.getEnabledProtocols()));
sslEngine.setEnabledProtocols(options.getEnabledProtocols());
}
return null;
}
};
BasicClientTlsStrategy tlsStrategy = new BasicClientTlsStrategy(sslContext, sessionVerifier);
AsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()

@ -40,8 +40,8 @@ class JdkClientHttpConnectorFactory implements ClientHttpConnectorFactory<JdkCli
SslOptions options = sslBundle.getOptions();
builder.sslContext(sslBundle.createSslContext());
SSLParameters parameters = new SSLParameters();
parameters.setCipherSuites(SslOptions.toArray(options.getCiphers()));
parameters.setProtocols(SslOptions.toArray(options.getEnabledProtocols()));
parameters.setCipherSuites(options.getCiphers());
parameters.setProtocols(options.getEnabledProtocols());
builder.sslParameters(parameters);
}
return new JdkClientHttpConnector(builder.build());

@ -46,11 +46,11 @@ class JettyClientHttpConnectorFactory implements ClientHttpConnectorFactory<Jett
if (sslBundle != null) {
SslOptions options = sslBundle.getOptions();
if (options.getCiphers() != null) {
sslContextFactory.setIncludeCipherSuites(SslOptions.toArray(options.getCiphers()));
sslContextFactory.setIncludeCipherSuites(options.getCiphers());
sslContextFactory.setExcludeCipherSuites();
}
if (options.getEnabledProtocols() != null) {
sslContextFactory.setIncludeProtocols(SslOptions.toArray(options.getEnabledProtocols()));
sslContextFactory.setIncludeProtocols(options.getEnabledProtocols());
sslContextFactory.setExcludeProtocols();
}
sslContextFactory.setSslContext(sslBundle.createSslContext());

@ -86,7 +86,7 @@ class ReactorClientHttpConnectorFactory implements ClientHttpConnectorFactory<Re
SslContextBuilder builder = SslContextBuilder.forClient()
.keyManager(managers.getKeyManagerFactory())
.trustManager(managers.getTrustManagerFactory())
.ciphers(options.getCiphers())
.ciphers(SslOptions.asSet(options.getCiphers()))
.protocols(options.getEnabledProtocols());
spec.sslContext(builder.build());
}

@ -40,7 +40,7 @@ public interface SslOptions {
/**
* Return if any SSL options have been specified.
* @return {@true} if SSL options have been specified
* @return {@code true} if SSL options have been specified
*/
default boolean isSpecified() {
return (getCiphers() != null) && (getEnabledProtocols() != null);
@ -52,7 +52,7 @@ public interface SslOptions {
* {@link SSLEngine#getSupportedCipherSuites()}.
* @return the ciphers that can be used or {@code null}
*/
Set<String> getCiphers();
String[] getCiphers();
/**
* Return the protocols that should be enabled or an empty set. The protocols names in
@ -60,7 +60,7 @@ public interface SslOptions {
* {@link SSLEngine#getSupportedProtocols()}.
* @return the protocols to enable or {@code null}
*/
Set<String> getEnabledProtocols();
String[] getEnabledProtocols();
/**
* Factory method to create a new {@link SslOptions} instance.
@ -69,44 +69,43 @@ public interface SslOptions {
* @return a new {@link SslOptions} instance
*/
static SslOptions of(String[] ciphers, String[] enabledProtocols) {
return of(asSet(ciphers), asSet(enabledProtocols));
}
/**
* Factory method to create a new {@link SslOptions} instance.
* @param ciphers the ciphers
* @param enabledProtocols the enabled protocols
* @return a new {@link SslOptions} instance
*/
static SslOptions of(Set<String> ciphers, Set<String> enabledProtocols) {
return new SslOptions() {
@Override
public Set<String> getCiphers() {
public String[] getCiphers() {
return ciphers;
}
@Override
public Set<String> getEnabledProtocols() {
public String[] getEnabledProtocols() {
return enabledProtocols;
}
};
}
/**
* Helper method that provides a null-safe way to convert a {@link Collection} to a
* {@code String[]} for client libraries to use.
* @param collection the collection to convert
* @return a string array or {@code null}
* Factory method to create a new {@link SslOptions} instance.
* @param ciphers the ciphers
* @param enabledProtocols the enabled protocols
* @return a new {@link SslOptions} instance
*/
static String[] toArray(Collection<String> collection) {
return (collection != null) ? collection.toArray(String[]::new) : null;
static SslOptions of(Set<String> ciphers, Set<String> enabledProtocols) {
return of(toArray(ciphers), toArray(enabledProtocols));
}
private static Set<String> asSet(String[] array) {
/**
* Helper method that provides a null-safe way to convert a {@code String[]} to a
* {@link Collection} for client libraries to use.
* @param array the array to convert
* @return a collection or {@code null}
*/
static Set<String> asSet(String[] array) {
return (array != null) ? Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(array))) : null;
}
private static String[] toArray(Collection<String> collection) {
return (collection != null) ? collection.toArray(String[]::new) : null;
}
}

@ -171,10 +171,8 @@ public final class ClientHttpRequestFactories {
}
if (sslBundle != null) {
SslOptions options = sslBundle.getOptions();
String[] enabledProtocols = SslOptions.toArray(options.getEnabledProtocols());
String[] ciphers = SslOptions.toArray(options.getCiphers());
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslBundle.createSslContext(),
enabledProtocols, ciphers, new DefaultHostnameVerifier());
options.getEnabledProtocols(), options.getCiphers(), new DefaultHostnameVerifier());
connectionManagerBuilder.setSSLSocketFactory(socketFactory);
}
PoolingHttpClientConnectionManager connectionManager = connectionManagerBuilder.build();

@ -179,11 +179,11 @@ class SslServerCustomizer implements JettyServerCustomizer {
}
factory.setCertAlias(key.getAlias());
if (options.getCiphers() != null) {
factory.setIncludeCipherSuites(SslOptions.toArray(options.getCiphers()));
factory.setIncludeCipherSuites(options.getCiphers());
factory.setExcludeCipherSuites();
}
if (options.getEnabledProtocols() != null) {
factory.setIncludeProtocols(SslOptions.toArray(options.getEnabledProtocols()));
factory.setIncludeProtocols(options.getEnabledProtocols());
factory.setExcludeProtocols();
}
try {

@ -66,7 +66,7 @@ public class SslServerCustomizer implements NettyServerCustomizer {
builder.trustManager(this.sslBundle.getManagers().getTrustManagerFactory());
SslOptions options = this.sslBundle.getOptions();
builder.protocols(options.getEnabledProtocols());
builder.ciphers(options.getCiphers());
builder.ciphers(SslOptions.asSet(options.getCiphers()));
builder.clientAuth(org.springframework.boot.web.server.Ssl.ClientAuth.map(this.clientAuth, ClientAuth.NONE,
ClientAuth.OPTIONAL, ClientAuth.REQUIRE));
});

@ -86,7 +86,7 @@ class SslConnectorCustomizer implements TomcatConnectorCustomizer {
}
sslHostConfig.addCertificate(certificate);
if (options.getCiphers() != null) {
String ciphers = StringUtils.collectionToCommaDelimitedString(options.getCiphers());
String ciphers = StringUtils.arrayToCommaDelimitedString(options.getCiphers());
sslHostConfig.setCiphers(ciphers);
}
configureEnabledProtocols(protocol);
@ -96,7 +96,7 @@ class SslConnectorCustomizer implements TomcatConnectorCustomizer {
private void configureEnabledProtocols(AbstractHttp11JsseProtocol<?> protocol) {
SslOptions options = this.sslBundle.getOptions();
if (options.getEnabledProtocols() != null) {
String enabledProtocols = StringUtils.collectionToCommaDelimitedString(options.getEnabledProtocols());
String enabledProtocols = StringUtils.arrayToCommaDelimitedString(options.getEnabledProtocols());
for (SSLHostConfig sslHostConfig : protocol.findSslHostConfigs()) {
sslHostConfig.setProtocols(enabledProtocols);
}

@ -59,8 +59,8 @@ class SslOptionsTests {
Set<String> ciphers = Set.of("a", "b", "c");
Set<String> enabledProtocols = Set.of("d", "e", "f");
SslOptions options = SslOptions.of(ciphers, enabledProtocols);
assertThat(options.getCiphers()).isEqualTo(ciphers);
assertThat(options.getEnabledProtocols()).isEqualTo(enabledProtocols);
assertThat(options.getCiphers()).contains("a", "b", "c");
assertThat(options.getEnabledProtocols()).contains("d", "e", "f");
}
@Test

Loading…
Cancel
Save