Refactor EncryptionOptions to use client / server encryption options builders

patch by Maulin Vasavada; reviewed by Maxwell Guo, Stefan Miklosovic for CASSANDRA-20404
This commit is contained in:
maulin-vasavada 2025-03-07 16:02:00 -08:00 committed by Stefan Miklosovic
parent 4805123eb8
commit bcea8f5815
No known key found for this signature in database
GPG Key ID: 32F35CB2F546D93E
50 changed files with 996 additions and 1012 deletions

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;
@ -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<EncryptionOptions, EncryptionOptions> update)
public static void updateNativeProtocolEncryptionOptions(Function<EncryptionOptions.ClientEncryptionOptions, EncryptionOptions.ClientEncryptionOptions> update)
{
conf.client_encryption_options = update.apply(conf.client_encryption_options);
}

File diff suppressed because it is too large Load Diff

View File

@ -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,

View File

@ -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);

View File

@ -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)

View File

@ -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<SuccessType extends OutboundConnectionI
private SslContext getSslContext(SslFallbackConnectionType connectionType) throws IOException
{
EncryptionOptions.ClientAuth requireClientAuth = NOT_REQUIRED;
EncryptionOptions.ClientEncryptionOptions.ClientAuth requireClientAuth = NOT_REQUIRED;
if (connectionType == SslFallbackConnectionType.MTLS )
{
requireClientAuth = REQUIRED;

View File

@ -37,8 +37,8 @@ import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import org.apache.cassandra.config.EncryptionOptions;
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.config.CassandraRelevantProperties.DISABLE_TCACTIVE_OPENSSL;
@ -68,7 +68,7 @@ abstract public class AbstractSslContextFactory implements ISslContextFactory
protected final List<String> 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)
{

View File

@ -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)

View File

@ -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)
{

View File

@ -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

View File

@ -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<InetSocketAddress> 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<InetAddress> hostsArg = new HashSet<>();
Set<InetAddress> ignoresArg = new HashSet<>();
Set<InetSocketAddress> 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);

View File

@ -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))

View File

@ -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

View File

@ -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());

View File

@ -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)
);

View File

@ -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);
}

View File

@ -94,7 +94,7 @@ public class IsolatedJmx
// CASSANDRA-18508: Sensitive JMX SSL configuration options can be easily exposed
Map<String, Object> jmxServerOptionsMap = (Map<String, Object>) 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<String, Object> jmxServerOptionsMap)
private EncryptionOptions.ClientEncryptionOptions getJmxEncryptionOptions(Map<String, Object> 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<String> acceptedProtocols = (List<String>) 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
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);
return jmxEncryptionOptions;
.withEnabled(enabled)
.build();
}
private void waitForJmxAvailability(Map<String, ?> env)

View File

@ -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<String> acceptedProtocols;
final List<String> cipherSuites;
final EncryptionOptions encryptionOptions = new EncryptionOptions()
final EncryptionOptions.ClientEncryptionOptions encryptionOptions = new EncryptionOptions.ClientEncryptionOptions.Builder()
.withEnabled(true)
.withKeyStore(validKeyStorePath).withKeyStorePassword(validKeyStorePassword)
.withTrustStore(validTrustStorePath).withTrustStorePassword(validTrustStorePassword);
.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();

View File

@ -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."));

View File

@ -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();

View File

@ -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());

View File

@ -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<String, String> parameters = Collections.singletonMap("validator_class_name", "org.apache.cassandra.auth.SpiffeCertificateValidator");
fallbackAuthenticator = new MutualTlsWithPasswordFallbackAuthenticator(parameters);
fallbackAuthenticator.setup();

View File

@ -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());
}
}

View File

@ -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<String,String> 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<String,String> 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<String,String> 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<String,String> 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<String,String> 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<String,String> 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());

View File

