mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
Bypass SSL validation option (#1289)
* Bypass ssl validation option * TrustManager inclusion
This commit is contained in:
parent
656960f483
commit
27644273fd
@ -54,3 +54,8 @@ For `openssl` type, the following options are available:
|
|||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
- `keyFilePath=file.key`
|
- `keyFilePath=file.key`
|
||||||
|
- **sslValidation** - optional boolean flag to enable/disable SSLValidation.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- `sslValidation=true` (the default)
|
||||||
|
- `sslValidation=false`
|
@ -178,8 +178,8 @@ public class SSLKsFactoryTest {
|
|||||||
NBConfiguration sslCfg = SSLKsFactory.get().getConfigModel().extractConfig(activityDef.getParams());
|
NBConfiguration sslCfg = SSLKsFactory.get().getConfigModel().extractConfig(activityDef.getParams());
|
||||||
|
|
||||||
assertThatExceptionOfType(RuntimeException.class)
|
assertThatExceptionOfType(RuntimeException.class)
|
||||||
.isThrownBy(() -> SSLKsFactory.get().getContext(sslCfg))
|
.isThrownBy(() -> SSLKsFactory.get().getContext(sslCfg))
|
||||||
.withMessageMatching("Unable to init KeyManagerFactory. Please check.*");
|
.withMessageMatching("Unable to init KeyManagerFactory. Please check.*");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -196,6 +196,62 @@ public class SSLKsFactoryTest {
|
|||||||
.withMessageMatching("Unable to load the truststore: .*");
|
.withMessageMatching("Unable to load the truststore: .*");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSSLValidationActive() {
|
||||||
|
{
|
||||||
|
final String[] params1 = {
|
||||||
|
"ssl=openssl",
|
||||||
|
"certFilePath=src/test/resources/ssl/client_cert.pem",
|
||||||
|
"keyFilePath=src/test/resources/ssl/client.key",
|
||||||
|
"sslValidation=true"
|
||||||
|
};
|
||||||
|
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params1));
|
||||||
|
NBConfiguration sslCfg1 = SSLKsFactory.get().getConfigModel().extractConfig(activityDef.getParams());
|
||||||
|
assertThat(SSLKsFactory.get().getContext(sslCfg1)).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final String[] params2 = {
|
||||||
|
"ssl=jdk",
|
||||||
|
"keystore=src/test/resources/ssl/client_diff_password.p12",
|
||||||
|
"kspass=nosqlbench_client",
|
||||||
|
"keyPassword=nosqlbench",
|
||||||
|
"sslValidation=true"
|
||||||
|
};
|
||||||
|
ActivityDef activityDef2 = ActivityDef.parseActivityDef(String.join(";", params2));
|
||||||
|
NBConfiguration sslCfg2 = SSLKsFactory.get().getConfigModel().extractConfig(activityDef2.getParams());
|
||||||
|
assertThat(SSLKsFactory.get().getContext(sslCfg2)).isNotNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSSLValidationNotActive() {
|
||||||
|
{
|
||||||
|
final String[] params1 = {
|
||||||
|
"ssl=openssl",
|
||||||
|
"certFilePath=src/test/resources/ssl/client_cert.pem",
|
||||||
|
"keyFilePath=src/test/resources/ssl/client.key",
|
||||||
|
"sslValidation=false"
|
||||||
|
};
|
||||||
|
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params1));
|
||||||
|
NBConfiguration sslCfg1 = SSLKsFactory.get().getConfigModel().extractConfig(activityDef.getParams());
|
||||||
|
assertThat(SSLKsFactory.get().getContext(sslCfg1)).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final String[] params2 = {
|
||||||
|
"ssl=jdk",
|
||||||
|
"keystore=src/test/resources/ssl/client_diff_password.p12",
|
||||||
|
"kspass=nosqlbench_client",
|
||||||
|
"keyPassword=nosqlbench",
|
||||||
|
"sslValidation=false"
|
||||||
|
};
|
||||||
|
ActivityDef activityDef2 = ActivityDef.parseActivityDef(String.join(";", params2));
|
||||||
|
NBConfiguration sslCfg2 = SSLKsFactory.get().getConfigModel().extractConfig(activityDef2.getParams());
|
||||||
|
assertThat(SSLKsFactory.get().getContext(sslCfg2)).isNotNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOpenSSLGetContextWithCaCertError() {
|
public void testOpenSSLGetContextWithCaCertError() {
|
||||||
String[] params = {
|
String[] params = {
|
||||||
@ -241,16 +297,16 @@ public class SSLKsFactoryTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testOpenSSLGetContextWithMissingCertError() {
|
public void testOpenSSLGetContextWithMissingCertError() {
|
||||||
String[] params = {
|
String[] params = {
|
||||||
"ssl=openssl",
|
"ssl=openssl",
|
||||||
"caCertFilePath=src/test/resources/ssl/cacert.crt",
|
"caCertFilePath=src/test/resources/ssl/cacert.crt",
|
||||||
"keyFilePath=src/test/resources/ssl/client.key"
|
"keyFilePath=src/test/resources/ssl/client.key"
|
||||||
};
|
};
|
||||||
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
||||||
NBConfiguration sslCfg = SSLKsFactory.get().getConfigModel().extractConfig(activityDef.getParams());
|
NBConfiguration sslCfg = SSLKsFactory.get().getConfigModel().extractConfig(activityDef.getParams());
|
||||||
assertThatExceptionOfType(RuntimeException.class)
|
assertThatExceptionOfType(RuntimeException.class)
|
||||||
.isThrownBy(() -> SSLKsFactory.get().getContext(sslCfg))
|
.isThrownBy(() -> SSLKsFactory.get().getContext(sslCfg))
|
||||||
.withMessageContaining("Unable to load key from")
|
.withMessageContaining("Unable to load key from")
|
||||||
.withCauseInstanceOf(IllegalArgumentException.class);
|
.withCauseInstanceOf(IllegalArgumentException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,7 @@ import org.apache.logging.log4j.Logger;
|
|||||||
|
|
||||||
import javax.net.ServerSocketFactory;
|
import javax.net.ServerSocketFactory;
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
import javax.net.ssl.KeyManagerFactory;
|
import javax.net.ssl.*;
|
||||||
import javax.net.ssl.SSLContext;
|
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.KeyFactory;
|
import java.security.KeyFactory;
|
||||||
@ -45,11 +43,31 @@ public class SSLKsFactory implements NBMapConfigurable {
|
|||||||
|
|
||||||
private static final SSLKsFactory instance = new SSLKsFactory();
|
private static final SSLKsFactory instance = new SSLKsFactory();
|
||||||
|
|
||||||
private static final Pattern CERT_PATTERN = Pattern.compile("-+BEGIN\\s+.*CERTIFICATE[^-]*-+(?:\\s|\\r|\\n){1,10}([a-z0-9+/=\\r\\n]+)-+END\\s+.*CERTIFICATE[^-]*-+", Pattern.CASE_INSENSITIVE);
|
private static final Pattern CERT_PATTERN = Pattern.compile("-+BEGIN\\s+.*CERTIFICATE[^-]*-+(?:\\s|\\r|\\n)" +
|
||||||
private static final Pattern KEY_PATTERN = Pattern.compile("-+BEGIN\\s+.*PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n){1,10}([a-z0-9+/=\\r\\n]+)-+END\\s+.*PRIVATE\\s+KEY[^-]*-+", Pattern.CASE_INSENSITIVE);
|
"{1,10}([a-z0-9+/=\\r\\n]+)-+END\\s+.*CERTIFICATE[^-]*-+", Pattern.CASE_INSENSITIVE);
|
||||||
|
private static final Pattern KEY_PATTERN = Pattern.compile("-+BEGIN\\s+.*PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)" +
|
||||||
|
"{1,10}([a-z0-9+/=\\r\\n]+)-+END\\s+.*PRIVATE\\s+KEY[^-]*-+", Pattern.CASE_INSENSITIVE);
|
||||||
|
|
||||||
public static final String SSL = "ssl";
|
public static final String SSL = "ssl";
|
||||||
public static final String DEFAULT_TLSVERSION = "TLSv1.2";
|
public static final String DEFAULT_TLSVERSION = "TLSv1.2";
|
||||||
|
|
||||||
|
private static final TrustManager[] trustAllCerts = new TrustManager[]{
|
||||||
|
new X509TrustManager() {
|
||||||
|
@Override
|
||||||
|
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return new java.security.cert.X509Certificate[]{};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consider: https://gist.github.com/artem-smotrakov/bd14e4bde4d7238f7e5ab12c697a86a3
|
* Consider: https://gist.github.com/artem-smotrakov/bd14e4bde4d7238f7e5ab12c697a86a3
|
||||||
*/
|
*/
|
||||||
@ -70,6 +88,7 @@ public class SSLKsFactory implements NBMapConfigurable {
|
|||||||
|
|
||||||
public SocketFactory createSocketFactory(NBConfiguration cfg) {
|
public SocketFactory createSocketFactory(NBConfiguration cfg) {
|
||||||
SSLContext context = getContext(cfg);
|
SSLContext context = getContext(cfg);
|
||||||
|
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
throw new IllegalArgumentException("SSL is not enabled.");
|
throw new IllegalArgumentException("SSL is not enabled.");
|
||||||
}
|
}
|
||||||
@ -81,18 +100,26 @@ public class SSLKsFactory implements NBMapConfigurable {
|
|||||||
if (sslParam.isPresent()) {
|
if (sslParam.isPresent()) {
|
||||||
String tlsVersion = cfg.getOptional("tlsversion").orElse(DEFAULT_TLSVERSION);
|
String tlsVersion = cfg.getOptional("tlsversion").orElse(DEFAULT_TLSVERSION);
|
||||||
|
|
||||||
KeyStore keyStore;
|
KeyStore keyStore = null;
|
||||||
char[] keyPassword = null;
|
char[] keyPassword = null;
|
||||||
KeyStore trustStore;
|
KeyStore trustStore = null;
|
||||||
|
|
||||||
|
boolean activeSSLValidation = true;
|
||||||
|
if (cfg.getOptional("sslValidation").isPresent() && cfg.getOptional("sslValidation")
|
||||||
|
.get().equals("false")) {
|
||||||
|
logger.warn("sslValidation=false, skipping SSL validation. " +
|
||||||
|
"THIS OPTION SHOULD ONLY BE TESTING AND NON-PROD ENVIRONMENTS");
|
||||||
|
activeSSLValidation = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (sslParam.get().equals("jdk")) {
|
if (sslParam.get().equals("jdk")) {
|
||||||
|
|
||||||
final char[] keyStorePassword = cfg.getOptional("kspass")
|
final char[] keyStorePassword = cfg.getOptional("kspass")
|
||||||
.map(String::toCharArray)
|
.map(String::toCharArray)
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
keyPassword = cfg.getOptional("keyPassword", "keypassword")
|
keyPassword = cfg.getOptional("keyPassword", "keypassword")
|
||||||
.map(String::toCharArray)
|
.map(String::toCharArray)
|
||||||
.orElse(keyStorePassword);
|
.orElse(keyStorePassword);
|
||||||
|
|
||||||
keyStore = cfg.getOptional("keystore").map(ksPath -> {
|
keyStore = cfg.getOptional("keystore").map(ksPath -> {
|
||||||
try {
|
try {
|
||||||
@ -105,9 +132,9 @@ public class SSLKsFactory implements NBMapConfigurable {
|
|||||||
trustStore = cfg.getOptional("truststore").map(tsPath -> {
|
trustStore = cfg.getOptional("truststore").map(tsPath -> {
|
||||||
try {
|
try {
|
||||||
return KeyStore.getInstance(new File(tsPath),
|
return KeyStore.getInstance(new File(tsPath),
|
||||||
cfg.getOptional("tspass")
|
cfg.getOptional("tspass")
|
||||||
.map(String::toCharArray)
|
.map(String::toCharArray)
|
||||||
.orElse(null));
|
.orElse(null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Unable to load the truststore: " + e, e);
|
throw new RuntimeException("Unable to load the truststore: " + e, e);
|
||||||
}
|
}
|
||||||
@ -115,8 +142,8 @@ public class SSLKsFactory implements NBMapConfigurable {
|
|||||||
|
|
||||||
} else if (sslParam.get().equals("openssl")) {
|
} else if (sslParam.get().equals("openssl")) {
|
||||||
try {
|
try {
|
||||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
|
||||||
|
|
||||||
|
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||||
keyStore = KeyStore.getInstance("JKS");
|
keyStore = KeyStore.getInstance("JKS");
|
||||||
keyStore.load(null, null);
|
keyStore.load(null, null);
|
||||||
|
|
||||||
@ -125,9 +152,8 @@ public class SSLKsFactory implements NBMapConfigurable {
|
|||||||
return cf.generateCertificate(is);
|
return cf.generateCertificate(is);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
String.format("Unable to load cert from %s: " + e, certFilePath),
|
String.format("Unable to load cert from %s: due to:%s ", certFilePath,
|
||||||
e
|
e.getMessage()), e);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}).orElse(null);
|
}).orElse(null);
|
||||||
|
|
||||||
@ -135,37 +161,33 @@ public class SSLKsFactory implements NBMapConfigurable {
|
|||||||
keyStore.setCertificateEntry("certFile", cert);
|
keyStore.setCertificateEntry("certFile", cert);
|
||||||
|
|
||||||
File keyFile = cfg.getOptional("keyfilepath").map(File::new)
|
File keyFile = cfg.getOptional("keyfilepath").map(File::new)
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
|
|
||||||
if (keyFile != null) {
|
if (keyFile != null) {
|
||||||
try {
|
try {
|
||||||
keyPassword = cfg.getOptional("keyPassword", "keypassword")
|
keyPassword = cfg.getOptional("keyPassword", "keypassword")
|
||||||
.map(String::toCharArray)
|
.map(String::toCharArray)
|
||||||
.orElse("temp_key_password".toCharArray());
|
.orElse("temp_key_password".toCharArray());
|
||||||
|
|
||||||
KeyFactory kf = KeyFactory.getInstance("RSA");
|
KeyFactory kf = KeyFactory.getInstance("RSA");
|
||||||
PrivateKey key = kf.generatePrivate(new PKCS8EncodedKeySpec(loadKeyFromPem(keyFile)));
|
PrivateKey key = kf.generatePrivate(new PKCS8EncodedKeySpec(loadKeyFromPem(keyFile)));
|
||||||
keyStore.setKeyEntry("key", key, keyPassword,
|
keyStore.setKeyEntry("key", key, keyPassword,
|
||||||
cert != null ? new Certificate[]{cert} : null);
|
cert != null ? new Certificate[]{cert} : null);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(String.format("Unable to load key from %s: " + e,
|
throw new RuntimeException(String.format("Unable to load key from: %s due to: %s ",
|
||||||
keyFile),
|
keyFile, e.getMessage()), e);
|
||||||
e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trustStore = cfg.getOptional("caCertFilePath", "cacertfilepath").map(caCertFilePath -> {
|
trustStore = cfg.getOptional("caCertFilePath", "cacertfilepath").map(caCertFilePath -> {
|
||||||
try (InputStream is = new FileInputStream(new File(caCertFilePath))) {
|
try (InputStream is = new FileInputStream(caCertFilePath)) {
|
||||||
KeyStore ts = KeyStore.getInstance("JKS");
|
KeyStore ts = KeyStore.getInstance("JKS");
|
||||||
ts.load(null, null);
|
ts.load(null, null);
|
||||||
|
ts.setCertificateEntry("caCertFile", cf.generateCertificate(is));
|
||||||
Certificate caCert = cf.generateCertificate(is);
|
|
||||||
ts.setCertificateEntry("caCertFile", caCert);
|
|
||||||
return ts;
|
return ts;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(String.format("Unable to load caCert from %s: " + e,
|
throw new RuntimeException(String.format("Unable to load caCert from: %s due to: %s",
|
||||||
caCertFilePath),
|
caCertFilePath, e.getMessage()), e);
|
||||||
e);
|
|
||||||
}
|
}
|
||||||
}).orElse(null);
|
}).orElse(null);
|
||||||
|
|
||||||
@ -183,20 +205,26 @@ public class SSLKsFactory implements NBMapConfigurable {
|
|||||||
kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||||
kmf.init(keyStore, keyPassword);
|
kmf.init(keyStore, keyPassword);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Unable to init KeyManagerFactory. Please check password and location: " + e, e);
|
throw new RuntimeException("Unable to init KeyManagerFactory. Please check password and location: "
|
||||||
|
+ e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
TrustManagerFactory tmf;
|
TrustManagerFactory tmf;
|
||||||
try {
|
try {
|
||||||
tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||||
tmf.init(trustStore != null ? trustStore : keyStore);
|
tmf.init(trustStore != null ? trustStore : keyStore);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Unable to init TrustManagerFactory: " + e, e);
|
throw new RuntimeException("Unable to init TrustManagerFactory: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SSLContext sslContext = SSLContext.getInstance(tlsVersion);
|
SSLContext sslContext = SSLContext.getInstance(tlsVersion);
|
||||||
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
|
if (!activeSSLValidation) {
|
||||||
|
sslContext.init(kmf.getKeyManagers(), trustAllCerts, new SecureRandom());
|
||||||
|
} else {
|
||||||
|
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
|
||||||
|
}
|
||||||
return sslContext;
|
return sslContext;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
@ -229,18 +257,19 @@ public class SSLKsFactory implements NBMapConfigurable {
|
|||||||
|
|
||||||
public NBConfigModel getConfigModel() {
|
public NBConfigModel getConfigModel() {
|
||||||
return ConfigModel.of(SSLKsFactory.class,
|
return ConfigModel.of(SSLKsFactory.class,
|
||||||
Param.optional("ssl")
|
Param.optional("ssl")
|
||||||
.setDescription("Enable ssl and set the mode")
|
.setDescription("Enable ssl and set the mode")
|
||||||
.setRegex("jdk|openssl"),
|
.setRegex("jdk|openssl"),
|
||||||
Param.defaultTo("tlsversion", DEFAULT_TLSVERSION),
|
Param.defaultTo("tlsversion", DEFAULT_TLSVERSION),
|
||||||
Param.optional("kspass"),
|
Param.optional("kspass"),
|
||||||
Param.optional("keyPassword"),
|
Param.optional("keyPassword"),
|
||||||
Param.optional("keystore"),
|
Param.optional("keystore"),
|
||||||
Param.optional("truststore"),
|
Param.optional("truststore"),
|
||||||
Param.optional("tspass"),
|
Param.optional("tspass"),
|
||||||
Param.optional(List.of("keyFilePath","keyfilepath")),
|
Param.optional(List.of("keyFilePath", "keyfilepath")),
|
||||||
Param.optional("caCertFilePath"),
|
Param.optional("caCertFilePath"),
|
||||||
Param.optional("certFilePath")
|
Param.optional("certFilePath"),
|
||||||
|
Param.optional("sslValidation")
|
||||||
).asReadOnly();
|
).asReadOnly();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user