Infer KeyStore type from pathname (elastic/x-pack-elasticsearch#2514)
If the keystore type is not explicitly specified, infer it from the filename. Treats .p12, .pfx and .pkcs12 as being PKCS12, all others as jks. This will allow certgen to produce PKCSelastic/x-pack-elasticsearch#12 files by default and make it easy to use them as x-pack keystores Original commit: elastic/x-pack-elasticsearch@fc361f0d87
This commit is contained in:
parent
24c2c62ca2
commit
dea82a07a2
|
@ -180,7 +180,7 @@ public class PkiRealm extends Realm {
|
|||
}
|
||||
try (SecureString password = SSL_SETTINGS.truststorePassword.get(settings)) {
|
||||
String trustStoreAlgorithm = SSL_SETTINGS.truststoreAlgorithm.get(settings);
|
||||
String trustStoreType = SSL_SETTINGS.truststoreType.get(settings);
|
||||
String trustStoreType = SSLConfigurationSettings.getKeyStoreType(SSL_SETTINGS.truststoreType, settings, truststorePath);
|
||||
try {
|
||||
return CertUtils.trustManager(truststorePath, trustStoreType, password.getChars(), trustStoreAlgorithm, realmConfig.env());
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -15,7 +15,6 @@ import org.elasticsearch.xpack.XPackSettings;
|
|||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import java.nio.file.Path;
|
||||
import java.security.KeyStore;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
@ -205,8 +204,8 @@ public final class SSLConfiguration {
|
|||
} else {
|
||||
SecureString keyStorePassword = SETTINGS_PARSER.keystorePassword.get(settings);
|
||||
String keyStoreAlgorithm = SETTINGS_PARSER.keystoreAlgorithm.get(settings);
|
||||
String keyStoreType = SETTINGS_PARSER.keystoreType.get(settings);
|
||||
SecureString keyStoreKeyPassword = SETTINGS_PARSER.keystoreKeyPassword.get(settings);;
|
||||
String keyStoreType = SSLConfigurationSettings.getKeyStoreType(SETTINGS_PARSER.keystoreType, settings, keyStorePath);
|
||||
SecureString keyStoreKeyPassword = SETTINGS_PARSER.keystoreKeyPassword.get(settings);
|
||||
if (keyStoreKeyPassword.length() == 0) {
|
||||
keyStoreKeyPassword = keyStorePassword;
|
||||
}
|
||||
|
@ -244,7 +243,7 @@ public final class SSLConfiguration {
|
|||
} else if (trustStorePath != null) {
|
||||
SecureString trustStorePassword = SETTINGS_PARSER.truststorePassword.get(settings);
|
||||
String trustStoreAlgorithm = SETTINGS_PARSER.truststoreAlgorithm.get(settings);
|
||||
String trustStoreType = SETTINGS_PARSER.truststoreType.get(settings);
|
||||
String trustStoreType = SSLConfigurationSettings.getKeyStoreType(SETTINGS_PARSER.truststoreType, settings, trustStorePath);
|
||||
return new StoreTrustConfig(trustStorePath, trustStoreType, trustStorePassword, trustStoreAlgorithm);
|
||||
} else if (global == null && System.getProperty("javax.net.ssl.trustStore") != null) {
|
||||
try (SecureString truststorePassword = new SecureString(System.getProperty("javax.net.ssl.trustStorePassword", ""))) {
|
||||
|
|
|
@ -7,21 +7,20 @@ package org.elasticsearch.xpack.ssl;
|
|||
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
|
||||
import java.security.KeyStore;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.elasticsearch.common.settings.SecureSetting;
|
||||
import org.elasticsearch.common.settings.SecureString;
|
||||
import org.elasticsearch.common.settings.Setting;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
|
||||
import org.elasticsearch.common.settings.Setting.Property;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
|
||||
/**
|
||||
* Bridges {@link SSLConfiguration} into the {@link Settings} framework, using {@link Setting} objects.
|
||||
|
@ -33,12 +32,12 @@ public class SSLConfigurationSettings {
|
|||
public final Setting<Optional<String>> keystorePath;
|
||||
public final Setting<SecureString> keystorePassword;
|
||||
public final Setting<String> keystoreAlgorithm;
|
||||
public final Setting<String> keystoreType;
|
||||
public final Setting<Optional<String>> keystoreType;
|
||||
public final Setting<SecureString> keystoreKeyPassword;
|
||||
public final Setting<Optional<String>> truststorePath;
|
||||
public final Setting<SecureString> truststorePassword;
|
||||
public final Setting<String> truststoreAlgorithm;
|
||||
public final Setting<String> truststoreType;
|
||||
public final Setting<Optional<String>> truststoreType;
|
||||
public final Setting<Optional<String>> trustRestrictionsPath;
|
||||
public final Setting<Optional<String>> keyPath;
|
||||
public final Setting<SecureString> keyPassword;
|
||||
|
@ -62,6 +61,7 @@ public class SSLConfigurationSettings {
|
|||
* Older versions of X-Pack only supported JKS and never looked at the JVM's configured default.
|
||||
*/
|
||||
private static final String DEFAULT_KEYSTORE_TYPE = "jks";
|
||||
private static final String PKCS12_KEYSTORE_TYPE = "PKCS12";
|
||||
|
||||
private static final Function<String, Setting<List<String>>> CIPHERS_SETTING_TEMPLATE = key -> Setting.listSetting(key, Collections
|
||||
.emptyList(), Function.identity(), Property.NodeScope, Property.Filtered);
|
||||
|
@ -132,14 +132,13 @@ public class SSLConfigurationSettings {
|
|||
public static final Setting<String> TRUST_STORE_ALGORITHM_PROFILES = Setting.affixKeySetting("transport.profiles.",
|
||||
"xpack.security.ssl.truststore.algorithm", TRUST_STORE_ALGORITHM_TEMPLATE);
|
||||
|
||||
private static final Function<String, Setting<String>> KEY_STORE_TYPE_TEMPLATE = key ->
|
||||
new Setting<>(key, DEFAULT_KEYSTORE_TYPE, Function.identity(), Property.NodeScope, Property.Filtered);
|
||||
public static final Setting<String> KEY_STORE_TYPE_PROFILES = Setting.affixKeySetting("transport.profiles.",
|
||||
private static final Function<String, Setting<Optional<String>>> KEY_STORE_TYPE_TEMPLATE = key ->
|
||||
new Setting<>(key, s -> null, Optional::ofNullable, Property.NodeScope, Property.Filtered);
|
||||
public static final Setting<Optional<String>> KEY_STORE_TYPE_PROFILES = Setting.affixKeySetting("transport.profiles.",
|
||||
"xpack.security.ssl.keystore.type", KEY_STORE_TYPE_TEMPLATE);
|
||||
|
||||
private static final Function<String, Setting<String>> TRUST_STORE_TYPE_TEMPLATE = key ->
|
||||
new Setting<>(key, DEFAULT_KEYSTORE_TYPE, Function.identity(), Property.NodeScope, Property.Filtered);
|
||||
public static final Setting<String> TRUST_STORE_TYPE_PROFILES = Setting.affixKeySetting("transport.profiles.",
|
||||
private static final Function<String, Setting<Optional<String>>> TRUST_STORE_TYPE_TEMPLATE = KEY_STORE_TYPE_TEMPLATE;
|
||||
public static final Setting<Optional<String>> TRUST_STORE_TYPE_PROFILES = Setting.affixKeySetting("transport.profiles.",
|
||||
"xpack.security.ssl.truststore.type", TRUST_STORE_TYPE_TEMPLATE);
|
||||
|
||||
private static final Function<String, Setting<Optional<String>>> TRUST_RESTRICTIONS_TEMPLATE = key -> new Setting<>(key, s -> null,
|
||||
|
@ -201,7 +200,7 @@ public class SSLConfigurationSettings {
|
|||
keystoreAlgorithm = KEY_STORE_ALGORITHM_TEMPLATE.apply(prefix + "keystore.algorithm");
|
||||
truststoreAlgorithm = TRUST_STORE_ALGORITHM_TEMPLATE.apply(prefix + "truststore.algorithm");
|
||||
keystoreType = KEY_STORE_TYPE_TEMPLATE.apply(prefix + "keystore.type");
|
||||
truststoreType = KEY_STORE_TYPE_TEMPLATE.apply(prefix + "truststore.type");
|
||||
truststoreType = TRUST_STORE_TYPE_TEMPLATE.apply(prefix + "truststore.type");
|
||||
trustRestrictionsPath = TRUST_RESTRICTIONS_TEMPLATE.apply(prefix + "trust_restrictions.path");
|
||||
keyPath = KEY_PATH_TEMPLATE.apply(prefix + "key");
|
||||
legacyKeyPassword = LEGACY_KEY_PASSWORD_TEMPLATE.apply(prefix + "key_passphrase");
|
||||
|
@ -218,6 +217,19 @@ public class SSLConfigurationSettings {
|
|||
legacyKeystorePassword, legacyKeystoreKeyPassword, legacyKeyPassword, legacyTruststorePassword);
|
||||
}
|
||||
|
||||
public static String getKeyStoreType(Setting<Optional<String>> setting, Settings settings, String path) {
|
||||
return setting.get(settings).orElseGet(() -> inferKeyStoreType(path));
|
||||
}
|
||||
|
||||
private static String inferKeyStoreType(String path) {
|
||||
String name = path == null ? "" : path.toLowerCase(Locale.ROOT);
|
||||
if (name.endsWith(".p12") || name.endsWith(".pfx") || name.endsWith(".pkcs12")) {
|
||||
return PKCS12_KEYSTORE_TYPE;
|
||||
} else {
|
||||
return DEFAULT_KEYSTORE_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Setting<?>> getAllSettings() {
|
||||
return allSettings;
|
||||
}
|
||||
|
|
|
@ -75,17 +75,20 @@ public class SSLConfigurationSettingsTests extends ESTestCase {
|
|||
assertThat(ssl.keyPassword.exists(settings), is(false));
|
||||
assertThat(ssl.keyPath.get(settings).isPresent(), is(false));
|
||||
assertThat(ssl.keystoreAlgorithm.get(settings), is(KeyManagerFactory.getDefaultAlgorithm()));
|
||||
assertThat(ssl.keystoreType.get(settings), is("jks"));
|
||||
assertThat(ssl.keystoreType.get(settings).isPresent(), is(false));
|
||||
assertThat(ssl.keystoreKeyPassword.exists(settings), is(false));
|
||||
assertThat(ssl.keystorePassword.exists(settings), is(false));
|
||||
assertThat(ssl.keystorePath.get(settings).isPresent(), is(false));
|
||||
assertThat(ssl.supportedProtocols.get(settings).size(), is(0));
|
||||
assertThat(ssl.truststoreAlgorithm.get(settings), is(TrustManagerFactory.getDefaultAlgorithm()));
|
||||
assertThat(ssl.truststoreType.get(settings), is("jks"));
|
||||
assertThat(ssl.truststoreType.get(settings).isPresent(), is(false));
|
||||
assertThat(ssl.truststorePassword.exists(settings), is(false));
|
||||
assertThat(ssl.truststorePath.get(settings).isPresent(), is(false));
|
||||
assertThat(ssl.trustRestrictionsPath.get(settings).isPresent(), is(false));
|
||||
assertThat(ssl.verificationMode.get(settings).isPresent(), is(false));
|
||||
|
||||
assertThat(SSLConfigurationSettings.getKeyStoreType(ssl.keystoreType, settings, null), is("jks"));
|
||||
assertThat(SSLConfigurationSettings.getKeyStoreType(ssl.truststoreType, settings, null), is("jks"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,12 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.ssl;
|
||||
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.elasticsearch.common.settings.MockSecureSettings;
|
||||
import org.elasticsearch.common.settings.Setting;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
|
@ -12,17 +18,11 @@ import org.elasticsearch.env.Environment;
|
|||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.xpack.ssl.TrustConfig.CombiningTrustConfig;
|
||||
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.everyItem;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.isIn;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.isIn;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.sameInstance;
|
||||
|
||||
|
@ -58,6 +58,7 @@ public class SSLConfigurationTests extends ESTestCase {
|
|||
|
||||
assertThat(ksKeyInfo.keyStorePath, is(equalTo(path)));
|
||||
assertThat(ksKeyInfo.keyStorePassword, is(equalTo("testnode")));
|
||||
assertThat(ksKeyInfo.keyStoreType, is(equalTo("jks")));
|
||||
assertThat(ksKeyInfo.keyPassword, is(equalTo(ksKeyInfo.keyStorePassword)));
|
||||
assertThat(ksKeyInfo.keyStoreAlgorithm, is(KeyManagerFactory.getDefaultAlgorithm()));
|
||||
assertThat(sslConfiguration.trustConfig(), is(instanceOf(CombiningTrustConfig.class)));
|
||||
|
@ -123,6 +124,66 @@ public class SSLConfigurationTests extends ESTestCase {
|
|||
SSLConfiguration.SETTINGS_PARSER.legacyKeystorePassword, SSLConfiguration.SETTINGS_PARSER.legacyKeystoreKeyPassword});
|
||||
}
|
||||
|
||||
public void testInferKeystoreTypeFromJksFile() {
|
||||
MockSecureSettings secureSettings = new MockSecureSettings();
|
||||
secureSettings.setString("keystore.secure_password", "password");
|
||||
secureSettings.setString("keystore.secure_key_password", "keypass");
|
||||
Settings settings = Settings.builder()
|
||||
.put("keystore.path", "xpack/tls/path.jks")
|
||||
.setSecureSettings(secureSettings)
|
||||
.build();
|
||||
SSLConfiguration sslConfiguration = new SSLConfiguration(settings);
|
||||
assertThat(sslConfiguration.keyConfig(), instanceOf(StoreKeyConfig.class));
|
||||
StoreKeyConfig ksKeyInfo = (StoreKeyConfig) sslConfiguration.keyConfig();
|
||||
assertThat(ksKeyInfo.keyStoreType, is(equalTo("jks")));
|
||||
}
|
||||
|
||||
public void testInferKeystoreTypeFromPkcs12File() {
|
||||
final String ext = randomFrom("p12", "pfx", "pkcs12");
|
||||
MockSecureSettings secureSettings = new MockSecureSettings();
|
||||
secureSettings.setString("keystore.secure_password", "password");
|
||||
secureSettings.setString("keystore.secure_key_password", "keypass");
|
||||
Settings settings = Settings.builder()
|
||||
.put("keystore.path", "xpack/tls/path." + ext)
|
||||
.setSecureSettings(secureSettings)
|
||||
.build();
|
||||
SSLConfiguration sslConfiguration = new SSLConfiguration(settings);
|
||||
assertThat(sslConfiguration.keyConfig(), instanceOf(StoreKeyConfig.class));
|
||||
StoreKeyConfig ksKeyInfo = (StoreKeyConfig) sslConfiguration.keyConfig();
|
||||
assertThat(ksKeyInfo.keyStoreType, is(equalTo("PKCS12")));
|
||||
}
|
||||
|
||||
public void testInferKeystoreTypeFromUnrecognised() {
|
||||
MockSecureSettings secureSettings = new MockSecureSettings();
|
||||
secureSettings.setString("keystore.secure_password", "password");
|
||||
secureSettings.setString("keystore.secure_key_password", "keypass");
|
||||
Settings settings = Settings.builder()
|
||||
.put("keystore.path", "xpack/tls/path.foo")
|
||||
.setSecureSettings(secureSettings)
|
||||
.build();
|
||||
SSLConfiguration sslConfiguration = new SSLConfiguration(settings);
|
||||
assertThat(sslConfiguration.keyConfig(), instanceOf(StoreKeyConfig.class));
|
||||
StoreKeyConfig ksKeyInfo = (StoreKeyConfig) sslConfiguration.keyConfig();
|
||||
assertThat(ksKeyInfo.keyStoreType, is(equalTo("jks")));
|
||||
}
|
||||
|
||||
public void testExplicitKeystoreType() {
|
||||
final String ext = randomFrom("p12", "jks");
|
||||
final String type = randomAlphaOfLengthBetween(2, 8);
|
||||
MockSecureSettings secureSettings = new MockSecureSettings();
|
||||
secureSettings.setString("keystore.secure_password", "password");
|
||||
secureSettings.setString("keystore.secure_key_password", "keypass");
|
||||
Settings settings = Settings.builder()
|
||||
.put("keystore.path", "xpack/tls/path." + ext)
|
||||
.put("keystore.type", type)
|
||||
.setSecureSettings(secureSettings)
|
||||
.build();
|
||||
SSLConfiguration sslConfiguration = new SSLConfiguration(settings);
|
||||
assertThat(sslConfiguration.keyConfig(), instanceOf(StoreKeyConfig.class));
|
||||
StoreKeyConfig ksKeyInfo = (StoreKeyConfig) sslConfiguration.keyConfig();
|
||||
assertThat(ksKeyInfo.keyStoreType, is(equalTo(type)));
|
||||
}
|
||||
|
||||
public void testThatProfileSettingsOverrideServiceSettings() {
|
||||
MockSecureSettings profileSecureSettings = new MockSecureSettings();
|
||||
profileSecureSettings.setString("keystore.secure_password", "password");
|
||||
|
|
Loading…
Reference in New Issue