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:
|
||||
- `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());
|
||||
|
||||
assertThatExceptionOfType(RuntimeException.class)
|
||||
.isThrownBy(() -> SSLKsFactory.get().getContext(sslCfg))
|
||||
.withMessageMatching("Unable to init KeyManagerFactory. Please check.*");
|
||||
.isThrownBy(() -> SSLKsFactory.get().getContext(sslCfg))
|
||||
.withMessageMatching("Unable to init KeyManagerFactory. Please check.*");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -196,6 +196,62 @@ public class SSLKsFactoryTest {
|
||||
.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
|
||||
public void testOpenSSLGetContextWithCaCertError() {
|
||||
String[] params = {
|
||||
@ -241,16 +297,16 @@ public class SSLKsFactoryTest {
|
||||
@Test
|
||||
public void testOpenSSLGetContextWithMissingCertError() {
|
||||
String[] params = {
|
||||
"ssl=openssl",
|
||||
"caCertFilePath=src/test/resources/ssl/cacert.crt",
|
||||
"keyFilePath=src/test/resources/ssl/client.key"
|
||||
"ssl=openssl",
|
||||
"caCertFilePath=src/test/resources/ssl/cacert.crt",
|
||||
"keyFilePath=src/test/resources/ssl/client.key"
|
||||
};
|
||||
ActivityDef activityDef = ActivityDef.parseActivityDef(String.join(";", params));
|
||||
NBConfiguration sslCfg = SSLKsFactory.get().getConfigModel().extractConfig(activityDef.getParams());
|
||||
assertThatExceptionOfType(RuntimeException.class)
|
||||
.isThrownBy(() -> SSLKsFactory.get().getContext(sslCfg))
|
||||
.withMessageContaining("Unable to load key from")
|
||||
.withCauseInstanceOf(IllegalArgumentException.class);
|
||||
.isThrownBy(() -> SSLKsFactory.get().getContext(sslCfg))
|
||||
.withMessageContaining("Unable to load key from")
|
||||
.withCauseInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,9 +22,7 @@ import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.net.ServerSocketFactory;
|
||||
import javax.net.SocketFactory;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.*;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyFactory;
|
||||
@ -45,11 +43,31 @@ public class SSLKsFactory implements NBMapConfigurable {
|
||||
|
||||
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 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);
|
||||
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 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 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
|
||||
*/
|
||||
@ -70,6 +88,7 @@ public class SSLKsFactory implements NBMapConfigurable {
|
||||
|
||||
public SocketFactory createSocketFactory(NBConfiguration cfg) {
|
||||
SSLContext context = getContext(cfg);
|
||||
|
||||
if (context == null) {
|
||||
throw new IllegalArgumentException("SSL is not enabled.");
|
||||
}
|
||||
@ -81,18 +100,26 @@ public class SSLKsFactory implements NBMapConfigurable {
|
||||
if (sslParam.isPresent()) {
|
||||
String tlsVersion = cfg.getOptional("tlsversion").orElse(DEFAULT_TLSVERSION);
|
||||
|
||||
KeyStore keyStore;
|
||||
KeyStore keyStore = 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")) {
|
||||
|
||||
final char[] keyStorePassword = cfg.getOptional("kspass")
|
||||
.map(String::toCharArray)
|
||||
.orElse(null);
|
||||
.map(String::toCharArray)
|
||||
.orElse(null);
|
||||
keyPassword = cfg.getOptional("keyPassword", "keypassword")
|
||||
.map(String::toCharArray)
|
||||
.orElse(keyStorePassword);
|
||||
.map(String::toCharArray)
|
||||
.orElse(keyStorePassword);
|
||||
|
||||
keyStore = cfg.getOptional("keystore").map(ksPath -> {
|
||||
try {
|
||||
@ -105,9 +132,9 @@ public class SSLKsFactory implements NBMapConfigurable {
|
||||
trustStore = cfg.getOptional("truststore").map(tsPath -> {
|
||||
try {
|
||||
return KeyStore.getInstance(new File(tsPath),
|
||||
cfg.getOptional("tspass")
|
||||
.map(String::toCharArray)
|
||||
.orElse(null));
|
||||
cfg.getOptional("tspass")
|
||||
.map(String::toCharArray)
|
||||
.orElse(null));
|
||||
} catch (Exception 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")) {
|
||||
try {
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
keyStore = KeyStore.getInstance("JKS");
|
||||
keyStore.load(null, null);
|
||||
|
||||
@ -125,9 +152,8 @@ public class SSLKsFactory implements NBMapConfigurable {
|
||||
return cf.generateCertificate(is);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
String.format("Unable to load cert from %s: " + e, certFilePath),
|
||||
e
|
||||
);
|
||||
String.format("Unable to load cert from %s: due to:%s ", certFilePath,
|
||||
e.getMessage()), e);
|
||||
}
|
||||
}).orElse(null);
|
||||
|
||||
@ -135,37 +161,33 @@ public class SSLKsFactory implements NBMapConfigurable {
|
||||
keyStore.setCertificateEntry("certFile", cert);
|
||||
|
||||
File keyFile = cfg.getOptional("keyfilepath").map(File::new)
|
||||
.orElse(null);
|
||||
.orElse(null);
|
||||
|
||||
if (keyFile != null) {
|
||||
try {
|
||||
keyPassword = cfg.getOptional("keyPassword", "keypassword")
|
||||
.map(String::toCharArray)
|
||||
.orElse("temp_key_password".toCharArray());
|
||||
.map(String::toCharArray)
|
||||
.orElse("temp_key_password".toCharArray());
|
||||
|
||||
KeyFactory kf = KeyFactory.getInstance("RSA");
|
||||
PrivateKey key = kf.generatePrivate(new PKCS8EncodedKeySpec(loadKeyFromPem(keyFile)));
|
||||
keyStore.setKeyEntry("key", key, keyPassword,
|
||||
cert != null ? new Certificate[]{cert} : null);
|
||||
cert != null ? new Certificate[]{cert} : null);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(String.format("Unable to load key from %s: " + e,
|
||||
keyFile),
|
||||
e);
|
||||
throw new RuntimeException(String.format("Unable to load key from: %s due to: %s ",
|
||||
keyFile, e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
ts.load(null, null);
|
||||
|
||||
Certificate caCert = cf.generateCertificate(is);
|
||||
ts.setCertificateEntry("caCertFile", caCert);
|
||||
ts.setCertificateEntry("caCertFile", cf.generateCertificate(is));
|
||||
return ts;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(String.format("Unable to load caCert from %s: " + e,
|
||||
caCertFilePath),
|
||||
e);
|
||||
throw new RuntimeException(String.format("Unable to load caCert from: %s due to: %s",
|
||||
caCertFilePath, e.getMessage()), e);
|
||||
}
|
||||
}).orElse(null);
|
||||
|
||||
@ -183,20 +205,26 @@ public class SSLKsFactory implements NBMapConfigurable {
|
||||
kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||
kmf.init(keyStore, keyPassword);
|
||||
} 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;
|
||||
try {
|
||||
tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
tmf.init(trustStore != null ? trustStore : keyStore);
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to init TrustManagerFactory: " + e, e);
|
||||
throw new RuntimeException("Unable to init TrustManagerFactory: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
try {
|
||||
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;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
@ -229,18 +257,19 @@ public class SSLKsFactory implements NBMapConfigurable {
|
||||
|
||||
public NBConfigModel getConfigModel() {
|
||||
return ConfigModel.of(SSLKsFactory.class,
|
||||
Param.optional("ssl")
|
||||
.setDescription("Enable ssl and set the mode")
|
||||
.setRegex("jdk|openssl"),
|
||||
Param.defaultTo("tlsversion", DEFAULT_TLSVERSION),
|
||||
Param.optional("kspass"),
|
||||
Param.optional("keyPassword"),
|
||||
Param.optional("keystore"),
|
||||
Param.optional("truststore"),
|
||||
Param.optional("tspass"),
|
||||
Param.optional(List.of("keyFilePath","keyfilepath")),
|
||||
Param.optional("caCertFilePath"),
|
||||
Param.optional("certFilePath")
|
||||
Param.optional("ssl")
|
||||
.setDescription("Enable ssl and set the mode")
|
||||
.setRegex("jdk|openssl"),
|
||||
Param.defaultTo("tlsversion", DEFAULT_TLSVERSION),
|
||||
Param.optional("kspass"),
|
||||
Param.optional("keyPassword"),
|
||||
Param.optional("keystore"),
|
||||
Param.optional("truststore"),
|
||||
Param.optional("tspass"),
|
||||
Param.optional(List.of("keyFilePath", "keyfilepath")),
|
||||
Param.optional("caCertFilePath"),
|
||||
Param.optional("certFilePath"),
|
||||
Param.optional("sslValidation")
|
||||
).asReadOnly();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user