diff --git a/server/src/main/java/org/elasticsearch/cli/KeyStoreAwareCommand.java b/server/src/main/java/org/elasticsearch/cli/KeyStoreAwareCommand.java index 201d45f54b0..ab6043026db 100644 --- a/server/src/main/java/org/elasticsearch/cli/KeyStoreAwareCommand.java +++ b/server/src/main/java/org/elasticsearch/cli/KeyStoreAwareCommand.java @@ -70,11 +70,11 @@ public abstract class KeyStoreAwareCommand extends EnvironmentAwareCommand { * Decrypt the {@code keyStore}, prompting the user to enter the password in the {@link Terminal} if it is password protected */ protected static void decryptKeyStore(KeyStoreWrapper keyStore, Terminal terminal) - throws UserException, GeneralSecurityException, IOException { + throws UserException, IOException { try (SecureString keystorePassword = keyStore.hasPassword() ? readPassword(terminal, false) : new SecureString(new char[0])) { keyStore.decrypt(keystorePassword.getChars()); - } catch (SecurityException e) { + } catch (SecurityException | GeneralSecurityException e) { throw new UserException(ExitCodes.DATA_ERROR, e.getMessage()); } } diff --git a/server/src/main/java/org/elasticsearch/common/settings/BaseKeyStoreCommand.java b/server/src/main/java/org/elasticsearch/common/settings/BaseKeyStoreCommand.java index 493d455e42f..98e37669ef7 100644 --- a/server/src/main/java/org/elasticsearch/common/settings/BaseKeyStoreCommand.java +++ b/server/src/main/java/org/elasticsearch/common/settings/BaseKeyStoreCommand.java @@ -28,6 +28,7 @@ import org.elasticsearch.cli.UserException; import org.elasticsearch.env.Environment; import java.nio.file.Path; +import java.security.GeneralSecurityException; public abstract class BaseKeyStoreCommand extends KeyStoreAwareCommand { @@ -64,7 +65,7 @@ public abstract class BaseKeyStoreCommand extends KeyStoreAwareCommand { keyStore.decrypt(keyStorePassword.getChars()); } executeCommand(terminal, options, env); - } catch (SecurityException e) { + } catch (SecurityException | GeneralSecurityException e) { throw new UserException(ExitCodes.DATA_ERROR, e.getMessage()); } finally { if (keyStorePassword != null) { diff --git a/server/src/main/java/org/elasticsearch/common/settings/KeyStoreWrapper.java b/server/src/main/java/org/elasticsearch/common/settings/KeyStoreWrapper.java index d3080df034c..d75456d4d9b 100644 --- a/server/src/main/java/org/elasticsearch/common/settings/KeyStoreWrapper.java +++ b/server/src/main/java/org/elasticsearch/common/settings/KeyStoreWrapper.java @@ -310,7 +310,14 @@ public class KeyStoreWrapper implements SecureSettings { private Cipher createCipher(int opmode, char[] password, byte[] salt, byte[] iv) throws GeneralSecurityException { PBEKeySpec keySpec = new PBEKeySpec(password, salt, KDF_ITERS, CIPHER_KEY_BITS); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KDF_ALGO); - SecretKey secretKey = keyFactory.generateSecret(keySpec); + SecretKey secretKey; + try { + secretKey = keyFactory.generateSecret(keySpec); + } catch (Error e) { + // Security Providers might throw a subclass of Error in FIPS 140 mode, if some prerequisite like + // salt, iv, or password length is not met. We catch this because we don't want the JVM to exit. + throw new GeneralSecurityException("Error generating an encryption key from the provided password", e); + } SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), CIPHER_ALGO); GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_BITS, iv); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/support/Hasher.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/support/Hasher.java index 1b5b65e60c2..774df6410a0 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/support/Hasher.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/support/Hasher.java @@ -513,7 +513,11 @@ public enum Hasher { result.put(Base64.getEncoder().encodeToString(secretKeyFactory.generateSecret(keySpec).getEncoded())); return result.array(); } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { - throw new ElasticsearchException("Can't use PBKDF2 for password hashing", e); + throw new ElasticsearchException("Error using PBKDF2 for password hashing", e); + } catch (Error e) { + // Security Providers might throw a subclass of Error in FIPS 140 mode, if some prerequisite like + // salt, iv, or password length is not met. We catch this because we don't want the JVM to exit. + throw new ElasticsearchException("Error using PBKDF2 implementation from the selected Security Provider", e); } } @@ -539,7 +543,11 @@ public enum Hasher { final boolean result = CharArrays.constantTimeEquals(computedPwdHash, hashChars); return result; } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { - throw new ElasticsearchException("Can't use PBKDF2 for password hashing", e); + throw new ElasticsearchException("Error using PBKDF2 for password hashing", e); + } catch (Error e) { + // Security Providers might throw a subclass of Error in FIPS 140 mode, if some prerequisite like + // salt, iv, or password length is not met. We catch this because we don't want the JVM to exit. + throw new ElasticsearchException("Error using PBKDF2 implementation from the selected Security Provider", e); } finally { if (null != hashChars) { Arrays.fill(hashChars, '\u0000'); diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/file/tool/UsersTool.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/file/tool/UsersTool.java index df6a86fe126..eaa4864a81b 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/file/tool/UsersTool.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/file/tool/UsersTool.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.security.authc.file.tool; import joptsimple.OptionSet; import joptsimple.OptionSpec; +import org.elasticsearch.ElasticsearchException; import org.elasticsearch.cli.EnvironmentAwareCommand; import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.cli.LoggingAwareMultiCommand; @@ -446,7 +447,10 @@ public class UsersTool extends LoggingAwareMultiCommand { final char[] passwordHash; try (SecureString password = parsePassword(terminal, cliPasswordValue)) { passwordHash = hasher.hash(password); + } catch (ElasticsearchException e) { + throw new UserException(ExitCodes.DATA_ERROR, "Error storing the password for the new user", e); } + return passwordHash; }