From 57d2d76f3d864178fd2d6f3bf5f7f1131cf19155 Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Thu, 30 Jan 2020 16:34:02 +0200 Subject: [PATCH 1/6] Add IDP Configuration settings and related tests --- .../xpack/idp/IdentityProviderPlugin.java | 59 ++++- .../xpack/idp/saml/idp/CloudIdp.java | 115 ++++++++++ .../idp/saml/idp/SamlIdentityProvider.java | 8 + .../plugin-metadata/plugin-security.policy | 2 +- ...ntityProviderPluginConfigurationTests.java | 210 ++++++++++++++++++ .../xpack/idp/saml/idp/README.txt | 24 ++ .../xpack/idp/saml/idp/multi_signing.jks | Bin 0 -> 6640 bytes .../xpack/idp/saml/idp/multi_signing.p12 | Bin 0 -> 7462 bytes .../xpack/idp/saml/idp/signing.p12 | Bin 0 -> 2419 bytes .../xpack/idp/saml/idp/signing1.crt | 17 ++ .../xpack/idp/saml/idp/signing1.key | 28 +++ .../xpack/idp/saml/idp/signing2.crt | 17 ++ .../xpack/idp/saml/idp/signing2.key | 28 +++ .../xpack/idp/saml/idp/signing23.crt | 0 .../xpack/idp/saml/idp/signing3.crt | 17 ++ .../xpack/idp/saml/idp/signing3.key | 28 +++ .../xpack/idp/saml/idp/signing4.crt | 9 + 17 files changed, 559 insertions(+), 3 deletions(-) create mode 100644 x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java create mode 100644 x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/idp/IdentityProviderPluginConfigurationTests.java create mode 100644 x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/README.txt create mode 100644 x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/multi_signing.jks create mode 100644 x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/multi_signing.p12 create mode 100644 x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing.p12 create mode 100644 x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing1.crt create mode 100644 x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing1.key create mode 100644 x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing2.crt create mode 100644 x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing2.key create mode 100644 x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing23.crt create mode 100644 x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing3.crt create mode 100644 x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing3.key create mode 100644 x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing4.crt diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java index 68ae24fd42d2d..99ba5da156bee 100644 --- a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java +++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java @@ -12,6 +12,7 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.env.Environment; import org.elasticsearch.env.NodeEnvironment; @@ -20,9 +21,15 @@ import org.elasticsearch.script.ScriptService; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.watcher.ResourceWatcherService; +import org.elasticsearch.xpack.core.ssl.X509KeyPairSettings; +import org.elasticsearch.xpack.idp.saml.idp.CloudIdp; import org.elasticsearch.xpack.idp.saml.support.SamlInit; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; /** @@ -31,22 +38,70 @@ */ public class IdentityProviderPlugin extends Plugin implements ActionPlugin { - private final Setting ENABLED_SETTING = Setting.boolSetting("xpack.idp.enabled", false, Setting.Property.NodeScope); + private static final Setting ENABLED_SETTING = Setting.boolSetting("xpack.idp.enabled", false, Setting.Property.NodeScope); + public static final Setting IDP_ENTITY_ID = Setting.simpleString("xpack.idp.entity_id"); + public static final Setting IDP_SSO_REDIRECT_ENDPOINT = Setting.simpleString("xpack.idp.sso_endpoint.redirect", value -> { + try { + new URI(value); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Invalid value [" + value + "] for [xpack.idp.sso_endpoint.redirect]. Not a valid URI", e); + } + }); + public static final Setting IDP_SSO_POST_ENDPOINT = Setting.simpleString("xpack.idp.sso_endpoint.post", value -> { + try { + new URI(value); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Invalid value [" + value + "] for [xpack.idp.sso_endpoint.post]. Not a valid URI", e); + } + }); + public static final Setting IDP_SLO_REDIRECT_ENDPOINT = Setting.simpleString("xpack.idp.slo_endpoint.redirect", value -> { + try { + new URI(value); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Invalid value [" + value + "] for [xpack.idp.slo_endpoint.redirect]. Not a valid URI", e); + } + }); + public static final Setting IDP_SLO_POST_ENDPOINT = Setting.simpleString("xpack.idp.slo_endpoint.post", value -> { + try { + new URI(value); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Invalid value [" + value + "] for [xpack.idp.slo_endpoint.post]. Not a valid URI", e); + } + }); + public static final Setting IDP_SIGNING_KEY_ALIAS = Setting.simpleString("xpack.idp.signing.keystore.alias"); private final Logger logger = LogManager.getLogger(); private boolean enabled; + private final Settings settings; + + public IdentityProviderPlugin(Settings settings) { + this.settings = settings; + this.enabled = ENABLED_SETTING.get(settings); + } @Override public Collection createComponents(Client client, ClusterService clusterService, ThreadPool threadPool, ResourceWatcherService resourceWatcherService, ScriptService scriptService, NamedXContentRegistry xContentRegistry, Environment environment, NodeEnvironment nodeEnvironment, NamedWriteableRegistry namedWriteableRegistry) { - enabled = ENABLED_SETTING.get(environment.settings()); if (enabled == false) { return List.of(); } SamlInit.initialize(); + CloudIdp idp = new CloudIdp(environment, settings); return List.of(); } + + @Override + public List> getSettings() { + List> settings = new ArrayList<>(); + settings.add(ENABLED_SETTING); + settings.add(IDP_ENTITY_ID); + settings.add(IDP_SLO_REDIRECT_ENDPOINT); + settings.add(IDP_SLO_POST_ENDPOINT); + settings.add(IDP_SSO_REDIRECT_ENDPOINT); + settings.addAll(X509KeyPairSettings.withPrefix("xpack.idp.signing.", false).getAllSettings()); + return Collections.unmodifiableList(settings); + } } diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java new file mode 100644 index 0000000000000..e731a32789bb1 --- /dev/null +++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java @@ -0,0 +1,115 @@ +package org.elasticsearch.xpack.idp.saml.idp; + +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.settings.SettingsException; +import org.elasticsearch.env.Environment; +import org.elasticsearch.xpack.core.ssl.CertParsingUtils; +import org.elasticsearch.xpack.core.ssl.X509KeyPairSettings; +import org.opensaml.security.x509.X509Credential; +import org.opensaml.security.x509.impl.X509KeyManagerX509CredentialAdapter; + +import javax.net.ssl.X509KeyManager; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import static org.elasticsearch.xpack.idp.IdentityProviderPlugin.IDP_ENTITY_ID; +import static org.elasticsearch.xpack.idp.IdentityProviderPlugin.IDP_SIGNING_KEY_ALIAS; +import static org.elasticsearch.xpack.idp.IdentityProviderPlugin.IDP_SLO_POST_ENDPOINT; +import static org.elasticsearch.xpack.idp.IdentityProviderPlugin.IDP_SLO_REDIRECT_ENDPOINT; +import static org.elasticsearch.xpack.idp.IdentityProviderPlugin.IDP_SSO_POST_ENDPOINT; +import static org.elasticsearch.xpack.idp.IdentityProviderPlugin.IDP_SSO_REDIRECT_ENDPOINT; + +public class CloudIdp implements SamlIdentityProvider { + + private final String entityId; + private final HashMap ssoEndpoints = new HashMap<>(); + private final HashMap sloEndpoints = new HashMap<>(); + private final X509Credential signingCredential; + + public CloudIdp(Environment env, Settings settings) { + this.entityId = require(settings, IDP_ENTITY_ID); + this.ssoEndpoints.put("redirect", require(settings, IDP_SSO_REDIRECT_ENDPOINT)); + this.ssoEndpoints.computeIfAbsent("post", v -> settings.get(IDP_SSO_POST_ENDPOINT.getKey())); + this.sloEndpoints.computeIfAbsent("post", v -> settings.get(IDP_SLO_POST_ENDPOINT.getKey())); + this.sloEndpoints.computeIfAbsent("redirect", v -> settings.get(IDP_SLO_REDIRECT_ENDPOINT.getKey())); + this.signingCredential = buildSigningCredential(env, settings); + } + + @Override + public String getEntityId() { + return entityId; + } + + @Override + public String getSingleSignOnEndpoint(String binding) { + return ssoEndpoints.get(binding); + } + + @Override + public String getSingleLogoutEndpoint(String binding) { + return sloEndpoints.get(binding); + } + + @Override + public X509Credential getSigningCredential() { + return signingCredential; + } + + private static String require(Settings settings, Setting setting) { + if (settings.hasValue(setting.getKey())) { + return setting.get(settings); + } else { + throw new SettingsException("The configuration setting [" + setting.getKey() + "] is required"); + } + } + + static X509Credential buildSigningCredential(Environment env, Settings settings) { + final X509KeyPairSettings keyPairSettings = X509KeyPairSettings.withPrefix("xpack.idp.signing.", false); + final X509KeyManager keyManager = CertParsingUtils.getKeyManager(keyPairSettings, settings, null, env); + if (keyManager == null) { + return null; + } + final Set aliases = new HashSet<>(); + final String configAlias = IDP_SIGNING_KEY_ALIAS.get(settings); + if (Strings.isNullOrEmpty(configAlias)) { + final String[] rsaAliases = keyManager.getServerAliases("RSA", null); + if (null != rsaAliases) { + aliases.addAll(Arrays.asList(rsaAliases)); + } + final String[] ecAliases = keyManager.getServerAliases("EC", null); + if (null != ecAliases) { + aliases.addAll(Arrays.asList(ecAliases)); + } + if (aliases.isEmpty()) { + throw new IllegalArgumentException("The configured keystore for xpack.idp.signing.keystore does not contain any RSA or EC" + + " key pairs"); + } + if (aliases.size() > 1) { + throw new IllegalArgumentException("The configured keystore for xpack.idp.signing.keystore contains multiple key pairs" + + " but no alias has been configured with [" + IDP_SIGNING_KEY_ALIAS.getKey() + "]"); + } + } else { + aliases.add(configAlias); + } + String alias = new ArrayList<>(aliases).get(0); + if (keyManager.getPrivateKey(alias) == null) { + throw new IllegalArgumentException("The configured keystore for xpack.idp.signing.keystore does not have a private key" + + " associated with alias [" + alias + "]"); + } + + final String keyType = keyManager.getPrivateKey(alias).getAlgorithm(); + if (keyType.equals("RSA") == false && keyType.equals("EC") == false) { + throw new IllegalArgumentException("The key associated with alias [" + alias + "] " + "that has been configured with [" + + IDP_SIGNING_KEY_ALIAS.getKey() + "] uses unsupported key algorithm type [" + keyType + + "], only RSA and EC are supported"); + } + return new X509KeyManagerX509CredentialAdapter(keyManager, alias); + } + + +} diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/SamlIdentityProvider.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/SamlIdentityProvider.java index 0031016404b4f..c81548120732a 100644 --- a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/SamlIdentityProvider.java +++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/SamlIdentityProvider.java @@ -7,10 +7,18 @@ package org.elasticsearch.xpack.idp.saml.idp; +import org.opensaml.security.x509.X509Credential; + /** * SAML 2.0 configuration information about this IdP */ public interface SamlIdentityProvider { String getEntityId(); + + String getSingleSignOnEndpoint(String binding); + + String getSingleLogoutEndpoint(String binding); + + X509Credential getSigningCredential(); } diff --git a/x-pack/plugin/identity-provider/src/main/plugin-metadata/plugin-security.policy b/x-pack/plugin/identity-provider/src/main/plugin-metadata/plugin-security.policy index 59d9531554e88..9a106b8226c1f 100644 --- a/x-pack/plugin/identity-provider/src/main/plugin-metadata/plugin-security.policy +++ b/x-pack/plugin/identity-provider/src/main/plugin-metadata/plugin-security.policy @@ -4,7 +4,7 @@ grant { // needed because of SAML (cf. o.e.x.c.s.s.RestorableContextClassLoader) permission java.lang.RuntimePermission "getClassLoader"; permission java.lang.RuntimePermission "setContextClassLoader"; - + // needed during initialization of OpenSAML library where xml security algorithms are registered // see https://github.com/apache/santuario-java/blob/e79f1fe4192de73a975bc7246aee58ed0703343d/src/main/java/org/apache/xml/security/utils/JavaUtils.java#L205-L220 // and https://git.shibboleth.net/view/?p=java-opensaml.git;a=blob;f=opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/signature/impl/SignatureMarshaller.java;hb=db0eaa64210f0e32d359cd6c57bedd57902bf811#l52 diff --git a/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/idp/IdentityProviderPluginConfigurationTests.java b/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/idp/IdentityProviderPluginConfigurationTests.java new file mode 100644 index 0000000000000..5f15846cc5b95 --- /dev/null +++ b/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/idp/IdentityProviderPluginConfigurationTests.java @@ -0,0 +1,210 @@ +package org.elasticsearch.xpack.idp.saml.idp; + +import org.apache.lucene.util.LuceneTestCase; +import org.elasticsearch.common.settings.MockSecureSettings; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.env.Environment; +import org.elasticsearch.env.TestEnvironment; +import org.elasticsearch.xpack.core.ssl.CertParsingUtils; +import org.elasticsearch.xpack.core.ssl.PemUtils; +import org.elasticsearch.xpack.idp.saml.test.IdpSamlTestCase; +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.opensaml.security.x509.X509Credential; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; +import java.util.Collections; + +import static org.elasticsearch.xpack.idp.IdentityProviderPlugin.IDP_ENTITY_ID; +import static org.elasticsearch.xpack.idp.IdentityProviderPlugin.IDP_SLO_POST_ENDPOINT; +import static org.elasticsearch.xpack.idp.IdentityProviderPlugin.IDP_SLO_REDIRECT_ENDPOINT; +import static org.elasticsearch.xpack.idp.IdentityProviderPlugin.IDP_SSO_POST_ENDPOINT; +import static org.elasticsearch.xpack.idp.IdentityProviderPlugin.IDP_SSO_REDIRECT_ENDPOINT; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; + +public class IdentityProviderPluginConfigurationTests extends IdpSamlTestCase { + + public void testAllSettings() { + Settings settings = Settings.builder() + .put("path.home", LuceneTestCase.createTempDir()) + .put(IDP_ENTITY_ID.getKey(), "urn:elastic:cloud:idp") + .put(IDP_SSO_REDIRECT_ENDPOINT.getKey(), "https://idp.org/sso/redirect") + .put(IDP_SSO_POST_ENDPOINT.getKey(), "https://idp.org/sso/post") + .put(IDP_SLO_REDIRECT_ENDPOINT.getKey(), "https://idp.org/slo/redirect") + .put(IDP_SLO_POST_ENDPOINT.getKey(), "https://idp.org/slo/post") + .build(); + final Environment env = TestEnvironment.newEnvironment(settings); + CloudIdp idp = new CloudIdp(env, settings); + Assert.assertThat(idp.getEntityId(), equalTo("urn:elastic:cloud:idp")); + Assert.assertThat(idp.getSingleSignOnEndpoint("redirect"), equalTo("https://idp.org/sso/redirect")); + Assert.assertThat(idp.getSingleSignOnEndpoint("post"), equalTo("https://idp.org/sso/post")); + Assert.assertThat(idp.getSingleLogoutEndpoint("redirect"), equalTo("https://idp.org/slo/redirect")); + Assert.assertThat(idp.getSingleLogoutEndpoint("post"), equalTo("https://idp.org/slo/post")); + } + + public void testInvalidSsoEndpoint() { + Settings settings = Settings.builder() + .put("path.home", LuceneTestCase.createTempDir()) + .put(IDP_ENTITY_ID.getKey(), "urn:elastic:cloud:idp") + .put(IDP_SSO_REDIRECT_ENDPOINT.getKey(), "not a uri") + .build(); + final Environment env = TestEnvironment.newEnvironment(settings); + IllegalArgumentException e = LuceneTestCase.expectThrows(IllegalArgumentException.class, () -> new CloudIdp(env, settings)); + Assert.assertThat(e.getMessage(), Matchers.containsString(IDP_SSO_REDIRECT_ENDPOINT.getKey())); + Assert.assertThat(e.getMessage(), Matchers.containsString("Not a valid URI")); + } + + public void testCreateSigningCredentialFromPemFiles() throws Exception { + Settings.Builder builder = Settings.builder() + .put("path.home", LuceneTestCase.createTempDir()) + .put(IDP_ENTITY_ID.getKey(), "urn:elastic:cloud:idp") + .put(IDP_SSO_REDIRECT_ENDPOINT.getKey(), "https://idp.org/sso/redirect"); + + final Path dir = LuceneTestCase.createTempDir("signing"); + final Path signingKeyPath = getDataPath("signing1.key"); + final Path destSigningKeyPath = dir.resolve("signing1.key"); + final PrivateKey signingKey = PemUtils.readPrivateKey(signingKeyPath, () -> null); + final Path signingCertPath = getDataPath("signing1.crt"); + final Path destSigningCertPath = dir.resolve("signing1.crt"); + final X509Certificate signingCert = CertParsingUtils.readX509Certificates(Collections.singletonList(signingCertPath))[0]; + Files.copy(signingKeyPath, destSigningKeyPath); + Files.copy(signingCertPath, destSigningCertPath); + builder.put("xpack.idp.signing.key", destSigningKeyPath); + builder.put("xpack.idp.signing.certificate", destSigningCertPath); + final Settings settings = builder.build(); + final Environment env = TestEnvironment.newEnvironment(settings); + final X509Credential credential = CloudIdp.buildSigningCredential(env, settings); + + assertThat(credential, notNullValue()); + assertThat(credential.getPrivateKey(), equalTo(signingKey)); + assertThat(credential.getPublicKey(), equalTo(signingCert.getPublicKey())); + } + + public void testCreateSigningCredentialFromΚeystoreWithSingleEntry() throws Exception { + Settings.Builder builder = Settings.builder() + .put("path.home", LuceneTestCase.createTempDir()) + .put(IDP_ENTITY_ID.getKey(), "urn:elastic:cloud:idp") + .put(IDP_SSO_REDIRECT_ENDPOINT.getKey(), "https://idp.org/sso/redirect"); + + final Path dir = LuceneTestCase.createTempDir("signing"); + final Path signingKeyStorePath = getDataPath("signing.p12"); + final Path destSigningKeyStorePath = dir.resolve("signing.p12"); + Files.copy(signingKeyStorePath, destSigningKeyStorePath); + builder.put("xpack.idp.signing.keystore.path", destSigningKeyStorePath); + + final MockSecureSettings secureSettings = new MockSecureSettings(); + secureSettings.setString("xpack.idp.signing.keystore.secure_password", "signing"); + builder.setSecureSettings(secureSettings); + final Settings settings = builder.build(); + final Environment env = TestEnvironment.newEnvironment(settings); + final X509Credential credential = CloudIdp.buildSigningCredential(env, settings); + final Path signingKeyPath = getDataPath("signing1.key"); + final PrivateKey signingKey = PemUtils.readPrivateKey(signingKeyPath, () -> null); + + assertThat(credential, notNullValue()); + assertThat(credential.getPrivateKey(), equalTo(signingKey)); + } + + public void testCreateSigningCredentialFromKeyStoreWithSingleEntryAndConfiguredAlias() throws Exception { + Settings.Builder builder = Settings.builder() + .put("path.home", LuceneTestCase.createTempDir()) + .put(IDP_ENTITY_ID.getKey(), "urn:elastic:cloud:idp") + .put(IDP_SSO_REDIRECT_ENDPOINT.getKey(), "https://idp.org/sso/redirect"); + + final Path dir = LuceneTestCase.createTempDir("signing"); + final Path signingKeyStorePath = getDataPath("signing.p12"); + final Path destSigningKeyStorePath = dir.resolve("signing.p12"); + Files.copy(signingKeyStorePath, destSigningKeyStorePath); + builder.put("xpack.idp.signing.keystore.path", destSigningKeyStorePath); + builder.put("xpack.idp.signing.keystore.alias", "signing1"); + + final MockSecureSettings secureSettings = new MockSecureSettings(); + secureSettings.setString("xpack.idp.signing.keystore.secure_password", "signing"); + builder.setSecureSettings(secureSettings); + final Settings settings = builder.build(); + final Environment env = TestEnvironment.newEnvironment(settings); + final X509Credential credential = CloudIdp.buildSigningCredential(env, settings); + final Path signingKeyPath = getDataPath("signing1.key"); + final PrivateKey signingKey = PemUtils.readPrivateKey(signingKeyPath, () -> null); + + assertThat(credential, notNullValue()); + assertThat(credential.getPrivateKey(), equalTo(signingKey)); + } + + public void testCreateSigningCredentialFromKeyStoreWithSingleEntryButWrongAlias() throws Exception { + Settings.Builder builder = Settings.builder() + .put("path.home", LuceneTestCase.createTempDir()) + .put(IDP_ENTITY_ID.getKey(), "urn:elastic:cloud:idp") + .put(IDP_SSO_REDIRECT_ENDPOINT.getKey(), "https://idp.org/sso/redirect"); + + final Path dir = LuceneTestCase.createTempDir("signing"); + final Path signingKeyStorePath = getDataPath("signing.p12"); + final Path destSigningKeyStorePath = dir.resolve("signing.p12"); + Files.copy(signingKeyStorePath, destSigningKeyStorePath); + builder.put("xpack.idp.signing.keystore.path", destSigningKeyStorePath); + builder.put("xpack.idp.signing.keystore.alias", "some-other"); + + final MockSecureSettings secureSettings = new MockSecureSettings(); + secureSettings.setString("xpack.idp.signing.keystore.secure_password", "signing"); + builder.setSecureSettings(secureSettings); + final Settings settings = builder.build(); + final Environment env = TestEnvironment.newEnvironment(settings); + IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> CloudIdp.buildSigningCredential(env, settings)); + assertThat(e.getMessage(), equalTo("The configured keystore for xpack.idp.signing.keystore does not have a private key associated" + + " with alias [some-other]")); + } + + public void testCreateSigningCredentialFromKeyStoreWithMultipleEntriesAndConfiguredAlias() throws Exception { + Settings.Builder builder = Settings.builder() + .put("path.home", LuceneTestCase.createTempDir()) + .put(IDP_ENTITY_ID.getKey(), "urn:elastic:cloud:idp") + .put(IDP_SSO_REDIRECT_ENDPOINT.getKey(), "https://idp.org/sso/redirect"); + final String ks = randomFrom("multi_signing.jks", "multi_signing.p12"); + final String alias = randomFrom("signing1", "signing2", "signing3", "signing4"); + final Path dir = LuceneTestCase.createTempDir("signing"); + final Path signingKeyStorePath = getDataPath(ks); + final Path destSigningKeyStorePath = dir.resolve(ks); + Files.copy(signingKeyStorePath, destSigningKeyStorePath); + builder.put("xpack.idp.signing.keystore.path", destSigningKeyStorePath); + builder.put("xpack.idp.signing.keystore.alias", alias); + + final MockSecureSettings secureSettings = new MockSecureSettings(); + secureSettings.setString("xpack.idp.signing.keystore.secure_password", "signing"); + builder.setSecureSettings(secureSettings); + final Settings settings = builder.build(); + final Environment env = TestEnvironment.newEnvironment(settings); + final X509Credential credential = CloudIdp.buildSigningCredential(env, settings); + final Path signingKeyPath = getDataPath(alias + ".key"); + final PrivateKey signingKey = PemUtils.readPrivateKey(signingKeyPath, () -> null); + + assertThat(credential, notNullValue()); + assertThat(credential.getPrivateKey(), equalTo(signingKey)); + } + + public void testCreateSigningCredentialFromKeyStoreWithMultipleEntriesButWrongAlias() throws Exception { + Settings.Builder builder = Settings.builder() + .put("path.home", LuceneTestCase.createTempDir()) + .put(IDP_ENTITY_ID.getKey(), "urn:elastic:cloud:idp") + .put(IDP_SSO_REDIRECT_ENDPOINT.getKey(), "https://idp.org/sso/redirect"); + + final Path dir = LuceneTestCase.createTempDir("signing"); + final Path signingKeyStorePath = getDataPath("multi_signing.p12"); + final Path destSigningKeyStorePath = dir.resolve("multi_signing.p12"); + Files.copy(signingKeyStorePath, destSigningKeyStorePath); + builder.put("xpack.idp.signing.keystore.path", destSigningKeyStorePath); + builder.put("xpack.idp.signing.keystore.alias", "some-other"); + + final MockSecureSettings secureSettings = new MockSecureSettings(); + secureSettings.setString("xpack.idp.signing.keystore.secure_password", "signing"); + builder.setSecureSettings(secureSettings); + final Settings settings = builder.build(); + final Environment env = TestEnvironment.newEnvironment(settings); + IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> CloudIdp.buildSigningCredential(env, settings)); + assertThat(e.getMessage(), equalTo("The configured keystore for xpack.idp.signing.keystore does not have a private key associated" + + " with alias [some-other]")); + } +} diff --git a/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/README.txt b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/README.txt new file mode 100644 index 0000000000000..af802e68a2236 --- /dev/null +++ b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/README.txt @@ -0,0 +1,24 @@ +## Create JKS keystore with multiple entries +keytool -genkey -alias signing1 -keyalg RSA -keysize 2048 -keystore multi_signing.jks -storepass signing -dname "CN=saml1-test" + +keytool -genkey -alias signing2 -keyalg RSA -keysize 2048 -keystore multi_signing.jks -storepass signing -dname "CN=saml2-test" + +keytool -genkey -alias signing3 -keyalg RSA -keysize 2048 -keystore multi_signing.jks -storepass signing -dname "CN=saml3-test" + +keytool -genkey -alias signing4 -keyalg EC -keysize 256 -keystore multi_signing.jks -storepass signing -dname "CN=saml4-test" + +## Create a PKCS12 with only signing1 +keytool -importkeystore -srckeystore multi_signing.jks -destkeystore signing.p12 -deststoretype PKCS12 -deststorepass signing -destkeypass signing -alias signing1 + +## Convert the keystore to a PKCS#12 one +keytool -importkeystore -srckeystore multi_signing.jks -destkeystore multi_signing.p12 -deststoretype PKCS12 -deststorepass signing -destkeypass signing + +## Export all keys (openssl pkcs12 doesn't have an `-alias` flag :( ) +openssl pkcs12 -in multi_signing.p12 -nocerts -nodes -out all_keys + +## Copy and paste the private keys files from all_keys into signing{1,2,3,4}.key + +## Export all certificates (openssl pkcs12 doesn't have an `-alias` flag :( ) +openssl pkcs12 -in multi_signing.p12 -nokeys -out all_certs + +## Copy and paste the certificates into signing{1,2,3,4}.crt diff --git a/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/multi_signing.jks b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/multi_signing.jks new file mode 100644 index 0000000000000000000000000000000000000000..6c5d73771197afa5aadf62e9afba59a175dc6530 GIT binary patch literal 6640 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 CU7=b4 literal 0 HcmV?d00001 diff --git a/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/multi_signing.p12 b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/multi_signing.p12 new file mode 100644 index 0000000000000000000000000000000000000000..a08be5d0a7206abd2b5cadbf2b456660983996bb GIT binary patch literal 7462 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 SnMOB%w{8=vJOm1k&HFbeab7$C literal 0 HcmV?d00001 diff --git a/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing1.crt b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing1.crt new file mode 100644 index 0000000000000..fe8e062bb7d6a --- /dev/null +++ b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing1.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIEB3RBlDANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwpz +YW1sMS10ZXN0MB4XDTIwMDEzMDEzMDYxM1oXDTIwMDQyOTEzMDYxM1owFTETMBEG +A1UEAxMKc2FtbDEtdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AN5KCDf5R6ZFhcehDH0o6KMmAq/bVLczjNUcclxb0jFj9qfT1Lp7lYCMlbY0sskq +2LncBIriihaC91OVBWWU1Z6fANxGn83ZPb+wM0h+iSN2IeHPjOP87vd1/oriSJEH +U6MtzVKi5BIDoLx9tMhykSkWuQu05XQvMM6ofUyYtLZt38yUBaG/auO68FN6xtz/ +1RadENMVTfbGhUEPmSv+F/XsMW/MnhW0rXMOoWdmL9pv4vuGI7YUipw3xE30MxYA +rEFfedmJFWhvonVoBg43pIa8cJLr8QX+G+Zgy1g0F8oLndreB0KbnsC8aqQ0z3qc +iIbQMehPTN8cYgujTpGXS7MCAwEAAaMhMB8wHQYDVR0OBBYEFLRsbY+bypAXcmC4 +JzhEDJoidIgVMA0GCSqGSIb3DQEBCwUAA4IBAQC8rd3TQ/MR+SnK0mdBjhkJdZWl +NiDkAuK1hRmreH3hYYBpVg3M51CcEAJIMsCH4RkJY66vjOWnsuPvF2Yxr0/dFI0W +tBg01kZEodtxKvl8klJq3SHg2DqVJsJ8Sfl+lj+MBMvzTfWT4YjHnxjslPu39K5P +tULjaO0pLHckkSSXH+JksUiYQ9enRp5aN/MbUvvHT4R5wd+SeQsThHKhrB3WZk3M +Pn8vmGhsfdUjJNBMEbMMGRJEZmIs/Zdrg0pcGgk+tB0YqYGuiNLwtR0G0AVxeEHI +Qf8IotlIg8mAKx9uHovTH8e3jyTDi+zBO0r3oSwiq43b1MOx88bSOtvATJbm +-----END CERTIFICATE----- diff --git a/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing1.key b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing1.key new file mode 100644 index 0000000000000..29908feeee4ce --- /dev/null +++ b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing1.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDeSgg3+UemRYXH +oQx9KOijJgKv21S3M4zVHHJcW9IxY/an09S6e5WAjJW2NLLJKti53ASK4ooWgvdT +lQVllNWenwDcRp/N2T2/sDNIfokjdiHhz4zj/O73df6K4kiRB1OjLc1SouQSA6C8 +fbTIcpEpFrkLtOV0LzDOqH1MmLS2bd/MlAWhv2rjuvBTesbc/9UWnRDTFU32xoVB +D5kr/hf17DFvzJ4VtK1zDqFnZi/ab+L7hiO2FIqcN8RN9DMWAKxBX3nZiRVob6J1 +aAYON6SGvHCS6/EF/hvmYMtYNBfKC53a3gdCm57AvGqkNM96nIiG0DHoT0zfHGIL +o06Rl0uzAgMBAAECggEAV/2KH04HtKOUfx8a6HhHDj2/lokFkbdQKhOmmTSnkXF2 +c5yAeojs9wOvR364vrS9MWUMT0W5T4vsByPYDQvLO4zJNGioXT1/Gd/PjQS5mFXs +t4wGw0Cd/0qvxZ4pB2+VBeTdf7aG/TJ+b956r1XabB9YhG/I3CLJ+SPs5WMVNZiv +kmHldz/XWaa0zIIodk3eZYUM6B45DpVEE+oU2KpL+as4MiO5EhO5razMZARUwUH/ +D5dx6pWBMrkVtITEOJlUbIrjkPoN2uIVL+DjIXgI4t0pEVI8tP2M18xcb1s9C/2v +wWkZkowaGXYADlvWtWRZSxRv8RAaIt7f+K9UkexRMQKBgQD5PfW5rI+fZr1xlto5 +NP0F8S5nM7Giw+L5DL5hPRhFX3TJR+mloItoIn2wBt5p7viJev1t+eFEITTQ/gnT +3qj/EUFfjl3mCPCv/bGVFyRuKG9z5921BWEhyxQscQW47nahaeTfsVkqjBKuPQym +FIa4d+TlIITdhQgwvKKDwmS+vQKBgQDkUPytZ4u9lEJAhBK37U1Oke2pZNwlwON7 +YJqhUV7rHtAffjHECjjOQFaU9qhUmQo0XMRMeyKjxZyxOBbPlNaDCEvj0pppK+fd +Y70fNraWFKn8Oq8LtxfCJAzjySA8P3DKyyjtMNnONSzZZGAGVburjTv94SbKB933 +9YuQ1NVTLwKBgGqS0tp07eiz7rd+UIt7m+GJklTwprk5V3k0uMctb45iVbaneEGp +F1MMxH+bQEk9tKpcm7cFzQvrwwDGT393yv1d7H0mjAILupcWPHPKtHoh8h42e/em +eDUR9+tU3KSJ2tIETKhV1hG6WVaFpj3xsvV31rkeoZFzC+CDGF6MpbVlAoGBAMZD +6dhvdbMQXyQFTPf5k0tqf7a9BkumoCSQtFboAYQtws/GV1MFCWVaC5XaSD0GlQz5 +jeFYgLE1NqfSrERg3JL3Dmfth/dSkEv5g87qRU447ZBCKaYDvhbyFVttWZfYA4un +NogbBtkB5kt11clKg+kqgXErJvMEN+ZOjX8cw48zAoGAcW4ntY69UNo2XEm+bRTK +Bde4WrlnLVztNckZOj6YbhqYzIkXIm9HRl7oOjPnK/M2D8f2UB8H9J8PEyNrFuis +6MR0eoc4VXuMmi90VYL3yXjUiPYVKjEe1VcA6wDVwudK0v3okVSRjGIp0cJt2OIS +5E+FvmJ79EQcNbRs/fGVyec= +-----END PRIVATE KEY----- diff --git a/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing2.crt b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing2.crt new file mode 100644 index 0000000000000..425bb42a2f487 --- /dev/null +++ b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing2.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIERQXVrDANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwpz +YW1sMi10ZXN0MB4XDTIwMDEzMDEzMDYzMloXDTIwMDQyOTEzMDYzMlowFTETMBEG +A1UEAxMKc2FtbDItdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AK8mo/SqI+RAbq1Q7qDTddnjdqIMcmnCpHcSID2fhgoNrikIT8voWSthgpCpR7Zp +CbVj1LK/RHtF7x9/HnrZr4Us07IESuK89NNKZYA6V5qiK1noctIGa2KIIDp0uVdL +Uv4/UaK6sUe0tex1davFivqR40uHemO0OZb890YtdBft0c0qBoS7eU4fqcwT7Gbv +gxMb7CrNqAsxT7Ax4gYGjWG0BYp+FicmB6A9aAJWIjac9YfABf0DDesazUAYpoAW +FRCVKyGVa+U7HTq4wITGts6OKAbAdaJpbshxk9/TU91SfWqeqG0PyImGbQkbXr2c +cAoylImud3EMUwkWgWfzsBECAwEAAaMhMB8wHQYDVR0OBBYEFPuTo5I6pHRzUZJX +6mbznuriQbpWMA0GCSqGSIb3DQEBCwUAA4IBAQCdWs1cZvttuUJ1GnWjuwY+cJJR +vNNl7D5Ge4zsyQeTzd8x0V4Pl5JVIyVxEP9Hu4+bgOo/daJtBT1y9B4eRfgtPGYO +/3XP1OXJ7zpIIqEUozaCgfLo6L5Qk9DUfb+ikxVNagsC5DvlB+nKblqH3zbrEAPo +tq7hFeow+PTr799U1flRkr9w/+FVJVZIvgKrb0E0BauPyR1+MHOr/XY50Mi6tH+/ +3F8SYRufLvdMSLQ9ZrBBZoQjcrfO1qb7GS364hbpu7TQIsXOHnfsAQsoGBBUrVla +IATAHbog6SxpKT729dcrMVrJ/1inJ8NZuOZpIgJozi1tiuJ56QdOyuji59iU +-----END CERTIFICATE----- diff --git a/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing2.key b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing2.key new file mode 100644 index 0000000000000..8419d4052068e --- /dev/null +++ b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing2.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCvJqP0qiPkQG6t +UO6g03XZ43aiDHJpwqR3EiA9n4YKDa4pCE/L6FkrYYKQqUe2aQm1Y9Syv0R7Re8f +fx562a+FLNOyBErivPTTSmWAOleaoitZ6HLSBmtiiCA6dLlXS1L+P1GiurFHtLXs +dXWrxYr6keNLh3pjtDmW/PdGLXQX7dHNKgaEu3lOH6nME+xm74MTG+wqzagLMU+w +MeIGBo1htAWKfhYnJgegPWgCViI2nPWHwAX9Aw3rGs1AGKaAFhUQlSshlWvlOx06 +uMCExrbOjigGwHWiaW7IcZPf01PdUn1qnqhtD8iJhm0JG169nHAKMpSJrndxDFMJ +FoFn87ARAgMBAAECggEAQjfAmrpMUXoOndXQMdtgXd0CN+euxc9BsIaYy9NosJpV +csvipzuTorP90cU+CHeTpRE2E9H+CQD6k5TSqC1uj1HQQygeS7SWdt9UmnL0NdED +xLz90+t7Y8gFLzR78cXXfangqj4c0fg/I0ORFjzb+zl2jlKM8e7sKuo+bji3AGhX +1Hl6F2yZmdsp+k3qLAiELc0ExBXq4M7SOCOzKE3BnMRtRE5QXieF39+l7g/YtSru +OZI+gdA101ONNxiQa/w0m39wqaZgWex0dHjSztlg3Ja9ZralH1op/Zhhh2txLMf1 +CTlKZOEa/rFMw4YGqVfSX460/W+gXC3h+VBogHY9VQKBgQDZKpV0fVisV8pEbZaj +kLtk1TGXX4gucgt9EOPqjuS4xF8RGGbS+Mk3DQgXWGRU7OE3Pd+SrQ+mqoesHtJK +4Md+cqKx1F0E8Gg2Dr+jWsmbmAWsOxk6cLZJPNTpIRxtBcjzUgawJoVnimz7L38p +4++VqpXZcG5CVvOKQAie7QiIwwKBgQDOeK4loplQF+UWSs7HmkJ0/MeELR7ICvhP +LUo70qppiXZzjgCbfDoT5TLriR8fA+mP+YIjPMmdC9iGY4mK6CxaDYtbcNW64aOW +j50VG7p3grS52yvzFgRX9V4/xJARO4UuYCab+gFLBaWd0LIZL/GbLZVD77Llg+qT +yifkhFV2mwKBgEEAHfvgCMqM/F2+73fFulFT/qPwVDKSsB2fEJkEbDFhlZLoWt6K +2K9Bl0pliqJgxIhkXKbqZeTc5f7+urLu1MdkSI4xoiX4Tzje8T1Tz0RjHE+Q4Nw9 +IFKLgq7E2l1Hff5WbuoKnaOAK16DuOww7WU+ydtra5UvsXWP9QScrhFBAoGAbjs1 +1nf53C31q7IitaQg6O5v4pxoO6rHqRXn9Qpi2td9+vGMV3a6Vxbd2awqhleDYc92 +8DMq/IJvhkgsDZIo46cpiJc0NIL04JQp7DQSmG2a6UMfMrfFd+RS/j6GH/0j/H9u +/YU7HX+VTS03eIUFO7DZaRzW6PxFx8N9Ct6v9hMCgYABNFC7oPj24NwmJHZPXWuN +V+ZRG2dC2E9K+MVg2Az1r+EyXCReBrzj0hYoZ2zS3SBGDD52ktIl6ekWCzEoC0VH +uyg/237P1/Vs1IfuneI2/zq4R6sjeNmSEFsjhMqu1K1nCM4ZiWl6SzZrwo12bFCL +93Lv9ufTBtMUgg154OM2xg== +-----END PRIVATE KEY----- diff --git a/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing23.crt b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing23.crt new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing3.crt b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing3.crt new file mode 100644 index 0000000000000..3dbc9ae0486c6 --- /dev/null +++ b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing3.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIEC9b3+jANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwpz +YW1sMy10ZXN0MB4XDTIwMDEzMDEzMDY0MloXDTIwMDQyOTEzMDY0MlowFTETMBEG +A1UEAxMKc2FtbDMtdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AKHUOCpcF2LYVujyV1OQEOteDFs+vysWfbPu+gdmmQtW4wbK2ZMx7dppbWz9uC3f +asyOqsxmhgGy9fkP/NfmKPPzN9gx+PzaGnu2oqvpAQMndBdIs4pmHn8ZlhNaHJvs +1cTJfEMacQPNwFxjxkavl4dfnYDKRdxD0RFpfdHlFyM48P7emJqEUASx419/cRSh +UoP6WUL1SInGkUDP0Zu8NR46Zk8XboeCKvTxPyOzMsDBZP726upAWQmmtYGpifra +ScyDp/YkeDn6gWuSkThfGZI7x4E/H2/qlwJXeU9vIonauZYvIFGpjWD0Xw8iojSO +2nkPutfvOOeb2Dvbxz1ANJsCAwEAAaMhMB8wHQYDVR0OBBYEFLlybUTvk1Yh5L55 +xhRWVN+i0D+/MA0GCSqGSIb3DQEBCwUAA4IBAQAv9l5udI0iSQmLPnRf876lczZG +dylwrMv1zduThOTQ2hok1vf+D2Bi1U8mFl/T2WIM+2JlELi9yJDcFKh85AKvkRxG +LY4CfKiOXEBpOrVETpNA2oEdh4HHsokKSt6mMe5GbUN+YdDYHNkmgTg01O7SIL4C +9Et0GJlZ59uXTC9Z6RK27qdGm3zvCWQezOdE88Q1hWr0vjlPEDk9bQFiLJvCkAEo +1vKjT3/NWJBK1mG7Z14YxFe1h28bHOCGruW84+sL4WLzJsSRXzEIJBJXpi0COdSg +LrTkx482oen6U/IaZ6IDuQDhex/AhLhjsDsr/cJ2zkfD2d+P+ZQm2XIa96RE +-----END CERTIFICATE----- diff --git a/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing3.key b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing3.key new file mode 100644 index 0000000000000..74cdc8cf9dd30 --- /dev/null +++ b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing3.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCh1DgqXBdi2Fbo +8ldTkBDrXgxbPr8rFn2z7voHZpkLVuMGytmTMe3aaW1s/bgt32rMjqrMZoYBsvX5 +D/zX5ijz8zfYMfj82hp7tqKr6QEDJ3QXSLOKZh5/GZYTWhyb7NXEyXxDGnEDzcBc +Y8ZGr5eHX52AykXcQ9ERaX3R5RcjOPD+3piahFAEseNff3EUoVKD+llC9UiJxpFA +z9GbvDUeOmZPF26Hgir08T8jszLAwWT+9urqQFkJprWBqYn62knMg6f2JHg5+oFr +kpE4XxmSO8eBPx9v6pcCV3lPbyKJ2rmWLyBRqY1g9F8PIqI0jtp5D7rX7zjnm9g7 +28c9QDSbAgMBAAECggEAG43+DkBl/v+lNL7m3aSfLORzqCmz9Us8FiIv0ojGsGaX ++3UYvPZ4cIMZDcDZ1n2/OptkO6+NS8bEGSd+vuhCut8D+DzyD2O3tK7xXeIruPTD +0J8hawReVvftVNg4HNijwYEpNmfPLH2hLloSzcBiRbujHuXSJWIqvBNBSDcAzI9E +GjxNHNUT39OiRrwkWFWEP+GdytC1QN34/FVY3IHuqytIMAu49b7ejTDi5PWKjHdt +7XjIwaFDQfxFihB3UxvifSZIosvc7nsQ6AZdIewmTHcmj3yRZoOWlh1UayeaCAu7 +6funIIpK0WqL6yaqDtB0X+Fc5nGiyxpNtO5ZytdPcQKBgQDy+QnUboC7LRQwiM1g +Wk2pXzXMQ68Bt50Ta6a4klOnNfeTcklfmOgmuneCdXfEIQUER9Jy0e2jappZDVY/ +S7XEHfKZAld5b9j71xUr/J+RxgD20EVWALM07zBiHiinPOcAKpuWY0y0uVWumO5o +blNtwlGAIwZLyjLcb+0RLDY/CQKBgQCqgW26zxM75tZWff7e0enXxhfEBeSdXVc3 +cTirnGWdI0ooGq3fLkpEL9gACg40GdoZtwLsiN8uN5JZJKaVAA0byO5jSDZwXPol +XOW0guex/s37XsB1ps2Nq3XzL85+y7UG8dxUFXe5n0LNa51iDEhWEDJRAofD32vD +iiLRHBgbgwKBgQDys8EV6au9TLI2KPC9pnadEPX0LEfMN1U36PiIteHJzSaYqjiQ +vXRn+ysVrbEMwM76D6Qv/XKbIgk7mw7j+wR9+kwyexxVuVvNdHM5lQbv3hFoeXJJ +Djn0TljOKcICC9vTVrxD5LziaZ8k4K6Esm+z2779d/76Bef4OfVcigVFwQKBgBMV +T1m0KXvv1xdxHKCFr/11b12CJ1cxhjxvUJ9sbrcKpxcb/U/YV3mQPUWr2nEcX5u3 +Lv2YSBpdH+UYRAizK8RrVbsI7wbecSTTY+YzLIlwck9rCHFijOkJQrdIJ31rgURY +t4c1q+O7nndtTv0VUNdJEsicVuOmUuJcyI7M7SnPAoGBAJhlAT+xRSolWcvNgdVH +g20Wvu6o0uHpYNsp75Ogk2uwufK+lXQx5zPG7NBAd8s50nsAzvuONVLJvNwu9gg1 +xQ+ytfhazZgfUrUXhtLu2qOxN8bRGk8aKve8UQ9sRsMKKGvoPEuHVDm74Eh+x32D +jdX6Jzav+5DL3/JvSGFGS6L/ +-----END PRIVATE KEY----- diff --git a/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing4.crt b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing4.crt new file mode 100644 index 0000000000000..53d1f356d2456 --- /dev/null +++ b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing4.crt @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBPzCB5aADAgECAgRijs0GMAwGCCqGSM49BAMCBQAwFTETMBEGA1UEAxMKc2Ft +bDQtdGVzdDAeFw0yMDAxMzAxMzU5MDFaFw0yMDA0MjkxMzU5MDFaMBUxEzARBgNV +BAMTCnNhbWw0LXRlc3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT5gZs/zPxN +8Ch2aEYMchapSxcMrGYVqtVBO4gIV2ZwYsFhq/mM3+DvenY/9xLwkMHdWx6E8eQG +gWFcsjPJcQ1CoyEwHzAdBgNVHQ4EFgQUrrGtOyJFw4hhgcdZIke00/BU9OIwDAYI +KoZIzj0EAwIFAANHADBEAiB+PMEby4C9HNPI0vhQetJhzMFBYg1CXNBCwy/uHFHf +qAIgTNPpG8hjuOWx7qAy6CSg5CPmO0huRm2sP5gLx68HLOo= +-----END CERTIFICATE----- From fcb2e8c28112e00dae8cb5a29d919a2772ba17ab Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Thu, 30 Jan 2020 16:40:33 +0200 Subject: [PATCH 2/6] license and missing conf --- .../org/elasticsearch/xpack/idp/IdentityProviderPlugin.java | 1 + .../java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java | 6 ++++++ .../saml/idp/IdentityProviderPluginConfigurationTests.java | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java index 99ba5da156bee..04a20df8d29bd 100644 --- a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java +++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java @@ -101,6 +101,7 @@ public List> getSettings() { settings.add(IDP_SLO_REDIRECT_ENDPOINT); settings.add(IDP_SLO_POST_ENDPOINT); settings.add(IDP_SSO_REDIRECT_ENDPOINT); + settings.add(IDP_SSO_POST_ENDPOINT); settings.addAll(X509KeyPairSettings.withPrefix("xpack.idp.signing.", false).getAllSettings()); return Collections.unmodifiableList(settings); } diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java index e731a32789bb1..a1afc01e8be4b 100644 --- a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java +++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java @@ -1,3 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + package org.elasticsearch.xpack.idp.saml.idp; import org.elasticsearch.common.Strings; diff --git a/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/idp/IdentityProviderPluginConfigurationTests.java b/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/idp/IdentityProviderPluginConfigurationTests.java index 5f15846cc5b95..5ffbf92b204f3 100644 --- a/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/idp/IdentityProviderPluginConfigurationTests.java +++ b/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/idp/IdentityProviderPluginConfigurationTests.java @@ -1,3 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + package org.elasticsearch.xpack.idp.saml.idp; import org.apache.lucene.util.LuceneTestCase; From db7cb6719c4d60050183e5fc3ab0446228e837cf Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Thu, 30 Jan 2020 16:51:40 +0200 Subject: [PATCH 3/6] Add scope to settings --- .../xpack/idp/IdentityProviderPlugin.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java index 04a20df8d29bd..f002344bddc03 100644 --- a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java +++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java @@ -39,36 +39,37 @@ public class IdentityProviderPlugin extends Plugin implements ActionPlugin { private static final Setting ENABLED_SETTING = Setting.boolSetting("xpack.idp.enabled", false, Setting.Property.NodeScope); - public static final Setting IDP_ENTITY_ID = Setting.simpleString("xpack.idp.entity_id"); + public static final Setting IDP_ENTITY_ID = Setting.simpleString("xpack.idp.entity_id", Setting.Property.NodeScope); public static final Setting IDP_SSO_REDIRECT_ENDPOINT = Setting.simpleString("xpack.idp.sso_endpoint.redirect", value -> { try { new URI(value); } catch (URISyntaxException e) { throw new IllegalArgumentException("Invalid value [" + value + "] for [xpack.idp.sso_endpoint.redirect]. Not a valid URI", e); } - }); + }, Setting.Property.NodeScope); public static final Setting IDP_SSO_POST_ENDPOINT = Setting.simpleString("xpack.idp.sso_endpoint.post", value -> { try { new URI(value); } catch (URISyntaxException e) { throw new IllegalArgumentException("Invalid value [" + value + "] for [xpack.idp.sso_endpoint.post]. Not a valid URI", e); } - }); + }, Setting.Property.NodeScope); public static final Setting IDP_SLO_REDIRECT_ENDPOINT = Setting.simpleString("xpack.idp.slo_endpoint.redirect", value -> { try { new URI(value); } catch (URISyntaxException e) { throw new IllegalArgumentException("Invalid value [" + value + "] for [xpack.idp.slo_endpoint.redirect]. Not a valid URI", e); } - }); + }, Setting.Property.NodeScope); public static final Setting IDP_SLO_POST_ENDPOINT = Setting.simpleString("xpack.idp.slo_endpoint.post", value -> { try { new URI(value); } catch (URISyntaxException e) { throw new IllegalArgumentException("Invalid value [" + value + "] for [xpack.idp.slo_endpoint.post]. Not a valid URI", e); } - }); - public static final Setting IDP_SIGNING_KEY_ALIAS = Setting.simpleString("xpack.idp.signing.keystore.alias"); + }, Setting.Property.NodeScope); + public static final Setting IDP_SIGNING_KEY_ALIAS = Setting.simpleString("xpack.idp.signing.keystore.alias", + Setting.Property.NodeScope); private final Logger logger = LogManager.getLogger(); private boolean enabled; From 8ed79cbab0a48778566813e4776750ae6cc5b031 Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Fri, 31 Jan 2020 07:28:14 +0200 Subject: [PATCH 4/6] address feedback --- .../xpack/idp/IdentityProviderPlugin.java | 8 ++---- .../xpack/idp/saml/idp/CloudIdp.java | 26 +++++++++++-------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java index f002344bddc03..d592652e08480 100644 --- a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java +++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java @@ -73,18 +73,14 @@ public class IdentityProviderPlugin extends Plugin implements ActionPlugin { private final Logger logger = LogManager.getLogger(); private boolean enabled; - private final Settings settings; - - public IdentityProviderPlugin(Settings settings) { - this.settings = settings; - this.enabled = ENABLED_SETTING.get(settings); - } @Override public Collection createComponents(Client client, ClusterService clusterService, ThreadPool threadPool, ResourceWatcherService resourceWatcherService, ScriptService scriptService, NamedXContentRegistry xContentRegistry, Environment environment, NodeEnvironment nodeEnvironment, NamedWriteableRegistry namedWriteableRegistry) { + final Settings settings = environment.settings(); + enabled = ENABLED_SETTING.get(settings); if (enabled == false) { return List.of(); } diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java index a1afc01e8be4b..4f446cdf43524 100644 --- a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java +++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java @@ -10,6 +10,7 @@ import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; +import org.elasticsearch.common.util.iterable.Iterables; import org.elasticsearch.env.Environment; import org.elasticsearch.xpack.core.ssl.CertParsingUtils; import org.elasticsearch.xpack.core.ssl.X509KeyPairSettings; @@ -17,7 +18,7 @@ import org.opensaml.security.x509.impl.X509KeyManagerX509CredentialAdapter; import javax.net.ssl.X509KeyManager; -import java.util.ArrayList; +import java.security.PrivateKey; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -80,9 +81,11 @@ static X509Credential buildSigningCredential(Environment env, Settings settings) if (keyManager == null) { return null; } - final Set aliases = new HashSet<>(); + + final String selectedAlias; final String configAlias = IDP_SIGNING_KEY_ALIAS.get(settings); if (Strings.isNullOrEmpty(configAlias)) { + final Set aliases = new HashSet<>(); final String[] rsaAliases = keyManager.getServerAliases("RSA", null); if (null != rsaAliases) { aliases.addAll(Arrays.asList(rsaAliases)); @@ -92,29 +95,30 @@ static X509Credential buildSigningCredential(Environment env, Settings settings) aliases.addAll(Arrays.asList(ecAliases)); } if (aliases.isEmpty()) { - throw new IllegalArgumentException("The configured keystore for xpack.idp.signing.keystore does not contain any RSA or EC" + - " key pairs"); + throw new IllegalArgumentException( + "The configured keystore for xpack.idp.signing.keystore does not contain any RSA or EC key pairs"); } if (aliases.size() > 1) { throw new IllegalArgumentException("The configured keystore for xpack.idp.signing.keystore contains multiple key pairs" + " but no alias has been configured with [" + IDP_SIGNING_KEY_ALIAS.getKey() + "]"); } + selectedAlias = Iterables.get(aliases, 0); } else { - aliases.add(configAlias); + selectedAlias = configAlias; } - String alias = new ArrayList<>(aliases).get(0); - if (keyManager.getPrivateKey(alias) == null) { + final PrivateKey signingKey = keyManager.getPrivateKey(selectedAlias); + if (signingKey == null) { throw new IllegalArgumentException("The configured keystore for xpack.idp.signing.keystore does not have a private key" + - " associated with alias [" + alias + "]"); + " associated with alias [" + selectedAlias + "]"); } - final String keyType = keyManager.getPrivateKey(alias).getAlgorithm(); + final String keyType = signingKey.getAlgorithm(); if (keyType.equals("RSA") == false && keyType.equals("EC") == false) { - throw new IllegalArgumentException("The key associated with alias [" + alias + "] " + "that has been configured with [" + throw new IllegalArgumentException("The key associated with alias [" + selectedAlias + "] " + "that has been configured with [" + IDP_SIGNING_KEY_ALIAS.getKey() + "] uses unsupported key algorithm type [" + keyType + "], only RSA and EC are supported"); } - return new X509KeyManagerX509CredentialAdapter(keyManager, alias); + return new X509KeyManagerX509CredentialAdapter(keyManager, selectedAlias); } From a4136c7166685413ee1f9032c301310039e41ee4 Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Fri, 31 Jan 2020 12:01:49 +0200 Subject: [PATCH 5/6] add missing file --- .../org/elasticsearch/xpack/idp/saml/idp/signing23.crt | 0 .../org/elasticsearch/xpack/idp/saml/idp/signing4.key | 4 ++++ 2 files changed, 4 insertions(+) delete mode 100644 x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing23.crt create mode 100644 x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing4.key diff --git a/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing23.crt b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing23.crt deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing4.key b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing4.key new file mode 100644 index 0000000000000..bf569cb418626 --- /dev/null +++ b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing4.key @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY----- +MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCDpKTGa+t0VcDav3WQ5 +ahJDxbmeCgjdZ/hhogVGE9GgyA== +-----END PRIVATE KEY----- From 5252c8bd7e4462999cc4fe82589c8fbb7aa7c730 Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Mon, 3 Feb 2020 11:06:54 +0200 Subject: [PATCH 6/6] address feedback --- .../elasticsearch/xpack/idp/saml/idp/CloudIdp.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java index 4f446cdf43524..a2ae1610ef90b 100644 --- a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java +++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java @@ -41,9 +41,15 @@ public class CloudIdp implements SamlIdentityProvider { public CloudIdp(Environment env, Settings settings) { this.entityId = require(settings, IDP_ENTITY_ID); this.ssoEndpoints.put("redirect", require(settings, IDP_SSO_REDIRECT_ENDPOINT)); - this.ssoEndpoints.computeIfAbsent("post", v -> settings.get(IDP_SSO_POST_ENDPOINT.getKey())); - this.sloEndpoints.computeIfAbsent("post", v -> settings.get(IDP_SLO_POST_ENDPOINT.getKey())); - this.sloEndpoints.computeIfAbsent("redirect", v -> settings.get(IDP_SLO_REDIRECT_ENDPOINT.getKey())); + if (settings.hasValue(IDP_SSO_POST_ENDPOINT.getKey())) { + this.ssoEndpoints.put("post", settings.get(IDP_SSO_POST_ENDPOINT.getKey())); + } + if (settings.hasValue(IDP_SLO_POST_ENDPOINT.getKey())) { + this.sloEndpoints.put("post", settings.get(IDP_SLO_POST_ENDPOINT.getKey())); + } + if (settings.hasValue(IDP_SLO_REDIRECT_ENDPOINT.getKey())) { + this.sloEndpoints.put("redirect", settings.get(IDP_SLO_REDIRECT_ENDPOINT.getKey())); + } this.signingCredential = buildSigningCredential(env, settings); }