org.elasticsearch.xpack.core.ssl.X509KeyPairSettings Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of x-pack-core Show documentation
Show all versions of x-pack-core Show documentation
Elasticsearch Expanded Pack Plugin - Core
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.core.ssl;
import org.elasticsearch.common.settings.SecureSetting;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.util.CollectionUtils;
import javax.net.ssl.KeyManagerFactory;
import java.security.KeyStore;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* An encapsulation of the configuration options for X.509 Key Pair support in X-Pack security.
* The most common use is as the private key and associated certificate for SSL/TLS support, but it can also be used for providing
* signing or encryption keys (if they are X.509 based).
* This class supports using a {@link java.security.KeyStore} (with configurable {@link KeyStore#getType() type}) or PEM based files.
*/
public class X509KeyPairSettings {
static final Function>> KEYSTORE_PATH_TEMPLATE = key -> new Setting<>(key, s -> null,
Optional::ofNullable, Setting.Property.NodeScope, Setting.Property.Filtered);
static final Function> LEGACY_KEYSTORE_PASSWORD_TEMPLATE = key -> new Setting<>(key, "",
SecureString::new, Setting.Property.Deprecated, Setting.Property.Filtered, Setting.Property.NodeScope);
static final Function> KEYSTORE_PASSWORD_TEMPLATE = key -> SecureSetting.secureString(key,
LEGACY_KEYSTORE_PASSWORD_TEMPLATE.apply(key.replace("keystore.secure_password", "keystore.password")));
static final Function> KEY_STORE_ALGORITHM_TEMPLATE = key ->
new Setting<>(key, s -> KeyManagerFactory.getDefaultAlgorithm(),
Function.identity(), Setting.Property.NodeScope, Setting.Property.Filtered);
static final Function>> KEY_STORE_TYPE_TEMPLATE = key ->
new Setting<>(key, s -> null, Optional::ofNullable, Setting.Property.NodeScope, Setting.Property.Filtered);
static final Function> LEGACY_KEYSTORE_KEY_PASSWORD_TEMPLATE = key -> new Setting<>(key, "",
SecureString::new, Setting.Property.Deprecated, Setting.Property.Filtered, Setting.Property.NodeScope);
static final Function> KEYSTORE_KEY_PASSWORD_TEMPLATE = key ->
SecureSetting.secureString(key, LEGACY_KEYSTORE_KEY_PASSWORD_TEMPLATE.apply(key.replace("keystore.secure_key_password",
"keystore.key_password")));
static final Function>> KEY_PATH_TEMPLATE = key -> new Setting<>(key, s -> null,
Optional::ofNullable, Setting.Property.NodeScope, Setting.Property.Filtered);
static final Function>> CERT_TEMPLATE = key -> new Setting<>(key, s -> null,
Optional::ofNullable, Setting.Property.NodeScope, Setting.Property.Filtered);
static final Function> LEGACY_KEY_PASSWORD_TEMPLATE = key -> new Setting<>(key, "",
SecureString::new, Setting.Property.Deprecated, Setting.Property.Filtered, Setting.Property.NodeScope);
static final Function> KEY_PASSWORD_TEMPLATE = key ->
SecureSetting.secureString(key, LEGACY_KEY_PASSWORD_TEMPLATE.apply(key.replace("secure_key_passphrase",
"key_passphrase")));
// Specify private cert/key pair via keystore
final Setting> keystorePath;
final Setting keystorePassword;
final Setting keystoreAlgorithm;
final Setting> keystoreType;
final Setting keystoreKeyPassword;
// Specify private cert/key pair via key and certificate files
final Setting> keyPath;
final Setting keyPassword;
final Setting> certificatePath;
// Optional support for legacy (non secure) passwords
// pkg private for tests
final Setting legacyKeystorePassword;
final Setting legacyKeystoreKeyPassword;
final Setting legacyKeyPassword;
private final List> allSettings;
private interface SettingFactory {
Setting apply(String keyPart, Function> template);
}
private X509KeyPairSettings(boolean acceptNonSecurePasswords, SettingFactory factory) {
keystorePath = factory.apply("keystore.path", KEYSTORE_PATH_TEMPLATE);
keystorePassword = factory.apply("keystore.secure_password", KEYSTORE_PASSWORD_TEMPLATE);
keystoreAlgorithm = factory.apply("keystore.algorithm", KEY_STORE_ALGORITHM_TEMPLATE);
keystoreType = factory.apply("keystore.type", KEY_STORE_TYPE_TEMPLATE);
keystoreKeyPassword = factory.apply("keystore.secure_key_password", KEYSTORE_KEY_PASSWORD_TEMPLATE);
keyPath = factory.apply("key", KEY_PATH_TEMPLATE);
keyPassword = factory.apply("secure_key_passphrase", KEY_PASSWORD_TEMPLATE);
certificatePath = factory.apply("certificate", CERT_TEMPLATE);
legacyKeystorePassword = factory.apply("keystore.password", LEGACY_KEYSTORE_PASSWORD_TEMPLATE);
legacyKeystoreKeyPassword = factory.apply("keystore.key_password", LEGACY_KEYSTORE_KEY_PASSWORD_TEMPLATE);
legacyKeyPassword = factory.apply("key_passphrase", LEGACY_KEY_PASSWORD_TEMPLATE);
final List> settings = CollectionUtils.arrayAsArrayList(
keystorePath, keystorePassword, keystoreAlgorithm, keystoreType, keystoreKeyPassword,
keyPath, keyPassword, certificatePath);
if (acceptNonSecurePasswords) {
settings.add(legacyKeystorePassword);
settings.add(legacyKeystoreKeyPassword);
settings.add(legacyKeyPassword);
}
allSettings = Collections.unmodifiableList(settings);
}
public static X509KeyPairSettings withPrefix(String prefix, boolean acceptNonSecurePasswords) {
return new X509KeyPairSettings(acceptNonSecurePasswords, new SettingFactory() {
@Override
public Setting apply(String key, Function> template) {
return template.apply(prefix + key);
}
});
}
public static Collection> affix(String prefix, String suffixPart, boolean acceptNonSecurePasswords) {
final X509KeyPairSettings settings = new X509KeyPairSettings(acceptNonSecurePasswords, new SettingFactory() {
@Override
public Setting apply(String keyPart, Function> template) {
return Setting.affixKeySetting(prefix, suffixPart + keyPart, template);
}
});
return settings.getAllSettings().stream().map(s -> (Setting.AffixSetting) s).collect(Collectors.toList());
}
public Collection> getAllSettings() {
return allSettings;
}
}