@ -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,7 +59,7 @@ 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",
return new EncryptionOptionsTestCase(new EncryptionOptions.ClientEncryptionOptions(new ParameterizedClass("org.apache.cassandra.security.DefaultSslContextFactory",
new HashMap<>()),
keystorePath, "dummypass", null,
"dummytruststore", "dummypass", null,
@ -70,10 +70,10 @@ public class EncryptionOptionsTest
}
public static EncryptionOptionsTestCase of(Boolean optional, String keystorePath, Boolean enabled,
Map<String,String> customSslContextFactoryParams,
Map<String, String> customSslContextFactoryParams,
EncryptionOptions.TlsEncryptionPolicy expected)
{
return new EncryptionOptionsTestCase(new EncryptionOptions(new ParameterizedClass("org.apache.cassandra.security.DefaultSslContextFactory",
return new EncryptionOptionsTestCase(new EncryptionOptions.ClientEncryptionOptions(new ParameterizedClass("org.apache.cassandra.security.DefaultSslContextFactory",
customSslContextFactoryParams),
keystorePath, "dummypass", null,
"dummytruststore", "dummypass", null,
@ -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;
@ -251,7 +251,7 @@ public class EncryptionOptionsTest
{
Map<String, String> customSslContextFactoryParams = new HashMap<>();
for(EncryptionOptions.ConfigKey configKey: EncryptionOptions.ConfigKey.values())
for (EncryptionOptions.ConfigKey configKey : EncryptionOptions.ConfigKey.values())
{
customSslContextFactoryParams.put(configKey.toString(), "my-custom-value");
}

View File

@ -663,13 +663,15 @@ public abstract class CQLTester
public static void requireNativeProtocolClientEncryption()
{
DatabaseDescriptor.updateNativeProtocolEncryptionOptions((encryptionOptions) ->
encryptionOptions.withEnabled(true)
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.ClientAuth.OPTIONAL));
.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);
}

View File

@ -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<String> 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");
}

View File

@ -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<EncryptionOptions.ServerEncryptionOptions> 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<Function<Settings, Settings>> MODIFIERS = ImmutableList.of(
settings -> settings.outbound(outbound -> outbound.withEncryption(encryptionOptions))

View File

@ -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)
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)
.withOutboundKeystore(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PATH)
.withOutboundKeystorePassword(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PASSWORD)
.withTrustStore(TlsTestUtils.SERVER_TRUSTSTORE_PATH)
.withTrustStorePassword(TlsTestUtils.SERVER_TRUSTSTORE_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)
serverEncryptionOptionsBuilder.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all)
.withRequireClientAuth(REQUIRED);
}
else if (sslConnectionType == SslFallbackConnectionType.SSL)
{
serverEncryptionOptions = serverEncryptionOptions.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all)
serverEncryptionOptionsBuilder.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all)
.withRequireClientAuth(NOT_REQUIRED);
}
return serverEncryptionOptions;
return serverEncryptionOptionsBuilder.build();
}
private InboundSockets getInboundSocket(ServerEncryptionOptions serverEncryptionOptions)

View File

@ -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()
ServerEncryptionOptions serverEncryptionOptions = new Builder().withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all)
.withLegacySslStoragePort(false)
.withOptional(false)
.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all)
.withLegacySslStoragePort(false);
.build();
listen(serverEncryptionOptions, false);
}
@Test
public void listenRequiredSecureConnectionWithBroadcastAddr() throws InterruptedException
{
ServerEncryptionOptions serverEncryptionOptions = new ServerEncryptionOptions()
ServerEncryptionOptions serverEncryptionOptions = new Builder().withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all)
.withLegacySslStoragePort(false)
.withOptional(false)
.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all)
.withLegacySslStoragePort(false);
.build();
listen(serverEncryptionOptions, true);
}
@Test
public void listenRequiredSecureConnectionWithLegacyPort() throws InterruptedException
{
ServerEncryptionOptions serverEncryptionOptions = new ServerEncryptionOptions()
.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all)
ServerEncryptionOptions serverEncryptionOptions = new Builder().withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all)
.withLegacySslStoragePort(true)
.withOptional(false)
.withLegacySslStoragePort(true);
.build();
listen(serverEncryptionOptions, false);
}
@Test
public void listenRequiredSecureConnectionWithBroadcastAddrAndLegacyPort() throws InterruptedException
{
ServerEncryptionOptions serverEncryptionOptions = new ServerEncryptionOptions()
.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all)
ServerEncryptionOptions serverEncryptionOptions = new Builder().withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all)
.withLegacySslStoragePort(true)
.withOptional(false)
.withLegacySslStoragePort(true);
.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);
}

View File

@ -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<String,Object> commonConfig = new HashMap<>();
private Map<String, Object> 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<String,Object> config)
private void addKeystoreOptions(Map<String, Object> 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)
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)
.withOutboundKeystore(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PATH)
.withOutboundKeystorePassword(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PASSWORD)
.withRequireClientAuth(NOT_REQUIRED)
.withCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA");
.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<String,Object> config = new HashMap<>();
Map<String, Object> 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<String,Object> config = new HashMap<>();
Map<String, Object> 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<String,Object> config = new HashMap<>();
Map<String, Object> 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<String,Object> config = new HashMap<>();
Map<String, Object> 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<String,Object> config = new HashMap<>();
Map<String, Object> 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<String,Object> config = new HashMap<>();
Map<String, Object> 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<String,Object> config = new HashMap<>();
Map<String, Object> config = new HashMap<>();
config.putAll(commonConfig);
DefaultSslContextFactory defaultSslContextFactoryImpl = new DefaultSslContextFactory(config);

