mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-04-25 07:37:19 -04:00
Support keystore tests on FIPS JVM (#66846)
As of #64024 we run FIPS CI on a true, FIPS approved only mode JVM. This mandates that any passwords that are fed into PBKDF2 must have at least 112 bits of entropy (that is, be 14 characters long). This commit updates our Keystore CLI tests so that tests either: 1. Use a 14+ character password when in FIPS mode, _or_ 2. Are skipped on FIPS mode (because they explicitly test empty passwords) Resolves: #66845
This commit is contained in:
parent
68a83473d3
commit
f05da6bda8
12 changed files with 131 additions and 59 deletions
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.elasticsearch.bootstrap;
|
||||
|
||||
import org.elasticsearch.common.settings.KeyStoreWrapperTests;
|
||||
import org.elasticsearch.core.internal.io.IOUtils;
|
||||
import org.elasticsearch.common.settings.KeyStoreCommandTestCase;
|
||||
import org.elasticsearch.common.settings.KeyStoreWrapper;
|
||||
|
@ -58,16 +59,20 @@ public class BootstrapTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testLoadSecureSettings() throws Exception {
|
||||
final char[] password = KeyStoreWrapperTests.getPossibleKeystorePassword();
|
||||
final Path configPath = env.configFile();
|
||||
final SecureString seed;
|
||||
try (KeyStoreWrapper keyStoreWrapper = KeyStoreWrapper.create()) {
|
||||
seed = KeyStoreWrapper.SEED_SETTING.get(Settings.builder().setSecureSettings(keyStoreWrapper).build());
|
||||
assertNotNull(seed);
|
||||
assertTrue(seed.length() > 0);
|
||||
keyStoreWrapper.save(configPath, new char[0]);
|
||||
keyStoreWrapper.save(configPath, password);
|
||||
}
|
||||
final InputStream in = password.length > 0
|
||||
? new ByteArrayInputStream(new String(password).getBytes(StandardCharsets.UTF_8))
|
||||
: System.in;
|
||||
assertTrue(Files.exists(configPath.resolve("elasticsearch.keystore")));
|
||||
try (SecureSettings secureSettings = Bootstrap.loadSecureSettings(env)) {
|
||||
try (SecureSettings secureSettings = Bootstrap.loadSecureSettings(env, in)) {
|
||||
SecureString seedAfterLoad = KeyStoreWrapper.SEED_SETTING.get(Settings.builder().setSecureSettings(secureSettings).build());
|
||||
assertEquals(seedAfterLoad.toString(), seed.toString());
|
||||
assertTrue(Files.exists(configPath.resolve("elasticsearch.keystore")));
|
||||
|
|
|
@ -64,6 +64,7 @@ public class AddFileKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testMissingCreateWithEmptyPasswordWhenPrompted() throws Exception {
|
||||
assumeFalse("Cannot create unprotected keystore on FIPS JVM", inFipsJvm());
|
||||
String password = "";
|
||||
Path file1 = createRandomFile();
|
||||
terminal.addTextInput("y");
|
||||
|
@ -72,6 +73,7 @@ public class AddFileKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testMissingCreateWithEmptyPasswordWithoutPromptIfForced() throws Exception {
|
||||
assumeFalse("Cannot create unprotected keystore on FIPS JVM", inFipsJvm());
|
||||
String password = "";
|
||||
Path file1 = createRandomFile();
|
||||
execute("-f", "foo", file1.toString());
|
||||
|
@ -211,6 +213,7 @@ public class AddFileKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testAddToUnprotectedKeystore() throws Exception {
|
||||
assumeFalse("Cannot open unprotected keystore on FIPS JVM", inFipsJvm());
|
||||
String password = "";
|
||||
Path file = createRandomFile();
|
||||
KeyStoreWrapper keystore = createKeystore(password);
|
||||
|
|
|
@ -73,6 +73,7 @@ public class AddStringKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testMissingPromptCreateWithoutPasswordWhenPrompted() throws Exception {
|
||||
assumeFalse("Cannot create unprotected keystore on FIPS JVM", inFipsJvm());
|
||||
terminal.addTextInput("y");
|
||||
terminal.addSecretInput("bar");
|
||||
execute("foo");
|
||||
|
@ -80,6 +81,7 @@ public class AddStringKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testMissingPromptCreateWithoutPasswordWithoutPromptIfForced() throws Exception {
|
||||
assumeFalse("Cannot create unprotected keystore on FIPS JVM", inFipsJvm());
|
||||
terminal.addSecretInput("bar");
|
||||
execute("-f", "foo");
|
||||
assertSecureString("foo", "bar", "");
|
||||
|
@ -251,7 +253,9 @@ public class AddStringKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testSpecialCharacterInName() throws Exception {
|
||||
createKeystore("");
|
||||
String password = randomAlphaOfLengthBetween(14, 24);
|
||||
createKeystore(password);
|
||||
terminal.addSecretInput(password);
|
||||
terminal.addSecretInput("value");
|
||||
final String key = randomAlphaOfLength(4) + '@' + randomAlphaOfLength(4);
|
||||
final UserException e = expectThrows(UserException.class, () -> execute(key));
|
||||
|
@ -260,6 +264,7 @@ public class AddStringKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testAddToUnprotectedKeystore() throws Exception {
|
||||
assumeFalse("Cannot create unprotected keystores in FIPS mode", inFipsJvm());
|
||||
String password = "";
|
||||
createKeystore(password, "foo", "bar");
|
||||
terminal.addTextInput("");
|
||||
|
|
|
@ -41,6 +41,7 @@ public class ChangeKeyStorePasswordCommandTests extends KeyStoreCommandTestCase
|
|||
}
|
||||
|
||||
public void testSetKeyStorePassword() throws Exception {
|
||||
assumeFalse("Cannot open unprotected keystore on FIPS JVM", inFipsJvm());
|
||||
createKeystore("");
|
||||
loadKeystore("");
|
||||
terminal.addSecretInput("thepassword");
|
||||
|
@ -54,14 +55,15 @@ public class ChangeKeyStorePasswordCommandTests extends KeyStoreCommandTestCase
|
|||
createKeystore("theoldpassword");
|
||||
loadKeystore("theoldpassword");
|
||||
terminal.addSecretInput("theoldpassword");
|
||||
terminal.addSecretInput("thepassword");
|
||||
terminal.addSecretInput("thepassword");
|
||||
terminal.addSecretInput("the-better-password");
|
||||
terminal.addSecretInput("the-better-password");
|
||||
// Prompted thrice: Once for the existing and twice for the new password
|
||||
execute();
|
||||
loadKeystore("thepassword");
|
||||
loadKeystore("the-better-password");
|
||||
}
|
||||
|
||||
public void testChangeKeyStorePasswordToEmpty() throws Exception {
|
||||
assumeFalse("Cannot set empty keystore password on FIPS JVM", inFipsJvm());
|
||||
createKeystore("theoldpassword");
|
||||
loadKeystore("theoldpassword");
|
||||
terminal.addSecretInput("theoldpassword");
|
||||
|
|
|
@ -19,16 +19,16 @@
|
|||
|
||||
package org.elasticsearch.common.settings;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
import org.elasticsearch.cli.Command;
|
||||
import org.elasticsearch.cli.ExitCodes;
|
||||
import org.elasticsearch.cli.UserException;
|
||||
import org.elasticsearch.env.Environment;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
public class CreateKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
||||
|
@ -44,7 +44,7 @@ public class CreateKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testNotMatchingPasswords() throws Exception {
|
||||
String password = randomFrom("", "keystorepassword");
|
||||
String password = getPossibleKeystorePassword();
|
||||
terminal.addSecretInput(password);
|
||||
terminal.addSecretInput("notthekeystorepasswordyouarelookingfor");
|
||||
UserException e = expectThrows(UserException.class, () -> execute(randomFrom("-p", "--password")));
|
||||
|
@ -53,48 +53,67 @@ public class CreateKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testDefaultNotPromptForPassword() throws Exception {
|
||||
assumeFalse("Cannot open unprotected keystore on FIPS JVM", inFipsJvm());
|
||||
execute();
|
||||
Path configDir = env.configFile();
|
||||
assertNotNull(KeyStoreWrapper.load(configDir));
|
||||
}
|
||||
|
||||
public void testPosix() throws Exception {
|
||||
String password = randomFrom("", "keystorepassword");
|
||||
final String password = getPossibleKeystorePassword();
|
||||
// Sometimes (rarely) test with explicit empty password
|
||||
final boolean withPassword = password.length() > 0 || rarely();
|
||||
if (withPassword) {
|
||||
terminal.addSecretInput(password);
|
||||
terminal.addSecretInput(password);
|
||||
execute(randomFrom("-p", "--password"));
|
||||
} else {
|
||||
execute();
|
||||
}
|
||||
Path configDir = env.configFile();
|
||||
assertNotNull(KeyStoreWrapper.load(configDir));
|
||||
}
|
||||
|
||||
public void testNotPosix() throws Exception {
|
||||
String password = randomFrom("", "keystorepassword");
|
||||
terminal.addSecretInput(password);
|
||||
terminal.addSecretInput(password);
|
||||
env = setupEnv(false, fileSystems);
|
||||
final String password = getPossibleKeystorePassword();
|
||||
// Sometimes (rarely) test with explicit empty password
|
||||
final boolean withPassword = password.length() > 0 || rarely();
|
||||
if (withPassword) {
|
||||
terminal.addSecretInput(password);
|
||||
terminal.addSecretInput(password);
|
||||
execute(randomFrom("-p", "--password"));
|
||||
} else {
|
||||
execute();
|
||||
}
|
||||
Path configDir = env.configFile();
|
||||
assertNotNull(KeyStoreWrapper.load(configDir));
|
||||
}
|
||||
|
||||
public void testOverwrite() throws Exception {
|
||||
String password = randomFrom("", "keystorepassword");
|
||||
String password = getPossibleKeystorePassword();
|
||||
Path keystoreFile = KeyStoreWrapper.keystorePath(env.configFile());
|
||||
byte[] content = "not a keystore".getBytes(StandardCharsets.UTF_8);
|
||||
Files.write(keystoreFile, content);
|
||||
|
||||
terminal.addTextInput(""); // default is no
|
||||
terminal.addTextInput(""); // default is no (don't overwrite)
|
||||
execute();
|
||||
assertArrayEquals(content, Files.readAllBytes(keystoreFile));
|
||||
|
||||
terminal.addTextInput("n"); // explicit no
|
||||
terminal.addTextInput("n"); // explicit no (don't overwrite)
|
||||
execute();
|
||||
assertArrayEquals(content, Files.readAllBytes(keystoreFile));
|
||||
|
||||
terminal.addTextInput("y");
|
||||
terminal.addTextInput("y"); // overwrite
|
||||
// Sometimes (rarely) test with explicit empty password
|
||||
final boolean withPassword = password.length() > 0 || rarely();
|
||||
if (withPassword) {
|
||||
terminal.addSecretInput(password);
|
||||
terminal.addSecretInput(password);
|
||||
execute(randomFrom("-p", "--password"));
|
||||
} else {
|
||||
execute();
|
||||
}
|
||||
assertNotNull(KeyStoreWrapper.load(env.configFile()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ public class HasPasswordKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testFailsWhenKeystoreLacksPassword() throws Exception {
|
||||
assumeFalse("Cannot create unprotected keystores in FIPS mode", inFipsJvm());
|
||||
createKeystore("");
|
||||
UserException e = expectThrows(UserException.class, this::execute);
|
||||
assertEquals("Unexpected exit code", HasPasswordKeyStoreCommand.NO_PASSWORD_EXIT_CODE, e.exitCode);
|
||||
|
|
|
@ -19,6 +19,17 @@
|
|||
|
||||
package org.elasticsearch.common.settings;
|
||||
|
||||
import com.google.common.jimfs.Configuration;
|
||||
import com.google.common.jimfs.Jimfs;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.elasticsearch.cli.CommandTestCase;
|
||||
import org.elasticsearch.common.io.PathUtilsForTesting;
|
||||
import org.elasticsearch.core.internal.io.IOUtils;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.env.TestEnvironment;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.FileSystem;
|
||||
|
@ -27,17 +38,6 @@ import java.nio.file.Path;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.jimfs.Configuration;
|
||||
import com.google.common.jimfs.Jimfs;
|
||||
import org.elasticsearch.core.internal.io.IOUtils;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.elasticsearch.cli.CommandTestCase;
|
||||
import org.elasticsearch.common.io.PathUtilsForTesting;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.env.TestEnvironment;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
/**
|
||||
* Base test case for manipulating the ES keystore.
|
||||
*/
|
||||
|
@ -124,4 +124,12 @@ public abstract class KeyStoreCommandTestCase extends CommandTestCase {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
String getPossibleKeystorePassword() {
|
||||
if (inFipsJvm()) {
|
||||
// FIPS Mode JVMs require a password for the ES keystore
|
||||
return "keystorepassword";
|
||||
}
|
||||
return randomFrom("", "keystorepassword");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ import java.security.KeyStore;
|
|||
import java.security.MessageDigest;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -81,15 +82,16 @@ public class KeyStoreWrapperTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testFileSettingExhaustiveBytes() throws Exception {
|
||||
final char[] password = getPossibleKeystorePassword();
|
||||
KeyStoreWrapper keystore = KeyStoreWrapper.create();
|
||||
byte[] bytes = new byte[256];
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
bytes[i] = (byte) i;
|
||||
}
|
||||
keystore.setFile("foo", bytes);
|
||||
keystore.save(env.configFile(), new char[0]);
|
||||
keystore.save(env.configFile(), password);
|
||||
keystore = KeyStoreWrapper.load(env.configFile());
|
||||
keystore.decrypt(new char[0]);
|
||||
keystore.decrypt(password);
|
||||
try (InputStream stream = keystore.getFile("foo")) {
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
int got = stream.read();
|
||||
|
@ -108,13 +110,18 @@ public class KeyStoreWrapperTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testDecryptKeyStoreWithWrongPassword() throws Exception {
|
||||
final char[] realPassword = getPossibleKeystorePassword();
|
||||
final char[] invalidPassword;
|
||||
if (realPassword.length < 1) {
|
||||
invalidPassword = new char[] { 'i', 'n', 'v', 'a', 'l', 'i', 'd' };
|
||||
} else {
|
||||
invalidPassword = Arrays.copyOf(realPassword, realPassword.length + 1);
|
||||
invalidPassword[realPassword.length] = '#';
|
||||
}
|
||||
KeyStoreWrapper keystore = KeyStoreWrapper.create();
|
||||
keystore.save(env.configFile(), new char[0]);
|
||||
keystore.save(env.configFile(), realPassword);
|
||||
final KeyStoreWrapper loadedkeystore = KeyStoreWrapper.load(env.configFile());
|
||||
final SecurityException exception = expectThrows(
|
||||
SecurityException.class,
|
||||
() -> loadedkeystore.decrypt(new char[] { 'i', 'n', 'v', 'a', 'l', 'i', 'd' })
|
||||
);
|
||||
final SecurityException exception = expectThrows(SecurityException.class, () -> loadedkeystore.decrypt(invalidPassword));
|
||||
if (inFipsJvm()) {
|
||||
assertThat(
|
||||
exception.getMessage(),
|
||||
|
@ -165,18 +172,20 @@ public class KeyStoreWrapperTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testUpgradeNoop() throws Exception {
|
||||
final char[] password = getPossibleKeystorePassword();
|
||||
KeyStoreWrapper keystore = KeyStoreWrapper.create();
|
||||
SecureString seed = keystore.getString(KeyStoreWrapper.SEED_SETTING.getKey());
|
||||
keystore.save(env.configFile(), new char[0]);
|
||||
keystore.save(env.configFile(), password);
|
||||
// upgrade does not overwrite seed
|
||||
KeyStoreWrapper.upgrade(keystore, env.configFile(), new char[0]);
|
||||
KeyStoreWrapper.upgrade(keystore, env.configFile(), password);
|
||||
assertEquals(seed.toString(), keystore.getString(KeyStoreWrapper.SEED_SETTING.getKey()).toString());
|
||||
keystore = KeyStoreWrapper.load(env.configFile());
|
||||
keystore.decrypt(new char[0]);
|
||||
keystore.decrypt(password);
|
||||
assertEquals(seed.toString(), keystore.getString(KeyStoreWrapper.SEED_SETTING.getKey()).toString());
|
||||
}
|
||||
|
||||
public void testFailWhenCannotConsumeSecretStream() throws Exception {
|
||||
assumeFalse("Cannot open unprotected keystore on FIPS JVM", inFipsJvm());
|
||||
Path configDir = env.configFile();
|
||||
SimpleFSDirectory directory = new SimpleFSDirectory(configDir);
|
||||
try (IndexOutput indexOutput = directory.createOutput("elasticsearch.keystore", IOContext.DEFAULT)) {
|
||||
|
@ -205,6 +214,7 @@ public class KeyStoreWrapperTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testFailWhenCannotConsumeEncryptedBytesStream() throws Exception {
|
||||
assumeFalse("Cannot open unprotected keystore on FIPS JVM", inFipsJvm());
|
||||
Path configDir = env.configFile();
|
||||
SimpleFSDirectory directory = new SimpleFSDirectory(configDir);
|
||||
try (IndexOutput indexOutput = directory.createOutput("elasticsearch.keystore", IOContext.DEFAULT)) {
|
||||
|
@ -234,6 +244,7 @@ public class KeyStoreWrapperTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testFailWhenSecretStreamNotConsumed() throws Exception {
|
||||
assumeFalse("Cannot open unprotected keystore on FIPS JVM", inFipsJvm());
|
||||
Path configDir = env.configFile();
|
||||
SimpleFSDirectory directory = new SimpleFSDirectory(configDir);
|
||||
try (IndexOutput indexOutput = directory.createOutput("elasticsearch.keystore", IOContext.DEFAULT)) {
|
||||
|
@ -261,6 +272,7 @@ public class KeyStoreWrapperTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testFailWhenEncryptedBytesStreamIsNotConsumed() throws Exception {
|
||||
assumeFalse("Cannot open unprotected keystore on FIPS JVM", inFipsJvm());
|
||||
Path configDir = env.configFile();
|
||||
SimpleFSDirectory directory = new SimpleFSDirectory(configDir);
|
||||
try (IndexOutput indexOutput = directory.createOutput("elasticsearch.keystore", IOContext.DEFAULT)) {
|
||||
|
@ -324,14 +336,15 @@ public class KeyStoreWrapperTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testUpgradeAddsSeed() throws Exception {
|
||||
final char[] password = getPossibleKeystorePassword();
|
||||
KeyStoreWrapper keystore = KeyStoreWrapper.create();
|
||||
keystore.remove(KeyStoreWrapper.SEED_SETTING.getKey());
|
||||
keystore.save(env.configFile(), new char[0]);
|
||||
KeyStoreWrapper.upgrade(keystore, env.configFile(), new char[0]);
|
||||
keystore.save(env.configFile(), password);
|
||||
KeyStoreWrapper.upgrade(keystore, env.configFile(), password);
|
||||
SecureString seed = keystore.getString(KeyStoreWrapper.SEED_SETTING.getKey());
|
||||
assertNotNull(seed);
|
||||
keystore = KeyStoreWrapper.load(env.configFile());
|
||||
keystore.decrypt(new char[0]);
|
||||
keystore.decrypt(password);
|
||||
assertEquals(seed.toString(), keystore.getString(KeyStoreWrapper.SEED_SETTING.getKey()).toString());
|
||||
}
|
||||
|
||||
|
@ -435,17 +448,18 @@ public class KeyStoreWrapperTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testStringAndFileDistinction() throws Exception {
|
||||
final char[] password = getPossibleKeystorePassword();
|
||||
final KeyStoreWrapper wrapper = KeyStoreWrapper.create();
|
||||
wrapper.setString("string_setting", "string_value".toCharArray());
|
||||
final Path temp = createTempDir();
|
||||
Files.writeString(temp.resolve("file_setting"), "file_value", StandardCharsets.UTF_8);
|
||||
wrapper.setFile("file_setting", Files.readAllBytes(temp.resolve("file_setting")));
|
||||
wrapper.save(env.configFile(), new char[0]);
|
||||
wrapper.save(env.configFile(), password);
|
||||
wrapper.close();
|
||||
|
||||
final KeyStoreWrapper afterSave = KeyStoreWrapper.load(env.configFile());
|
||||
assertNotNull(afterSave);
|
||||
afterSave.decrypt(new char[0]);
|
||||
afterSave.decrypt(password);
|
||||
assertThat(afterSave.getSettingNames(), equalTo(Set.of("keystore.seed", "string_setting", "file_setting")));
|
||||
assertThat(afterSave.getString("string_setting"), equalTo("string_value"));
|
||||
assertThat(toByteArray(afterSave.getFile("string_setting")), equalTo("string_value".getBytes(StandardCharsets.UTF_8)));
|
||||
|
@ -454,6 +468,7 @@ public class KeyStoreWrapperTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testLegacyV3() throws GeneralSecurityException, IOException {
|
||||
assumeFalse("Cannot open unprotected keystore on FIPS JVM", inFipsJvm());
|
||||
final Path configDir = createTempDir();
|
||||
final Path keystore = configDir.resolve("elasticsearch.keystore");
|
||||
try (
|
||||
|
@ -487,4 +502,11 @@ public class KeyStoreWrapperTests extends ESTestCase {
|
|||
return os.toByteArray();
|
||||
}
|
||||
|
||||
public static char[] getPossibleKeystorePassword() {
|
||||
if (inFipsJvm()) {
|
||||
// FIPS Mode JVMs require a password of at least 112 bits for the ES keystore
|
||||
return randomAlphaOfLengthBetween(14, 24).toCharArray();
|
||||
}
|
||||
return randomBoolean() ? new char[0] : randomAlphaOfLengthBetween(4, 24).toCharArray();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,13 +19,13 @@
|
|||
|
||||
package org.elasticsearch.common.settings;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.elasticsearch.cli.Command;
|
||||
import org.elasticsearch.cli.ExitCodes;
|
||||
import org.elasticsearch.cli.UserException;
|
||||
import org.elasticsearch.env.Environment;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.Matchers.anyOf;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
|
@ -48,7 +48,7 @@ public class ListKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testEmpty() throws Exception {
|
||||
String password = randomFrom("", "keystorepassword");
|
||||
String password = getPossibleKeystorePassword();
|
||||
createKeystore(password);
|
||||
terminal.addSecretInput(password);
|
||||
execute();
|
||||
|
@ -56,7 +56,7 @@ public class ListKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testOne() throws Exception {
|
||||
String password = randomFrom("", "keystorepassword");
|
||||
String password = getPossibleKeystorePassword();
|
||||
createKeystore(password, "foo", "bar");
|
||||
terminal.addSecretInput(password);
|
||||
execute();
|
||||
|
@ -64,7 +64,7 @@ public class ListKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testMultiple() throws Exception {
|
||||
String password = randomFrom("", "keystorepassword");
|
||||
String password = getPossibleKeystorePassword();
|
||||
createKeystore(password, "foo", "1", "baz", "2", "bar", "3");
|
||||
terminal.addSecretInput(password);
|
||||
execute();
|
||||
|
@ -91,6 +91,7 @@ public class ListKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testListWithUnprotectedKeystore() throws Exception {
|
||||
assumeFalse("Cannot open unprotected keystore on FIPS JVM", inFipsJvm());
|
||||
createKeystore("", "foo", "bar");
|
||||
execute();
|
||||
// Not prompted for a password
|
||||
|
|
|
@ -109,6 +109,7 @@ public class RemoveSettingKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testRemoveFromUnprotectedKeystore() throws Exception {
|
||||
assumeFalse("Cannot open unprotected keystore on FIPS JVM", inFipsJvm());
|
||||
String password = "";
|
||||
createKeystore(password, "foo", "bar");
|
||||
// will not be prompted for a password
|
||||
|
|
|
@ -49,6 +49,7 @@ public class UpgradeKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
}
|
||||
|
||||
public void testKeystoreUpgrade() throws Exception {
|
||||
assumeFalse("Cannot open unprotected keystore on FIPS JVM", inFipsJvm());
|
||||
final Path keystore = KeyStoreWrapper.keystorePath(env.configFile());
|
||||
try (
|
||||
InputStream is = KeyStoreWrapperTests.class.getResourceAsStream("/format-v3-elasticsearch.keystore");
|
||||
|
|
|
@ -233,6 +233,10 @@ final class Bootstrap {
|
|||
}
|
||||
|
||||
static SecureSettings loadSecureSettings(Environment initialEnv) throws BootstrapException {
|
||||
return loadSecureSettings(initialEnv, System.in);
|
||||
}
|
||||
|
||||
static SecureSettings loadSecureSettings(Environment initialEnv, InputStream stdin) throws BootstrapException {
|
||||
final KeyStoreWrapper keystore;
|
||||
try {
|
||||
keystore = KeyStoreWrapper.load(initialEnv.configFile());
|
||||
|
@ -243,7 +247,7 @@ final class Bootstrap {
|
|||
SecureString password;
|
||||
try {
|
||||
if (keystore != null && keystore.hasPassword()) {
|
||||
password = readPassphrase(System.in, KeyStoreAwareCommand.MAX_PASSPHRASE_LENGTH);
|
||||
password = readPassphrase(stdin, KeyStoreAwareCommand.MAX_PASSPHRASE_LENGTH);
|
||||
} else {
|
||||
password = new SecureString(new char[0]);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue