You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2019/11/25 18:52:55 UTC

[tinkerpop] 03/04: Move SSL tests to their own test class

This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch travis-fix
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 00c5d1aafe527e4a65137164a1ad3a3a21fec7ed
Author: stephen <sp...@gmail.com>
AuthorDate: Fri Nov 15 08:44:27 2019 -0500

    Move SSL tests to their own test class
---
 .../gremlin/server/GremlinServerIntegrateTest.java | 309 -------------------
 .../server/GremlinServerSslIntegrateTest.java      | 340 +++++++++++++++++++++
 2 files changed, 340 insertions(+), 309 deletions(-)

diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
index 0510328..cbb1f1f 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
@@ -18,12 +18,6 @@
  */
 package org.apache.tinkerpop.gremlin.server;
 
-import io.netty.handler.ssl.ClientAuth;
-import io.netty.handler.ssl.SslContext;
-import io.netty.handler.ssl.SslContextBuilder;
-import io.netty.handler.ssl.SslProvider;
-import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
-import io.netty.handler.ssl.util.SelfSignedCertificate;
 import org.apache.commons.configuration.BaseConfiguration;
 import org.apache.commons.configuration.Configuration;
 import org.apache.commons.lang3.exception.ExceptionUtils;
@@ -67,7 +61,6 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import java.lang.reflect.Field;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -104,10 +97,6 @@ import static org.junit.Assert.fail;
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegrationTest {
-    private static final String PEM_SERVER_KEY = "src/test/resources/server.key.pk8";
-    private static final String PEM_SERVER_CRT = "src/test/resources/server.crt";
-    private static final String PEM_CLIENT_KEY = "src/test/resources/client.key.pk8";
-    private static final String PEM_CLIENT_CRT = "src/test/resources/client.crt";
     private Level previousLogLevel;
 
     private Log4jRecordingAppender recordingAppender = null;
@@ -179,103 +168,6 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
             case "shouldBatchResultsByTwos":
                 settings.resultIterationBatchSize = 2;
                 break;
-            case "shouldEnableSsl":
-            case "shouldEnableSslButFailIfClientConnectsWithoutIt":
-                settings.ssl = new Settings.SslSettings();
-                settings.ssl.enabled = true;
-                settings.ssl.keyStore = JKS_SERVER_KEY;
-                settings.ssl.keyStorePassword = KEY_PASS;
-                settings.ssl.keyStoreType = KEYSTORE_TYPE_JKS;
-                break;
-            case "shouldEnableSslWithSslContextProgrammaticallySpecified":
-                settings.ssl = new Settings.SslSettings();
-                settings.ssl.enabled = true;
-                settings.ssl.overrideSslContext(createServerSslContext());
-                break;
-            case "shouldEnableSslAndClientCertificateAuthWithLegacyPem":
-                settings.ssl = new Settings.SslSettings();
-                settings.ssl.enabled = true;
-                settings.ssl.needClientAuth = ClientAuth.REQUIRE;
-                settings.ssl.keyCertChainFile = PEM_SERVER_CRT;
-                settings.ssl.keyFile = PEM_SERVER_KEY;
-                settings.ssl.keyPassword = KEY_PASS;
-                // Trust the client
-                settings.ssl.trustCertChainFile = PEM_CLIENT_CRT;
-                break;
-            case "shouldEnableSslAndClientCertificateAuthAndFailWithoutCertWithLegacyPem":
-                settings.ssl = new Settings.SslSettings();
-                settings.ssl.enabled = true;
-                settings.ssl.needClientAuth = ClientAuth.REQUIRE;
-                settings.ssl.keyCertChainFile = PEM_SERVER_CRT;
-                settings.ssl.keyFile = PEM_SERVER_KEY;
-                settings.ssl.keyPassword = KEY_PASS;
-                // Trust the client
-                settings.ssl.trustCertChainFile = PEM_CLIENT_CRT;
-                break;
-            case "shouldEnableSslAndClientCertificateAuthAndFailWithoutTrustedClientCertWithLegacyPem":
-                settings.ssl = new Settings.SslSettings();
-                settings.ssl.enabled = true;
-                settings.ssl.needClientAuth = ClientAuth.REQUIRE;
-                settings.ssl.keyCertChainFile = PEM_SERVER_CRT;
-                settings.ssl.keyFile = PEM_SERVER_KEY;
-                settings.ssl.keyPassword = KEY_PASS;
-                // Trust ONLY the server cert
-                settings.ssl.trustCertChainFile = PEM_SERVER_CRT;
-                break;
-            case "shouldEnableSslAndClientCertificateAuthWithPkcs12":
-                settings.ssl = new Settings.SslSettings();
-                settings.ssl.enabled = true;
-                settings.ssl.needClientAuth = ClientAuth.REQUIRE;
-                settings.ssl.keyStore = P12_SERVER_KEY;
-                settings.ssl.keyStorePassword = KEY_PASS;
-                settings.ssl.keyStoreType = KEYSTORE_TYPE_PKCS12;
-                settings.ssl.trustStore = P12_SERVER_TRUST;
-                settings.ssl.trustStorePassword = KEY_PASS;
-                break;
-            case "shouldEnableSslAndClientCertificateAuth":
-                settings.ssl = new Settings.SslSettings();
-                settings.ssl.enabled = true;
-                settings.ssl.needClientAuth = ClientAuth.REQUIRE;
-                settings.ssl.keyStore = JKS_SERVER_KEY;
-                settings.ssl.keyStorePassword = KEY_PASS;
-                settings.ssl.keyStoreType = KEYSTORE_TYPE_JKS;
-                settings.ssl.trustStore = JKS_SERVER_TRUST;
-                settings.ssl.trustStorePassword = KEY_PASS;
-                break;
-            case "shouldEnableSslAndClientCertificateAuthAndFailWithoutCert":
-                settings.ssl = new Settings.SslSettings();
-                settings.ssl.enabled = true;
-                settings.ssl.needClientAuth = ClientAuth.REQUIRE;
-                settings.ssl.keyStore = JKS_SERVER_KEY;
-                settings.ssl.keyStorePassword = KEY_PASS;
-                settings.ssl.keyStoreType = KEYSTORE_TYPE_JKS;
-                settings.ssl.trustStore = JKS_SERVER_TRUST;
-                settings.ssl.trustStorePassword = KEY_PASS;
-                break;
-            case "shouldEnableSslAndClientCertificateAuthAndFailWithoutTrustedClientCert":
-                settings.ssl = new Settings.SslSettings();
-                settings.ssl.enabled = true;
-                settings.ssl.needClientAuth = ClientAuth.REQUIRE;
-                settings.ssl.keyStore = JKS_SERVER_KEY;
-                settings.ssl.keyStorePassword = KEY_PASS;
-                settings.ssl.keyStoreType = KEYSTORE_TYPE_JKS;
-                break;
-            case "shouldEnableSslAndFailIfProtocolsDontMatch":
-                settings.ssl = new Settings.SslSettings();
-                settings.ssl.enabled = true;
-                settings.ssl.keyStore = JKS_SERVER_KEY;
-                settings.ssl.keyStorePassword = KEY_PASS;
-                settings.ssl.keyStoreType = KEYSTORE_TYPE_JKS;
-                settings.ssl.sslEnabledProtocols = Arrays.asList("TLSv1.1");
-                break;
-            case "shouldEnableSslAndFailIfCiphersDontMatch":
-                settings.ssl = new Settings.SslSettings();
-                settings.ssl.enabled = true;
-                settings.ssl.keyStore = JKS_SERVER_KEY;
-                settings.ssl.keyStorePassword = KEY_PASS;
-                settings.ssl.keyStoreType = KEYSTORE_TYPE_JKS;
-                settings.ssl.sslCipherSuites = Arrays.asList("TLS_DHE_RSA_WITH_AES_128_CBC_SHA");
-                break;
             case "shouldUseSimpleSandbox":
                 settings.scriptEngines.get("gremlin-groovy").plugins.put(GroovyCompilerGremlinPlugin.class.getName(), getScriptEngineConfForSimpleSandbox());
                 // remove the script because it isn't used in the test but also because it's not CompileStatic ready
@@ -317,18 +209,6 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
         return settings;
     }
 
