diff --git a/src/java/org/apache/cassandra/auth/MutualTlsAuthenticator.java b/src/java/org/apache/cassandra/auth/MutualTlsAuthenticator.java index 0337291a9d..7c5a6654f7 100644 --- a/src/java/org/apache/cassandra/auth/MutualTlsAuthenticator.java +++ b/src/java/org/apache/cassandra/auth/MutualTlsAuthenticator.java @@ -44,7 +44,7 @@ import org.apache.cassandra.schema.SchemaConstants; import org.apache.cassandra.utils.NoSpamLogger; import static org.apache.cassandra.auth.IAuthenticator.AuthenticationMode.MTLS; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; /** * Performs mTLS authentication for client connections by extracting identities from client certificate diff --git a/src/java/org/apache/cassandra/auth/MutualTlsInternodeAuthenticator.java b/src/java/org/apache/cassandra/auth/MutualTlsInternodeAuthenticator.java index c1fcbd6eab..91500cbeb2 100644 --- a/src/java/org/apache/cassandra/auth/MutualTlsInternodeAuthenticator.java +++ b/src/java/org/apache/cassandra/auth/MutualTlsInternodeAuthenticator.java @@ -49,7 +49,7 @@ import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.metrics.MutualTlsMetrics; import org.apache.cassandra.utils.NoSpamLogger; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; /** * Performs mTLS authentication for internode connections by extracting identities from the certificates of incoming diff --git a/src/java/org/apache/cassandra/auth/MutualTlsWithPasswordFallbackAuthenticator.java b/src/java/org/apache/cassandra/auth/MutualTlsWithPasswordFallbackAuthenticator.java index 219353d76a..f994399f21 100644 --- a/src/java/org/apache/cassandra/auth/MutualTlsWithPasswordFallbackAuthenticator.java +++ b/src/java/org/apache/cassandra/auth/MutualTlsWithPasswordFallbackAuthenticator.java @@ -81,7 +81,7 @@ public class MutualTlsWithPasswordFallbackAuthenticator extends PasswordAuthenti public void validateConfiguration() throws ConfigurationException { Config config = DatabaseDescriptor.getRawConfig(); - if (config.client_encryption_options.getClientAuth() == EncryptionOptions.ClientAuth.NOT_REQUIRED) + if (config.client_encryption_options.getClientAuth() == EncryptionOptions.ClientEncryptionOptions.ClientAuth.NOT_REQUIRED) { String msg = "MutualTlsWithPasswordFallbackAuthenticator requires client_encryption_options.require_client_auth to be optional/true"; throw new ConfigurationException(msg); diff --git a/src/java/org/apache/cassandra/config/Config.java b/src/java/org/apache/cassandra/config/Config.java index 65179fcd7e..1a3da1033f 100644 --- a/src/java/org/apache/cassandra/config/Config.java +++ b/src/java/org/apache/cassandra/config/Config.java @@ -454,7 +454,7 @@ public class Config public String failure_detector = "FailureDetector"; public EncryptionOptions.ServerEncryptionOptions server_encryption_options = new EncryptionOptions.ServerEncryptionOptions(); - public EncryptionOptions client_encryption_options = new EncryptionOptions(); + public EncryptionOptions.ClientEncryptionOptions client_encryption_options = new EncryptionOptions.ClientEncryptionOptions(); public JMXServerOptions jmx_server_options; diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java index 0439dbb00c..6167352897 100644 --- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java +++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java @@ -156,7 +156,7 @@ import static org.apache.cassandra.config.CassandraRelevantProperties.UNSAFE_SYS import static org.apache.cassandra.config.DataRateSpec.DataRateUnit.BYTES_PER_SECOND; import static org.apache.cassandra.config.DataRateSpec.DataRateUnit.MEBIBYTES_PER_SECOND; import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.MEBIBYTES; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; import static org.apache.cassandra.db.ConsistencyLevel.ALL; import static org.apache.cassandra.db.ConsistencyLevel.EACH_QUORUM; import static org.apache.cassandra.db.ConsistencyLevel.LOCAL_QUORUM; @@ -1088,10 +1088,10 @@ public class DatabaseDescriptor } else if (JMXServerOptions.isEnabledBySystemProperties()) { - throw new ConfigurationException("Configure either jmx_server_options in cassandra.yaml and comment out " + - "configure_jmx function call in cassandra-env.sh or keep cassandra-env.sh " + - "to call configure_jmx function but you have to keep jmx_server_options " + - "in cassandra.yaml commented out."); + throw new ConfigurationException("Configure either jmx_server_options in cassandra.yaml and comment out " + + "configure_jmx function call in cassandra-env.sh or keep cassandra-env.sh " + + "to call configure_jmx function but you have to keep jmx_server_options " + + "in cassandra.yaml commented out."); } conf.jmx_server_options.jmx_encryption_options.applyConfig(); @@ -3973,7 +3973,7 @@ public class DatabaseDescriptor conf.server_encryption_options = encryptionOptions; } - public static EncryptionOptions getNativeProtocolEncryptionOptions() + public static EncryptionOptions.ClientEncryptionOptions getNativeProtocolEncryptionOptions() { return conf.client_encryption_options; } @@ -3984,7 +3984,7 @@ public class DatabaseDescriptor } @VisibleForTesting - public static void updateNativeProtocolEncryptionOptions(Function update) + public static void updateNativeProtocolEncryptionOptions(Function update) { conf.client_encryption_options = update.apply(conf.client_encryption_options); } diff --git a/src/java/org/apache/cassandra/config/EncryptionOptions.java b/src/java/org/apache/cassandra/config/EncryptionOptions.java index 07f78b9a5e..5f94c14bcb 100644 --- a/src/java/org/apache/cassandra/config/EncryptionOptions.java +++ b/src/java/org/apache/cassandra/config/EncryptionOptions.java @@ -17,7 +17,6 @@ */ package org.apache.cassandra.config; -import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -46,10 +45,8 @@ import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; * Examples of such options are: supported cipher-suites, ssl protocol with version, accepted protocols, end-point * verification, require client-auth/cert etc. */ -public class EncryptionOptions +public abstract class EncryptionOptions> { - Logger logger = LoggerFactory.getLogger(EncryptionOptions.class); - public enum TlsEncryptionPolicy { UNENCRYPTED("unencrypted"), @@ -69,39 +66,50 @@ public class EncryptionOptions } } - public enum ClientAuth + public enum ConfigKey { - REQUIRED("true"), - NOT_REQUIRED("false"), - OPTIONAL("optional"); - private final String value; - private static final Map VALUES = new HashMap<>(); - static + KEYSTORE("keystore"), + KEYSTORE_PASSWORD("keystore_password"), + KEYSTORE_PASSWORD_FILE("keystore_password_file"), + OUTBOUND_KEYSTORE("outbound_keystore"), + OUTBOUND_KEYSTORE_PASSWORD("outbound_keystore_password"), + OUTBOUND_KEYSTORE_PASSWORD_FILE("outbound_keystore_password_file"), + TRUSTSTORE("truststore"), + TRUSTSTORE_PASSWORD("truststore_password"), + TRUSTSTORE_PASSWORD_FILE("truststore_password_file"), + CIPHER_SUITES("cipher_suites"), + PROTOCOL("protocol"), + ACCEPTED_PROTOCOLS("accepted_protocols"), + ALGORITHM("algorithm"), + STORE_TYPE("store_type"), + REQUIRE_CLIENT_AUTH("require_client_auth"), + REQUIRE_ENDPOINT_VERIFICATION("require_endpoint_verification"), + ENABLED("enabled"), + OPTIONAL("optional"), + MAX_CERTIFICATE_VALIDITY_PERIOD("max_certificate_validity_period"), + CERTIFICATE_VALIDITY_WARN_THRESHOLD("certificate_validity_warn_threshold"); + + final String keyName; + + ConfigKey(String keyName) { - for (ClientAuth clientAuth : ClientAuth.values()) + this.keyName = keyName; + } + + public String toString() + { + return keyName; + } + + static Set asSet() + { + Set valueSet = new HashSet<>(); + ConfigKey[] values = values(); + for (ConfigKey key : values) { - VALUES.put(clientAuth.value, clientAuth); - VALUES.put(toLowerCaseLocalized(clientAuth.name()), clientAuth); + valueSet.add(toLowerCaseLocalized(key.toString())); } - } - - ClientAuth(String value) - { - this.value = value; - } - - public static ClientAuth from(String value) - { - if (VALUES.containsKey(toLowerCaseLocalized(value))) - { - return VALUES.get(toLowerCaseLocalized(value)); - } - throw new ConfigurationException(value + " is not a valid ClientAuth option"); - } - - public String value() - { - return value; + return valueSet; } } @@ -153,53 +161,6 @@ public class EncryptionOptions */ public transient ISslContextFactory sslContextFactoryInstance; - public enum ConfigKey - { - KEYSTORE("keystore"), - KEYSTORE_PASSWORD("keystore_password"), - KEYSTORE_PASSWORD_FILE("keystore_password_file"), - OUTBOUND_KEYSTORE("outbound_keystore"), - OUTBOUND_KEYSTORE_PASSWORD("outbound_keystore_password"), - OUTBOUND_KEYSTORE_PASSWORD_FILE("outbound_keystore_password_file"), - TRUSTSTORE("truststore"), - TRUSTSTORE_PASSWORD("truststore_password"), - TRUSTSTORE_PASSWORD_FILE("truststore_password_file"), - CIPHER_SUITES("cipher_suites"), - PROTOCOL("protocol"), - ACCEPTED_PROTOCOLS("accepted_protocols"), - ALGORITHM("algorithm"), - STORE_TYPE("store_type"), - REQUIRE_CLIENT_AUTH("require_client_auth"), - REQUIRE_ENDPOINT_VERIFICATION("require_endpoint_verification"), - ENABLED("enabled"), - OPTIONAL("optional"), - MAX_CERTIFICATE_VALIDITY_PERIOD("max_certificate_validity_period"), - CERTIFICATE_VALIDITY_WARN_THRESHOLD("certificate_validity_warn_threshold"); - - final String keyName; - - ConfigKey(String keyName) - { - this.keyName = keyName; - } - - public String toString() - { - return keyName; - } - - static Set asSet() - { - Set valueSet = new HashSet<>(); - ConfigKey[] values = values(); - for (ConfigKey key : values) - { - valueSet.add(toLowerCaseLocalized(key.toString())); - } - return valueSet; - } - } - public EncryptionOptions() { ssl_context_factory = new ParameterizedClass("org.apache.cassandra.security.DefaultSslContextFactory", @@ -252,7 +213,7 @@ public class EncryptionOptions this.certificate_validity_warn_threshold = certificate_validity_warn_threshold; } - public EncryptionOptions(EncryptionOptions options) + public EncryptionOptions(EncryptionOptions options) { ssl_context_factory = options.ssl_context_factory; keystore = options.keystore; @@ -280,7 +241,7 @@ public class EncryptionOptions * * It also initializes the ISslContextFactory's instance */ - public EncryptionOptions applyConfig() + public T applyConfig() { ensureConfigNotApplied(); @@ -304,7 +265,7 @@ public class EncryptionOptions // Otherwise if there's no keystore, not possible to establish an optional secure connection isOptional = false; } - return this; + return (T) this; } /** @@ -312,22 +273,22 @@ public class EncryptionOptions * as the constructor for its implementation. * * @throws IllegalArgumentException in case any pre-defined key, as per {@link ConfigKey}, for the encryption - * options is duplicated in the parameterized keys. + * options is duplicated in the parameterized keys. */ - private void prepareSslContextFactoryParameterizedKeys(Map sslContextFactoryParameters) + private void prepareSslContextFactoryParameterizedKeys(Map sslContextFactoryParameters) { if (ssl_context_factory.parameters != null) { Set configKeys = ConfigKey.asSet(); for (Map.Entry entry : ssl_context_factory.parameters.entrySet()) { - if(configKeys.contains(toLowerCaseLocalized(entry.getKey()))) + if (configKeys.contains(toLowerCaseLocalized(entry.getKey()))) { - throw new IllegalArgumentException("SslContextFactory "+ssl_context_factory.class_name+" should " + - "configure '"+entry.getKey()+"' as encryption_options instead of" + + throw new IllegalArgumentException("SslContextFactory " + ssl_context_factory.class_name + " should " + + "configure '" + entry.getKey() + "' as encryption_options instead of" + " parameterized keys"); } - sslContextFactoryParameters.put(entry.getKey(),entry.getValue()); + sslContextFactoryParameters.put(entry.getKey(), entry.getValue()); } } } @@ -375,7 +336,8 @@ public class EncryptionOptions protected static void putSslContextFactoryParameter(Map existingParameters, ConfigKey configKey, Object value) { - if (value != null) { + if (value != null) + { existingParameters.put(configKey.toString(), value); } } @@ -480,9 +442,9 @@ public class EncryptionOptions return sslContextFactoryInstance == null ? null : sslContextFactoryInstance.getAcceptedProtocols(); } - public ClientAuth getClientAuth() + public ClientEncryptionOptions.ClientAuth getClientAuth() { - return this.require_client_auth == null ? ClientAuth.NOT_REQUIRED : ClientAuth.from(this.require_client_auth); + return this.require_client_auth == null ? ClientEncryptionOptions.ClientAuth.NOT_REQUIRED : ClientEncryptionOptions.ClientAuth.from(this.require_client_auth); } public String[] acceptedProtocolsArray() @@ -517,162 +479,6 @@ public class EncryptionOptions } } - public EncryptionOptions withSslContextFactory(ParameterizedClass sslContextFactoryClass) - { - return new EncryptionOptions(sslContextFactoryClass, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - public EncryptionOptions withKeyStore(String keystore) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - public EncryptionOptions withKeyStorePassword(String keystore_password) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - public EncryptionOptions withKeyStorePasswordFile(String keystore_password_file) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - public EncryptionOptions withTrustStore(String truststore) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - public EncryptionOptions withTrustStorePassword(String truststore_password) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - public EncryptionOptions withTrustStorePasswordFile(String truststore_password_file) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - public EncryptionOptions withCipherSuites(List cipher_suites) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - public EncryptionOptions withCipherSuites(String... cipher_suites) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, ImmutableList.copyOf(cipher_suites), protocol, - accepted_protocols, algorithm, store_type, require_client_auth, - require_endpoint_verification, enabled, optional, max_certificate_validity_period, - max_certificate_validity_period).applyConfig(); - } - - public EncryptionOptions withProtocol(String protocol) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - - public EncryptionOptions withAcceptedProtocols(List accepted_protocols) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols == null ? null : - ImmutableList.copyOf(accepted_protocols), - algorithm, store_type, require_client_auth, require_endpoint_verification, - enabled, optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - - public EncryptionOptions withAlgorithm(String algorithm) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - public EncryptionOptions withStoreType(String store_type) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - public EncryptionOptions withRequireClientAuth(ClientAuth require_client_auth) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth.value, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - public EncryptionOptions withRequireEndpointVerification(boolean require_endpoint_verification) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - public EncryptionOptions withEnabled(boolean enabled) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - public EncryptionOptions withOptional(Boolean optional) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, max_certificate_validity_period).applyConfig(); - } - - public EncryptionOptions withMaxCertificateValidityPeriod(DurationSpec.IntMinutesBound maxCertificateValidityPeriod) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, maxCertificateValidityPeriod, certificate_validity_warn_threshold).applyConfig(); - } - - public EncryptionOptions withCertificateValidityWarnThreshold(DurationSpec.IntMinutesBound certificateValidityWarnThreshold) - { - return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, - truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, - store_type, require_client_auth, require_endpoint_verification, enabled, - optional, max_certificate_validity_period, certificateValidityWarnThreshold).applyConfig(); - } - /** * The method is being mainly used to cache SslContexts therefore, we only consider * fields that would make a difference when the TrustStore or KeyStore files are updated @@ -685,7 +491,7 @@ public class EncryptionOptions if (o == null || getClass() != o.getClass()) return false; - EncryptionOptions opt = (EncryptionOptions)o; + EncryptionOptions opt = (EncryptionOptions) o; return enabled == opt.enabled && optional == opt.optional && require_client_auth.equals(opt.require_client_auth) && @@ -731,8 +537,258 @@ public class EncryptionOptions return result; } - public static class ServerEncryptionOptions extends EncryptionOptions + public static abstract class Builder> { + ParameterizedClass ssl_context_factory; + String keystore; + String keystore_password; + String keystore_password_file; + String truststore; + String truststore_password; + String truststore_password_file; + List cipher_suites; + String protocol; + List accepted_protocols; + String algorithm; + String store_type; + String require_client_auth; + boolean require_endpoint_verification; + DurationSpec.IntMinutesBound max_certificate_validity_period; + DurationSpec.IntMinutesBound certificate_validity_warn_threshold; + Boolean enabled; + Boolean optional; + Boolean isEnabled; + Boolean isOptional; + + public Builder(EncryptionOptions options) + { + ssl_context_factory = options.ssl_context_factory; + keystore = options.keystore; + keystore_password = options.keystore_password; + keystore_password_file = options.keystore_password_file; + truststore = options.truststore; + truststore_password = options.truststore_password; + truststore_password_file = options.truststore_password_file; + cipher_suites = options.cipher_suites; + protocol = options.protocol; + accepted_protocols = options.accepted_protocols; + algorithm = options.algorithm; + store_type = options.store_type; + require_client_auth = options.require_client_auth; + require_endpoint_verification = options.require_endpoint_verification; + enabled = options.enabled; + optional = options.optional; + max_certificate_validity_period = options.max_certificate_validity_period; + certificate_validity_warn_threshold = options.certificate_validity_warn_threshold; + } + + public Builder withSslContextFactory(ParameterizedClass sslContextFactoryClass) + { + this.ssl_context_factory = sslContextFactoryClass; + return this; + } + + public Builder withKeyStore(String keystore) + { + this.keystore = keystore; + return this; + } + + public Builder withKeyStorePassword(String keystore_password) + { + this.keystore_password = keystore_password; + return this; + } + + public Builder withKeyStorePasswordFile(String keystore_password_file) + { + this.keystore_password_file = keystore_password_file; + return this; + } + + public Builder withTrustStore(String truststore) + { + this.truststore = truststore; + return this; + } + + public Builder withTrustStorePassword(String truststore_password) + { + this.truststore_password = truststore_password; + return this; + } + + public Builder withTrustStorePasswordFile(String truststore_password_file) + { + this.truststore_password_file = truststore_password_file; + return this; + } + + public Builder withCipherSuites(List cipher_suites) + { + this.cipher_suites = cipher_suites; + return this; + } + + public Builder withCipherSuites(String... cipher_suites) + { + this.cipher_suites = ImmutableList.copyOf(cipher_suites); + return this; + } + + public Builder withProtocol(String protocol) + { + this.protocol = protocol; + return this; + } + + public Builder withAcceptedProtocols(List accepted_protocols) + { + this.accepted_protocols = accepted_protocols == null ? null : + ImmutableList.copyOf(accepted_protocols); + return this; + } + + public Builder withAlgorithm(String algorithm) + { + this.algorithm = algorithm; + return this; + } + + public Builder withStoreType(String store_type) + { + this.store_type = store_type; + return this; + } + + public Builder withRequireClientAuth(ClientEncryptionOptions.ClientAuth require_client_auth) + { + this.require_client_auth = require_client_auth.value; + return this; + } + + public Builder withRequireEndpointVerification(boolean require_endpoint_verification) + { + this.require_endpoint_verification = require_endpoint_verification; + return this; + } + + public Builder withEnabled(boolean enabled) + { + this.enabled = enabled; + return this; + } + + public Builder withOptional(Boolean optional) + { + this.optional = optional; + return this; + } + + public Builder withMaxCertificateValidityPeriod(DurationSpec.IntMinutesBound maxCertificateValidityPeriod) + { + this.max_certificate_validity_period = maxCertificateValidityPeriod; + return this; + } + + public Builder withCertificateValidityWarnThreshold(DurationSpec.IntMinutesBound certificateValidityWarnThreshold) + { + this.certificate_validity_warn_threshold = certificateValidityWarnThreshold; + return this; + } + + public abstract T build(); + } + + public static class ClientEncryptionOptions extends EncryptionOptions + { + public ClientEncryptionOptions() + { + } + + public ClientEncryptionOptions(ParameterizedClass ssl_context_factory, + String keystore, String keystore_password, String keystore_password_file, + String truststore, String truststore_password, String truststore_password_file, + List cipher_suites, String protocol, List accepted_protocols, + String algorithm, String store_type, String require_client_auth, + boolean require_endpoint_verification, Boolean enabled, Boolean optional, + DurationSpec.IntMinutesBound max_certificate_validity_period, + DurationSpec.IntMinutesBound certificate_validity_warn_threshold) + { + super(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, truststore_password, + truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, store_type, require_client_auth, + require_endpoint_verification, enabled, optional, max_certificate_validity_period, certificate_validity_warn_threshold); + } + + public ClientEncryptionOptions(ClientEncryptionOptions options) + { + super(options); + } + + public enum ClientAuth + { + REQUIRED("true"), + NOT_REQUIRED("false"), + OPTIONAL("optional"); + private final String value; + private static final Map VALUES = new HashMap<>(); + + static + { + for (ClientAuth clientAuth : ClientAuth.values()) + { + VALUES.put(clientAuth.value, clientAuth); + VALUES.put(toLowerCaseLocalized(clientAuth.name()), clientAuth); + } + } + + ClientAuth(String value) + { + this.value = value; + } + + public static ClientAuth from(String value) + { + if (VALUES.containsKey(toLowerCaseLocalized(value))) + { + return VALUES.get(toLowerCaseLocalized(value)); + } + throw new ConfigurationException(value + " is not a valid ClientAuth option"); + } + + public String value() + { + return value; + } + } + + public static class Builder extends EncryptionOptions.Builder + { + public Builder() + { + this(new ClientEncryptionOptions()); + } + + public Builder(ClientEncryptionOptions options) + { + super(options); + } + + @Override + public ClientEncryptionOptions build() + { + return new ClientEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, truststore, + truststore_password, truststore_password_file, cipher_suites, protocol, accepted_protocols, algorithm, + store_type, require_client_auth, require_endpoint_verification, enabled, + optional, max_certificate_validity_period, certificate_validity_warn_threshold).applyConfig(); + } + } + } + + public static class ServerEncryptionOptions extends EncryptionOptions + { + private static final Logger logger = LoggerFactory.getLogger(ServerEncryptionOptions.class); + public enum InternodeEncryption { all, none, dc, rack @@ -788,6 +844,73 @@ public class EncryptionOptions this.outbound_keystore_password_file = options.outbound_keystore_password_file; } + public static class Builder extends EncryptionOptions.Builder + { + private InternodeEncryption internode_encryption; + private boolean legacy_ssl_storage_port_enabled; + private String outbound_keystore; + private String outbound_keystore_password; + private String outbound_keystore_password_file; + + public Builder() + { + this(new ServerEncryptionOptions()); + } + + public Builder(ServerEncryptionOptions options) + { + super(options); + this.internode_encryption = options.internode_encryption; + this.legacy_ssl_storage_port_enabled = options.legacy_ssl_storage_port_enabled; + this.outbound_keystore = options.outbound_keystore; + this.outbound_keystore_password = options.outbound_keystore_password; + this.outbound_keystore_password_file = options.outbound_keystore_password_file; + } + + public Builder withInternodeEncryption(InternodeEncryption internode_encryption) + { + this.internode_encryption = internode_encryption; + return this; + } + + public Builder withLegacySslStoragePort(boolean enable_legacy_ssl_storage_port) + { + this.legacy_ssl_storage_port_enabled = enable_legacy_ssl_storage_port; + return this; + } + + public Builder withOutboundKeystore(String outboundKeystore) + { + this.outbound_keystore = outboundKeystore; + return this; + } + + public Builder withOutboundKeystorePassword(String outboundKeystorePassword) + { + this.outbound_keystore_password = outboundKeystorePassword; + return this; + } + + public Builder withOutboundKeystorePasswordFile(String outboundKeystorePasswordFile) + { + this.outbound_keystore_password_file = outboundKeystorePasswordFile; + return this; + } + + @Override + public ServerEncryptionOptions build() + { + return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, + outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, + truststore, truststore_password, truststore_password_file, + cipher_suites, protocol, accepted_protocols, + algorithm, store_type, require_client_auth, + require_endpoint_verification, optional, internode_encryption, + legacy_ssl_storage_port_enabled, max_certificate_validity_period, + certificate_validity_warn_threshold).applyConfig(); + } + } + @Override protected void fillSslContextParams(Map sslContextFactoryParameters) { @@ -798,7 +921,7 @@ public class EncryptionOptions } @Override - public EncryptionOptions applyConfig() + public ServerEncryptionOptions applyConfig() { return applyConfigInternal(); } @@ -814,13 +937,13 @@ public class EncryptionOptions logger.warn("Setting server_encryption_options.enabled has no effect, use internode_encryption"); } - if (getClientAuth() != ClientAuth.NOT_REQUIRED && (internode_encryption == InternodeEncryption.rack || internode_encryption == InternodeEncryption.dc)) + if (getClientAuth() != ClientEncryptionOptions.ClientAuth.NOT_REQUIRED && (internode_encryption == InternodeEncryption.rack || internode_encryption == InternodeEncryption.dc)) { logger.warn("Setting require_client_auth is incompatible with 'rack' and 'dc' internode_encryption values." - + " It is possible for an internode connection to pretend to be in the same rack/dc by spoofing" - + " its broadcast address in the handshake and bypass authentication. To ensure that mutual TLS" - + " authentication is not bypassed, please set internode_encryption to 'all'. Continuing with" - + " insecure configuration."); + + " It is possible for an internode connection to pretend to be in the same rack/dc by spoofing" + + " its broadcast address in the handshake and bypass authentication. To ensure that mutual TLS" + + " authentication is not bypassed, please set internode_encryption to 'all'. Continuing with" + + " insecure configuration."); } // regardless of the optional flag, if the internode encryption is set to rack or dc @@ -910,284 +1033,5 @@ public class EncryptionOptions result += 31 * (outbound_keystore_password_file == null ? 0 : outbound_keystore_password_file.hashCode()); return result; } - - @Override - public ServerEncryptionOptions withSslContextFactory(ParameterizedClass sslContextFactoryClass) - { - return new ServerEncryptionOptions(sslContextFactoryClass, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - @Override - public ServerEncryptionOptions withKeyStore(String keystore) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - @Override - public ServerEncryptionOptions withKeyStorePassword(String keystore_password) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - @Override - public ServerEncryptionOptions withKeyStorePasswordFile(String keystore_password_file) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - @Override - public ServerEncryptionOptions withTrustStore(String truststore) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - @Override - public ServerEncryptionOptions withTrustStorePassword(String truststore_password) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - @Override - public ServerEncryptionOptions withTrustStorePasswordFile(String truststore_password_file) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - @Override - public ServerEncryptionOptions withCipherSuites(List cipher_suites) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - @Override - public ServerEncryptionOptions withCipherSuites(String... cipher_suites) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - Arrays.asList(cipher_suites), protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - @Override - public ServerEncryptionOptions withProtocol(String protocol) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - @Override - public ServerEncryptionOptions withAcceptedProtocols(List accepted_protocols) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - @Override - public ServerEncryptionOptions withAlgorithm(String algorithm) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - @Override - public ServerEncryptionOptions withStoreType(String store_type) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - @Override - public ServerEncryptionOptions withRequireClientAuth(ClientAuth require_client_auth) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth.value, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - @Override - public ServerEncryptionOptions withRequireEndpointVerification(boolean require_endpoint_verification) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - public ServerEncryptionOptions withOptional(boolean optional) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - public ServerEncryptionOptions withInternodeEncryption(InternodeEncryption internode_encryption) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - public ServerEncryptionOptions withLegacySslStoragePort(boolean enable_legacy_ssl_storage_port) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - enable_legacy_ssl_storage_port, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - public ServerEncryptionOptions withOutboundKeystore(String outboundKeystore) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outboundKeystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - public ServerEncryptionOptions withOutboundKeystorePassword(String outboundKeystorePassword) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outboundKeystorePassword, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - - public ServerEncryptionOptions withOutboundKeystorePasswordFile(String outboundKeystorePasswordFile) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outboundKeystorePasswordFile, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, max_certificate_validity_period, - max_certificate_validity_period).applyConfigInternal(); - } - @Override - public ServerEncryptionOptions withMaxCertificateValidityPeriod(DurationSpec.IntMinutesBound maxCertificateValidityPeriod) - { - return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password, keystore_password_file, - outbound_keystore, outbound_keystore_password, outbound_keystore_password_file, - truststore, truststore_password, truststore_password_file, - cipher_suites, protocol, accepted_protocols, - algorithm, store_type, require_client_auth, - require_endpoint_verification, optional, internode_encryption, - legacy_ssl_storage_port_enabled, maxCertificateValidityPeriod, - certificate_validity_warn_threshold).applyConfigInternal(); - } } } diff --git a/src/java/org/apache/cassandra/config/JMXServerOptions.java b/src/java/org/apache/cassandra/config/JMXServerOptions.java index 705ab02bb8..ab80307e54 100644 --- a/src/java/org/apache/cassandra/config/JMXServerOptions.java +++ b/src/java/org/apache/cassandra/config/JMXServerOptions.java @@ -52,7 +52,7 @@ public class JMXServerOptions public final Boolean authenticate; // ssl options - public final EncryptionOptions jmx_encryption_options; + public final EncryptionOptions.ClientEncryptionOptions jmx_encryption_options; // options for using Cassandra's own authentication mechanisms public final String login_config_name; @@ -71,11 +71,11 @@ public class JMXServerOptions public JMXServerOptions() { this(true, false, 7199, 0, false, - new EncryptionOptions(), null, null, null, + new EncryptionOptions.ClientEncryptionOptions(), null, null, null, null, null); } - public static JMXServerOptions create(boolean enabled, boolean local, int jmxPort, EncryptionOptions options) + public static JMXServerOptions create(boolean enabled, boolean local, int jmxPort, EncryptionOptions.ClientEncryptionOptions options) { return new JMXServerOptions(enabled, !local, jmxPort, 0, false, options, null, null, null, @@ -95,7 +95,7 @@ public class JMXServerOptions int jmxPort, int rmiPort, Boolean authenticate, - EncryptionOptions jmx_encryption_options, + EncryptionOptions.ClientEncryptionOptions jmx_encryption_options, String loginConfigName, String loginConfigFile, String passwordFile, @@ -198,7 +198,8 @@ public class JMXServerOptions // in the `cassandra.yaml`. Since the JMX SSL Config can also leverage it as per CASSANDRA-18508, password file // support is not added to the JMX SSL configuration via the system properties. Hence, `null` is used as // the password file arguments for the keystore and the truststore while constructing the encryption options here. - EncryptionOptions encryptionOptions = new EncryptionOptions(new ParameterizedClass("org.apache.cassandra.security.DefaultSslContextFactory", new HashMap<>()), + + EncryptionOptions.ClientEncryptionOptions encryptionOptions = new EncryptionOptions.ClientEncryptionOptions(new ParameterizedClass("org.apache.cassandra.security.DefaultSslContextFactory", new HashMap<>()), keystore, keystorePassword, null, diff --git a/src/java/org/apache/cassandra/net/InboundConnectionInitiator.java b/src/java/org/apache/cassandra/net/InboundConnectionInitiator.java index fd5710e297..c4cbc50a2b 100644 --- a/src/java/org/apache/cassandra/net/InboundConnectionInitiator.java +++ b/src/java/org/apache/cassandra/net/InboundConnectionInitiator.java @@ -67,7 +67,7 @@ import static java.lang.Math.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.apache.cassandra.auth.IInternodeAuthenticator.InternodeConnectionDirection.INBOUND; import static org.apache.cassandra.concurrent.ExecutorFactory.Global.executorFactory; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; import static org.apache.cassandra.net.InternodeConnectionUtils.DISCARD_HANDLER_NAME; import static org.apache.cassandra.net.InternodeConnectionUtils.SSL_FACTORY_CONTEXT_DESCRIPTION; import static org.apache.cassandra.net.InternodeConnectionUtils.SSL_HANDLER_NAME; @@ -530,7 +530,7 @@ public class InboundConnectionInitiator private static SslHandler getSslHandler(String description, Channel channel, EncryptionOptions.ServerEncryptionOptions encryptionOptions) throws IOException { - final EncryptionOptions.ClientAuth verifyPeerCertificate = REQUIRED; + final EncryptionOptions.ClientEncryptionOptions.ClientAuth verifyPeerCertificate = REQUIRED; SslContext sslContext = SSLFactory.getOrCreateSslContext(encryptionOptions, verifyPeerCertificate, ISslContextFactory.SocketType.SERVER, SSL_FACTORY_CONTEXT_DESCRIPTION); diff --git a/src/java/org/apache/cassandra/net/InboundConnectionSettings.java b/src/java/org/apache/cassandra/net/InboundConnectionSettings.java index 448da62cbb..4a9db7ca81 100644 --- a/src/java/org/apache/cassandra/net/InboundConnectionSettings.java +++ b/src/java/org/apache/cassandra/net/InboundConnectionSettings.java @@ -146,7 +146,7 @@ public class InboundConnectionSettings ServerEncryptionOptions encryption = this.encryption; if (encryption == null) encryption = DatabaseDescriptor.getInternodeMessagingEncyptionOptions(); - encryption = encryption.withOptional(false).withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all); + encryption = new ServerEncryptionOptions.Builder(encryption).withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all).withOptional(false).build(); return this.withBindAddress(bindAddress.withPort(DatabaseDescriptor.getSSLStoragePort())) .withEncryption(encryption) diff --git a/src/java/org/apache/cassandra/net/OutboundConnectionInitiator.java b/src/java/org/apache/cassandra/net/OutboundConnectionInitiator.java index 27e55f6105..2bddc174f2 100644 --- a/src/java/org/apache/cassandra/net/OutboundConnectionInitiator.java +++ b/src/java/org/apache/cassandra/net/OutboundConnectionInitiator.java @@ -66,9 +66,9 @@ import org.apache.cassandra.utils.memory.BufferPools; import static java.util.concurrent.TimeUnit.*; import static org.apache.cassandra.auth.IInternodeAuthenticator.InternodeConnectionDirection.OUTBOUND; import static org.apache.cassandra.auth.IInternodeAuthenticator.InternodeConnectionDirection.OUTBOUND_PRECONNECT; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.NOT_REQUIRED; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.OPTIONAL; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.NOT_REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.OPTIONAL; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; import static org.apache.cassandra.net.InternodeConnectionUtils.DISCARD_HANDLER_NAME; import static org.apache.cassandra.net.InternodeConnectionUtils.SSL_FACTORY_CONTEXT_DESCRIPTION; import static org.apache.cassandra.net.InternodeConnectionUtils.SSL_HANDLER_NAME; @@ -245,7 +245,7 @@ public class OutboundConnectionInitiator accepted_protocols; protected final String algorithm; protected final String store_type; - protected final EncryptionOptions.ClientAuth clientAuth; + protected final EncryptionOptions.ClientEncryptionOptions.ClientAuth clientAuth; protected final boolean require_endpoint_verification; /* ServerEncryptionOptions does not use the enabled flag at all instead using the existing @@ -105,7 +105,7 @@ abstract public class AbstractSslContextFactory implements ISslContextFactory accepted_protocols = getStringList("accepted_protocols"); algorithm = getString("algorithm"); store_type = getString("store_type", "JKS"); - clientAuth = parameters.get("require_client_auth") == null ? NOT_REQUIRED : EncryptionOptions.ClientAuth.from(getString("require_client_auth")); + clientAuth = parameters.get("require_client_auth") == null ? NOT_REQUIRED : EncryptionOptions.ClientEncryptionOptions.ClientAuth.from(getString("require_client_auth")); require_endpoint_verification = getBoolean("require_endpoint_verification", false); enabled = getBoolean("enabled"); optional = getBoolean("optional"); @@ -158,7 +158,7 @@ abstract public class AbstractSslContextFactory implements ISslContextFactory } @Override - public SSLContext createJSSESslContext(EncryptionOptions.ClientAuth clientAuth) throws SSLException + public SSLContext createJSSESslContext(EncryptionOptions.ClientEncryptionOptions.ClientAuth clientAuth) throws SSLException { TrustManager[] trustManagers = null; if (clientAuth != NOT_REQUIRED) @@ -186,7 +186,7 @@ abstract public class AbstractSslContextFactory implements ISslContextFactory } @Override - public SslContext createNettySslContext(EncryptionOptions.ClientAuth clientAuth, SocketType socketType, + public SslContext createNettySslContext(EncryptionOptions.ClientEncryptionOptions.ClientAuth clientAuth, SocketType socketType, CipherSuiteFilter cipherFilter) throws SSLException { /* @@ -291,7 +291,7 @@ abstract public class AbstractSslContextFactory implements ISslContextFactory */ abstract protected KeyManagerFactory buildOutboundKeyManagerFactory() throws SSLException; - private ClientAuth toNettyClientAuth(EncryptionOptions.ClientAuth clientAuth) + private ClientAuth toNettyClientAuth(EncryptionOptions.ClientEncryptionOptions.ClientAuth clientAuth) { switch (clientAuth) { diff --git a/src/java/org/apache/cassandra/security/ISslContextFactory.java b/src/java/org/apache/cassandra/security/ISslContextFactory.java index 1db5f579b1..2f8b53d166 100644 --- a/src/java/org/apache/cassandra/security/ISslContextFactory.java +++ b/src/java/org/apache/cassandra/security/ISslContextFactory.java @@ -72,7 +72,7 @@ public interface ISslContextFactory * @return JSSE's {@link SSLContext} * @throws SSLException in case the Ssl Context creation fails for some reason */ - default SSLContext createJSSESslContext(EncryptionOptions.ClientAuth clientAuth) throws SSLException + default SSLContext createJSSESslContext(EncryptionOptions.ClientEncryptionOptions.ClientAuth clientAuth) throws SSLException { switch (clientAuth) { @@ -112,7 +112,7 @@ public interface ISslContextFactory * @return Netty's {@link SslContext} * @throws SSLException in case the Ssl Context creation fails for some reason */ - default SslContext createNettySslContext(EncryptionOptions.ClientAuth clientAuth, SocketType socketType, + default SslContext createNettySslContext(EncryptionOptions.ClientEncryptionOptions.ClientAuth clientAuth, SocketType socketType, CipherSuiteFilter cipherFilter) throws SSLException { switch (clientAuth) diff --git a/src/java/org/apache/cassandra/security/SSLFactory.java b/src/java/org/apache/cassandra/security/SSLFactory.java index a9b4be9d5c..65a6dfa24f 100644 --- a/src/java/org/apache/cassandra/security/SSLFactory.java +++ b/src/java/org/apache/cassandra/security/SSLFactory.java @@ -47,7 +47,7 @@ import org.apache.cassandra.security.ISslContextFactory.SocketType; import static org.apache.cassandra.config.CassandraRelevantProperties.DISABLE_TCACTIVE_OPENSSL; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; /** @@ -125,7 +125,7 @@ public final class SSLFactory /** * Create a JSSE {@link SSLContext}. */ - public static SSLContext createSSLContext(EncryptionOptions options, EncryptionOptions.ClientAuth clientAuth) throws IOException + public static SSLContext createSSLContext(EncryptionOptions options, EncryptionOptions.ClientEncryptionOptions.ClientAuth clientAuth) throws IOException { return options.sslContextFactoryInstance.createJSSESslContext(clientAuth); } @@ -133,7 +133,7 @@ public final class SSLFactory /** * get a netty {@link SslContext} instance */ - public static SslContext getOrCreateSslContext(EncryptionOptions options, EncryptionOptions.ClientAuth clientAuth, + public static SslContext getOrCreateSslContext(EncryptionOptions options, EncryptionOptions.ClientEncryptionOptions.ClientAuth clientAuth, SocketType socketType, String contextDescription) throws IOException { @@ -157,7 +157,7 @@ public final class SSLFactory /** * Create a Netty {@link SslContext} */ - static SslContext createNettySslContext(EncryptionOptions options, EncryptionOptions.ClientAuth clientAuth, + static SslContext createNettySslContext(EncryptionOptions options, EncryptionOptions.ClientEncryptionOptions.ClientAuth clientAuth, SocketType socketType) throws IOException { return createNettySslContext(options, clientAuth, socketType, @@ -167,7 +167,7 @@ public final class SSLFactory /** * Create a Netty {@link SslContext} with a supplied cipherFilter */ - static SslContext createNettySslContext(EncryptionOptions options, EncryptionOptions.ClientAuth clientAuth, + static SslContext createNettySslContext(EncryptionOptions options, EncryptionOptions.ClientEncryptionOptions.ClientAuth clientAuth, SocketType socketType, CipherSuiteFilter cipherFilter) throws IOException { return options.sslContextFactoryInstance.createNettySslContext(clientAuth, socketType, @@ -356,7 +356,7 @@ public final class SSLFactory return !string.equals("SSLv2Hello"); } - public static void validateSslContext(String contextDescription, EncryptionOptions options, EncryptionOptions.ClientAuth clientAuth, boolean logProtocolAndCiphers) throws IOException + public static void validateSslContext(String contextDescription, EncryptionOptions options, EncryptionOptions.ClientEncryptionOptions.ClientAuth clientAuth, boolean logProtocolAndCiphers) throws IOException { if (options != null && options.tlsEncryptionPolicy() != EncryptionOptions.TlsEncryptionPolicy.UNENCRYPTED) { diff --git a/src/java/org/apache/cassandra/tools/BulkLoader.java b/src/java/org/apache/cassandra/tools/BulkLoader.java index ecd6a5d31b..92ccbb96be 100644 --- a/src/java/org/apache/cassandra/tools/BulkLoader.java +++ b/src/java/org/apache/cassandra/tools/BulkLoader.java @@ -48,7 +48,7 @@ import org.apache.cassandra.utils.JVMStabilityInspector; import org.apache.cassandra.utils.NativeSSTableLoaderClient; import org.apache.cassandra.utils.OutputHandler; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; import static org.apache.cassandra.utils.Clock.Global.nanoTime; public class BulkLoader diff --git a/src/java/org/apache/cassandra/tools/LoaderOptions.java b/src/java/org/apache/cassandra/tools/LoaderOptions.java index c3d2072ff4..a68fb012eb 100644 --- a/src/java/org/apache/cassandra/tools/LoaderOptions.java +++ b/src/java/org/apache/cassandra/tools/LoaderOptions.java @@ -52,7 +52,7 @@ import org.apache.cassandra.locator.InetAddressAndPort; import org.apache.cassandra.tools.BulkLoader.CmdLineOptions; import static org.apache.cassandra.config.DataRateSpec.DataRateUnit.MEBIBYTES_PER_SECOND; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; public class LoaderOptions { @@ -121,7 +121,7 @@ public class LoaderOptions public final int entireSSTableInterDcThrottleMebibytes; public final int storagePort; public final int sslStoragePort; - public final EncryptionOptions clientEncOptions; + public final EncryptionOptions.ClientEncryptionOptions clientEncOptions; public final int connectionsPerHost; public final EncryptionOptions.ServerEncryptionOptions serverEncOptions; public final Set hosts; @@ -172,9 +172,11 @@ public class LoaderOptions int storagePort; int sslStoragePort; - EncryptionOptions clientEncOptions = new EncryptionOptions(); + EncryptionOptions.ClientEncryptionOptions clientEncOptions = new EncryptionOptions.ClientEncryptionOptions(); + EncryptionOptions.ClientEncryptionOptions.Builder clientEncOptionsBuilder = new EncryptionOptions.ClientEncryptionOptions.Builder(clientEncOptions); int connectionsPerHost = 1; EncryptionOptions.ServerEncryptionOptions serverEncOptions = new EncryptionOptions.ServerEncryptionOptions(); + EncryptionOptions.ServerEncryptionOptions.Builder serverEncOptionsBuilder = new EncryptionOptions.ServerEncryptionOptions.Builder(serverEncOptions); Set hostsArg = new HashSet<>(); Set ignoresArg = new HashSet<>(); Set hosts = new HashSet<>(); @@ -333,9 +335,10 @@ public class LoaderOptions return this; } - public Builder encOptions(EncryptionOptions encOptions) + public Builder encOptions(EncryptionOptions.ClientEncryptionOptions encOptions) { this.clientEncOptions = encOptions; + this.clientEncOptionsBuilder = new EncryptionOptions.ClientEncryptionOptions.Builder(encOptions); return this; } @@ -348,6 +351,7 @@ public class LoaderOptions public Builder serverEncOptions(EncryptionOptions.ServerEncryptionOptions serverEncOptions) { this.serverEncOptions = serverEncOptions; + this.serverEncOptionsBuilder = new EncryptionOptions.ServerEncryptionOptions.Builder(serverEncOptions); return this; } @@ -551,9 +555,10 @@ public class LoaderOptions "which is able to handle encrypted communication too."); // Copy the encryption options and apply the config so that argument parsing can accesss isEnabled. - clientEncOptions = config.client_encryption_options.applyConfig(); - serverEncOptions = config.server_encryption_options; - serverEncOptions.applyConfig(); + clientEncOptionsBuilder = new EncryptionOptions.ClientEncryptionOptions.Builder(config.client_encryption_options); + clientEncOptions = clientEncOptionsBuilder.build(); + serverEncOptionsBuilder = new EncryptionOptions.ServerEncryptionOptions.Builder(config.server_encryption_options); + serverEncOptions = serverEncOptionsBuilder.build(); if (cmd.hasOption(NATIVE_PORT_OPTION)) nativePort = Integer.parseInt(cmd.getOptionValue(NATIVE_PORT_OPTION)); @@ -625,51 +630,53 @@ public class LoaderOptions if (cmd.hasOption(SSL_TRUSTSTORE) || cmd.hasOption(SSL_TRUSTSTORE_PW) || cmd.hasOption(SSL_KEYSTORE) || cmd.hasOption(SSL_KEYSTORE_PW)) { - clientEncOptions = clientEncOptions.withEnabled(true); + clientEncOptionsBuilder.withEnabled(true); } if (cmd.hasOption(SSL_TRUSTSTORE)) { - clientEncOptions = clientEncOptions.withTrustStore(cmd.getOptionValue(SSL_TRUSTSTORE)); + clientEncOptionsBuilder.withTrustStore(cmd.getOptionValue(SSL_TRUSTSTORE)); } if (cmd.hasOption(SSL_TRUSTSTORE_PW)) { - clientEncOptions = clientEncOptions.withTrustStorePassword(cmd.getOptionValue(SSL_TRUSTSTORE_PW)); + clientEncOptionsBuilder.withTrustStorePassword(cmd.getOptionValue(SSL_TRUSTSTORE_PW)); } if (cmd.hasOption(SSL_KEYSTORE)) { // if a keystore was provided, lets assume we'll need to use - clientEncOptions = clientEncOptions.withKeyStore(cmd.getOptionValue(SSL_KEYSTORE)) + clientEncOptionsBuilder.withKeyStore(cmd.getOptionValue(SSL_KEYSTORE)) .withRequireClientAuth(REQUIRED); } if (cmd.hasOption(SSL_KEYSTORE_PW)) { - clientEncOptions = clientEncOptions.withKeyStorePassword(cmd.getOptionValue(SSL_KEYSTORE_PW)); + clientEncOptionsBuilder.withKeyStorePassword(cmd.getOptionValue(SSL_KEYSTORE_PW)); } if (cmd.hasOption(SSL_PROTOCOL)) { - clientEncOptions = clientEncOptions.withProtocol(cmd.getOptionValue(SSL_PROTOCOL)); + clientEncOptionsBuilder.withProtocol(cmd.getOptionValue(SSL_PROTOCOL)); } if (cmd.hasOption(SSL_ALGORITHM)) { - clientEncOptions = clientEncOptions.withAlgorithm(cmd.getOptionValue(SSL_ALGORITHM)); + clientEncOptionsBuilder.withAlgorithm(cmd.getOptionValue(SSL_ALGORITHM)); } if (cmd.hasOption(SSL_STORE_TYPE)) { - clientEncOptions = clientEncOptions.withStoreType(cmd.getOptionValue(SSL_STORE_TYPE)); + clientEncOptionsBuilder.withStoreType(cmd.getOptionValue(SSL_STORE_TYPE)); } if (cmd.hasOption(SSL_CIPHER_SUITES)) { - clientEncOptions = clientEncOptions.withCipherSuites(cmd.getOptionValue(SSL_CIPHER_SUITES).split(",")); + clientEncOptionsBuilder.withCipherSuites(cmd.getOptionValue(SSL_CIPHER_SUITES).split(",")); } + clientEncOptions = clientEncOptionsBuilder.build(); + if (cmd.hasOption(TARGET_KEYSPACE)) { targetKeyspace = cmd.getOptionValue(TARGET_KEYSPACE); diff --git a/src/java/org/apache/cassandra/transport/Client.java b/src/java/org/apache/cassandra/transport/Client.java index 96fea832a8..6c60f6508c 100644 --- a/src/java/org/apache/cassandra/transport/Client.java +++ b/src/java/org/apache/cassandra/transport/Client.java @@ -45,9 +45,9 @@ public class Client extends SimpleClient { private final SimpleEventHandler eventHandler = new SimpleEventHandler(); - public Client(String host, int port, ProtocolVersion version, EncryptionOptions encryptionOptions) + public Client(String host, int port, ProtocolVersion version, EncryptionOptions.ClientEncryptionOptions encryptionOptions) { - super(host, port, version, version.isBeta(), new EncryptionOptions(encryptionOptions).applyConfig()); + super(host, port, version, version.isBeta(), encryptionOptions.applyConfig()); setEventHandler(eventHandler); } @@ -260,7 +260,7 @@ public class Client extends SimpleClient int port = Integer.parseInt(args[1]); ProtocolVersion version = args.length == 3 ? ProtocolVersion.decode(Integer.parseInt(args[2]), DatabaseDescriptor.getNativeTransportAllowOlderProtocols()) : ProtocolVersion.CURRENT; - EncryptionOptions encryptionOptions = new EncryptionOptions().applyConfig(); + EncryptionOptions.ClientEncryptionOptions encryptionOptions = new EncryptionOptions.ClientEncryptionOptions().applyConfig(); System.out.println("CQL binary protocol console " + host + "@" + port + " using native protocol version " + version); try (Client client = new Client(host, port, version, encryptionOptions)) diff --git a/src/java/org/apache/cassandra/transport/SimpleClient.java b/src/java/org/apache/cassandra/transport/SimpleClient.java index f86b128be0..dea3535757 100644 --- a/src/java/org/apache/cassandra/transport/SimpleClient.java +++ b/src/java/org/apache/cassandra/transport/SimpleClient.java @@ -74,7 +74,7 @@ public class SimpleClient implements Closeable public final String host; public final int port; - private final EncryptionOptions encryptionOptions; + private final EncryptionOptions.ClientEncryptionOptions encryptionOptions; private final int largeMessageThreshold; protected final ResponseHandler responseHandler = new ResponseHandler(); @@ -92,7 +92,7 @@ public class SimpleClient implements Closeable { private final String host; private final int port; - private EncryptionOptions encryptionOptions = new EncryptionOptions(); + private EncryptionOptions.ClientEncryptionOptions encryptionOptions = new EncryptionOptions.ClientEncryptionOptions(); private ProtocolVersion version = ProtocolVersion.CURRENT; private boolean useBeta = false; private int largeMessageThreshold = FrameEncoder.Payload.MAX_SIZE; @@ -103,7 +103,7 @@ public class SimpleClient implements Closeable this.port = port; } - public Builder encryption(EncryptionOptions options) + public Builder encryption(EncryptionOptions.ClientEncryptionOptions options) { this.encryptionOptions = options; return this; @@ -149,22 +149,22 @@ public class SimpleClient implements Closeable this.largeMessageThreshold = builder.largeMessageThreshold; } - public SimpleClient(String host, int port, ProtocolVersion version, EncryptionOptions encryptionOptions) + public SimpleClient(String host, int port, ProtocolVersion version, EncryptionOptions.ClientEncryptionOptions encryptionOptions) { this(host, port, version, false, encryptionOptions); } - public SimpleClient(String host, int port, EncryptionOptions encryptionOptions) + public SimpleClient(String host, int port, EncryptionOptions.ClientEncryptionOptions encryptionOptions) { this(host, port, ProtocolVersion.CURRENT, encryptionOptions); } public SimpleClient(String host, int port, ProtocolVersion version) { - this(host, port, version, new EncryptionOptions()); + this(host, port, version, new EncryptionOptions.ClientEncryptionOptions()); } - public SimpleClient(String host, int port, ProtocolVersion version, boolean useBeta, EncryptionOptions encryptionOptions) + public SimpleClient(String host, int port, ProtocolVersion version, boolean useBeta, EncryptionOptions.ClientEncryptionOptions encryptionOptions) { this.host = host; this.port = port; @@ -172,7 +172,7 @@ public class SimpleClient implements Closeable throw new IllegalArgumentException(String.format("Beta version of server used (%s), but USE_BETA flag is not set", version)); this.version = version; - this.encryptionOptions = new EncryptionOptions(encryptionOptions).applyConfig(); + this.encryptionOptions = encryptionOptions.applyConfig(); this.largeMessageThreshold = FrameEncoder.Payload.MAX_SIZE - Math.max(FrameEncoderCrc.HEADER_AND_TRAILER_LENGTH, FrameEncoderLZ4.HEADER_AND_TRAILER_LENGTH); @@ -180,7 +180,7 @@ public class SimpleClient implements Closeable public SimpleClient(String host, int port) { - this(host, port, new EncryptionOptions()); + this(host, port, new EncryptionOptions.ClientEncryptionOptions()); } public SimpleClient connect(boolean useCompression) throws IOException diff --git a/src/java/org/apache/cassandra/utils/jmx/AbstractJmxSocketFactory.java b/src/java/org/apache/cassandra/utils/jmx/AbstractJmxSocketFactory.java index 3990c64ee7..ef68f52486 100644 --- a/src/java/org/apache/cassandra/utils/jmx/AbstractJmxSocketFactory.java +++ b/src/java/org/apache/cassandra/utils/jmx/AbstractJmxSocketFactory.java @@ -82,7 +82,7 @@ abstract public class AbstractJmxSocketFactory JMXServerOptions.setJmxSystemProperties(jmxEncryptionOptions.getAcceptedProtocols(), jmxEncryptionOptions.getCipherSuites()); logger.info("Enabling JMX SSL using jmx_encryption_options"); - boolean requireClientAuth = jmxEncryptionOptions.getClientAuth() == EncryptionOptions.ClientAuth.REQUIRED; + boolean requireClientAuth = jmxEncryptionOptions.getClientAuth() == EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; String[] ciphers = jmxEncryptionOptions.cipherSuitesArray(); String[] protocols = jmxEncryptionOptions.acceptedProtocolsArray(); SSLContext sslContext = jmxEncryptionOptions.sslContextFactoryInstance.createJSSESslContext(jmxEncryptionOptions.getClientAuth()); diff --git a/test/burn/org/apache/cassandra/transport/SimpleClientBurnTest.java b/test/burn/org/apache/cassandra/transport/SimpleClientBurnTest.java index ed3406d8bc..3247051197 100644 --- a/test/burn/org/apache/cassandra/transport/SimpleClientBurnTest.java +++ b/test/burn/org/apache/cassandra/transport/SimpleClientBurnTest.java @@ -138,11 +138,11 @@ public class SimpleClientBurnTest Arrays.asList( () -> new SimpleClient(address.getHostAddress(), port, ProtocolVersion.V5, true, - new EncryptionOptions()) + new EncryptionOptions.ClientEncryptionOptions()) .connect(false), () -> new SimpleClient(address.getHostAddress(), port, ProtocolVersion.V4, false, - new EncryptionOptions()) + new EncryptionOptions.ClientEncryptionOptions()) .connect(false) ); diff --git a/test/burn/org/apache/cassandra/transport/SimpleClientPerfTest.java b/test/burn/org/apache/cassandra/transport/SimpleClientPerfTest.java index 4417b7cb89..ca5adfff02 100644 --- a/test/burn/org/apache/cassandra/transport/SimpleClientPerfTest.java +++ b/test/burn/org/apache/cassandra/transport/SimpleClientPerfTest.java @@ -102,7 +102,7 @@ public class SimpleClientPerfTest new SizeCaps(10, 20, 5, 10), () -> new SimpleClient(address.getHostAddress(), port, version, true, - new EncryptionOptions()) + new EncryptionOptions.ClientEncryptionOptions()) .connect(false), version); } @@ -114,7 +114,7 @@ public class SimpleClientPerfTest new SizeCaps(10, 20, 5, 10), () -> new SimpleClient(address.getHostAddress(), port, version, true, - new EncryptionOptions()) + new EncryptionOptions.ClientEncryptionOptions()) .connect(true), version); } @@ -126,7 +126,7 @@ public class SimpleClientPerfTest new SizeCaps(1000, 2000, 5, 150), () -> new SimpleClient(address.getHostAddress(), port, version, true, - new EncryptionOptions()) + new EncryptionOptions.ClientEncryptionOptions()) .connect(false), version); } @@ -138,7 +138,7 @@ public class SimpleClientPerfTest new SizeCaps(1000, 2000, 5, 150), () -> new SimpleClient(address.getHostAddress(), port, version, true, - new EncryptionOptions()) + new EncryptionOptions.ClientEncryptionOptions()) .connect(true), version); } diff --git a/test/distributed/org/apache/cassandra/distributed/impl/IsolatedJmx.java b/test/distributed/org/apache/cassandra/distributed/impl/IsolatedJmx.java index 59e9e8ca04..7ad57a52b6 100644 --- a/test/distributed/org/apache/cassandra/distributed/impl/IsolatedJmx.java +++ b/test/distributed/org/apache/cassandra/distributed/impl/IsolatedJmx.java @@ -94,7 +94,7 @@ public class IsolatedJmx // CASSANDRA-18508: Sensitive JMX SSL configuration options can be easily exposed Map jmxServerOptionsMap = (Map) config.getParams().get("jmx_server_options"); - EncryptionOptions jmxEncryptionOptions; + EncryptionOptions.ClientEncryptionOptions jmxEncryptionOptions; if (jmxServerOptionsMap == null) { JMXServerOptions parsingSystemProperties = JMXServerOptions.createParsingSystemProperties(); @@ -175,7 +175,7 @@ public class IsolatedJmx * @return EncryptionOptions built object */ @SuppressWarnings("unchecked") - private EncryptionOptions getJmxEncryptionOptions(Map jmxServerOptionsMap) + private EncryptionOptions.ClientEncryptionOptions getJmxEncryptionOptions(Map jmxServerOptionsMap) { if (jmxServerOptionsMap == null) return null; @@ -186,34 +186,34 @@ public class IsolatedJmx { return null; } - EncryptionOptions jmxEncryptionOptions = new EncryptionOptions(); + EncryptionOptions.ClientEncryptionOptions.Builder jmxEncryptionOptionsBuilder = new EncryptionOptions.ClientEncryptionOptions.Builder(); String[] cipherSuitesArray = (String[]) encryptionOptionsMap.get(EncryptionOptions.ConfigKey.CIPHER_SUITES.toString()); if (cipherSuitesArray != null) { - jmxEncryptionOptions = jmxEncryptionOptions.withCipherSuites(cipherSuitesArray); + jmxEncryptionOptionsBuilder.withCipherSuites(cipherSuitesArray); } List acceptedProtocols = (List) encryptionOptionsMap.get(EncryptionOptions.ConfigKey.ACCEPTED_PROTOCOLS.toString()); if (acceptedProtocols != null) { - jmxEncryptionOptions = jmxEncryptionOptions.withAcceptedProtocols(acceptedProtocols); + jmxEncryptionOptionsBuilder.withAcceptedProtocols(acceptedProtocols); } Boolean requireClientAuthValue = (Boolean) encryptionOptionsMap.get(EncryptionOptions.ConfigKey.REQUIRE_CLIENT_AUTH.toString()); - EncryptionOptions.ClientAuth requireClientAuth = requireClientAuthValue == null ? - EncryptionOptions.ClientAuth.NOT_REQUIRED : - EncryptionOptions.ClientAuth.from(String.valueOf(requireClientAuthValue)); + EncryptionOptions.ClientEncryptionOptions.ClientAuth requireClientAuth = requireClientAuthValue == null ? + EncryptionOptions.ClientEncryptionOptions.ClientAuth.NOT_REQUIRED : + EncryptionOptions.ClientEncryptionOptions.ClientAuth.from(String.valueOf(requireClientAuthValue)); Object enabledOption = encryptionOptionsMap.get(EncryptionOptions.ConfigKey.ENABLED.toString()); boolean enabled = enabledOption != null ? (Boolean) encryptionOptionsMap.get(EncryptionOptions.ConfigKey.ENABLED.toString()) : false; //CASSANDRA-18508 NOTE - We do not populate sslContextFactory configuration here for tests, it could be enhanced - jmxEncryptionOptions = jmxEncryptionOptions - .withKeyStore((String) encryptionOptionsMap.get(EncryptionOptions.ConfigKey.KEYSTORE.toString())) - .withKeyStorePassword((String) encryptionOptionsMap.get(EncryptionOptions.ConfigKey.KEYSTORE_PASSWORD.toString())) - .withTrustStore((String) encryptionOptionsMap.get(EncryptionOptions.ConfigKey.TRUSTSTORE.toString())) - .withTrustStorePassword((String) encryptionOptionsMap.get(EncryptionOptions.ConfigKey.TRUSTSTORE_PASSWORD.toString())) - .withRequireClientAuth(requireClientAuth) - .withEnabled(enabled); - return jmxEncryptionOptions; + return jmxEncryptionOptionsBuilder + .withKeyStore((String) encryptionOptionsMap.get(EncryptionOptions.ConfigKey.KEYSTORE.toString())) + .withKeyStorePassword((String) encryptionOptionsMap.get(EncryptionOptions.ConfigKey.KEYSTORE_PASSWORD.toString())) + .withTrustStore((String) encryptionOptionsMap.get(EncryptionOptions.ConfigKey.TRUSTSTORE.toString())) + .withTrustStorePassword((String) encryptionOptionsMap.get(EncryptionOptions.ConfigKey.TRUSTSTORE_PASSWORD.toString())) + .withRequireClientAuth(requireClientAuth) + .withEnabled(enabled) + .build(); } private void waitForJmxAvailability(Map env) diff --git a/test/distributed/org/apache/cassandra/distributed/test/AbstractEncryptionOptionsImpl.java b/test/distributed/org/apache/cassandra/distributed/test/AbstractEncryptionOptionsImpl.java index 25e9e64b63..7c3b91127a 100644 --- a/test/distributed/org/apache/cassandra/distributed/test/AbstractEncryptionOptionsImpl.java +++ b/test/distributed/org/apache/cassandra/distributed/test/AbstractEncryptionOptionsImpl.java @@ -56,7 +56,7 @@ import org.apache.cassandra.security.ISslContextFactory; import org.apache.cassandra.security.SSLFactory; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; import static org.apache.cassandra.distributed.test.AbstractEncryptionOptionsImpl.ConnectResult.CONNECTING; import static org.apache.cassandra.distributed.test.AbstractEncryptionOptionsImpl.ConnectResult.UNINITIALIZED; import static org.apache.cassandra.utils.concurrent.Condition.newOneTimeCondition; @@ -118,10 +118,13 @@ public class AbstractEncryptionOptionsImpl extends TestBaseImpl final int port; final List acceptedProtocols; final List cipherSuites; - final EncryptionOptions encryptionOptions = new EncryptionOptions() - .withEnabled(true) - .withKeyStore(validKeyStorePath).withKeyStorePassword(validKeyStorePassword) - .withTrustStore(validTrustStorePath).withTrustStorePassword(validTrustStorePassword); + final EncryptionOptions.ClientEncryptionOptions encryptionOptions = new EncryptionOptions.ClientEncryptionOptions.Builder() + .withEnabled(true) + .withKeyStore(validKeyStorePath) + .withKeyStorePassword(validKeyStorePassword) + .withTrustStore(validTrustStorePath) + .withTrustStorePassword(validTrustStorePassword) + .build(); private Throwable lastThrowable; private String lastProtocol; private String lastCipher; @@ -202,7 +205,7 @@ public class AbstractEncryptionOptionsImpl extends TestBaseImpl setProtocolAndCipher(null, null); SslContext sslContext = SSLFactory.getOrCreateSslContext( - encryptionOptions.withAcceptedProtocols(acceptedProtocols).withCipherSuites(cipherSuites), + new EncryptionOptions.ClientEncryptionOptions.Builder(encryptionOptions).withAcceptedProtocols(acceptedProtocols).withCipherSuites(cipherSuites).build(), REQUIRED, ISslContextFactory.SocketType.CLIENT, "test"); EventLoopGroup workerGroup = new NioEventLoopGroup(); diff --git a/test/unit/org/apache/cassandra/auth/AuthConfigTest.java b/test/unit/org/apache/cassandra/auth/AuthConfigTest.java index b9bde913be..580c48eb9f 100644 --- a/test/unit/org/apache/cassandra/auth/AuthConfigTest.java +++ b/test/unit/org/apache/cassandra/auth/AuthConfigTest.java @@ -30,6 +30,7 @@ import org.junit.rules.ExpectedException; import org.apache.cassandra.config.Config; import org.apache.cassandra.config.DatabaseDescriptor; +import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions.Builder; import org.apache.cassandra.config.ParameterizedClass; import org.apache.cassandra.locator.InetAddressAndPort; import org.apache.cassandra.utils.MBeanWrapper; @@ -52,8 +53,10 @@ public class AuthConfigTest Config config = load("cassandra-mtls.yaml"); config.internode_authenticator.class_name = "org.apache.cassandra.auth.MutualTlsInternodeAuthenticator"; config.internode_authenticator.parameters = Collections.singletonMap("validator_class_name", "org.apache.cassandra.auth.SpiffeCertificateValidator"); - config.server_encryption_options = config.server_encryption_options.withOutboundKeystore("test/conf/cassandra_ssl_test_outbound.keystore") - .withOutboundKeystorePassword("cassandra"); + config.server_encryption_options = new Builder(config.server_encryption_options) + .withOutboundKeystore("test/conf/cassandra_ssl_test_outbound.keystore") + .withOutboundKeystorePassword("cassandra") + .build(); DatabaseDescriptor.setConfig(config); MutualTlsInternodeAuthenticator authenticator = ParameterizedClass.newInstance(config.internode_authenticator, Arrays.asList("", "org.apache.cassandra.auth.")); diff --git a/test/unit/org/apache/cassandra/auth/MutualTlsAuthenticatorTest.java b/test/unit/org/apache/cassandra/auth/MutualTlsAuthenticatorTest.java index 14b31a3c87..88e44cf0ab 100644 --- a/test/unit/org/apache/cassandra/auth/MutualTlsAuthenticatorTest.java +++ b/test/unit/org/apache/cassandra/auth/MutualTlsAuthenticatorTest.java @@ -48,7 +48,7 @@ import org.apache.cassandra.utils.MBeanWrapper; import static org.apache.cassandra.auth.AuthTestUtils.getMockInetAddress; import static org.apache.cassandra.auth.AuthTestUtils.initializeIdentityRolesTable; import static org.apache.cassandra.auth.AuthTestUtils.loadCertificateChain; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -79,8 +79,10 @@ public class MutualTlsAuthenticatorTest StorageService.instance.initServer(); ((CassandraRoleManager)DatabaseDescriptor.getRoleManager()).loadIdentityStatement(); final Config config = DatabaseDescriptor.getRawConfig(); - config.client_encryption_options = config.client_encryption_options.withEnabled(true) - .withRequireClientAuth(REQUIRED); + config.client_encryption_options = new EncryptionOptions.ClientEncryptionOptions.Builder(config.client_encryption_options) + .withEnabled(true) + .withRequireClientAuth(REQUIRED) + .build(); } @After @@ -183,8 +185,10 @@ public class MutualTlsAuthenticatorTest " & client_encryption_options.require_client_auth to be true"; MutualTlsAuthenticator mutualTlsAuthenticator = createAndInitializeMtlsAuthenticator(); - config.client_encryption_options = config.client_encryption_options.withEnabled(true) - .withRequireClientAuth(EncryptionOptions.ClientAuth.NOT_REQUIRED); + config.client_encryption_options = new EncryptionOptions.ClientEncryptionOptions.Builder(config.client_encryption_options) + .withEnabled(true) + .withRequireClientAuth(EncryptionOptions.ClientEncryptionOptions.ClientAuth.NOT_REQUIRED) + .build(); expectedException.expect(ConfigurationException.class); expectedException.expectMessage(msg); mutualTlsAuthenticator.validateConfiguration(); diff --git a/test/unit/org/apache/cassandra/auth/MutualTlsInternodeAuthenticatorTest.java b/test/unit/org/apache/cassandra/auth/MutualTlsInternodeAuthenticatorTest.java index 8fdd23a444..94fe66133b 100644 --- a/test/unit/org/apache/cassandra/auth/MutualTlsInternodeAuthenticatorTest.java +++ b/test/unit/org/apache/cassandra/auth/MutualTlsInternodeAuthenticatorTest.java @@ -39,6 +39,7 @@ import org.junit.runners.Parameterized; import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.config.Config; import org.apache.cassandra.config.DatabaseDescriptor; +import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions.Builder; import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.locator.InetAddressAndPort; import org.apache.cassandra.transport.TlsTestUtils; @@ -81,8 +82,10 @@ public class MutualTlsInternodeAuthenticatorTest public void before() { Config config = DatabaseDescriptor.getRawConfig(); - config.server_encryption_options = config.server_encryption_options.withOutboundKeystore("test/conf/cassandra_ssl_test_outbound.keystore") - .withOutboundKeystorePassword("cassandra"); + config.server_encryption_options = new Builder(config.server_encryption_options) + .withOutboundKeystore("test/conf/cassandra_ssl_test_outbound.keystore") + .withOutboundKeystorePassword("cassandra") + .build(); } String getValidatorClass() @@ -164,8 +167,10 @@ public class MutualTlsInternodeAuthenticatorTest public void testNoIdentitiesInKeystore() { Config config = DatabaseDescriptor.getRawConfig(); - config.server_encryption_options = config.server_encryption_options.withOutboundKeystore(TlsTestUtils.SERVER_KEYSTORE_PATH) - .withOutboundKeystorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD); + config.server_encryption_options = new Builder(config.server_encryption_options) + .withOutboundKeystore(TlsTestUtils.SERVER_KEYSTORE_PATH) + .withOutboundKeystorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) + .build(); expectedException.expect(ConfigurationException.class); expectedException.expectMessage(String.format("No identity was extracted from the outbound keystore '%s'", TlsTestUtils.SERVER_KEYSTORE_PATH)); new MutualTlsInternodeAuthenticator(getParams()); diff --git a/test/unit/org/apache/cassandra/auth/MutualTlsWithPasswordFallbackAuthenticatorTest.java b/test/unit/org/apache/cassandra/auth/MutualTlsWithPasswordFallbackAuthenticatorTest.java index 95f7c133ea..f0c642846b 100644 --- a/test/unit/org/apache/cassandra/auth/MutualTlsWithPasswordFallbackAuthenticatorTest.java +++ b/test/unit/org/apache/cassandra/auth/MutualTlsWithPasswordFallbackAuthenticatorTest.java @@ -50,8 +50,10 @@ public class MutualTlsWithPasswordFallbackAuthenticatorTest DatabaseDescriptor.daemonInitialization(); SchemaLoader.loadSchema(); Config config = DatabaseDescriptor.getRawConfig(); - config.client_encryption_options = config.client_encryption_options.withEnabled(true) - .withRequireClientAuth(EncryptionOptions.ClientAuth.OPTIONAL); + config.client_encryption_options = new EncryptionOptions.ClientEncryptionOptions.Builder(config.client_encryption_options) + .withEnabled(true) + .withRequireClientAuth(EncryptionOptions.ClientEncryptionOptions.ClientAuth.OPTIONAL) + .build(); Map parameters = Collections.singletonMap("validator_class_name", "org.apache.cassandra.auth.SpiffeCertificateValidator"); fallbackAuthenticator = new MutualTlsWithPasswordFallbackAuthenticator(parameters); fallbackAuthenticator.setup(); diff --git a/test/unit/org/apache/cassandra/auth/jmx/JMXAuthJMXServerOptionsTest.java b/test/unit/org/apache/cassandra/auth/jmx/JMXAuthJMXServerOptionsTest.java index cb83a61eda..98749ca314 100644 --- a/test/unit/org/apache/cassandra/auth/jmx/JMXAuthJMXServerOptionsTest.java +++ b/test/unit/org/apache/cassandra/auth/jmx/JMXAuthJMXServerOptionsTest.java @@ -42,7 +42,7 @@ public class JMXAuthJMXServerOptionsTest extends AbstractJMXAuthTest String config = Paths.get(ClassLoader.getSystemResource("auth/cassandra-test-jaas.conf").toURI()).toString(); return new JMXServerOptions(true, false, 9999, 0, true, - new EncryptionOptions(), "TestLogin", config, null, null, + new EncryptionOptions.ClientEncryptionOptions(), "TestLogin", config, null, null, NoSuperUserAuthorizationProxy.class.getName()); } } diff --git a/test/unit/org/apache/cassandra/config/EncryptionOptionsEqualityTest.java b/test/unit/org/apache/cassandra/config/EncryptionOptionsEqualityTest.java index 5e6d26b817..b2770c2361 100644 --- a/test/unit/org/apache/cassandra/config/EncryptionOptionsEqualityTest.java +++ b/test/unit/org/apache/cassandra/config/EncryptionOptionsEqualityTest.java @@ -27,8 +27,8 @@ import org.apache.cassandra.security.DefaultSslContextFactory; import org.apache.cassandra.security.DummySslContextFactoryImpl; import org.apache.cassandra.transport.TlsTestUtils; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.NOT_REQUIRED; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.NOT_REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -40,23 +40,25 @@ public class EncryptionOptionsEqualityTest { private EncryptionOptions.ServerEncryptionOptions createServerEncryptionOptions() { - return new EncryptionOptions.ServerEncryptionOptions() + EncryptionOptions.ServerEncryptionOptions.Builder serverEncryptionOptionsBuilder = new EncryptionOptions.ServerEncryptionOptions.Builder(); + return serverEncryptionOptionsBuilder + .withOutboundKeystore(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PATH) + .withOutboundKeystorePassword(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PASSWORD) .withStoreType("JKS") .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) .withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PATH) .withTrustStorePassword(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD) - .withOutboundKeystore(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PATH) - .withOutboundKeystorePassword(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PASSWORD) .withProtocol("TLSv1.1") .withRequireClientAuth(REQUIRED) - .withRequireEndpointVerification(false); + .withRequireEndpointVerification(false) + .build(); } @Test public void testKeystoreOptions() { - EncryptionOptions encryptionOptions1 = - new EncryptionOptions() + EncryptionOptions.ServerEncryptionOptions encryptionOptions1 = + new EncryptionOptions.ServerEncryptionOptions.Builder() .withStoreType("JKS") .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) @@ -64,10 +66,11 @@ public class EncryptionOptionsEqualityTest .withTrustStorePassword(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD) .withProtocol("TLSv1.1") .withRequireClientAuth(REQUIRED) - .withRequireEndpointVerification(false); + .withRequireEndpointVerification(false) + .build(); - EncryptionOptions encryptionOptions2 = - new EncryptionOptions() + EncryptionOptions.ServerEncryptionOptions encryptionOptions2 = + new EncryptionOptions.ServerEncryptionOptions.Builder() .withStoreType("JKS") .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) @@ -75,7 +78,8 @@ public class EncryptionOptionsEqualityTest .withTrustStorePassword(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD) .withProtocol("TLSv1.1") .withRequireClientAuth(REQUIRED) - .withRequireEndpointVerification(false); + .withRequireEndpointVerification(false) + .build(); assertEquals(encryptionOptions1, encryptionOptions2); assertEquals(encryptionOptions1.hashCode(), encryptionOptions2.hashCode()); @@ -83,8 +87,8 @@ public class EncryptionOptionsEqualityTest @Test public void testKeystoreOptionsWithPasswordFile() { - EncryptionOptions encryptionOptions1 = - new EncryptionOptions() + EncryptionOptions.ServerEncryptionOptions encryptionOptions1 = + new EncryptionOptions.ServerEncryptionOptions.Builder() .withStoreType("JKS") .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) .withKeyStorePasswordFile(TlsTestUtils.SERVER_KEYSTORE_PASSWORD_FILE) @@ -92,10 +96,11 @@ public class EncryptionOptionsEqualityTest .withTrustStorePasswordFile(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD_FILE) .withProtocol("TLSv1.1") .withRequireClientAuth(REQUIRED) - .withRequireEndpointVerification(false); + .withRequireEndpointVerification(false) + .build(); - EncryptionOptions encryptionOptions2 = - new EncryptionOptions() + EncryptionOptions.ServerEncryptionOptions encryptionOptions2 = + new EncryptionOptions.ServerEncryptionOptions.Builder() .withStoreType("JKS") .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) .withKeyStorePasswordFile(TlsTestUtils.SERVER_KEYSTORE_PASSWORD_FILE) @@ -103,7 +108,8 @@ public class EncryptionOptionsEqualityTest .withTrustStorePasswordFile(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD_FILE) .withProtocol("TLSv1.1") .withRequireClientAuth(REQUIRED) - .withRequireEndpointVerification(false); + .withRequireEndpointVerification(false) + .build(); assertEquals(encryptionOptions1, encryptionOptions2); assertEquals(encryptionOptions1.hashCode(), encryptionOptions2.hashCode()); @@ -115,15 +121,17 @@ public class EncryptionOptionsEqualityTest EncryptionOptions.ServerEncryptionOptions encryptionOptions1 = createServerEncryptionOptions(); EncryptionOptions.ServerEncryptionOptions encryptionOptions2 = createServerEncryptionOptions(); - encryptionOptions1 = encryptionOptions1 + encryptionOptions1 = new EncryptionOptions.ServerEncryptionOptions.Builder(encryptionOptions1) .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) .withKeyStorePassword(null) - .withKeyStorePasswordFile(TlsTestUtils.SERVER_KEYSTORE_PASSWORD_FILE); + .withKeyStorePasswordFile(TlsTestUtils.SERVER_KEYSTORE_PASSWORD_FILE) + .build(); - encryptionOptions2 = encryptionOptions2 + encryptionOptions2 = new EncryptionOptions.ServerEncryptionOptions.Builder(encryptionOptions2) .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) .withKeyStorePassword(null) - .withKeyStorePasswordFile(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD_FILE); + .withKeyStorePasswordFile(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD_FILE) + .build(); assertNotEquals(encryptionOptions1, encryptionOptions2); assertNotEquals(encryptionOptions1.hashCode(), encryptionOptions2.hashCode()); @@ -135,22 +143,24 @@ public class EncryptionOptionsEqualityTest Map parameters1 = new HashMap<>(); parameters1.put("key1", "value1"); parameters1.put("key2", "value2"); - EncryptionOptions encryptionOptions1 = - new EncryptionOptions() + EncryptionOptions.ClientEncryptionOptions encryptionOptions1 = + new EncryptionOptions.ClientEncryptionOptions.Builder() .withSslContextFactory(new ParameterizedClass(DummySslContextFactoryImpl.class.getName(), parameters1)) .withProtocol("TLSv1.1") .withRequireClientAuth(REQUIRED) - .withRequireEndpointVerification(false); + .withRequireEndpointVerification(false) + .build(); Map parameters2 = new HashMap<>(); parameters2.put("key1", "value1"); parameters2.put("key2", "value2"); - EncryptionOptions encryptionOptions2 = - new EncryptionOptions() + EncryptionOptions.ClientEncryptionOptions encryptionOptions2 = + new EncryptionOptions.ClientEncryptionOptions.Builder() .withSslContextFactory(new ParameterizedClass(DummySslContextFactoryImpl.class.getName(), parameters2)) .withProtocol("TLSv1.1") .withRequireClientAuth(REQUIRED) - .withRequireEndpointVerification(false); + .withRequireEndpointVerification(false) + .build(); assertEquals(encryptionOptions1, encryptionOptions2); assertEquals(encryptionOptions1.hashCode(), encryptionOptions2.hashCode()); @@ -162,22 +172,24 @@ public class EncryptionOptionsEqualityTest Map parameters1 = new HashMap<>(); parameters1.put("key1", "value1"); parameters1.put("key2", "value2"); - EncryptionOptions encryptionOptions1 = - new EncryptionOptions() + EncryptionOptions.ClientEncryptionOptions encryptionOptions1 = + new EncryptionOptions.ClientEncryptionOptions.Builder() .withSslContextFactory(new ParameterizedClass(DummySslContextFactoryImpl.class.getName(), parameters1)) .withProtocol("TLSv1.1") .withRequireClientAuth(NOT_REQUIRED) - .withRequireEndpointVerification(true); + .withRequireEndpointVerification(true) + .build(); Map parameters2 = new HashMap<>(); parameters2.put("key1", "value1"); parameters2.put("key2", "value2"); - EncryptionOptions encryptionOptions2 = - new EncryptionOptions() + EncryptionOptions.ClientEncryptionOptions encryptionOptions2 = + new EncryptionOptions.ClientEncryptionOptions.Builder() .withSslContextFactory(new ParameterizedClass(DefaultSslContextFactory.class.getName(), parameters2)) .withProtocol("TLSv1.1") .withRequireClientAuth(NOT_REQUIRED) - .withRequireEndpointVerification(true); + .withRequireEndpointVerification(true) + .build(); assertNotEquals(encryptionOptions1, encryptionOptions2); assertNotEquals(encryptionOptions1.hashCode(), encryptionOptions2.hashCode()); @@ -189,18 +201,20 @@ public class EncryptionOptionsEqualityTest Map parameters1 = new HashMap<>(); parameters1.put("key1", "value11"); parameters1.put("key2", "value12"); - EncryptionOptions encryptionOptions1 = - new EncryptionOptions() + EncryptionOptions.ClientEncryptionOptions encryptionOptions1 = + new EncryptionOptions.ClientEncryptionOptions.Builder() .withSslContextFactory(new ParameterizedClass(DummySslContextFactoryImpl.class.getName(), parameters1)) - .withProtocol("TLSv1.1"); + .withProtocol("TLSv1.1") + .build(); Map parameters2 = new HashMap<>(); parameters2.put("key1", "value21"); parameters2.put("key2", "value22"); - EncryptionOptions encryptionOptions2 = - new EncryptionOptions() + EncryptionOptions.ClientEncryptionOptions encryptionOptions2 = + new EncryptionOptions.ClientEncryptionOptions.Builder() .withSslContextFactory(new ParameterizedClass(DummySslContextFactoryImpl.class.getName(), parameters2)) - .withProtocol("TLSv1.1"); + .withProtocol("TLSv1.1") + .build(); assertNotEquals(encryptionOptions1, encryptionOptions2); assertNotEquals(encryptionOptions1.hashCode(), encryptionOptions2.hashCode()); @@ -222,13 +236,15 @@ public class EncryptionOptionsEqualityTest EncryptionOptions.ServerEncryptionOptions encryptionOptions1 = createServerEncryptionOptions(); EncryptionOptions.ServerEncryptionOptions encryptionOptions2 = createServerEncryptionOptions(); - encryptionOptions1 = encryptionOptions1 + encryptionOptions1 = new EncryptionOptions.ServerEncryptionOptions.Builder(encryptionOptions1) .withOutboundKeystore("test/conf/cassandra_outbound1.keystore") - .withOutboundKeystorePassword("cassandra1"); + .withOutboundKeystorePassword("cassandra1") + .build(); - encryptionOptions2 = encryptionOptions2 + encryptionOptions2 = new EncryptionOptions.ServerEncryptionOptions.Builder(encryptionOptions2) .withOutboundKeystore("test/conf/cassandra_outbound2.keystore") - .withOutboundKeystorePassword("cassandra2"); + .withOutboundKeystorePassword("cassandra2") + .build(); assertNotEquals(encryptionOptions1, encryptionOptions2); assertNotEquals(encryptionOptions1.hashCode(), encryptionOptions2.hashCode()); @@ -240,13 +256,15 @@ public class EncryptionOptionsEqualityTest EncryptionOptions.ServerEncryptionOptions encryptionOptions1 = createServerEncryptionOptions(); EncryptionOptions.ServerEncryptionOptions encryptionOptions2 = createServerEncryptionOptions(); - encryptionOptions1 = encryptionOptions1 + encryptionOptions1 = new EncryptionOptions.ServerEncryptionOptions.Builder(encryptionOptions1) .withKeyStore("test/conf/cassandra1.keystore") - .withKeyStorePassword("cassandra1"); + .withKeyStorePassword("cassandra1") + .build(); - encryptionOptions2 = encryptionOptions2 + encryptionOptions2 = new EncryptionOptions.ServerEncryptionOptions.Builder(encryptionOptions2) .withKeyStore("test/conf/cassandra2.keystore") - .withKeyStorePassword("cassandra2"); + .withKeyStorePassword("cassandra2") + .build(); assertNotEquals(encryptionOptions1, encryptionOptions2); assertNotEquals(encryptionOptions1.hashCode(), encryptionOptions2.hashCode()); diff --git a/test/unit/org/apache/cassandra/config/EncryptionOptionsTest.java b/test/unit/org/apache/cassandra/config/EncryptionOptionsTest.java index 5ef08eb060..cec982d0c5 100644 --- a/test/unit/org/apache/cassandra/config/EncryptionOptionsTest.java +++ b/test/unit/org/apache/cassandra/config/EncryptionOptionsTest.java @@ -23,11 +23,11 @@ import java.util.HashMap; import java.util.Map; import com.google.common.collect.ImmutableMap; -import org.apache.cassandra.io.util.File; import org.junit.Assert; import org.junit.Test; import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.io.util.File; import org.assertj.core.api.Assertions; import org.yaml.snakeyaml.constructor.ConstructorException; @@ -46,11 +46,11 @@ public class EncryptionOptionsTest { static class EncryptionOptionsTestCase { - final EncryptionOptions encryptionOptions; + final EncryptionOptions.ClientEncryptionOptions encryptionOptions; final EncryptionOptions.TlsEncryptionPolicy expected; final String description; - public EncryptionOptionsTestCase(EncryptionOptions encryptionOptions, EncryptionOptions.TlsEncryptionPolicy expected, String description) + public EncryptionOptionsTestCase(EncryptionOptions.ClientEncryptionOptions encryptionOptions, EncryptionOptions.TlsEncryptionPolicy expected, String description) { this.encryptionOptions = encryptionOptions; this.expected = expected; @@ -59,25 +59,25 @@ public class EncryptionOptionsTest public static EncryptionOptionsTestCase of(Boolean optional, String keystorePath, Boolean enabled, EncryptionOptions.TlsEncryptionPolicy expected) { - return new EncryptionOptionsTestCase(new EncryptionOptions(new ParameterizedClass("org.apache.cassandra.security.DefaultSslContextFactory", - new HashMap<>()), - keystorePath, "dummypass", null, - "dummytruststore", "dummypass", null, - Collections.emptyList(), null, null, null, "JKS", "false", false, enabled, optional, null, null) + return new EncryptionOptionsTestCase(new EncryptionOptions.ClientEncryptionOptions(new ParameterizedClass("org.apache.cassandra.security.DefaultSslContextFactory", + new HashMap<>()), + keystorePath, "dummypass", null, + "dummytruststore", "dummypass", null, + Collections.emptyList(), null, null, null, "JKS", "false", false, enabled, optional, null, null) .applyConfig(), expected, String.format("optional=%s keystore=%s enabled=%s", optional, keystorePath, enabled)); } public static EncryptionOptionsTestCase of(Boolean optional, String keystorePath, Boolean enabled, - Map customSslContextFactoryParams, + Map customSslContextFactoryParams, EncryptionOptions.TlsEncryptionPolicy expected) { - return new EncryptionOptionsTestCase(new EncryptionOptions(new ParameterizedClass("org.apache.cassandra.security.DefaultSslContextFactory", - customSslContextFactoryParams), - keystorePath, "dummypass", null, - "dummytruststore", "dummypass", null, - Collections.emptyList(), null, null, null, "JKS", "false", false, enabled, optional, null, null) + return new EncryptionOptionsTestCase(new EncryptionOptions.ClientEncryptionOptions(new ParameterizedClass("org.apache.cassandra.security.DefaultSslContextFactory", + customSslContextFactoryParams), + keystorePath, "dummypass", null, + "dummytruststore", "dummypass", null, + Collections.emptyList(), null, null, null, "JKS", "false", false, enabled, optional, null, null) .applyConfig(), expected, String.format("optional=%s keystore=%s enabled=%s", optional, keystorePath, enabled)); @@ -87,15 +87,15 @@ public class EncryptionOptionsTest static final String absentKeystore = "test/conf/missing-keystore-is-not-here"; static final String presentKeystore = "test/conf/keystore.jks"; final EncryptionOptionsTestCase[] encryptionOptionTestCases = { - // Optional Keystore Enabled Expected - EncryptionOptionsTestCase.of(null, absentKeystore, false, UNENCRYPTED), - EncryptionOptionsTestCase.of(null, absentKeystore, true, ENCRYPTED), - EncryptionOptionsTestCase.of(null, presentKeystore, false, OPTIONAL), - EncryptionOptionsTestCase.of(null, presentKeystore, true, ENCRYPTED), - EncryptionOptionsTestCase.of(false, absentKeystore, false, UNENCRYPTED), - EncryptionOptionsTestCase.of(false, absentKeystore, true, ENCRYPTED), - EncryptionOptionsTestCase.of(true, presentKeystore, false, OPTIONAL), - EncryptionOptionsTestCase.of(true, presentKeystore, true, OPTIONAL) + // Optional Keystore Enabled Expected + EncryptionOptionsTestCase.of(null, absentKeystore, false, UNENCRYPTED), + EncryptionOptionsTestCase.of(null, absentKeystore, true, ENCRYPTED), + EncryptionOptionsTestCase.of(null, presentKeystore, false, OPTIONAL), + EncryptionOptionsTestCase.of(null, presentKeystore, true, ENCRYPTED), + EncryptionOptionsTestCase.of(false, absentKeystore, false, UNENCRYPTED), + EncryptionOptionsTestCase.of(false, absentKeystore, true, ENCRYPTED), + EncryptionOptionsTestCase.of(true, presentKeystore, false, OPTIONAL), + EncryptionOptionsTestCase.of(true, presentKeystore, true, OPTIONAL) }; @Test @@ -111,11 +111,11 @@ public class EncryptionOptionsTest static class ServerEncryptionOptionsTestCase { - final EncryptionOptions encryptionOptions; + final EncryptionOptions.ServerEncryptionOptions encryptionOptions; final EncryptionOptions.TlsEncryptionPolicy expected; final String description; - public ServerEncryptionOptionsTestCase(EncryptionOptions encryptionOptions, EncryptionOptions.TlsEncryptionPolicy expected, String description) + public ServerEncryptionOptionsTestCase(EncryptionOptions.ServerEncryptionOptions encryptionOptions, EncryptionOptions.TlsEncryptionPolicy expected, String description) { this.encryptionOptions = encryptionOptions; this.expected = expected; @@ -131,10 +131,10 @@ public class EncryptionOptionsTest keystorePath, "dummypass", null, keystorePath, "dummypass", null, "dummytruststore", "dummypass", null, - Collections.emptyList(), null, null, null, "JKS", "false", false, optional, internodeEncryption, false, null, null) + Collections.emptyList(), null, null, null, "JKS", "false", false, optional, internodeEncryption, false, null, null) .applyConfig(), - expected, - String.format("optional=%s keystore=%s internode=%s", optional, keystorePath, internodeEncryption)); + expected, + String.format("optional=%s keystore=%s internode=%s", optional, keystorePath, internodeEncryption)); } } @@ -143,8 +143,8 @@ public class EncryptionOptionsTest { Map yaml = ImmutableMap.of( "server_encryption_options", ImmutableMap.of( - "isEnabled", false - ) + "isEnabled", false + ) ); Assertions.assertThatThrownBy(() -> YamlConfigurationLoader.fromMap(yaml, Config.class)) @@ -157,8 +157,8 @@ public class EncryptionOptionsTest { Map yaml = ImmutableMap.of( "server_encryption_options", ImmutableMap.of( - "isOptional", false - ) + "isOptional", false + ) ); Assertions.assertThatThrownBy(() -> YamlConfigurationLoader.fromMap(yaml, Config.class)) @@ -171,11 +171,11 @@ public class EncryptionOptionsTest { Map yaml = ImmutableMap.of( "server_encryption_options", ImmutableMap.of( - "max_certificate_validity_period", "2d" - ), + "max_certificate_validity_period", "2d" + ), "client_encryption_options", ImmutableMap.of( - "max_certificate_validity_period", "10d" - ) + "max_certificate_validity_period", "10d" + ) ); Config config = YamlConfigurationLoader.fromMap(yaml, Config.class); @@ -188,8 +188,8 @@ public class EncryptionOptionsTest { Map yaml = ImmutableMap.of( "server_encryption_options", ImmutableMap.of( - "max_certificate_validity_period", "not-a-valid-input" - ) + "max_certificate_validity_period", "not-a-valid-input" + ) ); Assertions.assertThatThrownBy(() -> YamlConfigurationLoader.fromMap(yaml, Config.class)) @@ -202,8 +202,8 @@ public class EncryptionOptionsTest { Map yaml = ImmutableMap.of( "server_encryption_options", ImmutableMap.of( - "max_certificate_validity_period", "-2d" - ) + "max_certificate_validity_period", "-2d" + ) ); Assertions.assertThatThrownBy(() -> YamlConfigurationLoader.fromMap(yaml, Config.class)) @@ -213,26 +213,26 @@ public class EncryptionOptionsTest final ServerEncryptionOptionsTestCase[] serverEncryptionOptionTestCases = { - // Optional Keystore Internode Expected - ServerEncryptionOptionsTestCase.of(null, absentKeystore, none, UNENCRYPTED), - ServerEncryptionOptionsTestCase.of(null, absentKeystore, rack, OPTIONAL), - ServerEncryptionOptionsTestCase.of(null, absentKeystore, dc, OPTIONAL), - ServerEncryptionOptionsTestCase.of(null, absentKeystore, all, ENCRYPTED), + // Optional Keystore Internode Expected + ServerEncryptionOptionsTestCase.of(null, absentKeystore, none, UNENCRYPTED), + ServerEncryptionOptionsTestCase.of(null, absentKeystore, rack, OPTIONAL), + ServerEncryptionOptionsTestCase.of(null, absentKeystore, dc, OPTIONAL), + ServerEncryptionOptionsTestCase.of(null, absentKeystore, all, ENCRYPTED), - ServerEncryptionOptionsTestCase.of(null, presentKeystore, none, OPTIONAL), - ServerEncryptionOptionsTestCase.of(null, presentKeystore, rack, OPTIONAL), - ServerEncryptionOptionsTestCase.of(null, absentKeystore, dc, OPTIONAL), - ServerEncryptionOptionsTestCase.of(null, absentKeystore, all, ENCRYPTED), + ServerEncryptionOptionsTestCase.of(null, presentKeystore, none, OPTIONAL), + ServerEncryptionOptionsTestCase.of(null, presentKeystore, rack, OPTIONAL), + ServerEncryptionOptionsTestCase.of(null, absentKeystore, dc, OPTIONAL), + ServerEncryptionOptionsTestCase.of(null, absentKeystore, all, ENCRYPTED), - ServerEncryptionOptionsTestCase.of(false, absentKeystore, none, UNENCRYPTED), - ServerEncryptionOptionsTestCase.of(false, absentKeystore, rack, OPTIONAL), - ServerEncryptionOptionsTestCase.of(false, absentKeystore, dc, OPTIONAL), - ServerEncryptionOptionsTestCase.of(false, absentKeystore, all, ENCRYPTED), + ServerEncryptionOptionsTestCase.of(false, absentKeystore, none, UNENCRYPTED), + ServerEncryptionOptionsTestCase.of(false, absentKeystore, rack, OPTIONAL), + ServerEncryptionOptionsTestCase.of(false, absentKeystore, dc, OPTIONAL), + ServerEncryptionOptionsTestCase.of(false, absentKeystore, all, ENCRYPTED), - ServerEncryptionOptionsTestCase.of(true, presentKeystore, none, OPTIONAL), - ServerEncryptionOptionsTestCase.of(true, presentKeystore, rack, OPTIONAL), - ServerEncryptionOptionsTestCase.of(true, absentKeystore, dc, OPTIONAL), - ServerEncryptionOptionsTestCase.of(true, absentKeystore, all, OPTIONAL), + ServerEncryptionOptionsTestCase.of(true, presentKeystore, none, OPTIONAL), + ServerEncryptionOptionsTestCase.of(true, presentKeystore, rack, OPTIONAL), + ServerEncryptionOptionsTestCase.of(true, absentKeystore, dc, OPTIONAL), + ServerEncryptionOptionsTestCase.of(true, absentKeystore, all, OPTIONAL), }; @Test @@ -246,12 +246,12 @@ public class EncryptionOptionsTest } } - @Test(expected = IllegalArgumentException.class) + @Test(expected = IllegalArgumentException.class) public void testMisplacedConfigKey() { Map customSslContextFactoryParams = new HashMap<>(); - for(EncryptionOptions.ConfigKey configKey: EncryptionOptions.ConfigKey.values()) + for (EncryptionOptions.ConfigKey configKey : EncryptionOptions.ConfigKey.values()) { customSslContextFactoryParams.put(configKey.toString(), "my-custom-value"); } diff --git a/test/unit/org/apache/cassandra/cql3/CQLTester.java b/test/unit/org/apache/cassandra/cql3/CQLTester.java index 91d86d2c81..05c64f956e 100644 --- a/test/unit/org/apache/cassandra/cql3/CQLTester.java +++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java @@ -663,13 +663,15 @@ public abstract class CQLTester public static void requireNativeProtocolClientEncryption() { DatabaseDescriptor.updateNativeProtocolEncryptionOptions((encryptionOptions) -> - encryptionOptions.withEnabled(true) - .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) - .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) - .withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PATH) - .withTrustStorePassword(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD) - .withRequireEndpointVerification(false) - .withRequireClientAuth(EncryptionOptions.ClientAuth.OPTIONAL)); + new EncryptionOptions.ClientEncryptionOptions.Builder(encryptionOptions) + .withEnabled(true) + .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) + .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) + .withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PATH) + .withTrustStorePassword(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD) + .withRequireEndpointVerification(false) + .withRequireClientAuth(EncryptionOptions.ClientEncryptionOptions.ClientAuth.OPTIONAL) + .build()); } /** @@ -1691,7 +1693,7 @@ public abstract class CQLTester protected SimpleClient newSimpleClient(ProtocolVersion version) throws IOException { - return new SimpleClient(nativeAddr.getHostAddress(), nativePort, version, version.isBeta(), new EncryptionOptions().applyConfig()) + return new SimpleClient(nativeAddr.getHostAddress(), nativePort, version, version.isBeta(), new EncryptionOptions.ClientEncryptionOptions()) .connect(false, false); } diff --git a/test/unit/org/apache/cassandra/db/virtual/SettingsTableTest.java b/test/unit/org/apache/cassandra/db/virtual/SettingsTableTest.java index 71b9172da7..78fb0d47d6 100644 --- a/test/unit/org/apache/cassandra/db/virtual/SettingsTableTest.java +++ b/test/unit/org/apache/cassandra/db/virtual/SettingsTableTest.java @@ -31,6 +31,7 @@ import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import org.apache.cassandra.config.Config; import org.apache.cassandra.config.DurationSpec; +import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions.Builder; import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions.InternodeEncryption; import org.apache.cassandra.config.JMXServerOptions; import org.apache.cassandra.config.ParameterizedClass; @@ -38,7 +39,7 @@ import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.security.SSLFactory; import org.yaml.snakeyaml.introspector.Property; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; public class SettingsTableTest extends CQLTester { @@ -176,52 +177,53 @@ public class SettingsTableTest extends CQLTester List expectedNames = SettingsTable.PROPERTIES.keySet().stream().filter(n -> n.startsWith("server_encryption")).collect(Collectors.toList()); Assert.assertEquals(expectedNames.size(), executeNet(all).all().size()); + Builder serverEncryptionOptionsBuilder = new Builder(config.server_encryption_options); check(pre + "algorithm", null); - config.server_encryption_options = config.server_encryption_options.withAlgorithm("SUPERSSL"); + config.server_encryption_options = serverEncryptionOptionsBuilder.withAlgorithm("SUPERSSL").build(); check(pre + "algorithm", "SUPERSSL"); check(pre + "cipher_suites", null); - config.server_encryption_options = config.server_encryption_options.withCipherSuites("c1", "c2"); + config.server_encryption_options = serverEncryptionOptionsBuilder.withCipherSuites("c1", "c2").build(); check(pre + "cipher_suites", "[c1, c2]"); // name doesn't match yaml check(pre + "protocol", null); - config.server_encryption_options = config.server_encryption_options.withProtocol("TLSv5"); + config.server_encryption_options = serverEncryptionOptionsBuilder.withProtocol("TLSv5").build(); check(pre + "protocol", "[TLSv5]"); - config.server_encryption_options = config.server_encryption_options.withProtocol("TLS"); + config.server_encryption_options = serverEncryptionOptionsBuilder.withProtocol("TLS").build(); check(pre + "protocol", SSLFactory.tlsInstanceProtocolSubstitution().toString()); - config.server_encryption_options = config.server_encryption_options.withProtocol("TLS"); - config.server_encryption_options = config.server_encryption_options.withAcceptedProtocols(ImmutableList.of("TLSv1.2","TLSv1.1")); + config.server_encryption_options = serverEncryptionOptionsBuilder.withProtocol("TLS").build(); + config.server_encryption_options = serverEncryptionOptionsBuilder.withAcceptedProtocols(ImmutableList.of("TLSv1.2","TLSv1.1")).build(); check(pre + "protocol", "[TLSv1.2, TLSv1.1]"); - config.server_encryption_options = config.server_encryption_options.withProtocol("TLSv2"); - config.server_encryption_options = config.server_encryption_options.withAcceptedProtocols(ImmutableList.of("TLSv1.2","TLSv1.1")); + config.server_encryption_options = serverEncryptionOptionsBuilder.withProtocol("TLSv2").build(); + config.server_encryption_options = serverEncryptionOptionsBuilder.withAcceptedProtocols(ImmutableList.of("TLSv1.2","TLSv1.1")).build(); check(pre + "protocol", "[TLSv1.2, TLSv1.1, TLSv2]"); // protocol goes after the explicit accept list if non-TLS check(pre + "optional", "false"); - config.server_encryption_options = config.server_encryption_options.withOptional(true); + config.server_encryption_options = serverEncryptionOptionsBuilder.withOptional(true).build(); check(pre + "optional", "true"); // name doesn't match yaml check(pre + "client_auth", "false"); - config.server_encryption_options = config.server_encryption_options.withRequireClientAuth(REQUIRED); + config.server_encryption_options = serverEncryptionOptionsBuilder.withRequireClientAuth(REQUIRED).build(); check(pre + "client_auth", "true"); // name doesn't match yaml check(pre + "endpoint_verification", "false"); - config.server_encryption_options = config.server_encryption_options.withRequireEndpointVerification(true); + config.server_encryption_options = serverEncryptionOptionsBuilder.withRequireEndpointVerification(true).build(); check(pre + "endpoint_verification", "true"); check(pre + "internode_encryption", "none"); - config.server_encryption_options = config.server_encryption_options.withInternodeEncryption(InternodeEncryption.all); + config.server_encryption_options = serverEncryptionOptionsBuilder.withInternodeEncryption(InternodeEncryption.all).build(); check(pre + "internode_encryption", "all"); check(pre + "enabled", "true"); // name doesn't match yaml check(pre + "legacy_ssl_storage_port", "false"); - config.server_encryption_options = config.server_encryption_options.withLegacySslStoragePort(true); + config.server_encryption_options = serverEncryptionOptionsBuilder.withLegacySslStoragePort(true).build(); check(pre + "legacy_ssl_storage_port", "true"); } diff --git a/test/unit/org/apache/cassandra/net/ConnectionTest.java b/test/unit/org/apache/cassandra/net/ConnectionTest.java index 70bb0c8046..233d067d12 100644 --- a/test/unit/org/apache/cassandra/net/ConnectionTest.java +++ b/test/unit/org/apache/cassandra/net/ConnectionTest.java @@ -57,6 +57,7 @@ import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.EncryptionOptions; +import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions.Builder; import org.apache.cassandra.db.commitlog.CommitLog; import org.apache.cassandra.distributed.test.log.ClusterMetadataTestHelper; import org.apache.cassandra.exceptions.RequestFailure; @@ -72,7 +73,7 @@ import org.apache.cassandra.utils.FBUtilities; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.NOT_REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.NOT_REQUIRED; import static org.apache.cassandra.net.MessagingService.VERSION_40; import static org.apache.cassandra.net.NoPayload.noPayload; import static org.apache.cassandra.net.MessagingService.current_version; @@ -176,17 +177,18 @@ public class ConnectionTest } } - static final EncryptionOptions.ServerEncryptionOptions encryptionOptions = - new EncryptionOptions.ServerEncryptionOptions() + static final EncryptionOptions.Builder encryptionOptionsBuilder = + new Builder() .withLegacySslStoragePort(true) - .withOptional(true) .withInternodeEncryption(EncryptionOptions.ServerEncryptionOptions.InternodeEncryption.all) + .withOptional(true) .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) .withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PATH) .withTrustStorePassword(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD) .withRequireClientAuth(NOT_REQUIRED) .withCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA"); + static final EncryptionOptions.ServerEncryptionOptions encryptionOptions = encryptionOptionsBuilder.build(); static final List> MODIFIERS = ImmutableList.of( settings -> settings.outbound(outbound -> outbound.withEncryption(encryptionOptions)) diff --git a/test/unit/org/apache/cassandra/net/HandshakeTest.java b/test/unit/org/apache/cassandra/net/HandshakeTest.java index c84643497d..2806bac86d 100644 --- a/test/unit/org/apache/cassandra/net/HandshakeTest.java +++ b/test/unit/org/apache/cassandra/net/HandshakeTest.java @@ -39,6 +39,7 @@ import io.netty.channel.EventLoop; import io.netty.util.concurrent.Future; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions; +import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions.Builder; import org.apache.cassandra.config.ParameterizedClass; import org.apache.cassandra.db.commitlog.CommitLog; import org.apache.cassandra.distributed.test.log.ClusterMetadataTestHelper; @@ -49,9 +50,9 @@ import org.apache.cassandra.security.DefaultSslContextFactory; import org.apache.cassandra.transport.TlsTestUtils; import org.apache.cassandra.utils.concurrent.AsyncPromise; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.NOT_REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; import static org.apache.cassandra.net.ConnectionType.SMALL_MESSAGES; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.NOT_REQUIRED; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; import static org.apache.cassandra.net.MessagingService.current_version; import static org.apache.cassandra.net.MessagingService.minimum_version; import static org.apache.cassandra.net.OutboundConnectionInitiator.Result; @@ -279,26 +280,28 @@ public class HandshakeTest private ServerEncryptionOptions getServerEncryptionOptions(SslFallbackConnectionType sslConnectionType, boolean optional) { - ServerEncryptionOptions serverEncryptionOptions = new ServerEncryptionOptions().withOptional(optional) - .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) - .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) - .withOutboundKeystore(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PATH) - .withOutboundKeystorePassword(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PASSWORD) - .withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PATH) - .withTrustStorePassword(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD) - .withSslContextFactory((new ParameterizedClass(DefaultSslContextFactory.class.getName(), - new HashMap<>()))); + Builder serverEncryptionOptionsBuilder = new Builder(); + + serverEncryptionOptionsBuilder.withOutboundKeystore(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PATH) + .withOutboundKeystorePassword(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PASSWORD) + .withOptional(optional) + .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) + .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) + .withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PATH).withTrustStorePassword(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD) + .withSslContextFactory((new ParameterizedClass(DefaultSslContextFactory.class.getName(), + new HashMap<>()))); + if (sslConnectionType == SslFallbackConnectionType.MTLS) { - serverEncryptionOptions = serverEncryptionOptions.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) - .withRequireClientAuth(REQUIRED); + serverEncryptionOptionsBuilder.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) + .withRequireClientAuth(REQUIRED); } else if (sslConnectionType == SslFallbackConnectionType.SSL) { - serverEncryptionOptions = serverEncryptionOptions.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) - .withRequireClientAuth(NOT_REQUIRED); + serverEncryptionOptionsBuilder.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) + .withRequireClientAuth(NOT_REQUIRED); } - return serverEncryptionOptions; + return serverEncryptionOptionsBuilder.build(); } private InboundSockets getInboundSocket(ServerEncryptionOptions serverEncryptionOptions) diff --git a/test/unit/org/apache/cassandra/net/MessagingServiceTest.java b/test/unit/org/apache/cassandra/net/MessagingServiceTest.java index 95c72f4bc0..45746d5e6e 100644 --- a/test/unit/org/apache/cassandra/net/MessagingServiceTest.java +++ b/test/unit/org/apache/cassandra/net/MessagingServiceTest.java @@ -50,6 +50,7 @@ import com.codahale.metrics.Timer; import org.apache.cassandra.auth.IInternodeAuthenticator; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions; +import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions.Builder; import org.apache.cassandra.db.commitlog.CommitLog; import org.apache.cassandra.distributed.test.log.ClusterMetadataTestHelper; import org.apache.cassandra.exceptions.ConfigurationException; @@ -257,8 +258,7 @@ public class MessagingServiceTest public void testFailedOutboundInternodeAuth() throws Exception { // Listen on serverside for connections - ServerEncryptionOptions serverEncryptionOptions = new ServerEncryptionOptions() - .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.none); + ServerEncryptionOptions serverEncryptionOptions = new Builder().withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.none).build(); DatabaseDescriptor.setInternodeAuthenticator(REJECT_OUTBOUND_AUTHENTICATOR); InetAddress listenAddress = FBUtilities.getJustLocalAddress(); @@ -293,8 +293,7 @@ public class MessagingServiceTest @Test public void testFailedInboundInternodeAuth() throws IOException, InterruptedException { - ServerEncryptionOptions serverEncryptionOptions = new ServerEncryptionOptions() - .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.none); + ServerEncryptionOptions serverEncryptionOptions = new Builder().withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.none).build(); DatabaseDescriptor.setInternodeAuthenticator(ALLOW_NOTHING_AUTHENTICATOR); InetAddress listenAddress = FBUtilities.getJustLocalAddress(); @@ -348,56 +347,54 @@ public class MessagingServiceTest @Test public void listenPlainConnection() throws InterruptedException { - ServerEncryptionOptions serverEncryptionOptions = new ServerEncryptionOptions() - .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.none); + ServerEncryptionOptions serverEncryptionOptions = new Builder().withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.none).build(); listen(serverEncryptionOptions, false); } @Test public void listenPlainConnectionWithBroadcastAddr() throws InterruptedException { - ServerEncryptionOptions serverEncryptionOptions = new ServerEncryptionOptions() - .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.none); + ServerEncryptionOptions serverEncryptionOptions = new Builder().withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.none).build(); listen(serverEncryptionOptions, true); } @Test public void listenRequiredSecureConnection() throws InterruptedException { - ServerEncryptionOptions serverEncryptionOptions = new ServerEncryptionOptions() - .withOptional(false) - .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) - .withLegacySslStoragePort(false); + ServerEncryptionOptions serverEncryptionOptions = new Builder().withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) + .withLegacySslStoragePort(false) + .withOptional(false) + .build(); listen(serverEncryptionOptions, false); } @Test public void listenRequiredSecureConnectionWithBroadcastAddr() throws InterruptedException { - ServerEncryptionOptions serverEncryptionOptions = new ServerEncryptionOptions() - .withOptional(false) - .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) - .withLegacySslStoragePort(false); + ServerEncryptionOptions serverEncryptionOptions = new Builder().withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) + .withLegacySslStoragePort(false) + .withOptional(false) + .build(); listen(serverEncryptionOptions, true); } @Test public void listenRequiredSecureConnectionWithLegacyPort() throws InterruptedException { - ServerEncryptionOptions serverEncryptionOptions = new ServerEncryptionOptions() - .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) - .withOptional(false) - .withLegacySslStoragePort(true); + ServerEncryptionOptions serverEncryptionOptions = new Builder().withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) + .withLegacySslStoragePort(true) + .withOptional(false) + .build(); listen(serverEncryptionOptions, false); } @Test public void listenRequiredSecureConnectionWithBroadcastAddrAndLegacyPort() throws InterruptedException { - ServerEncryptionOptions serverEncryptionOptions = new ServerEncryptionOptions() - .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) - .withOptional(false) - .withLegacySslStoragePort(true); + ServerEncryptionOptions serverEncryptionOptions = new Builder().withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) + .withLegacySslStoragePort(true) + .withOptional(false) + .build(); listen(serverEncryptionOptions, true); } @@ -406,8 +403,7 @@ public class MessagingServiceTest { for (int i = 0; i < 500; i++) // test used to be flaky, so run in a loop to make sure stable (see CASSANDRA-17033) { - ServerEncryptionOptions serverEncryptionOptions = new ServerEncryptionOptions() - .withOptional(true); + ServerEncryptionOptions serverEncryptionOptions = new Builder().withOptional(true).build(); listen(serverEncryptionOptions, false); } } @@ -415,8 +411,7 @@ public class MessagingServiceTest @Test public void listenOptionalSecureConnectionWithBroadcastAddr() throws InterruptedException { - ServerEncryptionOptions serverEncryptionOptions = new ServerEncryptionOptions() - .withOptional(true); + ServerEncryptionOptions serverEncryptionOptions = new Builder().withOptional(true).build(); listen(serverEncryptionOptions, true); } diff --git a/test/unit/org/apache/cassandra/security/DefaultSslContextFactoryTest.java b/test/unit/org/apache/cassandra/security/DefaultSslContextFactoryTest.java index fa3eb7c845..5dc6d7e39b 100644 --- a/test/unit/org/apache/cassandra/security/DefaultSslContextFactoryTest.java +++ b/test/unit/org/apache/cassandra/security/DefaultSslContextFactoryTest.java @@ -33,17 +33,17 @@ import io.netty.handler.ssl.OpenSslContext; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslProvider; import org.apache.cassandra.config.EncryptionOptions; +import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions.Builder; import org.apache.cassandra.distributed.shared.WithProperties; import org.apache.cassandra.transport.TlsTestUtils; import static org.apache.cassandra.config.CassandraRelevantProperties.DISABLE_TCACTIVE_OPENSSL; - -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.NOT_REQUIRED; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.NOT_REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; public class DefaultSslContextFactoryTest { - private Map commonConfig = new HashMap<>(); + private Map commonConfig = new HashMap<>(); @Before public void setup() @@ -54,7 +54,7 @@ public class DefaultSslContextFactoryTest commonConfig.put("cipher_suites", Arrays.asList("TLS_RSA_WITH_AES_128_CBC_SHA")); } - private void addKeystoreOptions(Map config) + private void addKeystoreOptions(Map config) { config.put("keystore", TlsTestUtils.SERVER_KEYSTORE_PATH); config.put("keystore_password", TlsTestUtils.SERVER_KEYSTORE_PASSWORD); @@ -69,14 +69,18 @@ public class DefaultSslContextFactoryTest @Test public void getSslContextOpenSSL() throws IOException { - EncryptionOptions.ServerEncryptionOptions options = new EncryptionOptions.ServerEncryptionOptions().withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PATH) - .withTrustStorePassword(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD) - .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) - .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) - .withOutboundKeystore(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PATH) - .withOutboundKeystorePassword(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PASSWORD) - .withRequireClientAuth(NOT_REQUIRED) - .withCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA"); + EncryptionOptions.ServerEncryptionOptions.Builder builder = new Builder(); + EncryptionOptions.ServerEncryptionOptions options = builder + .withOutboundKeystore(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PATH) + .withOutboundKeystorePassword(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PASSWORD) + .withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PATH) + .withTrustStorePassword(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD) + .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) + .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) + .withRequireClientAuth(NOT_REQUIRED) + .withCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA") + .build(); + SslContext sslContext = SSLFactory.getOrCreateSslContext(options, REQUIRED, ISslContextFactory.SocketType.CLIENT, "test"); Assert.assertNotNull(sslContext); if (OpenSsl.isAvailable()) @@ -88,7 +92,7 @@ public class DefaultSslContextFactoryTest @Test(expected = IOException.class) public void buildTrustManagerFactoryWithInvalidTruststoreFile() throws IOException { - Map config = new HashMap<>(); + Map config = new HashMap<>(); config.putAll(commonConfig); config.put("truststore", "/this/is/probably/not/a/file/on/your/test/machine"); @@ -100,7 +104,7 @@ public class DefaultSslContextFactoryTest @Test(expected = IOException.class) public void buildTrustManagerFactoryWithBadPassword() throws IOException { - Map config = new HashMap<>(); + Map config = new HashMap<>(); config.putAll(commonConfig); config.put("truststore_password", "HomeOfBadPasswords"); @@ -112,7 +116,7 @@ public class DefaultSslContextFactoryTest @Test public void buildTrustManagerFactoryHappyPath() throws IOException { - Map config = new HashMap<>(); + Map config = new HashMap<>(); config.putAll(commonConfig); DefaultSslContextFactory defaultSslContextFactoryImpl = new DefaultSslContextFactory(config); @@ -124,7 +128,7 @@ public class DefaultSslContextFactoryTest @Test(expected = IOException.class) public void buildKeyManagerFactoryWithInvalidKeystoreFile() throws IOException { - Map config = new HashMap<>(); + Map config = new HashMap<>(); config.putAll(commonConfig); config.put("keystore", "/this/is/probably/not/a/file/on/your/test/machine"); config.put("keystore_password", "ThisWontMatter"); @@ -137,7 +141,7 @@ public class DefaultSslContextFactoryTest @Test(expected = IOException.class) public void buildKeyManagerFactoryWithBadPassword() throws IOException { - Map config = new HashMap<>(); + Map config = new HashMap<>(); config.putAll(commonConfig); addKeystoreOptions(config); config.put("keystore_password", "HomeOfBadPasswords"); @@ -149,7 +153,7 @@ public class DefaultSslContextFactoryTest @Test public void buildKeyManagerFactoryHappyPath() throws IOException { - Map config = new HashMap<>(); + Map config = new HashMap<>(); config.putAll(commonConfig); DefaultSslContextFactory defaultSslContextFactoryImpl = new DefaultSslContextFactory(config); @@ -222,12 +226,13 @@ public class DefaultSslContextFactoryTest } @Test - public void testDisableOpenSslForInJvmDtests() { + public void testDisableOpenSslForInJvmDtests() + { // The configuration name below is hard-coded intentionally to make sure we don't break the contract without // changing the documentation appropriately try (WithProperties properties = new WithProperties().set(DISABLE_TCACTIVE_OPENSSL, true)) { - Map config = new HashMap<>(); + Map config = new HashMap<>(); config.putAll(commonConfig); DefaultSslContextFactory defaultSslContextFactoryImpl = new DefaultSslContextFactory(config); diff --git a/test/unit/org/apache/cassandra/security/DummySslContextFactoryImpl.java b/test/unit/org/apache/cassandra/security/DummySslContextFactoryImpl.java index ca4f4e86f0..12649cfb0c 100644 --- a/test/unit/org/apache/cassandra/security/DummySslContextFactoryImpl.java +++ b/test/unit/org/apache/cassandra/security/DummySslContextFactoryImpl.java @@ -44,7 +44,7 @@ public class DummySslContextFactoryImpl implements ISslContextFactory } @Override - public SSLContext createJSSESslContext(EncryptionOptions.ClientAuth clientAuth) throws SSLException + public SSLContext createJSSESslContext(EncryptionOptions.ClientEncryptionOptions.ClientAuth clientAuth) throws SSLException { return null; } @@ -56,7 +56,7 @@ public class DummySslContextFactoryImpl implements ISslContextFactory } @Override - public SslContext createNettySslContext(EncryptionOptions.ClientAuth clientAuth, SocketType socketType, + public SslContext createNettySslContext(EncryptionOptions.ClientEncryptionOptions.ClientAuth clientAuth, SocketType socketType, CipherSuiteFilter cipherFilter) throws SSLException { return null; diff --git a/test/unit/org/apache/cassandra/security/FileBasedSslContextFactoryTest.java b/test/unit/org/apache/cassandra/security/FileBasedSslContextFactoryTest.java index d6d936ba0e..cc6c05af5d 100644 --- a/test/unit/org/apache/cassandra/security/FileBasedSslContextFactoryTest.java +++ b/test/unit/org/apache/cassandra/security/FileBasedSslContextFactoryTest.java @@ -36,11 +36,12 @@ import org.apache.cassandra.transport.TlsTestUtils; import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_CONFIG; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.NOT_REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.NOT_REQUIRED; public class FileBasedSslContextFactoryTest { private EncryptionOptions.ServerEncryptionOptions encryptionOptions; + private EncryptionOptions.ServerEncryptionOptions.Builder encryptionOptionsBuilder; static WithProperties properties; @@ -60,7 +61,10 @@ public class FileBasedSslContextFactoryTest @Before public void setup() { - encryptionOptions = new EncryptionOptions.ServerEncryptionOptions() + encryptionOptionsBuilder = new EncryptionOptions.ServerEncryptionOptions.Builder(); + encryptionOptions = encryptionOptionsBuilder + .withOutboundKeystore(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PATH) + .withOutboundKeystorePassword(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PASSWORD) .withSslContextFactory(new ParameterizedClass(TestFileBasedSSLContextFactory.class.getName(), new HashMap<>())) .withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PATH) @@ -69,8 +73,7 @@ public class FileBasedSslContextFactoryTest .withCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA") .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) - .withOutboundKeystore(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PATH) - .withOutboundKeystorePassword(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PASSWORD); + .build(); } @Test @@ -95,11 +98,12 @@ public class FileBasedSslContextFactoryTest @Test public void testEmptyKeystorePasswords() throws SSLException { - EncryptionOptions.ServerEncryptionOptions localEncryptionOptions = encryptionOptions + EncryptionOptions.ServerEncryptionOptions localEncryptionOptions = encryptionOptionsBuilder + .withOutboundKeystorePassword("") + .withOutboundKeystore("test/conf/cassandra_ssl_test_nopassword.keystore") .withKeyStorePassword("") .withKeyStore("test/conf/cassandra_ssl_test_nopassword.keystore") - .withOutboundKeystorePassword("") - .withOutboundKeystore("test/conf/cassandra_ssl_test_nopassword.keystore"); + .build(); Assert.assertEquals("org.apache.cassandra.security.FileBasedSslContextFactoryTest$TestFileBasedSSLContextFactory", localEncryptionOptions.ssl_context_factory.class_name); @@ -118,13 +122,14 @@ public class FileBasedSslContextFactoryTest { // Here we only override password configuration and specify password_file configuration since keystore paths // are already loaded in the `encryptionOptions` - EncryptionOptions.ServerEncryptionOptions localEncryptionOptions = encryptionOptions - .withKeyStorePassword(null) - .withKeyStorePasswordFile(TlsTestUtils.SERVER_KEYSTORE_PASSWORD_FILE) + EncryptionOptions.ServerEncryptionOptions localEncryptionOptions = encryptionOptionsBuilder .withOutboundKeystorePassword(null) .withOutboundKeystorePasswordFile(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PASSWORD_FILE) + .withKeyStorePassword(null) + .withKeyStorePasswordFile(TlsTestUtils.SERVER_KEYSTORE_PASSWORD_FILE) .withTrustStorePassword(null) - .withTrustStorePasswordFile(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD_FILE); + .withTrustStorePasswordFile(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD_FILE) + .build(); Assert.assertEquals("org.apache.cassandra.security.FileBasedSslContextFactoryTest$TestFileBasedSSLContextFactory", localEncryptionOptions.ssl_context_factory.class_name); @@ -144,13 +149,14 @@ public class FileBasedSslContextFactoryTest { // Here we only override password configuration and specify password_file configuration since keystore paths // are already loaded in the `encryptionOptions` - encryptionOptions - .withKeyStorePassword(null) - .withKeyStorePasswordFile("/path/to/non-existance-password-file") + encryptionOptionsBuilder .withOutboundKeystorePassword(null) .withOutboundKeystorePasswordFile("/path/to/non-existance-password-file") + .withKeyStorePassword(null) + .withKeyStorePasswordFile("/path/to/non-existance-password-file") .withTrustStorePassword(null) - .withTrustStorePasswordFile("/path/to/non-existance-password-file"); + .withTrustStorePasswordFile("/path/to/non-existance-password-file") + .build(); } /** @@ -159,7 +165,9 @@ public class FileBasedSslContextFactoryTest @Test(expected = IllegalArgumentException.class) public void testNullKeystorePasswordDisallowed() throws SSLException { - EncryptionOptions.ServerEncryptionOptions localEncryptionOptions = encryptionOptions.withKeyStorePassword(null); + EncryptionOptions.ServerEncryptionOptions localEncryptionOptions = encryptionOptionsBuilder + .withKeyStorePassword(null) + .build(); Assert.assertEquals("org.apache.cassandra.security.FileBasedSslContextFactoryTest$TestFileBasedSSLContextFactory", localEncryptionOptions.ssl_context_factory.class_name); @@ -187,7 +195,9 @@ public class FileBasedSslContextFactoryTest @Test public void testOnlyEmptyOutboundKeystorePassword() throws SSLException { - EncryptionOptions.ServerEncryptionOptions localEncryptionOptions = encryptionOptions.withOutboundKeystorePassword(null); + EncryptionOptions.ServerEncryptionOptions localEncryptionOptions = encryptionOptionsBuilder + .withOutboundKeystorePassword(null) + .build(); Assert.assertEquals("org.apache.cassandra.security.FileBasedSslContextFactoryTest$TestFileBasedSSLContextFactory", localEncryptionOptions.ssl_context_factory.class_name); @@ -203,7 +213,9 @@ public class FileBasedSslContextFactoryTest @Test public void testEmptyTruststorePassword() throws SSLException { - EncryptionOptions.ServerEncryptionOptions localEncryptionOptions = encryptionOptions.withTrustStorePassword(null); + EncryptionOptions.ServerEncryptionOptions localEncryptionOptions = encryptionOptionsBuilder + .withTrustStorePassword(null) + .build(); Assert.assertEquals("org.apache.cassandra.security.FileBasedSslContextFactoryTest$TestFileBasedSSLContextFactory", localEncryptionOptions.ssl_context_factory.class_name); Assert.assertNotNull("keystore_password must not be null", localEncryptionOptions.keystore_password); diff --git a/test/unit/org/apache/cassandra/security/PEMBasedSslContextFactoryTest.java b/test/unit/org/apache/cassandra/security/PEMBasedSslContextFactoryTest.java index 9781e9d08a..18d323286d 100644 --- a/test/unit/org/apache/cassandra/security/PEMBasedSslContextFactoryTest.java +++ b/test/unit/org/apache/cassandra/security/PEMBasedSslContextFactoryTest.java @@ -39,8 +39,8 @@ import org.apache.cassandra.distributed.shared.WithProperties; import org.apache.cassandra.transport.TlsTestUtils; import static org.apache.cassandra.config.CassandraRelevantProperties.DISABLE_TCACTIVE_OPENSSL; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.NOT_REQUIRED; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.NOT_REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; import static org.apache.cassandra.security.PEMBasedSslContextFactory.ConfigKey.ENCODED_CERTIFICATES; import static org.apache.cassandra.security.PEMBasedSslContextFactory.ConfigKey.ENCODED_KEY; import static org.apache.cassandra.security.PEMBasedSslContextFactory.ConfigKey.KEY_PASSWORD; @@ -215,12 +215,14 @@ public class PEMBasedSslContextFactoryTest { ParameterizedClass sslContextFactory = new ParameterizedClass(PEMBasedSslContextFactory.class.getSimpleName() , new HashMap<>()); - EncryptionOptions options = new EncryptionOptions().withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PEM_PATH) - .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH_PEM) - .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) - .withRequireClientAuth(NOT_REQUIRED) - .withCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA") - .withSslContextFactory(sslContextFactory); + EncryptionOptions.ClientEncryptionOptions options = new EncryptionOptions.ClientEncryptionOptions.Builder() + .withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PEM_PATH) + .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH_PEM) + .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) + .withRequireClientAuth(NOT_REQUIRED) + .withCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA") + .withSslContextFactory(sslContextFactory) + .build(); SslContext sslContext = SSLFactory.getOrCreateSslContext(options, REQUIRED, ISslContextFactory.SocketType.SERVER, "test"); Assert.assertNotNull(sslContext); if (OpenSsl.isAvailable()) @@ -234,14 +236,16 @@ public class PEMBasedSslContextFactoryTest { ParameterizedClass sslContextFactory = new ParameterizedClass(PEMBasedSslContextFactory.class.getSimpleName() , new HashMap<>()); - EncryptionOptions.ServerEncryptionOptions options = new EncryptionOptions.ServerEncryptionOptions().withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PEM_PATH) - .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH_PEM) - .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) - .withOutboundKeystore(TlsTestUtils.SERVER_KEYSTORE_PATH_PEM) - .withOutboundKeystorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) - .withRequireClientAuth(NOT_REQUIRED) - .withCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA") - .withSslContextFactory(sslContextFactory); + EncryptionOptions.ServerEncryptionOptions options = + new EncryptionOptions.ServerEncryptionOptions.Builder().withOutboundKeystore(TlsTestUtils.SERVER_KEYSTORE_PATH_PEM) + .withOutboundKeystorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) + .withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PEM_PATH) + .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH_PEM) + .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) + .withRequireClientAuth(NOT_REQUIRED) + .withCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA") + .withSslContextFactory(sslContextFactory) + .build(); SslContext sslContext = SSLFactory.getOrCreateSslContext(options, REQUIRED, ISslContextFactory.SocketType.CLIENT, "test"); Assert.assertNotNull(sslContext); if (OpenSsl.isAvailable()) diff --git a/test/unit/org/apache/cassandra/security/SSLFactoryTest.java b/test/unit/org/apache/cassandra/security/SSLFactoryTest.java index ba46588686..7ac9517337 100644 --- a/test/unit/org/apache/cassandra/security/SSLFactoryTest.java +++ b/test/unit/org/apache/cassandra/security/SSLFactoryTest.java @@ -1,21 +1,21 @@ /* -* Licensed to the Apache Software Foundation (ASF) under one -* or more contributor license agreements. See the NOTICE file -* distributed with this work for additional information -* regarding copyright ownership. The ASF licenses this file -* to you under the Apache License, Version 2.0 (the -* "License"); you may not use this file except in compliance -* with the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, -* software distributed under the License is distributed on an -* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -* KIND, either express or implied. See the License for the -* specific language governing permissions and limitations -* under the License. -*/ + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package org.apache.cassandra.security; import java.io.FileInputStream; @@ -46,18 +46,20 @@ import io.netty.handler.ssl.util.SelfSignedCertificate; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.EncryptionOptions; import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions; +import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions.Builder; import org.apache.cassandra.config.ParameterizedClass; import org.apache.cassandra.io.util.File; import org.apache.cassandra.transport.TlsTestUtils; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.NOT_REQUIRED; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.NOT_REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; public class SSLFactoryTest { static final SelfSignedCertificate ssc; + static { DatabaseDescriptor.daemonInitialization(); @@ -77,33 +79,41 @@ public class SSLFactoryTest public void setup() { SSLFactory.clearSslContextCache(); - encryptionOptions = new ServerEncryptionOptions() - .withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PATH) - .withTrustStorePassword(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD) - .withRequireClientAuth(NOT_REQUIRED) - .withCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA") - .withSslContextFactory(new ParameterizedClass(TestFileBasedSSLContextFactory.class.getName(), - new HashMap<>())); + encryptionOptions = new Builder().withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PATH) + .withTrustStorePassword(TlsTestUtils.SERVER_TRUSTSTORE_PASSWORD) + .withRequireClientAuth(NOT_REQUIRED) + .withCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA") + .withSslContextFactory(new ParameterizedClass(TestFileBasedSSLContextFactory.class.getName(), + new HashMap<>())) + .build(); } - private ServerEncryptionOptions addKeystoreOptions(ServerEncryptionOptions options) + private Builder addKeystoreOptions(ServerEncryptionOptions options) { - return options.withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH) - .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) - .withOutboundKeystore(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PATH) - .withOutboundKeystorePassword(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PASSWORD); + EncryptionOptions.ServerEncryptionOptions.Builder builder = new EncryptionOptions.ServerEncryptionOptions.Builder(options); + + builder.withOutboundKeystorePassword(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PASSWORD) + .withOutboundKeystore(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PATH) + .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) + .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH); + + return builder; } - private ServerEncryptionOptions addPEMKeystoreOptions(ServerEncryptionOptions options) + private Builder addPEMKeystoreOptions(ServerEncryptionOptions options) { ParameterizedClass sslContextFactoryClass = new ParameterizedClass("org.apache.cassandra.security.PEMBasedSslContextFactory", new HashMap<>()); - return options.withSslContextFactory(sslContextFactoryClass) - .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH_PEM) - .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) - .withOutboundKeystore(TlsTestUtils.SERVER_KEYSTORE_PATH_PEM) - .withOutboundKeystorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) - .withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PEM_PATH); + EncryptionOptions.ServerEncryptionOptions.Builder builder = new EncryptionOptions.ServerEncryptionOptions.Builder(options); + + builder.withOutboundKeystore(TlsTestUtils.SERVER_KEYSTORE_PATH_PEM) + .withOutboundKeystorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) + .withSslContextFactory(sslContextFactoryClass) + .withKeyStore(TlsTestUtils.SERVER_KEYSTORE_PATH_PEM) + .withKeyStorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD) + .withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PEM_PATH); + + return builder; } @Test @@ -111,9 +121,13 @@ public class SSLFactoryTest { try { - ServerEncryptionOptions options = addKeystoreOptions(encryptionOptions) - .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all); - ServerEncryptionOptions legacyOptions = options.withOptional(false).withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all); + Builder optionsBuilder = addKeystoreOptions(encryptionOptions) + .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all); + ServerEncryptionOptions options = optionsBuilder.build(); + ServerEncryptionOptions legacyOptions = optionsBuilder + .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) + .withOptional(false) + .build(); options.sslContextFactoryInstance.initHotReloading(); legacyOptions.sslContextFactoryInstance.initHotReloading(); @@ -146,8 +160,9 @@ public class SSLFactoryTest public void testServerSocketShouldUseKeystore() throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException, NoSuchFieldException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException { ServerEncryptionOptions options = addKeystoreOptions(encryptionOptions) - .withOutboundKeystore("dummyKeystore") - .withOutboundKeystorePassword("dummyPassword"); + .withOutboundKeystore("dummyKeystore") + .withOutboundKeystorePassword("dummyPassword") + .build(); // Server socket type should create a keystore with keystore & keystore password final OpenSslServerContext context = (OpenSslServerContext) SSLFactory.createNettySslContext(options, REQUIRED, ISslContextFactory.SocketType.SERVER); @@ -163,8 +178,9 @@ public class SSLFactoryTest public void testClientSocketShouldUseOutboundKeystore() throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException, NoSuchFieldException, ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException { ServerEncryptionOptions options = addKeystoreOptions(encryptionOptions) - .withKeyStore("dummyKeystore") - .withKeyStorePassword("dummyPassword"); + .withKeyStore("dummyKeystore") + .withKeyStorePassword("dummyPassword") + .build(); // Client socket type should create a keystore with outbound Keystore & outbound password final OpenSslClientContext context = (OpenSslClientContext) SSLFactory.createNettySslContext(options, REQUIRED, ISslContextFactory.SocketType.CLIENT); @@ -181,10 +197,14 @@ public class SSLFactoryTest { try { - ServerEncryptionOptions options = addPEMKeystoreOptions(encryptionOptions) - .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.dc); + Builder optionsBuilder = addPEMKeystoreOptions(encryptionOptions); + ServerEncryptionOptions options = optionsBuilder.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.dc) + .build(); // emulate InboundSockets and share the cert but with different options, no extra hot reloading init - ServerEncryptionOptions legacyOptions = options.withOptional(false).withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all); + ServerEncryptionOptions legacyOptions = optionsBuilder + .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) + .withOptional(false) + .build(); options.sslContextFactoryInstance.initHotReloading(); legacyOptions.sslContextFactoryInstance.initHotReloading(); @@ -217,8 +237,9 @@ public class SSLFactoryTest public void testSslFactorySslInit_BadPassword_ThrowsException() throws IOException { ServerEncryptionOptions options = addKeystoreOptions(encryptionOptions) - .withKeyStorePassword("bad password") - .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all); + .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) + .withKeyStorePassword("bad password") + .build(); SSLFactory.validateSslContext("testSslFactorySslInit_BadPassword_ThrowsException", options, NOT_REQUIRED, true); } @@ -228,13 +249,17 @@ public class SSLFactoryTest { try { - ServerEncryptionOptions options = addKeystoreOptions(encryptionOptions); + Builder optionsBuilder = addKeystoreOptions(encryptionOptions); + ServerEncryptionOptions options = optionsBuilder.build(); // emulate InboundSockets and share the cert but with different options, no extra hot reloading init - ServerEncryptionOptions legacyOptions = options.withOptional(false).withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all); + ServerEncryptionOptions legacyOptions = optionsBuilder + .withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all) + .withOptional(false) + .build(); File testKeystoreFile = new File(options.keystore + ".test"); FileUtils.copyFile(new File(options.keystore).toJavaIOFile(), testKeystoreFile.toJavaIOFile()); - options = options.withKeyStore(testKeystoreFile.path()); + options = new Builder(options).withKeyStore(testKeystoreFile.path()).build(); SSLFactory.initHotReloading(options, options, true); // deliberately not initializing with legacyOptions to match InboundSockets.addBindings @@ -261,11 +286,12 @@ public class SSLFactoryTest { try { - ServerEncryptionOptions options = addKeystoreOptions(encryptionOptions); + Builder optionsBuilder = addKeystoreOptions(encryptionOptions); + ServerEncryptionOptions options = optionsBuilder.build(); File testKeystoreFile = new File(options.keystore + ".test"); FileUtils.copyFile(new File(options.keystore).toJavaIOFile(), testKeystoreFile.toJavaIOFile()); - options = options.withKeyStore(testKeystoreFile.path()); + options = optionsBuilder.withKeyStore(testKeystoreFile.path()).build(); SSLFactory.initHotReloading(options, options, true); @@ -294,8 +320,10 @@ public class SSLFactoryTest @Test public void getSslContext_ParamChanges() throws IOException { - ServerEncryptionOptions options = addKeystoreOptions(encryptionOptions) - .withCipherSuites("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"); + Builder optionsBuilder = addKeystoreOptions(encryptionOptions); + ServerEncryptionOptions options = optionsBuilder + .withCipherSuites("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") + .build(); SslContext ctx1 = SSLFactory.getOrCreateSslContext(options, REQUIRED, ISslContextFactory.SocketType.SERVER, "test"); @@ -303,7 +331,7 @@ public class SSLFactoryTest Assert.assertTrue(ctx1.isServer()); Assert.assertEquals(ctx1.cipherSuites(), options.cipher_suites); - options = options.withCipherSuites("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"); + options = optionsBuilder.withCipherSuites("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256").build(); SslContext ctx2 = SSLFactory.getOrCreateSslContext(options, REQUIRED, ISslContextFactory.SocketType.CLIENT, "test"); @@ -313,30 +341,33 @@ public class SSLFactoryTest } @Test - public void testCacheKeyEqualityForCustomSslContextFactory() { + public void testCacheKeyEqualityForCustomSslContextFactory() + { - Map parameters1 = new HashMap<>(); + Map parameters1 = new HashMap<>(); parameters1.put("key1", "value1"); parameters1.put("key2", "value2"); - EncryptionOptions encryptionOptions1 = - new EncryptionOptions() + EncryptionOptions.ClientEncryptionOptions encryptionOptions1 = + new EncryptionOptions.ClientEncryptionOptions.Builder() .withSslContextFactory(new ParameterizedClass(DummySslContextFactoryImpl.class.getName(), parameters1)) .withProtocol("TLSv1.1") .withRequireClientAuth(REQUIRED) - .withRequireEndpointVerification(false); + .withRequireEndpointVerification(false) + .build(); SSLFactory.CacheKey cacheKey1 = new SSLFactory.CacheKey(encryptionOptions1, ISslContextFactory.SocketType.SERVER, "test" ); - Map parameters2 = new HashMap<>(); + Map parameters2 = new HashMap<>(); parameters2.put("key1", "value1"); parameters2.put("key2", "value2"); - EncryptionOptions encryptionOptions2 = - new EncryptionOptions() + EncryptionOptions.ClientEncryptionOptions encryptionOptions2 = + new EncryptionOptions.ClientEncryptionOptions.Builder() .withSslContextFactory(new ParameterizedClass(DummySslContextFactoryImpl.class.getName(), parameters2)) .withProtocol("TLSv1.1") .withRequireClientAuth(REQUIRED) - .withRequireEndpointVerification(false); + .withRequireEndpointVerification(false) + .build(); SSLFactory.CacheKey cacheKey2 = new SSLFactory.CacheKey(encryptionOptions2, ISslContextFactory.SocketType.SERVER, "test" ); @@ -345,26 +376,29 @@ public class SSLFactoryTest } @Test - public void testCacheKeyInequalityForCustomSslContextFactory() { + public void testCacheKeyInequalityForCustomSslContextFactory() + { - Map parameters1 = new HashMap<>(); + Map parameters1 = new HashMap<>(); parameters1.put("key1", "value11"); parameters1.put("key2", "value12"); - EncryptionOptions encryptionOptions1 = - new EncryptionOptions() + EncryptionOptions.ClientEncryptionOptions encryptionOptions1 = + new EncryptionOptions.ClientEncryptionOptions.Builder() .withSslContextFactory(new ParameterizedClass(DummySslContextFactoryImpl.class.getName(), parameters1)) - .withProtocol("TLSv1.1"); + .withProtocol("TLSv1.1") + .build(); SSLFactory.CacheKey cacheKey1 = new SSLFactory.CacheKey(encryptionOptions1, ISslContextFactory.SocketType.SERVER, "test" ); - Map parameters2 = new HashMap<>(); + Map parameters2 = new HashMap<>(); parameters2.put("key1", "value21"); parameters2.put("key2", "value22"); - EncryptionOptions encryptionOptions2 = - new EncryptionOptions() + EncryptionOptions.ClientEncryptionOptions encryptionOptions2 = + new EncryptionOptions.ClientEncryptionOptions.Builder() .withSslContextFactory(new ParameterizedClass(DummySslContextFactoryImpl.class.getName(), parameters2)) - .withProtocol("TLSv1.1"); + .withProtocol("TLSv1.1") + .build(); SSLFactory.CacheKey cacheKey2 = new SSLFactory.CacheKey(encryptionOptions2, ISslContextFactory.SocketType.SERVER, "test" ); @@ -372,7 +406,8 @@ public class SSLFactoryTest Assert.assertNotEquals(cacheKey1, cacheKey2); } - public static class TestFileBasedSSLContextFactory extends FileBasedSslContextFactory { + public static class TestFileBasedSSLContextFactory extends FileBasedSslContextFactory + { public TestFileBasedSSLContextFactory(Map parameters) { super(parameters); diff --git a/test/unit/org/apache/cassandra/service/ClientWarningsTest.java b/test/unit/org/apache/cassandra/service/ClientWarningsTest.java index cf6d6ed400..fb9f594801 100644 --- a/test/unit/org/apache/cassandra/service/ClientWarningsTest.java +++ b/test/unit/org/apache/cassandra/service/ClientWarningsTest.java @@ -70,7 +70,7 @@ public class ClientWarningsTest extends CQLTester createTable("CREATE TABLE %s (pk int PRIMARY KEY, v text)"); // v4 and higher - try (SimpleClient client = new SimpleClient(nativeAddr.getHostAddress(), nativePort, version, true, new EncryptionOptions())) + try (SimpleClient client = new SimpleClient(nativeAddr.getHostAddress(), nativePort, version, true, new EncryptionOptions.ClientEncryptionOptions())) { client.connect(false); @@ -90,7 +90,7 @@ public class ClientWarningsTest extends CQLTester createTable("CREATE TABLE %s (pk int PRIMARY KEY, v text)"); // v4 and higher - try (SimpleClient client = new SimpleClient(nativeAddr.getHostAddress(), nativePort, version, true, new EncryptionOptions())) + try (SimpleClient client = new SimpleClient(nativeAddr.getHostAddress(), nativePort, version, true, new EncryptionOptions.ClientEncryptionOptions())) { client.connect(false); @@ -112,7 +112,7 @@ public class ClientWarningsTest extends CQLTester final int iterations = 10000; createTable("CREATE TABLE %s (pk int, ck int, v int, PRIMARY KEY (pk, ck))"); - try (SimpleClient client = new SimpleClient(nativeAddr.getHostAddress(), nativePort, version, true, new EncryptionOptions())) + try (SimpleClient client = new SimpleClient(nativeAddr.getHostAddress(), nativePort, version, true, new EncryptionOptions.ClientEncryptionOptions())) { client.connect(false); diff --git a/test/unit/org/apache/cassandra/service/NativeTransportServiceTest.java b/test/unit/org/apache/cassandra/service/NativeTransportServiceTest.java index 645d5b8f8b..9602899400 100644 --- a/test/unit/org/apache/cassandra/service/NativeTransportServiceTest.java +++ b/test/unit/org/apache/cassandra/service/NativeTransportServiceTest.java @@ -36,7 +36,7 @@ import static org.junit.Assert.assertTrue; public class NativeTransportServiceTest { - static EncryptionOptions defaultOptions; + static EncryptionOptions.ClientEncryptionOptions defaultOptions; @BeforeClass public static void setupDD() @@ -48,7 +48,7 @@ public class NativeTransportServiceTest @After public void resetConfig() { - DatabaseDescriptor.updateNativeProtocolEncryptionOptions(update -> new EncryptionOptions(defaultOptions).applyConfig()); + DatabaseDescriptor.updateNativeProtocolEncryptionOptions(update -> new EncryptionOptions.ClientEncryptionOptions.Builder(defaultOptions).build()); } @Test @@ -127,8 +127,11 @@ public class NativeTransportServiceTest public void testSSLOnly() { // default ssl settings: client encryption enabled and default native transport port used for ssl only - DatabaseDescriptor.updateNativeProtocolEncryptionOptions(options -> options.withEnabled(true) - .withOptional(false)); + DatabaseDescriptor.updateNativeProtocolEncryptionOptions(options -> + new EncryptionOptions.ClientEncryptionOptions.Builder(options) + .withEnabled(true) + .withOptional(false) + .build()); withService((NativeTransportService service) -> { @@ -144,8 +147,11 @@ public class NativeTransportServiceTest public void testSSLOptional() { // default ssl settings: client encryption enabled and default native transport port used for optional ssl - DatabaseDescriptor.updateNativeProtocolEncryptionOptions(options -> options.withEnabled(true) - .withOptional(true)); + DatabaseDescriptor.updateNativeProtocolEncryptionOptions(options -> + new EncryptionOptions.ClientEncryptionOptions.Builder(options) + .withEnabled(true) + .withOptional(true) + .build()); withService((NativeTransportService service) -> { diff --git a/test/unit/org/apache/cassandra/service/ProtocolBetaVersionTest.java b/test/unit/org/apache/cassandra/service/ProtocolBetaVersionTest.java index a5b32bfa1f..22324f178b 100644 --- a/test/unit/org/apache/cassandra/service/ProtocolBetaVersionTest.java +++ b/test/unit/org/apache/cassandra/service/ProtocolBetaVersionTest.java @@ -68,7 +68,7 @@ public class ProtocolBetaVersionTest extends CQLTester createTable("CREATE TABLE %s (pk int PRIMARY KEY, v int)"); assertTrue(betaVersion.isBeta()); // change to another beta version or remove test if no beta version - try (SimpleClient client = new SimpleClient(nativeAddr.getHostAddress(), nativePort, betaVersion, true, new EncryptionOptions())) + try (SimpleClient client = new SimpleClient(nativeAddr.getHostAddress(), nativePort, betaVersion, true, new EncryptionOptions.ClientEncryptionOptions())) { client.connect(false); for (int i = 0; i < 10; i++) @@ -103,7 +103,7 @@ public class ProtocolBetaVersionTest extends CQLTester } assertTrue(betaVersion.isBeta()); // change to another beta version or remove test if no beta version - try (SimpleClient client = new SimpleClient(nativeAddr.getHostAddress(), nativePort, betaVersion, false, new EncryptionOptions())) + try (SimpleClient client = new SimpleClient(nativeAddr.getHostAddress(), nativePort, betaVersion, false, new EncryptionOptions.ClientEncryptionOptions())) { client.connect(false); fail("Exception should have been thrown"); diff --git a/test/unit/org/apache/cassandra/tools/LoaderOptionsTest.java b/test/unit/org/apache/cassandra/tools/LoaderOptionsTest.java index 4fc2325677..b203af1b43 100644 --- a/test/unit/org/apache/cassandra/tools/LoaderOptionsTest.java +++ b/test/unit/org/apache/cassandra/tools/LoaderOptionsTest.java @@ -28,6 +28,7 @@ import com.google.common.net.HostAndPort; import org.junit.Test; import org.apache.cassandra.io.util.File; +import org.apache.cassandra.transport.TlsTestUtils; import static org.apache.cassandra.tools.OfflineToolUtils.sstableDirName; import static org.junit.Assert.assertEquals; @@ -85,6 +86,35 @@ public class LoaderOptionsTest assertEquals("test.jks", options.clientEncOptions.keystore); } + /** + * Tests for client_encryption_options override from the command line. + */ + @Test + public void testEncryptionSettingsOverride() throws Exception + { + // Default Cassandra config + File config = new File(Paths.get(".", "test", "conf", "cassandra-mtls.yaml").normalize()); + String[] args = { "-d", "127.9.9.1", "-f", config.absolutePath(), + "-ts", "test.jks", "-tspw", "truststorePass1", + "-ks", "test.jks", "-kspw", "testdata1", + "--ssl-ciphers", "TLS_RSA_WITH_AES_256_CBC_SHA", + "--ssl-alg", "SunX509", "--store-type", "JKS", "--ssl-protocol", "TLS", + sstableDirName("legacy_sstables", "legacy_ma_simple") }; + LoaderOptions options = LoaderOptions.builder().parseArgs(args).build(); + // Below two lines validating server encryption options is to verify that we are loading config from the yaml + assertEquals(TlsTestUtils.SERVER_KEYSTORE_PATH, options.serverEncOptions.keystore); + assertEquals(TlsTestUtils.SERVER_KEYSTORE_PASSWORD, options.serverEncOptions.keystore_password); + // Below asserts validate the overrides for the client encryption options from the command line + // Since the values are provided by (and local to) this test, they are hardcoded + assertEquals("JKS", options.clientEncOptions.store_type); + assertEquals("test.jks", options.clientEncOptions.truststore); + assertEquals("truststorePass1", options.clientEncOptions.truststore_password); + assertEquals("test.jks", options.clientEncOptions.keystore); + assertEquals("testdata1", options.clientEncOptions.keystore_password); + assertEquals("TLS_RSA_WITH_AES_256_CBC_SHA", options.clientEncOptions.cipherSuitesArray()[0]); + assertEquals("SunX509", options.clientEncOptions.algorithm); + } + @Test public void testThrottleDefaultSettings() { diff --git a/test/unit/org/apache/cassandra/transport/EarlyAuthenticationTest.java b/test/unit/org/apache/cassandra/transport/EarlyAuthenticationTest.java index ed98140b9b..a581086c76 100644 --- a/test/unit/org/apache/cassandra/transport/EarlyAuthenticationTest.java +++ b/test/unit/org/apache/cassandra/transport/EarlyAuthenticationTest.java @@ -84,23 +84,23 @@ public class EarlyAuthenticationTest extends CQLTester }); } - private EncryptionOptions clientEncryptionOptions(boolean presentClientCertificate) + private EncryptionOptions.ClientEncryptionOptions clientEncryptionOptions(boolean presentClientCertificate) { - EncryptionOptions encryptionOptions = new EncryptionOptions() - .withEnabled(true) - .withRequireClientAuth(EncryptionOptions.ClientAuth.OPTIONAL) - .withTrustStore(TlsTestUtils.CLIENT_TRUSTSTORE_PATH) - .withTrustStorePassword(TlsTestUtils.CLIENT_TRUSTSTORE_PASSWORD) - .withSslContextFactory(new ParameterizedClass(SimpleClientSslContextFactory.class.getName())); + EncryptionOptions.ClientEncryptionOptions.Builder builder = new EncryptionOptions.ClientEncryptionOptions.Builder(); + builder.withEnabled(true) + .withRequireClientAuth(EncryptionOptions.ClientEncryptionOptions.ClientAuth.OPTIONAL) + .withTrustStore(TlsTestUtils.CLIENT_TRUSTSTORE_PATH) + .withTrustStorePassword(TlsTestUtils.CLIENT_TRUSTSTORE_PASSWORD) + .withSslContextFactory(new ParameterizedClass(SimpleClientSslContextFactory.class.getName())); if (presentClientCertificate) { - encryptionOptions = encryptionOptions.withKeyStore(TlsTestUtils.CLIENT_SPIFFE_KEYSTORE_PATH) - .withStoreType("JKS") - .withKeyStorePassword(TlsTestUtils.CLIENT_SPIFFE_KEYSTORE_PASSWORD); + builder.withKeyStore(TlsTestUtils.CLIENT_SPIFFE_KEYSTORE_PATH) + .withStoreType("JKS") + .withKeyStorePassword(TlsTestUtils.CLIENT_SPIFFE_KEYSTORE_PASSWORD); } - return new EncryptionOptions(encryptionOptions); + return new EncryptionOptions.ClientEncryptionOptions(builder.build()); } @Test @@ -180,6 +180,5 @@ public class EarlyAuthenticationTest extends CQLTester } }; } - } diff --git a/test/unit/org/apache/cassandra/transport/MessagePayloadTest.java b/test/unit/org/apache/cassandra/transport/MessagePayloadTest.java index a50174bd87..42c6cbd021 100644 --- a/test/unit/org/apache/cassandra/transport/MessagePayloadTest.java +++ b/test/unit/org/apache/cassandra/transport/MessagePayloadTest.java @@ -127,7 +127,7 @@ public class MessagePayloadTest extends CQLTester nativePort, ProtocolVersion.V5, true, - new EncryptionOptions()); + new EncryptionOptions.ClientEncryptionOptions()); try { client.connect(false); diff --git a/test/unit/org/apache/cassandra/transport/SimpleClientSslContextFactory.java b/test/unit/org/apache/cassandra/transport/SimpleClientSslContextFactory.java index 1a6871716a..468c9cbc17 100644 --- a/test/unit/org/apache/cassandra/transport/SimpleClientSslContextFactory.java +++ b/test/unit/org/apache/cassandra/transport/SimpleClientSslContextFactory.java @@ -30,12 +30,12 @@ import io.netty.handler.ssl.SslContextBuilder; import org.apache.cassandra.config.EncryptionOptions; import org.apache.cassandra.security.FileBasedSslContextFactory; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.NOT_REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.NOT_REQUIRED; /** * A custom implementation of {@link FileBasedSslContextFactory} to be used by tests utilizing {@link SimpleClient}. *

- * Provides a subtly different implementation of {@link #createNettySslContext(EncryptionOptions.ClientAuth, SocketType, CipherSuiteFilter)} + * Provides a subtly different implementation of {@link #createNettySslContext(EncryptionOptions.ClientEncryptionOptions.ClientAuth, SocketType, CipherSuiteFilter)} * that only configures an {@link SslContext} for clients and most importantly only configures a key manager if an * outbound keystore is configured, where the existing implementation always does this. This is useful for tests * that try to create a client that uses encryption but does not provide a certificate. @@ -49,7 +49,7 @@ public class SimpleClientSslContextFactory extends FileBasedSslContextFactory } @Override - public SSLContext createJSSESslContext(EncryptionOptions.ClientAuth clientAuth) throws SSLException + public SSLContext createJSSESslContext(EncryptionOptions.ClientEncryptionOptions.ClientAuth clientAuth) throws SSLException { TrustManager[] trustManagers = null; if (clientAuth != NOT_REQUIRED) @@ -76,7 +76,7 @@ public class SimpleClientSslContextFactory extends FileBasedSslContextFactory } @Override - public SslContext createNettySslContext(EncryptionOptions.ClientAuth clientAuth, SocketType socketType, + public SslContext createNettySslContext(EncryptionOptions.ClientEncryptionOptions.ClientAuth clientAuth, SocketType socketType, CipherSuiteFilter cipherFilter) throws SSLException { SslContextBuilder builder = SslContextBuilder.forClient(); diff --git a/test/unit/org/apache/cassandra/transport/TlsTestUtils.java b/test/unit/org/apache/cassandra/transport/TlsTestUtils.java index 30a6054127..76faec85b1 100644 --- a/test/unit/org/apache/cassandra/transport/TlsTestUtils.java +++ b/test/unit/org/apache/cassandra/transport/TlsTestUtils.java @@ -86,17 +86,18 @@ public class TlsTestUtils public static String CLIENT_TRUSTSTORE_PATH = "test/conf/cassandra_ssl_test.truststore"; public static String CLIENT_TRUSTSTORE_PASSWORD = "cassandra"; - public static EncryptionOptions getClientEncryptionOptions() + public static EncryptionOptions.ClientEncryptionOptions getClientEncryptionOptions() { - return new EncryptionOptions(new EncryptionOptions() + return new EncryptionOptions.ClientEncryptionOptions(new EncryptionOptions.ClientEncryptionOptions.Builder() .withEnabled(true) - .withRequireClientAuth(EncryptionOptions.ClientAuth.OPTIONAL) + .withRequireClientAuth(EncryptionOptions.ClientEncryptionOptions.ClientAuth.OPTIONAL) .withOptional(true) .withKeyStore(SERVER_KEYSTORE_PATH) .withKeyStorePassword(SERVER_KEYSTORE_PASSWORD) .withTrustStore(SERVER_TRUSTSTORE_PATH) .withTrustStorePassword(SERVER_TRUSTSTORE_PASSWORD) - .withRequireEndpointVerification(false)); + .withRequireEndpointVerification(false) + .build()); } public static void configureWithMutualTlsWithPasswordFallbackAuthenticator(Config config) @@ -129,7 +130,7 @@ public class TlsTestUtils { return RemoteEndpointAwareJdkSSLOptions.builder() .withSSLContext(getClientSslContextFactory(provideClientCert) - .createJSSESslContext(EncryptionOptions.ClientAuth.OPTIONAL)) + .createJSSESslContext(EncryptionOptions.ClientEncryptionOptions.ClientAuth.OPTIONAL)) .build(); } @@ -139,7 +140,7 @@ public class TlsTestUtils { return RemoteEndpointAwareJdkSSLOptions.builder() .withSSLContext(getClientSslContextFactory(keystorePath, truststorePath) - .createJSSESslContext(EncryptionOptions.ClientAuth.OPTIONAL)) + .createJSSESslContext(EncryptionOptions.ClientEncryptionOptions.ClientAuth.OPTIONAL)) .build(); } catch (SSLException e) diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsTransport.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsTransport.java index cf62999822..ccdf0a53b2 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsTransport.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsTransport.java @@ -44,31 +44,32 @@ public class SettingsTransport implements Serializable this.credentials = credentials; } - public EncryptionOptions getEncryptionOptions() + public EncryptionOptions.ClientEncryptionOptions getEncryptionOptions() { - EncryptionOptions encOptions = new EncryptionOptions().applyConfig(); + EncryptionOptions.ClientEncryptionOptions encOptions = new EncryptionOptions.ClientEncryptionOptions().applyConfig(); if (options.trustStore.present()) { - encOptions = encOptions - .withEnabled(true) - .withTrustStore(options.trustStore.value()) - .withTrustStorePassword(options.trustStorePw.setByUser() ? options.trustStorePw.value() : credentials.transportTruststorePassword) - .withAlgorithm(options.alg.value()) - .withProtocol(options.protocol.value()) - .withCipherSuites(options.ciphers.value().split(",")); + EncryptionOptions.Builder encOptionsBuilder = new EncryptionOptions.ClientEncryptionOptions.Builder(encOptions) + .withEnabled(true) + .withTrustStore(options.trustStore.value()) + .withTrustStorePassword(options.trustStorePw.setByUser() ? options.trustStorePw.value() : credentials.transportTruststorePassword) + .withAlgorithm(options.alg.value()) + .withProtocol(options.protocol.value()) + .withCipherSuites(options.ciphers.value().split(",")); + if (options.keyStore.present()) { - encOptions = encOptions - .withKeyStore(options.keyStore.value()) - .withKeyStorePassword(options.keyStorePw.setByUser() ? options.keyStorePw.value() : credentials.transportKeystorePassword); + encOptionsBuilder.withKeyStore(options.keyStore.value()) + .withKeyStorePassword(options.keyStorePw.setByUser() ? options.keyStorePw.value() : credentials.transportKeystorePassword); } else { // mandatory for SSLFactory.createSSLContext(), see CASSANDRA-9325 - encOptions = encOptions - .withKeyStore(encOptions.truststore) - .withKeyStorePassword(encOptions.truststore_password != null ? encOptions.truststore_password : credentials.transportTruststorePassword); + encOptionsBuilder.withKeyStore(encOptions.truststore) + .withKeyStorePassword(encOptions.truststore_password != null ? encOptions.truststore_password : credentials.transportTruststorePassword); } + + encOptions = encOptionsBuilder.build(); } return encOptions; } diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/StressSettings.java b/tools/stress/src/org/apache/cassandra/stress/settings/StressSettings.java index 6aea048b4c..f81c4a9787 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/StressSettings.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/StressSettings.java @@ -139,7 +139,7 @@ public class StressSettings implements Serializable if (client != null) return client; - EncryptionOptions encOptions = transport.getEncryptionOptions(); + EncryptionOptions.ClientEncryptionOptions encOptions = transport.getEncryptionOptions(); JavaDriverClient c = new JavaDriverClient(this, node.nodes, port.nativePort, encOptions); c.connect(mode.compression()); if (keyspace != null) diff --git a/tools/stress/src/org/apache/cassandra/stress/util/JavaDriverClient.java b/tools/stress/src/org/apache/cassandra/stress/util/JavaDriverClient.java index 3d72828daf..f2a92fe5aa 100644 --- a/tools/stress/src/org/apache/cassandra/stress/util/JavaDriverClient.java +++ b/tools/stress/src/org/apache/cassandra/stress/util/JavaDriverClient.java @@ -41,7 +41,7 @@ import org.apache.cassandra.config.EncryptionOptions; import org.apache.cassandra.security.SSLFactory; import org.apache.cassandra.stress.settings.StressSettings; -import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions.ClientAuth.REQUIRED; public class JavaDriverClient { @@ -60,7 +60,7 @@ public class JavaDriverClient public final int connectionsPerHost; private final ProtocolVersion protocolVersion; - private final EncryptionOptions encryptionOptions; + private final EncryptionOptions.ClientEncryptionOptions encryptionOptions; private Cluster cluster; private Session session; private final LoadBalancingPolicy loadBalancingPolicy; @@ -69,15 +69,15 @@ public class JavaDriverClient public JavaDriverClient(StressSettings settings, String host, int port) { - this(settings, Collections.singletonList(host), port, new EncryptionOptions()); + this(settings, Collections.singletonList(host), port, new EncryptionOptions.ClientEncryptionOptions()); } public JavaDriverClient(StressSettings settings, List hosts, int port) { - this(settings, hosts, port, new EncryptionOptions()); + this(settings, hosts, port, new EncryptionOptions.ClientEncryptionOptions()); } - public JavaDriverClient(StressSettings settings, List hosts, int port, EncryptionOptions encryptionOptions) + public JavaDriverClient(StressSettings settings, List hosts, int port, EncryptionOptions.ClientEncryptionOptions encryptionOptions) { this.protocolVersion = settings.mode.protocolVersion; this.hosts = hosts; @@ -85,7 +85,7 @@ public class JavaDriverClient this.username = settings.mode.username; this.password = settings.mode.password; this.authProvider = settings.mode.authProvider; - this.encryptionOptions = new EncryptionOptions(encryptionOptions).applyConfig(); + this.encryptionOptions = new EncryptionOptions.ClientEncryptionOptions(encryptionOptions).applyConfig(); this.loadBalancingPolicy = loadBalancingPolicy(settings); this.connectionsPerHost = settings.mode.connectionsPerHost == null ? 8 : settings.mode.connectionsPerHost;