Browse Source

Switch usages from KeyStoreWrapper to SecureSettings (#92339)

Move away from using the KeyStoreWrapper type directly
and switch to SecureSettings, where possible.
Nikola Grcevski 2 years ago
parent
commit
a3f8abb953

+ 8 - 9
distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/APMJvmOptions.java

@@ -13,7 +13,7 @@ import org.elasticsearch.Version;
 import org.elasticsearch.cli.ExitCodes;
 import org.elasticsearch.cli.UserException;
 import org.elasticsearch.common.Strings;
-import org.elasticsearch.common.settings.KeyStoreWrapper;
+import org.elasticsearch.common.settings.SecureSettings;
 import org.elasticsearch.common.settings.SecureString;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.core.Nullable;
@@ -133,11 +133,10 @@ class APMJvmOptions {
      * because it will be deleted once Elasticsearch starts.
      *
      * @param settings the Elasticsearch settings to consider
-     * @param keystore a wrapper to access the keystore, or null if there is no keystore
+     * @param secrets a wrapper to access the secrets, or null if there is no secrets
      * @param tmpdir Elasticsearch's temporary directory, where the config file will be written
      */
-    static List<String> apmJvmOptions(Settings settings, @Nullable KeyStoreWrapper keystore, Path tmpdir) throws UserException,
-        IOException {
+    static List<String> apmJvmOptions(Settings settings, @Nullable SecureSettings secrets, Path tmpdir) throws UserException, IOException {
         final Path agentJar = findAgentJar();
 
         if (agentJar == null) {
@@ -158,8 +157,8 @@ class APMJvmOptions {
             }
         }
 
-        if (keystore != null) {
-            extractSecureSettings(keystore, propertiesMap);
+        if (secrets != null) {
+            extractSecureSettings(secrets, propertiesMap);
         }
         final Map<String, String> dynamicSettings = extractDynamicSettings(propertiesMap);
 
@@ -180,11 +179,11 @@ class APMJvmOptions {
         return "-javaagent:" + agentJar + "=c=" + tmpPropertiesFile;
     }
 
-    private static void extractSecureSettings(KeyStoreWrapper keystore, Map<String, String> propertiesMap) {
-        final Set<String> settingNames = keystore.getSettingNames();
+    private static void extractSecureSettings(SecureSettings secrets, Map<String, String> propertiesMap) {
+        final Set<String> settingNames = secrets.getSettingNames();
         for (String key : List.of("api_key", "secret_token")) {
             if (settingNames.contains("tracing.apm." + key)) {
-                try (SecureString token = keystore.getString("tracing.apm." + key)) {
+                try (SecureString token = secrets.getString("tracing.apm." + key)) {
                     propertiesMap.put(key, token.toString());
                 }
             }

+ 6 - 6
distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/JvmOptionsParser.java

@@ -11,7 +11,7 @@ package org.elasticsearch.server.cli;
 import org.elasticsearch.bootstrap.ServerArgs;
 import org.elasticsearch.cli.ExitCodes;
 import org.elasticsearch.cli.UserException;
-import org.elasticsearch.common.settings.KeyStoreWrapper;
+import org.elasticsearch.common.settings.SecureSettings;
 
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -70,7 +70,7 @@ final class JvmOptionsParser {
      * files in the {@code jvm.options.d} directory, and the options given by the {@code ES_JAVA_OPTS} environment
      * variable.
      *
-     * @param keystore        the installation's keystore
+     * @param secrets         the installation's secrets
      * @param configDir       the ES config dir
      * @param tmpDir          the directory that should be passed to {@code -Djava.io.tmpdir}
      * @param envOptions      the options passed through the ES_JAVA_OPTS env var
@@ -79,7 +79,7 @@ final class JvmOptionsParser {
      * @throws IOException          if there is a problem reading any of the files
      * @throws UserException        if there is a problem parsing the `jvm.options` file or `jvm.options.d` files
      */
-    static List<String> determineJvmOptions(ServerArgs args, KeyStoreWrapper keystore, Path configDir, Path tmpDir, String envOptions)
+    static List<String> determineJvmOptions(ServerArgs args, SecureSettings secrets, Path configDir, Path tmpDir, String envOptions)
         throws InterruptedException, IOException, UserException {
 
         final JvmOptionsParser parser = new JvmOptionsParser();
@@ -89,7 +89,7 @@ final class JvmOptionsParser {
         substitutions.put("ES_PATH_CONF", configDir.toString());
 
         try {
-            return parser.jvmOptions(args, keystore, configDir, tmpDir, envOptions, substitutions);
+            return parser.jvmOptions(args, secrets, configDir, tmpDir, envOptions, substitutions);
         } catch (final JvmOptionsFileParserException e) {
             final String errorMessage = String.format(
                 Locale.ROOT,
@@ -120,7 +120,7 @@ final class JvmOptionsParser {
 
     private List<String> jvmOptions(
         ServerArgs args,
-        KeyStoreWrapper keystore,
+        SecureSettings secrets,
         final Path config,
         Path tmpDir,
         final String esJavaOpts,
@@ -141,7 +141,7 @@ final class JvmOptionsParser {
         final List<String> ergonomicJvmOptions = JvmErgonomics.choose(substitutedJvmOptions);
         final List<String> systemJvmOptions = SystemJvmOptions.systemJvmOptions();
 
-        final List<String> apmOptions = APMJvmOptions.apmJvmOptions(args.nodeSettings(), keystore, tmpDir);
+        final List<String> apmOptions = APMJvmOptions.apmJvmOptions(args.nodeSettings(), secrets, tmpDir);
 
         final List<String> finalJvmOptions = new ArrayList<>(
             systemJvmOptions.size() + substitutedJvmOptions.size() + ergonomicJvmOptions.size() + apmOptions.size()

+ 2 - 1
distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/ServerCli.java

@@ -23,6 +23,7 @@ import org.elasticsearch.cli.Terminal;
 import org.elasticsearch.cli.UserException;
 import org.elasticsearch.common.cli.EnvironmentAwareCommand;
 import org.elasticsearch.common.settings.KeyStoreWrapper;
+import org.elasticsearch.common.settings.SecureSettings;
 import org.elasticsearch.common.settings.SecureString;
 import org.elasticsearch.env.Environment;
 import org.elasticsearch.monitor.jvm.JvmInfo;
@@ -229,7 +230,7 @@ class ServerCli extends EnvironmentAwareCommand {
     }
 
     // protected to allow tests to override
-    protected ServerProcess startServer(Terminal terminal, ProcessInfo processInfo, ServerArgs args, KeyStoreWrapper keystore)
+    protected ServerProcess startServer(Terminal terminal, ProcessInfo processInfo, ServerArgs args, SecureSettings keystore)
         throws UserException {
         return ServerProcess.start(terminal, processInfo, args, keystore);
     }

+ 10 - 10
distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/ServerProcess.java

@@ -15,7 +15,7 @@ import org.elasticsearch.cli.ProcessInfo;
 import org.elasticsearch.cli.Terminal;
 import org.elasticsearch.cli.UserException;
 import org.elasticsearch.common.io.stream.OutputStreamStreamOutput;
-import org.elasticsearch.common.settings.KeyStoreWrapper;
+import org.elasticsearch.common.settings.SecureSettings;
 import org.elasticsearch.core.IOUtils;
 import org.elasticsearch.core.PathUtils;
 import org.elasticsearch.core.SuppressForbidden;
@@ -37,7 +37,7 @@ import static org.elasticsearch.server.cli.ProcessUtil.nonInterruptible;
 /**
  * A helper to control a {@link Process} running the main Elasticsearch server.
  *
- * <p> The process can be started by calling {@link #start(Terminal, ProcessInfo, ServerArgs, KeyStoreWrapper)}.
+ * <p> The process can be started by calling {@link #start(Terminal, ProcessInfo, ServerArgs, SecureSettings)}.
  * The process is controlled by internally sending arguments and control signals on stdin,
  * and receiving control signals on stderr. The start method does not return until the
  * server is ready to process requests and has exited the bootstrap thread.
@@ -67,7 +67,7 @@ public class ServerProcess {
 
     // this allows mocking the process building by tests
     interface OptionsBuilder {
-        List<String> getJvmOptions(ServerArgs args, KeyStoreWrapper keyStoreWrapper, Path configDir, Path tmpDir, String envOptions)
+        List<String> getJvmOptions(ServerArgs args, SecureSettings secrets, Path configDir, Path tmpDir, String envOptions)
             throws InterruptedException, IOException, UserException;
     }
 
@@ -82,13 +82,13 @@ public class ServerProcess {
      * @param terminal        A terminal to connect the standard inputs and outputs to for the new process.
      * @param processInfo     Info about the current process, for passing through to the subprocess.
      * @param args            Arguments to the server process.
-     * @param keystore        A keystore for accessing secrets.
+     * @param secrets        A secrets for accessing secrets.
      * @return A running server process that is ready for requests
      * @throws UserException If the process failed during bootstrap
      */
-    public static ServerProcess start(Terminal terminal, ProcessInfo processInfo, ServerArgs args, KeyStoreWrapper keystore)
+    public static ServerProcess start(Terminal terminal, ProcessInfo processInfo, ServerArgs args, SecureSettings secrets)
         throws UserException {
-        return start(terminal, processInfo, args, keystore, JvmOptionsParser::determineJvmOptions, ProcessBuilder::start);
+        return start(terminal, processInfo, args, secrets, JvmOptionsParser::determineJvmOptions, ProcessBuilder::start);
     }
 
     // package private so tests can mock options building and process starting
@@ -96,7 +96,7 @@ public class ServerProcess {
         Terminal terminal,
         ProcessInfo processInfo,
         ServerArgs args,
-        KeyStoreWrapper keystore,
+        SecureSettings secrets,
         OptionsBuilder optionsBuilder,
         ProcessStarter processStarter
     ) throws UserException {
@@ -105,7 +105,7 @@ public class ServerProcess {
 
         boolean success = false;
         try {
-            jvmProcess = createProcess(args, keystore, processInfo, args.configDir(), optionsBuilder, processStarter);
+            jvmProcess = createProcess(args, secrets, processInfo, args.configDir(), optionsBuilder, processStarter);
             errorPump = new ErrorPumpThread(terminal.getErrorWriter(), jvmProcess.getErrorStream());
             errorPump.start();
             sendArgs(args, jvmProcess.getOutputStream());
@@ -199,7 +199,7 @@ public class ServerProcess {
 
     private static Process createProcess(
         ServerArgs args,
-        KeyStoreWrapper keystore,
+        SecureSettings secrets,
         ProcessInfo processInfo,
         Path configDir,
         OptionsBuilder optionsBuilder,
@@ -211,7 +211,7 @@ public class ServerProcess {
             envVars.put("LIBFFI_TMPDIR", tempDir.toString());
         }
 
-        List<String> jvmOptions = optionsBuilder.getJvmOptions(args, keystore, configDir, tempDir, envVars.remove("ES_JAVA_OPTS"));
+        List<String> jvmOptions = optionsBuilder.getJvmOptions(args, secrets, configDir, tempDir, envVars.remove("ES_JAVA_OPTS"));
         // also pass through distribution type
         jvmOptions.add("-Des.distribution.type=" + processInfo.sysprops().get("es.distribution.type"));
 

+ 2 - 1
distribution/tools/server-cli/src/test/java/org/elasticsearch/server/cli/ServerCliTests.java

@@ -22,6 +22,7 @@ import org.elasticsearch.cli.Terminal.Verbosity;
 import org.elasticsearch.cli.UserException;
 import org.elasticsearch.common.cli.EnvironmentAwareCommand;
 import org.elasticsearch.common.settings.KeyStoreWrapper;
+import org.elasticsearch.common.settings.SecureSettings;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.env.Environment;
 import org.elasticsearch.monitor.jvm.JvmInfo;
@@ -436,7 +437,7 @@ public class ServerCliTests extends CommandTestCase {
             }
 
             @Override
-            protected ServerProcess startServer(Terminal terminal, ProcessInfo processInfo, ServerArgs args, KeyStoreWrapper keystore) {
+            protected ServerProcess startServer(Terminal terminal, ProcessInfo processInfo, ServerArgs args, SecureSettings secrets) {
                 if (argsValidator != null) {
                     argsValidator.accept(args);
                 }

+ 1 - 1
server/src/main/java/org/elasticsearch/common/settings/SecureSettings.java

@@ -26,7 +26,7 @@ public interface SecureSettings extends Closeable {
     Set<String> getSettingNames();
 
     /** Return a string setting. The {@link SecureString} should be closed once it is used. */
-    SecureString getString(String setting) throws GeneralSecurityException;
+    SecureString getString(String setting);
 
     /** Return a file setting. The {@link InputStream} should be closed once it is used. */
     InputStream getFile(String setting) throws GeneralSecurityException;

+ 1 - 1
server/src/main/java/org/elasticsearch/common/settings/Settings.java

@@ -1503,7 +1503,7 @@ public final class Settings implements ToXContentFragment, Writeable, Diffable<S
         }
 
         @Override
-        public SecureString getString(String setting) throws GeneralSecurityException {
+        public SecureString getString(String setting) {
             return delegate.getString(addPrefix.apply(setting));
         }
 

+ 2 - 2
server/src/main/java/org/elasticsearch/common/settings/StatelessSecureSettings.java

@@ -62,7 +62,7 @@ public class StatelessSecureSettings implements SecureSettings {
     }
 
     @Override
-    public SecureString getString(String setting) throws GeneralSecurityException {
+    public SecureString getString(String setting) {
         return new SecureString(STATELESS_SECURE_SETTINGS.getConcreteSetting(PREFIX + setting).get(settings).toCharArray());
     }
 
@@ -74,7 +74,7 @@ public class StatelessSecureSettings implements SecureSettings {
     }
 
     @Override
-    public byte[] getSHA256Digest(String setting) throws GeneralSecurityException {
+    public byte[] getSHA256Digest(String setting) {
         return MessageDigests.sha256()
             .digest(STATELESS_SECURE_SETTINGS.getConcreteSetting(PREFIX + setting).get(settings).getBytes(StandardCharsets.UTF_8));
     }

+ 1 - 1
x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/notification/NotificationServiceTests.java

@@ -253,7 +253,7 @@ public class NotificationServiceTests extends ESTestCase {
             }
 
             @Override
-            public SecureString getString(String setting) throws GeneralSecurityException {
+            public SecureString getString(String setting) {
                 return new SecureString(secureSettingsMap.get(setting));
             }