Allow empty keystore_password in encryption_options

patch by Andy Tolbert; reviewed by Jon Meredith and Stefan Miklosovic for CASSANDRA-18778
This commit is contained in:
Andy Tolbert 2023-08-18 09:33:57 -05:00 committed by Stefan Miklosovic
parent ac3b356063
commit b47bee42d3
No known key found for this signature in database
GPG Key ID: 32F35CB2F546D93E
4 changed files with 17 additions and 21 deletions

View File

@ -1,4 +1,5 @@
4.1.4
* Allow empty keystore_password in encryption_options (CASSANDRA-18778)
* Skip ColumnFamilyStore#topPartitions initialization when client or tool mode (CASSANDRA-18697)
Merged from 4.0:
* Fix NTS log message when an unrecognized strategy option is passed (CASSANDRA-18679)

View File

@ -123,12 +123,11 @@ abstract public class FileBasedSslContextFactory extends AbstractSslContextFacto
* Validates the given keystore password.
*
* @param password value
* @throws IllegalArgumentException if the {@code password} is empty as per the definition of {@link StringUtils#isEmpty(CharSequence)}
* @throws IllegalArgumentException if the {@code password} is null
*/
protected void validatePassword(String password)
{
boolean keystorePasswordEmpty = StringUtils.isEmpty(password);
if (keystorePasswordEmpty)
if (password == null)
{
throw new IllegalArgumentException("'keystore_password' must be specified");
}
@ -155,13 +154,14 @@ abstract public class FileBasedSslContextFactory extends AbstractSslContextFacto
final String algorithm = this.algorithm == null ? KeyManagerFactory.getDefaultAlgorithm() : this.algorithm;
KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
KeyStore ks = KeyStore.getInstance(store_type);
ks.load(ksf, keystore_password.toCharArray());
final char[] password = keystore_password.toCharArray();
ks.load(ksf, password);
if (!checkedExpiry)
{
checkExpiredCerts(ks);
checkedExpiry = true;
}
kmf.init(ks, keystore_password.toCharArray());
kmf.init(ks, password);
return kmf;
}
catch (Exception e)

Binary file not shown.

View File

@ -81,36 +81,31 @@ public class FileBasedSslContextFactoryTest
}
/**
* Tests for empty {@code keystore_password} and empty {@code outbound_keystore_password} configurations.
* Tests that empty {@code keystore_password} is allowed.
*/
@Test(expected = IllegalArgumentException.class)
@Test
public void testEmptyKeystorePasswords() throws SSLException
{
EncryptionOptions.ServerEncryptionOptions localEncryptionOptions = encryptionOptions.withKeyStorePassword(null);
EncryptionOptions.ServerEncryptionOptions localEncryptionOptions = encryptionOptions
.withKeyStorePassword("")
.withKeyStore("test/conf/cassandra_ssl_test_nopassword.keystore");
Assert.assertEquals("org.apache.cassandra.security.FileBasedSslContextFactoryTest$TestFileBasedSSLContextFactory",
localEncryptionOptions.ssl_context_factory.class_name);
Assert.assertNull("keystore_password must be null", localEncryptionOptions.keystore_password);
Assert.assertEquals("keystore_password must be empty", "", localEncryptionOptions.keystore_password);
TestFileBasedSSLContextFactory sslContextFactory =
(TestFileBasedSSLContextFactory) localEncryptionOptions.sslContextFactoryInstance;
try
{
sslContextFactory.buildKeyManagerFactory();
sslContextFactory.buildTrustManagerFactory();
}
catch (Exception e)
{
Assert.assertEquals("'keystore_password' must be specified", e.getMessage());
throw e;
}
sslContextFactory.buildKeyManagerFactory();
sslContextFactory.buildTrustManagerFactory();
}
/**
* Tests for the empty password for the {@code keystore} used for the client communication.
* Tests that an absent keystore_password for the {@code keystore} is disallowed.
*/
@Test(expected = IllegalArgumentException.class)
public void testEmptyKeystorePassword() throws SSLException
public void testNullKeystorePasswordDisallowed() throws SSLException
{
EncryptionOptions.ServerEncryptionOptions localEncryptionOptions = encryptionOptions.withKeyStorePassword(null);