mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
Fix SSLKsFactory issue
Use Netty to create SslContext Add SSLKsFactoryTest Add keystore, truststore, pem files for testing Update markdown files
This commit is contained in:
parent
65cbbe7fb4
commit
819b7b3786
@ -1,25 +1,43 @@
|
||||
package io.nosqlbench.activitytype.cql.statements.core;
|
||||
|
||||
import com.datastax.driver.core.*;
|
||||
import com.datastax.driver.core.policies.*;
|
||||
import com.datastax.driver.dse.DseCluster;
|
||||
import io.nosqlbench.activitytype.cql.core.CQLOptions;
|
||||
import io.nosqlbench.activitytype.cql.core.ProxyTranslator;
|
||||
import io.nosqlbench.engine.api.activityapi.core.Shutdownable;
|
||||
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
||||
import io.nosqlbench.engine.api.metrics.ActivityMetrics;
|
||||
import io.nosqlbench.engine.api.scripting.NashornEvaluator;
|
||||
import io.nosqlbench.engine.api.util.SSLKsFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.datastax.driver.core.Cluster;
|
||||
import com.datastax.driver.core.ProtocolOptions;
|
||||
import com.datastax.driver.core.RemoteEndpointAwareJdkSSLOptions;
|
||||
import com.datastax.driver.core.RemoteEndpointAwareNettySSLOptions;
|
||||
import com.datastax.driver.core.SSLOptions;
|
||||
import com.datastax.driver.core.Session;
|
||||
import com.datastax.driver.core.policies.DefaultRetryPolicy;
|
||||
import com.datastax.driver.core.policies.LoadBalancingPolicy;
|
||||
import com.datastax.driver.core.policies.LoggingRetryPolicy;
|
||||
import com.datastax.driver.core.policies.RetryPolicy;
|
||||
import com.datastax.driver.core.policies.RoundRobinPolicy;
|
||||
import com.datastax.driver.core.policies.SpeculativeExecutionPolicy;
|
||||
import com.datastax.driver.core.policies.WhiteListPolicy;
|
||||
import com.datastax.driver.dse.DseCluster;
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import io.nosqlbench.activitytype.cql.core.CQLOptions;
|
||||
import io.nosqlbench.activitytype.cql.core.ProxyTranslator;
|
||||
import io.nosqlbench.engine.api.activityapi.core.Shutdownable;
|
||||
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
||||
import io.nosqlbench.engine.api.metrics.ActivityMetrics;
|
||||
import io.nosqlbench.engine.api.scripting.NashornEvaluator;
|
||||
import io.nosqlbench.engine.api.util.SSLKsFactory;
|
||||
|
||||
public class CQLSessionCache implements Shutdownable {
|
||||
|
||||
@ -202,99 +220,12 @@ public class CQLSessionCache implements Shutdownable {
|
||||
.map(CQLOptions::withCompression)
|
||||
.ifPresent(builder::withCompression);
|
||||
|
||||
if (activityDef.getParams().getOptionalString("ssl").isPresent()) {
|
||||
logger.info("Cluster builder proceeding with SSL but no Client Auth");
|
||||
Object context = SSLKsFactory.get().getContext(activityDef);
|
||||
SSLOptions sslOptions;
|
||||
if (context instanceof javax.net.ssl.SSLContext) {
|
||||
sslOptions = RemoteEndpointAwareJdkSSLOptions.builder()
|
||||
.withSSLContext((javax.net.ssl.SSLContext) context).build();
|
||||
builder.withSSL(sslOptions);
|
||||
} else if (context instanceof io.netty.handler.ssl.SslContext) {
|
||||
sslOptions =
|
||||
new RemoteEndpointAwareNettySSLOptions((io.netty.handler.ssl.SslContext) context);
|
||||
} else {
|
||||
throw new RuntimeException("Unrecognized ssl context object type: " + context.getClass().getCanonicalName());
|
||||
}
|
||||
SslContext context = SSLKsFactory.get().getContext(activityDef);
|
||||
if (context != null) {
|
||||
SSLOptions sslOptions = new RemoteEndpointAwareNettySSLOptions(context);
|
||||
builder.withSSL(sslOptions);
|
||||
}
|
||||
|
||||
// JdkSSLOptions sslOptions = RemoteEndpointAwareJdkSSLOptions
|
||||
// .builder()
|
||||
// .withSSLContext(context)
|
||||
// .build();
|
||||
// builder.withSSL(sslOptions);
|
||||
//
|
||||
// }
|
||||
//
|
||||
// boolean sslEnabled = activityDef.getParams().getOptionalBoolean("ssl").orElse(false);
|
||||
// boolean jdkSslEnabled = activityDef.getParams().getOptionalBoolean("jdkssl").orElse(false);
|
||||
// if (jdkSslEnabled){
|
||||
// sslEnabled = true;
|
||||
// }
|
||||
//
|
||||
// // used for OpenSSL
|
||||
// boolean openSslEnabled = activityDef.getParams().getOptionalBoolean("openssl").orElse(false);
|
||||
//
|
||||
// if (sslEnabled && openSslEnabled) {
|
||||
// logger.error("You cannot enable both OpenSSL and JDKSSL, please pick one and try again!");
|
||||
// System.exit(2);
|
||||
// }
|
||||
//
|
||||
// if (sslEnabled) {
|
||||
// logger.info("Cluster builder proceeding with SSL but no Client Auth");
|
||||
// SSLContext context = SSLKsFactory.get().getContext(activityDef);
|
||||
// JdkSSLOptions sslOptions = RemoteEndpointAwareJdkSSLOptions
|
||||
// .builder()
|
||||
// .withSSLContext(context)
|
||||
// .build();
|
||||
// builder.withSSL(sslOptions);
|
||||
// }
|
||||
// else if (openSslEnabled) {
|
||||
// logger.info("Cluster builder proceeding with SSL and Client Auth");
|
||||
// String keyPassword = activityDef.getParams().getOptionalString("keyPassword").orElse(null);
|
||||
// String caCertFileLocation = activityDef.getParams().getOptionalString("caCertFilePath").orElse(null);
|
||||
// String certFileLocation = activityDef.getParams().getOptionalString("certFilePath").orElse(null);
|
||||
// String keyFileLocation = activityDef.getParams().getOptionalString("keyFilePath").orElse(null);
|
||||
//
|
||||
//
|
||||
// try {
|
||||
//
|
||||
// KeyStore ks = KeyStore.getInstance("JKS", "SUN");
|
||||
// ks.load(null, keyPassword.toCharArray());
|
||||
//
|
||||
// X509Certificate cert = (X509Certificate) CertificateFactory.
|
||||
// getInstance("X509").
|
||||
// generateCertificate(new FileInputStream(caCertFileLocation));
|
||||
//
|
||||
// //set alias to cert
|
||||
// ks.setCertificateEntry(cert.getSubjectX500Principal().getName(), cert);
|
||||
//
|
||||
// TrustManagerFactory tMF = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
// tMF.init(ks);
|
||||
//
|
||||
//
|
||||
// SslContext sslContext = SslContextBuilder
|
||||
// .forClient()
|
||||
// /* configured with the TrustManagerFactory that has the cert from the ca.cert
|
||||
// * This tells the driver to trust the server during the SSL handshake */
|
||||
// .trustManager(tMF)
|
||||
// /* These are needed because the server is configured with require_client_auth
|
||||
// * In this case the client's public key must be in the truststore on each DSE
|
||||
// * server node and the CA configured */
|
||||
// .keyManager(new File(certFileLocation), new File(keyFileLocation))
|
||||
// .build();
|
||||
//
|
||||
// RemoteEndpointAwareNettySSLOptions sslOptions = new RemoteEndpointAwareNettySSLOptions(sslContext);
|
||||
//
|
||||
// // Cluster builder with sslOptions
|
||||
// builder.withSSL(sslOptions);
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
// }
|
||||
|
||||
RetryPolicy retryPolicy = activityDef.getParams()
|
||||
.getOptionalString("retrypolicy")
|
||||
.map(CQLOptions::retryPolicyFor).orElse(DefaultRetryPolicy.INSTANCE);
|
||||
|
@ -1,6 +1,6 @@
|
||||
# cql driver
|
||||
|
||||
This is an driver which allows for the execution of CQL statements. This driver supports both sync and async modes, with
|
||||
This is a driver which allows for the execution of CQL statements. This driver supports both sync and async modes, with
|
||||
detailed metrics provided for both.
|
||||
|
||||
### Example activity definitions
|
||||
@ -38,7 +38,7 @@ activity types.
|
||||
with no spaces.
|
||||
Examples:
|
||||
- `host=192.168.1.25`
|
||||
- `host=`192.168.1.25,testhost42`
|
||||
- `host=192.168.1.25,testhost42`
|
||||
- **workload** - The workload definition which holds the schema and statement defs.
|
||||
see workload yaml location for additional details
|
||||
(no default, required)
|
||||
@ -59,8 +59,8 @@ activity types.
|
||||
policy in the driver. If used, a WhitelistPolicy(RoundRobinPolicy())
|
||||
will be created and added to the cluster builder on startup.
|
||||
Examples:
|
||||
- whitelist=127.0.0.1
|
||||
- whitelist=127.0.0.1:9042,127.0.0.2:1234
|
||||
- `whitelist=127.0.0.1`
|
||||
- `whitelist=127.0.0.1:9042,127.0.0.2:1234`
|
||||
- **retrypolicy** default: none - Applies a retry policy in the driver
|
||||
The only option supported for this version is `retrypolicy=logging`,
|
||||
which uses the default retry policy, but with logging added.
|
||||
@ -107,7 +107,7 @@ activity types.
|
||||
|
||||
Examples:
|
||||
- `socketoptions=read_timeout_ms=23423,connect_timeout_ms=4444`
|
||||
- `socketoptions=tcp_no_delay=true
|
||||
- `socketoptions=tcp_no_delay=true`
|
||||
|
||||
- **tokens** default: unset - Only executes statements that fall within
|
||||
any of the specified token ranges. Others are counted in metrics
|
||||
@ -133,36 +133,12 @@ activity types.
|
||||
ignored if passfile is also present.
|
||||
- **passfile** - the file to read the password from. The first
|
||||
line of this file is used as the password.
|
||||
|
||||
- **ssl** - specifies the type of the SSL implementation.
|
||||
Disabled by default, possible values are `jdk`, and `openssl`.
|
||||
Depending on type, additional parameters need to be provided.
|
||||
- **tlsversion** - specify the TLS version to use for SSL.
|
||||
Examples:
|
||||
- `tlsversion=TLSv1.2` (the default)
|
||||
- **truststore** (`jdk`, `openssl`) - specify the path to the SSL truststore.
|
||||
Examples:
|
||||
- `truststore=file.truststore`
|
||||
- **tspass** (`jdk`, `openssl`) - specify the password for the SSL truststore.
|
||||
Examples:
|
||||
- `tspass=mypass`
|
||||
- **keystore** (`jdk`) - specify the path to the SSL keystore.
|
||||
Examples:
|
||||
- `keystore=file.keystore`
|
||||
- **kspass** (`jdk`) - specify the password for the SSL keystore.
|
||||
Examples:
|
||||
- `kspass=mypass`
|
||||
- **keyFilePath** (`openssl`) - path to the OpenSSL key file.
|
||||
Examples:
|
||||
- `keyFilePath=file.key`
|
||||
- **keyPassword** (`openssl`) - key password;
|
||||
Examples:
|
||||
- `keyPassword=password`
|
||||
- **caCertFilePath** (`openssl`) - path to the X509 CA certificate file.
|
||||
Examples:
|
||||
- `caCertFilePath=cacert.pem`
|
||||
- **certFilePath** (`openssl`) - path to the X509 certificate file.
|
||||
Examples:
|
||||
- `certFilePath=ca.pem`
|
||||
Disabled by default, possible values are `jdk` and `openssl`.
|
||||
|
||||
[Additional parameters may need to be provided](ssl.md).
|
||||
|
||||
- **jmxreporting** - enable JMX reporting if needed.
|
||||
Examples:
|
||||
- `jmxreporting=true`
|
||||
|
56
driver-cql/src/main/resources/ssl.md
Normal file
56
driver-cql/src/main/resources/ssl.md
Normal file
@ -0,0 +1,56 @@
|
||||
# SSL
|
||||
|
||||
Supported options:
|
||||
|
||||
- **ssl** - specifies the type of the SSL implementation.
|
||||
Disabled by default, possible values are `jdk`, and `openssl`.
|
||||
|
||||
- **tlsversion** - specify the TLS version to use for SSL.
|
||||
|
||||
Examples:
|
||||
- `tlsversion=TLSv1.2` (the default)
|
||||
|
||||
For `jdk` type, the following options are available:
|
||||
|
||||
- **truststore** - specify the path to the SSL truststore.
|
||||
|
||||
Examples:
|
||||
- `truststore=file.truststore`
|
||||
|
||||
- **tspass** - specify the password for the SSL truststore.
|
||||
|
||||
Examples:
|
||||
- `tspass=truststore_pass`
|
||||
|
||||
- **keystore** - specify the path to the SSL keystore.
|
||||
|
||||
Examples:
|
||||
- `keystore=file.keystore`
|
||||
|
||||
- **kspass** - specify the password for the SSL keystore.
|
||||
|
||||
Examples:
|
||||
- `kspass=keystore_pass`
|
||||
|
||||
- **keyPassword** - specify the password for the key.
|
||||
|
||||
Examples:
|
||||
- `keyPassword=password`
|
||||
|
||||
|
||||
For `openssl` type, the following options are available:
|
||||
|
||||
- **caCertFilePath** - path to the X509 CA certificate file.
|
||||
|
||||
Examples:
|
||||
- `caCertFilePath=cacert.crt`
|
||||
|
||||
- **certFilePath** - path to the X509 certificate file.
|
||||
|
||||
Examples:
|
||||
- `certFilePath=ca.pem`
|
||||
|
||||
- **keyFilePath** - path to the OpenSSL key file.
|
||||
|
||||
Examples:
|
||||
- `keyFilePath=file.key`
|
@ -37,6 +37,11 @@ Run a stdout activity named 'stdout-test', with definitions from activities/stdo
|
||||
- **ssl** - boolean to enable or disable ssl
|
||||
- default: false
|
||||
- dynamic: false
|
||||
|
||||
To enable, specifies the type of the SSL implementation with either `jdk` or `openssl`.
|
||||
|
||||
[Additional parameters may need to be provided](../../../../driver-cql/src/main/resources/ssl.md).
|
||||
|
||||
- **host** - this is the name to connect to (remote server IP address)
|
||||
- default: localhost
|
||||
- dynamic: false
|
||||
@ -50,5 +55,4 @@ Run a stdout activity named 'stdout-test', with definitions from activities/stdo
|
||||
|
||||
## Statement Format
|
||||
|
||||
Refer to the help for the stdout driver for for details.
|
||||
|
||||
Refer to the help for the stdout driver for details.
|
||||
|
@ -36,9 +36,15 @@ Run a stdout activity named 'stdout-test', with definitions from activities/stdo
|
||||
failed.
|
||||
- default: 3
|
||||
- dynamic: false
|
||||
|
||||
- **ssl** - boolean to enable or disable ssl
|
||||
- default: false
|
||||
- dynamic: false
|
||||
|
||||
To enable, specifies the type of the SSL implementation with either `jdk` or `openssl`.
|
||||
|
||||
[Additional parameters may need to be provided](../../../../driver-cql/src/main/resources/ssl.md).
|
||||
|
||||
- **host** - this is the name to bind to (local interface address)
|
||||
- default: localhost
|
||||
- dynamic: false
|
||||
@ -52,5 +58,4 @@ Run a stdout activity named 'stdout-test', with definitions from activities/stdo
|
||||
|
||||
## Statement Format
|
||||
|
||||
Refer to the help for the stdout driver for for details.
|
||||
|
||||
Refer to the help for the stdout driver for details.
|
||||
|
@ -17,29 +17,26 @@
|
||||
|
||||
package io.nosqlbench.engine.api.util;
|
||||
|
||||
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import io.netty.handler.ssl.SslContextBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.security.KeyStore;
|
||||
import java.util.Optional;
|
||||
import javax.net.ServerSocketFactory;
|
||||
import javax.net.SocketFactory;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.netty.handler.ssl.JdkSslContext;
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import io.netty.handler.ssl.SslContextBuilder;
|
||||
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
||||
|
||||
public class SSLKsFactory {
|
||||
private final static Logger logger = LoggerFactory.getLogger(SSLKsFactory.class);
|
||||
|
||||
private static SSLKsFactory instance = new SSLKsFactory();
|
||||
private static final SSLKsFactory instance = new SSLKsFactory();
|
||||
|
||||
/**
|
||||
* Consider: https://gist.github.com/artem-smotrakov/bd14e4bde4d7238f7e5ab12c697a86a3
|
||||
@ -52,16 +49,28 @@ public class SSLKsFactory {
|
||||
}
|
||||
|
||||
public ServerSocketFactory createSSLServerSocketFactory(ActivityDef def) {
|
||||
return ((SSLContext) getContext(def)).getServerSocketFactory();
|
||||
SslContext context = getContext(def);
|
||||
if (context == null) {
|
||||
throw new IllegalArgumentException("SSL is not enabled.");
|
||||
}
|
||||
// FIXME: potential incompatibility issue
|
||||
return ((JdkSslContext) context).context().getServerSocketFactory();
|
||||
}
|
||||
|
||||
public SocketFactory createSocketFactory(ActivityDef def) {
|
||||
return ((SSLContext) getContext(def)).getSocketFactory();
|
||||
SslContext context = getContext(def);
|
||||
if (context == null) {
|
||||
throw new IllegalArgumentException("SSL is not enabled.");
|
||||
}
|
||||
// FIXME: potential incompatibility issue
|
||||
return ((JdkSslContext) context).context().getSocketFactory();
|
||||
}
|
||||
|
||||
public Object getContext(ActivityDef def) {
|
||||
public SslContext getContext(ActivityDef def) {
|
||||
Optional<String> sslParam = def.getParams().getOptionalString("ssl");
|
||||
if (sslParam.isPresent()) {
|
||||
String tlsVersion = def.getParams().getOptionalString("tlsversion").orElse("TLSv1.2");
|
||||
|
||||
if (sslParam.get().equals("jdk") || sslParam.get().equals("true")) {
|
||||
if (sslParam.get().equals("true")) {
|
||||
logger.warn("Please update your 'ssl=true' parameter to 'ssl=jdk'");
|
||||
@ -69,104 +78,71 @@ public class SSLKsFactory {
|
||||
|
||||
Optional<String> keystorePath = def.getParams().getOptionalString("keystore");
|
||||
Optional<String> keystorePass = def.getParams().getOptionalString("kspass");
|
||||
char[] keyPassword = def.getParams().getOptionalString("keyPassword")
|
||||
.map(String::toCharArray)
|
||||
.orElse(null);
|
||||
Optional<String> truststorePath = def.getParams().getOptionalString("truststore");
|
||||
Optional<String> truststorePass = def.getParams().getOptionalString("tspass");
|
||||
String tlsVersion = def.getParams().getOptionalString("tlsversion").orElse("TLSv1.2");
|
||||
|
||||
if (keystorePath.isPresent() && keystorePass.isPresent() && truststorePath.isPresent() && truststorePass.isPresent()) {
|
||||
KeyStore ks = keystorePath.map(ksPath -> {
|
||||
try {
|
||||
KeyStore ks = KeyStore.getInstance("JKS");
|
||||
ks.load(new FileInputStream(keystorePath.get()), keystorePass.get().toCharArray());
|
||||
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||
kmf.init(ks, keystorePass.get().toCharArray());
|
||||
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
if (!truststorePath.get().isEmpty()) {
|
||||
KeyStore ts = KeyStore.getInstance("JKS");
|
||||
InputStream trustStore = new FileInputStream(truststorePath.get());
|
||||
|
||||
String truststorePassword = truststorePass.get();
|
||||
ts.load(trustStore, truststorePassword.toCharArray());
|
||||
tmf.init(ts);
|
||||
} else {
|
||||
tmf.init(ks);
|
||||
}
|
||||
|
||||
SSLContext sc = SSLContext.getInstance(tlsVersion);
|
||||
sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
|
||||
|
||||
return sc;
|
||||
return KeyStore.getInstance(new File(ksPath),
|
||||
keystorePass.map(String::toCharArray).orElse(null));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
throw new RuntimeException("Unable to load the keystore. Please check.", e);
|
||||
}
|
||||
}).orElse(null);
|
||||
|
||||
} else if (keystorePath.isEmpty() && keystorePass.isEmpty() && truststorePath.isPresent() && truststorePass.isPresent()) {
|
||||
try {
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
KeyStore ts = KeyStore.getInstance("JKS");
|
||||
InputStream trustStore = new FileInputStream(truststorePath.get());
|
||||
String truststorePassword = truststorePass.get();
|
||||
ts.load(trustStore, truststorePassword.toCharArray());
|
||||
tmf.init(ts);
|
||||
SSLContext sc = SSLContext.getInstance(tlsVersion);
|
||||
sc.init(null, tmf.getTrustManagers(), null);
|
||||
return sc;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("SSL arguments are incorrectly configured. Please Check.");
|
||||
KeyManagerFactory kmf;
|
||||
try {
|
||||
kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||
kmf.init(ks, keyPassword);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to init KeyManagerFactory. Please check.", e);
|
||||
}
|
||||
|
||||
KeyStore ts = truststorePath.map(tsPath -> {
|
||||
try {
|
||||
return KeyStore.getInstance(new File(tsPath),
|
||||
truststorePass.map(String::toCharArray).orElse(null));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to load the truststore. Please check.", e);
|
||||
}
|
||||
}).orElse(null);
|
||||
|
||||
} else if (sslParam.get().equals("openssl")) {
|
||||
|
||||
logger.info("Cluster builder proceeding with SSL and Client Auth");
|
||||
String keyPassword = def.getParams().getOptionalString("keyPassword").orElse(null);
|
||||
String caCertFileLocation = def.getParams().getOptionalString("caCertFilePath").orElse(null);
|
||||
String certFileLocation = def.getParams().getOptionalString("certFilePath").orElse(null);
|
||||
String keyFileLocation = def.getParams().getOptionalString("keyFilePath").orElse(null);
|
||||
String truststorePath = def.getParams().getOptionalString("truststore").orElse(null);
|
||||
String truststorePass = def.getParams().getOptionalString("tspass").orElse(null);
|
||||
TrustManagerFactory tmf;
|
||||
try {
|
||||
tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
tmf.init(ts != null ? ts : ks);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to init TrustManagerFactory. Please check.", e);
|
||||
}
|
||||
|
||||
try {
|
||||
KeyStore ks = KeyStore.getInstance("JKS", "SUN");
|
||||
char[] pass = keyPassword==null? null : keyPassword.toCharArray();
|
||||
ks.load(null, pass);
|
||||
|
||||
X509Certificate cert = (X509Certificate) CertificateFactory.
|
||||
getInstance("X509").
|
||||
generateCertificate(new FileInputStream(caCertFileLocation));
|
||||
|
||||
//set alias to cert
|
||||
ks.setCertificateEntry(cert.getSubjectX500Principal().getName(), cert);
|
||||
|
||||
TrustManagerFactory tMF = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
//String truststorePath = System.getProperty("javax.net.ssl.trustStore");
|
||||
|
||||
if (truststorePath != null && !truststorePath.isEmpty() && truststorePass != null) {
|
||||
KeyStore ts = KeyStore.getInstance("JKS");
|
||||
InputStream trustStore = new FileInputStream(truststorePath);
|
||||
ts.load(trustStore, truststorePass.toCharArray());
|
||||
tMF.init(ts);
|
||||
} else {
|
||||
tMF.init(ks);
|
||||
}
|
||||
|
||||
SslContext sslContext = SslContextBuilder
|
||||
.forClient()
|
||||
/* configured with the TrustManagerFactory that has the cert from the ca.cert
|
||||
* This tells the driver to trust the server during the SSL handshake */
|
||||
.trustManager(tMF)
|
||||
/* These are needed because the server is configured with require_client_auth
|
||||
* In this case the client's public key must be in the truststore on each DSE
|
||||
* server node and the CA configured */
|
||||
.keyManager(new File(certFileLocation), new File(keyFileLocation))
|
||||
.build();
|
||||
|
||||
return sslContext;
|
||||
return SslContextBuilder.forClient()
|
||||
.protocols(tlsVersion)
|
||||
.trustManager(tmf)
|
||||
.keyManager(kmf)
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else if (sslParam.get().equals("openssl")) {
|
||||
File caCertFileLocation = def.getParams().getOptionalString("caCertFilePath").map(File::new).orElse(null);
|
||||
File certFileLocation = def.getParams().getOptionalString("certFilePath").map(File::new).orElse(null);
|
||||
File keyFileLocation = def.getParams().getOptionalString("keyFilePath").map(File::new).orElse(null);
|
||||
|
||||
try {
|
||||
return SslContextBuilder.forClient()
|
||||
.protocols(tlsVersion)
|
||||
/* configured with the TrustManagerFactory that has the cert from the ca.cert
|
||||
* This tells the driver to trust the server during the SSL handshake */
|
||||
.trustManager(caCertFileLocation)
|
||||
/* These are needed if the server is configured with require_client_auth
|
||||
* In this case the client's public key must be in the truststore on each DSE
|
||||
* server node and the CA configured */
|
||||
.keyManager(certFileLocation, keyFileLocation)
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -0,0 +1,187 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2020 jshook
|
||||
* Licensed 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 io.nosqlbench.engine.api.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
public class SSLKsFactoryTest
|
||||
{
|
||||
@Test
|
||||
public void testJdkGetContextWithTruststoreAndKeystore() {
|
||||
String[] params = {
|
||||
"ssl=jdk",
|
||||
"truststore=src/test/resources/ssl/server_truststore.p12",
|
||||
"tspass=nosqlbench_server",
|
||||
"keystore=src/test/resources/ssl/client.p12",
|
||||
"kspass=nosqlbench_client",
|
||||
"keyPassword=nosqlbench_client"
|
||||
};
|
||||
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
||||
assertThat(SSLKsFactory.get().getContext(activityDef)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJdkGetContextWithTruststore() {
|
||||
String[] params = {
|
||||
"ssl=jdk",
|
||||
"truststore=src/test/resources/ssl/server_truststore.p12",
|
||||
"tspass=nosqlbench_server"
|
||||
};
|
||||
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
||||
assertThat(SSLKsFactory.get().getContext(activityDef)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJdkGetContextWithKeystore() {
|
||||
String[] params = {
|
||||
"ssl=jdk",
|
||||
"keystore=src/test/resources/ssl/client.p12",
|
||||
"kspass=nosqlbench_client",
|
||||
"keyPassword=nosqlbench_client"
|
||||
};
|
||||
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
||||
assertThat(SSLKsFactory.get().getContext(activityDef)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenSSLGetContextWithCaCertAndClientCert() {
|
||||
String[] params = {
|
||||
"ssl=openssl",
|
||||
"caCertFilePath=src/test/resources/ssl/cacert.crt",
|
||||
"certFilePath=src/test/resources/ssl/client_cert.pem",
|
||||
"keyFilePath=src/test/resources/ssl/client.key"
|
||||
};
|
||||
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
||||
assertThat(SSLKsFactory.get().getContext(activityDef)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenSSLGetContextWithCaCert() {
|
||||
String[] params = {
|
||||
"ssl=openssl",
|
||||
"caCertFilePath=src/test/resources/ssl/cacert.crt"
|
||||
};
|
||||
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
||||
assertThat(SSLKsFactory.get().getContext(activityDef)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJdkGetContext() {
|
||||
String[] params = {
|
||||
"ssl=jdk",
|
||||
"tlsversion=TLSv1.2",
|
||||
};
|
||||
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
||||
assertThat(SSLKsFactory.get().getContext(activityDef)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenSSLGetContext() {
|
||||
String[] params = {
|
||||
"ssl=openssl",
|
||||
"tlsversion=TLSv1.2",
|
||||
};
|
||||
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
||||
assertThat(SSLKsFactory.get().getContext(activityDef)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadKeystoreError() {
|
||||
String[] params = {
|
||||
"ssl=jdk",
|
||||
"keystore=src/test/resources/ssl/non_existing.p12",
|
||||
"kspass=nosqlbench_client",
|
||||
"keyPassword=nosqlbench_client"
|
||||
};
|
||||
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
||||
assertThatExceptionOfType(RuntimeException.class)
|
||||
.isThrownBy(() -> SSLKsFactory.get().getContext(activityDef))
|
||||
.withMessageMatching("Unable to load the keystore. Please check.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitKeyManagerFactoryError() {
|
||||
String[] params = {
|
||||
"ssl=jdk",
|
||||
"keystore=src/test/resources/ssl/client.p12",
|
||||
"kspass=nosqlbench_client",
|
||||
"keyPassword=incorrect_password"
|
||||
};
|
||||
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
||||
assertThatExceptionOfType(RuntimeException.class)
|
||||
.isThrownBy(() -> SSLKsFactory.get().getContext(activityDef))
|
||||
.withMessageMatching("Unable to init KeyManagerFactory. Please check.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadTruststoreError() {
|
||||
String[] params = {
|
||||
"ssl=jdk",
|
||||
"truststore=src/test/resources/ssl/non_existing.p12",
|
||||
"tspass=nosqlbench_server"
|
||||
};
|
||||
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
||||
assertThatExceptionOfType(RuntimeException.class)
|
||||
.isThrownBy(() -> SSLKsFactory.get().getContext(activityDef))
|
||||
.withMessageMatching("Unable to load the truststore. Please check.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenSSLGetContextWithCaCertError() {
|
||||
String[] params = {
|
||||
"ssl=openssl",
|
||||
"caCertFilePath=src/test/resources/ssl/non_existing.pem"
|
||||
};
|
||||
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
||||
assertThatExceptionOfType(RuntimeException.class)
|
||||
.isThrownBy(() -> SSLKsFactory.get().getContext(activityDef))
|
||||
.withMessageContaining("File does not contain valid certificates")
|
||||
.withCauseInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenSSLGetContextWithCertError() {
|
||||
String[] params = {
|
||||
"ssl=openssl",
|
||||
"certFilePath=src/test/resources/ssl/non_existing.pem"
|
||||
};
|
||||
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
||||
assertThatExceptionOfType(RuntimeException.class)
|
||||
.isThrownBy(() -> SSLKsFactory.get().getContext(activityDef))
|
||||
.withMessageContaining("File does not contain valid certificates")
|
||||
.withCauseInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenSSLGetContextWithKeyError() {
|
||||
String[] params = {
|
||||
"ssl=openssl",
|
||||
"keyFilePath=src/test/resources/ssl/non_existing.pem"
|
||||
};
|
||||
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
||||
assertThatExceptionOfType(RuntimeException.class)
|
||||
.isThrownBy(() -> SSLKsFactory.get().getContext(activityDef))
|
||||
.withMessageContaining("File does not contain valid private key")
|
||||
.withCauseInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
}
|
19
engine-api/src/test/resources/ssl/cacert.crt
Normal file
19
engine-api/src/test/resources/ssl/cacert.crt
Normal file
@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDEzCCAfsCFA3o5Ne8hiqC9/d5sJzmHg3t3iD8MA0GCSqGSIb3DQEBCwUAMEYx
|
||||
DzANBgNVBAMMBnJvb3RDYTETMBEGA1UECwwKbm9zcWxiZW5jaDERMA8GA1UECgwI
|
||||
RGF0YVN0YXgxCzAJBgNVBAYTAlVTMB4XDTIwMDUwNDIyMTcyOFoXDTMwMDUwMjIy
|
||||
MTcyOFowRjEPMA0GA1UEAwwGcm9vdENhMRMwEQYDVQQLDApub3NxbGJlbmNoMREw
|
||||
DwYDVQQKDAhEYXRhU3RheDELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUA
|
||||
A4IBDwAwggEKAoIBAQC5LFz/eR3k8d8F3cB6jnpsnOVIPonHwthcWKOXEy9Z8f31
|
||||
s70QhF7tkep3ExqUGhQJyjz4Cdk4cFvElMob9WuaoM5Qp4scKW5rQ47WCV660Ok1
|
||||
skKJXE/wLFc8edEn6vyvyUTpAce+B8HlY7cONiwA8mGALnYoPlsn2wFbTYIEGVVv
|
||||
My01990zgkMYwZErEYe2XXvc3gZEC7An16xzYrfYmYFfs0CsH2GUuDQtcFSmyTKH
|
||||
nYA+kn92JWEx1WMSsC07B8A0qwxdLJy6/d3VLHshbd3Aimf0Jhkg0mLHC5XlkVxr
|
||||
3pVYrdVEMuBee6A8v4BG8pG42Fjb1xSYwGM9GelvAgMBAAEwDQYJKoZIhvcNAQEL
|
||||
BQADggEBADz9MhhOA0/RF6iqW7gfWXlSpU2ks696IEhVRi+F9/y8jbKcwKHFchkN
|
||||
FRc1W6Xyx6LVunOw3zlbeMh+E0DzNTWMF+njcBQH7S5A8TcumU2CDgGNBdl1692x
|
||||
/z6nGhYIv4IBxaYEd30HPuRz3MXeVyfbGEnIU8jU0vsbfdtZqPdyEk3PNZoFvosk
|
||||
WhE0Z4KhYoPjwJLhpAnQgW3/RRSNJySReen5YTWJ0qQGYt1HO0Oqz+YgTsthofWc
|
||||
g/JbmCAD6L1YiCb6WCbDG5qrjwlzhw8bjiT3vw+y10ZIk07Vwbm4QlHSCoe0ayI4
|
||||
Pckz9yE0knBOV+Y1kV2DITKV6kYkWBw=
|
||||
-----END CERTIFICATE-----
|
28
engine-api/src/test/resources/ssl/client.key
Normal file
28
engine-api/src/test/resources/ssl/client.key
Normal file
@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC8NqAtNjapKtai
|
||||
hauevzX64ikBE0vugZLbXjlqfHYMoPqYBcP+Qj7JM1QnRbU0p15NCi/eUuNbzuGQ
|
||||
IzQFIo/IF3F3ivohOrTsunpFYdZlNCx3ixr4mJr4q5G/HbqGHPRSBGgyB/Sye550
|
||||
N819RiZh7d71dkSvig3CTnCK/d4NckSJ2dzYYEE/8ue+gfUsQZJrCPJcp2GTCEsq
|
||||
kq+3FMyVyZHC0V/BiCO9RouC1P5uE70CHKedpPUdZBJU8vRUMM7y75TqzKIT9/xI
|
||||
fZ0azUDWO89v/n99+O71M8uYhf4MMvS60DMgW8TfWqrToK+jYwnx4zVVburqu6b/
|
||||
JSsvODWvAgMBAAECggEANu+W1zuAvuXjGjL8Aez724vRvh+cxTQK4n7hMWS8rDj8
|
||||
jAz6xSce3mleAcyF9KV5j/EOQc1d0XlUO1cbIviQkS3Oj77//Vz+XC6d68x/4LBW
|
||||
3lm6+J7KdRTXCLqrq+OdqKbipt/Nm58bg/6ZuxwTrffZYToxGC+qjnGIxfkNrEyS
|
||||
jrTJRBOW7MlUhTjlnSYInsBZljRS7V2Zte3F53PCS8p2dbGRLu224bow/5oE5lt6
|
||||
x92cpjt+f/+a7Je+K2KoT/KAfG/SeGKzEQaYrqw1+WMEu4xwCvO+atJQDE0cShzl
|
||||
4vYwUp3GEmMhwdML817MyxxBKpcz+inqvCatZWgrOQKBgQDtVMLvgFPLnpmKJ1g9
|
||||
TGZE5a7FeZQVdF/ALnxko4pvw0ZyqPStlklfkyVvzPZYa99CP5p8oFNyVMONsLVk
|
||||
U57Y1pmU5Dm0e9E1Zqk4fMPL5h8FOv5F8g6vfg3ZEe2C0FvV7CekxchgcJKTmat6
|
||||
fzbwXPK+rW0Ld7etCiPAT+o/jQKBgQDLBMJ0gySusIkBG5gCHymAcgchYj16bbC0
|
||||
lbckxYzGXYJoqg/HpEfh7Auh6ofoXnYKRcZ696Rk7vQ6jTaNl3NOLMkxkdhHdQvK
|
||||
gze1+zWmzsakntfk+auf70M+feh2bSPe7tRoY6y+WYpTuxCGYgEV2WRNL1syEeXW
|
||||
8lmoDrLtKwKBgQC/MRWJU9wtoSsX/PI9D5sjzdSqCXOehQ3OCKT1fjo8JxhNrobO
|
||||
gM/DSwtRsdCTEvPcrtiJpa8T3+1Z7A11MVg6X0eChwlluImld3rDot8pF83NrOTC
|
||||
/GmQPwBw6txoEeqpv4GAYEU4S/gJKDbYjDt6D6cOrS+3mU5C/HQorTiM0QKBgFu0
|
||||
1rIS22sdy4V4lX2/3dtrptTpr6OyEPRB/OzbX+/rJZFp4J7qEp53JfoKG0JYCTIy
|
||||
uqmpW9VMK36Xc2EaXLefe3Ks0unUcXMVOwE1bNLg7NJH/nYsYd5pEhMUhQGZ4248
|
||||
rC5LeCi0Acw44AoUEzFvdeN31NYVR6GE8AL+QMzpAoGAJYdZbz/i+EoV23TiWnEE
|
||||
q0vBZ9dCKhYA3SaV/cwesFANGLOtFhhiUDA9/Jkw8P9eHoWfsqY4ud/nGGWeXvUu
|
||||
Ox576QcrYoIW6g0Gk7bwS2tSC943LAxS2YkAdMM27BhCZw7jAkmoxbQhf9t2IBMc
|
||||
ixHr+et58pQWFjF73/Ex16k=
|
||||
-----END PRIVATE KEY-----
|
BIN
engine-api/src/test/resources/ssl/client.p12
Normal file
BIN
engine-api/src/test/resources/ssl/client.p12
Normal file
Binary file not shown.
19
engine-api/src/test/resources/ssl/client_cert.pem
Normal file
19
engine-api/src/test/resources/ssl/client_cert.pem
Normal file
@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDEzCCAfsCFBuaP3upDuMBExO4l649oUURC/SkMA0GCSqGSIb3DQEBCwUAMEYx
|
||||
DzANBgNVBAMMBnJvb3RDYTETMBEGA1UECwwKbm9zcWxiZW5jaDERMA8GA1UECgwI
|
||||
RGF0YVN0YXgxCzAJBgNVBAYTAlVTMB4XDTIwMDUwNDIzMTQ1MloXDTMwMDUwMjIz
|
||||
MTQ1MlowRjEPMA0GA1UEAwwGY2xpZW50MRMwEQYDVQQLDApub3NxbGJlbmNoMREw
|
||||
DwYDVQQKDAhEYXRhU3RheDELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUA
|
||||
A4IBDwAwggEKAoIBAQC8NqAtNjapKtaihauevzX64ikBE0vugZLbXjlqfHYMoPqY
|
||||
BcP+Qj7JM1QnRbU0p15NCi/eUuNbzuGQIzQFIo/IF3F3ivohOrTsunpFYdZlNCx3
|
||||
ixr4mJr4q5G/HbqGHPRSBGgyB/Sye550N819RiZh7d71dkSvig3CTnCK/d4NckSJ
|
||||
2dzYYEE/8ue+gfUsQZJrCPJcp2GTCEsqkq+3FMyVyZHC0V/BiCO9RouC1P5uE70C
|
||||
HKedpPUdZBJU8vRUMM7y75TqzKIT9/xIfZ0azUDWO89v/n99+O71M8uYhf4MMvS6
|
||||
0DMgW8TfWqrToK+jYwnx4zVVburqu6b/JSsvODWvAgMBAAEwDQYJKoZIhvcNAQEL
|
||||
BQADggEBAFx3oSbS/6PfEYQjfesUMdHIPHGosrLfjzk0KUtSwRbmIJLIzujaUz4s
|
||||
UEyuxQhA6ERFNN8AUaighAO6IScYgVlxTeykeE3nGP+tZ+EuIxo6wXoo8WI85ivk
|
||||
OGspI+2Ne/mo45xSNdvnALnsPLEZM870LBe0UvHcSnDYR0V0d28BzzuAZfMRyT4z
|
||||
DkBSdouxahzzXIMi/TR0DDu4VMsVl55MNACgV+JDRAAwdYjN6kwJrtfVrsYBrIew
|
||||
TMUFXuEa1vDcsvAoALDN4+wGa/8TdPnAJuRirHVVfxoKb1XlcDCy/79pCOirUmbn
|
||||
ib/nCyq+MlFFYrE1YQSVZ2IM8x8n5d4=
|
||||
-----END CERTIFICATE-----
|
BIN
engine-api/src/test/resources/ssl/server_truststore.p12
Normal file
BIN
engine-api/src/test/resources/ssl/server_truststore.p12
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user