Add ability to configure client TLS enabled protocol versions and cipher suites via Spring properties.

- Adding the ability to explicitly configure the enabled SSL protocol
versions and cipher suites used by the Vault HTTP client via the
following Spring properties:

* vault.ssl.enabled-protocols
* vault.ssl.enabled-cipher-suites

- Properties should be a comma-separated list of String constants that
correspond to those used by the enabled SSL provider.

Closes gh-635
Original pull request: gh-640.
This commit is contained in:
Ryan Gow
2021-03-09 20:40:26 +02:00
committed by Mark Paluch
parent 69ba330511
commit a85fa86535
8 changed files with 439 additions and 21 deletions

View File

@@ -105,6 +105,14 @@ public class ClientHttpConnectorFactory {
sslContextBuilder.keyManager(createKeyManagerFactory(sslConfiguration.getKeyStoreConfiguration(),
sslConfiguration.getKeyConfiguration()));
}
if (sslConfiguration.getEnabledProtocols() != null) {
sslContextBuilder.protocols(sslConfiguration.getEnabledProtocols());
}
if (sslConfiguration.getEnabledCipherSuites() != null) {
sslContextBuilder.ciphers(sslConfiguration.getEnabledCipherSuites());
}
}
catch (GeneralSecurityException | IOException e) {
throw new IllegalStateException(e);
@@ -189,6 +197,16 @@ public class ClientHttpConnectorFactory {
sslContextFactory.setKeyManagerPassword(new String(keyConfiguration.getKeyPassword()));
}
if (sslConfiguration.getEnabledProtocols() != null) {
sslContextFactory
.setIncludeProtocols(sslConfiguration.getEnabledProtocols().toArray(new String[0]));
}
if (sslConfiguration.getEnabledCipherSuites() != null) {
sslContextFactory
.setIncludeCipherSuites(sslConfiguration.getEnabledCipherSuites().toArray(new String[0]));
}
return new org.eclipse.jetty.client.HttpClient(sslContextFactory);
}

View File