View File

@ -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;

View File

@ -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);

View File

@ -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)
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);
.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)
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)
.withOutboundKeystore(TlsTestUtils.SERVER_KEYSTORE_PATH_PEM)
.withOutboundKeystorePassword(TlsTestUtils.SERVER_KEYSTORE_PASSWORD)
.withRequireClientAuth(NOT_REQUIRED)
.withCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA")
.withSslContextFactory(sslContextFactory);
.withSslContextFactory(sslContextFactory)
.build();
SslContext sslContext = SSLFactory.getOrCreateSslContext(options, REQUIRED, ISslContextFactory.SocketType.CLIENT, "test");
Assert.assertNotNull(sslContext);
if (OpenSsl.isAvailable())

View File

@ -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)
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<>()));
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)
EncryptionOptions.ServerEncryptionOptions.Builder builder = new EncryptionOptions.ServerEncryptionOptions.Builder(options);
builder.withOutboundKeystorePassword(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PASSWORD)
.withOutboundKeystore(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PATH)
.withOutboundKeystorePassword(TlsTestUtils.SERVER_OUTBOUND_KEYSTORE_PASSWORD);
.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)
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)
.withOutboundKeystore(TlsTestUtils.SERVER_KEYSTORE_PATH_PEM)
.withOutboundKeystorePassword(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)
Builder optionsBuilder = addKeystoreOptions(encryptionOptions)
.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all);
ServerEncryptionOptions legacyOptions = options.withOptional(false).withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all);
ServerEncryptionOptions options = optionsBuilder.build();
ServerEncryptionOptions legacyOptions = optionsBuilder
.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all)
.withOptional(false)
.build();
options.sslContextFactoryInstance.initHotReloading();
legacyOptions.sslContextFactoryInstance.initHotReloading();
@ -147,7 +161,8 @@ public class SSLFactoryTest
{
ServerEncryptionOptions options = addKeystoreOptions(encryptionOptions)
.withOutboundKeystore("dummyKeystore")
.withOutboundKeystorePassword("dummyPassword");
.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);
@ -164,7 +179,8 @@ public class SSLFactoryTest
{
ServerEncryptionOptions options = addKeystoreOptions(encryptionOptions)
.withKeyStore("dummyKeystore")
.withKeyStorePassword("dummyPassword");
.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)
.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all)
.withKeyStorePassword("bad password")
.withInternodeEncryption(ServerEncryptionOptions.InternodeEncryption.all);
.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<String,String> parameters1 = new HashMap<>();
Map<String, String> 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<String,String> parameters2 = new HashMap<>();
Map<String, String> 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<String,String> parameters1 = new HashMap<>();
Map<String, String> 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<String,String> parameters2 = new HashMap<>();
Map<String, String> 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<String, Object> parameters)
{
super(parameters);

View File

@ -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);

View File

@ -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) ->
{

View File

@ -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");

View File

@ -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()
{

View File

@ -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)
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)
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
}
};
}
}

View File

@ -127,7 +127,7 @@ public class MessagePayloadTest extends CQLTester
nativePort,
ProtocolVersion.V5,
true,
new EncryptionOptions());
new EncryptionOptions.ClientEncryptionOptions());
try
{
client.connect(false);

View File

@ -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}.
* <p>
* 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();

View File

@ -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)

View File

@ -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
EncryptionOptions.Builder<EncryptionOptions.ClientEncryptionOptions> 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())
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)
encOptionsBuilder.withKeyStore(encOptions.truststore)
.withKeyStorePassword(encOptions.truststore_password != null ? encOptions.truststore_password : credentials.transportTruststorePassword);
}
encOptions = encOptionsBuilder.build();
}
return encOptions;
}

View File

@ -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)

View File

@ -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<String> hosts, int port)
{
this(settings, hosts, port, new EncryptionOptions());
this(settings, hosts, port, new EncryptionOptions.ClientEncryptionOptions());
}
public JavaDriverClient(StressSettings settings, List<String> hosts, int port, EncryptionOptions encryptionOptions)
public JavaDriverClient(StressSettings settings, List<String> 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;