blob: 68d94c1bf63024f189d5e3e971d8e86c6cd9b0ce [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.geode.rest.internal.web.controllers;
import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_SSL_CIPHERS;
import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_SSL_ENABLED;
import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_SSL_KEYSTORE;
import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_SSL_KEYSTORE_PASSWORD;
import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_SSL_KEYSTORE_TYPE;
import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_SSL_PROTOCOLS;
import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_SSL_REQUIRE_AUTHENTICATION;
import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_SSL_TRUSTSTORE;
import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_SSL_TRUSTSTORE_PASSWORD;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_CIPHERS;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_ENABLED_COMPONENTS;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE_PASSWORD;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE_TYPE;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_PROTOCOLS;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_REQUIRE_AUTHENTICATION;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE_PASSWORD;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_WEB_ALIAS;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_WEB_SERVICE_REQUIRE_AUTHENTICATION;
import static org.apache.geode.test.util.ResourceUtils.createTempFileFromResource;
import static org.junit.Assert.assertEquals;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyStore;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
import javax.net.ssl.SSLContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.geode.internal.security.SecurableCommunicationChannel;
import org.apache.geode.test.dunit.rules.ClientVM;
import org.apache.geode.test.dunit.rules.ClusterStartupRule;
import org.apache.geode.test.dunit.rules.DistributedRestoreSystemProperties;
import org.apache.geode.test.dunit.rules.MemberVM;
import org.apache.geode.test.junit.categories.RestAPITest;
/**
* @since GemFire 8.0
*/
@Category(RestAPITest.class)
public class RestAPIsWithSSLDUnitTest {
private static final String PEOPLE_REGION_NAME = "People";
private static final String INVALID_CLIENT_ALIAS = "INVALID_CLIENT_ALIAS";
private String urlContext = "/geode";
@Rule
public ClusterStartupRule cluster = new ClusterStartupRule();
@Rule
public DistributedRestoreSystemProperties restoreSystemProperties =
new DistributedRestoreSystemProperties();
private MemberVM server;
private ClientVM client;
private String restEndpoint;
private static File findTrustedJKSWithSingleEntry() {
return new File(
createTempFileFromResource(RestAPIsWithSSLDUnitTest.class, "/ssl/trusted.keystore")
.getAbsolutePath());
}
private static File findTrustStore(Properties props) {
String propertyValue = props.getProperty(SSL_TRUSTSTORE);
if (StringUtils.isEmpty(propertyValue)) {
propertyValue = props.getProperty(HTTP_SERVICE_SSL_TRUSTSTORE);
}
if (StringUtils.isEmpty(propertyValue)) {
propertyValue = props.getProperty(HTTP_SERVICE_SSL_KEYSTORE);
}
return new File(propertyValue);
}
private static File findKeyStoreJKS(Properties props) {
String propertyValue = props.getProperty(SSL_KEYSTORE);
if (StringUtils.isEmpty(propertyValue)) {
propertyValue = props.getProperty(HTTP_SERVICE_SSL_KEYSTORE);
}
return new File(propertyValue);
}
private void startClusterWithSSL(final Properties sslProperties)
throws Exception {
int locatorPort = ClusterStartupRule.getDUnitLocatorPort();
server = cluster.startServerVM(0, s -> s.withRestService()
.withProperties(sslProperties)
.withConnectionToLocator(locatorPort)
.withRegion(RegionShortcut.REPLICATE, PEOPLE_REGION_NAME));
client = cluster.startClientVM(1, c -> c.withLocatorConnection(locatorPort)
.withCacheSetup(cf -> cf.setPdxReadSerialized(true)));
client.invoke(() -> {
ClientCache clientCache = ClusterStartupRule.getClientCache();
Region region = clientCache.createClientRegionFactory(ClientRegionShortcut.PROXY)
.create(PEOPLE_REGION_NAME);
// put person object
region.put("1", new Person(101L, "Mithali", "Dorai", "Raj", new Date(), Gender.FEMALE));
region.put("2", new Person(102L, "Sachin", "Ramesh", "Tendulkar", new Date(), Gender.MALE));
region.put("3", new Person(103L, "Saurabh", "Baburav", "Ganguly", new Date(), Gender.MALE));
region.put("4", new Person(104L, "Rahul", "subrymanyam", "Dravid", new Date(), Gender.MALE));
region.put("5",
new Person(105L, "Jhulan", "Chidambaram", "Goswami", new Date(), Gender.FEMALE));
Map<String, Object> userMap = new HashMap<String, Object>();
userMap.put("6", new Person(101L, "Rahul", "Rajiv", "Gndhi", new Date(), Gender.MALE));
userMap.put("7", new Person(102L, "Narendra", "Damodar", "Modi", new Date(), Gender.MALE));
userMap.put("8", new Person(103L, "Atal", "Bihari", "Vajpayee", new Date(), Gender.MALE));
userMap.put("9", new Person(104L, "Soniya", "Rajiv", "Gandhi", new Date(), Gender.FEMALE));
userMap.put("10",
new Person(104L, "Priyanka", "Robert", "Gandhi", new Date(), Gender.FEMALE));
userMap.put("11", new Person(104L, "Murali", "Manohar", "Joshi", new Date(), Gender.MALE));
userMap.put("12",
new Person(104L, "Lalkrishna", "Parmhansh", "Advani", new Date(), Gender.MALE));
userMap.put("13", new Person(104L, "Shushma", "kumari", "Swaraj", new Date(), Gender.FEMALE));
userMap.put("14", new Person(104L, "Arun", "raman", "jetly", new Date(), Gender.MALE));
userMap.put("15", new Person(104L, "Amit", "kumar", "shah", new Date(), Gender.MALE));
userMap.put("16", new Person(104L, "Shila", "kumari", "Dixit", new Date(), Gender.FEMALE));
region.putAll(userMap);
clientCache.getLogger().info("Gemfire Cache Client: Puts successfully done");
});
restEndpoint = "https://localhost:" + server.getHttpPort() + urlContext + "/v1";
}
private static CloseableHttpClient getSSLBasedHTTPClient(Properties properties) throws Exception {
KeyStore clientKeys = KeyStore.getInstance("JKS");
File keystoreJKSForPath = findKeyStoreJKS(properties);
clientKeys.load(new FileInputStream(keystoreJKSForPath), "password".toCharArray());
KeyStore clientTrust = KeyStore.getInstance("JKS");
File trustStoreJKSForPath = findTrustStore(properties);
clientTrust.load(new FileInputStream(trustStoreJKSForPath), "password".toCharArray());
// this is needed
SSLContextBuilder custom = SSLContexts.custom();
SSLContextBuilder sslContextBuilder =
custom.loadTrustMaterial(clientTrust, new TrustSelfSignedStrategy());
SSLContext sslcontext = sslContextBuilder
.loadKeyMaterial(clientKeys, "password".toCharArray(), (aliases, socket) -> {
if (aliases.size() == 1) {
return aliases.keySet().stream().findFirst().get();
}
if (!StringUtils.isEmpty(properties.getProperty(INVALID_CLIENT_ALIAS))) {
return properties.getProperty(INVALID_CLIENT_ALIAS);
} else {
return properties.getProperty(SSL_WEB_ALIAS);
}
}).build();
// Host checking is disabled here, as tests might run on multiple hosts and
// host entries can not be assumed
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
sslcontext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
return HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
}
private void validateConnection(Properties properties) throws Exception {
HttpGet get = new HttpGet(restEndpoint + "/People/1");
get.addHeader("Content-Type", "application/json");
get.addHeader("Accept", "application/json");
CloseableHttpClient httpclient = getSSLBasedHTTPClient(properties);
CloseableHttpResponse response = httpclient.execute(get);
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
StringBuilder str = new StringBuilder();
while ((line = reader.readLine()) != null) {
str.append(line);
}
ObjectMapper mapper = new ObjectMapper();
JsonNode json = mapper.readTree(str.toString());
assertEquals(json.get("id").asInt(), 101);
assertEquals(json.get("firstName").asText(), "Mithali");
assertEquals(json.get("middleName").asText(), "Dorai");
assertEquals(json.get("lastName").asText(), "Raj");
assertEquals(json.get("gender").asText(), Gender.FEMALE.name());
}
@Test
public void testSimpleSSL() throws Exception {
Properties props = new Properties();
props.setProperty(SSL_KEYSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_TRUSTSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(SSL_TRUSTSTORE_PASSWORD, "password");
props.setProperty(SSL_KEYSTORE_TYPE, "JKS");
props.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant());
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testSimpleSSLWithMultiKey_KeyStore() throws Exception {
Properties props = new Properties();
props.setProperty(SSL_KEYSTORE,
createTempFileFromResource(getClass(), "/org/apache/geode/internal/net/multiKey.jks")
.getAbsolutePath());
props.setProperty(SSL_TRUSTSTORE,
createTempFileFromResource(getClass(),
"/org/apache/geode/internal/net/multiKeyTrust.jks").getAbsolutePath());
props.setProperty(SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(SSL_TRUSTSTORE_PASSWORD, "password");
props.setProperty(SSL_KEYSTORE_TYPE, "JKS");
props.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant());
props.setProperty(SSL_WEB_ALIAS, "httpservicekey");
props.setProperty(SSL_WEB_SERVICE_REQUIRE_AUTHENTICATION, "true");
startClusterWithSSL(props);
validateConnection(props);
}
@Test(expected = RuntimeException.class)
public void testSimpleSSLWithMultiKey_KeyStore_WithInvalidClientKey() throws Exception {
Properties props = new Properties();
props.setProperty(SSL_KEYSTORE,
createTempFileFromResource(getClass(), "/org/apache/geode/internal/net/multiKey.jks")
.getAbsolutePath());
props.setProperty(SSL_TRUSTSTORE,
createTempFileFromResource(getClass(),
"/org/apache/geode/internal/net/multiKeyTrust.jks").getAbsolutePath());
props.setProperty(SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(SSL_TRUSTSTORE_PASSWORD, "password");
props.setProperty(SSL_KEYSTORE_TYPE, "JKS");
props.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant());
props.setProperty(SSL_WEB_SERVICE_REQUIRE_AUTHENTICATION, "true");
props.setProperty(SSL_WEB_ALIAS, "httpservicekey");
props.setProperty(INVALID_CLIENT_ALIAS, "someAlias");
startClusterWithSSL(props);
}
@Test
public void testSSLWithoutKeyStoreType() throws Exception {
Properties props = new Properties();
props.setProperty(SSL_KEYSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_TRUSTSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(SSL_TRUSTSTORE_PASSWORD, "password");
props.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant());
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testSSLWithSSLProtocol() throws Exception {
Properties props = new Properties();
props.setProperty(SSL_KEYSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_TRUSTSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(SSL_TRUSTSTORE_PASSWORD, "password");
props.setProperty(SSL_KEYSTORE_TYPE, "JKS");
props.setProperty(SSL_PROTOCOLS, "SSL");
props.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant());
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testSSLWithTLSProtocol() throws Exception {
Properties props = new Properties();
props.setProperty(SSL_KEYSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_TRUSTSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(SSL_TRUSTSTORE_PASSWORD, "password");
props.setProperty(SSL_KEYSTORE_TYPE, "JKS");
props.setProperty(SSL_PROTOCOLS, "TLS");
props.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant());
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testSSLWithTLSv11Protocol() throws Exception {
Properties props = new Properties();
props.setProperty(SSL_KEYSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_TRUSTSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(SSL_TRUSTSTORE_PASSWORD, "password");
props.setProperty(SSL_KEYSTORE_TYPE, "JKS");
props.setProperty(SSL_PROTOCOLS, "TLSv1.1");
props.setProperty(SSL_CIPHERS, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA");
props.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant());
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testSSLWithTLSv12Protocol() throws Exception {
Properties props = new Properties();
props.setProperty(SSL_KEYSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_TRUSTSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(SSL_TRUSTSTORE_PASSWORD, "password");
props.setProperty(SSL_KEYSTORE_TYPE, "JKS");
props.setProperty(SSL_PROTOCOLS, "TLSv1.2");
props.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant());
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testWithMultipleProtocol() throws Exception {
Properties props = new Properties();
props.setProperty(SSL_KEYSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_TRUSTSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(SSL_TRUSTSTORE_PASSWORD, "password");
props.setProperty(SSL_KEYSTORE_TYPE, "JKS");
props.setProperty(SSL_PROTOCOLS, "SSL,TLSv1.2");
props.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant());
startClusterWithSSL(props);
validateConnection(props);
}
private List<String> getRSACiphers() throws Exception {
SSLContext ssl = SSLContext.getInstance("TLSv1.2");
ssl.init(null, null, new java.security.SecureRandom());
String[] cipherSuites = ssl.getSocketFactory().getSupportedCipherSuites();
return Arrays.stream(cipherSuites).filter(c -> c.contains("RSA")).collect(Collectors.toList());
}
@Test
public void testSSLWithCipherSuite() throws Exception {
System.setProperty("javax.net.debug", "ssl,handshake");
Properties props = new Properties();
props.setProperty(SSL_KEYSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_TRUSTSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(SSL_TRUSTSTORE_PASSWORD, "password");
props.setProperty(SSL_KEYSTORE_TYPE, "JKS");
props.setProperty(SSL_PROTOCOLS, "TLSv1.2");
props.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant());
// This is the safest in terms of support across various JDK releases
List<String> rsaCiphers = getRSACiphers();
props.setProperty(SSL_CIPHERS, rsaCiphers.get(0));
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testSSLWithMultipleCipherSuite() throws Exception {
System.setProperty("javax.net.debug", "ssl,handshake");
Properties props = new Properties();
props.setProperty(SSL_KEYSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_TRUSTSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(SSL_TRUSTSTORE_PASSWORD, "password");
props.setProperty(SSL_KEYSTORE_TYPE, "JKS");
props.setProperty(SSL_PROTOCOLS, "TLSv1.2");
props.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant());
// This is the safest in terms of support across various JDK releases
List<String> rsaCiphers = getRSACiphers();
props.setProperty(SSL_CIPHERS, rsaCiphers.get(0) + "," + rsaCiphers.get(1));
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testSSLWithMultipleCipherSuiteLegacy() throws Exception {
System.setProperty("javax.net.debug", "ssl,handshake");
Properties props = new Properties();
props.setProperty(HTTP_SERVICE_SSL_ENABLED, "true");
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE,
findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(HTTP_SERVICE_SSL_PROTOCOLS, "TLSv1.2");
// This is the safest in terms of support across various JDK releases
List<String> rsaCiphers = getRSACiphers();
props.setProperty(SSL_CIPHERS, rsaCiphers.get(0) + "," + rsaCiphers.get(1));
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testMutualAuthentication() throws Exception {
Properties props = new Properties();
props.setProperty(SSL_KEYSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(SSL_TRUSTSTORE, findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(SSL_TRUSTSTORE_PASSWORD, "password");
props.setProperty(SSL_KEYSTORE_TYPE, "JKS");
props.setProperty(SSL_PROTOCOLS, "SSL");
props.setProperty(SSL_REQUIRE_AUTHENTICATION, "true");
props.setProperty(SSL_WEB_SERVICE_REQUIRE_AUTHENTICATION, "true");
props.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant());
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testSimpleSSLLegacy() throws Exception {
Properties props = new Properties();
props.setProperty(HTTP_SERVICE_SSL_ENABLED, "true");
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE,
findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE_TYPE, "JKS");
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testSSLWithoutKeyStoreTypeLegacy() throws Exception {
Properties props = new Properties();
props.setProperty(HTTP_SERVICE_SSL_ENABLED, "true");
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE,
findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD, "password");
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testSSLWithSSLProtocolLegacy() throws Exception {
Properties props = new Properties();
props.setProperty(HTTP_SERVICE_SSL_ENABLED, "true");
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE,
findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(HTTP_SERVICE_SSL_PROTOCOLS, "SSL");
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testSSLWithTLSProtocolLegacy() throws Exception {
Properties props = new Properties();
props.setProperty(HTTP_SERVICE_SSL_ENABLED, "true");
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE,
findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(HTTP_SERVICE_SSL_PROTOCOLS, "TLS");
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testSSLWithTLSv11ProtocolLegacy() throws Exception {
Properties props = new Properties();
props.setProperty(HTTP_SERVICE_SSL_ENABLED, "true");
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE,
findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(HTTP_SERVICE_SSL_PROTOCOLS, "TLSv1.1");
props.setProperty(HTTP_SERVICE_SSL_CIPHERS, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA");
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testSSLWithTLSv12ProtocolLegacy() throws Exception {
Properties props = new Properties();
props.setProperty(HTTP_SERVICE_SSL_ENABLED, "true");
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE,
findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(HTTP_SERVICE_SSL_PROTOCOLS, "TLSv1.2");
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testWithMultipleProtocolLegacy() throws Exception {
Properties props = new Properties();
props.setProperty(HTTP_SERVICE_SSL_ENABLED, "true");
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE,
findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(HTTP_SERVICE_SSL_PROTOCOLS, "SSL,TLSv1.2");
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testSSLWithCipherSuiteLegacy() throws Exception {
System.setProperty("javax.net.debug", "ssl");
Properties props = new Properties();
props.setProperty(HTTP_SERVICE_SSL_ENABLED, "true");
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE,
findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(HTTP_SERVICE_SSL_PROTOCOLS, "TLSv1.2");
SSLContext ssl = SSLContext.getInstance("TLSv1.2");
ssl.init(null, null, new java.security.SecureRandom());
String[] cipherSuites = ssl.getSocketFactory().getSupportedCipherSuites();
String rsaCipher = Arrays.stream(cipherSuites).filter(c -> c.contains("RSA")).findFirst().get();
props.setProperty(HTTP_SERVICE_SSL_CIPHERS, rsaCipher);
startClusterWithSSL(props);
validateConnection(props);
}
@Test
public void testMutualAuthenticationLegacy() throws Exception {
Properties props = new Properties();
props.setProperty(HTTP_SERVICE_SSL_ENABLED, "true");
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE,
findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD, "password");
props.setProperty(HTTP_SERVICE_SSL_PROTOCOLS, "SSL");
props.setProperty(HTTP_SERVICE_SSL_REQUIRE_AUTHENTICATION, "true");
props.setProperty(HTTP_SERVICE_SSL_TRUSTSTORE,
findTrustedJKSWithSingleEntry().getCanonicalPath());
props.setProperty(HTTP_SERVICE_SSL_TRUSTSTORE_PASSWORD, "password");
startClusterWithSSL(props);
validateConnection(props);
}
}