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..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 @@ -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,7 +38,38 @@ */ 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", 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); + } + }, 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; @@ -41,12 +79,27 @@ public Collection createComponents(Client client, ClusterService cluster ResourceWatcherService resourceWatcherService, ScriptService scriptService, NamedXContentRegistry xContentRegistry, Environment environment, NodeEnvironment nodeEnvironment, NamedWriteableRegistry namedWriteableRegistry) { - enabled = ENABLED_SETTING.get(environment.settings()); + final Settings settings = environment.settings(); + enabled = ENABLED_SETTING.get(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.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 new file mode 100644 index 0000000000000..a2ae1610ef90b --- /dev/null +++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/CloudIdp.java @@ -0,0 +1,131 @@ +/* + * 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; +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; +import org.opensaml.security.x509.X509Credential; +import org.opensaml.security.x509.impl.X509KeyManagerX509CredentialAdapter; + +import javax.net.ssl.X509KeyManager; +import java.security.PrivateKey; +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)); + 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); + } + + @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 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)); + } + 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() + "]"); + } + selectedAlias = Iterables.get(aliases, 0); + } else { + selectedAlias = configAlias; + } + 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 [" + selectedAlias + "]"); + } + + final String keyType = signingKey.getAlgorithm(); + if (keyType.equals("RSA") == false && keyType.equals("EC") == false) { + 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, selectedAlias); + } + + +} 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..5ffbf92b204f3 --- /dev/null +++ b/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/idp/IdentityProviderPluginConfigurationTests.java @@ -0,0 +1,216 @@ +/* + * 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; +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 0000000000000..6c5d73771197a Binary files /dev/null and b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/multi_signing.jks differ 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 0000000000000..a08be5d0a7206 Binary files /dev/null and b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/multi_signing.p12 differ diff --git a/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing.p12 b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing.p12 new file mode 100644 index 0000000000000..5e8f06d3d616a Binary files /dev/null and b/x-pack/plugin/identity-provider/src/test/resources/org/elasticsearch/xpack/idp/saml/idp/signing.p12 differ 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/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----- 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-----