-    private static SslContext createServerSslContext() {
-        final SslProvider provider = SslProvider.JDK;
-
-        try {
-            // this is not good for production - just testing
-            final SelfSignedCertificate ssc = new SelfSignedCertificate();
-            return SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).sslProvider(provider).build();
-        } catch (Exception ce) {
-            throw new RuntimeException("Couldn't setup self-signed certificate for test");
-        }
-    }
-
     private static Map<String, Object> getScriptEngineConfForSimpleSandbox() {
         final Map<String,Object> scriptEngineConf = new HashMap<>();
         scriptEngineConf.put("compilation", COMPILE_STATIC.name());
@@ -607,195 +487,6 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
     }
 
     @Test
-    public void shouldEnableSsl() {
-        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_SERVER_KEY).keyStorePassword(KEY_PASS).sslSkipCertValidation(true).create();
-        final Client client = cluster.connect();
-
-        try {
-            // this should return "nothing" - there should be no exception
-            assertEquals("test", client.submit("'test'").one().getString());
-        } finally {
-            cluster.close();
-        }
-    }
-
-    @Test
-    public void shouldEnableSslWithSslContextProgrammaticallySpecified() throws Exception {
-        // just for testing - this is not good for production use
-        final SslContextBuilder builder = SslContextBuilder.forClient();
-        builder.trustManager(InsecureTrustManagerFactory.INSTANCE);
-        builder.sslProvider(SslProvider.JDK);
-
-        final Cluster cluster = TestClientFactory.build().enableSsl(true).sslContext(builder.build()).create();
-        final Client client = cluster.connect();
-
-        try {
-            // this should return "nothing" - there should be no exception
-            assertEquals("test", client.submit("'test'").one().getString());
-        } finally {
-            cluster.close();
-        }
-    }
-
-    @Test
-    public void shouldEnableSslButFailIfClientConnectsWithoutIt() {
-        final Cluster cluster = TestClientFactory.build().enableSsl(false).create();
-        final Client client = cluster.connect();
-
-        try {
-            client.submit("'test'").one();
-            fail("Should throw exception because ssl is enabled on the server but not on client");
-        } catch(Exception x) {
-            final Throwable root = ExceptionUtils.getRootCause(x);
-            assertThat(root, instanceOf(TimeoutException.class));
-        } finally {
-            cluster.close();
-        }
-    }
-
-    @Test
-    public void shouldEnableSslAndClientCertificateAuthWithLegacyPem() {
-        final Cluster cluster = TestClientFactory.build().enableSsl(true)
-                .keyCertChainFile(PEM_CLIENT_CRT).keyFile(PEM_CLIENT_KEY)
-                .keyPassword(KEY_PASS).trustCertificateChainFile(PEM_SERVER_CRT).create();
-        final Client client = cluster.connect();
-
-        try {
-            assertEquals("test", client.submit("'test'").one().getString());
-        } finally {
-            cluster.close();
-        }
-    }
-
-    @Test
-    public void shouldEnableSslAndClientCertificateAuthAndFailWithoutCertWithLegacyPem() {
-        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_SERVER_KEY).keyStorePassword(KEY_PASS).sslSkipCertValidation(true).create();
-        final Client client = cluster.connect();
-
-        try {
-            client.submit("'test'").one();
-            fail("Should throw exception because ssl client auth is enabled on the server but client does not have a cert");
-        } catch(Exception x) {
-            final Throwable root = ExceptionUtils.getRootCause(x);
-            assertThat(root, instanceOf(TimeoutException.class));
-        } finally {
-            cluster.close();
-        }
-    }
-
-    @Test
-    public void shouldEnableSslAndClientCertificateAuthAndFailWithoutTrustedClientCertWithLegacyPem() {
-        final Cluster cluster = TestClientFactory.build().enableSsl(true)
-                .keyCertChainFile(PEM_CLIENT_CRT).keyFile(PEM_CLIENT_KEY)
-                .keyPassword(KEY_PASS).trustCertificateChainFile(PEM_SERVER_CRT).create();
-        final Client client = cluster.connect();
-
-        try {
-            client.submit("'test'").one();
-            fail("Should throw exception because ssl client auth is enabled on the server but does not trust client's cert");
-        } catch(Exception x) {
-            final Throwable root = ExceptionUtils.getRootCause(x);
-            assertThat(root, instanceOf(TimeoutException.class));
-        } finally {
-            cluster.close();
-        }
-    }
-
-    @Test
-    public void shouldEnableSslAndClientCertificateAuthWithPkcs12() {
-        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(P12_CLIENT_KEY).keyStorePassword(KEY_PASS)
-                .keyStoreType(KEYSTORE_TYPE_PKCS12).trustStore(P12_CLIENT_TRUST).trustStorePassword(KEY_PASS).create();
-        final Client client = cluster.connect();
-
-        try {
-            assertEquals("test", client.submit("'test'").one().getString());
-        } finally {
-            cluster.close();
-        }
-    }
-
-    @Test
-    public void shouldEnableSslAndClientCertificateAuth() {
-        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_CLIENT_KEY).keyStorePassword(KEY_PASS)
-                .keyStoreType(KEYSTORE_TYPE_JKS).trustStore(JKS_CLIENT_TRUST).trustStorePassword(KEY_PASS).create();
-        final Client client = cluster.connect();
-
-        try {
-            assertEquals("test", client.submit("'test'").one().getString());
-        } finally {
-            cluster.close();
-        }
-    }
-
-    @Test
-    public void shouldEnableSslAndClientCertificateAuthAndFailWithoutCert() {
-        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_SERVER_KEY).keyStorePassword(KEY_PASS)
-                .keyStoreType(KEYSTORE_TYPE_JKS).sslSkipCertValidation(true).create();
-        final Client client = cluster.connect();
-
-        try {
-            client.submit("'test'").one();
-            fail("Should throw exception because ssl client auth is enabled on the server but client does not have a cert");
-        } catch (Exception x) {
-            final Throwable root = ExceptionUtils.getRootCause(x);
-            assertThat(root, instanceOf(TimeoutException.class));
-        } finally {
-            cluster.close();
-        }
-    }
-
-    @Test
-    public void shouldEnableSslAndClientCertificateAuthAndFailWithoutTrustedClientCert() {
-        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_CLIENT_KEY).keyStorePassword(KEY_PASS)
-                .keyStoreType(KEYSTORE_TYPE_JKS).trustStore(JKS_CLIENT_TRUST).trustStorePassword(KEY_PASS).create();
-        final Client client = cluster.connect();
-
-        try {
-            client.submit("'test'").one();
-            fail("Should throw exception because ssl client auth is enabled on the server but does not trust client's cert");
-        } catch (Exception x) {
-            final Throwable root = ExceptionUtils.getRootCause(x);
-            assertThat(root, instanceOf(TimeoutException.class));
-        } finally {
-            cluster.close();
-        }
-    }
-
-    @Test
-    public void shouldEnableSslAndFailIfProtocolsDontMatch() {
-        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_SERVER_KEY).keyStorePassword(KEY_PASS)
-                .sslSkipCertValidation(true).sslEnabledProtocols(Arrays.asList("TLSv1.2")).create();
-        final Client client = cluster.connect();
-
-        try {
-            client.submit("'test'").one();
-            fail("Should throw exception because ssl client requires TLSv1.2 whereas server supports only TLSv1.1");
-        } catch (Exception x) {
-            final Throwable root = ExceptionUtils.getRootCause(x);
-            assertThat(root, instanceOf(TimeoutException.class));
-        } finally {
-            cluster.close();
-        }
-    }
-
-    @Test
-    public void shouldEnableSslAndFailIfCiphersDontMatch() {
-        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_SERVER_KEY).keyStorePassword(KEY_PASS)
-                .sslSkipCertValidation(true).sslCipherSuites(Arrays.asList("SSL_RSA_WITH_RC4_128_SHA")).create();
-        final Client client = cluster.connect();
-
-        try {
-            client.submit("'test'").one();
-            fail("Should throw exception because ssl client requires TLSv1.2 whereas server supports only TLSv1.1");
-        } catch (Exception x) {
-            final Throwable root = ExceptionUtils.getRootCause(x);
-            assertThat(root, instanceOf(TimeoutException.class));
-        } finally {
-            cluster.close();
-        }
-    }
-
-    @Test
     public void shouldRespectHighWaterMarkSettingAndSucceed() throws Exception {
         // the highwatermark should get exceeded on the server and thus pause the writes, but have no problem catching
         // itself up - this is a tricky tests to get passing on all environments so this assumption will deny the
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSslIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSslIntegrateTest.java
new file mode 100644
index 0000000..7a3d499
--- /dev/null
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSslIntegrateTest.java
@@ -0,0 +1,340 @@
+/*
+ * 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.tinkerpop.gremlin.server;
+
+import io.netty.handler.ssl.ClientAuth;
+import io.netty.handler.ssl.SslContext;
+import io.netty.handler.ssl.SslContextBuilder;
+import io.netty.handler.ssl.SslProvider;
+import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
+import io.netty.handler.ssl.util.SelfSignedCertificate;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.tinkerpop.gremlin.driver.Client;
+import org.apache.tinkerpop.gremlin.driver.Cluster;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.TimeoutException;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class GremlinServerSslIntegrateTest extends AbstractGremlinServerIntegrationTest {
+    private static final String PEM_SERVER_KEY = "src/test/resources/server.key.pk8";
+    private static final String PEM_SERVER_CRT = "src/test/resources/server.crt";
+    private static final String PEM_CLIENT_KEY = "src/test/resources/client.key.pk8";
+    private static final String PEM_CLIENT_CRT = "src/test/resources/client.crt";
+
+    /**
+     * Configure specific Gremlin Server settings for specific tests.
+     */
+    @Override
+    public Settings overrideSettings(final Settings settings) {
+        final String nameOfTest = name.getMethodName();
+        switch (nameOfTest) {
+            case "shouldEnableSsl":
+            case "shouldEnableSslButFailIfClientConnectsWithoutIt":
+                settings.ssl = new Settings.SslSettings();
+                settings.ssl.enabled = true;
+                settings.ssl.keyStore = JKS_SERVER_KEY;
+                settings.ssl.keyStorePassword = KEY_PASS;
+                settings.ssl.keyStoreType = KEYSTORE_TYPE_JKS;
+                break;
+            case "shouldEnableSslWithSslContextProgrammaticallySpecified":
+                settings.ssl = new Settings.SslSettings();
+                settings.ssl.enabled = true;
+                settings.ssl.overrideSslContext(createServerSslContext());
+                break;
+            case "shouldEnableSslAndClientCertificateAuthWithLegacyPem":
+            case "shouldEnableSslAndClientCertificateAuthAndFailWithoutCertWithLegacyPem":
+                settings.ssl = new Settings.SslSettings();
+                settings.ssl.enabled = true;
+                settings.ssl.needClientAuth = ClientAuth.REQUIRE;
+                settings.ssl.keyCertChainFile = PEM_SERVER_CRT;
+                settings.ssl.keyFile = PEM_SERVER_KEY;
+                settings.ssl.keyPassword = KEY_PASS;
+                // Trust the client
+                settings.ssl.trustCertChainFile = PEM_CLIENT_CRT;
+                break;
+            // Trust the client
+            case "shouldEnableSslAndClientCertificateAuthAndFailWithoutTrustedClientCertWithLegacyPem":
+                settings.ssl = new Settings.SslSettings();
+                settings.ssl.enabled = true;
+                settings.ssl.needClientAuth = ClientAuth.REQUIRE;
+                settings.ssl.keyCertChainFile = PEM_SERVER_CRT;
+                settings.ssl.keyFile = PEM_SERVER_KEY;
+                settings.ssl.keyPassword = KEY_PASS;
+                // Trust ONLY the server cert
+                settings.ssl.trustCertChainFile = PEM_SERVER_CRT;
+                break;
+            case "shouldEnableSslAndClientCertificateAuthWithPkcs12":
+                settings.ssl = new Settings.SslSettings();
+                settings.ssl.enabled = true;
+                settings.ssl.needClientAuth = ClientAuth.REQUIRE;
+                settings.ssl.keyStore = P12_SERVER_KEY;
+                settings.ssl.keyStorePassword = KEY_PASS;
+                settings.ssl.keyStoreType = KEYSTORE_TYPE_PKCS12;
+                settings.ssl.trustStore = P12_SERVER_TRUST;
+                settings.ssl.trustStorePassword = KEY_PASS;
+                break;
+            case "shouldEnableSslAndClientCertificateAuth":
+            case "shouldEnableSslAndClientCertificateAuthAndFailWithoutCert":
+                settings.ssl = new Settings.SslSettings();
+                settings.ssl.enabled = true;
+                settings.ssl.needClientAuth = ClientAuth.REQUIRE;
+                settings.ssl.keyStore = JKS_SERVER_KEY;
+                settings.ssl.keyStorePassword = KEY_PASS;
+                settings.ssl.keyStoreType = KEYSTORE_TYPE_JKS;
+                settings.ssl.trustStore = JKS_SERVER_TRUST;
+                settings.ssl.trustStorePassword = KEY_PASS;
+                break;
+            case "shouldEnableSslAndClientCertificateAuthAndFailWithoutTrustedClientCert":
+                settings.ssl = new Settings.SslSettings();
+                settings.ssl.enabled = true;
+                settings.ssl.needClientAuth = ClientAuth.REQUIRE;
+                settings.ssl.keyStore = JKS_SERVER_KEY;
+                settings.ssl.keyStorePassword = KEY_PASS;
+                settings.ssl.keyStoreType = KEYSTORE_TYPE_JKS;
+                break;
+            case "shouldEnableSslAndFailIfProtocolsDontMatch":
+                settings.ssl = new Settings.SslSettings();
+                settings.ssl.enabled = true;
+                settings.ssl.keyStore = JKS_SERVER_KEY;
+                settings.ssl.keyStorePassword = KEY_PASS;
+                settings.ssl.keyStoreType = KEYSTORE_TYPE_JKS;
+                settings.ssl.sslEnabledProtocols = Collections.singletonList("TLSv1.1");
+                break;
+            case "shouldEnableSslAndFailIfCiphersDontMatch":
+                settings.ssl = new Settings.SslSettings();
+                settings.ssl.enabled = true;
+                settings.ssl.keyStore = JKS_SERVER_KEY;
+                settings.ssl.keyStorePassword = KEY_PASS;
+                settings.ssl.keyStoreType = KEYSTORE_TYPE_JKS;
+                settings.ssl.sslCipherSuites = Collections.singletonList("TLS_DHE_RSA_WITH_AES_128_CBC_SHA");
+                break;
+        }
+
+        return settings;
+    }
+
+    private static SslContext createServerSslContext() {
+        final SslProvider provider = SslProvider.JDK;
+
+        try {
+            // this is not good for production - just testing
+            final SelfSignedCertificate ssc = new SelfSignedCertificate();
+            return SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).sslProvider(provider).build();
+        } catch (Exception ce) {
+            throw new RuntimeException("Couldn't setup self-signed certificate for test");
+        }
+    }
+
+
+    @Test
+    public void shouldEnableSsl() {
+        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_SERVER_KEY).keyStorePassword(KEY_PASS).sslSkipCertValidation(true).create();
+        final Client client = cluster.connect();
+
+        try {
+            // this should return "nothing" - there should be no exception
+            assertEquals("test", client.submit("'test'").one().getString());
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldEnableSslWithSslContextProgrammaticallySpecified() throws Exception {
+        // just for testing - this is not good for production use
+        final SslContextBuilder builder = SslContextBuilder.forClient();
+        builder.trustManager(InsecureTrustManagerFactory.INSTANCE);
+        builder.sslProvider(SslProvider.JDK);
+
+        final Cluster cluster = TestClientFactory.build().enableSsl(true).sslContext(builder.build()).create();
+        final Client client = cluster.connect();
+
+        try {
+            // this should return "nothing" - there should be no exception
+            assertEquals("test", client.submit("'test'").one().getString());
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldEnableSslButFailIfClientConnectsWithoutIt() {
+        final Cluster cluster = TestClientFactory.build().enableSsl(false).create();
+        final Client client = cluster.connect();
+
+        try {
+            client.submit("'test'").one();
+            fail("Should throw exception because ssl is enabled on the server but not on client");
+        } catch(Exception x) {
+            final Throwable root = ExceptionUtils.getRootCause(x);
+            assertThat(root, instanceOf(TimeoutException.class));
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldEnableSslAndClientCertificateAuthWithLegacyPem() {
+        final Cluster cluster = TestClientFactory.build().enableSsl(true)
+                .keyCertChainFile(PEM_CLIENT_CRT).keyFile(PEM_CLIENT_KEY)
+                .keyPassword(KEY_PASS).trustCertificateChainFile(PEM_SERVER_CRT).create();
+        final Client client = cluster.connect();
+
+        try {
+            assertEquals("test", client.submit("'test'").one().getString());
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldEnableSslAndClientCertificateAuthAndFailWithoutCertWithLegacyPem() {
+        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_SERVER_KEY).keyStorePassword(KEY_PASS).sslSkipCertValidation(true).create();
+        final Client client = cluster.connect();
+
+        try {
+            client.submit("'test'").one();
+            fail("Should throw exception because ssl client auth is enabled on the server but client does not have a cert");
+        } catch(Exception x) {
+            final Throwable root = ExceptionUtils.getRootCause(x);
+            assertThat(root, instanceOf(TimeoutException.class));
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldEnableSslAndClientCertificateAuthAndFailWithoutTrustedClientCertWithLegacyPem() {
+        final Cluster cluster = TestClientFactory.build().enableSsl(true)
+                .keyCertChainFile(PEM_CLIENT_CRT).keyFile(PEM_CLIENT_KEY)
+                .keyPassword(KEY_PASS).trustCertificateChainFile(PEM_SERVER_CRT).create();
+        final Client client = cluster.connect();
+
+        try {
+            client.submit("'test'").one();
+            fail("Should throw exception because ssl client auth is enabled on the server but does not trust client's cert");
+        } catch(Exception x) {
+            final Throwable root = ExceptionUtils.getRootCause(x);
+            assertThat(root, instanceOf(TimeoutException.class));
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldEnableSslAndClientCertificateAuthWithPkcs12() {
+        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(P12_CLIENT_KEY).keyStorePassword(KEY_PASS)
+                .keyStoreType(KEYSTORE_TYPE_PKCS12).trustStore(P12_CLIENT_TRUST).trustStorePassword(KEY_PASS).create();
+        final Client client = cluster.connect();
+
+        try {
+            assertEquals("test", client.submit("'test'").one().getString());
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldEnableSslAndClientCertificateAuth() {
+        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_CLIENT_KEY).keyStorePassword(KEY_PASS)
+                .keyStoreType(KEYSTORE_TYPE_JKS).trustStore(JKS_CLIENT_TRUST).trustStorePassword(KEY_PASS).create();
+        final Client client = cluster.connect();
+
+        try {
+            assertEquals("test", client.submit("'test'").one().getString());
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldEnableSslAndClientCertificateAuthAndFailWithoutCert() {
+        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_SERVER_KEY).keyStorePassword(KEY_PASS)
+                .keyStoreType(KEYSTORE_TYPE_JKS).sslSkipCertValidation(true).create();
+        final Client client = cluster.connect();
+
+        try {
+            client.submit("'test'").one();
+            fail("Should throw exception because ssl client auth is enabled on the server but client does not have a cert");
+        } catch (Exception x) {
+            final Throwable root = ExceptionUtils.getRootCause(x);
+            assertThat(root, instanceOf(TimeoutException.class));
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldEnableSslAndClientCertificateAuthAndFailWithoutTrustedClientCert() {
+        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_CLIENT_KEY).keyStorePassword(KEY_PASS)
+                .keyStoreType(KEYSTORE_TYPE_JKS).trustStore(JKS_CLIENT_TRUST).trustStorePassword(KEY_PASS).create();
+        final Client client = cluster.connect();
+
+        try {
+            client.submit("'test'").one();
+            fail("Should throw exception because ssl client auth is enabled on the server but does not trust client's cert");
+        } catch (Exception x) {
+            final Throwable root = ExceptionUtils.getRootCause(x);
+            assertThat(root, instanceOf(TimeoutException.class));
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldEnableSslAndFailIfProtocolsDontMatch() {
+        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_SERVER_KEY).keyStorePassword(KEY_PASS)
+                .sslSkipCertValidation(true).sslEnabledProtocols(Arrays.asList("TLSv1.2")).create();
+        final Client client = cluster.connect();
+
+        try {
+            client.submit("'test'").one();
+            fail("Should throw exception because ssl client requires TLSv1.2 whereas server supports only TLSv1.1");
+        } catch (Exception x) {
+            final Throwable root = ExceptionUtils.getRootCause(x);
+            assertThat(root, instanceOf(TimeoutException.class));
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldEnableSslAndFailIfCiphersDontMatch() {
+        final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_SERVER_KEY).keyStorePassword(KEY_PASS)
+                .sslSkipCertValidation(true).sslCipherSuites(Arrays.asList("SSL_RSA_WITH_RC4_128_SHA")).create();
+        final Client client = cluster.connect();
+
+        try {
+            client.submit("'test'").one();
+            fail("Should throw exception because ssl client requires TLSv1.2 whereas server supports only TLSv1.1");
+        } catch (Exception x) {
+            final Throwable root = ExceptionUtils.getRootCause(x);
+            assertThat(root, instanceOf(TimeoutException.class));
+        } finally {
+            cluster.close();
+        }
+    }
+}