[java-shib-metadata] branch main updated: Move security namespace parsers back up into metadata Spring module.
Scott Cantor
cantor.2 at osu.edu
Fri Jul 1 18:42:34 UTC 2022
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-shib-metadata.
View the commit online:
http://git.shibboleth.net/view/?p=java-shib-metadata.git;a=commit;h=111574a41fedb1bfd41c22da8ac12bbbd3d1c7ae
The following commit(s) were added to refs/heads/main by this push:
new 111574a41 Move security namespace parsers back up into metadata Spring module.
111574a41 is described below
commit 111574a41fedb1bfd41c22da8ac12bbbd3d1c7ae
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Fri Jul 1 14:42:31 2022 -0400
Move security namespace parsers back up into metadata Spring module.
---
.../spring/security/SecurityNamespaceHandler.java | 88 +++
.../credential/AbstractBasicCredentialParser.java | 163 ++++++
.../credential/AbstractCredentialParser.java | 94 ++++
.../credential/AbstractX509CredentialParser.java | 141 +++++
.../credential/BasicInlineCredentialParser.java | 39 ++
.../credential/BasicResourceCredentialParser.java | 40 ++
.../credential/X509InlineCredentialParser.java | 38 ++
.../credential/X509ResourceCredentialParser.java | 40 ++
.../spring/security/credential/package-info.java | 22 +
.../shibboleth/spring/security/package-info.java | 22 +
.../security/trust/AbstractChainingParser.java | 61 ++
.../trust/AbstractPKIXValidationInfoParser.java | 78 +++
.../security/trust/AbstractStaticPKIXParser.java | 154 ++++++
.../security/trust/AbstractTrustEngineParser.java | 44 ++
.../trust/CertPathPKIXValidationOptionsParser.java | 89 +++
.../spring/security/trust/ChainingParser.java | 39 ++
.../trust/PKIXInlineValidationInfoParser.java | 44 ++
.../trust/PKIXResourceValidationInfoParser.java | 45 ++
.../trust/PKIXValidationOptionsParser.java | 77 +++
.../security/trust/SignatureChainingParser.java | 40 ++
.../security/trust/StaticExplicitKeyParser.java | 62 +++
.../trust/StaticExplicitKeySignatureParser.java | 66 +++
.../security/trust/StaticPKIXSignatureParser.java | 67 +++
.../trust/StaticPKIXX509CredentialParser.java | 63 +++
.../spring/security/trust/package-info.java | 22 +
.../src/main/resources/META-INF/spring.handlers | 1 +
.../src/main/resources/META-INF/spring.schemas | 5 +
.../main/resources/schema/shibboleth-security.xsd | 612 +++++++++++++++++++++
.../security/AbstractSecurityParserTest.java | 97 ++++
.../security/credential/BasicInlineParserTest.java | 71 +++
.../credential/BasicResourceParserTest.java | 80 +++
.../credential/X509FilesystemParserTest.java | 88 +++
.../security/credential/X509InlineParserTest.java | 62 +++
.../security/trust/ChainingTrustEngineTest.java | 50 ++
.../spring/security/trust/MockTrustEngine.java | 44 ++
.../security/trust/PKIXFilesystemParserTest.java | 52 ++
.../security/trust/PKIXInlineParserTest.java | 53 ++
.../trust/PKIXValidationOptionsParserTest.java | 53 ++
.../trust/SignatureChainingParserTest.java | 56 ++
.../trust/StaticExplicitKeyParserTest.java | 52 ++
.../StaticExplicitKeySignatureParserTest.java | 52 ++
.../trust/StaticPKIXSignatureParserTest.java | 163 ++++++
.../trust/StaticPKIXX509CredentialParserTest.java | 116 ++++
.../spring/security/credential/aes-base64.txt | 1 +
.../spring/security/credential/aes-binary.data | 1 +
.../spring/security/credential/aes-hex.txt | 1 +
.../shibboleth/spring/security/credential/cert.pem | 22 +
.../spring/security/credential/certificate.pem | 52 ++
.../shibboleth/spring/security/credential/crl.pem | 19 +
.../spring/security/credential/inlineCertOnly.xml | 30 +
.../security/credential/inlineKeyCertCrl.xml | 128 +++++
.../security/credential/inlinePublicOnly.xml | 17 +
.../security/credential/inlinePublicPrivate.xml | 48 ++
.../spring/security/credential/inlineWrongCert.xml | 87 +++
.../shibboleth/spring/security/credential/key.pem | 27 +
.../spring/security/credential/publicKey.pem | 9 +
.../spring/security/credential/resourceBasic.xml | 8 +
.../credential/resourceCertElementsKeyName.xml | 10 +
.../security/credential/resourceCertOnly.xml | 8 +
.../security/credential/resourceKeyCertCrl.xml | 11 +
.../security/credential/resourcePublicOnly.xml | 9 +
.../security/credential/resourcePublicPrivate.xml | 9 +
.../credential/resourceSecretAESBase64.xml | 9 +
.../credential/resourceSecretAESBinary.xml | 9 +
.../security/credential/resourceSecretAESHex.xml | 9 +
.../spring/security/credential/resourceTwoCert.xml | 8 +
.../security/credential/resourceWrongCert.xml | 9 +
.../security/credential/resourceWrongPublic.xml | 9 +
.../spring/security/credential/resourceX509.xml | 8 +
.../security/credential/secretKeyAESBase64.xml | 11 +
.../spring/security/credential/secretKeyAESHex.xml | 11 +
.../spring/security/credential/wrongPublicKey.pem | 6 +
.../net/shibboleth/spring/security/trust/cert.pem | 22 +
.../net/shibboleth/spring/security/trust/chain.xml | 41 ++
.../spring/security/trust/chainingTrue.xml | 17 +
.../spring/security/trust/chainingTrueFalse.xml | 21 +
.../net/shibboleth/spring/security/trust/crl.pem | 19 +
.../spring/security/trust/inlineValidationInfo.xml | 5 +
.../security/trust/inlineValidationInfoValues.xml | 77 +++
.../security/trust/resourceValidationInfo.xml | 5 +
.../trust/resourceValidationInfoValues.xml | 10 +
.../spring/security/trust/staticExplicit.xml | 30 +
.../security/trust/staticExplicitSignature.xml | 30 +
.../trust/staticPKIX-nameCheckDisabled.xml | 8 +
.../spring/security/trust/staticPKIX.xml | 8 +
.../staticPKIXCredentials-nameCheckDisabled.xml | 18 +
.../security/trust/staticPKIXCredentials.xml | 19 +
.../spring/security/trust/staticPKIXValues.xml | 16 +
.../trust/staticPKIXValuesCertPathOpts.xml | 19 +
.../spring/security/trust/validationOptions.xml | 5 +
.../security/trust/validationOptionsValues.xml | 7 +
91 files changed, 4308 insertions(+)
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/SecurityNamespaceHandler.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/SecurityNamespaceHandler.java
new file mode 100644
index 000000000..9d727e858
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/SecurityNamespaceHandler.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security;
+
+import javax.annotation.Nonnull;
+import javax.xml.namespace.QName;
+
+import net.shibboleth.ext.spring.util.BaseSpringNamespaceHandler;
+import net.shibboleth.spring.security.credential.BasicInlineCredentialParser;
+import net.shibboleth.spring.security.credential.BasicResourceCredentialParser;
+import net.shibboleth.spring.security.credential.X509InlineCredentialParser;
+import net.shibboleth.spring.security.credential.X509ResourceCredentialParser;
+import net.shibboleth.spring.security.trust.CertPathPKIXValidationOptionsParser;
+import net.shibboleth.spring.security.trust.ChainingParser;
+import net.shibboleth.spring.security.trust.PKIXInlineValidationInfoParser;
+import net.shibboleth.spring.security.trust.PKIXResourceValidationInfoParser;
+import net.shibboleth.spring.security.trust.PKIXValidationOptionsParser;
+import net.shibboleth.spring.security.trust.SignatureChainingParser;
+import net.shibboleth.spring.security.trust.StaticExplicitKeyParser;
+import net.shibboleth.spring.security.trust.StaticExplicitKeySignatureParser;
+import net.shibboleth.spring.security.trust.StaticPKIXSignatureParser;
+import net.shibboleth.spring.security.trust.StaticPKIXX509CredentialParser;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+
+/** Namespace handler for {@link #SECURITY_NAMESPACE}. */
+public class SecurityNamespaceHandler extends BaseSpringNamespaceHandler {
+
+ /** Namespace for Security. */
+ @Nonnull @NotEmpty public static final String SECURITY_NAMESPACE = "urn:mace:shibboleth:2.0:security";
+
+ /** Credential element name. */
+ @Nonnull public static final QName CREDENTIAL_ELEMENT_NAME = new QName(SECURITY_NAMESPACE, "Credential");
+
+ /** TrustEngine Element name. */
+ @Nonnull public static final QName TRUST_ENGINE_ELEMENT_NAME = new QName(SECURITY_NAMESPACE, "TrustEngine");
+
+ /** TrustEngineRef element name. */
+ @Nonnull public static final QName TRUST_ENGINE_REF = new QName(SECURITY_NAMESPACE, "TrustEngineRef");
+
+ /** {@inheritDoc} */
+ @Override public void init() {
+ // Credentials
+ registerBeanDefinitionParser(X509ResourceCredentialParser.TYPE_NAME_RESOURCE,
+ new X509ResourceCredentialParser());
+ registerBeanDefinitionParser(X509InlineCredentialParser.TYPE_NAME, new X509InlineCredentialParser());
+ registerBeanDefinitionParser(BasicInlineCredentialParser.TYPE_NAME, new BasicInlineCredentialParser());
+ registerBeanDefinitionParser(BasicResourceCredentialParser.TYPE_NAME_RESOURCE,
+ new BasicResourceCredentialParser());
+
+ registerBeanDefinitionParser(StaticExplicitKeySignatureParser.TYPE_NAME,
+ new StaticExplicitKeySignatureParser());
+ registerBeanDefinitionParser(StaticPKIXSignatureParser.TYPE_NAME, new StaticPKIXSignatureParser());
+ registerBeanDefinitionParser(SignatureChainingParser.TYPE_NAME, new SignatureChainingParser());
+
+ // Validation Info
+ registerBeanDefinitionParser(PKIXResourceValidationInfoParser.TYPE_NAME_RESOURCE,
+ new PKIXResourceValidationInfoParser());
+ registerBeanDefinitionParser(PKIXInlineValidationInfoParser.SCHEMA_TYPE, new PKIXInlineValidationInfoParser());
+
+ // Validation Opts
+ registerBeanDefinitionParser(PKIXValidationOptionsParser.ELEMENT_NAME, new PKIXValidationOptionsParser());
+ registerBeanDefinitionParser(CertPathPKIXValidationOptionsParser.ELEMENT_NAME,
+ new CertPathPKIXValidationOptionsParser());
+
+ //
+ // Trust Engines needed for the HttpMetadataProvider
+ //
+ registerBeanDefinitionParser(ChainingParser.TYPE_NAME, new ChainingParser());
+ registerBeanDefinitionParser(StaticExplicitKeyParser.TYPE_NAME, new StaticExplicitKeyParser());
+ registerBeanDefinitionParser(StaticPKIXX509CredentialParser.TYPE_NAME, new StaticPKIXX509CredentialParser());
+
+ }
+}
\ No newline at end of file
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/AbstractBasicCredentialParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/AbstractBasicCredentialParser.java
new file mode 100644
index 000000000..4420d2ff3
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/AbstractBasicCredentialParser.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.credential;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.xml.namespace.QName;
+
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.xml.ElementSupport;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Specific parser for all BasicCredentials.
+ *
+ * <p>
+ * This does the work of putting the element values into strings. The bean factory then does the correct thing - with
+ * some help from Spring doing auto-conversion.
+ * </p>
+ */
+public abstract class AbstractBasicCredentialParser extends AbstractCredentialParser {
+
+ /** <PrivateKey>. */
+ public static final QName PRIVATE_KEY_ELEMENT_NAME = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "PrivateKey");
+
+ /** <PublicKey>. */
+ public static final QName PUBLIC_KEY_ELEMENT_NAME = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "PublicKey");
+
+ /** <SecretKey>. */
+ public static final QName SECRET_KEY_ELEMENT_NAME = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "SecretKey");
+
+ /** log. */
+ private final Logger log = LoggerFactory.getLogger(AbstractBasicCredentialParser.class);
+
+ /** {@inheritDoc} */
+ @Override protected void doParse(final Element element, final ParserContext parserContext,
+ final BeanDefinitionBuilder builder) {
+ super.doParse(element, parserContext, builder);
+ builder.addPropertyValue("configDescription", parserContext.getReaderContext().getResource().getDescription());
+
+ parsePrivateKey(ElementSupport.getChildElements(element, PRIVATE_KEY_ELEMENT_NAME), parserContext, builder);
+ parsePublicKey(ElementSupport.getChildElements(element, PUBLIC_KEY_ELEMENT_NAME), parserContext, builder);
+ parseSecretKey(ElementSupport.getChildElements(element, SECRET_KEY_ELEMENT_NAME), parserContext, builder);
+ }
+
+ /**
+ * Parse the <PrivateKey> element.
+ *
+ * @param childElements the elements containing the private key, may be null or empty.
+ * @param parserContext used for logging.
+ * @param builder the builder.
+ */
+ private void parsePrivateKey(@Nullable final List<Element> childElements, final ParserContext parserContext,
+ @Nonnull final BeanDefinitionBuilder builder) {
+ if (null == childElements || childElements.isEmpty()) {
+ return;
+ }
+ if (childElements.size() > 1) {
+ log.error("{}: More than one <PrivateKey> Elements present.", parserContext.getReaderContext()
+ .getResource().getDescription());
+ throw new BeanCreationException("More than one <PrivateKey> Elements present.");
+ }
+ final Element key = childElements.get(0);
+ final String value = StringSupport.trimOrNull(key.getTextContent());
+ if (null == value) {
+ log.error("{}: <PrivateKey> Must contain text.", parserContext.getReaderContext().getResource()
+ .getDescription());
+ throw new BeanCreationException("<PrivateKey> Must contain text.");
+ }
+ log.debug("Found a private key <Supressed>");
+ builder.addPropertyValue("privateKeyInfo", value);
+ builder.addPropertyValue("privateKeyPassword", key.getAttributeNS(null, "password"));
+ }
+
+ /**
+ * Parse the <PublicKey> elements.
+ *
+ * @param childElements the elements containing the public key, must have exactly one element
+ * @param parserContext used for logging.
+ * @param builder the builder
+ */
+ private void parsePublicKey(@Nullable final List<Element> childElements, final ParserContext parserContext,
+ @Nonnull final BeanDefinitionBuilder builder) {
+ if (null == childElements || childElements.isEmpty()) {
+ return;
+ }
+ if (childElements.size() > 1) {
+ log.error("{}: More than one <PublicKey> elements present.", parserContext.getReaderContext().getResource()
+ .getDescription());
+ throw new BeanCreationException("More than one <PublicKey> elements present.");
+ }
+ final Element key = childElements.get(0);
+ final String value = StringSupport.trimOrNull(key.getTextContent());
+ if (null == value) {
+ log.error("{}: <PublicKey> Must contain text.", parserContext.getReaderContext().getResource()
+ .getDescription());
+ throw new BeanCreationException("<PublicKey> Must contain text.");
+ }
+ log.debug("Found a public key {}", value);
+ builder.addPropertyValue("publicKeyInfo", value);
+
+ if (key.hasAttributeNS(null, "password")) {
+ log.warn("password on public key is ignored");
+ }
+ }
+
+ /**
+ * Parse the <SecretKey> element.
+ *
+ * @param childElements the elements containing the private key, may be null or empty.
+ * @param parserContext used for logging.
+ * @param builder the builder
+ */
+ private void parseSecretKey(@Nullable final List<Element> childElements, final ParserContext parserContext,
+ @Nonnull final BeanDefinitionBuilder builder) {
+ if (null == childElements || childElements.isEmpty()) {
+ return;
+ }
+ if (childElements.size() > 1) {
+ log.error("{}: More than one <SecretKey> Elements present.", parserContext.getReaderContext().getResource()
+ .getDescription());
+ throw new BeanCreationException("More than one <SecretKey> Elements present.");
+ }
+ final Element key = childElements.get(0);
+ final String value = StringSupport.trimOrNull(key.getTextContent());
+ if (null == value) {
+ log.error("{}: <SecretKey> Must contain text.", parserContext.getReaderContext().getResource()
+ .getDescription());
+ throw new BeanCreationException("<SecretKey> Must contain text.");
+ }
+ log.debug("Found a secret key <Supressed>");
+ builder.addPropertyValue("secretKeyInfo", value);
+ builder.addPropertyValue("secretKeyAlgorithm", StringSupport.trimOrNull(key.getAttributeNS(null, "algorithm")));
+ builder.addPropertyValue("secretKeyEncoding", StringSupport.trimOrNull(key.getAttributeNS(null, "encoding")));
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/AbstractCredentialParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/AbstractCredentialParser.java
new file mode 100644
index 000000000..219eb76b1
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/AbstractCredentialParser.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.credential;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+import net.shibboleth.ext.spring.util.AbstractCustomBeanDefinitionParser;
+import net.shibboleth.ext.spring.util.SpringSupport;
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.xml.ElementSupport;
+
+/**
+ * Base parser for all <Credential> elements.
+ */
+public abstract class AbstractCredentialParser extends AbstractCustomBeanDefinitionParser {
+
+ /** <Credential>. */
+ public static final QName CREDENTIAL_ELEMENT_NAME = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "Credential");
+
+ /** <KeyName>. */
+ public static final QName KEY_NAME_ELEMENT_NAME = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "KeyName");
+
+ /** {@inheritDoc} */
+ @Override protected String resolveId(final Element element, final AbstractBeanDefinition definition,
+ final ParserContext parserContext) {
+ return StringSupport.trimOrNull(element.getAttributeNS(null, "id"));
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void doParse(final Element element, final ParserContext parserContext,
+ final BeanDefinitionBuilder builder) {
+ super.doParse(element, parserContext, builder);
+
+ builder.setLazyInit(true);
+
+ parseAttributes(element, builder);
+ parseKeyNames(ElementSupport.getChildElements(element, KEY_NAME_ELEMENT_NAME), builder);
+ }
+
+ /**
+ * Parse the credential element attributes.
+ *
+ * @param element credential element
+ * @param builder bean definition builder
+ */
+ protected void parseAttributes(final Element element, final BeanDefinitionBuilder builder) {
+ final String usage = StringSupport.trimOrNull(element.getAttributeNS(null, "usage"));
+ builder.addPropertyValue("usageType", usage);
+
+ final String entityID = StringSupport.trimOrNull(element.getAttributeNS(null, "entityID"));
+ if (entityID != null) {
+ builder.addPropertyValue("entityID", entityID);
+ }
+ }
+
+ /**
+ * Parses the key names from the credential configuration.
+ *
+ * @param keyNameElems the elements to parse
+ * @param builder credential build
+ */
+ protected void parseKeyNames(final List<Element> keyNameElems, final BeanDefinitionBuilder builder) {
+ if (keyNameElems == null || keyNameElems.isEmpty()) {
+ return;
+ }
+
+ builder.addPropertyValue("keyNames", SpringSupport.getElementTextContentAsManagedList(keyNameElems));
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/AbstractX509CredentialParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/AbstractX509CredentialParser.java
new file mode 100644
index 000000000..726b44ca8
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/AbstractX509CredentialParser.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.credential;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.xml.namespace.QName;
+
+import net.shibboleth.ext.spring.util.SpringSupport;
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.xml.AttributeSupport;
+import net.shibboleth.utilities.java.support.xml.ElementSupport;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.w3c.dom.Element;
+
+/**
+ * Specific parser for all X509Credentials.
+ *
+ * <p>
+ * This does the work of putting the element values into strings. The bean factory then does the correct thing - with
+ * some help from Spring doing auto-conversion.
+ * </p>
+ */
+public abstract class AbstractX509CredentialParser extends AbstractCredentialParser {
+
+ /** <PrivateKey>. */
+ public static final QName PRIVATE_KEY_ELEMENT_NAME = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "PrivateKey");
+
+ /** <Certificate>. */
+ public static final QName CERTIFICATE_ELEMENT_NAME = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "Certificate");
+
+ /** <CRL>. */
+ public static final QName CRL_ELEMENT_NAME = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE, "CRL");
+
+ /** log. */
+ private Logger log = LoggerFactory.getLogger(AbstractX509CredentialParser.class);
+
+ /** {@inheritDoc} */
+ @Override protected void doParse(final Element element, final BeanDefinitionBuilder builder) {
+ super.doParse(element, builder);
+ parsePrivateKey(ElementSupport.getChildElements(element, PRIVATE_KEY_ELEMENT_NAME), builder);
+ parseCertificates(ElementSupport.getChildElements(element, CERTIFICATE_ELEMENT_NAME), builder);
+ parseCRLs(ElementSupport.getChildElements(element, CRL_ELEMENT_NAME), builder);
+ }
+
+ /**
+ * Parse the <PrivateKey> element.
+ *
+ * @param childElements the elements containing the private key, may be null or empty.
+ * @param builder the builder
+ */
+ private void parsePrivateKey(@Nullable final List<Element> childElements,
+ @Nonnull final BeanDefinitionBuilder builder) {
+ if (null == childElements || childElements.isEmpty()) {
+ return;
+ }
+ if (childElements.size() > 1) {
+ throw new BeanCreationException("More than one <PrivateKey> Elements present.");
+ }
+ final Element key = childElements.get(0);
+ final String value = StringSupport.trimOrNull(key.getTextContent());
+ if (null == value) {
+ throw new BeanCreationException("<PrivateKey> Must contain text.");
+ }
+ log.debug("Found a private key <Supressed>");
+ builder.addPropertyValue("privateKey", value);
+ builder.addPropertyValue("privateKeyPassword", key.getAttributeNS(null, "password"));
+ }
+
+ /**
+ * Parse the <Certificate> elements.
+ *
+ * @param childElements the elements containing the certificates, Must have at least one element.
+ * @param builder the builder
+ */
+ private void parseCertificates(@Nullable final List<Element> childElements,
+ @Nonnull final BeanDefinitionBuilder builder) {
+ if (null == childElements || childElements.isEmpty()) {
+ throw new BeanCreationException("At least one <Certificate> should be present.");
+ }
+
+ final List<String> certs = new ManagedList<>(childElements.size());
+
+ for (final Element elem : childElements) {
+ final String cert = StringSupport.trimOrNull(elem.getTextContent());
+ if (null == cert) {
+ throw new BeanCreationException("All <Certificate> elements must contain text.");
+ }
+ if (elem.hasAttributeNS(null, "entityCertificate")
+ && AttributeSupport.getAttributeValueAsBoolean(elem.getAttributeNodeNS(null,
+ "entityCertificate"))) {
+ // Note the loss of property replacement for this undocumented extension
+ log.debug("Found a certficate marked as an entityCertificate {}", cert);
+ builder.addPropertyValue("entity", cert);
+ } else {
+ log.debug("Found a certficate {}", cert);
+ }
+ certs.add(cert);
+ }
+ builder.addPropertyValue("certificates", certs);
+ }
+
+ /**
+ * Parse the <CRL> elements.
+ *
+ * @param childElements the elements containing the CRLs, Must have at least one element.
+ * @param builder the builder
+ */
+ private void parseCRLs(@Nullable final List<Element> childElements, @Nonnull final BeanDefinitionBuilder builder) {
+ if (null == childElements || childElements.isEmpty()) {
+ return;
+ }
+
+ builder.addPropertyValue("CRLs", SpringSupport.getElementTextContentAsManagedList(childElements));
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/BasicInlineCredentialParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/BasicInlineCredentialParser.java
new file mode 100644
index 000000000..ae8ce3977
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/BasicInlineCredentialParser.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.credential;
+
+import javax.xml.namespace.QName;
+
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+
+import org.opensaml.spring.credential.BasicInlineCredentialFactoryBean;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for BasicInline Credentials.
+ */
+public class BasicInlineCredentialParser extends AbstractBasicCredentialParser {
+
+ /** Element Name.*/
+ public static final QName TYPE_NAME = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE, "BasicInline");
+
+ /** {@inheritDoc} */
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return BasicInlineCredentialFactoryBean.class;
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/BasicResourceCredentialParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/BasicResourceCredentialParser.java
new file mode 100644
index 000000000..679608cea
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/BasicResourceCredentialParser.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.credential;
+
+import javax.xml.namespace.QName;
+
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+
+import org.opensaml.spring.credential.BasicResourceCredentialFactoryBean;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for BasicFilesystem and BasicResourceBacked Credentials.
+ */
+public class BasicResourceCredentialParser extends AbstractBasicCredentialParser {
+
+ /** Type for Resource. */
+ public static final QName TYPE_NAME_RESOURCE = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "BasicResourceBacked");
+
+ /** {@inheritDoc} */
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return BasicResourceCredentialFactoryBean.class;
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/X509InlineCredentialParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/X509InlineCredentialParser.java
new file mode 100644
index 000000000..c677a3492
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/X509InlineCredentialParser.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.credential;
+
+import javax.xml.namespace.QName;
+
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+
+import org.opensaml.spring.credential.X509InlineCredentialFactoryBean;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for X509Inline credentials.
+ */
+public class X509InlineCredentialParser extends AbstractX509CredentialParser {
+
+ /** Element Name.*/
+ public static final QName TYPE_NAME = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE, "X509Inline");
+
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return X509InlineCredentialFactoryBean.class;
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/X509ResourceCredentialParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/X509ResourceCredentialParser.java
new file mode 100644
index 000000000..0858e2bf8
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/X509ResourceCredentialParser.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.credential;
+
+import javax.xml.namespace.QName;
+
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+
+import org.opensaml.spring.credential.BasicX509CredentialFactoryBean;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for X509Filesystem credentials.
+ */
+public class X509ResourceCredentialParser extends AbstractX509CredentialParser {
+
+ /** Type for X509 credentials. */
+ public static final QName TYPE_NAME_RESOURCE = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "X509ResourceBacked");
+
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return BasicX509CredentialFactoryBean.class;
+ }
+
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/package-info.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/package-info.java
new file mode 100644
index 000000000..b6cc724b1
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/credential/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Parsers for Credential objects.
+ */
+
+package net.shibboleth.spring.security.credential;
\ No newline at end of file
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/package-info.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/package-info.java
new file mode 100644
index 000000000..fe49bf9fe
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Security namespace Spring parsing support.
+ */
+
+package net.shibboleth.spring.security;
\ No newline at end of file
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/AbstractChainingParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/AbstractChainingParser.java
new file mode 100644
index 000000000..00230b92b
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/AbstractChainingParser.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import java.util.List;
+
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+import net.shibboleth.ext.spring.util.SpringSupport;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.xml.ElementSupport;
+
+import org.springframework.beans.BeanMetadataElement;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Base Parser for trust engines of type SignatureChaining and Chaining.
+ */
+public abstract class AbstractChainingParser extends AbstractTrustEngineParser {
+
+ /** {@inheritDoc} */
+ @Override protected void doParse(final Element element, final ParserContext parserContext,
+ final BeanDefinitionBuilder builder) {
+ super.doParse(element, parserContext, builder);
+
+ final List<Element> childEngines =
+ ElementSupport.getChildElements(element, SecurityNamespaceHandler.TRUST_ENGINE_ELEMENT_NAME);
+ final List<Element> childEngineRefs =
+ ElementSupport.getChildElements(element, SecurityNamespaceHandler.TRUST_ENGINE_REF);
+
+ final List<BeanMetadataElement> allChildren = new ManagedList<>(childEngines.size()+ childEngineRefs.size());
+
+ allChildren.addAll(SpringSupport.parseCustomElements(childEngines, parserContext, builder));
+
+ for (final Element ref:childEngineRefs) {
+ final String reference = StringSupport.trimOrNull(ref.getAttributeNS(null, "ref"));
+ if (null != reference) {
+ allChildren.add(new RuntimeBeanReference(StringSupport.trim(reference)));
+ }
+ }
+ builder.addConstructorArgValue(allChildren);
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/AbstractPKIXValidationInfoParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/AbstractPKIXValidationInfoParser.java
new file mode 100644
index 000000000..0b66cbcb6
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/AbstractPKIXValidationInfoParser.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import net.shibboleth.ext.spring.util.AbstractCustomBeanDefinitionParser;
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.xml.ElementSupport;
+
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Base parser for all <ValidationInfo> types. This does all the heavy lifting of creating lists of strings from
+ * the sub-elements. The derived classes specify which factory bean to create and that in turn converts from string to
+ * CRL or Certificate (either inline or from a file).
+ */
+public abstract class AbstractPKIXValidationInfoParser extends AbstractCustomBeanDefinitionParser {
+
+ /** The element <Certificate>. */
+ private static final QName CERTIFICATE =
+ new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE, "Certificate");
+
+ /** The element <CRL>. */
+ private static final QName CRL = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE, "CRL");
+
+ /** {@inheritDoc} */
+ @Override protected void doParse(final Element element, final ParserContext parserContext,
+ final BeanDefinitionBuilder builder) {
+ super.doParse(element, parserContext, builder);
+
+ builder.addPropertyValue("configDescription", parserContext.getReaderContext().getResource().getDescription());
+
+ if (element.hasAttributeNS(null, "verifyDepth")) {
+ builder.addPropertyValue("verifyDepth",
+ StringSupport.trimOrNull(element.getAttributeNS(null, "verifyDepth")));
+ }
+
+ final List<Element> certificates = ElementSupport.getChildElements(element, CERTIFICATE);
+ final List<String> certStrings = new ManagedList<>(certificates.size());
+
+ for (final Element cert : certificates) {
+ certStrings.add(cert.getTextContent());
+ }
+
+ builder.addPropertyValue("certificates", certStrings);
+
+ final List<Element> crls = ElementSupport.getChildElements(element, CRL);
+ final List<String> crlStrings = new ManagedList<>(certificates.size());
+
+ for (final Element crl : crls) {
+ crlStrings.add(crl.getTextContent());
+ }
+
+ builder.addPropertyValue("CRLs", crlStrings);
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/AbstractStaticPKIXParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/AbstractStaticPKIXParser.java
new file mode 100644
index 000000000..a59ae56ce
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/AbstractStaticPKIXParser.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.xml.namespace.QName;
+
+import net.shibboleth.ext.spring.util.SpringSupport;
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.xml.ElementSupport;
+
+import org.opensaml.security.x509.impl.BasicX509CredentialNameEvaluator;
+import org.opensaml.security.x509.impl.CertPathPKIXTrustEvaluator;
+import org.opensaml.security.x509.impl.StaticPKIXValidationInformationResolver;
+import org.opensaml.security.x509.impl.X509CredentialNameEvaluator;
+import org.springframework.beans.factory.config.AbstractFactoryBean;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Base Parser for trust engines of type StaticPKIXKeySignature and StaticPKIXX509Credential.
+ */
+public abstract class AbstractStaticPKIXParser extends AbstractTrustEngineParser {
+
+ /** Validation Information. */
+ public static final QName VALIDATION_INFO = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "ValidationInfo");
+
+ /** Trusted Names Information. */
+ public static final QName TRUSTED_NAMES = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "TrustedName");
+
+ /**
+ * Get the definition for the {@link org.opensaml.security.x509.PKIXValidationInformationResolver}. This is
+ * constructed from the Trusted names and the Validation Info.
+ *
+ * @param element what to parse
+ * @param parserContext the context to parse inside
+ * @return the definition
+ */
+ protected BeanDefinition getPKIXValidationInformationResolver(@Nonnull final Element element,
+ @Nonnull final ParserContext parserContext) {
+
+ final List<Element> validationInfoElements = ElementSupport.getChildElements(element, VALIDATION_INFO);
+ final List<Element> trustedNameElements = ElementSupport.getChildElements(element, TRUSTED_NAMES);
+
+ final BeanDefinitionBuilder builder =
+ BeanDefinitionBuilder.genericBeanDefinition(StaticPKIXValidationInformationResolver.class);
+ builder.addConstructorArgValue(
+ SpringSupport.parseCustomElements(validationInfoElements, parserContext, builder));
+ builder.addConstructorArgValue(
+ SpringSupport.getElementTextContentAsManagedList(trustedNameElements));
+
+ return builder.getBeanDefinition();
+ }
+
+ /**
+ * Get the definition for the {@link org.opensaml.security.x509.PKIXTrustEvaluator}. This is purely a
+ * {@link CertPathPKIXTrustEvaluator} constructed with whatever ValidationOptions we provide.
+ *
+ * @param element what to parse
+ * @param parserContext the context to parse inside
+ * @return the definition
+ */
+ protected BeanDefinition getPKIXTrustEvaluator(@Nonnull final Element element,
+ @Nonnull final ParserContext parserContext) {
+
+ final BeanDefinitionBuilder builder =
+ BeanDefinitionBuilder.genericBeanDefinition(CertPathPKIXTrustEvaluator.class);
+
+ final List<Element> validationOptionsElements =
+ ElementSupport.getChildElements(element, PKIXValidationOptionsParser.ELEMENT_NAME);
+
+ if (null != validationOptionsElements && !validationOptionsElements.isEmpty()) {
+ builder.addConstructorArgValue(
+ SpringSupport.parseCustomElements(validationOptionsElements, parserContext, builder));
+ }
+ return builder.getBeanDefinition();
+ }
+
+ /**
+ * Get the effective X509CredentialNameEvaluator to use. Currently we return a literal value, but in the future a
+ * BeanDefinition could be returned if necessary if we support toggling the name evaluator settings, hence the
+ * Object return type.
+ *
+ * @param element what to parse
+ * @param parserContext the context to parse inside
+ * @return an X509CredentialNameEvaluator instance or a BeanDefinition. May be null.
+ */
+ protected Object getX509CredentialNameEvaluator(@Nonnull final Element element,
+ @Nonnull final ParserContext parserContext) {
+
+ final BeanDefinitionBuilder builder =
+ BeanDefinitionBuilder.genericBeanDefinition(X509CredentialNameEvaluatorFactoryBean.class);
+ final String attrValue = StringSupport.trimOrNull(element.getAttributeNS(null, "trustedNameCheckEnabled"));
+ if (attrValue != null) {
+ builder.addPropertyValue("trustedNameCheckEnabled", attrValue);
+ }
+ return builder.getBeanDefinition();
+ }
+
+ /**
+ * FactoryBean to do a deferred decision on whether to create a {@link X509CredentialNameEvaluator}. This is in a
+ * factory bean to allow for property replacement. The default (no value setting) is true.
+ */
+ protected static class X509CredentialNameEvaluatorFactoryBean extends
+ AbstractFactoryBean<X509CredentialNameEvaluator> {
+
+ /** Do we emit a {@link X509CredentialNameEvaluator} or not. */
+ private boolean trustedNameCheckEnabled = true;
+
+ /**
+ * Set whether to perform the trusted name check.
+ *
+ * @param enabled whether we emit a {@link X509CredentialNameEvaluator} .
+ */
+ public void setTrustedNameCheckEnabled(final boolean enabled) {
+ trustedNameCheckEnabled = enabled;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Class<?> getObjectType() {
+ return BasicX509CredentialNameEvaluator.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected BasicX509CredentialNameEvaluator createInstance() throws Exception {
+ if (trustedNameCheckEnabled) {
+ return new BasicX509CredentialNameEvaluator();
+ }
+ return null;
+ }
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/AbstractTrustEngineParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/AbstractTrustEngineParser.java
new file mode 100644
index 000000000..8537c94e3
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/AbstractTrustEngineParser.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+import net.shibboleth.ext.spring.util.AbstractCustomBeanDefinitionParser;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+
+/**
+ * Basis of all parsers for <security:TrustEngine>.
+ */
+public abstract class AbstractTrustEngineParser extends AbstractCustomBeanDefinitionParser {
+
+ /** {@inheritDoc} */
+ @Override protected String resolveId(final Element element, final AbstractBeanDefinition definition,
+ final ParserContext parserContext) {
+ return StringSupport.trimOrNull(element.getAttributeNS(null, "id"));
+ }
+
+ @Override protected void doParse(final Element element, final ParserContext parserContext,
+ final BeanDefinitionBuilder builder) {
+ super.doParse(element, parserContext, builder);
+ builder.setLazyInit(true);
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/CertPathPKIXValidationOptionsParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/CertPathPKIXValidationOptionsParser.java
new file mode 100644
index 000000000..bac1b4f7a
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/CertPathPKIXValidationOptionsParser.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.xml.ElementSupport;
+
+import org.opensaml.security.x509.impl.CertPathPKIXValidationOptions;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Spring bean definition parser for {urn:mace:shibboleth:2.0:security}ValidationOptions elements which have a type
+ * specialization of {urn:mace:shibboleth:2.0:security}CertPathValidationOptionsType.
+ */
+public class CertPathPKIXValidationOptionsParser extends PKIXValidationOptionsParser {
+ /** Schema type. */
+ public static final QName SCHEMA_TYPE = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "CertPathValidationOptionsType");
+
+ /** PolicyOid Element type. */
+ public static final QName POLICY_OID_ELEMENT = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "PolicyOID");
+
+ /** {@inheritDoc} */
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return CertPathPKIXValidationOptions.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void doParse(final Element element, final ParserContext parserContext,
+ final BeanDefinitionBuilder builder) {
+ super.doParse(element, parserContext, builder);
+
+ if (element.hasAttributeNS(null, "forceRevocationEnabled")) {
+ builder.addPropertyValue("forceRevocationEnabled",
+ StringSupport.trimOrNull(element.getAttributeNS(null, "forceRevocationEnabled")));
+ }
+
+ if (element.hasAttributeNS(null, "revocationEnabled")) {
+ builder.addPropertyValue("revocationEnabled",
+ StringSupport.trimOrNull(element.getAttributeNS(null, "revocationEnabled")));
+ }
+
+ if (element.hasAttributeNS(null, "policyMappingInhibit")) {
+ builder.addPropertyValue("policyMappingInhibit",
+ StringSupport.trimOrNull(element.getAttributeNS(null, "policyMappingInhibit")));
+ }
+
+ if (element.hasAttributeNS(null, "anyPolicyInhibit")) {
+ builder.addPropertyValue("anyPolicyInhibit",
+ StringSupport.trimOrNull(element.getAttributeNS(null, "anyPolicyInhibit")));
+ }
+
+ final List<Element> childElems = ElementSupport.getChildElements(element, POLICY_OID_ELEMENT);
+ if (null != childElems && !childElems.isEmpty()) {
+ final List<String> initialPolicies = new ManagedList<>(childElems.size());
+ for (final Element nameElem : childElems) {
+ final String value = StringSupport.trimOrNull(nameElem.getTextContent());
+ if (null != value) {
+ initialPolicies.add(value);
+ }
+ }
+ builder.addPropertyValue("initialPolicies", initialPolicies);
+ }
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/ChainingParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/ChainingParser.java
new file mode 100644
index 000000000..7b217b729
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/ChainingParser.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import javax.xml.namespace.QName;
+
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+
+import org.opensaml.spring.trust.ChainingTrustEngineFactoryBean;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for trust engines of type SignatureChaining.
+ */
+public class ChainingParser extends AbstractChainingParser {
+
+ /** Schema type. */
+ public static final QName TYPE_NAME = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE, "Chaining");
+
+ /** {@inheritDoc} */
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return ChainingTrustEngineFactoryBean.class;
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/PKIXInlineValidationInfoParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/PKIXInlineValidationInfoParser.java
new file mode 100644
index 000000000..e503b4488
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/PKIXInlineValidationInfoParser.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import javax.xml.namespace.QName;
+
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+
+import org.opensaml.spring.trust.PKIXInlineValidationInfoFactoryBean;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for <ValidationInfo type="PKIXInline">.
+ *
+ * <p>
+ * All of the heavy lifting is done in the super class and the associated factory bean (which gets the parameters of
+ * the type is wants by virtue of Springs type coercion).
+ * </p>
+ */
+public class PKIXInlineValidationInfoParser extends AbstractPKIXValidationInfoParser {
+
+ /** Element Name.*/
+ public static final QName SCHEMA_TYPE = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE, "PKIXInline");
+
+ /** {@inheritDoc} */
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return PKIXInlineValidationInfoFactoryBean.class;
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/PKIXResourceValidationInfoParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/PKIXResourceValidationInfoParser.java
new file mode 100644
index 000000000..16b558f13
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/PKIXResourceValidationInfoParser.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import javax.xml.namespace.QName;
+
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+
+import org.opensaml.spring.trust.PKIXResourceValidationInfoFactoryBean;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for <ValidationInfo type="PKIXFilesystem"> and <ValidationInfo type="PKIXResourceBacked">.
+ *
+ * <p>
+ * All of the heavy lifting is done in the super class and the associated factory bean (which gets the parameters of the
+ * type is wants by virtue of Springs type coercion).
+ * </p>
+ */
+public class PKIXResourceValidationInfoParser extends AbstractPKIXValidationInfoParser {
+
+ /** Schema type for PKIXResourceBackedValidationInformation. */
+ public static final QName TYPE_NAME_RESOURCE = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "PKIXResourceBacked");
+
+ /** {@inheritDoc} */
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return PKIXResourceValidationInfoFactoryBean.class;
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/PKIXValidationOptionsParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/PKIXValidationOptionsParser.java
new file mode 100644
index 000000000..d842b70b3
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/PKIXValidationOptionsParser.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import javax.xml.namespace.QName;
+
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+
+import org.opensaml.security.x509.PKIXValidationOptions;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+import net.shibboleth.ext.spring.util.AbstractCustomBeanDefinitionParser;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+
+/**
+ * A Parser for the < ValidationOptions > within a StaticPKIXSignature.
+ */
+public class PKIXValidationOptionsParser extends AbstractCustomBeanDefinitionParser {
+
+ /** Validation Options. */
+ public static final QName ELEMENT_NAME = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "ValidationOptions");
+
+ /** {@inheritDoc} */
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return PKIXValidationOptions.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void doParse(final Element element, final ParserContext parserContext,
+ final BeanDefinitionBuilder builder) {
+ super.doParse(element, parserContext, builder);
+
+ if (element.hasAttributeNS(null, "processEmptyCRLs")) {
+ builder.addPropertyValue("processEmptyCRLs",
+ StringSupport.trimOrNull(element.getAttributeNS(null, "processEmptyCRLs")));
+ }
+
+ if (element.hasAttributeNS(null, "processExpiredCRLs")) {
+ builder.addPropertyValue("processExpiredCRLs",
+ StringSupport.trimOrNull(element.getAttributeNS(null, "processExpiredCRLs")));
+ }
+
+ if (element.hasAttributeNS(null, "processCredentialCRLs")) {
+ builder.addPropertyValue("processCredentialCRLs",
+ StringSupport.trimOrNull(element.getAttributeNS(null, "processCredentialCRLs")));
+ }
+
+ if (element.hasAttributeNS(null, "defaultVerificationDepth")) {
+ builder.addPropertyValue("defaultVerificationDepth",
+ StringSupport.trimOrNull(element.getAttributeNS(null, "defaultVerificationDepth")));
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected boolean shouldGenerateId() {
+ return true;
+ }
+
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/SignatureChainingParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/SignatureChainingParser.java
new file mode 100644
index 000000000..81e102f6d
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/SignatureChainingParser.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import javax.xml.namespace.QName;
+
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+
+import org.opensaml.spring.trust.ChainingSignatureTrustEngineFactoryBean;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for trust engines of type SignatureChaining.
+ */
+public class SignatureChainingParser extends AbstractChainingParser {
+
+ /** Schema type. */
+ public static final QName TYPE_NAME = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "SignatureChaining");
+
+ /** {@inheritDoc} */
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return ChainingSignatureTrustEngineFactoryBean.class;
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/StaticExplicitKeyParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/StaticExplicitKeyParser.java
new file mode 100644
index 000000000..1f845babc
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/StaticExplicitKeyParser.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import net.shibboleth.ext.spring.util.SpringSupport;
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+import net.shibboleth.utilities.java.support.xml.ElementSupport;
+
+import org.opensaml.security.credential.impl.StaticCredentialResolver;
+import org.opensaml.security.trust.impl.ExplicitKeyTrustEngine;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for trust engines of type StaticExplicitKey TrustEngine.
+ */
+public class StaticExplicitKeyParser extends AbstractTrustEngineParser {
+
+ /** Schema type. */
+ public static final QName TYPE_NAME =
+ new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE, "StaticExplicitKey");
+
+ /** {@inheritDoc} */
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return ExplicitKeyTrustEngine.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void doParse(final Element element, final ParserContext parserContext,
+ final BeanDefinitionBuilder builder) {
+ super.doParse(element, parserContext, builder);
+
+ final List<Element> credentials =
+ ElementSupport.getChildElements(element, SecurityNamespaceHandler.CREDENTIAL_ELEMENT_NAME);
+
+ final BeanDefinitionBuilder resolver =
+ BeanDefinitionBuilder.genericBeanDefinition(StaticCredentialResolver.class);
+ resolver.addConstructorArgValue(SpringSupport.parseCustomElements(credentials, parserContext, resolver));
+
+ builder.addConstructorArgValue(resolver.getBeanDefinition());
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/StaticExplicitKeySignatureParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/StaticExplicitKeySignatureParser.java
new file mode 100644
index 000000000..d7c10ed36
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/StaticExplicitKeySignatureParser.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import net.shibboleth.ext.spring.util.SpringSupport;
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+import net.shibboleth.utilities.java.support.xml.ElementSupport;
+
+import org.opensaml.security.credential.impl.StaticCredentialResolver;
+import org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap;
+import org.opensaml.xmlsec.signature.support.impl.ExplicitKeySignatureTrustEngine;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for trust engines of type StaticExplicitKeySignature.
+ */
+public class StaticExplicitKeySignatureParser extends AbstractTrustEngineParser {
+
+ /** Schema type. */
+ public static final QName TYPE_NAME =
+ new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE, "StaticExplicitKeySignature");
+
+ /** {@inheritDoc} */
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return ExplicitKeySignatureTrustEngine.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void doParse(final Element element, final ParserContext parserContext,
+ final BeanDefinitionBuilder builder) {
+ super.doParse(element, parserContext, builder);
+
+ final List<Element> credentials =
+ ElementSupport.getChildElements(element, SecurityNamespaceHandler.CREDENTIAL_ELEMENT_NAME);
+
+ final BeanDefinitionBuilder resolver =
+ BeanDefinitionBuilder.genericBeanDefinition(StaticCredentialResolver.class);
+ resolver.addConstructorArgValue(SpringSupport.parseCustomElements(credentials, parserContext, resolver));
+
+ builder.addConstructorArgValue(resolver.getBeanDefinition());
+
+ builder.addConstructorArgValue(DefaultSecurityConfigurationBootstrap
+ .buildBasicInlineKeyInfoCredentialResolver());
+ }
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/StaticPKIXSignatureParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/StaticPKIXSignatureParser.java
new file mode 100644
index 000000000..5109131ee
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/StaticPKIXSignatureParser.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import javax.xml.namespace.QName;
+
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+
+import org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap;
+import org.opensaml.xmlsec.signature.support.impl.PKIXSignatureTrustEngine;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for trust engines of type StaticPKIXKeySignature.
+ */
+public class StaticPKIXSignatureParser extends AbstractStaticPKIXParser {
+
+ /** Schema type. */
+ public static final QName TYPE_NAME = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "StaticPKIXSignature");
+
+ /** {@inheritDoc} */
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return PKIXSignatureTrustEngine.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>We call into
+ * {@link
+ * PKIXSignatureTrustEngine#PKIXSignatureTrustEngine(
+ * org.opensaml.security.x509.PKIXValidationInformationResolver,
+ * org.opensaml.xmlsec.keyinfo.KeyInfoCredentialResolver,
+ * org.opensaml.security.x509.PKIXTrustEvaluator,
+ * org.opensaml.security.x509.impl.X509CredentialNameEvaluator)}.
+ * </p>
+ */
+ @Override protected void doParse(final Element element, final ParserContext parserContext,
+ final BeanDefinitionBuilder builder) {
+ super.doParse(element, parserContext, builder);
+
+ builder.addConstructorArgValue(getPKIXValidationInformationResolver(element, parserContext));
+ builder.addConstructorArgValue(DefaultSecurityConfigurationBootstrap
+ .buildBasicInlineKeyInfoCredentialResolver());
+ builder.addConstructorArgValue(getPKIXTrustEvaluator(element, parserContext));
+ builder.addConstructorArgValue(getX509CredentialNameEvaluator(element, parserContext));
+ }
+
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/StaticPKIXX509CredentialParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/StaticPKIXX509CredentialParser.java
new file mode 100644
index 000000000..343be82e8
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/StaticPKIXX509CredentialParser.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import javax.xml.namespace.QName;
+
+import net.shibboleth.spring.security.SecurityNamespaceHandler;
+
+import org.opensaml.security.x509.impl.PKIXX509CredentialTrustEngine;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for trust engines of type StaticPKIXX509Credential.
+ */
+public class StaticPKIXX509CredentialParser extends AbstractStaticPKIXParser {
+
+ /** Schema type. */
+ public static final QName TYPE_NAME = new QName(SecurityNamespaceHandler.SECURITY_NAMESPACE,
+ "StaticPKIXX509Credential");
+
+ /** {@inheritDoc} */
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return PKIXX509CredentialTrustEngine.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>
+ * We call into
+ * {@link PKIXX509CredentialTrustEngine#PKIXX509CredentialTrustEngine(
+ * org.opensaml.security.x509.PKIXValidationInformationResolver,
+ * org.opensaml.security.x509.PKIXTrustEvaluator,
+ * org.opensaml.security.x509.impl.X509CredentialNameEvaluator)}.
+ * </p>
+ */
+ @Override protected void doParse(final Element element, final ParserContext parserContext,
+ final BeanDefinitionBuilder builder) {
+ super.doParse(element, parserContext, builder);
+
+ builder.addConstructorArgValue(getPKIXValidationInformationResolver(element, parserContext));
+ builder.addConstructorArgValue(getPKIXTrustEvaluator(element, parserContext));
+ builder.addConstructorArgValue(getX509CredentialNameEvaluator(element, parserContext));
+ }
+
+}
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/package-info.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/package-info.java
new file mode 100644
index 000000000..dffeb31b4
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/security/trust/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Parsers for TrustEngines.
+ */
+
+package net.shibboleth.spring.security.trust;
\ No newline at end of file
diff --git a/shib-metadata-spring/src/main/resources/META-INF/spring.handlers b/shib-metadata-spring/src/main/resources/META-INF/spring.handlers
index 35f4d5f69..56e256f42 100644
--- a/shib-metadata-spring/src/main/resources/META-INF/spring.handlers
+++ b/shib-metadata-spring/src/main/resources/META-INF/spring.handlers
@@ -1 +1,2 @@
urn\:mace\:shibboleth\:2.0\:metadata = net.shibboleth.spring.metadata.MetadataNamespaceHandler
+urn\:mace\:shibboleth\:2.0\:security = net.shibboleth.spring.security.SecurityNamespaceHandler
diff --git a/shib-metadata-spring/src/main/resources/META-INF/spring.schemas b/shib-metadata-spring/src/main/resources/META-INF/spring.schemas
new file mode 100644
index 000000000..c71f89d10
--- /dev/null
+++ b/shib-metadata-spring/src/main/resources/META-INF/spring.schemas
@@ -0,0 +1,5 @@
+# Modern variant
+http\://shibboleth.net/schema/idp/shibboleth-security.xsd = schema/shibboleth-security.xsd
+
+# Legacy variant
+classpath\:/schema/shibboleth-2.0-security.xsd = schema/shibboleth-security.xsd
diff --git a/shib-metadata-spring/src/main/resources/schema/shibboleth-security.xsd b/shib-metadata-spring/src/main/resources/schema/shibboleth-security.xsd
new file mode 100644
index 000000000..95ad23fb0
--- /dev/null
+++ b/shib-metadata-spring/src/main/resources/schema/shibboleth-security.xsd
@@ -0,0 +1,612 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:sec="urn:mace:shibboleth:2.0:security" targetNamespace="urn:mace:shibboleth:2.0:security" elementFormDefault="qualified">
+
+ <!-- CREDENTIAL RELATED OBJECTS -->
+ <element name="Credential" type="sec:CredentialType"/>
+
+ <complexType name="X509Inline">
+ <annotation>
+ <documentation>
+ Allows credentials to be components to be specified as content within the child elements. Keys,
+ Certificates, and CRLs may be PKCS#12, DER, or PEM encoded and may be encrypted or not.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:X509Credential"/>
+ </complexContent>
+ </complexType>
+
+ <complexType name="X509ResourceBacked">
+ <annotation>
+ <documentation>
+ Allows credential components to be loaded from a Spring Resource. Keys, Certificates, and CRLs may be
+ PKCS#12, DER, or PEM encoded and may be encrypted or not.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:X509Credential"/>
+ </complexContent>
+ </complexType>
+
+ <complexType name="X509Credential" abstract="true">
+ <annotation>
+ <documentation>
+ Defines the components of an X.509 credential.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:CredentialType">
+ <sequence>
+ <element name="PrivateKey" minOccurs="0">
+ <annotation>
+ <documentation>Credential's RSA/DSA private key.</documentation>
+ </annotation>
+ </element>
+ <element name="Certificate" minOccurs="1" maxOccurs="unbounded">
+ <annotation>
+ <documentation>
+ Certificate associated with the credential. More than one certificate
+ may be present within a single element, if the encoding form used allows
+ it, or multiple certificate elements may be used, or both.
+ </documentation>
+ </annotation>
+ </element>
+ <element name="CRL" minOccurs="0" maxOccurs="unbounded">
+ <annotation>
+ <documentation>
+ Certificate revocation list associated with the Credential. More than
+ one CRL may be present within a single element, if the encoding form
+ used allows it, or multiple CRL elements may be used, or both.
+ </documentation>
+ </annotation>
+ </element>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="BasicInline">
+ <annotation>
+ <documentation>
+ Allows credentials to be components to be specified as content within the child elements.
+ Keys may be PKCS#12, DER, or PEM encoded and may be encrypted or not.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:BasicCredential"/>
+ </complexContent>
+ </complexType>
+
+ <complexType name="BasicResourceBacked">
+ <annotation>
+ <documentation>
+ Allows credential components to be specified by Spring Resource specification.
+ Keys may be PKCS#12, DER, or PEM encoded and may be encrypted or not.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:BasicCredential"/>
+ </complexContent>
+ </complexType>
+
+ <complexType name="BasicCredential" abstract="true">
+ <annotation>
+ <documentation>
+ Defines the components of a basic credential containing either a
+ public key and optional private key, or a symmetric (secret) key.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:CredentialType">
+ <sequence>
+ <choice>
+ <element name="SecretKey">
+ <annotation>
+ <documentation>Credential's symmetric key.</documentation>
+ </annotation>
+ <complexType>
+ <simpleContent>
+ <extension base="string">
+ <attribute name="algorithm" type="sec:string" use="required">
+ <annotation>
+ <documentation>
+ The JCA key algorithm identifier.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="encoding" use="required">
+ <annotation>
+ <documentation>
+ The encoded format of the key data. Defaults to: base64.
+ </documentation>
+ </annotation>
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="binary" />
+ <enumeration value="hex" />
+ <enumeration value="base64" />
+ </restriction>
+ </simpleType>
+ </attribute>
+ </extension>
+ </simpleContent>
+ </complexType>
+ </element>
+ <sequence>
+ <element name="PrivateKey" minOccurs="0">
+ <annotation>
+ <documentation>Credential's RSA/DSA private key.</documentation>
+ </annotation>
+ </element>
+ <element name="PublicKey">
+ <annotation>
+ <documentation>Credential's RSA/DSA public key.</documentation>
+ </annotation>
+ </element>
+ </sequence>
+ </choice>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="CredentialType" abstract="true">
+ <annotation>
+ <documentation>Base type for credential information.</documentation>
+ </annotation>
+ <sequence>
+ <element name="KeyName" type="sec:string" minOccurs="0" maxOccurs="unbounded">
+ <annotation>
+ <documentation>Name(s) of the key this credential represents.</documentation>
+ </annotation>
+ </element>
+ </sequence>
+ <attribute name="id" type="sec:string">
+ <annotation>
+ <documentation>Unique id for this credential.</documentation>
+ </annotation>
+ </attribute>
+ <attribute name="entityID" type="sec:string">
+ <annotation>
+ <documentation>Identifier for the entity which owns this credential.</documentation>
+ </annotation>
+ </attribute>
+ <attribute name="usage" type="sec:CredentialUsageType">
+ <annotation>
+ <documentation>
+ Usage type for this credential. Acceptable values are "Encryption" or "Signing". If no usage type is
+ given components may choose to use the credential for either encryption or signing operations.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+
+ <simpleType name="CredentialUsageType">
+ <restriction base="string">
+ <enumeration value="Encryption"/>
+ <enumeration value="Signing"/>
+ </restriction>
+ </simpleType>
+
+ <complexType name="PasswordBearingString">
+ <simpleContent>
+ <extension base="string">
+ <attribute name="password" type="string">
+ <annotation>
+ <documentation>
+ Password associated with the resource identified by elements of this type.
+ </documentation>
+ </annotation>
+ </attribute>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <!-- VALIDATION RELATED OBJECTS, FOR EXAMPLE PKIX INFO -->
+ <element name="ValidationInfo" type="sec:ValidationInfoType"/>
+
+ <element name="ValidationOptions" type="sec:ValidationOptionsType"/>
+
+ <complexType name="PKIXInline">
+ <annotation>
+ <documentation>
+ Allows PKIX validation info components to be specified as content within the child elements.
+ Certificates and CRLs may be PKCS#12, DER, or PEM encoded and may be encrypted or not.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:PKIXValidationInfoType"/>
+ </complexContent>
+ </complexType>
+
+ <complexType name="PKIXResourceBacked">
+ <annotation>
+ <documentation>
+ Allows PKIX validation info components to be specified by a Spring Resource specification.
+ Certificates, and CRLs may be PKCS#12, DER, or PEM encoded and may be encrypted or not.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:PKIXValidationInfoType"/>
+ </complexContent>
+ </complexType>
+
+ <complexType name="PKIXValidationInfoType" abstract="true">
+ <annotation>
+ <documentation>
+ Defines the components of a set of PKIX validation information.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:ValidationInfoType">
+ <sequence>
+ <element name="Certificate" minOccurs="0" maxOccurs="unbounded">
+ <annotation>
+ <documentation>
+ Trusted certificates, typically of root and intermediate CA's , which are used
+ as input to the PKIX validation process.
+ </documentation>
+ </annotation>
+ </element>
+ <element name="CRL" minOccurs="0" maxOccurs="unbounded">
+ <annotation>
+ <documentation>
+ Certificate revocation lists which are used as input to the PKIX validation process.
+ </documentation>
+ </annotation>
+ </element>
+ </sequence>
+ <attribute name="verifyDepth" type="sec:string">
+ <annotation>
+ <documentation>
+ The maximum path verification depth to consider when constructing a PKIX cert path.
+ </documentation>
+ </annotation>
+ </attribute>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="ValidationInfoType" abstract="true">
+ <annotation>
+ <documentation>Base type for validation information.</documentation>
+ </annotation>
+ <attribute name="id" type="sec:string" use="required">
+ <annotation>
+ <documentation>Unique id for this validation info set.</documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+
+ <complexType name="ValidationOptionsType">
+ <annotation>
+ <documentation>Type for basic PKIX validation options set for PKIX trust engines.</documentation>
+ </annotation>
+ <attribute name="processEmptyCRLs" type="sec:string">
+ <annotation>
+ <documentation>Flag as to whether empty CRL's will be processed. Defaults to true.</documentation>
+ </annotation>
+ </attribute>
+ <attribute name="processExpiredCRLs" type="sec:string">
+ <annotation>
+ <documentation>Flag as to whether expired CRL's will be processed. Defaults to true.</documentation>
+ </annotation>
+ </attribute>
+ <attribute name="processCredentialCRLs" type="sec:string">
+ <annotation>
+ <documentation>
+ Flag as to whether CRL's supplied in the untrusted credential
+ being evaluated will be processed. Defaults to true.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="defaultVerificationDepth" type="sec:string">
+ <annotation>
+ <documentation>Default PKIX path verification depth. Defaults to 1.</documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+
+ <complexType name="CertPathValidationOptionsType">
+ <annotation>
+ <documentation>
+ Type specialization for PKIX validation options set for PKIX trust engines
+ using the Java CertPath API.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:ValidationOptionsType">
+ <sequence>
+ <element name="PolicyOID" type="sec:string" minOccurs="0" maxOccurs="unbounded">
+ <annotation>
+ <documentation>
+ Sets the initial policy identifiers (OID strings) for the underlying CertPath Provider,
+ i.e. those policies that are acceptable to the certificate user.
+ See also RFC 5280, section 6.1.1 (c).
+ If no policy identifier is specified, any policy is considered acceptable.
+ </documentation>
+ </annotation>
+ </element>
+ </sequence>
+ <attribute name="forceRevocationEnabled" type="sec:string">
+ <annotation>
+ <documentation>
+ If true, the revocation behavior of the underlying CertPath provider will be forced to the
+ value supplied by the revocationEnabled attribute. If false, the revocation behavior
+ of the underlying provider will be determined by the PKIXTrustEvaluator implementation.
+ Defaults to false.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="revocationEnabled" type="sec:string">
+ <annotation>
+ <documentation>
+ If the attribute forceRevocationEnabled is true, the revocation behavior of the underlying CertPath
+ Provider will be forced to this value. If the former is false, the revocation behavior
+ of the underlying provider will be determined by the PKIXTrustEvaluator implementation.
+ Defaults to true.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="policyMappingInhibit" type="sec:string">
+ <annotation>
+ <documentation>
+ Sets the policy mapping inhibited flag for the underlying CertPath Provider.
+ See also RFC 5280, section 6.1.1 (e).
+ Defaults to false.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="anyPolicyInhibit" type="sec:string">
+ <annotation>
+ <documentation>
+ Sets the any policy inhibited flag for the underlying CertPath Provider.
+ See also RFC 5280, section 6.1.1 (g).
+ Defaults to false.
+ </documentation>
+ </annotation>
+ </attribute>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- TRUST ENGINE RELATED OBJECTS -->
+ <element name="TrustEngine" type="sec:TrustEngineType"/>
+
+ <complexType name="Chaining">
+ <annotation>
+ <documentation>
+ Trust engine which chains together other trust engine instances, evaluating a token
+ against each engine in chain order.
+
+ If the token to be evaluated can be established as trusted by one member of the chain,
+ then the token is trusted. Otherwise it is evaluated as untrusted.
+
+ Trust chain members must all evaluate tokens of a compatible type,
+ for example a Credential or Signature.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:TrustEngineType">
+ <choice minOccurs="1" maxOccurs="unbounded">
+ <element ref="sec:TrustEngine"/>
+ <element name="TrustEngineRef">
+ <annotation>
+ <documentation>Reference to a trust engine.</documentation>
+ </annotation>
+ <complexType>
+ <attribute name="ref">
+ <annotation>
+ <documentation>Bean reference id for a trust engine declared elsewhere.</documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+ </choice>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="SignatureChaining">
+ <annotation>
+ <documentation>
+ Trust engine which chains together other signature trust engine instances, evaluating the signature
+ against each engine in chain order.
+
+ If the signature to be evaluated can be established as trusted by one member of the chain,
+ then the signature is trusted. Otherwise it is evaluated as untrusted.
+
+ Trust chain members must all evaluate signatures.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:TrustEngineType">
+ <choice minOccurs="1" maxOccurs="unbounded">
+ <element ref="sec:TrustEngine"/>
+ <element name="TrustEngineRef">
+ <annotation>
+ <documentation>Reference to a trust engine.</documentation>
+ </annotation>
+ <complexType>
+ <attribute name="ref">
+ <annotation>
+ <documentation>Bean reference id for a trust engine declared elsewhere.</documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+ </choice>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Trust engines which use resolvers configured via static information -->
+ <complexType name="StaticExplicitKey">
+ <annotation>
+ <documentation>
+ Trust engine used to validate a key against statically-configured trusted keys.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:TrustEngineType">
+ <sequence>
+ <element ref="sec:Credential" minOccurs="1" maxOccurs="unbounded">
+ <annotation>
+ <documentation>
+ A trusted credential to be included in the static trusted credential set.
+ </documentation>
+ </annotation>
+ </element>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="StaticPKIXX509Credential">
+ <annotation>
+ <documentation>
+ Trust engine used to validate an X509 credential against statically-configured PKIX information.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:TrustEngineType">
+ <sequence>
+ <element name="TrustedName" type="sec:string" minOccurs="0" maxOccurs="unbounded">
+ <annotation>
+ <documentation>
+ Specifies a trusted name against which the target entity
+ certificate's public key must be bound for trust processing to be successful.
+
+ Supported trusted name formats are:
+ 1) Subject DN in RFC 2253 or RFC 1779 format
+ 2) CN component of subject DN
+ 3) Subject alt names (DNS and URI types)
+
+ If multiple instances of this element are present, trust processing
+ is successful if the target entity certificate matches at least one of them.
+
+ Trusted names are ignored and therefore optional if trustedNameCheckEnabled = false.
+ </documentation>
+ </annotation>
+ </element>
+ <element ref="sec:ValidationInfo" minOccurs="1" maxOccurs="unbounded">
+ <annotation>
+ <documentation>
+ PKIX validation info against which to validate an X509 credential.
+ </documentation>
+ </annotation>
+ </element>
+ <element ref="sec:ValidationOptions" minOccurs="0" maxOccurs="1">
+ <annotation>
+ <documentation>
+ Set of options to influence PKIX trust validation processing.
+ </documentation>
+ </annotation>
+ </element>
+ </sequence>
+ <attribute name="trustedNameCheckEnabled" type="sec:string">
+ <annotation>
+ <documentation>
+ If true, the candidate X509Crednetial's certificate must match one of the
+ names indicated via the TrustedName child elements.
+ Defaults to true.
+ </documentation>
+ </annotation>
+ </attribute>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="StaticExplicitKeySignature">
+ <annotation>
+ <documentation>
+ Trust engine used to validate a signature against statically-configured trusted keys.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:TrustEngineType">
+ <sequence>
+ <element ref="sec:Credential" minOccurs="1" maxOccurs="unbounded">
+ <annotation>
+ <documentation>
+ A trusted credential to be included in the static trusted credential set.
+ </documentation>
+ </annotation>
+ </element>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="StaticPKIXSignature">
+ <annotation>
+ <documentation>
+ Trust engine used to validate signatures against statically-configured PKIX information.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="sec:TrustEngineType">
+ <sequence>
+ <element name="TrustedName" type="sec:string" minOccurs="0" maxOccurs="unbounded">
+ <annotation>
+ <documentation>
+ Specifies a trusted name against which the target entity
+ certificate's public key must be bound for trust processing to be successful.
+
+ Supported trusted name formats are:
+ 1) Subject DN in RFC 2253 or RFC 1779 format
+ 2) CN component of subject DN
+ 3) Subject alt names (DNS and URI types)
+
+ If multiple instances of this element are present, trust processing
+ is successful if the target entity certificate matches at least one of them.
+
+ Trusted names are ignored and therefore optional if trustedNameCheckEnabled=false.
+ </documentation>
+ </annotation>
+ </element>
+ <element ref="sec:ValidationInfo" minOccurs="1" maxOccurs="unbounded">
+ <annotation>
+ <documentation>
+ PKIX validation info against which to validate a signature.
+ </documentation>
+ </annotation>
+ </element>
+ <element ref="sec:ValidationOptions" minOccurs="0" maxOccurs="1">
+ <annotation>
+ <documentation>
+ Set of options to influence PKIX trust validation processing.
+ </documentation>
+ </annotation>
+ </element>
+ </sequence>
+ <attribute name="trustedNameCheckEnabled" type="sec:string">
+ <annotation>
+ <documentation>
+ If true, the candidate X509Crednetial's certificate must match one of the
+ names indicated via the TrustedName child elements.
+ Defaults to true.
+ </documentation>
+ </annotation>
+ </attribute>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="TrustEngineType" abstract="true">
+ <attribute name="id" type="sec:string" use="required">
+ <annotation>
+ <documentation>
+ Unique ID of the trust engine.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+
+ <simpleType name="string">
+ <restriction base="string">
+ <minLength value="1"/>
+ </restriction>
+ </simpleType>
+
+</schema>
diff --git a/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/AbstractSecurityParserTest.java b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/AbstractSecurityParserTest.java
new file mode 100644
index 000000000..667fc32f1
--- /dev/null
+++ b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/AbstractSecurityParserTest.java
@@ -0,0 +1,97 @@
+
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+
+import net.shibboleth.ext.spring.util.ApplicationContextBuilder;
+
+import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.mock.env.MockPropertySource;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeSuite;
+
+/**
+ * Base mechanics for Security parser tests
+ */
+ at SuppressWarnings("javadoc")
+public class AbstractSecurityParserTest {
+
+ private static final String PATH = "/net/shibboleth/spring/security/";
+
+ protected static final String SP_ID = "https://sp.example.org/sp/shibboleth";
+ protected static final String IDP_ID = "https://idp.example.org/idp/shibboleth";
+
+ static private String workspaceDirName;
+
+ private GenericApplicationContext pendingTeardownContext = null;
+
+ @AfterMethod public void tearDownTestContext() {
+ if (null == pendingTeardownContext ) {
+ return;
+ }
+ pendingTeardownContext.close();
+ pendingTeardownContext = null;
+ }
+
+ protected void setTestContext(final GenericApplicationContext context) {
+ tearDownTestContext();
+ pendingTeardownContext = context;
+ }
+
+ @BeforeSuite public void setupDirs() throws IOException {
+ final ClassPathResource resource = new ClassPathResource(PATH);
+ workspaceDirName = resource.getFile().getAbsolutePath();
+ }
+
+ protected <T> T getBean(final Class<T> claz, final String... files) throws IOException{
+ return getBean(null, claz, files);
+ }
+
+ protected <T> T getBean(final String name, final Class<T> claz, final String... files) throws IOException{
+ final Resource[] resources = new Resource[files.length];
+
+ for (int i = 0; i < files.length; i++) {
+ resources[i] = new ClassPathResource(PATH + files[i]);
+ }
+
+ final ApplicationContextBuilder builder = new ApplicationContextBuilder();
+
+ builder.setName("ApplicationContext: " + claz);
+
+ final MockPropertySource mockEnvVars = new MockPropertySource();
+ mockEnvVars.setProperty("DIR", workspaceDirName);
+ builder.setPropertySources(Collections.singletonList(mockEnvVars));
+
+ builder.setServiceConfigurations(Arrays.asList(resources));
+
+ final GenericApplicationContext context = builder.build();
+
+ setTestContext(context);
+
+ if (name != null) {
+ return context.getBean(name, claz);
+ }
+ return context.getBean(claz);
+ }
+}
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/credential/BasicInlineParserTest.java b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/credential/BasicInlineParserTest.java
new file mode 100644
index 000000000..725fe7421
--- /dev/null
+++ b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/credential/BasicInlineParserTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.credential;
+
+import java.io.IOException;
+
+import javax.crypto.SecretKey;
+
+import org.opensaml.security.credential.BasicCredential;
+import org.opensaml.security.credential.Credential;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.spring.security.AbstractSecurityParserTest;
+
+/**
+ * test parsing Basic Inline Credentials
+ */
+ at SuppressWarnings("javadoc")
+public class BasicInlineParserTest extends AbstractSecurityParserTest {
+
+ @Test public void publicOnly() throws IOException {
+ final BasicCredential credential =
+ (BasicCredential) getBean(Credential.class, "credential/inlinePublicOnly.xml");
+
+ Assert.assertNull(credential.getPrivateKey());
+ }
+/*
+ @Test(expectedExceptions={BeanCreationException.class,}) public void wrongCert() throws IOException {
+ getBean(Credential.class, true, "credential/inlineWrongCert.xml");
+ }
+ */
+ @Test public void publicPrivate() throws IOException {
+ final BasicCredential credential =
+ (BasicCredential) getBean(Credential.class, "credential/inlinePublicPrivate.xml");
+ Assert.assertNotNull(credential.getPrivateKey());
+
+ }
+
+ @Test public void secretBase64() throws IOException {
+ final BasicCredential credential =
+ (BasicCredential) getBean(Credential.class, "credential/secretKeyAESBase64.xml");
+ Assert.assertNotNull(credential.getSecretKey());
+ SecretKey key = credential.getSecretKey();
+ Assert.assertEquals(key.getAlgorithm(), "AES");
+ }
+
+ @Test public void secretHex() throws IOException {
+ final BasicCredential credential =
+ (BasicCredential) getBean(Credential.class, "credential/secretKeyAESHex.xml");
+ Assert.assertNotNull(credential.getSecretKey());
+ SecretKey key = credential.getSecretKey();
+ Assert.assertEquals(key.getAlgorithm(), "AES");
+ }
+
+}
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/credential/BasicResourceParserTest.java b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/credential/BasicResourceParserTest.java
new file mode 100644
index 000000000..d483c32fd
--- /dev/null
+++ b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/credential/BasicResourceParserTest.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.credential;
+
+import java.io.IOException;
+
+import javax.crypto.SecretKey;
+
+import org.opensaml.security.credential.BasicCredential;
+import org.opensaml.security.credential.Credential;
+import org.springframework.beans.factory.BeanCreationException;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.spring.security.AbstractSecurityParserTest;
+
+/**
+ * test parsing Basic File System and Resource Credentials
+ */
+ at SuppressWarnings("javadoc")
+public class BasicResourceParserTest extends AbstractSecurityParserTest {
+
+ @Test public void publicOnly() throws IOException {
+ final BasicCredential credential =
+ (BasicCredential) getBean(Credential.class, "credential/resourcePublicOnly.xml");
+
+ Assert.assertNull(credential.getPrivateKey());
+ }
+
+ @Test(expectedExceptions={BeanCreationException.class,}) public void wrongCert() throws IOException {
+ getBean(Credential.class, "credential/resourceWrongPublic.xml");
+ }
+
+ @Test public void publicPrivate() throws IOException {
+ final BasicCredential credential =
+ (BasicCredential) getBean(Credential.class, "credential/resourcePublicPrivate.xml");
+ Assert.assertNotNull(credential.getPrivateKey());
+
+ }
+
+ @Test public void secretBase64() throws IOException {
+ final BasicCredential credential =
+ (BasicCredential) getBean(Credential.class, "credential/resourceSecretAESBase64.xml");
+ Assert.assertNotNull(credential.getSecretKey());
+ SecretKey key = credential.getSecretKey();
+ Assert.assertEquals(key.getAlgorithm(), "AES");
+ }
+
+ @Test public void secretHex() throws IOException {
+ final BasicCredential credential =
+ (BasicCredential) getBean(Credential.class, "credential/resourceSecretAESHex.xml");
+ Assert.assertNotNull(credential.getSecretKey());
+ SecretKey key = credential.getSecretKey();
+ Assert.assertEquals(key.getAlgorithm(), "AES");
+ }
+
+ @Test public void secretBinary() throws IOException {
+ final BasicCredential credential =
+ (BasicCredential) getBean(Credential.class, "credential/resourceSecretAESBinary.xml");
+ Assert.assertNotNull(credential.getSecretKey());
+ SecretKey key = credential.getSecretKey();
+ Assert.assertEquals(key.getAlgorithm(), "AES");
+ }
+
+}
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/credential/X509FilesystemParserTest.java b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/credential/X509FilesystemParserTest.java
new file mode 100644
index 000000000..9c54bc64c
--- /dev/null
+++ b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/credential/X509FilesystemParserTest.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.credential;
+
+import java.io.IOException;
+import java.time.Instant;
+
+import org.opensaml.security.credential.Credential;
+import org.opensaml.security.credential.UsageType;
+import org.opensaml.security.x509.BasicX509Credential;
+import org.springframework.beans.factory.BeanCreationException;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.spring.security.AbstractSecurityParserTest;
+
+/**
+ * test parsing X509 Filesystem Credentials
+ */
+ at SuppressWarnings("javadoc")
+public class X509FilesystemParserTest extends AbstractSecurityParserTest {
+
+ private BasicX509Credential lookup(String file) throws IOException {
+ return (BasicX509Credential) getBean(Credential.class, "credential/" + file);
+ }
+
+ @Test public void certOnly() throws IOException {
+ final BasicX509Credential credential = lookup("resourceCertOnly.xml");
+
+ Assert.assertEquals(credential.getEntityCertificateChain().size(), 1);
+ Assert.assertTrue(credential.getEntityCertificateChain().contains(credential.getEntityCertificate()));
+
+ Assert.assertEquals(credential.getEntityCertificate().getNotAfter().getTime(),
+ Instant.parse("2024-04-08T13:39:18Z").toEpochMilli());
+ }
+
+ @Test(expectedExceptions = {BeanCreationException.class,}) public void twoCert() throws IOException {
+ lookup("resourceTwoCert.xml");
+ }
+
+ @Test(expectedExceptions = {BeanCreationException.class,}) public void wrongCert() throws IOException {
+ lookup("resourceWrongCert.xml");
+ }
+
+ @Test public void certKeyCrl() throws IOException {
+ final BasicX509Credential credential = lookup("resourceKeyCertCrl.xml");
+
+ Assert.assertEquals(credential.getEntityCertificate().getNotAfter().getTime(),
+ Instant.parse("2024-04-08T13:39:18Z").toEpochMilli());
+ Assert.assertEquals(credential.getEntityCertificateChain().size(), 3);
+ Assert.assertTrue(credential.getEntityCertificateChain().contains(credential.getEntityCertificate()));
+ Assert.assertEquals(credential.getCRLs().size(), 1);
+ Assert.assertEquals(credential.getCRLs().iterator().next().getNextUpdate().getTime(),
+ Instant.parse("2007-09-02T14:14:48Z").toEpochMilli());
+ }
+
+ @Test public void certElementsKeyNames() throws IOException {
+ final BasicX509Credential credential = lookup("resourceCertElementsKeyName.xml");
+
+ Assert.assertEquals(credential.getEntityCertificateChain().size(), 1);
+ Assert.assertTrue(credential.getEntityCertificateChain().contains(credential.getEntityCertificate()));
+
+ Assert.assertEquals(credential.getEntityCertificate().getNotAfter().getTime(),
+ Instant.parse("2024-04-08T13:39:18Z").toEpochMilli());
+
+ Assert.assertEquals(credential.getUsageType(), UsageType.SIGNING);
+ Assert.assertEquals(credential.getKeyNames().size(), 2);
+ Assert.assertTrue(credential.getKeyNames().contains("Name1"));
+ Assert.assertTrue(credential.getKeyNames().contains("Name2"));
+
+ }
+
+}
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/credential/X509InlineParserTest.java b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/credential/X509InlineParserTest.java
new file mode 100644
index 000000000..e830f43f4
--- /dev/null
+++ b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/credential/X509InlineParserTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.credential;
+
+import java.io.IOException;
+import java.time.Instant;
+
+import org.opensaml.security.credential.Credential;
+import org.opensaml.security.x509.BasicX509Credential;
+import org.springframework.beans.factory.BeanCreationException;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.spring.security.AbstractSecurityParserTest;
+
+/**
+ * test parsing X509 Inline Credentials
+ */
+ at SuppressWarnings("javadoc")
+public class X509InlineParserTest extends AbstractSecurityParserTest {
+
+ @Test public void certOnly() throws IOException {
+ final BasicX509Credential credential =
+ (BasicX509Credential) getBean(Credential.class, "credential/inlineCertOnly.xml");
+
+ Assert.assertEquals(credential.getEntityCertificateChain().size(), 1);
+ Assert.assertTrue(credential.getEntityCertificateChain().contains(credential.getEntityCertificate()));
+
+ Assert.assertEquals(credential.getEntityCertificate().getNotAfter().getTime(), Instant.parse("2024-04-08T13:39:18Z").toEpochMilli());
+ }
+
+ @Test(expectedExceptions={BeanCreationException.class,}) public void wrongCert() throws IOException {
+ getBean(Credential.class, "credential/inlineWrongCert.xml");
+ }
+
+ @Test public void certKeyCrl() throws IOException {
+ final BasicX509Credential credential =
+ (BasicX509Credential) getBean(Credential.class, "credential/inlineKeyCertCrl.xml");
+
+ Assert.assertEquals(credential.getEntityCertificate().getNotAfter().getTime(), Instant.parse("2024-04-08T13:39:18Z").toEpochMilli());
+ Assert.assertEquals(credential.getEntityCertificateChain().size(), 3);
+ Assert.assertTrue(credential.getEntityCertificateChain().contains(credential.getEntityCertificate()));
+ Assert.assertEquals(credential.getCRLs().size(), 1);
+ Assert.assertEquals(credential.getCRLs().iterator().next().getNextUpdate().getTime(), Instant.parse("2007-09-02T14:14:48Z").toEpochMilli());
+ }
+
+}
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/ChainingTrustEngineTest.java b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/ChainingTrustEngineTest.java
new file mode 100644
index 000000000..b85a0ce61
--- /dev/null
+++ b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/ChainingTrustEngineTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import java.io.IOException;
+
+import org.opensaml.security.SecurityException;
+import org.opensaml.security.trust.impl.ChainingTrustEngine;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.spring.security.AbstractSecurityParserTest;
+
+ at SuppressWarnings("javadoc")
+public class ChainingTrustEngineTest extends AbstractSecurityParserTest {
+
+ private ChainingTrustEngine<?> lookup(String file) throws IOException {
+ return getBean(ChainingTrustEngine.class, "trust/" + file);
+ }
+
+
+ @Test public void one() throws IOException, SecurityException {
+ final ChainingTrustEngine<?> engine = lookup("chainingTrue.xml");
+
+ Assert.assertEquals(engine.getChain().size(), 1);
+ Assert.assertTrue(engine.validate(null, null));
+ }
+
+ @Test public void two() throws IOException, SecurityException {
+ final ChainingTrustEngine<?> engine = lookup("chainingTrueFalse.xml");
+
+ Assert.assertEquals(engine.getChain().size(), 2);
+ Assert.assertTrue(engine.validate(null, null));
+ }
+}
diff --git a/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/MockTrustEngine.java b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/MockTrustEngine.java
new file mode 100644
index 000000000..9acb8046f
--- /dev/null
+++ b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/MockTrustEngine.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+
+import org.opensaml.security.SecurityException;
+import org.opensaml.security.trust.TrustEngine;
+
+ at SuppressWarnings("javadoc")
+public class MockTrustEngine<T> implements TrustEngine<T> {
+
+ private final boolean result;
+
+ /**
+ * Constructor.
+ *
+ * @param retVal ...
+ */
+ public MockTrustEngine(boolean retVal) {
+ result = retVal;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean validate(T token, CriteriaSet trustBasisCriteria) throws SecurityException {
+ return result;
+ }
+
+}
diff --git a/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/PKIXFilesystemParserTest.java b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/PKIXFilesystemParserTest.java
new file mode 100644
index 000000000..10ad84717
--- /dev/null
+++ b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/PKIXFilesystemParserTest.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import java.io.IOException;
+
+import org.opensaml.security.x509.PKIXValidationInformation;
+import org.opensaml.security.x509.impl.BasicPKIXValidationInformation;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.spring.security.AbstractSecurityParserTest;
+
+/**
+ * test for parsing of filesystem backed ValidationInfo
+ */
+ at SuppressWarnings("javadoc")
+public class PKIXFilesystemParserTest extends AbstractSecurityParserTest {
+
+ private BasicPKIXValidationInformation lookup(String file) throws IOException {
+ return (BasicPKIXValidationInformation) getBean(PKIXValidationInformation.class, "trust/" + file);
+ }
+
+ @Test public void simple() throws IOException {
+ final BasicPKIXValidationInformation info = lookup("resourceValidationInfo.xml");
+ Assert.assertNull(info.getVerificationDepth());
+ Assert.assertTrue(info.getCertificates().isEmpty());
+ Assert.assertTrue(info.getCRLs().isEmpty());
+ }
+
+ @Test public void complex() throws IOException {
+ final BasicPKIXValidationInformation info = lookup("resourceValidationInfoValues.xml");
+ Assert.assertEquals(info.getVerificationDepth().intValue(), 99);
+ Assert.assertEquals(info.getCertificates().size(), 2);
+ Assert.assertEquals(info.getCRLs().size(), 1);
+ }
+}
diff --git a/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/PKIXInlineParserTest.java b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/PKIXInlineParserTest.java
new file mode 100644
index 000000000..8fb6d60d3
--- /dev/null
+++ b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/PKIXInlineParserTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import java.io.IOException;
+
+import org.opensaml.security.x509.PKIXValidationInformation;
+import org.opensaml.security.x509.impl.BasicPKIXValidationInformation;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.spring.security.AbstractSecurityParserTest;
+
+/**
+ * test for parsing of inline ValidationInfo
+ */
+ at SuppressWarnings("javadoc")
+public class PKIXInlineParserTest extends AbstractSecurityParserTest {
+
+ private BasicPKIXValidationInformation lookup(String file) throws IOException {
+ return (BasicPKIXValidationInformation) getBean(PKIXValidationInformation.class, "trust/" + file);
+ }
+
+ @Test public void simple() throws IOException {
+ final BasicPKIXValidationInformation info = lookup("inlineValidationInfo.xml");
+ Assert.assertNull(info.getVerificationDepth());
+ Assert.assertTrue(info.getCertificates().isEmpty());
+ Assert.assertTrue(info.getCRLs().isEmpty());
+ }
+
+ @Test(enabled=true) public void complex() throws IOException {
+ final BasicPKIXValidationInformation info = lookup("inlineValidationInfoValues.xml");
+ Assert.assertEquals(info.getVerificationDepth().intValue(), 98);
+ Assert.assertEquals(info.getCertificates().size(), 2);
+ Assert.assertEquals(info.getCRLs().size(), 1);
+ }
+
+}
diff --git a/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/PKIXValidationOptionsParserTest.java b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/PKIXValidationOptionsParserTest.java
new file mode 100644
index 000000000..470ddf5a5
--- /dev/null
+++ b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/PKIXValidationOptionsParserTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import java.io.IOException;
+
+import org.opensaml.security.x509.PKIXValidationOptions;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.spring.security.AbstractSecurityParserTest;
+
+/**
+ * Test for {@link PKIXValidationOptionsParser}.
+ */
+ at SuppressWarnings("javadoc")
+public class PKIXValidationOptionsParserTest extends AbstractSecurityParserTest {
+
+
+ @Test public void simple() throws IOException {
+ PKIXValidationOptions what = getBean(PKIXValidationOptions.class, "trust/validationOptions.xml");
+
+ Assert.assertTrue(what.isProcessCredentialCRLs());
+ Assert.assertTrue(what.isProcessEmptyCRLs());
+ Assert.assertTrue(what.isProcessExpiredCRLs());
+ Assert.assertEquals(what.getDefaultVerificationDepth(), Integer.valueOf(1));
+ }
+
+ @Test public void complex() throws IOException {
+ PKIXValidationOptions what = getBean(PKIXValidationOptions.class, "trust/validationOptionsValues.xml");
+
+ Assert.assertFalse(what.isProcessCredentialCRLs());
+ Assert.assertFalse(what.isProcessEmptyCRLs());
+ Assert.assertTrue(what.isProcessExpiredCRLs());
+ Assert.assertEquals(what.getDefaultVerificationDepth(), Integer.valueOf(2));
+ }
+
+}
diff --git a/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/SignatureChainingParserTest.java b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/SignatureChainingParserTest.java
new file mode 100644
index 000000000..02bc60822
--- /dev/null
+++ b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/SignatureChainingParserTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import java.io.IOException;
+import java.time.Instant;
+
+import net.shibboleth.spring.security.AbstractSecurityParserTest;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+import org.opensaml.security.credential.impl.StaticCredentialResolver;
+import org.opensaml.security.trust.TrustedCredentialTrustEngine;
+import org.opensaml.security.x509.BasicX509Credential;
+import org.opensaml.xmlsec.signature.support.impl.ChainingSignatureTrustEngine;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * test for xsi:type="security:StaticExplicitKeySignature".
+ */
+ at SuppressWarnings("javadoc")
+public class SignatureChainingParserTest extends AbstractSecurityParserTest {
+
+ @Test public void simple() throws IOException, ResolverException {
+ final ChainingSignatureTrustEngine chain = getBean(ChainingSignatureTrustEngine.class, "trust/chain.xml");
+
+ Assert.assertEquals(chain.getChain().size(),2);
+
+ final TrustedCredentialTrustEngine<?> engine = (TrustedCredentialTrustEngine<?>) chain.getChain().get(1);
+
+ final StaticCredentialResolver resolver = (StaticCredentialResolver) engine.getCredentialResolver();
+
+ BasicX509Credential credential = (BasicX509Credential) resolver.resolveSingle(null);
+
+ Assert.assertEquals(credential.getEntityCertificateChain().size(), 1);
+ Assert.assertTrue(credential.getEntityCertificateChain().contains(credential.getEntityCertificate()));
+
+ Assert.assertEquals(credential.getEntityCertificate().getNotAfter().getTime(), Instant.parse("2024-04-08T13:39:18Z").toEpochMilli());
+
+ }
+}
diff --git a/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/StaticExplicitKeyParserTest.java b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/StaticExplicitKeyParserTest.java
new file mode 100644
index 000000000..351eb66d8
--- /dev/null
+++ b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/StaticExplicitKeyParserTest.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import java.io.IOException;
+import java.time.Instant;
+
+import net.shibboleth.spring.security.AbstractSecurityParserTest;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+import org.opensaml.security.credential.impl.StaticCredentialResolver;
+import org.opensaml.security.trust.TrustEngine;
+import org.opensaml.security.trust.impl.ExplicitKeyTrustEngine;
+import org.opensaml.security.x509.BasicX509Credential;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * test for xsi:type="security:StaticExplicitKeySignature".
+ */
+ at SuppressWarnings("javadoc")
+public class StaticExplicitKeyParserTest extends AbstractSecurityParserTest {
+
+ @Test public void simple() throws IOException, ResolverException {
+ final ExplicitKeyTrustEngine engine = (ExplicitKeyTrustEngine) getBean(TrustEngine.class, "trust/staticExplicit.xml");
+
+ final StaticCredentialResolver resolver = (StaticCredentialResolver) engine.getCredentialResolver();
+
+ BasicX509Credential credential = (BasicX509Credential) resolver.resolveSingle(null);
+
+ Assert.assertEquals(credential.getEntityCertificateChain().size(), 1);
+ Assert.assertTrue(credential.getEntityCertificateChain().contains(credential.getEntityCertificate()));
+
+ Assert.assertEquals(credential.getEntityCertificate().getNotAfter().getTime(), Instant.parse("2024-04-08T13:39:18Z").toEpochMilli());
+
+ }
+}
diff --git a/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/StaticExplicitKeySignatureParserTest.java b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/StaticExplicitKeySignatureParserTest.java
new file mode 100644
index 000000000..943fb210e
--- /dev/null
+++ b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/StaticExplicitKeySignatureParserTest.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import java.io.IOException;
+import java.time.Instant;
+
+import net.shibboleth.spring.security.AbstractSecurityParserTest;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+import org.opensaml.security.credential.impl.StaticCredentialResolver;
+import org.opensaml.security.trust.TrustEngine;
+import org.opensaml.security.trust.TrustedCredentialTrustEngine;
+import org.opensaml.security.x509.BasicX509Credential;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * test for xsi:type="security:StaticExplicitKeySignature".
+ */
+ at SuppressWarnings("javadoc")
+public class StaticExplicitKeySignatureParserTest extends AbstractSecurityParserTest {
+
+ @Test public void simple() throws IOException, ResolverException {
+ final TrustedCredentialTrustEngine<?> engine = (TrustedCredentialTrustEngine<?>) getBean(TrustEngine.class, "trust/staticExplicitSignature.xml");
+
+ final StaticCredentialResolver resolver = (StaticCredentialResolver) engine.getCredentialResolver();
+
+ BasicX509Credential credential = (BasicX509Credential) resolver.resolveSingle(null);
+
+ Assert.assertEquals(credential.getEntityCertificateChain().size(), 1);
+ Assert.assertTrue(credential.getEntityCertificateChain().contains(credential.getEntityCertificate()));
+
+ Assert.assertEquals(credential.getEntityCertificate().getNotAfter().getTime(), Instant.parse("2024-04-08T13:39:18Z").toEpochMilli());
+
+ }
+}
diff --git a/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/StaticPKIXSignatureParserTest.java b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/StaticPKIXSignatureParserTest.java
new file mode 100644
index 000000000..d8b06e175
--- /dev/null
+++ b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/StaticPKIXSignatureParserTest.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import net.shibboleth.spring.security.AbstractSecurityParserTest;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+import org.opensaml.security.trust.TrustEngine;
+import org.opensaml.security.x509.PKIXValidationInformation;
+import org.opensaml.security.x509.PKIXValidationOptions;
+import org.opensaml.security.x509.impl.BasicPKIXValidationInformation;
+import org.opensaml.security.x509.impl.CertPathPKIXTrustEvaluator;
+import org.opensaml.security.x509.impl.CertPathPKIXValidationOptions;
+import org.opensaml.security.x509.impl.StaticPKIXValidationInformationResolver;
+import org.opensaml.xmlsec.signature.support.impl.PKIXSignatureTrustEngine;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * test for xsi:type="security:StaticPKIXKeySignature".
+ */
+ at SuppressWarnings("javadoc")
+public class StaticPKIXSignatureParserTest extends AbstractSecurityParserTest {
+
+ @Test public void simple() throws IOException, ResolverException {
+ final PKIXSignatureTrustEngine engine =
+ (PKIXSignatureTrustEngine) getBean(TrustEngine.class, "trust/staticPKIX.xml");
+
+ Assert.assertNotNull(engine.getX509CredentialNameEvaluator());
+
+ final StaticPKIXValidationInformationResolver resolver =
+ (StaticPKIXValidationInformationResolver) engine.getPKIXResolver();
+ Assert.assertTrue(resolver.resolveTrustedNames(null).isEmpty());
+
+ final List<PKIXValidationInformation> infos = new ArrayList<>();
+ for (final PKIXValidationInformation info : resolver.resolve(null)) {
+ infos.add(info);
+ }
+ Assert.assertEquals(infos.size(), 1);
+
+ final CertPathPKIXTrustEvaluator trustEvaluator = (CertPathPKIXTrustEvaluator) engine.getPKIXTrustEvaluator();
+ final PKIXValidationOptions options = trustEvaluator.getPKIXValidationOptions();
+ Assert.assertTrue(options.isProcessCredentialCRLs());
+ Assert.assertTrue(options.isProcessEmptyCRLs());
+ Assert.assertTrue(options.isProcessExpiredCRLs());
+ Assert.assertEquals(options.getDefaultVerificationDepth().intValue(), 1);
+ }
+
+ @Test public void nameCheckDisabled() throws IOException, ResolverException {
+ final PKIXSignatureTrustEngine engine =
+ (PKIXSignatureTrustEngine) getBean(TrustEngine.class, "trust/staticPKIX-nameCheckDisabled.xml");
+
+ Assert.assertNull(engine.getX509CredentialNameEvaluator());
+
+ final StaticPKIXValidationInformationResolver resolver =
+ (StaticPKIXValidationInformationResolver) engine.getPKIXResolver();
+ Assert.assertTrue(resolver.resolveTrustedNames(null).isEmpty());
+
+ final List<PKIXValidationInformation> infos = new ArrayList<>();
+ for (final PKIXValidationInformation info : resolver.resolve(null)) {
+ infos.add(info);
+ }
+ Assert.assertEquals(infos.size(), 1);
+
+ final CertPathPKIXTrustEvaluator trustEvaluator = (CertPathPKIXTrustEvaluator) engine.getPKIXTrustEvaluator();
+ final PKIXValidationOptions options = trustEvaluator.getPKIXValidationOptions();
+ Assert.assertTrue(options.isProcessCredentialCRLs());
+ Assert.assertTrue(options.isProcessEmptyCRLs());
+ Assert.assertTrue(options.isProcessExpiredCRLs());
+ Assert.assertEquals(options.getDefaultVerificationDepth().intValue(), 1);
+ }
+
+ @Test public void values() throws IOException, ResolverException {
+ final PKIXSignatureTrustEngine engine =
+ (PKIXSignatureTrustEngine) getBean(TrustEngine.class, "trust/staticPKIXValues.xml");
+
+ Assert.assertNotNull(engine.getX509CredentialNameEvaluator());
+
+ final StaticPKIXValidationInformationResolver resolver =
+ (StaticPKIXValidationInformationResolver) engine.getPKIXResolver();
+ final Set<String> tns = resolver.resolveTrustedNames(null);
+ Assert.assertEquals(tns.size(), 3);
+ Assert.assertTrue(tns.contains("Name1"));
+ Assert.assertTrue(tns.contains("Name2"));
+ Assert.assertTrue(tns.contains("Name3"));
+
+ final List<PKIXValidationInformation> infos = new ArrayList<>();
+ for (final PKIXValidationInformation info : resolver.resolve(null)) {
+ infos.add(info);
+ }
+ Assert.assertEquals(infos.size(), 2);
+ final int firstVal = ((BasicPKIXValidationInformation) infos.get(0)).getVerificationDepth().intValue();
+ final int secondVal = ((BasicPKIXValidationInformation) infos.get(1)).getVerificationDepth().intValue();
+
+ Assert.assertTrue((98 == firstVal) || (99 == firstVal));
+ Assert.assertTrue((98 == secondVal) || (99 == secondVal));
+ Assert.assertNotEquals(firstVal, secondVal);
+
+ final CertPathPKIXTrustEvaluator trustEvaluator = (CertPathPKIXTrustEvaluator) engine.getPKIXTrustEvaluator();
+ final PKIXValidationOptions options = trustEvaluator.getPKIXValidationOptions();
+ Assert.assertFalse(options.isProcessCredentialCRLs());
+ Assert.assertFalse(options.isProcessEmptyCRLs());
+ Assert.assertFalse(options.isProcessExpiredCRLs());
+ Assert.assertEquals(options.getDefaultVerificationDepth().intValue(), 2);
+ }
+
+ @Test public void certPath() throws IOException, ResolverException {
+ final PKIXSignatureTrustEngine engine =
+ (PKIXSignatureTrustEngine) getBean(TrustEngine.class, "trust/staticPKIXValuesCertPathOpts.xml");
+
+ Assert.assertNotNull(engine.getX509CredentialNameEvaluator());
+
+ final StaticPKIXValidationInformationResolver resolver =
+ (StaticPKIXValidationInformationResolver) engine.getPKIXResolver();
+ final Set<String> tns = resolver.resolveTrustedNames(null);
+ Assert.assertEquals(tns.size(), 1);
+ Assert.assertTrue(tns.contains("Name1"));
+
+ final List<PKIXValidationInformation> infos = new ArrayList<>();
+ for (final PKIXValidationInformation info : resolver.resolve(null)) {
+ infos.add(info);
+ }
+ Assert.assertEquals(infos.size(), 1);
+ final int value = ((BasicPKIXValidationInformation) infos.get(0)).getVerificationDepth().intValue();
+
+ Assert.assertEquals(value, 99);
+
+ final CertPathPKIXTrustEvaluator trustEvaluator = (CertPathPKIXTrustEvaluator) engine.getPKIXTrustEvaluator();
+ final CertPathPKIXValidationOptions options = (CertPathPKIXValidationOptions) trustEvaluator.getPKIXValidationOptions();
+ Assert.assertFalse(options.isProcessCredentialCRLs());
+ Assert.assertFalse(options.isProcessEmptyCRLs());
+ Assert.assertFalse(options.isProcessExpiredCRLs());
+ Assert.assertEquals(options.getDefaultVerificationDepth().intValue(), 3);
+
+ Assert.assertFalse(options.isRevocationEnabled());
+ Assert.assertTrue(options.isAnyPolicyInhibited());
+ Assert.assertTrue(options.isPolicyMappingInhibited());
+ Assert.assertTrue(options.isForceRevocationEnabled());
+ Assert.assertEquals(options.getInitialPolicies().size(), 1);
+ Assert.assertTrue(options.getInitialPolicies().contains("1234"));
+ }
+
+}
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/StaticPKIXX509CredentialParserTest.java b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/StaticPKIXX509CredentialParserTest.java
new file mode 100644
index 000000000..58a51db41
--- /dev/null
+++ b/shib-metadata-spring/src/test/java/net/shibboleth/spring/security/trust/StaticPKIXX509CredentialParserTest.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.security.trust;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import net.shibboleth.spring.security.AbstractSecurityParserTest;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+import org.opensaml.security.trust.TrustEngine;
+import org.opensaml.security.x509.PKIXValidationInformation;
+import org.opensaml.security.x509.impl.BasicPKIXValidationInformation;
+import org.opensaml.security.x509.impl.CertPathPKIXTrustEvaluator;
+import org.opensaml.security.x509.impl.CertPathPKIXValidationOptions;
+import org.opensaml.security.x509.impl.PKIXX509CredentialTrustEngine;
+import org.opensaml.security.x509.impl.StaticPKIXValidationInformationResolver;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * test for xsi:type="security:StaticPKIXX509CredentialParser".
+ */
+ at SuppressWarnings("javadoc")
+public class StaticPKIXX509CredentialParserTest extends AbstractSecurityParserTest {
+
+ @Test public void certPath() throws IOException, ResolverException {
+ final PKIXX509CredentialTrustEngine engine =
+ (PKIXX509CredentialTrustEngine) getBean(TrustEngine.class, "trust/staticPKIXCredentials.xml");
+
+ Assert.assertNotNull(engine.getX509CredentialNameEvaluator());
+
+ final StaticPKIXValidationInformationResolver resolver =
+ (StaticPKIXValidationInformationResolver) engine.getPKIXResolver();
+ final Set<String> tns = resolver.resolveTrustedNames(null);
+ Assert.assertEquals(tns.size(), 1);
+ Assert.assertTrue(tns.contains("Name1"));
+
+ final List<PKIXValidationInformation> infos = new ArrayList<>();
+ for (final PKIXValidationInformation info : resolver.resolve(null)) {
+ infos.add(info);
+ }
+ Assert.assertEquals(infos.size(), 1);
+ final int value = ((BasicPKIXValidationInformation) infos.get(0)).getVerificationDepth().intValue();
+
+ Assert.assertEquals(value, 99);
+
+ final CertPathPKIXTrustEvaluator trustEvaluator = (CertPathPKIXTrustEvaluator) engine.getPKIXTrustEvaluator();
+ final CertPathPKIXValidationOptions options = (CertPathPKIXValidationOptions) trustEvaluator.getPKIXValidationOptions();
+ Assert.assertFalse(options.isProcessCredentialCRLs());
+ Assert.assertFalse(options.isProcessEmptyCRLs());
+ Assert.assertFalse(options.isProcessExpiredCRLs());
+ Assert.assertEquals(options.getDefaultVerificationDepth().intValue(), 3);
+
+ Assert.assertFalse(options.isRevocationEnabled());
+ Assert.assertTrue(options.isAnyPolicyInhibited());
+ Assert.assertTrue(options.isPolicyMappingInhibited());
+ Assert.assertTrue(options.isForceRevocationEnabled());
+ Assert.assertEquals(options.getInitialPolicies().size(), 1);
+ Assert.assertTrue(options.getInitialPolicies().contains("1234"));
+ }
+
+ @Test public void nameCheckDisabled() throws IOException, ResolverException {
+ final PKIXX509CredentialTrustEngine engine =
+ (PKIXX509CredentialTrustEngine) getBean(TrustEngine.class, "trust/staticPKIXCredentials-nameCheckDisabled.xml");
+
+ Assert.assertNull(engine.getX509CredentialNameEvaluator());
+
+ final StaticPKIXValidationInformationResolver resolver =
+ (StaticPKIXValidationInformationResolver) engine.getPKIXResolver();
+ final Set<String> tns = resolver.resolveTrustedNames(null);
+ Assert.assertEquals(tns.size(), 0);
+
+ final List<PKIXValidationInformation> infos = new ArrayList<>();
+ for (final PKIXValidationInformation info : resolver.resolve(null)) {
+ infos.add(info);
+ }
+ Assert.assertEquals(infos.size(), 1);
+ final int value = ((BasicPKIXValidationInformation) infos.get(0)).getVerificationDepth().intValue();
+
+ Assert.assertEquals(value, 99);
+
+ final CertPathPKIXTrustEvaluator trustEvaluator = (CertPathPKIXTrustEvaluator) engine.getPKIXTrustEvaluator();
+ final CertPathPKIXValidationOptions options = (CertPathPKIXValidationOptions) trustEvaluator.getPKIXValidationOptions();
+ Assert.assertFalse(options.isProcessCredentialCRLs());
+ Assert.assertFalse(options.isProcessEmptyCRLs());
+ Assert.assertFalse(options.isProcessExpiredCRLs());
+ Assert.assertEquals(options.getDefaultVerificationDepth().intValue(), 3);
+
+ Assert.assertFalse(options.isRevocationEnabled());
+ Assert.assertTrue(options.isAnyPolicyInhibited());
+ Assert.assertTrue(options.isPolicyMappingInhibited());
+ Assert.assertTrue(options.isForceRevocationEnabled());
+ Assert.assertEquals(options.getInitialPolicies().size(), 1);
+ Assert.assertTrue(options.getInitialPolicies().contains("1234"));
+ }
+
+
+}
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/aes-base64.txt b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/aes-base64.txt
new file mode 100644
index 000000000..fee2306c9
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/aes-base64.txt
@@ -0,0 +1 @@
+3MvnCRvjjWgqazN4O2cHCw==
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/aes-binary.data b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/aes-binary.data
new file mode 100644
index 000000000..a1e00caa9
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/aes-binary.data
@@ -0,0 +1 @@
+Z T�|�T��e�
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/aes-hex.txt b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/aes-hex.txt
new file mode 100644
index 000000000..a3c8fef1d
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/aes-hex.txt
@@ -0,0 +1 @@
+dccbe7091be38d682a6b33783b67070b
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/cert.pem b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/cert.pem
new file mode 100644
index 000000000..c0df65bc9
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/cert.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDtTCCAp2gAwIBAgIJAPmsD+VGldyPMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDExMTMzOTE4WhcNMjQwNDA4MTMzOTE4WjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAxg0TyQAP/tIvOH89EtaXuRRn8SYzTj7W1TbNY4VvBmobjkRmSkki4hH9
+x4sQpi635wn6WtXTN/FNNmkTK3N/LspmBWxfZS+n+cc7I82E5yvCAPX67QsZgqgg
+lp2W5dvK/FsMMCS6X6SVqzBLMP88NenXKxY+HMxMs0sT0UKYh1cAEqadrHRBO65a
+DBcm5a0sBVYt9K6pgaOHrp/zSIbhnR5tFFLjBbtFktDpHL3AdGBH3OYidNGKBO3t
+J3Ms7LeKXsM0+0Y4P+9fHZINL2X3E2N6GVnKs5PZTg9sP0FtIpAbYm/+zCx7Yj1E
+T/Er8mDd6tNVGSQsn9s5xUBwGqn14wIDAQABo4GnMIGkMB0GA1UdDgQWBBSiQhSu
+p9BYjD2ZuMkEiQK7w/Zq0TB1BgNVHSMEbjBsgBSiQhSup9BYjD2ZuMkEiQK7w/Zq
+0aFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV
+BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAPmsD+VGldyPMAwGA1UdEwQF
+MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHZmIo9GBTSsD5DJfKkCVUvBafwR089H
+BkgVPOuVuEe803BRlKd4BVIsuxAUAy3oqdJYqf9ptPEx8Ef+ALbcDhRbWINhMgO7
+0/S4x3pS9gOn7/Y9yZplOe4Jd2q3R8QBef+hKLcD/Uv0Sqy2nilM8BnMga5tqsL+
+8oFt0blzXtQ2vcOVyNyG326uZBZv2Cf6FXFsYQX1L/tLeTBJegefgGkg2dqCTKIU
+1Qy/Kd2P3/S01kQxjDeG7UfXc9qtelJ68kvzK2d3WOJ2qmsdMxjMNfTItP7FO54M
+i8V7gp9HK+EimdSbgu7xktKlrqA2Rsn+dBoPSgOUs/LOGtCS9/biF0w=
+-----END CERTIFICATE-----
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/certificate.pem b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/certificate.pem
new file mode 100644
index 000000000..d9e8f8606
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/certificate.pem
@@ -0,0 +1,52 @@
+-----BEGIN CERTIFICATE-----
+MIIDSTCCArKgAwIBAgIJAKg8tR5hjVM4MA0GCSqGSIb3DQEBBQUAMHcxCzAJBgNV
+BAYTAlVTMR0wGwYDVQQIExREaXN0cmljdCBvZiBDb2x1bWJpYTETMBEGA1UEBxMK
+V2FzaGluZ3RvbjEeMBwGA1UEChMVR2VvcmdldG93biBVbml2ZXJzaXR5MRQwEgYD
+VQQDEwtleGFtcGxlLm9yZzAeFw0wNzA4MDUxMzA4MDJaFw0xNzA4MDIxMzA4MDJa
+MHcxCzAJBgNVBAYTAlVTMR0wGwYDVQQIExREaXN0cmljdCBvZiBDb2x1bWJpYTET
+MBEGA1UEBxMKV2FzaGluZ3RvbjEeMBwGA1UEChMVR2VvcmdldG93biBVbml2ZXJz
+aXR5MRQwEgYDVQQDEwtleGFtcGxlLm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
+gYkCgYEA5zKHuD5DGPEQH+yLDMIA5M46HwJk7HxlGQ7N9WmkhaI22zXPC0UO8sY4
+AJW/8nlm0pc505iQmbgslg7/JyBemBj1sI7pOp6eCUPs7NR2mwaujXBturiRaJIe
+AX1Gjr3sO+3aLvqxUEu0PWqci4m1uc8XHQCA+PlEQQQnB9UIJwcCAwEAAaOB3DCB
+2TAdBgNVHQ4EFgQUzEhylzE4wmr4FK1lZ7zjR/KmA24wgakGA1UdIwSBoTCBnoAU
+zEhylzE4wmr4FK1lZ7zjR/KmA26he6R5MHcxCzAJBgNVBAYTAlVTMR0wGwYDVQQI
+ExREaXN0cmljdCBvZiBDb2x1bWJpYTETMBEGA1UEBxMKV2FzaGluZ3RvbjEeMBwG
+A1UEChMVR2VvcmdldG93biBVbml2ZXJzaXR5MRQwEgYDVQQDEwtleGFtcGxlLm9y
+Z4IJAKg8tR5hjVM4MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAGfkM
+HUeWzHzsBkwTu+S2vX4gzlJPjiL3RzL40og/qyGz38P4KVg8IQvsGDjs1VFzzcAJ
+I5ULnSocUOTk5sCTjDKT6VILhgAYJ1jnqIo7Z+VC1r3AS9cSDakzqWTc19EFKxEw
+6jeBWaqyykdSiVhCAmG5AJsvk+K032zjkWWMo+0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFmjCCBIKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJVUzEc
+MBoGA1UEChMTSW5Db21tb24gRmVkZXJhdGlvbjEpMCcGA1UEAxMgSW5Db21tb24g
+Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwMzMwMjAzNDAwWhcNMTQwMzI5
+MjAzNDAwWjBWMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTSW5Db21tb24gRmVkZXJh
+dGlvbjEpMCcGA1UEAxMgSW5Db21tb24gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRGjKsUM2QAupLAaWx82/C
+WPalKjKFY8UPmz0T3gf7tJPztTy1Zq8pD0WFRLcQeSBKZGCu8upe8X966b6TZ5yu
+oUDA754If0DWismuHNoMgRR/l0UvZmPWDGRWd3NBTB8/soLA4EbqFf5Xq8MOJKhP
+tzcDR33gtaAb3oilZ+ZTpnhTFFrn/qXrAKcSDBpuW2JRpi3xaF/hTPI097oUShOz
+D1Zj21UYLA6iSFVN+1wlfwilf2KFNK/+zbkCge6wgipZyXxaOAam6ncqmkxy+hy/
+OiJMmdB+6xkO0xXSBUUcqxJrOcUQhA1vntgb3q5zOJISXhC4RAReA0HyBp/wd0iD
+AgMBAAGjggJxMIICbTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
+BgNVHQ4EFgQUky3IYRitY+ObZbOd3Y2TuufKY0UwfgYDVR0jBHcwdYAUky3IYRit
+Y+ObZbOd3Y2TuufKY0WhWqRYMFYxCzAJBgNVBAYTAlVTMRwwGgYDVQQKExNJbkNv
+bW1vbiBGZWRlcmF0aW9uMSkwJwYDVQQDEyBJbkNvbW1vbiBDZXJ0aWZpY2F0aW9u
+IEF1dGhvcml0eYIBADCBugYIKwYBBQUHAQEEga0wgaowgacGCCsGAQUFBzAChoGa
+aHR0cDovL2luY29tbW9uY2ExLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvYnJpZGdl
+L2NlcnRzL2NhLWNlcnRzLnA3YgoJCUNBIElzc3VlcnMgLSBVUkk6aHR0cDovL2lu
+Y29tbW9uY2EyLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvYnJpZGdlL2NlcnRzL2Nh
+LWNlcnRzLnA3YjCBjQYDVR0fBIGFMIGCMD+gPaA7hjlodHRwOi8vaW5jb21tb25j
+cmwxLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvY3JsL2VlY3Jscy5jcmwwP6A9oDuG
+OWh0dHA6Ly9pbmNvbW1vbmNybDIuaW5jb21tb25mZWRlcmF0aW9uLm9yZy9jcmwv
+ZWVjcmxzLmNybDBeBgNVHSAEVzBVMFMGCysGAQQBriMBBAEBMEQwQgYIKwYBBQUH
+AgEWNmh0dHA6Ly9pbmNvbW1vbmNhLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvcHJh
+Y3RpY2VzLnBkZjANBgkqhkiG9w0BAQUFAAOCAQEAZfgKUPA+Ky+Ou/vclMlFTMlU
+GspfbNSdG/fmIq+E/Lv1d2c73Am1zGhOpxgdkM8SE+BPnXW2rl71/N8gaqwgBBxk
+pwn410siumxlDTwV3HoVFvCGWylNy9o8OE1LyTCqfo8PRwrMzhwcagDgD813BIyj
+uJg/JQz1LnHMocIW/JligloSIzF1O435/+ckfWXQsmBIhvV5TmA3ZrcycrI1cHGE
+ZqrCXL0FMZLSr+Vady/tFbVojqI8pSubSMxNkZectePTBjVj1Qeb4hmG8jRv/fwy
+1Iw6OFH8RKny8nQaO5mOe/fF/swEsMVU9TDpvLIgbhTwnP7Nhfotgaxf5wG8WA==
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/crl.pem b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/crl.pem
new file mode 100644
index 000000000..f8036cef1
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/crl.pem
@@ -0,0 +1,19 @@
+-----BEGIN X509 CRL-----
+MIIDBjCCAe4CAQEwDQYJKoZIhvcNAQEEBQAwVjELMAkGA1UEBhMCVVMxHDAaBgNV
+BAoTE0luQ29tbW9uIEZlZGVyYXRpb24xKTAnBgNVBAMTIEluQ29tbW9uIENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5Fw0wNzA4MDMxNDE0NDhaFw0wNzA5MDIxNDE0NDha
+MIHdMBICAQIXDTA0MDMzMTE5NDk0NFowEgIBDhcNMDQwOTE3MTkzMTUxWjASAgEP
+Fw0wNDA5MTcxOTMyMTRaMBICARYXDTA1MDMyMjE3MTYyMFowEgIBHBcNMDUwMjAx
+MTkyOTUxWjASAgE+Fw0wNjA0MDcxNjM1MzFaMBICAUAXDTA2MDQwNzE2MzQ1NFow
+EgIBQRcNMDYwNDEwMTcyMjE1WjASAgFWFw0wNjA3MjAxNzIyMzVaMBICAW8XDTA2
+MTIxOTIwMTQxMVowEwICAIwXDTA3MDMyOTIxMjE0N1qggYMwgYAwfgYDVR0jBHcw
+dYAUky3IYRitY+ObZbOd3Y2TuufKY0WhWqRYMFYxCzAJBgNVBAYTAlVTMRwwGgYD
+VQQKExNJbkNvbW1vbiBGZWRlcmF0aW9uMSkwJwYDVQQDEyBJbkNvbW1vbiBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eYIBADANBgkqhkiG9w0BAQQFAAOCAQEAeCvRTq70
+RJxkxgbV+crqhN6oh3k974GGXhOxYDTTGjYbhK8JnCXkt1uJcnGfl1xyqrozoSrl
+oxoBUmStA8vVqYwtO/FfGpnCyfOG9H2/rAkzbqwr/EXO+MqSd8e1AIJho97i/QSs
+FWp40h7GeanmiZXL6bc4o9cKb0ROtc1n2nYHkLXptf9bFHte2Z/RhbUr8KaPU4b9
+T9PW9a2Z7Oc4BDHpEUcljZL0AlO6mGI2RtDB9RdrtRY6M9YQbBwUcV9r+/+ylfZY
+ugMRDTNUqL72hHKJgmbnfc0CmkcZKHOIGXdGCIX6ewNsLOQnlFAQEVyojQqbzT8w
+s6E8aj6AzPhKyw==
+-----END X509 CRL-----
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/inlineCertOnly.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/inlineCertOnly.xml
new file mode 100644
index 000000000..559000881
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/inlineCertOnly.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="IdPCredential" xsi:type="security:X509Inline">
+ <security:Certificate>
+ MIIDtTCCAp2gAwIBAgIJAPmsD+VGldyPMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
+ BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+ aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDExMTMzOTE4WhcNMjQwNDA4MTMzOTE4WjBF
+ MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
+ ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+ CgKCAQEAxg0TyQAP/tIvOH89EtaXuRRn8SYzTj7W1TbNY4VvBmobjkRmSkki4hH9
+ x4sQpi635wn6WtXTN/FNNmkTK3N/LspmBWxfZS+n+cc7I82E5yvCAPX67QsZgqgg
+ lp2W5dvK/FsMMCS6X6SVqzBLMP88NenXKxY+HMxMs0sT0UKYh1cAEqadrHRBO65a
+ DBcm5a0sBVYt9K6pgaOHrp/zSIbhnR5tFFLjBbtFktDpHL3AdGBH3OYidNGKBO3t
+ J3Ms7LeKXsM0+0Y4P+9fHZINL2X3E2N6GVnKs5PZTg9sP0FtIpAbYm/+zCx7Yj1E
+ T/Er8mDd6tNVGSQsn9s5xUBwGqn14wIDAQABo4GnMIGkMB0GA1UdDgQWBBSiQhSu
+ p9BYjD2ZuMkEiQK7w/Zq0TB1BgNVHSMEbjBsgBSiQhSup9BYjD2ZuMkEiQK7w/Zq
+ 0aFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV
+ BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAPmsD+VGldyPMAwGA1UdEwQF
+ MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHZmIo9GBTSsD5DJfKkCVUvBafwR089H
+ BkgVPOuVuEe803BRlKd4BVIsuxAUAy3oqdJYqf9ptPEx8Ef+ALbcDhRbWINhMgO7
+ 0/S4x3pS9gOn7/Y9yZplOe4Jd2q3R8QBef+hKLcD/Uv0Sqy2nilM8BnMga5tqsL+
+ 8oFt0blzXtQ2vcOVyNyG326uZBZv2Cf6FXFsYQX1L/tLeTBJegefgGkg2dqCTKIU
+ 1Qy/Kd2P3/S01kQxjDeG7UfXc9qtelJ68kvzK2d3WOJ2qmsdMxjMNfTItP7FO54M
+ i8V7gp9HK+EimdSbgu7xktKlrqA2Rsn+dBoPSgOUs/LOGtCS9/biF0w=
+ </security:Certificate>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/inlineKeyCertCrl.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/inlineKeyCertCrl.xml
new file mode 100644
index 000000000..a0d55070b
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/inlineKeyCertCrl.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="IdPCredential" xsi:type="security:X509Inline">
+ <security:PrivateKey>
+ MIIEowIBAAKCAQEAxg0TyQAP/tIvOH89EtaXuRRn8SYzTj7W1TbNY4VvBmobjkRm
+ Skki4hH9x4sQpi635wn6WtXTN/FNNmkTK3N/LspmBWxfZS+n+cc7I82E5yvCAPX6
+ 7QsZgqgglp2W5dvK/FsMMCS6X6SVqzBLMP88NenXKxY+HMxMs0sT0UKYh1cAEqad
+ rHRBO65aDBcm5a0sBVYt9K6pgaOHrp/zSIbhnR5tFFLjBbtFktDpHL3AdGBH3OYi
+ dNGKBO3tJ3Ms7LeKXsM0+0Y4P+9fHZINL2X3E2N6GVnKs5PZTg9sP0FtIpAbYm/+
+ zCx7Yj1ET/Er8mDd6tNVGSQsn9s5xUBwGqn14wIDAQABAoIBAHG6nLv13zmTdS5a
+ UrX4qNPNVgryxs+N4kw51iPqQeFLGVvPB3ZtHSz46+SkhQEJHu37mtqCo3IijRZL
+ rIhtIIG8FG3U18sBXNJgiCN9J26ggB2RI3DvyMxww5X6FOcWGjBkEFGtJaE6n//Y
+ EbWnO+oxyC+j7DMZVoo2+MBYH8LHPXpMPFPhYbf12LpHY+WeNgX/eemMTlSylBln
+ lfhySCtpLcgY7+juYlXaZ9Y1z37QZBcP6yYLTnXJVlhY1KcULh+/PUnmzVpHbkwU
+ v/yQiFGFsve1ROp0ztB6sFufLnvGcTa3T1Oeza9ZaX/zjbMbGp3qjSGoknS23U0Q
+ ZotRB+ECgYEA9EmvBYLWgEayOlZPcBwKZ3Qrwf9ip3xmtubrf9byIozEeQTKvHmA
+ UvK5dKN1pwK0gTaWk5aq+n64HtwJ0+pO4bV32TJJlV/la4xd7wHdH5+S5cdQjd/r
+ tuxyejp5FhqT+x2rKibskEeFKhfgIIolpkcNFIKc9xa3/VBOWPxV19kCgYEAz4vl
+ xJhD8Cf97bm5hemiJPt2eQMCTGCE39O4UaY6xi5lINoySoh8qd2e59nnneG4YaNp
+ tHU23oh00m68Jx8b7wMFliQ/J59lxAkfP262EkBqf/VOAVXQo/iaA8HSwq3Hfwt5
+ 0F4HMQEfB6qf7/LGvFHTQ8+Wn1upZGaYP1YAghsCgYBe3FILmNAExe8luihkx26+
+ 15y6W5qKoUMdmTQv0175TaJpwBOd9qx/CWQ8x9DDBsjjODhmnWZNmXGUAiwKz3zM
+ JvSgMefjCncDOWGskxOz2PppIenE/gQBZ3XYwuYMUEvQgqfZ2X2ZVTx/qP/Ogva1
+ x/drVIDxbjAKPOn/ohUPmQKBgQChW5qfZeIr7Gu3TxW1zxaIuhg5rOU0jDXB7tD2
+ ac54Fcn56KoA2GxThEHu77LrRHodLvcXnamzCVQJ5p3RrJYDFM5bFIMlQv/TkWQB
+ 5QkY14v1P7oNv7IeSUE0epRpVsIrO7jRDsl4h+6f/z+pRY7NCrC9n77y1ki0Di9/
+ zlVG0QKBgFXQkO/bf0Qs3COPWUs5nHyQ/sR0ptx1jrFDSjCdGvBC7NrDlwNP3894
+ EHCUTrEHhjtAGVzyZakZ6PLAN9cf86N1QhvOdj/oasL5vddWyFK74x2/mtp59VOU
+ LaCxnnbG4JoSVX96BSzUFbtRrQbf2+t5ZON9K12IPIxstMkF2j8u
+ </security:PrivateKey>
+ <security:Certificate>
+ MIIDSTCCArKgAwIBAgIJAKg8tR5hjVM4MA0GCSqGSIb3DQEBBQUAMHcxCzAJBgNV
+ BAYTAlVTMR0wGwYDVQQIExREaXN0cmljdCBvZiBDb2x1bWJpYTETMBEGA1UEBxMK
+ V2FzaGluZ3RvbjEeMBwGA1UEChMVR2VvcmdldG93biBVbml2ZXJzaXR5MRQwEgYD
+ VQQDEwtleGFtcGxlLm9yZzAeFw0wNzA4MDUxMzA4MDJaFw0xNzA4MDIxMzA4MDJa
+ MHcxCzAJBgNVBAYTAlVTMR0wGwYDVQQIExREaXN0cmljdCBvZiBDb2x1bWJpYTET
+ MBEGA1UEBxMKV2FzaGluZ3RvbjEeMBwGA1UEChMVR2VvcmdldG93biBVbml2ZXJz
+ aXR5MRQwEgYDVQQDEwtleGFtcGxlLm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
+ gYkCgYEA5zKHuD5DGPEQH+yLDMIA5M46HwJk7HxlGQ7N9WmkhaI22zXPC0UO8sY4
+ AJW/8nlm0pc505iQmbgslg7/JyBemBj1sI7pOp6eCUPs7NR2mwaujXBturiRaJIe
+ AX1Gjr3sO+3aLvqxUEu0PWqci4m1uc8XHQCA+PlEQQQnB9UIJwcCAwEAAaOB3DCB
+ 2TAdBgNVHQ4EFgQUzEhylzE4wmr4FK1lZ7zjR/KmA24wgakGA1UdIwSBoTCBnoAU
+ zEhylzE4wmr4FK1lZ7zjR/KmA26he6R5MHcxCzAJBgNVBAYTAlVTMR0wGwYDVQQI
+ ExREaXN0cmljdCBvZiBDb2x1bWJpYTETMBEGA1UEBxMKV2FzaGluZ3RvbjEeMBwG
+ A1UEChMVR2VvcmdldG93biBVbml2ZXJzaXR5MRQwEgYDVQQDEwtleGFtcGxlLm9y
+ Z4IJAKg8tR5hjVM4MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAGfkM
+ HUeWzHzsBkwTu+S2vX4gzlJPjiL3RzL40og/qyGz38P4KVg8IQvsGDjs1VFzzcAJ
+ I5ULnSocUOTk5sCTjDKT6VILhgAYJ1jnqIo7Z+VC1r3AS9cSDakzqWTc19EFKxEw
+ 6jeBWaqyykdSiVhCAmG5AJsvk+K032zjkWWMo+0=
+ </security:Certificate>
+ <security:Certificate>
+ MIIFmjCCBIKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJVUzEc
+ MBoGA1UEChMTSW5Db21tb24gRmVkZXJhdGlvbjEpMCcGA1UEAxMgSW5Db21tb24g
+ Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwMzMwMjAzNDAwWhcNMTQwMzI5
+ MjAzNDAwWjBWMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTSW5Db21tb24gRmVkZXJh
+ dGlvbjEpMCcGA1UEAxMgSW5Db21tb24gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
+ ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRGjKsUM2QAupLAaWx82/C
+ WPalKjKFY8UPmz0T3gf7tJPztTy1Zq8pD0WFRLcQeSBKZGCu8upe8X966b6TZ5yu
+ oUDA754If0DWismuHNoMgRR/l0UvZmPWDGRWd3NBTB8/soLA4EbqFf5Xq8MOJKhP
+ tzcDR33gtaAb3oilZ+ZTpnhTFFrn/qXrAKcSDBpuW2JRpi3xaF/hTPI097oUShOz
+ D1Zj21UYLA6iSFVN+1wlfwilf2KFNK/+zbkCge6wgipZyXxaOAam6ncqmkxy+hy/
+ OiJMmdB+6xkO0xXSBUUcqxJrOcUQhA1vntgb3q5zOJISXhC4RAReA0HyBp/wd0iD
+ AgMBAAGjggJxMIICbTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
+ BgNVHQ4EFgQUky3IYRitY+ObZbOd3Y2TuufKY0UwfgYDVR0jBHcwdYAUky3IYRit
+ Y+ObZbOd3Y2TuufKY0WhWqRYMFYxCzAJBgNVBAYTAlVTMRwwGgYDVQQKExNJbkNv
+ bW1vbiBGZWRlcmF0aW9uMSkwJwYDVQQDEyBJbkNvbW1vbiBDZXJ0aWZpY2F0aW9u
+ IEF1dGhvcml0eYIBADCBugYIKwYBBQUHAQEEga0wgaowgacGCCsGAQUFBzAChoGa
+ aHR0cDovL2luY29tbW9uY2ExLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvYnJpZGdl
+ L2NlcnRzL2NhLWNlcnRzLnA3YgoJCUNBIElzc3VlcnMgLSBVUkk6aHR0cDovL2lu
+ Y29tbW9uY2EyLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvYnJpZGdlL2NlcnRzL2Nh
+ LWNlcnRzLnA3YjCBjQYDVR0fBIGFMIGCMD+gPaA7hjlodHRwOi8vaW5jb21tb25j
+ cmwxLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvY3JsL2VlY3Jscy5jcmwwP6A9oDuG
+ OWh0dHA6Ly9pbmNvbW1vbmNybDIuaW5jb21tb25mZWRlcmF0aW9uLm9yZy9jcmwv
+ ZWVjcmxzLmNybDBeBgNVHSAEVzBVMFMGCysGAQQBriMBBAEBMEQwQgYIKwYBBQUH
+ AgEWNmh0dHA6Ly9pbmNvbW1vbmNhLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvcHJh
+ Y3RpY2VzLnBkZjANBgkqhkiG9w0BAQUFAAOCAQEAZfgKUPA+Ky+Ou/vclMlFTMlU
+ GspfbNSdG/fmIq+E/Lv1d2c73Am1zGhOpxgdkM8SE+BPnXW2rl71/N8gaqwgBBxk
+ pwn410siumxlDTwV3HoVFvCGWylNy9o8OE1LyTCqfo8PRwrMzhwcagDgD813BIyj
+ uJg/JQz1LnHMocIW/JligloSIzF1O435/+ckfWXQsmBIhvV5TmA3ZrcycrI1cHGE
+ ZqrCXL0FMZLSr+Vady/tFbVojqI8pSubSMxNkZectePTBjVj1Qeb4hmG8jRv/fwy
+ 1Iw6OFH8RKny8nQaO5mOe/fF/swEsMVU9TDpvLIgbhTwnP7Nhfotgaxf5wG8WA==
+ </security:Certificate>
+ <security:Certificate entityCertificate="true">
+ MIIDtTCCAp2gAwIBAgIJAPmsD+VGldyPMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
+ BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+ aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDExMTMzOTE4WhcNMjQwNDA4MTMzOTE4WjBF
+ MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
+ ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+ CgKCAQEAxg0TyQAP/tIvOH89EtaXuRRn8SYzTj7W1TbNY4VvBmobjkRmSkki4hH9
+ x4sQpi635wn6WtXTN/FNNmkTK3N/LspmBWxfZS+n+cc7I82E5yvCAPX67QsZgqgg
+ lp2W5dvK/FsMMCS6X6SVqzBLMP88NenXKxY+HMxMs0sT0UKYh1cAEqadrHRBO65a
+ DBcm5a0sBVYt9K6pgaOHrp/zSIbhnR5tFFLjBbtFktDpHL3AdGBH3OYidNGKBO3t
+ J3Ms7LeKXsM0+0Y4P+9fHZINL2X3E2N6GVnKs5PZTg9sP0FtIpAbYm/+zCx7Yj1E
+ T/Er8mDd6tNVGSQsn9s5xUBwGqn14wIDAQABo4GnMIGkMB0GA1UdDgQWBBSiQhSu
+ p9BYjD2ZuMkEiQK7w/Zq0TB1BgNVHSMEbjBsgBSiQhSup9BYjD2ZuMkEiQK7w/Zq
+ 0aFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV
+ BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAPmsD+VGldyPMAwGA1UdEwQF
+ MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHZmIo9GBTSsD5DJfKkCVUvBafwR089H
+ BkgVPOuVuEe803BRlKd4BVIsuxAUAy3oqdJYqf9ptPEx8Ef+ALbcDhRbWINhMgO7
+ 0/S4x3pS9gOn7/Y9yZplOe4Jd2q3R8QBef+hKLcD/Uv0Sqy2nilM8BnMga5tqsL+
+ 8oFt0blzXtQ2vcOVyNyG326uZBZv2Cf6FXFsYQX1L/tLeTBJegefgGkg2dqCTKIU
+ 1Qy/Kd2P3/S01kQxjDeG7UfXc9qtelJ68kvzK2d3WOJ2qmsdMxjMNfTItP7FO54M
+ i8V7gp9HK+EimdSbgu7xktKlrqA2Rsn+dBoPSgOUs/LOGtCS9/biF0w=
+ </security:Certificate>
+ <security:CRL>
+ MIIDBjCCAe4CAQEwDQYJKoZIhvcNAQEEBQAwVjELMAkGA1UEBhMCVVMxHDAaBgNV
+ BAoTE0luQ29tbW9uIEZlZGVyYXRpb24xKTAnBgNVBAMTIEluQ29tbW9uIENlcnRp
+ ZmljYXRpb24gQXV0aG9yaXR5Fw0wNzA4MDMxNDE0NDhaFw0wNzA5MDIxNDE0NDha
+ MIHdMBICAQIXDTA0MDMzMTE5NDk0NFowEgIBDhcNMDQwOTE3MTkzMTUxWjASAgEP
+ Fw0wNDA5MTcxOTMyMTRaMBICARYXDTA1MDMyMjE3MTYyMFowEgIBHBcNMDUwMjAx
+ MTkyOTUxWjASAgE+Fw0wNjA0MDcxNjM1MzFaMBICAUAXDTA2MDQwNzE2MzQ1NFow
+ EgIBQRcNMDYwNDEwMTcyMjE1WjASAgFWFw0wNjA3MjAxNzIyMzVaMBICAW8XDTA2
+ MTIxOTIwMTQxMVowEwICAIwXDTA3MDMyOTIxMjE0N1qggYMwgYAwfgYDVR0jBHcw
+ dYAUky3IYRitY+ObZbOd3Y2TuufKY0WhWqRYMFYxCzAJBgNVBAYTAlVTMRwwGgYD
+ VQQKExNJbkNvbW1vbiBGZWRlcmF0aW9uMSkwJwYDVQQDEyBJbkNvbW1vbiBDZXJ0
+ aWZpY2F0aW9uIEF1dGhvcml0eYIBADANBgkqhkiG9w0BAQQFAAOCAQEAeCvRTq70
+ RJxkxgbV+crqhN6oh3k974GGXhOxYDTTGjYbhK8JnCXkt1uJcnGfl1xyqrozoSrl
+ oxoBUmStA8vVqYwtO/FfGpnCyfOG9H2/rAkzbqwr/EXO+MqSd8e1AIJho97i/QSs
+ FWp40h7GeanmiZXL6bc4o9cKb0ROtc1n2nYHkLXptf9bFHte2Z/RhbUr8KaPU4b9
+ T9PW9a2Z7Oc4BDHpEUcljZL0AlO6mGI2RtDB9RdrtRY6M9YQbBwUcV9r+/+ylfZY
+ ugMRDTNUqL72hHKJgmbnfc0CmkcZKHOIGXdGCIX6ewNsLOQnlFAQEVyojQqbzT8w
+ s6E8aj6AzPhKyw==
+ </security:CRL>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/inlinePublicOnly.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/inlinePublicOnly.xml
new file mode 100644
index 000000000..4fc9f0e7c
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/inlinePublicOnly.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="IdPCredential" xsi:type="security:BasicInline">
+ <security:PublicKey>
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxg0TyQAP/tIvOH89EtaX
+uRRn8SYzTj7W1TbNY4VvBmobjkRmSkki4hH9x4sQpi635wn6WtXTN/FNNmkTK3N/
+LspmBWxfZS+n+cc7I82E5yvCAPX67QsZgqgglp2W5dvK/FsMMCS6X6SVqzBLMP88
+NenXKxY+HMxMs0sT0UKYh1cAEqadrHRBO65aDBcm5a0sBVYt9K6pgaOHrp/zSIbh
+nR5tFFLjBbtFktDpHL3AdGBH3OYidNGKBO3tJ3Ms7LeKXsM0+0Y4P+9fHZINL2X3
+E2N6GVnKs5PZTg9sP0FtIpAbYm/+zCx7Yj1ET/Er8mDd6tNVGSQsn9s5xUBwGqn1
+4wIDAQAB
+</security:PublicKey>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/inlinePublicPrivate.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/inlinePublicPrivate.xml
new file mode 100644
index 000000000..e270c0edb
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/inlinePublicPrivate.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="IdPCredential" xsi:type="security:BasicInline">
+ <security:PrivateKey >
+
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDGDRPJAA/+0i84
+fz0S1pe5FGfxJjNOPtbVNs1jhW8GahuORGZKSSLiEf3HixCmLrfnCfpa1dM38U02
+aRMrc38uymYFbF9lL6f5xzsjzYTnK8IA9frtCxmCqCCWnZbl28r8WwwwJLpfpJWr
+MEsw/zw16dcrFj4czEyzSxPRQpiHVwASpp2sdEE7rloMFyblrSwFVi30rqmBo4eu
+n/NIhuGdHm0UUuMFu0WS0OkcvcB0YEfc5iJ00YoE7e0ncyzst4pewzT7Rjg/718d
+kg0vZfcTY3oZWcqzk9lOD2w/QW0ikBtib/7MLHtiPURP8SvyYN3q01UZJCyf2znF
+QHAaqfXjAgMBAAECggEAcbqcu/XfOZN1LlpStfio081WCvLGz43iTDnWI+pB4UsZ
+W88Hdm0dLPjr5KSFAQke7fua2oKjciKNFkusiG0ggbwUbdTXywFc0mCII30nbqCA
+HZEjcO/IzHDDlfoU5xYaMGQQUa0loTqf/9gRtac76jHIL6PsMxlWijb4wFgfwsc9
+ekw8U+Fht/XYukdj5Z42Bf956YxOVLKUGWeV+HJIK2ktyBjv6O5iVdpn1jXPftBk
+Fw/rJgtOdclWWFjUpxQuH789SebNWkduTBS//JCIUYWy97VE6nTO0HqwW58ue8Zx
+NrdPU57Nr1lpf/ONsxsaneqNIaiSdLbdTRBmi1EH4QKBgQD0Sa8FgtaARrI6Vk9w
+HApndCvB/2KnfGa25ut/1vIijMR5BMq8eYBS8rl0o3WnArSBNpaTlqr6frge3AnT
+6k7htXfZMkmVX+VrjF3vAd0fn5Llx1CN3+u27HJ6OnkWGpP7HasqJuyQR4UqF+Ag
+iiWmRw0Ugpz3Frf9UE5Y/FXX2QKBgQDPi+XEmEPwJ/3tubmF6aIk+3Z5AwJMYITf
+07hRpjrGLmUg2jJKiHyp3Z7n2eed4bhho2m0dTbeiHTSbrwnHxvvAwWWJD8nn2XE
+CR8/brYSQGp/9U4BVdCj+JoDwdLCrcd/C3nQXgcxAR8Hqp/v8sa8UdNDz5afW6lk
+Zpg/VgCCGwKBgF7cUguY0ATF7yW6KGTHbr7XnLpbmoqhQx2ZNC/TXvlNomnAE532
+rH8JZDzH0MMGyOM4OGadZk2ZcZQCLArPfMwm9KAx5+MKdwM5YayTE7PY+mkh6cT+
+BAFnddjC5gxQS9CCp9nZfZlVPH+o/86C9rXH92tUgPFuMAo86f+iFQ+ZAoGBAKFb
+mp9l4ivsa7dPFbXPFoi6GDms5TSMNcHu0PZpzngVyfnoqgDYbFOEQe7vsutEeh0u
+9xedqbMJVAnmndGslgMUzlsUgyVC/9ORZAHlCRjXi/U/ug2/sh5JQTR6lGlWwis7
+uNEOyXiH7p//P6lFjs0KsL2fvvLWSLQOL3/OVUbRAoGAVdCQ79t/RCzcI49ZSzmc
+fJD+xHSm3HWOsUNKMJ0a8ELs2sOXA0/fz3gQcJROsQeGO0AZXPJlqRno8sA31x/z
+o3VCG852P+hqwvm911bIUrvjHb+a2nn1U5QtoLGedsbgmhJVf3oFLNQVu1GtBt/b
+63lk430rXYg8jGy0yQXaPy4=
+
+ </security:PrivateKey>
+ <security:PublicKey>
+
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxg0TyQAP/tIvOH89EtaX
+uRRn8SYzTj7W1TbNY4VvBmobjkRmSkki4hH9x4sQpi635wn6WtXTN/FNNmkTK3N/
+LspmBWxfZS+n+cc7I82E5yvCAPX67QsZgqgglp2W5dvK/FsMMCS6X6SVqzBLMP88
+NenXKxY+HMxMs0sT0UKYh1cAEqadrHRBO65aDBcm5a0sBVYt9K6pgaOHrp/zSIbh
+nR5tFFLjBbtFktDpHL3AdGBH3OYidNGKBO3tJ3Ms7LeKXsM0+0Y4P+9fHZINL2X3
+E2N6GVnKs5PZTg9sP0FtIpAbYm/+zCx7Yj1ET/Er8mDd6tNVGSQsn9s5xUBwGqn1
+4wIDAQAB
+
+ </security:PublicKey>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/inlineWrongCert.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/inlineWrongCert.xml
new file mode 100644
index 000000000..ec0486538
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/inlineWrongCert.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="IdPCredential" xsi:type="security:X509Inline">
+ <security:PrivateKey>
+MIIEowIBAAKCAQEAxg0TyQAP/tIvOH89EtaXuRRn8SYzTj7W1TbNY4VvBmobjkRm
+Skki4hH9x4sQpi635wn6WtXTN/FNNmkTK3N/LspmBWxfZS+n+cc7I82E5yvCAPX6
+7QsZgqgglp2W5dvK/FsMMCS6X6SVqzBLMP88NenXKxY+HMxMs0sT0UKYh1cAEqad
+rHRBO65aDBcm5a0sBVYt9K6pgaOHrp/zSIbhnR5tFFLjBbtFktDpHL3AdGBH3OYi
+dNGKBO3tJ3Ms7LeKXsM0+0Y4P+9fHZINL2X3E2N6GVnKs5PZTg9sP0FtIpAbYm/+
+zCx7Yj1ET/Er8mDd6tNVGSQsn9s5xUBwGqn14wIDAQABAoIBAHG6nLv13zmTdS5a
+UrX4qNPNVgryxs+N4kw51iPqQeFLGVvPB3ZtHSz46+SkhQEJHu37mtqCo3IijRZL
+rIhtIIG8FG3U18sBXNJgiCN9J26ggB2RI3DvyMxww5X6FOcWGjBkEFGtJaE6n//Y
+EbWnO+oxyC+j7DMZVoo2+MBYH8LHPXpMPFPhYbf12LpHY+WeNgX/eemMTlSylBln
+lfhySCtpLcgY7+juYlXaZ9Y1z37QZBcP6yYLTnXJVlhY1KcULh+/PUnmzVpHbkwU
+v/yQiFGFsve1ROp0ztB6sFufLnvGcTa3T1Oeza9ZaX/zjbMbGp3qjSGoknS23U0Q
+ZotRB+ECgYEA9EmvBYLWgEayOlZPcBwKZ3Qrwf9ip3xmtubrf9byIozEeQTKvHmA
+UvK5dKN1pwK0gTaWk5aq+n64HtwJ0+pO4bV32TJJlV/la4xd7wHdH5+S5cdQjd/r
+tuxyejp5FhqT+x2rKibskEeFKhfgIIolpkcNFIKc9xa3/VBOWPxV19kCgYEAz4vl
+xJhD8Cf97bm5hemiJPt2eQMCTGCE39O4UaY6xi5lINoySoh8qd2e59nnneG4YaNp
+tHU23oh00m68Jx8b7wMFliQ/J59lxAkfP262EkBqf/VOAVXQo/iaA8HSwq3Hfwt5
+0F4HMQEfB6qf7/LGvFHTQ8+Wn1upZGaYP1YAghsCgYBe3FILmNAExe8luihkx26+
+15y6W5qKoUMdmTQv0175TaJpwBOd9qx/CWQ8x9DDBsjjODhmnWZNmXGUAiwKz3zM
+JvSgMefjCncDOWGskxOz2PppIenE/gQBZ3XYwuYMUEvQgqfZ2X2ZVTx/qP/Ogva1
+x/drVIDxbjAKPOn/ohUPmQKBgQChW5qfZeIr7Gu3TxW1zxaIuhg5rOU0jDXB7tD2
+ac54Fcn56KoA2GxThEHu77LrRHodLvcXnamzCVQJ5p3RrJYDFM5bFIMlQv/TkWQB
+5QkY14v1P7oNv7IeSUE0epRpVsIrO7jRDsl4h+6f/z+pRY7NCrC9n77y1ki0Di9/
+zlVG0QKBgFXQkO/bf0Qs3COPWUs5nHyQ/sR0ptx1jrFDSjCdGvBC7NrDlwNP3894
+EHCUTrEHhjtAGVzyZakZ6PLAN9cf86N1QhvOdj/oasL5vddWyFK74x2/mtp59VOU
+LaCxnnbG4JoSVX96BSzUFbtRrQbf2+t5ZON9K12IPIxstMkF2j8u
+
+</security:PrivateKey>
+ <security:Certificate>
+MIIDSTCCArKgAwIBAgIJAKg8tR5hjVM4MA0GCSqGSIb3DQEBBQUAMHcxCzAJBgNV
+BAYTAlVTMR0wGwYDVQQIExREaXN0cmljdCBvZiBDb2x1bWJpYTETMBEGA1UEBxMK
+V2FzaGluZ3RvbjEeMBwGA1UEChMVR2VvcmdldG93biBVbml2ZXJzaXR5MRQwEgYD
+VQQDEwtleGFtcGxlLm9yZzAeFw0wNzA4MDUxMzA4MDJaFw0xNzA4MDIxMzA4MDJa
+MHcxCzAJBgNVBAYTAlVTMR0wGwYDVQQIExREaXN0cmljdCBvZiBDb2x1bWJpYTET
+MBEGA1UEBxMKV2FzaGluZ3RvbjEeMBwGA1UEChMVR2VvcmdldG93biBVbml2ZXJz
+aXR5MRQwEgYDVQQDEwtleGFtcGxlLm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
+gYkCgYEA5zKHuD5DGPEQH+yLDMIA5M46HwJk7HxlGQ7N9WmkhaI22zXPC0UO8sY4
+AJW/8nlm0pc505iQmbgslg7/JyBemBj1sI7pOp6eCUPs7NR2mwaujXBturiRaJIe
+AX1Gjr3sO+3aLvqxUEu0PWqci4m1uc8XHQCA+PlEQQQnB9UIJwcCAwEAAaOB3DCB
+2TAdBgNVHQ4EFgQUzEhylzE4wmr4FK1lZ7zjR/KmA24wgakGA1UdIwSBoTCBnoAU
+zEhylzE4wmr4FK1lZ7zjR/KmA26he6R5MHcxCzAJBgNVBAYTAlVTMR0wGwYDVQQI
+ExREaXN0cmljdCBvZiBDb2x1bWJpYTETMBEGA1UEBxMKV2FzaGluZ3RvbjEeMBwG
+A1UEChMVR2VvcmdldG93biBVbml2ZXJzaXR5MRQwEgYDVQQDEwtleGFtcGxlLm9y
+Z4IJAKg8tR5hjVM4MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAGfkM
+HUeWzHzsBkwTu+S2vX4gzlJPjiL3RzL40og/qyGz38P4KVg8IQvsGDjs1VFzzcAJ
+I5ULnSocUOTk5sCTjDKT6VILhgAYJ1jnqIo7Z+VC1r3AS9cSDakzqWTc19EFKxEw
+6jeBWaqyykdSiVhCAmG5AJsvk+K032zjkWWMo+0=
+</security:Certificate>
+<security:Certificate>
+MIIFmjCCBIKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJVUzEc
+MBoGA1UEChMTSW5Db21tb24gRmVkZXJhdGlvbjEpMCcGA1UEAxMgSW5Db21tb24g
+Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwMzMwMjAzNDAwWhcNMTQwMzI5
+MjAzNDAwWjBWMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTSW5Db21tb24gRmVkZXJh
+dGlvbjEpMCcGA1UEAxMgSW5Db21tb24gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRGjKsUM2QAupLAaWx82/C
+WPalKjKFY8UPmz0T3gf7tJPztTy1Zq8pD0WFRLcQeSBKZGCu8upe8X966b6TZ5yu
+oUDA754If0DWismuHNoMgRR/l0UvZmPWDGRWd3NBTB8/soLA4EbqFf5Xq8MOJKhP
+tzcDR33gtaAb3oilZ+ZTpnhTFFrn/qXrAKcSDBpuW2JRpi3xaF/hTPI097oUShOz
+D1Zj21UYLA6iSFVN+1wlfwilf2KFNK/+zbkCge6wgipZyXxaOAam6ncqmkxy+hy/
+OiJMmdB+6xkO0xXSBUUcqxJrOcUQhA1vntgb3q5zOJISXhC4RAReA0HyBp/wd0iD
+AgMBAAGjggJxMIICbTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
+BgNVHQ4EFgQUky3IYRitY+ObZbOd3Y2TuufKY0UwfgYDVR0jBHcwdYAUky3IYRit
+Y+ObZbOd3Y2TuufKY0WhWqRYMFYxCzAJBgNVBAYTAlVTMRwwGgYDVQQKExNJbkNv
+bW1vbiBGZWRlcmF0aW9uMSkwJwYDVQQDEyBJbkNvbW1vbiBDZXJ0aWZpY2F0aW9u
+IEF1dGhvcml0eYIBADCBugYIKwYBBQUHAQEEga0wgaowgacGCCsGAQUFBzAChoGa
+aHR0cDovL2luY29tbW9uY2ExLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvYnJpZGdl
+L2NlcnRzL2NhLWNlcnRzLnA3YgoJCUNBIElzc3VlcnMgLSBVUkk6aHR0cDovL2lu
+Y29tbW9uY2EyLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvYnJpZGdlL2NlcnRzL2Nh
+LWNlcnRzLnA3YjCBjQYDVR0fBIGFMIGCMD+gPaA7hjlodHRwOi8vaW5jb21tb25j
+cmwxLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvY3JsL2VlY3Jscy5jcmwwP6A9oDuG
+OWh0dHA6Ly9pbmNvbW1vbmNybDIuaW5jb21tb25mZWRlcmF0aW9uLm9yZy9jcmwv
+ZWVjcmxzLmNybDBeBgNVHSAEVzBVMFMGCysGAQQBriMBBAEBMEQwQgYIKwYBBQUH
+AgEWNmh0dHA6Ly9pbmNvbW1vbmNhLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvcHJh
+Y3RpY2VzLnBkZjANBgkqhkiG9w0BAQUFAAOCAQEAZfgKUPA+Ky+Ou/vclMlFTMlU
+GspfbNSdG/fmIq+E/Lv1d2c73Am1zGhOpxgdkM8SE+BPnXW2rl71/N8gaqwgBBxk
+pwn410siumxlDTwV3HoVFvCGWylNy9o8OE1LyTCqfo8PRwrMzhwcagDgD813BIyj
+uJg/JQz1LnHMocIW/JligloSIzF1O435/+ckfWXQsmBIhvV5TmA3ZrcycrI1cHGE
+ZqrCXL0FMZLSr+Vady/tFbVojqI8pSubSMxNkZectePTBjVj1Qeb4hmG8jRv/fwy
+1Iw6OFH8RKny8nQaO5mOe/fF/swEsMVU9TDpvLIgbhTwnP7Nhfotgaxf5wG8WA==
+</security:Certificate>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/key.pem b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/key.pem
new file mode 100644
index 000000000..951462f0d
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAxg0TyQAP/tIvOH89EtaXuRRn8SYzTj7W1TbNY4VvBmobjkRm
+Skki4hH9x4sQpi635wn6WtXTN/FNNmkTK3N/LspmBWxfZS+n+cc7I82E5yvCAPX6
+7QsZgqgglp2W5dvK/FsMMCS6X6SVqzBLMP88NenXKxY+HMxMs0sT0UKYh1cAEqad
+rHRBO65aDBcm5a0sBVYt9K6pgaOHrp/zSIbhnR5tFFLjBbtFktDpHL3AdGBH3OYi
+dNGKBO3tJ3Ms7LeKXsM0+0Y4P+9fHZINL2X3E2N6GVnKs5PZTg9sP0FtIpAbYm/+
+zCx7Yj1ET/Er8mDd6tNVGSQsn9s5xUBwGqn14wIDAQABAoIBAHG6nLv13zmTdS5a
+UrX4qNPNVgryxs+N4kw51iPqQeFLGVvPB3ZtHSz46+SkhQEJHu37mtqCo3IijRZL
+rIhtIIG8FG3U18sBXNJgiCN9J26ggB2RI3DvyMxww5X6FOcWGjBkEFGtJaE6n//Y
+EbWnO+oxyC+j7DMZVoo2+MBYH8LHPXpMPFPhYbf12LpHY+WeNgX/eemMTlSylBln
+lfhySCtpLcgY7+juYlXaZ9Y1z37QZBcP6yYLTnXJVlhY1KcULh+/PUnmzVpHbkwU
+v/yQiFGFsve1ROp0ztB6sFufLnvGcTa3T1Oeza9ZaX/zjbMbGp3qjSGoknS23U0Q
+ZotRB+ECgYEA9EmvBYLWgEayOlZPcBwKZ3Qrwf9ip3xmtubrf9byIozEeQTKvHmA
+UvK5dKN1pwK0gTaWk5aq+n64HtwJ0+pO4bV32TJJlV/la4xd7wHdH5+S5cdQjd/r
+tuxyejp5FhqT+x2rKibskEeFKhfgIIolpkcNFIKc9xa3/VBOWPxV19kCgYEAz4vl
+xJhD8Cf97bm5hemiJPt2eQMCTGCE39O4UaY6xi5lINoySoh8qd2e59nnneG4YaNp
+tHU23oh00m68Jx8b7wMFliQ/J59lxAkfP262EkBqf/VOAVXQo/iaA8HSwq3Hfwt5
+0F4HMQEfB6qf7/LGvFHTQ8+Wn1upZGaYP1YAghsCgYBe3FILmNAExe8luihkx26+
+15y6W5qKoUMdmTQv0175TaJpwBOd9qx/CWQ8x9DDBsjjODhmnWZNmXGUAiwKz3zM
+JvSgMefjCncDOWGskxOz2PppIenE/gQBZ3XYwuYMUEvQgqfZ2X2ZVTx/qP/Ogva1
+x/drVIDxbjAKPOn/ohUPmQKBgQChW5qfZeIr7Gu3TxW1zxaIuhg5rOU0jDXB7tD2
+ac54Fcn56KoA2GxThEHu77LrRHodLvcXnamzCVQJ5p3RrJYDFM5bFIMlQv/TkWQB
+5QkY14v1P7oNv7IeSUE0epRpVsIrO7jRDsl4h+6f/z+pRY7NCrC9n77y1ki0Di9/
+zlVG0QKBgFXQkO/bf0Qs3COPWUs5nHyQ/sR0ptx1jrFDSjCdGvBC7NrDlwNP3894
+EHCUTrEHhjtAGVzyZakZ6PLAN9cf86N1QhvOdj/oasL5vddWyFK74x2/mtp59VOU
+LaCxnnbG4JoSVX96BSzUFbtRrQbf2+t5ZON9K12IPIxstMkF2j8u
+-----END RSA PRIVATE KEY-----
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/publicKey.pem b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/publicKey.pem
new file mode 100644
index 000000000..5c4e2e78c
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/publicKey.pem
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxg0TyQAP/tIvOH89EtaX
+uRRn8SYzTj7W1TbNY4VvBmobjkRmSkki4hH9x4sQpi635wn6WtXTN/FNNmkTK3N/
+LspmBWxfZS+n+cc7I82E5yvCAPX67QsZgqgglp2W5dvK/FsMMCS6X6SVqzBLMP88
+NenXKxY+HMxMs0sT0UKYh1cAEqadrHRBO65aDBcm5a0sBVYt9K6pgaOHrp/zSIbh
+nR5tFFLjBbtFktDpHL3AdGBH3OYidNGKBO3tJ3Ms7LeKXsM0+0Y4P+9fHZINL2X3
+E2N6GVnKs5PZTg9sP0FtIpAbYm/+zCx7Yj1ET/Er8mDd6tNVGSQsn9s5xUBwGqn1
+4wIDAQAB
+-----END PUBLIC KEY-----
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceBasic.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceBasic.xml
new file mode 100644
index 000000000..92124520e
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceBasic.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="IdPCredential" xsi:type="security:BasicResourceBacked">
+ <security:PublicKey>%{DIR}/credential/cert.pem</security:PublicKey>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceCertElementsKeyName.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceCertElementsKeyName.xml
new file mode 100644
index 000000000..2e29412e9
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceCertElementsKeyName.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="IdPCredential" xsi:type="security:X509ResourceBacked" entityID="https://sp.example.org/sp/shibboleth" usage="Signing" >
+ <security:KeyName>Name1</security:KeyName>
+ <security:KeyName>Name2</security:KeyName>
+ <security:Certificate>%{DIR}/credential/cert.pem</security:Certificate>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceCertOnly.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceCertOnly.xml
new file mode 100644
index 000000000..393fc1a18
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceCertOnly.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="IdPCredential" xsi:type="security:X509ResourceBacked">
+ <security:Certificate>classpath:/net/shibboleth/spring/security/credential/cert.pem</security:Certificate>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceKeyCertCrl.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceKeyCertCrl.xml
new file mode 100644
index 000000000..be79fa870
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceKeyCertCrl.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="IdPCredential" xsi:type="security:X509ResourceBacked">
+ <security:PrivateKey>%{DIR}/credential/key.pem</security:PrivateKey>
+ <security:Certificate>%{DIR}/credential/certificate.pem</security:Certificate>
+ <security:Certificate entityCertificate="true">%{DIR}/credential/cert.pem</security:Certificate>
+ <security:CRL>%{DIR}/credential/crl.pem</security:CRL>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourcePublicOnly.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourcePublicOnly.xml
new file mode 100644
index 000000000..f68487b43
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourcePublicOnly.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="IdPCredential" xsi:type="security:BasicResourceBacked">
+ <security:PublicKey>classpath:/net/shibboleth/spring/security/credential/publicKey.pem</security:PublicKey>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourcePublicPrivate.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourcePublicPrivate.xml
new file mode 100644
index 000000000..40c917f27
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourcePublicPrivate.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="IdPCredential" xsi:type="security:BasicResourceBacked">
+ <security:PrivateKey>%{DIR}/credential/key.pem</security:PrivateKey>
+ <security:PublicKey>%{DIR}/credential/publicKey.pem</security:PublicKey>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceSecretAESBase64.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceSecretAESBase64.xml
new file mode 100644
index 000000000..da43c6950
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceSecretAESBase64.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="credential" xsi:type="security:BasicResourceBacked">
+ <security:SecretKey algorithm="AES" encoding="base64">classpath:/net/shibboleth/spring/security/credential/aes-base64.txt</security:SecretKey>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceSecretAESBinary.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceSecretAESBinary.xml
new file mode 100644
index 000000000..0f9db3ca4
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceSecretAESBinary.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="credential" xsi:type="security:BasicResourceBacked">
+ <security:SecretKey algorithm="AES" encoding="binary">classpath:/net/shibboleth/spring/security/credential/aes-binary.data</security:SecretKey>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceSecretAESHex.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceSecretAESHex.xml
new file mode 100644
index 000000000..c0bdb3105
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceSecretAESHex.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="credential" xsi:type="security:BasicResourceBacked">
+ <security:SecretKey algorithm="AES" encoding="hex">classpath:/net/shibboleth/spring/security/credential/aes-hex.txt</security:SecretKey>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceTwoCert.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceTwoCert.xml
new file mode 100644
index 000000000..5c840bf59
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceTwoCert.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="IdPCredential" xsi:type="security:X509ResourceBacked">
+ <security:Certificate entityCertificate="true">%{DIR}/credential/certificate.pem</security:Certificate>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceWrongCert.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceWrongCert.xml
new file mode 100644
index 000000000..1d90f7fef
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceWrongCert.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="IdPCredential" xsi:type="security:X509ResourceBacked">
+ <security:PrivateKey>%{DIR}/credential/key.pem</security:PrivateKey>
+ <security:Certificate>%{DIR}/credential/certificate.pem</security:Certificate>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceWrongPublic.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceWrongPublic.xml
new file mode 100644
index 000000000..fd37c2e98
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceWrongPublic.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="IdPCredential" xsi:type="security:BasicResourceBacked">
+ <security:PrivateKey>%{DIR}/credential/key.pem</security:PrivateKey>
+ <security:PublicKey>%{DIR}/credential/wrongPublicKey.pem</security:PublicKey>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceX509.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceX509.xml
new file mode 100644
index 000000000..b087dd962
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/resourceX509.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="IdPCredential" xsi:type="security:X509ResourceBacked">
+ <security:Certificate>%{DIR}/credential/cert.pem</security:Certificate>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/secretKeyAESBase64.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/secretKeyAESBase64.xml
new file mode 100644
index 000000000..6eb1ad98f
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/secretKeyAESBase64.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="credential" xsi:type="security:BasicInline">
+ <security:SecretKey algorithm="AES" encoding="base64">
+ 3MvnCRvjjWgqazN4O2cHCw==
+ </security:SecretKey>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/secretKeyAESHex.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/secretKeyAESHex.xml
new file mode 100644
index 000000000..75925e63e
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/secretKeyAESHex.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:Credential xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="credential" xsi:type="security:BasicInline">
+ <security:SecretKey algorithm="AES" encoding="hex">
+ dccbe7091be38d682a6b33783b67070b
+ </security:SecretKey>
+</security:Credential>
+
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/wrongPublicKey.pem b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/wrongPublicKey.pem
new file mode 100644
index 000000000..33164a38a
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/credential/wrongPublicKey.pem
@@ -0,0 +1,6 @@
+-----BEGIN PUBLIC KEY-----
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDnMoe4PkMY8RAf7IsMwgDkzjof
+AmTsfGUZDs31aaSFojbbNc8LRQ7yxjgAlb/yeWbSlznTmJCZuCyWDv8nIF6YGPWw
+juk6np4JQ+zs1HabBq6NcG26uJFokh4BfUaOvew77dou+rFQS7Q9apyLibW5zxcd
+AID4+URBBCcH1QgnBwIDAQAB
+-----END PUBLIC KEY-----
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/cert.pem b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/cert.pem
new file mode 100644
index 000000000..c0df65bc9
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/cert.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDtTCCAp2gAwIBAgIJAPmsD+VGldyPMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDExMTMzOTE4WhcNMjQwNDA4MTMzOTE4WjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAxg0TyQAP/tIvOH89EtaXuRRn8SYzTj7W1TbNY4VvBmobjkRmSkki4hH9
+x4sQpi635wn6WtXTN/FNNmkTK3N/LspmBWxfZS+n+cc7I82E5yvCAPX67QsZgqgg
+lp2W5dvK/FsMMCS6X6SVqzBLMP88NenXKxY+HMxMs0sT0UKYh1cAEqadrHRBO65a
+DBcm5a0sBVYt9K6pgaOHrp/zSIbhnR5tFFLjBbtFktDpHL3AdGBH3OYidNGKBO3t
+J3Ms7LeKXsM0+0Y4P+9fHZINL2X3E2N6GVnKs5PZTg9sP0FtIpAbYm/+zCx7Yj1E
+T/Er8mDd6tNVGSQsn9s5xUBwGqn14wIDAQABo4GnMIGkMB0GA1UdDgQWBBSiQhSu
+p9BYjD2ZuMkEiQK7w/Zq0TB1BgNVHSMEbjBsgBSiQhSup9BYjD2ZuMkEiQK7w/Zq
+0aFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV
+BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAPmsD+VGldyPMAwGA1UdEwQF
+MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHZmIo9GBTSsD5DJfKkCVUvBafwR089H
+BkgVPOuVuEe803BRlKd4BVIsuxAUAy3oqdJYqf9ptPEx8Ef+ALbcDhRbWINhMgO7
+0/S4x3pS9gOn7/Y9yZplOe4Jd2q3R8QBef+hKLcD/Uv0Sqy2nilM8BnMga5tqsL+
+8oFt0blzXtQ2vcOVyNyG326uZBZv2Cf6FXFsYQX1L/tLeTBJegefgGkg2dqCTKIU
+1Qy/Kd2P3/S01kQxjDeG7UfXc9qtelJ68kvzK2d3WOJ2qmsdMxjMNfTItP7FO54M
+i8V7gp9HK+EimdSbgu7xktKlrqA2Rsn+dBoPSgOUs/LOGtCS9/biF0w=
+-----END CERTIFICATE-----
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/chain.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/chain.xml
new file mode 100644
index 000000000..30154f530
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/chain.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:TrustEngine
+ xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+ xsi:type="security:SignatureChaining" id="Chain">
+ <security:TrustEngine id="testBean"
+ xsi:type="security:StaticPKIXSignature" xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd">
+ <security:ValidationInfo id="PKIXInline"
+ xsi:type="security:PKIXInline" />
+ </security:TrustEngine>
+ <security:TrustEngine id="testBean"
+ xsi:type="security:StaticExplicitKeySignature">
+ <security:Credential id="IdPCredential" xsi:type="security:X509Inline">
+ <security:Certificate>
+ MIIDtTCCAp2gAwIBAgIJAPmsD+VGldyPMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
+ BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+ aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDExMTMzOTE4WhcNMjQwNDA4MTMzOTE4WjBF
+ MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
+ ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+ CgKCAQEAxg0TyQAP/tIvOH89EtaXuRRn8SYzTj7W1TbNY4VvBmobjkRmSkki4hH9
+ x4sQpi635wn6WtXTN/FNNmkTK3N/LspmBWxfZS+n+cc7I82E5yvCAPX67QsZgqgg
+ lp2W5dvK/FsMMCS6X6SVqzBLMP88NenXKxY+HMxMs0sT0UKYh1cAEqadrHRBO65a
+ DBcm5a0sBVYt9K6pgaOHrp/zSIbhnR5tFFLjBbtFktDpHL3AdGBH3OYidNGKBO3t
+ J3Ms7LeKXsM0+0Y4P+9fHZINL2X3E2N6GVnKs5PZTg9sP0FtIpAbYm/+zCx7Yj1E
+ T/Er8mDd6tNVGSQsn9s5xUBwGqn14wIDAQABo4GnMIGkMB0GA1UdDgQWBBSiQhSu
+ p9BYjD2ZuMkEiQK7w/Zq0TB1BgNVHSMEbjBsgBSiQhSup9BYjD2ZuMkEiQK7w/Zq
+ 0aFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV
+ BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAPmsD+VGldyPMAwGA1UdEwQF
+ MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHZmIo9GBTSsD5DJfKkCVUvBafwR089H
+ BkgVPOuVuEe803BRlKd4BVIsuxAUAy3oqdJYqf9ptPEx8Ef+ALbcDhRbWINhMgO7
+ 0/S4x3pS9gOn7/Y9yZplOe4Jd2q3R8QBef+hKLcD/Uv0Sqy2nilM8BnMga5tqsL+
+ 8oFt0blzXtQ2vcOVyNyG326uZBZv2Cf6FXFsYQX1L/tLeTBJegefgGkg2dqCTKIU
+ 1Qy/Kd2P3/S01kQxjDeG7UfXc9qtelJ68kvzK2d3WOJ2qmsdMxjMNfTItP7FO54M
+ i8V7gp9HK+EimdSbgu7xktKlrqA2Rsn+dBoPSgOUs/LOGtCS9/biF0w=
+ </security:Certificate>
+ </security:Credential>
+ </security:TrustEngine>
+</security:TrustEngine>
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/chainingTrue.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/chainingTrue.xml
new file mode 100644
index 000000000..2f78c2ac1
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/chainingTrue.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:c="http://www.springframework.org/schema/c" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
+
+ <security:TrustEngine id="testBean" xsi:type="security:Chaining">
+ <security:TrustEngineRef ref="OneTrue"/>
+ </security:TrustEngine>
+
+ <bean id="OneTrue" class="net.shibboleth.spring.security.trust.MockTrustEngine" c:retVal="true"/>
+ </beans>
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/chainingTrueFalse.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/chainingTrueFalse.xml
new file mode 100644
index 000000000..5b3b1add8
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/chainingTrueFalse.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:c="http://www.springframework.org/schema/c" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
+
+ <security:TrustEngine id="testBean" xsi:type="security:Chaining">
+ <security:TrustEngineRef ref="OneFalse"/>
+ <security:TrustEngineRef ref="OneTrue"/>
+ <security:TrustEngineRef ref="Object"/>
+ </security:TrustEngine>
+
+ <bean id="OneFalse" class="net.shibboleth.spring.security.trust.MockTrustEngine" c:retVal="false"/>
+ <bean id="OneTrue" class="net.shibboleth.spring.security.trust.MockTrustEngine" c:retVal="true"/>
+ <bean id="Object" class="java.lang.Object"/>
+ </beans>
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/crl.pem b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/crl.pem
new file mode 100644
index 000000000..f8036cef1
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/crl.pem
@@ -0,0 +1,19 @@
+-----BEGIN X509 CRL-----
+MIIDBjCCAe4CAQEwDQYJKoZIhvcNAQEEBQAwVjELMAkGA1UEBhMCVVMxHDAaBgNV
+BAoTE0luQ29tbW9uIEZlZGVyYXRpb24xKTAnBgNVBAMTIEluQ29tbW9uIENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5Fw0wNzA4MDMxNDE0NDhaFw0wNzA5MDIxNDE0NDha
+MIHdMBICAQIXDTA0MDMzMTE5NDk0NFowEgIBDhcNMDQwOTE3MTkzMTUxWjASAgEP
+Fw0wNDA5MTcxOTMyMTRaMBICARYXDTA1MDMyMjE3MTYyMFowEgIBHBcNMDUwMjAx
+MTkyOTUxWjASAgE+Fw0wNjA0MDcxNjM1MzFaMBICAUAXDTA2MDQwNzE2MzQ1NFow
+EgIBQRcNMDYwNDEwMTcyMjE1WjASAgFWFw0wNjA3MjAxNzIyMzVaMBICAW8XDTA2
+MTIxOTIwMTQxMVowEwICAIwXDTA3MDMyOTIxMjE0N1qggYMwgYAwfgYDVR0jBHcw
+dYAUky3IYRitY+ObZbOd3Y2TuufKY0WhWqRYMFYxCzAJBgNVBAYTAlVTMRwwGgYD
+VQQKExNJbkNvbW1vbiBGZWRlcmF0aW9uMSkwJwYDVQQDEyBJbkNvbW1vbiBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eYIBADANBgkqhkiG9w0BAQQFAAOCAQEAeCvRTq70
+RJxkxgbV+crqhN6oh3k974GGXhOxYDTTGjYbhK8JnCXkt1uJcnGfl1xyqrozoSrl
+oxoBUmStA8vVqYwtO/FfGpnCyfOG9H2/rAkzbqwr/EXO+MqSd8e1AIJho97i/QSs
+FWp40h7GeanmiZXL6bc4o9cKb0ROtc1n2nYHkLXptf9bFHte2Z/RhbUr8KaPU4b9
+T9PW9a2Z7Oc4BDHpEUcljZL0AlO6mGI2RtDB9RdrtRY6M9YQbBwUcV9r+/+ylfZY
+ugMRDTNUqL72hHKJgmbnfc0CmkcZKHOIGXdGCIX6ewNsLOQnlFAQEVyojQqbzT8w
+s6E8aj6AzPhKyw==
+-----END X509 CRL-----
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/inlineValidationInfo.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/inlineValidationInfo.xml
new file mode 100644
index 000000000..263193d70
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/inlineValidationInfo.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:ValidationInfo xmlns:security="urn:mace:shibboleth:2.0:security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="PKIXInline" xsi:type="security:PKIXInline"/>
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/inlineValidationInfoValues.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/inlineValidationInfoValues.xml
new file mode 100644
index 000000000..025db6ed1
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/inlineValidationInfoValues.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:ValidationInfo xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+ id="PKIXInlineValues" xsi:type="security:PKIXInline" verifyDepth="98">
+ <security:Certificate>
+ MIIDSTCCArKgAwIBAgIJAKg8tR5hjVM4MA0GCSqGSIb3DQEBBQUAMHcxCzAJBgNV
+ BAYTAlVTMR0wGwYDVQQIExREaXN0cmljdCBvZiBDb2x1bWJpYTETMBEGA1UEBxMK
+ V2FzaGluZ3RvbjEeMBwGA1UEChMVR2VvcmdldG93biBVbml2ZXJzaXR5MRQwEgYD
+ VQQDEwtleGFtcGxlLm9yZzAeFw0wNzA4MDUxMzA4MDJaFw0xNzA4MDIxMzA4MDJa
+ MHcxCzAJBgNVBAYTAlVTMR0wGwYDVQQIExREaXN0cmljdCBvZiBDb2x1bWJpYTET
+ MBEGA1UEBxMKV2FzaGluZ3RvbjEeMBwGA1UEChMVR2VvcmdldG93biBVbml2ZXJz
+ aXR5MRQwEgYDVQQDEwtleGFtcGxlLm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
+ gYkCgYEA5zKHuD5DGPEQH+yLDMIA5M46HwJk7HxlGQ7N9WmkhaI22zXPC0UO8sY4
+ AJW/8nlm0pc505iQmbgslg7/JyBemBj1sI7pOp6eCUPs7NR2mwaujXBturiRaJIe
+ AX1Gjr3sO+3aLvqxUEu0PWqci4m1uc8XHQCA+PlEQQQnB9UIJwcCAwEAAaOB3DCB
+ 2TAdBgNVHQ4EFgQUzEhylzE4wmr4FK1lZ7zjR/KmA24wgakGA1UdIwSBoTCBnoAU
+ zEhylzE4wmr4FK1lZ7zjR/KmA26he6R5MHcxCzAJBgNVBAYTAlVTMR0wGwYDVQQI
+ ExREaXN0cmljdCBvZiBDb2x1bWJpYTETMBEGA1UEBxMKV2FzaGluZ3RvbjEeMBwG
+ A1UEChMVR2VvcmdldG93biBVbml2ZXJzaXR5MRQwEgYDVQQDEwtleGFtcGxlLm9y
+ Z4IJAKg8tR5hjVM4MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAGfkM
+ HUeWzHzsBkwTu+S2vX4gzlJPjiL3RzL40og/qyGz38P4KVg8IQvsGDjs1VFzzcAJ
+ I5ULnSocUOTk5sCTjDKT6VILhgAYJ1jnqIo7Z+VC1r3AS9cSDakzqWTc19EFKxEw
+ 6jeBWaqyykdSiVhCAmG5AJsvk+K032zjkWWMo+0=
+ </security:Certificate>
+ <security:Certificate>
+ MIIFmjCCBIKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJVUzEc
+ MBoGA1UEChMTSW5Db21tb24gRmVkZXJhdGlvbjEpMCcGA1UEAxMgSW5Db21tb24g
+ Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwMzMwMjAzNDAwWhcNMTQwMzI5
+ MjAzNDAwWjBWMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTSW5Db21tb24gRmVkZXJh
+ dGlvbjEpMCcGA1UEAxMgSW5Db21tb24gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
+ ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRGjKsUM2QAupLAaWx82/C
+ WPalKjKFY8UPmz0T3gf7tJPztTy1Zq8pD0WFRLcQeSBKZGCu8upe8X966b6TZ5yu
+ oUDA754If0DWismuHNoMgRR/l0UvZmPWDGRWd3NBTB8/soLA4EbqFf5Xq8MOJKhP
+ tzcDR33gtaAb3oilZ+ZTpnhTFFrn/qXrAKcSDBpuW2JRpi3xaF/hTPI097oUShOz
+ D1Zj21UYLA6iSFVN+1wlfwilf2KFNK/+zbkCge6wgipZyXxaOAam6ncqmkxy+hy/
+ OiJMmdB+6xkO0xXSBUUcqxJrOcUQhA1vntgb3q5zOJISXhC4RAReA0HyBp/wd0iD
+ AgMBAAGjggJxMIICbTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
+ BgNVHQ4EFgQUky3IYRitY+ObZbOd3Y2TuufKY0UwfgYDVR0jBHcwdYAUky3IYRit
+ Y+ObZbOd3Y2TuufKY0WhWqRYMFYxCzAJBgNVBAYTAlVTMRwwGgYDVQQKExNJbkNv
+ bW1vbiBGZWRlcmF0aW9uMSkwJwYDVQQDEyBJbkNvbW1vbiBDZXJ0aWZpY2F0aW9u
+ IEF1dGhvcml0eYIBADCBugYIKwYBBQUHAQEEga0wgaowgacGCCsGAQUFBzAChoGa
+ aHR0cDovL2luY29tbW9uY2ExLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvYnJpZGdl
+ L2NlcnRzL2NhLWNlcnRzLnA3YgoJCUNBIElzc3VlcnMgLSBVUkk6aHR0cDovL2lu
+ Y29tbW9uY2EyLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvYnJpZGdlL2NlcnRzL2Nh
+ LWNlcnRzLnA3YjCBjQYDVR0fBIGFMIGCMD+gPaA7hjlodHRwOi8vaW5jb21tb25j
+ cmwxLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvY3JsL2VlY3Jscy5jcmwwP6A9oDuG
+ OWh0dHA6Ly9pbmNvbW1vbmNybDIuaW5jb21tb25mZWRlcmF0aW9uLm9yZy9jcmwv
+ ZWVjcmxzLmNybDBeBgNVHSAEVzBVMFMGCysGAQQBriMBBAEBMEQwQgYIKwYBBQUH
+ AgEWNmh0dHA6Ly9pbmNvbW1vbmNhLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvcHJh
+ Y3RpY2VzLnBkZjANBgkqhkiG9w0BAQUFAAOCAQEAZfgKUPA+Ky+Ou/vclMlFTMlU
+ GspfbNSdG/fmIq+E/Lv1d2c73Am1zGhOpxgdkM8SE+BPnXW2rl71/N8gaqwgBBxk
+ pwn410siumxlDTwV3HoVFvCGWylNy9o8OE1LyTCqfo8PRwrMzhwcagDgD813BIyj
+ uJg/JQz1LnHMocIW/JligloSIzF1O435/+ckfWXQsmBIhvV5TmA3ZrcycrI1cHGE
+ ZqrCXL0FMZLSr+Vady/tFbVojqI8pSubSMxNkZectePTBjVj1Qeb4hmG8jRv/fwy
+ 1Iw6OFH8RKny8nQaO5mOe/fF/swEsMVU9TDpvLIgbhTwnP7Nhfotgaxf5wG8WA==
+ </security:Certificate>
+ <security:CRL>
+ MIIDBjCCAe4CAQEwDQYJKoZIhvcNAQEEBQAwVjELMAkGA1UEBhMCVVMxHDAaBgNV
+ BAoTE0luQ29tbW9uIEZlZGVyYXRpb24xKTAnBgNVBAMTIEluQ29tbW9uIENlcnRp
+ ZmljYXRpb24gQXV0aG9yaXR5Fw0wNzA4MDMxNDE0NDhaFw0wNzA5MDIxNDE0NDha
+ MIHdMBICAQIXDTA0MDMzMTE5NDk0NFowEgIBDhcNMDQwOTE3MTkzMTUxWjASAgEP
+ Fw0wNDA5MTcxOTMyMTRaMBICARYXDTA1MDMyMjE3MTYyMFowEgIBHBcNMDUwMjAx
+ MTkyOTUxWjASAgE+Fw0wNjA0MDcxNjM1MzFaMBICAUAXDTA2MDQwNzE2MzQ1NFow
+ EgIBQRcNMDYwNDEwMTcyMjE1WjASAgFWFw0wNjA3MjAxNzIyMzVaMBICAW8XDTA2
+ MTIxOTIwMTQxMVowEwICAIwXDTA3MDMyOTIxMjE0N1qggYMwgYAwfgYDVR0jBHcw
+ dYAUky3IYRitY+ObZbOd3Y2TuufKY0WhWqRYMFYxCzAJBgNVBAYTAlVTMRwwGgYD
+ VQQKExNJbkNvbW1vbiBGZWRlcmF0aW9uMSkwJwYDVQQDEyBJbkNvbW1vbiBDZXJ0
+ aWZpY2F0aW9uIEF1dGhvcml0eYIBADANBgkqhkiG9w0BAQQFAAOCAQEAeCvRTq70
+ RJxkxgbV+crqhN6oh3k974GGXhOxYDTTGjYbhK8JnCXkt1uJcnGfl1xyqrozoSrl
+ oxoBUmStA8vVqYwtO/FfGpnCyfOG9H2/rAkzbqwr/EXO+MqSd8e1AIJho97i/QSs
+ FWp40h7GeanmiZXL6bc4o9cKb0ROtc1n2nYHkLXptf9bFHte2Z/RhbUr8KaPU4b9
+ T9PW9a2Z7Oc4BDHpEUcljZL0AlO6mGI2RtDB9RdrtRY6M9YQbBwUcV9r+/+ylfZY
+ ugMRDTNUqL72hHKJgmbnfc0CmkcZKHOIGXdGCIX6ewNsLOQnlFAQEVyojQqbzT8w
+ s6E8aj6AzPhKyw==
+ </security:CRL>
+</security:ValidationInfo>
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/resourceValidationInfo.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/resourceValidationInfo.xml
new file mode 100644
index 000000000..3ee7a7dbd
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/resourceValidationInfo.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:ValidationInfo xmlns:security="urn:mace:shibboleth:2.0:security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ id="validInfoSimple" xsi:type="security:PKIXResourceBacked"/>
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/resourceValidationInfoValues.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/resourceValidationInfoValues.xml
new file mode 100644
index 000000000..737cfe185
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/resourceValidationInfoValues.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:ValidationInfo xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+ id="validInfoValues" xsi:type="security:PKIXResourceBacked" verifyDepth="99">
+
+ <security:Certificate>%{DIR}/trust/cert.pem</security:Certificate>
+ <security:Certificate>classpath:/net/shibboleth/spring/security/trust/cert.pem</security:Certificate>
+ <security:CRL>%{DIR}/trust/crl.pem</security:CRL>
+</security:ValidationInfo>
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticExplicit.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticExplicit.xml
new file mode 100644
index 000000000..ec84d9966
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticExplicit.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:TrustEngine id="testBean"
+ xsi:type="security:StaticExplicitKey" xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd">
+ <security:Credential id="InLineBean" xsi:type="security:X509Inline">
+ <security:Certificate>
+ MIIDtTCCAp2gAwIBAgIJAPmsD+VGldyPMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
+ BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+ aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDExMTMzOTE4WhcNMjQwNDA4MTMzOTE4WjBF
+ MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
+ ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+ CgKCAQEAxg0TyQAP/tIvOH89EtaXuRRn8SYzTj7W1TbNY4VvBmobjkRmSkki4hH9
+ x4sQpi635wn6WtXTN/FNNmkTK3N/LspmBWxfZS+n+cc7I82E5yvCAPX67QsZgqgg
+ lp2W5dvK/FsMMCS6X6SVqzBLMP88NenXKxY+HMxMs0sT0UKYh1cAEqadrHRBO65a
+ DBcm5a0sBVYt9K6pgaOHrp/zSIbhnR5tFFLjBbtFktDpHL3AdGBH3OYidNGKBO3t
+ J3Ms7LeKXsM0+0Y4P+9fHZINL2X3E2N6GVnKs5PZTg9sP0FtIpAbYm/+zCx7Yj1E
+ T/Er8mDd6tNVGSQsn9s5xUBwGqn14wIDAQABo4GnMIGkMB0GA1UdDgQWBBSiQhSu
+ p9BYjD2ZuMkEiQK7w/Zq0TB1BgNVHSMEbjBsgBSiQhSup9BYjD2ZuMkEiQK7w/Zq
+ 0aFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV
+ BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAPmsD+VGldyPMAwGA1UdEwQF
+ MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHZmIo9GBTSsD5DJfKkCVUvBafwR089H
+ BkgVPOuVuEe803BRlKd4BVIsuxAUAy3oqdJYqf9ptPEx8Ef+ALbcDhRbWINhMgO7
+ 0/S4x3pS9gOn7/Y9yZplOe4Jd2q3R8QBef+hKLcD/Uv0Sqy2nilM8BnMga5tqsL+
+ 8oFt0blzXtQ2vcOVyNyG326uZBZv2Cf6FXFsYQX1L/tLeTBJegefgGkg2dqCTKIU
+ 1Qy/Kd2P3/S01kQxjDeG7UfXc9qtelJ68kvzK2d3WOJ2qmsdMxjMNfTItP7FO54M
+ i8V7gp9HK+EimdSbgu7xktKlrqA2Rsn+dBoPSgOUs/LOGtCS9/biF0w=
+ </security:Certificate>
+ </security:Credential>
+</security:TrustEngine>
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticExplicitSignature.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticExplicitSignature.xml
new file mode 100644
index 000000000..2fbaec963
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticExplicitSignature.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:TrustEngine id="testBean"
+ xsi:type="security:StaticExplicitKeySignature" xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd">
+ <security:Credential id="InLineBean" xsi:type="security:X509Inline">
+ <security:Certificate>
+ MIIDtTCCAp2gAwIBAgIJAPmsD+VGldyPMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
+ BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+ aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDExMTMzOTE4WhcNMjQwNDA4MTMzOTE4WjBF
+ MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
+ ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+ CgKCAQEAxg0TyQAP/tIvOH89EtaXuRRn8SYzTj7W1TbNY4VvBmobjkRmSkki4hH9
+ x4sQpi635wn6WtXTN/FNNmkTK3N/LspmBWxfZS+n+cc7I82E5yvCAPX67QsZgqgg
+ lp2W5dvK/FsMMCS6X6SVqzBLMP88NenXKxY+HMxMs0sT0UKYh1cAEqadrHRBO65a
+ DBcm5a0sBVYt9K6pgaOHrp/zSIbhnR5tFFLjBbtFktDpHL3AdGBH3OYidNGKBO3t
+ J3Ms7LeKXsM0+0Y4P+9fHZINL2X3E2N6GVnKs5PZTg9sP0FtIpAbYm/+zCx7Yj1E
+ T/Er8mDd6tNVGSQsn9s5xUBwGqn14wIDAQABo4GnMIGkMB0GA1UdDgQWBBSiQhSu
+ p9BYjD2ZuMkEiQK7w/Zq0TB1BgNVHSMEbjBsgBSiQhSup9BYjD2ZuMkEiQK7w/Zq
+ 0aFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV
+ BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAPmsD+VGldyPMAwGA1UdEwQF
+ MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHZmIo9GBTSsD5DJfKkCVUvBafwR089H
+ BkgVPOuVuEe803BRlKd4BVIsuxAUAy3oqdJYqf9ptPEx8Ef+ALbcDhRbWINhMgO7
+ 0/S4x3pS9gOn7/Y9yZplOe4Jd2q3R8QBef+hKLcD/Uv0Sqy2nilM8BnMga5tqsL+
+ 8oFt0blzXtQ2vcOVyNyG326uZBZv2Cf6FXFsYQX1L/tLeTBJegefgGkg2dqCTKIU
+ 1Qy/Kd2P3/S01kQxjDeG7UfXc9qtelJ68kvzK2d3WOJ2qmsdMxjMNfTItP7FO54M
+ i8V7gp9HK+EimdSbgu7xktKlrqA2Rsn+dBoPSgOUs/LOGtCS9/biF0w=
+ </security:Certificate>
+ </security:Credential>
+</security:TrustEngine>
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIX-nameCheckDisabled.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIX-nameCheckDisabled.xml
new file mode 100644
index 000000000..a67e5bdba
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIX-nameCheckDisabled.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:TrustEngine id="testBean" trustedNameCheckEnabled="false"
+ xsi:type="security:StaticPKIXSignature" xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd">
+ <security:ValidationInfo id="PKIXInline"
+ xsi:type="security:PKIXInline" />
+</security:TrustEngine>
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIX.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIX.xml
new file mode 100644
index 000000000..c32778780
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIX.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:TrustEngine id="testBean"
+ xsi:type="security:StaticPKIXSignature" xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd">
+ <security:ValidationInfo id="PKIXInline"
+ xsi:type="security:PKIXInline" />
+</security:TrustEngine>
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIXCredentials-nameCheckDisabled.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIXCredentials-nameCheckDisabled.xml
new file mode 100644
index 000000000..10468c5d4
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIXCredentials-nameCheckDisabled.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:TrustEngine id="testBean" trustedNameCheckEnabled="false"
+ xsi:type="security:StaticPKIXX509Credential" xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd">
+ <security:ValidationInfo id="PKIXFS"
+ xsi:type="security:PKIXResourceBacked" verifyDepth="99" />
+ <security:ValidationOptions xsi:type="security:CertPathValidationOptionsType"
+ processCredentialCRLs="false" processExpiredCRLs="false"
+ processEmptyCRLs="false" defaultVerificationDepth="3"
+ anyPolicyInhibit="true" policyMappingInhibit="true" forceRevocationEnabled="true" revocationEnabled="false"
+ >
+ <security:PolicyOID>1234
+ </security:PolicyOID><security:PolicyOID>
+
+ </security:PolicyOID>
+ </security:ValidationOptions>
+</security:TrustEngine>
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIXCredentials.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIXCredentials.xml
new file mode 100644
index 000000000..552f3ac82
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIXCredentials.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:TrustEngine id="testBean"
+ xsi:type="security:StaticPKIXX509Credential" xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd">
+ <security:TrustedName>Name1</security:TrustedName>
+ <security:ValidationInfo id="PKIXFS"
+ xsi:type="security:PKIXResourceBacked" verifyDepth="99" />
+ <security:ValidationOptions xsi:type="security:CertPathValidationOptionsType"
+ processCredentialCRLs="false" processExpiredCRLs="false"
+ processEmptyCRLs="false" defaultVerificationDepth="3"
+ anyPolicyInhibit="true" policyMappingInhibit="true" forceRevocationEnabled="true" revocationEnabled="false"
+ >
+ <security:PolicyOID>1234
+ </security:PolicyOID><security:PolicyOID>
+
+ </security:PolicyOID>
+ </security:ValidationOptions>
+</security:TrustEngine>
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIXValues.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIXValues.xml
new file mode 100644
index 000000000..19dc58de5
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIXValues.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:TrustEngine id="testBean"
+ xsi:type="security:StaticPKIXSignature" xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd">
+ <security:TrustedName>Name1</security:TrustedName>
+ <security:TrustedName>Name2</security:TrustedName>
+ <security:TrustedName>Name3</security:TrustedName>
+ <security:ValidationInfo id="PKIXFS"
+ xsi:type="security:PKIXResourceBacked" verifyDepth="99" />
+ <security:ValidationInfo id="PKIXIL"
+ xsi:type="security:PKIXInline" verifyDepth="98" />
+ <security:ValidationOptions
+ processCredentialCRLs="false" processExpiredCRLs="false"
+ processEmptyCRLs="false" defaultVerificationDepth="2" />
+</security:TrustEngine>
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIXValuesCertPathOpts.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIXValuesCertPathOpts.xml
new file mode 100644
index 000000000..deacbff09
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/staticPKIXValuesCertPathOpts.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:TrustEngine id="testBean"
+ xsi:type="security:StaticPKIXSignature" xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd">
+ <security:TrustedName>Name1</security:TrustedName>
+ <security:ValidationInfo id="PKIXFS"
+ xsi:type="security:PKIXResourceBacked" verifyDepth="99" />
+ <security:ValidationOptions xsi:type="security:CertPathValidationOptionsType"
+ processCredentialCRLs="false" processExpiredCRLs="false"
+ processEmptyCRLs="false" defaultVerificationDepth="3"
+ anyPolicyInhibit="true" policyMappingInhibit="true" forceRevocationEnabled="true" revocationEnabled="false"
+ >
+ <security:PolicyOID>1234
+ </security:PolicyOID><security:PolicyOID>
+
+ </security:PolicyOID>
+ </security:ValidationOptions>
+</security:TrustEngine>
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/validationOptions.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/validationOptions.xml
new file mode 100644
index 000000000..eb36a831b
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/validationOptions.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:ValidationOptions
+ xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"/>
\ No newline at end of file
diff --git a/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/validationOptionsValues.xml b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/validationOptionsValues.xml
new file mode 100644
index 000000000..7ec42ed68
--- /dev/null
+++ b/shib-metadata-spring/src/test/resources/net/shibboleth/spring/security/trust/validationOptionsValues.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<security:ValidationOptions
+ xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd"
+
+ processCredentialCRLs="false" processExpiredCRLs="true" processEmptyCRLs="false" defaultVerificationDepth="2"/>
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list