You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by rd...@apache.org on 2018/08/12 07:52:34 UTC
tinkerpop git commit: TINKERPOP-2023 new SSL client, server parameters
Repository: tinkerpop
Updated Branches:
refs/heads/TINKERPOP-2023 [created] e0176c2e5
TINKERPOP-2023 new SSL client, server parameters
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/e0176c2e
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/e0176c2e
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/e0176c2e
Branch: refs/heads/TINKERPOP-2023
Commit: e0176c2e522c2a20371d435c286293309db35744
Parents: 1b99323
Author: Robert Dale <ro...@gmail.com>
Authored: Sat Aug 11 21:12:50 2018 -0400
Committer: Robert Dale <ro...@gmail.com>
Committed: Sun Aug 12 03:52:03 2018 -0400
----------------------------------------------------------------------
.../tinkerpop/gremlin/driver/Cluster.java | 163 ++++++++++++++++++-
.../tinkerpop/gremlin/driver/Settings.java | 57 +++++++
.../gremlin/server/AbstractChannelizer.java | 78 +++++++--
.../tinkerpop/gremlin/server/Settings.java | 64 +++++++-
.../AbstractGremlinServerIntegrationTest.java | 7 +
.../server/GremlinServerAuthIntegrateTest.java | 4 +-
.../GremlinServerAuthOldIntegrateTest.java | 4 +-
.../server/GremlinServerIntegrateTest.java | 41 ++---
...ctGremlinServerChannelizerIntegrateTest.java | 10 +-
gremlin-server/src/test/resources/server.jks | Bin 0 -> 2258 bytes
gremlin-server/src/test/resources/server.p12 | Bin 0 -> 2613 bytes
11 files changed, 374 insertions(+), 54 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e0176c2e/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
index 567bfb4..b2e3e40 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
@@ -33,15 +33,25 @@ import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.UnknownHostException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -446,29 +456,80 @@ public final class Cluster {
return manager.authProps;
}
- SslContext createSSLContext() throws Exception {
+ SslContext createSSLContext() throws Exception {
// if the context is provided then just use that and ignore the other settings
- if (manager.sslContextOptional.isPresent()) return manager.sslContextOptional.get();
+ if (manager.sslContextOptional.isPresent())
+ return manager.sslContextOptional.get();
final SslProvider provider = SslProvider.JDK;
final Settings.ConnectionPoolSettings connectionPoolSettings = connectionPoolSettings();
final SslContextBuilder builder = SslContextBuilder.forClient();
- if (connectionPoolSettings.trustCertChainFile != null)
+ if (connectionPoolSettings.trustCertChainFile != null) {
+ logger.warn("Using deprecated SSL trustCertChainFile support");
builder.trustManager(new File(connectionPoolSettings.trustCertChainFile));
- else {
- logger.warn("SSL configured without a trustCertChainFile and thus trusts all certificates without verification (not suitable for production)");
- builder.trustManager(InsecureTrustManagerFactory.INSTANCE);
}
if (null != connectionPoolSettings.keyCertChainFile && null != connectionPoolSettings.keyFile) {
+ logger.warn("Using deprecated SSL keyFile support");
final File keyCertChainFile = new File(connectionPoolSettings.keyCertChainFile);
final File keyFile = new File(connectionPoolSettings.keyFile);
- // note that keyPassword may be null here if the keyFile is not password-protected.
+ // note that keyPassword may be null here if the keyFile is not
+ // password-protected.
builder.keyManager(keyCertChainFile, keyFile, connectionPoolSettings.keyPassword);
}
+ // Build JSSE SSLContext
+ try {
+
+ // Load private key/public cert for client auth
+ if (null != connectionPoolSettings.keyStore) {
+ final String keyStoreType = null == connectionPoolSettings.keyStoreType ? KeyStore.getDefaultType()
+ : connectionPoolSettings.keyStoreType;
+ final KeyStore keystore = KeyStore.getInstance(keyStoreType);
+ final char[] password = null == connectionPoolSettings.keyStorePassword ? null
+ : connectionPoolSettings.keyStorePassword.toCharArray();
+ try (final InputStream in = new FileInputStream(connectionPoolSettings.keyStore)) {
+ keystore.load(in, password);
+ }
+ final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ kmf.init(keystore, password);
+ builder.keyManager(kmf);
+ }
+
+ // Load custom truststore
+ if (null != connectionPoolSettings.trustStore) {
+ final String keystoreType = null == connectionPoolSettings.keyStoreType ? KeyStore.getDefaultType()
+ : connectionPoolSettings.keyStoreType;
+ final KeyStore truststore = KeyStore.getInstance(keystoreType);
+ final char[] password = null == connectionPoolSettings.trustStorePassword ? null
+ : connectionPoolSettings.trustStorePassword.toCharArray();
+ try (final InputStream in = new FileInputStream(connectionPoolSettings.trustStore)) {
+ truststore.load(in, password);
+ }
+ final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ tmf.init(truststore);
+ builder.trustManager(tmf);
+ }
+
+ } catch (UnrecoverableKeyException | NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException e) {
+ logger.error("There was an error enabling SSL.", e);
+ return null;
+ }
+
+ if (null != connectionPoolSettings.sslCipherSuites && !connectionPoolSettings.sslCipherSuites.isEmpty()) {
+ builder.ciphers(connectionPoolSettings.sslCipherSuites);
+ }
+
+ if (null != connectionPoolSettings.sslEnabledProtocols && !connectionPoolSettings.sslEnabledProtocols.isEmpty()) {
+ builder.protocols(connectionPoolSettings.sslEnabledProtocols.toArray(new String[] {}));
+ }
+
+ if (connectionPoolSettings.sslSkipCertValidation) {
+ builder.trustManager(InsecureTrustManagerFactory.INSTANCE);
+ }
+
builder.sslProvider(provider);
return builder.build();
@@ -499,6 +560,14 @@ public final class Cluster {
private String keyCertChainFile = null;
private String keyFile = null;
private String keyPassword = null;
+ private String keyStore;
+ private String keyStorePassword;
+ private String trustStore;
+ private String trustStorePassword;
+ private String keyStoreType;
+ private List<String> sslEnabledProtocols = new ArrayList<>();
+ private List<String> sslCipherSuites = new ArrayList<>();
+ private boolean sslSkipCertValidation = false;
private SslContext sslContext = null;
private LoadBalancingStrategy loadBalancingStrategy = new LoadBalancingStrategy.RoundRobin();
private AuthProperties authProps = new AuthProperties();
@@ -579,7 +648,9 @@ public final class Cluster {
* File location for a SSL Certificate Chain to use when SSL is enabled. If this value is not provided and
* SSL is enabled, the {@link TrustManager} will be established with a self-signed certificate which is NOT
* suitable for production purposes.
+ * @deprecated
*/
+ @Deprecated
public Builder trustCertificateChainFile(final String certificateChainFile) {
this.trustCertChainFile = certificateChainFile;
return this;
@@ -597,7 +668,9 @@ public final class Cluster {
/**
* The X.509 certificate chain file in PEM format.
+ * @deprecated
*/
+ @Deprecated
public Builder keyCertChainFile(final String keyCertChainFile) {
this.keyCertChainFile = keyCertChainFile;
return this;
@@ -605,7 +678,9 @@ public final class Cluster {
/**
* The PKCS#8 private key file in PEM format.
+ * @deprecated
*/
+ @Deprecated
public Builder keyFile(final String keyFile) {
this.keyFile = keyFile;
return this;
@@ -613,11 +688,77 @@ public final class Cluster {
/**
* The password of the {@link #keyFile}, or {@code null} if it's not password-protected.
+ * @deprecated
*/
+ @Deprecated
public Builder keyPassword(final String keyPassword) {
this.keyPassword = keyPassword;
return this;
}
+
+ /**
+ *
+ */
+ public Builder keyStore(final String keyStore) {
+ this.keyStore = keyStore;
+ return this;
+ }
+
+ /**
+ *
+ */
+ public Builder keyStorePassword(final String keyStorePassword) {
+ this.keyStorePassword = keyStorePassword;
+ return this;
+ }
+
+ /**
+ *
+ */
+ public Builder trustStore(final String trustStore) {
+ this.trustStore = trustStore;
+ return this;
+ }
+
+ /**
+ *
+ */
+ public Builder trustStorePassword(final String trustStorePassword) {
+ this.trustStorePassword = trustStorePassword;
+ return this;
+ }
+
+ /**
+ *
+ */
+ public Builder keyStoreType(final String keyStoreType) {
+ this.keyStoreType = keyStoreType;
+ return this;
+ }
+
+ /**
+ *
+ */
+ public Builder sslEnabledProtocols(final List<String> sslEnabledProtocols) {
+ this.sslEnabledProtocols = sslEnabledProtocols;
+ return this;
+ }
+
+ /**
+ *
+ */
+ public Builder sslCipherSuites(final List<String> sslCipherSuites) {
+ this.sslCipherSuites = sslCipherSuites;
+ return this;
+ }
+
+ /**
+ *
+ */
+ public Builder sslSkipCertValidation(final boolean sslSkipCertValidation) {
+ this.sslSkipCertValidation = sslSkipCertValidation;
+ return this;
+ }
/**
* The minimum number of in-flight requests that can occur on a {@link Connection} before it is considered
@@ -901,6 +1042,14 @@ public final class Cluster {
connectionPoolSettings.keyCertChainFile = builder.keyCertChainFile;
connectionPoolSettings.keyFile = builder.keyFile;
connectionPoolSettings.keyPassword = builder.keyPassword;
+ connectionPoolSettings.keyStore = builder.keyStore;
+ connectionPoolSettings.keyStorePassword = builder.keyStorePassword;
+ connectionPoolSettings.trustStore = builder.trustStore;
+ connectionPoolSettings.trustStorePassword = builder.trustStorePassword;
+ connectionPoolSettings.keyStoreType = builder.keyStoreType;
+ connectionPoolSettings.sslCipherSuites = builder.sslCipherSuites;
+ connectionPoolSettings.sslEnabledProtocols = builder.sslEnabledProtocols;
+ connectionPoolSettings.sslSkipCertValidation = builder.sslSkipCertValidation;
connectionPoolSettings.keepAliveInterval = builder.keepAliveInterval;
connectionPoolSettings.channelizer = builder.channelizer;
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e0176c2e/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java
index 8a2517d..009a0bf 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Settings.java
@@ -232,25 +232,82 @@ final class Settings {
/**
* The trusted certificate in PEM format.
+ * @deprecated Use JSSE-based settings
*/
+ @Deprecated
public String trustCertChainFile = null;
/**
* The X.509 certificate chain file in PEM format.
+ * @deprecated Use JSSE-based settings
*/
+ @Deprecated
public String keyCertChainFile = null;
/**
* The PKCS#8 private key file in PEM format.
+ * @deprecated Use JSSE-based settings
*/
+ @Deprecated
public String keyFile = null;
/**
* The password of the {@link #keyFile}, or {@code null} if it's not password-protected.
+ * @deprecated Use JSSE-based settings
*/
+ @Deprecated
public String keyPassword = null;
/**
+ * JSSE keystore file path. Similar to setting JSSE property
+ * {@code javax.net.ssl.keyStore}.
+ */
+ public String keyStore;
+
+ /**
+ * JSSE keystore password. Similar to setting JSSE property
+ * {@code javax.net.ssl.keyStorePassword}.
+ */
+ public String keyStorePassword;
+
+ /**
+ * JSSE truststore file path. Similar to setting JSSE property
+ * {@code javax.net.ssl.trustStore}.
+ */
+ public String trustStore;
+
+ /**
+ * JSSE truststore password. Similar to setting JSSE property
+ * {@code javax.net.ssl.trustStorePassword}.
+ */
+ public String trustStorePassword;
+
+ /**
+ * JSSE keystore format. Similar to setting JSSE property
+ * {@code javax.net.ssl.keyStoreType}.
+ */
+ public String keyStoreType;
+
+ /**
+ * @see <a href=
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SunJSSE_Protocols">JSSE
+ * Protocols</a>
+ */
+ public List<String> sslEnabledProtocols = new ArrayList<>();
+
+ /**
+ * @see <a href=
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SupportedCipherSuites">Cipher
+ * Suites</a>
+ */
+ public List<String> sslCipherSuites = new ArrayList<>();
+
+ /**
+ *
+ */
+ public boolean sslSkipCertValidation = false;
+
+ /**
* The minimum size of a connection pool for a {@link Host}. By default this is set to 2.
*/
public int minSize = ConnectionPool.MIN_POOL_SIZE;
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e0176c2e/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
index edea752..2a29fec 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/AbstractChannelizer.java
@@ -22,7 +22,6 @@ import io.netty.channel.EventLoopGroup;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
-import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.timeout.IdleStateHandler;
import org.apache.tinkerpop.gremlin.driver.MessageSerializer;
import org.apache.tinkerpop.gremlin.driver.ser.AbstractGryoMessageSerializerV1d0;
@@ -43,8 +42,18 @@ import org.javatuples.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLException;
+import javax.net.ssl.TrustManagerFactory;
+
import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.Collections;
@@ -258,7 +267,7 @@ public abstract class AbstractChannelizer extends ChannelInitializer<SocketChann
}
}
- private SslContext createSSLContext(final Settings settings) {
+ private SslContext createSSLContext(final Settings settings) {
final Settings.SslSettings sslSettings = settings.ssl;
if (sslSettings.getSslContext().isPresent()) {
@@ -270,25 +279,62 @@ public abstract class AbstractChannelizer extends ChannelInitializer<SocketChann
final SslContextBuilder builder;
- // if the config doesn't contain a cert or key then use a self signed cert - not suitable for production
- if (null == sslSettings.keyCertChainFile || null == sslSettings.keyFile) {
- try {
- logger.warn("Enabling SSL with self-signed certificate (NOT SUITABLE FOR PRODUCTION)");
- final SelfSignedCertificate ssc = new SelfSignedCertificate();
- builder = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey());
- } catch (CertificateException ce) {
- logger.error("There was an error creating the self-signed certificate for SSL - SSL is not enabled", ce);
- return null;
- }
- } else {
+ // DEPRECATED: If the config has the required, deprecated settings, then use it
+ if (null != sslSettings.keyCertChainFile && null != sslSettings.keyFile) {
+ logger.warn("Using deprecated SSL keyFile support");
final File keyCertChainFile = new File(sslSettings.keyCertChainFile);
final File keyFile = new File(sslSettings.keyFile);
final File trustCertChainFile = null == sslSettings.trustCertChainFile ? null : new File(sslSettings.trustCertChainFile);
- // note that keyPassword may be null here if the keyFile is not password-protected. passing null to
+ // note that keyPassword may be null here if the keyFile is not
+ // password-protected. passing null to
// trustManager is also ok (default will be used)
- builder = SslContextBuilder.forServer(keyCertChainFile, keyFile, sslSettings.keyPassword)
- .trustManager(trustCertChainFile);
+ builder = SslContextBuilder.forServer(keyCertChainFile, keyFile, sslSettings.keyPassword).trustManager(trustCertChainFile);
+ } else {
+
+ // Build JSSE SSLContext
+ try {
+ final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+
+ // Load private key and signed cert
+ if (null != sslSettings.keyStore) {
+ final String keyStoreType = null == sslSettings.keyStoreType ? KeyStore.getDefaultType() : sslSettings.keyStoreType;
+ final KeyStore keystore = KeyStore.getInstance(keyStoreType);
+ final char[] password = null == sslSettings.keyStorePassword ? null : sslSettings.keyStorePassword.toCharArray();
+ try (final InputStream in = new FileInputStream(sslSettings.keyStore)) {
+ keystore.load(in, password);
+ }
+ kmf.init(keystore, password);
+ }
+
+ builder = SslContextBuilder.forServer(kmf);
+
+ // Load custom truststore for client auth certs
+ if (null != sslSettings.trustStore) {
+ final String keystoreType = null == sslSettings.keyStoreType ? KeyStore.getDefaultType() : sslSettings.keyStoreType;
+ final KeyStore truststore = KeyStore.getInstance(keystoreType);
+ final char[] password = null == sslSettings.trustStorePassword ? null : sslSettings.trustStorePassword.toCharArray();
+ try (final InputStream in = new FileInputStream(sslSettings.trustStore)) {
+ truststore.load(in, password);
+ }
+ final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ tmf.init(truststore);
+ builder.trustManager(tmf);
+ }
+
+ } catch (UnrecoverableKeyException | NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException e) {
+ logger.error("There was an error enabling SSL.", e);
+ return null;
+ }
+
+ }
+
+ if (null != sslSettings.sslCipherSuites && !sslSettings.sslCipherSuites.isEmpty()) {
+ builder.ciphers(sslSettings.sslCipherSuites);
+ }
+
+ if (null != sslSettings.sslEnabledProtocols && !sslSettings.sslEnabledProtocols.isEmpty()) {
+ builder.protocols(sslSettings.sslEnabledProtocols.toArray(new String[] {}));
}
builder.clientAuth(sslSettings.needClientAuth).sslProvider(provider);
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e0176c2e/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
index 74a5a1a..c918f8b 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java
@@ -450,34 +450,86 @@ public class Settings {
*/
public static class SslSettings {
/**
- * Enables SSL. Other settings will be ignored unless this is set to true. By default a self-signed
- * certificate is used (not suitable for production) for SSL. To override this setting, be sure to set
- * the {@link #keyCertChainFile} and the {@link #keyFile}.
+ * Enables SSL. Other SSL settings will be ignored unless this is set to true.
*/
public boolean enabled = false;
/**
* The X.509 certificate chain file in PEM format.
+ *
+ * @deprecated Use JSSE-based settings
*/
+ @Deprecated
public String keyCertChainFile = null;
/**
* The PKCS#8 private key file in PEM format.
+ *
+ * @deprecated Use JSSE-based settings
*/
+ @Deprecated
public String keyFile = null;
/**
- * The password of the {@link #keyFile}, or {@code null} if it's not password-protected.
+ * The password of the {@link #keyFile}, or {@code null} if it's not
+ * password-protected.
+ *
+ * @deprecated Use JSSE-based settings
*/
+ @Deprecated
public String keyPassword = null;
/**
- * Trusted certificates for verifying the remote endpoint's certificate. The file should
- * contain an X.509 certificate chain in PEM format. {@code null} uses the system default.
+ * Trusted certificates for verifying the remote endpoint's certificate. The
+ * file should contain an X.509 certificate chain in PEM format. {@code null}
+ * uses the system default.
+ *
+ * @deprecated Use JSSE-based settings
*/
+ @Deprecated
public String trustCertChainFile = null;
/**
+ * JSSE keystore file path. Similar to setting JSSE property
+ * {@code javax.net.ssl.keyStore}.
+ */
+ public String keyStore;
+
+ /**
+ * JSSE keystore password. Similar to setting JSSE property
+ * {@code javax.net.ssl.keyStorePassword}.
+ */
+ public String keyStorePassword;
+
+ /**
+ * JSSE truststore file path. Similar to setting JSSE property
+ * {@code javax.net.ssl.trustStore}.
+ */
+ public String trustStore;
+
+ /**
+ * JSSE truststore password. Similar to setting JSSE property
+ * {@code javax.net.ssl.trustStorePassword}.
+ */
+ public String trustStorePassword;
+
+ /**
+ * JSSE keystore format. Similar to setting JSSE property
+ * {@code javax.net.ssl.keyStoreType}.
+ */
+ public String keyStoreType;
+
+ /**
+ * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SunJSSE_Protocols">JSSE Protocols</a>
+ */
+ public List<String> sslEnabledProtocols = new ArrayList<>();
+
+ /**
+ * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SupportedCipherSuites">Cipher Suites</a>
+ */
+ public List<String> sslCipherSuites = new ArrayList<>();
+
+ /**
* Require client certificate authentication
*/
public ClientAuth needClientAuth = ClientAuth.NONE;
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e0176c2e/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java
index f11a045..0543a59 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java
@@ -38,6 +38,13 @@ import static org.junit.Assume.assumeThat;
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
public abstract class AbstractGremlinServerIntegrationTest {
+
+ public static final String KEY_PASS = "changeit";
+ public static final String JKS_SERVER_KEY = "src/test/resources/server.jks";
+ public static final String JKS_CLIENT_KEY = "src/test/resources/client.jks";
+ public static final String P12_SERVER_KEY = "src/test/resources/server.p12";
+ public static final String P12_CLIENT_KEY = "src/test/resources/client.p12";
+
protected GremlinServer server;
private Settings overriddenSettings;
private final static String epollOption = "gremlin.server.epoll";
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e0176c2e/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuthIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuthIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuthIntegrateTest.java
index e06bbb7..b4d979a 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuthIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuthIntegrateTest.java
@@ -66,6 +66,8 @@ public class GremlinServerAuthIntegrateTest extends AbstractGremlinServerIntegra
case "shouldFailIfSslEnabledOnServerButNotClient":
final Settings.SslSettings sslConfig = new Settings.SslSettings();
sslConfig.enabled = true;
+ sslConfig.keyStore = JKS_SERVER_KEY;
+ sslConfig.keyStorePassword = KEY_PASS;
settings.ssl = sslConfig;
break;
}
@@ -107,7 +109,7 @@ public class GremlinServerAuthIntegrateTest extends AbstractGremlinServerIntegra
@Test
public void shouldAuthenticateOverSslWithPlainText() throws Exception {
final Cluster cluster = TestClientFactory.build()
- .enableSsl(true)
+ .enableSsl(true).sslSkipCertValidation(true)
.credentials("stephen", "password").create();
final Client client = cluster.connect();
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e0176c2e/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuthOldIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuthOldIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuthOldIntegrateTest.java
index b26dd1e..10755f1 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuthOldIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuthOldIntegrateTest.java
@@ -69,6 +69,8 @@ public class GremlinServerAuthOldIntegrateTest extends AbstractGremlinServerInte
case "shouldFailIfSslEnabledOnServerButNotClient":
final Settings.SslSettings sslConfig = new Settings.SslSettings();
sslConfig.enabled = true;
+ sslConfig.keyStore = JKS_SERVER_KEY;
+ sslConfig.keyStorePassword = KEY_PASS;
settings.ssl = sslConfig;
break;
}
@@ -110,7 +112,7 @@ public class GremlinServerAuthOldIntegrateTest extends AbstractGremlinServerInte
@Test
public void shouldAuthenticateOverSslWithPlainText() throws Exception {
final Cluster cluster = TestClientFactory.build()
- .enableSsl(true)
+ .enableSsl(true).keyStore(JKS_SERVER_KEY).keyStorePassword(KEY_PASS).sslSkipCertValidation(true)
.credentials("stephen", "password").create();
final Client client = cluster.connect();
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e0176c2e/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
----------------------------------------------------------------------
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 eb5def9..238d2b2 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
@@ -110,11 +110,10 @@ import static org.junit.Assert.assertEquals;
*/
public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegrationTest {
- private static final String SERVER_KEY = "src/test/resources/server.key.pk8";
- private static final String SERVER_CRT = "src/test/resources/server.crt";
- private static final String KEY_PASS = "changeit";
- private static final String CLIENT_KEY = "src/test/resources/client.key.pk8";
- private static final String CLIENT_CRT = "src/test/resources/client.crt";
+ 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;
@@ -194,6 +193,8 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
case "shouldEnableSslButFailIfClientConnectsWithoutIt":
settings.ssl = new Settings.SslSettings();
settings.ssl.enabled = true;
+ settings.ssl.keyStore = JKS_SERVER_KEY;
+ settings.ssl.keyStorePassword = KEY_PASS;
break;
case "shouldEnableSslWithSslContextProgrammaticallySpecified":
settings.ssl = new Settings.SslSettings();
@@ -204,31 +205,31 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
settings.ssl = new Settings.SslSettings();
settings.ssl.enabled = true;
settings.ssl.needClientAuth = ClientAuth.REQUIRE;
- settings.ssl.keyCertChainFile = SERVER_CRT;
- settings.ssl.keyFile = SERVER_KEY;
+ settings.ssl.keyCertChainFile = PEM_SERVER_CRT;
+ settings.ssl.keyFile = PEM_SERVER_KEY;
settings.ssl.keyPassword =KEY_PASS;
// Trust the client
- settings.ssl.trustCertChainFile = CLIENT_CRT;
+ settings.ssl.trustCertChainFile = PEM_CLIENT_CRT;
break;
case "shouldEnableSslAndClientCertificateAuthAndFailWithoutCert":
settings.ssl = new Settings.SslSettings();
settings.ssl.enabled = true;
settings.ssl.needClientAuth = ClientAuth.REQUIRE;
- settings.ssl.keyCertChainFile = SERVER_CRT;
- settings.ssl.keyFile = SERVER_KEY;
+ settings.ssl.keyCertChainFile = PEM_SERVER_CRT;
+ settings.ssl.keyFile = PEM_SERVER_KEY;
settings.ssl.keyPassword =KEY_PASS;
// Trust the client
- settings.ssl.trustCertChainFile = CLIENT_CRT;
+ settings.ssl.trustCertChainFile = PEM_CLIENT_CRT;
break;
case "shouldEnableSslAndClientCertificateAuthAndFailWithoutTrustedClientCert":
settings.ssl = new Settings.SslSettings();
settings.ssl.enabled = true;
settings.ssl.needClientAuth = ClientAuth.REQUIRE;
- settings.ssl.keyCertChainFile = SERVER_CRT;
- settings.ssl.keyFile = SERVER_KEY;
+ 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 = SERVER_CRT;
+ settings.ssl.trustCertChainFile = PEM_SERVER_CRT;
break;
case "shouldUseSimpleSandbox":
settings.scriptEngines.get("gremlin-groovy").config = getScriptEngineConfForSimpleSandbox();
@@ -485,7 +486,7 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
@Test
public void shouldEnableSsl() {
- final Cluster cluster = TestClientFactory.build().enableSsl(true).create();
+ final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_SERVER_KEY).keyStorePassword(KEY_PASS).sslSkipCertValidation(true).create();
final Client client = cluster.connect();
try {
@@ -533,8 +534,8 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
@Test
public void shouldEnableSslAndClientCertificateAuth() {
final Cluster cluster = TestClientFactory.build().enableSsl(true)
- .keyCertChainFile(CLIENT_CRT).keyFile(CLIENT_KEY)
- .keyPassword(KEY_PASS).trustCertificateChainFile(SERVER_CRT).create();
+ .keyCertChainFile(PEM_CLIENT_CRT).keyFile(PEM_CLIENT_KEY)
+ .keyPassword(KEY_PASS).trustCertificateChainFile(PEM_SERVER_CRT).create();
final Client client = cluster.connect();
try {
@@ -546,7 +547,7 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
@Test
public void shouldEnableSslAndClientCertificateAuthAndFailWithoutCert() {
- final Cluster cluster = TestClientFactory.build().enableSsl(true).create();
+ final Cluster cluster = TestClientFactory.build().enableSsl(true).keyStore(JKS_SERVER_KEY).keyStorePassword(KEY_PASS).sslSkipCertValidation(true).create();
final Client client = cluster.connect();
try {
@@ -563,8 +564,8 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
@Test
public void shouldEnableSslAndClientCertificateAuthAndFailWithoutTrustedClientCert() {
final Cluster cluster = TestClientFactory.build().enableSsl(true)
- .keyCertChainFile(CLIENT_CRT).keyFile(CLIENT_KEY)
- .keyPassword(KEY_PASS).trustCertificateChainFile(SERVER_CRT).create();
+ .keyCertChainFile(PEM_CLIENT_CRT).keyFile(PEM_CLIENT_KEY)
+ .keyPassword(KEY_PASS).trustCertificateChainFile(PEM_SERVER_CRT).create();
final Client client = cluster.connect();
try {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e0176c2e/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/AbstractGremlinServerChannelizerIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/AbstractGremlinServerChannelizerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/AbstractGremlinServerChannelizerIntegrateTest.java
index 738ca89..300a7f4 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/AbstractGremlinServerChannelizerIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/channel/AbstractGremlinServerChannelizerIntegrateTest.java
@@ -100,6 +100,8 @@ abstract class AbstractGremlinServerChannelizerIntegrateTest extends AbstractGre
case "shouldWorkWithSSL":
settings.ssl = new Settings.SslSettings();
settings.ssl.enabled = true;
+ settings.ssl.keyStore = JKS_SERVER_KEY;
+ settings.ssl.keyStorePassword = KEY_PASS;
break;
case "shouldWorkWithAuth":
if (authSettings != null) {
@@ -109,6 +111,8 @@ abstract class AbstractGremlinServerChannelizerIntegrateTest extends AbstractGre
case "shouldWorkWithSSLAndAuth":
settings.ssl = new Settings.SslSettings();
settings.ssl.enabled = true;
+ settings.ssl.keyStore = JKS_SERVER_KEY;
+ settings.ssl.keyStorePassword = KEY_PASS;
if (authSettings != null) {
settings.authentication = getAuthSettings();
}
@@ -304,7 +308,7 @@ abstract class AbstractGremlinServerChannelizerIntegrateTest extends AbstractGre
.with(Property.USERNAME, username)
.with(Property.PASSWORD, password);
- nioCluster = nioBuilder.enableSsl(secure).authProperties(authProps).create();
+ nioCluster = nioBuilder.enableSsl(secure).sslSkipCertValidation(true).authProperties(authProps).create();
nioClient = nioCluster.connect();
} else {
nioCluster = nioBuilder.enableSsl(secure).create();
@@ -318,10 +322,10 @@ abstract class AbstractGremlinServerChannelizerIntegrateTest extends AbstractGre
.with(Property.USERNAME, username)
.with(Property.PASSWORD, password);
- wsCluster = wsBuilder.enableSsl(secure).authProperties(authProps).create();
+ wsCluster = wsBuilder.enableSsl(secure).sslSkipCertValidation(true).authProperties(authProps).create();
wsClient = wsCluster.connect();
} else {
- wsCluster = wsBuilder.enableSsl(secure).create();
+ wsCluster = wsBuilder.enableSsl(secure).sslSkipCertValidation(true).create();
wsClient = wsCluster.connect();
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e0176c2e/gremlin-server/src/test/resources/server.jks
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/resources/server.jks b/gremlin-server/src/test/resources/server.jks
new file mode 100644
index 0000000..85dbe67
Binary files /dev/null and b/gremlin-server/src/test/resources/server.jks differ
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e0176c2e/gremlin-server/src/test/resources/server.p12
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/resources/server.p12 b/gremlin-server/src/test/resources/server.p12
new file mode 100644
index 0000000..4d1aad7
Binary files /dev/null and b/gremlin-server/src/test/resources/server.p12 differ