@@ -43,9 +43,6 @@ import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509ExtendedKeyManager;
import javax.net.ssl.X509TrustManager;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import okhttp3.OkHttpClient.Builder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.client.config.RequestConfig;
@@ -55,7 +52,6 @@ import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.impl.conn.DefaultSchemePortResolver;
import org.apache.http.impl.conn.SystemDefaultRoutePlanner;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.Netty4ClientHttpRequestFactory;
@@ -69,9 +65,13 @@ import org.springframework.util.StringUtils;
import org.springframework.vault.support.ClientOptions;
import org.springframework.vault.support.PemObject;
import org.springframework.vault.support.SslConfiguration;
import org.springframework.vault.support.SslConfiguration.KeyConfiguration;
import org.springframework.vault.support.SslConfiguration.KeyStoreConfiguration;
import static org.springframework.vault.support.SslConfiguration.KeyConfiguration;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient.Builder;
/**
* Factory for {@link ClientHttpRequestFactory} that supports Apache HTTP Components,
@@ -298,7 +298,21 @@ public class ClientHttpRequestFactoryFactory {
if (hasSslConfiguration(sslConfiguration)) {
SSLContext sslContext = getSSLContext(sslConfiguration, getTrustManagers(sslConfiguration));
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext);
String[] enabledProtocols = null;
if (sslConfiguration.getEnabledProtocols() != null) {
enabledProtocols = sslConfiguration.getEnabledProtocols().toArray(new String[0]);
}
String[] enabledCipherSuites = null;
if (sslConfiguration.getEnabledCipherSuites() != null) {
enabledCipherSuites = sslConfiguration.getEnabledCipherSuites().toArray(new String[0]);
}
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext,
enabledProtocols, enabledCipherSuites, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
httpClientBuilder.setSSLSocketFactory(sslSocketFactory);
httpClientBuilder.setSSLContext(sslContext);
}
@@ -332,6 +346,8 @@ public class ClientHttpRequestFactoryFactory {
Builder builder = new Builder();
ConnectionSpec sslConnectionSpec = ConnectionSpec.MODERN_TLS;
if (hasSslConfiguration(sslConfiguration)) {
TrustManager[] trustManagers = getTrustManagers(sslConfiguration);
@@ -344,9 +360,24 @@ public class ClientHttpRequestFactoryFactory {
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
SSLContext sslContext = getSSLContext(sslConfiguration, trustManagers);
ConnectionSpec.Builder sslConnectionSpecBuilder = new ConnectionSpec.Builder(sslConnectionSpec);
if (sslConfiguration.getEnabledProtocols() != null) {
sslConnectionSpecBuilder.tlsVersions(sslConfiguration.getEnabledProtocols().toArray(new String[0]));
}
if (sslConfiguration.getEnabledCipherSuites() != null) {
sslConnectionSpecBuilder
.cipherSuites(sslConfiguration.getEnabledCipherSuites().toArray(new String[0]));
}
sslConnectionSpec = sslConnectionSpecBuilder.build();
builder.sslSocketFactory(sslContext.getSocketFactory(), trustManager);
}
builder.connectionSpecs(Arrays.asList(sslConnectionSpec, ConnectionSpec.CLEARTEXT));
builder.connectTimeout(options.getConnectionTimeout().toMillis(), TimeUnit.MILLISECONDS)
.readTimeout(options.getReadTimeout().toMillis(), TimeUnit.MILLISECONDS);
@@ -382,6 +413,14 @@ public class ClientHttpRequestFactoryFactory {
sslConfiguration.getKeyConfiguration()));
}
if (sslConfiguration.getEnabledProtocols() != null) {
sslContextBuilder.protocols(sslConfiguration.getEnabledProtocols());
}
if (sslConfiguration.getEnabledCipherSuites() != null) {
sslContextBuilder.ciphers(sslConfiguration.getEnabledCipherSuites());
}
requestFactory.setSslContext(sslContextBuilder.sslProvider(SslProvider.JDK).build());
}

View File

@@ -16,10 +16,11 @@
package org.springframework.vault.config;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
@@ -231,7 +232,12 @@ public class EnvironmentVaultConfiguration extends AbstractVaultConfiguration im
KeyStoreConfiguration trustStoreConfiguration = getKeyStoreConfiguration("vault.ssl.trust-store",
"vault.ssl.trust-store-password", "vault.ssl.trust-store-type");
return new SslConfiguration(keyStoreConfiguration, trustStoreConfiguration);
List<String> enabledProtocols = getList("vault.ssl.enabled-protocols");
List<String> enabledCipherSuites = getList("vault.ssl.enabled-cipher-suites");
return new SslConfiguration(keyStoreConfiguration, trustStoreConfiguration, enabledProtocols,
enabledCipherSuites);
}
private KeyStoreConfiguration getKeyStoreConfiguration(String resourceProperty, String passwordProperty,
@@ -421,6 +427,16 @@ public class EnvironmentVaultConfiguration extends AbstractVaultConfiguration im
return new KubernetesAuthentication(builder.build(), restOperations());
}
private List<String> getList(String key) {
String val = getEnvironment().getProperty(key);
if (val == null) {
return null;
}
return Arrays.asList(val.split(","));
}
@Nullable
private String getProperty(String key) {
return getEnvironment().getProperty(key);

View File

@@ -18,7 +18,10 @@ package org.springframework.vault.support;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.springframework.core.io.AbstractResource;
import org.springframework.core.io.Resource;
@@ -60,6 +63,10 @@ public class SslConfiguration {
private final KeyConfiguration keyConfiguration;
private final List<String> enabledProtocols;
private final List<String> enabledCipherSuites;
/**
* Create a new {@link SslConfiguration} with the default {@link KeyStore} type.
* @param keyStore the key store resource, must not be {@literal null}.
@@ -96,14 +103,23 @@ public class SslConfiguration {
* Create a new {@link SslConfiguration}.
* @param keyStoreConfiguration the key store configuration, must not be
* {@literal null}.
* @param keyConfiguration the configuration for a specific key in
* {@code keyStoreConfiguration} to use.
* @param trustStoreConfiguration the trust store configuration, must not be
* {@literal null}.
* @since 2.2
* @param enabledProtocols the enabled SSL protocols, elements must match protocol
* version strings used by the enabled Java SSL provider. May be {@literal null} to
* indicate the SSL socket factory should use a default list of enabled protocol
* versions.
* @param enabledCipherSuites the enabled SSL cipher suites, elements must match
* cipher suite strings used by the enabled Java SSL provider. May be {@literal null}
* to indicate the SSL socket factory should use a default list of enabled cipher
* suites.
* @since 2.4
* @see sun.security.ssl.ProtocolVersion
* @see sun.security.ssl.CipherSuite
*/
public SslConfiguration(KeyStoreConfiguration keyStoreConfiguration, KeyConfiguration keyConfiguration,
KeyStoreConfiguration trustStoreConfiguration) {
KeyStoreConfiguration trustStoreConfiguration, List<String> enabledProtocols,
List<String> enabledCipherSuites) {
Assert.notNull(keyStoreConfiguration, "KeyStore configuration must not be null");
Assert.notNull(keyConfiguration, "KeyConfiguration must not be null");
@@ -112,6 +128,50 @@ public class SslConfiguration {
this.keyStoreConfiguration = keyStoreConfiguration;
this.keyConfiguration = keyConfiguration;
this.trustStoreConfiguration = trustStoreConfiguration;
this.enabledProtocols = enabledProtocols != null
? Collections.unmodifiableList(new ArrayList<>(enabledProtocols)) : null;
this.enabledCipherSuites = enabledCipherSuites != null
? Collections.unmodifiableList(new ArrayList<>(enabledCipherSuites)) : null;
}
/**
* Create a new {@link SslConfiguration}.
* @param keyStoreConfiguration the key store configuration, must not be
* {@literal null}.
* @param keyConfiguration the configuration for a specific key in
* {@code keyStoreConfiguration} to use.
* @param trustStoreConfiguration the trust store configuration, must not be
* {@literal null}.
* @since 2.2
*/
public SslConfiguration(KeyStoreConfiguration keyStoreConfiguration, KeyConfiguration keyConfiguration,
KeyStoreConfiguration trustStoreConfiguration) {
this(keyStoreConfiguration, keyConfiguration, trustStoreConfiguration, null, null);
}
/**
* Create a new {@link SslConfiguration}.
* @param keyStoreConfiguration the key store configuration, must not be
* {@literal null}.
* @param trustStoreConfiguration the trust store configuration, must not be
* {@literal null}.
* @param enabledProtocols the enabled SSL protocols, elements must match protocol
* version strings used by the enabled Java SSL provider. May be {@literal null} to
* indicate the SSL socket factory should use a default list of enabled protocol
* versions.
* @param enabledCipherSuites the enabled SSL cipher suites, elements must match
* cipher suite strings used by the enabled Java SSL provider. May be {@literal null}
* to indicate the SSL socket factory should use a default list of enabled cipher
* suites.
* @since 2.4
* @see sun.security.ssl.ProtocolVersion
* @see sun.security.ssl.CipherSuite
*/
public SslConfiguration(KeyStoreConfiguration keyStoreConfiguration, KeyStoreConfiguration trustStoreConfiguration,
List<String> enabledProtocols, List<String> enabledCipherSuites) {
this(keyStoreConfiguration, KeyConfiguration.unconfigured(), trustStoreConfiguration, enabledProtocols,
enabledCipherSuites);
}
/**
@@ -299,6 +359,54 @@ public class SslConfiguration {
return new SslConfiguration(KeyStoreConfiguration.unconfigured(), KeyStoreConfiguration.unconfigured());
}
/**
* The list of SSL protocol versions that must be enabled. A value of {@literal null}
* indicates that the SSL socket factory should use a default list of enabled protocol
* versions.
* @return the list of enabled SSL protocol versions.
* @since 2.4
*/
public List<String> getEnabledProtocols() {
return this.enabledProtocols;
}
/**
* Create a new {@link SslConfiguration} with the enabled protocol versions applied
* retaining the other configuration from this instance.
* @param enabledProtocols may be {@literal null}.
* @return a new {@link SslConfiguration} with the enabled protocol versions applied.
* @since 2.4
* @see sun.security.ssl.ProtocolVersion
*/
public SslConfiguration withEnabledProtocols(List<String> enabledProtocols) {
return new SslConfiguration(this.keyStoreConfiguration, this.keyConfiguration, this.trustStoreConfiguration,
enabledProtocols, this.enabledCipherSuites);
}
/**
* The list of SSL cipher suites that must be enabled. A value of {@literal null}
* indicates that the SSL socket factory should use a default list of enabled cipher
* suites.
* @return the list of enabled SSL cipher suites.
* @since 2.4
*/
public List<String> getEnabledCipherSuites() {
return this.enabledCipherSuites;
}
/**
* Create a new {@link SslConfiguration} with the enabled cipher suites applied
* retaining the other configuration from this instance.
* @param enabledCipherSuites may be {@literal null}.
* @return a new {@link SslConfiguration} with the enabled cipher suites applied.
* @since 2.4
* @see sun.security.ssl.CipherSuite
*/
public SslConfiguration withEnabledCipherSuites(List<String> enabledCipherSuites) {
return new SslConfiguration(this.keyStoreConfiguration, this.keyConfiguration, this.trustStoreConfiguration,
this.enabledProtocols, enabledCipherSuites);
}
/**
* @return the {@link java.security.KeyStore key store} resource or {@literal null} if
* not configured.

View File

@@ -27,6 +27,9 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.springframework.vault.client.ClientHttpConnectorFactory.JettyClient;
import static org.springframework.vault.client.ClientHttpConnectorFactory.ReactorNetty;
import java.util.ArrayList;
import java.util.List;
/**
* Integration tests for {@link ClientHttpConnectorFactory}.
*
@@ -49,6 +52,39 @@ class ClientHttpConnectorFactoryIntegrationTests {
assertThat(response).isNotNull().contains("initialized");
}
@Test
void reactorNettyClientWithExplicitEnabledCipherSuitesShouldWork() {
List<String> enabledCipherSuites = new ArrayList<String>();
enabledCipherSuites.add("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384");
enabledCipherSuites.add("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
ClientHttpConnector factory = ReactorNetty.usingReactorNetty(new ClientOptions(),
Settings.createSslConfiguration().withEnabledCipherSuites(enabledCipherSuites));
WebClient webClient = WebClient.builder().clientConnector(factory).build();
String response = request(webClient);
assertThat(response).isNotNull().contains("initialized");
}
@Test
void reactorNettyClientWithExplicitEnabledProtocolsShouldWork() {
List<String> enabledProtocols = new ArrayList<String>();
enabledProtocols.add("TLSv1.2");
ClientHttpConnector factory = ReactorNetty.usingReactorNetty(new ClientOptions(),
Settings.createSslConfiguration().withEnabledProtocols(enabledProtocols));
WebClient webClient = WebClient.builder().clientConnector(factory).build();
String response = request(webClient);
assertThat(response).isNotNull().contains("initialized");
}
@Test
void jettyClientShouldWork() {
@@ -61,6 +97,39 @@ class ClientHttpConnectorFactoryIntegrationTests {
assertThat(response).isNotNull().contains("initialized");
}
@Test
void jettyClientWithExplicitEnabledCipherSuitesShouldWork() {
List<String> enabledCipherSuites = new ArrayList<String>();
enabledCipherSuites.add("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384");
enabledCipherSuites.add("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
ClientHttpConnector factory = JettyClient.usingJetty(new ClientOptions(),
Settings.createSslConfiguration().withEnabledCipherSuites(enabledCipherSuites));
WebClient webClient = WebClient.builder().clientConnector(factory).build();
String response = request(webClient);
assertThat(response).isNotNull().contains("initialized");
}
@Test
void jettyClientWithExplicitEnabledProtocolsShouldWork() {
List<String> enabledProtocols = new ArrayList<String>();
enabledProtocols.add("TLSv1.2");
ClientHttpConnector factory = JettyClient.usingJetty(new ClientOptions(),
Settings.createSslConfiguration().withEnabledProtocols(enabledProtocols));
WebClient webClient = WebClient.builder().clientConnector(factory).build();
String response = request(webClient);
assertThat(response).isNotNull().contains("initialized");
}
private String request(WebClient webClient) {
// Uninitialized and sealed can cause status 500

View File

@@ -15,10 +15,13 @@
*/
package org.springframework.vault.client;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.FileSystemResource;
@@ -27,17 +30,17 @@ import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.Netty4ClientHttpRequestFactory;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.vault.client.ClientHttpRequestFactoryFactory.HttpComponents;
import org.springframework.vault.client.ClientHttpRequestFactoryFactory.Netty;
import org.springframework.vault.client.ClientHttpRequestFactoryFactory.OkHttp3;
import org.springframework.vault.support.ClientOptions;
import org.springframework.vault.support.SslConfiguration;
import org.springframework.vault.util.Settings;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestTemplate;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
/**
* Integration tests for {@link ClientHttpRequestFactory}.
*
@@ -80,6 +83,43 @@ class ClientHttpRequestFactoryFactoryIntegrationTests {
((DisposableBean) factory).destroy();
}
@Test
void httpComponentsClientWithExplicitEnabledCipherSuitesShouldWork() throws Exception {
List<String> enabledCipherSuites = new ArrayList<String>();
enabledCipherSuites.add("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384");
enabledCipherSuites.add("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
ClientHttpRequestFactory factory = HttpComponents.usingHttpComponents(new ClientOptions(),
Settings.createSslConfiguration().withEnabledCipherSuites(enabledCipherSuites));
RestTemplate template = new RestTemplate(factory);
String response = request(template);
assertThat(factory).isInstanceOf(HttpComponentsClientHttpRequestFactory.class);
assertThat(response).isNotNull().contains("initialized");
((DisposableBean) factory).destroy();
}
@Test
void httpComponentsClientWithExplicitEnabledProtocolsShouldWork() throws Exception {
List<String> enabledProtocols = new ArrayList<String>();
enabledProtocols.add("TLSv1.2");
ClientHttpRequestFactory factory = HttpComponents.usingHttpComponents(new ClientOptions(),
Settings.createSslConfiguration().withEnabledProtocols(enabledProtocols));
RestTemplate template = new RestTemplate(factory);
String response = request(template);
assertThat(factory).isInstanceOf(HttpComponentsClientHttpRequestFactory.class);
assertThat(response).isNotNull().contains("initialized");
((DisposableBean) factory).destroy();
}
@Test
void nettyClientWithoutSslConfigShouldWork() throws Exception {
@@ -103,6 +143,96 @@ class ClientHttpRequestFactoryFactoryIntegrationTests {
((DisposableBean) factory).destroy();
}
@Test
void nettyClientWithExplicitEnabledCipherSuitesShouldWork() throws Exception {
List<String> enabledCipherSuites = new ArrayList<String>();
enabledCipherSuites.add("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384");
enabledCipherSuites.add("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
ClientHttpRequestFactory factory = Netty.usingNetty(new ClientOptions(),
Settings.createSslConfiguration().withEnabledCipherSuites(enabledCipherSuites));
((InitializingBean) factory).afterPropertiesSet();
RestTemplate template = new RestTemplate(factory);
String response = request(template);
assertThat(factory).isInstanceOf(Netty4ClientHttpRequestFactory.class);
assertThat(response).isNotNull().contains("initialized");
((DisposableBean) factory).destroy();
}
@Test
void nettyClientWithExplicitEnabledProtocolsShouldWork() throws Exception {
List<String> enabledProtocols = new ArrayList<String>();
enabledProtocols.add("TLSv1.2");
ClientHttpRequestFactory factory = Netty.usingNetty(new ClientOptions(),
Settings.createSslConfiguration().withEnabledProtocols(enabledProtocols));
((InitializingBean) factory).afterPropertiesSet();
RestTemplate template = new RestTemplate(factory);
String response = request(template);
assertThat(factory).isInstanceOf(Netty4ClientHttpRequestFactory.class);
assertThat(response).isNotNull().contains("initialized");
((DisposableBean) factory).destroy();
}
@Test
void okHttp3ClientShouldWork() throws Exception {
ClientHttpRequestFactory factory = OkHttp3.usingOkHttp3(new ClientOptions(), Settings.createSslConfiguration());
RestTemplate template = new RestTemplate(factory);
String response = request(template);
assertThat(factory).isInstanceOf(OkHttp3ClientHttpRequestFactory.class);
assertThat(response).isNotNull().contains("initialized");
((DisposableBean) factory).destroy();
}
@Test
void okHttp3ClientWithExplicitCipherSuitesShouldWork() throws Exception {
List<String> enabledCipherSuites = new ArrayList<String>();
enabledCipherSuites.add("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384");
enabledCipherSuites.add("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
ClientHttpRequestFactory factory = OkHttp3.usingOkHttp3(new ClientOptions(),
Settings.createSslConfiguration().withEnabledCipherSuites(enabledCipherSuites));
RestTemplate template = new RestTemplate(factory);
String response = request(template);
assertThat(factory).isInstanceOf(OkHttp3ClientHttpRequestFactory.class);
assertThat(response).isNotNull().contains("initialized");
((DisposableBean) factory).destroy();
}
@Test
void okHttp3ClientWithExplicitProtocolsShouldWork() throws Exception {
List<String> enabledProtocols = new ArrayList<String>();
enabledProtocols.add("TLSv1.2");
ClientHttpRequestFactory factory = OkHttp3.usingOkHttp3(new ClientOptions(),
Settings.createSslConfiguration().withEnabledProtocols(enabledProtocols));
RestTemplate template = new RestTemplate(factory);
String response = request(template);
assertThat(factory).isInstanceOf(OkHttp3ClientHttpRequestFactory.class);
assertThat(response).isNotNull().contains("initialized");
((DisposableBean) factory).destroy();
}
private String request(RestTemplate template) {
// Uninitialized and sealed can cause status 500

View File

@@ -15,12 +15,13 @@
*/
package org.springframework.vault.config;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@@ -34,8 +35,6 @@ import org.springframework.vault.authentication.TokenAuthentication;
import org.springframework.vault.support.SslConfiguration;
import org.springframework.vault.support.VaultToken;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Unit tests for {@link EnvironmentVaultConfiguration}.
*
@@ -78,6 +77,9 @@ class EnvironmentVaultConfigurationUnitTests {
Map<String, Object> map = new HashMap<String, Object>();
map.put("vault.ssl.key-store", "classpath:certificate.json");
map.put("vault.ssl.trust-store", "classpath:certificate.json");
map.put("vault.ssl.enabled-protocols", "TLSv1.2,TLSv1.1");
map.put("vault.ssl.enabled-cipher-suites",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
MapPropertySource propertySource = new MapPropertySource("shouldConfigureSsl", map);
this.configurableEnvironment.getPropertySources().addFirst(propertySource);
@@ -90,6 +92,10 @@ class EnvironmentVaultConfigurationUnitTests {
assertThat(sslConfiguration.getTrustStore()).isInstanceOf(ClassPathResource.class);
assertThat(sslConfiguration.getTrustStorePassword()).isEqualTo("trust store password");
assertThat(sslConfiguration.getEnabledProtocols()).containsExactly("TLSv1.2", "TLSv1.1");
assertThat(sslConfiguration.getEnabledCipherSuites()).containsExactly("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
this.configurableEnvironment.getPropertySources().remove(propertySource.getName());
}

View File

@@ -15,14 +15,15 @@
*/
package org.springframework.vault.support;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.vault.support.SslConfiguration.KeyStoreConfiguration;
import org.springframework.vault.util.Settings;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Unit tests for {@link SslConfiguration}.
*
@@ -46,6 +47,8 @@ class SslConfigurationUnitTests {
assertThat(sslConfiguration.getKeyStoreConfiguration().isPresent()).isFalse();
assertThat(sslConfiguration.getTrustStoreConfiguration().isPresent()).isFalse();
assertThat(sslConfiguration.getEnabledCipherSuites()).isNull();
assertThat(sslConfiguration.getEnabledProtocols()).isNull();
}
@Test
@@ -63,6 +66,35 @@ class SslConfigurationUnitTests {
assertThat(tsConfig.getKeyStoreConfiguration().isPresent()).isFalse();
}
@Test
void shouldCreateConfigurationWithEnabledCipherSuites() {
KeyStoreConfiguration keystore = KeyStoreConfiguration.of(new ClassPathResource("certificate.json"));
SslConfiguration tsConfig = SslConfiguration.unconfigured().withTrustStore(keystore)
.withEnabledCipherSuites(Arrays.asList(new String[] { "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" }));
assertThat(tsConfig.getTrustStoreConfiguration()).isSameAs(keystore);
assertThat(tsConfig.getKeyStoreConfiguration().isPresent()).isFalse();
assertThat(tsConfig.getEnabledCipherSuites().size()).isEqualTo(2);
assertThat(tsConfig.getEnabledCipherSuites().get(0)).isEqualTo("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384");
assertThat(tsConfig.getEnabledCipherSuites().get(1)).isEqualTo("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
}
@Test
void shouldCreateConfigurationWithEnabledProtocols() {
KeyStoreConfiguration keystore = KeyStoreConfiguration.of(new ClassPathResource("certificate.json"));
SslConfiguration tsConfig = SslConfiguration.unconfigured().withTrustStore(keystore)
.withEnabledProtocols(Arrays.asList(new String[] { "TLSv1.2", "TLSv1.1" }));
assertThat(tsConfig.getTrustStoreConfiguration()).isSameAs(keystore);
assertThat(tsConfig.getKeyStoreConfiguration().isPresent()).isFalse();
assertThat(tsConfig.getEnabledProtocols().size()).isEqualTo(2);
assertThat(tsConfig.getEnabledProtocols().get(0)).isEqualTo("TLSv1.2");
assertThat(tsConfig.getEnabledProtocols().get(1)).isEqualTo("TLSv1.1");
}
@Test
void shouldCreatePemConfiguration() {