diff --git a/spring-data-geode/src/main/java/org/springframework/data/gemfire/GemFireProperties.java b/spring-data-geode/src/main/java/org/springframework/data/gemfire/GemFireProperties.java index 18787048..552a7a0d 100644 --- a/spring-data-geode/src/main/java/org/springframework/data/gemfire/GemFireProperties.java +++ b/spring-data-geode/src/main/java/org/springframework/data/gemfire/GemFireProperties.java @@ -116,29 +116,29 @@ public enum GemFireProperties { SERVER_BIND_ADDRESS(ConfigurationProperties.SERVER_BIND_ADDRESS, String.class), SOCKET_BUFFER_SIZE(ConfigurationProperties.SOCKET_BUFFER_SIZE, Integer.class, 32768), SOCKET_LEASE_TIME(ConfigurationProperties.SOCKET_LEASE_TIME, Long.class, 60000L), - SSL_CLIENT_PROTOCOLS(ConfigurationProperties.SSL_CLIENT_PROTOCOLS, String.class, ""), - SSL_ENABLED_COMPONENTS(ConfigurationProperties.SSL_ENABLED_COMPONENTS, String.class, "all"), - SSL_ENDPOINT_IDENTIFICATION_ENABLED(ConfigurationProperties.SSL_ENDPOINT_IDENTIFICATION_ENABLED, Boolean.class, false), - SSL_REQUIRE_AUTHENTICATION(ConfigurationProperties.SSL_REQUIRE_AUTHENTICATION, Boolean.class, true), - SSL_SERVER_PROTOCOLS(ConfigurationProperties.SSL_SERVER_PROTOCOLS, String.class, ""), SSL_CIPHERS(ConfigurationProperties.SSL_CIPHERS, String.class, "any"), + SSL_CLIENT_PROTOCOLS(ConfigurationProperties.SSL_CLIENT_PROTOCOLS, String.class, ""), SSL_CLUSTER_ALIAS(ConfigurationProperties.SSL_CLUSTER_ALIAS, String.class), SSL_DEFAULT_ALIAS(ConfigurationProperties.SSL_DEFAULT_ALIAS, String.class), + SSL_ENABLED_COMPONENTS(ConfigurationProperties.SSL_ENABLED_COMPONENTS, String.class, "all"), + SSL_ENDPOINT_IDENTIFICATION_ENABLED(ConfigurationProperties.SSL_ENDPOINT_IDENTIFICATION_ENABLED, Boolean.class, false), SSL_GATEWAY_ALIAS(ConfigurationProperties.SSL_GATEWAY_ALIAS, String.class), SSL_JMX_ALIAS(ConfigurationProperties.SSL_JMX_ALIAS, String.class), - SSL_LOCATOR_ALIAS(ConfigurationProperties.SSL_LOCATOR_ALIAS, String.class), - SSL_PARAMETER_EXTENSION(ConfigurationProperties.SSL_PARAMETER_EXTENSION, String.class), - SSL_SERVER_ALIAS(ConfigurationProperties.SSL_SERVER_ALIAS, String.class), - SSL_WEB_ALIAS(ConfigurationProperties.SSL_WEB_ALIAS, String.class), - SSL_WEB_SERVICE_REQUIRE_AUTHENTICATION(ConfigurationProperties.SSL_WEB_SERVICE_REQUIRE_AUTHENTICATION, Boolean.class, false), SSL_KEYSTORE(ConfigurationProperties.SSL_KEYSTORE, String.class), SSL_KEYSTORE_PASSWORD(ConfigurationProperties.SSL_KEYSTORE_PASSWORD, String.class), SSL_KEYSTORE_TYPE(ConfigurationProperties.SSL_KEYSTORE_TYPE, String.class, "JKS"), + SSL_LOCATOR_ALIAS(ConfigurationProperties.SSL_LOCATOR_ALIAS, String.class), + SSL_PARAMETER_EXTENSION(ConfigurationProperties.SSL_PARAMETER_EXTENSION, String.class), SSL_PROTOCOLS(ConfigurationProperties.SSL_PROTOCOLS, String.class, "any"), + SSL_REQUIRE_AUTHENTICATION(ConfigurationProperties.SSL_REQUIRE_AUTHENTICATION, Boolean.class, true), + SSL_SERVER_ALIAS(ConfigurationProperties.SSL_SERVER_ALIAS, String.class), + SSL_SERVER_PROTOCOLS(ConfigurationProperties.SSL_SERVER_PROTOCOLS, String.class, ""), SSL_TRUSTSTORE(ConfigurationProperties.SSL_TRUSTSTORE, String.class), SSL_TRUSTSTORE_PASSWORD(ConfigurationProperties.SSL_TRUSTSTORE_PASSWORD, String.class), SSL_TRUSTSTORE_TYPE(ConfigurationProperties.SSL_TRUSTSTORE_TYPE, String.class, "JKS"), SSL_USE_DEFAULT_CONTEXT(ConfigurationProperties.SSL_USE_DEFAULT_CONTEXT, Boolean.class, false), + SSL_WEB_ALIAS(ConfigurationProperties.SSL_WEB_ALIAS, String.class), + SSL_WEB_SERVICE_REQUIRE_AUTHENTICATION(ConfigurationProperties.SSL_WEB_SERVICE_REQUIRE_AUTHENTICATION, Boolean.class, false), START_DEV_REST_API(ConfigurationProperties.START_DEV_REST_API, Boolean.class, false), START_LOCATOR(ConfigurationProperties.START_LOCATOR, Boolean.class), STATISTIC_ARCHIVE_FILE(ConfigurationProperties.STATISTIC_ARCHIVE_FILE, File.class), diff --git a/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/EnableSsl.java b/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/EnableSsl.java index 9570d399..511c4c6f 100644 --- a/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/EnableSsl.java +++ b/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/EnableSsl.java @@ -65,6 +65,18 @@ public @interface EnableSsl { */ String[] ciphers() default { "any" }; + /** + * Configures a list of the SSL protocols to enable on the client-side of the SSL connection. + * + * The protocols listed must be supported by the available providers. + * + * Defaults to {@literal empty}. + * + * Use the {@literal spring.data.gemfire.security.ssl.client.protocols} property + * in {@literal application.properties}. + */ + String[] clientProtocols() default {}; + /** * Configures the Pivotal GemFire/Apache Geode components for which SSL will be enabled. * @@ -171,6 +183,18 @@ public @interface EnableSsl { */ boolean requireAuthentication() default true; + /** + * Configures a list of the SSL protocols to enable on the server-side of the SSL connection. + * + * The protocols listed must be supported by the available providers. + * + * Defaults to {@literal empty}. + * + * Use the {@literal spring.data.gemfire.security.ssl.server.protocols} property + * in {@literal application.properties}. + */ + String[] serverProtocols() default {}; + /** * Pathname to the truststore used for SSL communications. * diff --git a/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/SslConfiguration.java b/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/SslConfiguration.java index 3ae83e60..82fb8f20 100644 --- a/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/SslConfiguration.java +++ b/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/SslConfiguration.java @@ -44,6 +44,8 @@ import org.springframework.util.StringUtils; */ public class SslConfiguration extends EmbeddedServiceConfigurationSupport { + private static final String SPACE_DELIMITER = " "; + /** * Returns the {@link EnableSsl} {@link Annotation} {@link Class type}. * @@ -73,6 +75,11 @@ public class SslConfiguration extends EmbeddedServiceConfigurationSupport { resolveProperty(sslProperty("ciphers"), StringUtils.arrayToCommaDelimitedString(annotationAttributes.getStringArray("ciphers")))) + .setProperty("ssl-client-protocols", + resolveProperty(sslProperty("client.protocols"), + StringUtils.arrayToDelimitedString(annotationAttributes.getStringArray("clientProtocols"), + SPACE_DELIMITER))) + .setPropertyIfNotDefault("ssl-default-alias", resolveProperty(sslProperty("certificate.alias.default"), annotationAttributes.getString("defaultCertificateAlias")), "") @@ -101,6 +108,11 @@ public class SslConfiguration extends EmbeddedServiceConfigurationSupport { resolveProperty(sslProperty("require-authentication"), annotationAttributes.getBoolean("requireAuthentication"))) + .setProperty("ssl-server-protocols", + resolveProperty(sslProperty("server.protocols"), + StringUtils.arrayToDelimitedString(annotationAttributes.getStringArray("serverProtocols"), + SPACE_DELIMITER))) + .setProperty("ssl-truststore", resolveProperty(sslProperty("truststore"), annotationAttributes.getString("truststore"))) diff --git a/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/EnableSslConfigurationUnitTests.java b/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/EnableSslConfigurationUnitTests.java index 0fcf4d71..d81e988e 100644 --- a/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/EnableSslConfigurationUnitTests.java +++ b/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/EnableSslConfigurationUnitTests.java @@ -79,6 +79,7 @@ public class EnableSslConfigurationUnitTests extends SpringApplicationContextInt assertThat(gemfireProperties).isNotNull(); assertThat(gemfireProperties.getProperty("ssl-ciphers")).isEqualTo("FISH,Scream,SEAL,SNOW"); + assertThat(gemfireProperties.getProperty("ssl-client-protocols")).isEqualTo("ONE TWO"); assertThat(gemfireProperties.getProperty("ssl-enabled-components")).isEqualTo("server,gateway"); assertThat(gemfireProperties.getProperty("ssl-default-alias")).isEqualTo("TestCert"); assertThat(gemfireProperties.getProperty("ssl-gateway-alias")).isEqualTo("WanCert"); @@ -88,6 +89,7 @@ public class EnableSslConfigurationUnitTests extends SpringApplicationContextInt assertThat(gemfireProperties.getProperty("ssl-keystore-type")).isEqualTo("JKS"); assertThat(gemfireProperties.getProperty("ssl-protocols")).isEqualTo("TCP/IP,HTTP"); assertThat(gemfireProperties.getProperty("ssl-require-authentication")).isEqualTo("true"); + assertThat(gemfireProperties.getProperty("ssl-server-protocols")).isEqualTo("TWO FOUR"); assertThat(gemfireProperties.getProperty("ssl-truststore")).isEqualTo("/path/to/truststore.jks"); assertThat(gemfireProperties.getProperty("ssl-truststore-password")).isEqualTo("p@55w0rd!"); assertThat(gemfireProperties.getProperty("ssl-truststore-type")).isEqualTo("PKCS11"); @@ -99,17 +101,19 @@ public class EnableSslConfigurationUnitTests extends SpringApplicationContextInt public void sslPropertyBasedConfigurationIsCorrect() { PropertySource testPropertySource = new MockPropertySource("TestPropertySource") - .withProperty("spring.data.gemfire.security.ssl.ciphers", "Scream, SEAL, SNOW") - .withProperty("spring.data.gemfire.security.ssl.components", "locator, server, gateway") .withProperty("spring.data.gemfire.security.ssl.certificate.alias.default", "MockCert") .withProperty("spring.data.gemfire.security.ssl.certificate.alias.gateway", "WanCert") .withProperty("spring.data.gemfire.security.ssl.certificate.alias.server", "ServerCert") + .withProperty("spring.data.gemfire.security.ssl.ciphers", "Scream, SEAL, SNOW") + .withProperty("spring.data.gemfire.security.ssl.client.protocols", "ONE, TWO") + .withProperty("spring.data.gemfire.security.ssl.components", "locator, server, gateway") .withProperty("spring.data.gemfire.security.ssl.enable-endpoint-identification", "true") .withProperty("spring.data.gemfire.security.ssl.keystore", "~/test/app/keystore.jks") .withProperty("spring.data.gemfire.security.ssl.keystore.password", "0p3nS@y5M3") .withProperty("spring.data.gemfire.security.ssl.keystore.type", "R2D2") .withProperty("spring.data.gemfire.security.ssl.protocols", "IP, TCP/IP, UDP") .withProperty("spring.data.gemfire.security.ssl.require-authentication", "false") + .withProperty("spring.data.gemfire.security.ssl.server.protocols", "TWO, FOUR") .withProperty("spring.data.gemfire.security.ssl.truststore", "relative/path/to/trusted.keystore") .withProperty("spring.data.gemfire.security.ssl.truststore.password", "kn0ckKn0ck") .withProperty("spring.data.gemfire.security.ssl.truststore.type", "C3PO") @@ -135,6 +139,7 @@ public class EnableSslConfigurationUnitTests extends SpringApplicationContextInt assertThat(gemfireProperties).isNotNull(); assertThat(gemfireProperties.getProperty("ssl-ciphers")).isEqualTo("Scream, SEAL, SNOW"); + assertThat(gemfireProperties.getProperty("ssl-client-protocols")).isEqualTo("ONE, TWO"); assertThat(sslEnabledComponents).isEqualTo("gateway,locator,server"); assertThat(gemfireProperties.getProperty("ssl-default-alias")).isEqualTo("MockCert"); assertThat(gemfireProperties.getProperty("ssl-gateway-alias")).isEqualTo("WanCert"); @@ -145,6 +150,7 @@ public class EnableSslConfigurationUnitTests extends SpringApplicationContextInt assertThat(gemfireProperties.getProperty("ssl-keystore-type")).isEqualTo("R2D2"); assertThat(gemfireProperties.getProperty("ssl-protocols")).isEqualTo("IP, TCP/IP, UDP"); assertThat(gemfireProperties.getProperty("ssl-require-authentication")).isEqualTo("false"); + assertThat(gemfireProperties.getProperty("ssl-server-protocols")).isEqualTo("TWO, FOUR"); assertThat(gemfireProperties.getProperty("ssl-truststore")).isEqualTo("relative/path/to/trusted.keystore"); assertThat(gemfireProperties.getProperty("ssl-truststore-password")).isEqualTo("kn0ckKn0ck"); assertThat(gemfireProperties.getProperty("ssl-truststore-type")).isEqualTo("C3PO"); @@ -156,6 +162,7 @@ public class EnableSslConfigurationUnitTests extends SpringApplicationContextInt @ClientCacheApplication(logLevel = "error") @EnableSsl( ciphers = { "FISH", "Scream", "SEAL", "SNOW" }, + clientProtocols = { "ONE", "TWO" }, components = { EnableSsl.Component.SERVER, EnableSsl.Component.GATEWAY }, componentCertificateAliases = { @EnableSsl.ComponentAlias(component = EnableSsl.Component.GATEWAY, alias = "WanCert") @@ -165,6 +172,7 @@ public class EnableSslConfigurationUnitTests extends SpringApplicationContextInt keystore = "/path/to/keystore.jks", keystorePassword = "s3cr3t!", protocols = { "TCP/IP", "HTTP" }, + serverProtocols = { "TWO", "FOUR" }, truststore = "/path/to/truststore.jks", truststorePassword = "p@55w0rd!", truststoreType = "PKCS11", @@ -173,8 +181,8 @@ public class EnableSslConfigurationUnitTests extends SpringApplicationContextInt ) static class SslAnnotationBasedConfiguration { } + @ClientCacheApplication @EnableGemFireMockObjects - @ClientCacheApplication(logLevel = "error") @EnableSsl static class SslPropertyBasedConfiguration { }