[java-opensaml] branch main updated: OSJ-353 - Move IdP Spring support for credentials/trust into new module
Scott Cantor
cantor.2 at osu.edu
Tue Jul 5 14:28:08 UTC 2022
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-opensaml.
View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=06c5567e6668bfb4028bfb59441b4d0b7db1644c
The following commit(s) were added to refs/heads/main by this push:
new 06c5567e6 OSJ-353 - Move IdP Spring support for credentials/trust into new module
06c5567e6 is described below
commit 06c5567e6668bfb4028bfb59441b4d0b7db1644c
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Jul 5 10:27:35 2022 -0400
OSJ-353 - Move IdP Spring support for credentials/trust into new module
https://shibboleth.atlassian.net/browse/OSJ-353
---
opensaml-bom/pom.xml | 5 +
opensaml-core/.classpath | 1 +
opensaml-core/.project | 12 +
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
opensaml-messaging-api/.classpath | 1 +
opensaml-messaging-api/.project | 12 +
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
opensaml-messaging-impl/.classpath | 1 +
opensaml-messaging-impl/.project | 12 +
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
opensaml-parent/pom.xml | 2 +
opensaml-profile-api/.classpath | 1 +
opensaml-profile-api/.project | 12 +
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
opensaml-profile-impl/.classpath | 1 +
opensaml-profile-impl/.project | 12 +
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
opensaml-saml-api/.classpath | 1 +
opensaml-saml-api/.project | 12 +
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
opensaml-saml-impl/.classpath | 1 +
opensaml-saml-impl/.project | 12 +
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
opensaml-security-api/.classpath | 1 +
opensaml-security-api/.project | 12 +
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
opensaml-security-impl/.classpath | 1 +
opensaml-security-impl/.project | 12 +
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
opensaml-soap-api/.classpath | 1 +
opensaml-soap-api/.project | 12 +
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
opensaml-soap-impl/.classpath | 1 +
opensaml-soap-impl/.project | 12 +
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
opensaml-spring/.checkstyle | 15 +
.../.classpath | 2 +
opensaml-spring/.gitignore | 2 +
.../.project | 15 +-
.../.settings/org.eclipse.core.resources.prefs | 6 +
.../.settings/org.eclipse.jdt.core.prefs | 413 +++++++++++++++++++++
opensaml-spring/.settings/org.eclipse.jdt.ui.prefs | 63 ++++
.../.settings/org.eclipse.m2e.core.prefs | 4 +
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
opensaml-spring/pom.xml | 102 +++++
.../AbstractBasicCredentialFactoryBean.java | 207 +++++++++++
.../credential/AbstractCredentialFactoryBean.java | 144 +++++++
.../AbstractX509CredentialFactoryBean.java | 133 +++++++
.../BasicInlineCredentialFactoryBean.java | 126 +++++++
.../BasicResourceCredentialFactoryBean.java | 147 ++++++++
.../credential/BasicX509CredentialFactoryBean.java | 224 +++++++++++
.../X509InlineCredentialFactoryBean.java | 147 ++++++++
.../opensaml/spring/credential/package-info.java | 22 ++
.../spring/tls/TLSSocketFactoryFactoryBean.java | 96 +++++
.../java/org/opensaml/spring/tls/package-info.java | 22 ++
...AbstractBasicPKIXValidationInfoFactoryBean.java | 103 +++++
.../ChainingSignatureTrustEngineFactoryBean.java | 69 ++++
.../trust/ChainingTrustEngineFactoryBean.java | 70 ++++
.../trust/PKIXInlineValidationInfoFactoryBean.java | 107 ++++++
.../PKIXResourceValidationInfoFactoryBean.java | 112 ++++++
.../spring/trust/StaticExplicitKeyFactoryBean.java | 140 +++++++
.../spring/trust/StaticPKIXFactoryBean.java | 277 ++++++++++++++
.../org/opensaml/spring/trust/package-info.java | 22 ++
.../BasicX509CredentialFactoryBeanTest.java | 60 +++
.../spring/trust/AbstractSecurityTest.java | 97 +++++
.../org/opensaml/spring/trust/MockTrustEngine.java | 44 +++
.../trust/StaticExplicitKeyFactoryBeanTest.java | 96 +++++
.../spring/trust/StaticPKIXFactoryBeanTest.java | 132 +++++++
.../org/opensaml/spring/credential/bean.xml | 28 ++
.../org/opensaml/spring/credential/cert.pem | 22 ++
.../org/opensaml/spring/credential/certificate.pem | 52 +++
.../org/opensaml/spring/credential/idp-signing.crt | 22 ++
.../org/opensaml/spring/credential/idp-signing.key | 27 ++
.../spring/credential/idp-signing.key.pass | 30 ++
.../org/opensaml/spring/credential/publicKey.pem | 9 +
.../static-pkix-factory-custom-failsValidation.xml | 34 ++
.../trust/static-pkix-factory-custom-success.xml | 30 ++
.../spring/trust/static-pkix-factory-defaults.xml | 24 ++
.../opensaml/spring/trust/staticExplicitNative.xml | 28 ++
opensaml-storage-api/.classpath | 1 +
opensaml-storage-api/.project | 60 +--
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
opensaml-storage-impl/.classpath | 1 +
opensaml-storage-impl/.project | 12 +
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
opensaml-tests-bom/pom.xml | 7 +
opensaml-xmlsec-api/.classpath | 1 +
opensaml-xmlsec-api/.project | 12 +
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
opensaml-xmlsec-impl/.classpath | 1 +
opensaml-xmlsec-impl/.project | 12 +
.../.settings/org.eclipse.wst.common.component | 6 +
.../org.eclipse.wst.common.project.facet.core.xml | 5 +
108 files changed, 3930 insertions(+), 28 deletions(-)
diff --git a/opensaml-bom/pom.xml b/opensaml-bom/pom.xml
index aa0bc06bf..3d71b1dd2 100644
--- a/opensaml-bom/pom.xml
+++ b/opensaml-bom/pom.xml
@@ -73,6 +73,11 @@
<artifactId>opensaml-soap-impl</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>opensaml-spring</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>opensaml-storage-api</artifactId>
diff --git a/opensaml-core/.classpath b/opensaml-core/.classpath
index 77be441ed..8c2ac107c 100644
--- a/opensaml-core/.classpath
+++ b/opensaml-core/.classpath
@@ -32,6 +32,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-core/.project b/opensaml-core/.project
index 757d7c8fd..d34925c73 100644
--- a/opensaml-core/.project
+++ b/opensaml-core/.project
@@ -5,6 +5,11 @@
<projects>
</projects>
<buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
@@ -20,10 +25,17 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
diff --git a/opensaml-core/.settings/org.eclipse.wst.common.component b/opensaml-core/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..da1ba7740
--- /dev/null
+++ b/opensaml-core/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-core">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-core/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-core/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-core/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
diff --git a/opensaml-messaging-api/.classpath b/opensaml-messaging-api/.classpath
index 77be441ed..8c2ac107c 100644
--- a/opensaml-messaging-api/.classpath
+++ b/opensaml-messaging-api/.classpath
@@ -32,6 +32,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-messaging-api/.project b/opensaml-messaging-api/.project
index ff5ddf77b..16825a759 100644
--- a/opensaml-messaging-api/.project
+++ b/opensaml-messaging-api/.project
@@ -5,6 +5,11 @@
<projects>
</projects>
<buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
@@ -20,10 +25,17 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
diff --git a/opensaml-messaging-api/.settings/org.eclipse.wst.common.component b/opensaml-messaging-api/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..7f24b93eb
--- /dev/null
+++ b/opensaml-messaging-api/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-messaging-api">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-messaging-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-messaging-api/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-messaging-api/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
diff --git a/opensaml-messaging-impl/.classpath b/opensaml-messaging-impl/.classpath
index 77be441ed..8c2ac107c 100644
--- a/opensaml-messaging-impl/.classpath
+++ b/opensaml-messaging-impl/.classpath
@@ -32,6 +32,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-messaging-impl/.project b/opensaml-messaging-impl/.project
index c29a25afb..516d594eb 100644
--- a/opensaml-messaging-impl/.project
+++ b/opensaml-messaging-impl/.project
@@ -5,6 +5,11 @@
<projects>
</projects>
<buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
@@ -25,11 +30,18 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
diff --git a/opensaml-messaging-impl/.settings/org.eclipse.wst.common.component b/opensaml-messaging-impl/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..96089f781
--- /dev/null
+++ b/opensaml-messaging-impl/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-messaging-impl">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-messaging-impl/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-messaging-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-messaging-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
diff --git a/opensaml-parent/pom.xml b/opensaml-parent/pom.xml
index 741bcfe3c..a6549679f 100644
--- a/opensaml-parent/pom.xml
+++ b/opensaml-parent/pom.xml
@@ -47,6 +47,8 @@
<module>../opensaml-xacml-saml-impl</module>
<module>../opensaml-profile-api</module>
<module>../opensaml-profile-impl</module>
+
+ <module>../opensaml-spring</module>
<module>../opensaml-bom</module>
<module>../opensaml-tests-bom</module>
diff --git a/opensaml-profile-api/.classpath b/opensaml-profile-api/.classpath
index 77be441ed..8c2ac107c 100644
--- a/opensaml-profile-api/.classpath
+++ b/opensaml-profile-api/.classpath
@@ -32,6 +32,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-profile-api/.project b/opensaml-profile-api/.project
index b43f792bb..af049c813 100644
--- a/opensaml-profile-api/.project
+++ b/opensaml-profile-api/.project
@@ -5,6 +5,11 @@
<projects>
</projects>
<buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
@@ -25,11 +30,18 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
diff --git a/opensaml-profile-api/.settings/org.eclipse.wst.common.component b/opensaml-profile-api/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..79b3cb1f5
--- /dev/null
+++ b/opensaml-profile-api/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-profile-api">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-profile-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-profile-api/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-profile-api/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
diff --git a/opensaml-profile-impl/.classpath b/opensaml-profile-impl/.classpath
index 77be441ed..8c2ac107c 100644
--- a/opensaml-profile-impl/.classpath
+++ b/opensaml-profile-impl/.classpath
@@ -32,6 +32,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-profile-impl/.project b/opensaml-profile-impl/.project
index d464fbb69..5092f09d9 100644
--- a/opensaml-profile-impl/.project
+++ b/opensaml-profile-impl/.project
@@ -5,6 +5,11 @@
<projects>
</projects>
<buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
@@ -25,11 +30,18 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
diff --git a/opensaml-profile-impl/.settings/org.eclipse.wst.common.component b/opensaml-profile-impl/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..ab42e66ab
--- /dev/null
+++ b/opensaml-profile-impl/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-profile-impl">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-profile-impl/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-profile-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-profile-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
diff --git a/opensaml-saml-api/.classpath b/opensaml-saml-api/.classpath
index 77be441ed..8c2ac107c 100644
--- a/opensaml-saml-api/.classpath
+++ b/opensaml-saml-api/.classpath
@@ -32,6 +32,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-saml-api/.project b/opensaml-saml-api/.project
index 3323b390d..09f14b9f2 100644
--- a/opensaml-saml-api/.project
+++ b/opensaml-saml-api/.project
@@ -5,6 +5,11 @@
<projects>
</projects>
<buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
@@ -20,10 +25,17 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
diff --git a/opensaml-saml-api/.settings/org.eclipse.wst.common.component b/opensaml-saml-api/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..c0a67ab83
--- /dev/null
+++ b/opensaml-saml-api/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-saml-api">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-saml-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-saml-api/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-saml-api/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
diff --git a/opensaml-saml-impl/.classpath b/opensaml-saml-impl/.classpath
index 77be441ed..8c2ac107c 100644
--- a/opensaml-saml-impl/.classpath
+++ b/opensaml-saml-impl/.classpath
@@ -32,6 +32,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-saml-impl/.project b/opensaml-saml-impl/.project
index 4e908d873..8daa5a618 100644
--- a/opensaml-saml-impl/.project
+++ b/opensaml-saml-impl/.project
@@ -5,6 +5,11 @@
<projects>
</projects>
<buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
@@ -25,11 +30,18 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
diff --git a/opensaml-saml-impl/.settings/org.eclipse.wst.common.component b/opensaml-saml-impl/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..f51a3aba2
--- /dev/null
+++ b/opensaml-saml-impl/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-saml-impl">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-saml-impl/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-saml-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-saml-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
diff --git a/opensaml-security-api/.classpath b/opensaml-security-api/.classpath
index 77be441ed..8c2ac107c 100644
--- a/opensaml-security-api/.classpath
+++ b/opensaml-security-api/.classpath
@@ -32,6 +32,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-security-api/.project b/opensaml-security-api/.project
index fddc4a163..6c7a1c0ec 100644
--- a/opensaml-security-api/.project
+++ b/opensaml-security-api/.project
@@ -5,6 +5,11 @@
<projects>
</projects>
<buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
@@ -30,11 +35,18 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
diff --git a/opensaml-security-api/.settings/org.eclipse.wst.common.component b/opensaml-security-api/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..13893effa
--- /dev/null
+++ b/opensaml-security-api/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-security-api">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-security-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-security-api/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-security-api/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
diff --git a/opensaml-security-impl/.classpath b/opensaml-security-impl/.classpath
index 77be441ed..8c2ac107c 100644
--- a/opensaml-security-impl/.classpath
+++ b/opensaml-security-impl/.classpath
@@ -32,6 +32,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-security-impl/.project b/opensaml-security-impl/.project
index 99c378a83..b484917cf 100644
--- a/opensaml-security-impl/.project
+++ b/opensaml-security-impl/.project
@@ -5,6 +5,11 @@
<projects>
</projects>
<buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
@@ -20,10 +25,17 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
diff --git a/opensaml-security-impl/.settings/org.eclipse.wst.common.component b/opensaml-security-impl/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..05cdaec0a
--- /dev/null
+++ b/opensaml-security-impl/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-security-impl">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-security-impl/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-security-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-security-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
diff --git a/opensaml-soap-api/.classpath b/opensaml-soap-api/.classpath
index 77be441ed..8c2ac107c 100644
--- a/opensaml-soap-api/.classpath
+++ b/opensaml-soap-api/.classpath
@@ -32,6 +32,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-soap-api/.project b/opensaml-soap-api/.project
index 52462fae1..26d9ba4e3 100644
--- a/opensaml-soap-api/.project
+++ b/opensaml-soap-api/.project
@@ -5,6 +5,11 @@
<projects>
</projects>
<buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
@@ -20,10 +25,17 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
diff --git a/opensaml-soap-api/.settings/org.eclipse.wst.common.component b/opensaml-soap-api/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..4f1a24849
--- /dev/null
+++ b/opensaml-soap-api/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-soap-api">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-soap-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-soap-api/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-soap-api/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
diff --git a/opensaml-soap-impl/.classpath b/opensaml-soap-impl/.classpath
index 77be441ed..8c2ac107c 100644
--- a/opensaml-soap-impl/.classpath
+++ b/opensaml-soap-impl/.classpath
@@ -32,6 +32,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-soap-impl/.project b/opensaml-soap-impl/.project
index e8c041f4e..60754d09a 100644
--- a/opensaml-soap-impl/.project
+++ b/opensaml-soap-impl/.project
@@ -5,6 +5,11 @@
<projects>
</projects>
<buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
@@ -25,11 +30,18 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
diff --git a/opensaml-soap-impl/.settings/org.eclipse.wst.common.component b/opensaml-soap-impl/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..c16c94ff1
--- /dev/null
+++ b/opensaml-soap-impl/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-soap-impl">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-soap-impl/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-soap-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-soap-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
diff --git a/opensaml-spring/.checkstyle b/opensaml-spring/.checkstyle
new file mode 100644
index 000000000..c04bf97d7
--- /dev/null
+++ b/opensaml-spring/.checkstyle
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="false" sync-formatter="false">
+
+ <local-check-config name="Shibboleth Checkstyle" location="/opensaml-parent/resources/checkstyle/checkstyle.xml" type="project" description="">
+ <additional-data name="cache-file" value="true"/>
+ <additional-data name="cache-props-file-location" value="null_1312636288299_cache.properties"/>
+ <additional-data name="cache-file-location" value="null_1312636288299_cache.xml"/>
+ </local-check-config>
+
+ <fileset name="main source" enabled="true" check-config-name="Shibboleth Checkstyle" local="true">
+ <file-match-pattern match-pattern="src/main/java/.*\.java$" include-pattern="true"/>
+ </fileset>
+
+</fileset-config>
diff --git a/opensaml-messaging-impl/.classpath b/opensaml-spring/.classpath
similarity index 92%
copy from opensaml-messaging-impl/.classpath
copy to opensaml-spring/.classpath
index 77be441ed..8ea303622 100644
--- a/opensaml-messaging-impl/.classpath
+++ b/opensaml-spring/.classpath
@@ -26,12 +26,14 @@
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
<attributes>
+ <attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-spring/.gitignore b/opensaml-spring/.gitignore
new file mode 100644
index 000000000..289d9e9af
--- /dev/null
+++ b/opensaml-spring/.gitignore
@@ -0,0 +1,2 @@
+/target/
+/test-output/
diff --git a/opensaml-security-api/.project b/opensaml-spring/.project
similarity index 73%
copy from opensaml-security-api/.project
copy to opensaml-spring/.project
index fddc4a163..aa177194c 100644
--- a/opensaml-security-api/.project
+++ b/opensaml-spring/.project
@@ -1,40 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
- <name>opensaml-security-api</name>
+ <name>opensaml-spring</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
- <name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
+ <name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
- <name>org.springframework.ide.eclipse.core.springbuilder</name>
+ <name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
- <name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
- <name>org.eclipse.m2e.core.maven2Builder</name>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
- <nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
diff --git a/opensaml-spring/.settings/org.eclipse.core.resources.prefs b/opensaml-spring/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 000000000..29abf9995
--- /dev/null
+++ b/opensaml-spring/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,6 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/main/resources=UTF-8
+encoding//src/test/java=UTF-8
+encoding//src/test/resources=UTF-8
+encoding/<project>=UTF-8
diff --git a/opensaml-spring/.settings/org.eclipse.jdt.core.prefs b/opensaml-spring/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..7dda60bd3
--- /dev/null
+++ b/opensaml-spring/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,413 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=ignore
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.mainOnlyProjectHasTestOnlyDependency=error
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=17
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.APILeak=warning
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=info
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=info
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=enabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
+org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=info
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=info
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=17
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=16
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=1
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=120
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=120
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=false
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/opensaml-spring/.settings/org.eclipse.jdt.ui.prefs b/opensaml-spring/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..86c79c4bc
--- /dev/null
+++ b/opensaml-spring/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,63 @@
+cleanup.add_default_serial_version_id=false
+cleanup.add_generated_serial_version_id=true
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=false
+cleanup.add_missing_override_annotations_interface_methods=true
+cleanup.add_serial_version_id=true
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=true
+cleanup.format_source_code=true
+cleanup.format_source_code_changes_only=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=true
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=true
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=true
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_trailing_whitespaces=true
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_blocks=true
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_parentheses_in_expressions=true
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup_profile=_Shibboleth
+cleanup_settings_version=2
+eclipse.preferences.version=1
+formatter_profile=_Shibboleth
+formatter_settings_version=11
+internal.default.compliance=default
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=false
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return Returns the ${bare_field_name}.\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Commen [...]
diff --git a/opensaml-spring/.settings/org.eclipse.m2e.core.prefs b/opensaml-spring/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 000000000..f897a7f1c
--- /dev/null
+++ b/opensaml-spring/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/opensaml-spring/.settings/org.eclipse.wst.common.component b/opensaml-spring/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..8feb3fd43
--- /dev/null
+++ b/opensaml-spring/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-spring">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-spring/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-spring/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-spring/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
diff --git a/opensaml-spring/pom.xml b/opensaml-spring/pom.xml
new file mode 100644
index 000000000..3b71e1f74
--- /dev/null
+++ b/opensaml-spring/pom.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.opensaml</groupId>
+ <artifactId>opensaml-parent</artifactId>
+ <version>5.0.0-SNAPSHOT</version>
+ <relativePath>../opensaml-parent</relativePath>
+ </parent>
+
+ <name>OpenSAML :: Spring Support</name>
+ <description>Spring Support</description>
+ <artifactId>opensaml-spring</artifactId>
+ <packaging>jar</packaging>
+
+ <properties>
+ <automatic.module.name>org.opensaml.spring</automatic.module.name>
+ </properties>
+
+ <dependencies>
+ <!-- Compile Dependencies -->
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>opensaml-security-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>opensaml-security-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>opensaml-xmlsec-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>net.shibboleth.ext</groupId>
+ <artifactId>spring-extensions</artifactId>
+ <!-- Exception to usual test scope. -->
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ </dependency>
+
+ <!-- Provided Dependencies -->
+
+ <!-- Runtime Dependencies -->
+
+ <!-- Test Dependencies -->
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <scm>
+ <connection>${shibboleth.scm.connection}java-opensaml</connection>
+ <developerConnection>${shibboleth.scm.developerConnection}java-opensaml</developerConnection>
+ <url>${shibboleth.scm.url}java-opensaml.git</url>
+ </scm>
+
+ <distributionManagement>
+ <site>
+ <id>site</id>
+ <url>scp:${opensaml-module.site.url}</url>
+ </site>
+ </distributionManagement>
+
+
+</project>
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/credential/AbstractBasicCredentialFactoryBean.java b/opensaml-spring/src/main/java/org/opensaml/spring/credential/AbstractBasicCredentialFactoryBean.java
new file mode 100644
index 000000000..dd7ffe6a8
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/credential/AbstractBasicCredentialFactoryBean.java
@@ -0,0 +1,207 @@
+/*
+ * 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 org.opensaml.spring.credential;
+
+import java.io.UnsupportedEncodingException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.crypto.SecretKey;
+
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+
+import org.apache.commons.codec.binary.Base64;
+import org.bouncycastle.util.encoders.Hex;
+import org.opensaml.security.credential.BasicCredential;
+import org.opensaml.security.credential.UsageType;
+import org.opensaml.security.crypto.KeySupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.BeanCreationException;
+
+/**
+ * A factory bean to collect information to do with a {@link BasicCredential}.
+ */
+public abstract class AbstractBasicCredentialFactoryBean extends AbstractCredentialFactoryBean<BasicCredential> {
+
+ /** Form of encoding for SecretKey info. */
+ public enum SecretKeyEncoding {
+ /** Raw binary encoding. */
+ binary,
+ /** Hexidecimal encoding. */
+ hex,
+ /** Base64 encoding. */
+ base64
+ }
+
+ /** Log. */
+ private final Logger log = LoggerFactory.getLogger(AbstractBasicCredentialFactoryBean.class);
+
+ /** The SecretKey algorithm. */
+ @Nullable private String secretKeyAlgorithm;
+
+ /** The SecretKey encoding used. */
+ @Nullable private SecretKeyEncoding secretKeyEncoding = SecretKeyEncoding.base64;
+
+ /**
+ * Decode the SecretKey data, based on the specified encoding.
+ *
+ * @param data the Secret key data
+ * @return the decoded SecretKey byte array
+ */
+ protected byte[] decodeSecretKey(final String data) {
+ Constraint.isNotNull(data, "SecretKey data was null");
+ switch (getSecretKeyEncoding()) {
+ case binary:
+ // This sort of doesn't make sense for the String input, but just assume it's UTF-8
+ try {
+ return data.getBytes("UTF-8");
+ } catch (final UnsupportedEncodingException e) {
+ // Can't actually happen, UTF-8 always supported.
+ return null;
+ }
+ case hex:
+ return Hex.decode(data);
+ case base64:
+ return Base64.decodeBase64(data);
+ default:
+ throw new IllegalArgumentException("Saw unsupported encoding: " + getSecretKeyEncoding());
+
+ }
+ }
+
+ /**
+ * Decode the SecretKey data, based on the specified encoding.
+ *
+ * @param data the Secret key data
+ * @return the decoded SecretKey byte array
+ */
+ protected byte[] decodeSecretKey(final byte[] data) {
+ Constraint.isNotNull(data, "SecretKey data was null");
+ switch (getSecretKeyEncoding()) {
+ case binary:
+ return data;
+ case hex:
+ return Hex.decode(data);
+ case base64:
+ return Base64.decodeBase64(data);
+ default:
+ throw new IllegalArgumentException("Saw unsupported encoding: " + getSecretKeyEncoding());
+
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected BasicCredential doCreateInstance() throws Exception {
+
+ final PrivateKey privateKey = getPrivateKey();
+ final PublicKey publicKey = getPublicKey();
+ final SecretKey secretKey = getSecretKey();
+ final BasicCredential credential;
+
+ // Asymmetric credential
+ if (null != publicKey) {
+ if (null == privateKey) {
+ credential = new BasicCredential(publicKey);
+ } else {
+ if (!KeySupport.matchKeyPair(publicKey, privateKey)) {
+ log.error("{}: Public and private keys do not match", getConfigDescription());
+ throw new BeanCreationException("Public and private keys do not match");
+ }
+ credential = new BasicCredential(publicKey, privateKey);
+ }
+ // Symmetric credential
+ } else if (null != secretKey) {
+ credential = new BasicCredential(secretKey);
+ } else {
+ throw new BeanCreationException("Neither public key nor secret key specified");
+ }
+
+ if (null != getUsageType()) {
+ credential.setUsageType(UsageType.valueOf(getUsageType()));
+ }
+ return credential;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Class<?> getObjectType() {
+ return BasicCredential.class;
+ }
+
+ /**
+ * Get the algorithm for the SecretKey.
+ *
+ * @return Returns the SecretKey algorithm
+ */
+ @Nullable public String getSecretKeyAlgorithm() {
+ return secretKeyAlgorithm;
+ }
+
+ /**
+ * Set the algorithm for the SecretKey.
+ *
+ * @param algorithm The algorithm to set.
+ */
+ public void setSecretKeyAlgorithm(@Nonnull final String algorithm) {
+ secretKeyAlgorithm = Constraint.isNotNull(StringSupport.trimOrNull(algorithm),
+ "SecretKey algorithm may not be null");
+ }
+
+ /**
+ * Get the SecretKey encoding. Defaults to: base64.
+ *
+ * @return the encoding
+ */
+ public SecretKeyEncoding getSecretKeyEncoding() {
+ return secretKeyEncoding;
+ }
+
+ /**
+ * Set the SecretKey encoding. Defaults to: base64
+ *
+ * @param encoding the new encoding
+ */
+ public void setSecretKeyEncoding(@Nonnull final SecretKeyEncoding encoding) {
+ secretKeyEncoding = Constraint.isNotNull(encoding, "SecretKey encoding may not be null");
+ }
+
+ /**
+ * return the configured Public Key.
+ *
+ * @return the key, or none if not configured.
+ */
+ @Nullable protected abstract PublicKey getPublicKey();
+
+ /**
+ * Get the configured Private key.
+ *
+ * @return the key or null if non configured
+ */
+ @Nullable protected abstract PrivateKey getPrivateKey();
+
+ /**
+ * return the configured Secret Key.
+ *
+ * @return the key, or none if not configured.
+ */
+ @Nullable protected abstract SecretKey getSecretKey();
+
+}
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/credential/AbstractCredentialFactoryBean.java b/opensaml-spring/src/main/java/org/opensaml/spring/credential/AbstractCredentialFactoryBean.java
new file mode 100644
index 000000000..82a895110
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/credential/AbstractCredentialFactoryBean.java
@@ -0,0 +1,144 @@
+/*
+ * 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 org.opensaml.spring.credential;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.security.credential.Credential;
+
+import net.shibboleth.ext.spring.factory.AbstractComponentAwareFactoryBean;
+
+/**
+ * A factory bean to accumulate the information pertaining to an
+ * {@link org.opensaml.security.credential.AbstractCredential}.
+ * @param <T> the type of credential to create.
+ */
+public abstract class AbstractCredentialFactoryBean<T extends Credential> extends AbstractComponentAwareFactoryBean<T> {
+
+ /** Usage type of the credential. */
+ private String usageType;
+
+ /** Names for the key represented by the credential. */
+ private List<String> keyNames;
+
+ /** Identifier for the owner of the credential. */
+ private String entityID;
+
+ /** The privateKey Password (if any). */
+ @Nullable private char[] privateKeyPassword;
+
+ /** For logging: The description of the source of the configuration.*/
+ @Nonnull private String configDescription;
+
+ /**
+ * Gets the names for the key represented by the credential.
+ *
+ * @return names for the key represented by the credential
+ */
+ @Nullable public List<String> getKeyNames() {
+ return keyNames;
+ }
+
+ /**
+ * Gets the usage type of the credential.
+ *
+ * @return usage type of the credential
+ */
+ @Nullable public String getUsageType() {
+ return usageType;
+ }
+
+ /**
+ * Get the entity ID of the credential.
+ *
+ * @return the entity ID
+ */
+ @Nullable public String getEntityID() {
+ return entityID;
+ }
+
+ /**
+ * Sets the names for the key represented by the credential.
+ *
+ * @param names names for the key represented by the credential
+ */
+ public void setKeyNames(@Nullable final List<String> names) {
+ keyNames = names;
+ }
+
+ /**
+ * Sets the usage type of the credential.
+ *
+ * @param type usage type of the credential
+ */
+ public void setUsageType(@Nullable final String type) {
+ if (null != type) {
+ usageType = type.toUpperCase();
+ } else {
+ usageType = type;
+ }
+ }
+
+ /**
+ * Set the entity ID of the credential.
+ *
+ * @param newEntityID the entity ID
+ */
+ public void setEntityID(@Nullable final String newEntityID) {
+ entityID = newEntityID;
+ }
+
+ /**
+ * Get the password for the private key.
+ *
+ * @return Returns the privateKeyPassword.
+ */
+ @Nullable public char[] getPrivateKeyPassword() {
+ return privateKeyPassword;
+ }
+
+ /**
+ * Set the password for the private key.
+ *
+ * @param password The password to set.
+ */
+ public void setPrivateKeyPassword(@Nullable final char[] password) {
+ if (null != password && password.length > 0) {
+ privateKeyPassword = password;
+ } else {
+ privateKeyPassword = null;
+ }
+ }
+
+ /** For logging, get the description of the resource that defined this bean.
+ * @return Returns the description.
+ */
+ public String getConfigDescription() {
+ return configDescription;
+ }
+
+ /** For logging, set the description of the resource that defined this bean.
+ * @param desc what to set.
+ */
+ public void setConfigDescription(@Nonnull final String desc) {
+ configDescription = desc;
+ }
+}
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/credential/AbstractX509CredentialFactoryBean.java b/opensaml-spring/src/main/java/org/opensaml/spring/credential/AbstractX509CredentialFactoryBean.java
new file mode 100644
index 000000000..786361dd6
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/credential/AbstractX509CredentialFactoryBean.java
@@ -0,0 +1,133 @@
+/*
+ * 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 org.opensaml.spring.credential;
+
+import java.security.PrivateKey;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+
+import org.opensaml.security.credential.UsageType;
+import org.opensaml.security.crypto.KeySupport;
+import org.opensaml.security.x509.BasicX509Credential;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.BeanCreationException;
+
+/**
+ * A factory bean to collect information to do with an X509 backed {@link BasicX509Credential}.
+ */
+public abstract class AbstractX509CredentialFactoryBean extends AbstractCredentialFactoryBean<BasicX509Credential> {
+
+ /** Log. */
+ private final Logger log = LoggerFactory.getLogger(AbstractX509CredentialFactoryBean.class);
+
+ /** {@inheritDoc} */
+ // Checkstyle: CyclomaticComplexity OFF
+ @Override protected BasicX509Credential doCreateInstance() throws Exception {
+
+ final List<X509Certificate> certificates = getCertificates();
+ if (null == certificates || certificates.isEmpty()) {
+ log.error("{}: No Certificates provided", getConfigDescription());
+ throw new BeanCreationException("No Certificates provided");
+ }
+
+ X509Certificate entityCertificate = getEntityCertificate();
+ if (null == entityCertificate) {
+ entityCertificate = certificates.get(0);
+ }
+
+ final PrivateKey privateKey = getPrivateKey();
+
+ final BasicX509Credential credential;
+ if (null == privateKey) {
+ credential = new BasicX509Credential(entityCertificate);
+ } else {
+ credential = new BasicX509Credential(entityCertificate, privateKey);
+
+ if (!KeySupport.matchKeyPair(entityCertificate.getPublicKey(), privateKey)) {
+ log.error("{}: Public and private keys do not match", getConfigDescription());
+ throw new BeanCreationException("Public and private keys do not match");
+ }
+ }
+
+ credential.setEntityCertificateChain(certificates);
+
+ final List<X509CRL> crls = getCRLs();
+ if (null != crls && !crls.isEmpty()) {
+ credential.setCRLs(crls);
+ }
+
+ if (null != getUsageType()) {
+ credential.setUsageType(UsageType.valueOf(getUsageType()));
+ }
+
+ if (null != getEntityID()) {
+ credential.setEntityId(getEntityID());
+ }
+
+ final List<String> keyNames = getKeyNames();
+ if (null != keyNames) {
+ credential.getKeyNames().addAll(keyNames);
+ }
+
+ return credential;
+ }
+
+ // Checkstyle: CyclomaticComplexity ON
+
+ /** {@inheritDoc} */
+ @Override public Class<BasicX509Credential> getObjectType() {
+ return BasicX509Credential.class;
+ }
+
+ /**
+ * return the explicitly configured entity certificate.
+ *
+ * @return the certificate, or none if not configured.
+ */
+ @Nullable protected abstract X509Certificate getEntityCertificate();
+
+ /**
+ * Get the configured certificates. This <strong>MUST</strong> include the entity certificate if it was configured.
+ *
+ * @return the certificates.
+ */
+
+ @Nonnull @NotEmpty protected abstract List<X509Certificate> getCertificates();
+
+ /**
+ * Get the configured private key.
+ *
+ * @return the key or null if non configured
+ */
+ @Nullable protected abstract PrivateKey getPrivateKey();
+
+ /**
+ * Get the configured CRL list.
+ *
+ * @return the crls or null
+ */
+ @Nullable protected abstract List<X509CRL> getCRLs();
+
+}
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/credential/BasicInlineCredentialFactoryBean.java b/opensaml-spring/src/main/java/org/opensaml/spring/credential/BasicInlineCredentialFactoryBean.java
new file mode 100644
index 000000000..bac2aebc0
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/credential/BasicInlineCredentialFactoryBean.java
@@ -0,0 +1,126 @@
+/*
+ * 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 org.opensaml.spring.credential;
+
+import java.security.KeyException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+import javax.annotation.Nullable;
+import javax.crypto.SecretKey;
+
+import org.cryptacular.util.KeyPairUtil;
+import org.opensaml.security.crypto.KeySupport;
+import org.springframework.beans.factory.BeanCreationException;
+
+/**
+ * Factory bean for BasicInline Credentials.
+ */
+public class BasicInlineCredentialFactoryBean extends AbstractBasicCredentialFactoryBean {
+
+ /** Configured public key Info. */
+ @Nullable private byte[] publicKeyInfo;
+
+ /** Configured private key Info. */
+ @Nullable private byte[] privateKeyInfo;
+
+ /** Configured secret key Info. */
+ @Nullable private byte[] secretKeyInfo;
+
+ /**
+ * Get the information used to generate the public key.
+ *
+ * @return Returns the info.
+ */
+ @Nullable public byte[] getPublicKeyInfo() {
+ return publicKeyInfo;
+ }
+
+ /**
+ * Set the information used to generate the public key.
+ *
+ * @param info The info to set.
+ */
+ public void setPublicKeyInfo(@Nullable final byte[] info) {
+ publicKeyInfo = info;
+ }
+
+ /**
+ * Get the information used to generate the private key.
+ *
+ * @return Returns the info.
+ */
+ @Nullable public byte[] getPrivateKeyInfo() {
+ return privateKeyInfo;
+ }
+
+ /**
+ * Set the information used to generate the private key.
+ *
+ * @param info The info to set.
+ */
+ public void setPrivateKeyInfo(@Nullable final byte[] info) {
+ privateKeyInfo = info;
+ }
+
+ /**
+ * Get the information used to generate the secret key.
+ *
+ * @return Returns the info.
+ */
+ @Nullable public byte[] getSecretKeyInfo() {
+ return secretKeyInfo;
+ }
+
+ /**
+ * Set the information used to generate the secret key.
+ *
+ * @param info The info to set.
+ */
+ public void setSecretKeyInfo(@Nullable final byte[] info) {
+ secretKeyInfo = info;
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable protected PublicKey getPublicKey() {
+ if (null == getPublicKeyInfo()) {
+ return null;
+ }
+ return KeyPairUtil.decodePublicKey(getPublicKeyInfo());
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable protected PrivateKey getPrivateKey() {
+ if (null == getPrivateKeyInfo()) {
+ return null;
+ }
+ return KeyPairUtil.decodePrivateKey(getPrivateKeyInfo(), getPrivateKeyPassword());
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable protected SecretKey getSecretKey() {
+ if (null == getSecretKeyInfo()) {
+ return null;
+ }
+ try {
+ return KeySupport.decodeSecretKey(decodeSecretKey(getSecretKeyInfo()), getSecretKeyAlgorithm());
+ } catch (final KeyException e) {
+ throw new BeanCreationException("Could not decode secret key", e);
+ }
+ }
+}
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/credential/BasicResourceCredentialFactoryBean.java b/opensaml-spring/src/main/java/org/opensaml/spring/credential/BasicResourceCredentialFactoryBean.java
new file mode 100644
index 000000000..f70bcf263
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/credential/BasicResourceCredentialFactoryBean.java
@@ -0,0 +1,147 @@
+/*
+ * 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 org.opensaml.spring.credential;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+import javax.annotation.Nullable;
+import javax.crypto.SecretKey;
+
+import org.cryptacular.util.KeyPairUtil;
+import org.opensaml.security.crypto.KeySupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.core.io.Resource;
+
+import com.google.common.io.ByteStreams;
+
+/**
+ * Spring bean factory for producing a {@link org.opensaml.security.credential.BasicCredential} from {@link Resource}s.
+ */
+public class BasicResourceCredentialFactoryBean extends AbstractBasicCredentialFactoryBean {
+
+ /** log. */
+ private final Logger log = LoggerFactory.getLogger(BasicResourceCredentialFactoryBean.class);
+
+ /** Configured public key Info. */
+ @Nullable private Resource publicKeyInfo;
+
+ /** Configured private key Info. */
+ @Nullable private Resource privateKeyInfo;
+
+ /** Configured secret key Info. */
+ @Nullable private Resource secretKeyInfo;
+
+ /**
+ * Get the information used to generate the public key.
+ *
+ * @return Returns the info.
+ */
+ @Nullable public Resource getPublicKeyInfo() {
+ return publicKeyInfo;
+ }
+
+ /**
+ * Set the information used to generate the public key.
+ *
+ * @param info The info to set.
+ */
+ public void setPublicKeyInfo(@Nullable final Resource info) {
+ publicKeyInfo = info;
+ }
+
+ /**
+ * Get the information used to generate the private key.
+ *
+ * @return Returns the info.
+ */
+ @Nullable public Resource getPrivateKeyInfo() {
+ return privateKeyInfo;
+ }
+
+ /**
+ * Set the information used to generate the private key.
+ *
+ * @param info The info to set.
+ */
+ public void setPrivateKeyInfo(@Nullable final Resource info) {
+ privateKeyInfo = info;
+ }
+
+ /**
+ * Get the information used to generate the secret key.
+ *
+ * @return Returns the info.
+ */
+ @Nullable public Resource getSecretKeyInfo() {
+ return secretKeyInfo;
+ }
+
+ /**
+ * Set the information used to generate the secret key.
+ *
+ * @param info The info to set.
+ */
+ public void setSecretKeyInfo(@Nullable final Resource info) {
+ secretKeyInfo = info;
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable protected PublicKey getPublicKey() {
+ if (null == getPublicKeyInfo()) {
+ return null;
+ }
+ try (InputStream is = getPublicKeyInfo().getInputStream()) {
+ return KeyPairUtil.readPublicKey(is);
+ } catch (final IOException e) {
+ log.error("{}: Could not decode public key: {}", getConfigDescription(), e.getMessage());
+ throw new BeanCreationException("Could not decode public key", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable protected PrivateKey getPrivateKey() {
+ if (null == getPrivateKeyInfo()) {
+ return null;
+ }
+ try (InputStream is = getPrivateKeyInfo().getInputStream()) {
+ return KeySupport.decodePrivateKey(is, getPrivateKeyPassword());
+ } catch (final KeyException | IOException e) {
+ log.error("{}: Could not decode private key: {}", getConfigDescription(), e.getMessage());
+ throw new BeanCreationException("Could not decode private key", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable protected SecretKey getSecretKey() {
+ if (null == getSecretKeyInfo()) {
+ return null;
+ }
+ try (InputStream is = getSecretKeyInfo().getInputStream()) {
+ return KeySupport.decodeSecretKey(decodeSecretKey(ByteStreams.toByteArray(is)), getSecretKeyAlgorithm());
+ } catch (final KeyException | IOException e) {
+ log.error("{}: Could not decode secret key: {}", getConfigDescription(), e.getMessage());
+ throw new BeanCreationException("Could not decode secret key", e);
+ }
+ }
+}
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/credential/BasicX509CredentialFactoryBean.java b/opensaml-spring/src/main/java/org/opensaml/spring/credential/BasicX509CredentialFactoryBean.java
new file mode 100644
index 000000000..bbacc69e4
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/credential/BasicX509CredentialFactoryBean.java
@@ -0,0 +1,224 @@
+/*
+ * 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 org.opensaml.spring.credential;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyException;
+import java.security.PrivateKey;
+import java.security.cert.CRLException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.collection.LazyList;
+
+import org.opensaml.security.crypto.KeySupport;
+import org.opensaml.security.x509.X509Support;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.core.io.Resource;
+
+/**
+ * Spring bean factory for producing a {@link org.opensaml.security.x509.BasicX509Credential} from {@link Resource}s.
+ *
+ * <p>
+ * This factory bean supports DER and PEM encoded certificate resources and encrypted and non-encrypted PKCS8, DER, or
+ * PEM encoded private key resources.
+ * </p>
+ */
+public class BasicX509CredentialFactoryBean extends AbstractX509CredentialFactoryBean {
+
+ /** log. */
+ private final Logger log = LoggerFactory.getLogger(BasicX509CredentialFactoryBean.class);
+
+ /** The specification of where the entity Resource is to be found. */
+ private Resource entityResource;
+
+ /** Where the certificates are to be found. */
+ private List<Resource> certificateResources;
+
+ /** Where the private key is to be found. */
+ private Resource privateKeyResource;
+
+ /** Where the crls are to be found. */
+ private List<Resource> crlResources;
+
+ /**
+ * Set the Resource with the entity certificate.
+ *
+ * @param what The Resource to set.
+ */
+ public void setEntity(@Nonnull final Resource what) {
+ entityResource = what;
+ }
+
+ /**
+ * Sets the Resources which contain the certificates.
+ *
+ * @param what The values to set.
+ */
+ public void setCertificates(@Nullable @NotEmpty final List<Resource> what) {
+ certificateResources = what;
+ }
+
+ /**
+ * Set the Resource with the entity certificate.
+ *
+ * @param what The resource to set.
+ */
+ public void setPrivateKey(@Nullable final Resource what) {
+ privateKeyResource = what;
+ }
+
+ /**
+ * Sets the Resources which contain the crls.
+ *
+ * @param what The value to set.
+ */
+ public void setCRLs(@Nullable @NotEmpty final List<Resource> what) {
+ crlResources = what;
+ }
+
+ //
+ // BasicX509CredentialFactoryBean
+ //
+ /**
+ * Set the resource containing the private key.
+ *
+ * @param res private key resource, never <code>null</code>
+ */
+ public void setPrivateKeyResource(@Nonnull final Resource res) {
+ setPrivateKey(res);
+ }
+
+ /**
+ * Set the password for the private key.
+ *
+ * @param password password for the private key, may be null if the key is not encrypted
+ */
+ public void setPrivateKeyPassword(@Nullable final String password) {
+ setPrivateKeyPassword(password.toCharArray());
+ }
+
+ /**
+ * Set the certificate resource.
+ *
+ * @param res certificate resource
+ */
+ public void setCertificateResource(@Nonnull final Resource res) {
+ setCertificates(Collections.singletonList(res));
+ }
+
+ /**
+ * Set the entityID for the credential.
+ *
+ * @param id entityID
+ */
+ public void setEntityId(@Nullable final String id) {
+ setEntityID(id);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isSingleton() {
+ return true;
+ }
+
+ /** {@inheritDoc}. */
+ @Override @Nullable protected X509Certificate getEntityCertificate() {
+
+ if (null == entityResource) {
+ return null;
+ }
+ try {
+ final Collection<X509Certificate> certs = X509Support.decodeCertificates(entityResource.getInputStream());
+ if (certs.size() > 1) {
+ log.error("{}: Configuration element indicated an entityCertificate,"
+ + " but multiple certificates were decoded", getConfigDescription());
+ throw new FatalBeanException("Configuration element indicated an entityCertificate,"
+ + " but multiple certificates were decoded");
+ }
+ return certs.iterator().next();
+ } catch (final CertificateException | IOException e) {
+ log.error("{}: Could not decode provided Entity Certificate at {}: {}", getConfigDescription(),
+ entityResource.getDescription(), e.getMessage());
+ throw new FatalBeanException("Could not decode provided Entity Certificate file "
+ + entityResource.getDescription(), e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nonnull protected List<X509Certificate> getCertificates() {
+
+ if (certificateResources == null) {
+ return Collections.emptyList();
+ }
+
+ final List<X509Certificate> certificates = new LazyList<>();
+ for (final Resource r : certificateResources) {
+ try(InputStream is = r.getInputStream()) {
+ certificates.addAll(X509Support.decodeCertificates(is));
+ } catch (final CertificateException | IOException e) {
+ log.error("{}: could not decode CertificateFile at {}: {}", getConfigDescription(),
+ r.getDescription(), e.getMessage());
+ throw new FatalBeanException("Could not decode provided CertificateFile: " + r.getDescription(), e);
+ }
+ }
+ return certificates;
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable protected PrivateKey getPrivateKey() {
+ if (null == privateKeyResource) {
+ return null;
+ }
+ try (InputStream is = privateKeyResource.getInputStream()) {
+ return KeySupport.decodePrivateKey(is, getPrivateKeyPassword());
+ } catch (final KeyException | IOException e) {
+ log.error("{}: Could not decode KeyFile at {}: {}", getConfigDescription(),
+ privateKeyResource.getDescription(), e.getMessage());
+ throw new FatalBeanException("Could not decode provided KeyFile " + privateKeyResource.getDescription(), e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable protected List<X509CRL> getCRLs() {
+ if (null == crlResources) {
+ return null;
+ }
+ final List<X509CRL> crls = new LazyList<>();
+ for (final Resource crl : crlResources) {
+ try (InputStream is = crl.getInputStream()) {
+ crls.addAll(X509Support.decodeCRLs(is));
+ } catch (final CRLException | IOException e) {
+ log.error("{}: Could not decode CRL file at {}: {}", getConfigDescription(), crl.getDescription(),
+ e.getMessage());
+ throw new FatalBeanException("Could not decode provided CRL file " + crl.getDescription(), e);
+ }
+ }
+ return crls;
+ }
+}
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/credential/X509InlineCredentialFactoryBean.java b/opensaml-spring/src/main/java/org/opensaml/spring/credential/X509InlineCredentialFactoryBean.java
new file mode 100644
index 000000000..f5f1b80de
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/credential/X509InlineCredentialFactoryBean.java
@@ -0,0 +1,147 @@
+/*
+ * 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 org.opensaml.spring.credential;
+
+import java.security.PrivateKey;
+import java.security.cert.CRLException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.collection.LazyList;
+
+import org.cryptacular.util.KeyPairUtil;
+import org.opensaml.security.x509.X509Support;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.FatalBeanException;
+
+/**
+ * A factory bean to understand X509Inline credentials.
+ */
+public class X509InlineCredentialFactoryBean extends AbstractX509CredentialFactoryBean {
+
+ /** log. */
+ private final Logger log = LoggerFactory.getLogger(X509InlineCredentialFactoryBean.class);
+
+ /** The entity certificate. */
+ private String entityCertificate;
+
+ /** The certificates. */
+ private List<String> certificates;
+
+ /** The private key. */
+ private byte[] privateKey;
+
+ /** The crls. */
+ private List<String> crls;
+
+ /**
+ * Set the file with the entity certificate.
+ *
+ * @param entityCert The file to set.
+ */
+ public void setEntity(@Nonnull final String entityCert) {
+ entityCertificate = entityCert;
+ }
+
+ /**
+ * Sets the certificates.
+ *
+ * @param certs The value to set.
+ */
+ public void setCertificates(@Nullable @NotEmpty final List<String> certs) {
+ certificates = certs;
+ }
+
+ /**
+ * Set the private key.
+ *
+ * @param key The file to set.
+ */
+ public void setPrivateKey(@Nullable final byte[] key) {
+ privateKey = key;
+ }
+
+ /**
+ * Sets the files which contain the crls.
+ *
+ * @param list The value to set.
+ */
+ public void setCRLs(@Nullable @NotEmpty final List<String> list) {
+ crls = list;
+ }
+
+ /** {@inheritDoc}. */
+ @Override @Nullable protected X509Certificate getEntityCertificate() {
+
+ if (null == entityCertificate) {
+ return null;
+ }
+ try {
+ return X509Support.decodeCertificate(entityCertificate);
+ } catch (final CertificateException e) {
+ log.error("{}: Could not decode provided Entity Certificate: {}", getConfigDescription(), e.getMessage());
+ throw new FatalBeanException("Could not decode provided Entity Certificate", e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nonnull protected List<X509Certificate> getCertificates() {
+ final List<X509Certificate> certs = new LazyList<>();
+ for (final String cert : certificates) {
+ try {
+ certs.add(X509Support.decodeCertificate(cert.trim()));
+ } catch (final CertificateException e) {
+ log.error("{}: Could not decode provided Certificate: {}", getConfigDescription(), e.getMessage());
+ throw new FatalBeanException("Could not decode provided Certificate", e);
+ }
+ }
+ return certs;
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable protected PrivateKey getPrivateKey() {
+ if (null == privateKey) {
+ return null;
+ }
+ return KeyPairUtil.decodePrivateKey(privateKey, getPrivateKeyPassword());
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable protected List<X509CRL> getCRLs() {
+ if (null == crls) {
+ return null;
+ }
+ final List<X509CRL> result = new LazyList<>();
+ for (final String crl : crls) {
+ try {
+ result.add(X509Support.decodeCRL(crl));
+ } catch (final CRLException | CertificateException e) {
+ log.error("{}: Could not decode provided CRL: {}", getConfigDescription(), e.getMessage());
+ throw new FatalBeanException("Could not decode provided CRL", e);
+ }
+ }
+ return result;
+ }
+}
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/credential/package-info.java b/opensaml-spring/src/main/java/org/opensaml/spring/credential/package-info.java
new file mode 100644
index 000000000..b599cb5e9
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/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.
+ */
+
+/**
+ * Factory beans for various credential classes.
+ */
+
+package org.opensaml.spring.credential;
\ No newline at end of file
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/tls/TLSSocketFactoryFactoryBean.java b/opensaml-spring/src/main/java/org/opensaml/spring/tls/TLSSocketFactoryFactoryBean.java
new file mode 100644
index 000000000..3c11c406e
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/tls/TLSSocketFactoryFactoryBean.java
@@ -0,0 +1,96 @@
+/*
+ * 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 org.opensaml.spring.tls;
+
+import javax.annotation.Nullable;
+
+import org.apache.http.client.HttpClient;
+import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
+import org.opensaml.security.httpclient.HttpClientSecurityParameters;
+import org.opensaml.security.httpclient.impl.SecurityEnhancedHttpClientSupport;
+import org.opensaml.security.trust.TrustEngine;
+import org.opensaml.security.x509.X509Credential;
+import org.springframework.beans.factory.config.AbstractFactoryBean;
+
+import net.shibboleth.utilities.java.support.httpclient.HttpClientSupport;
+
+/**
+ * A factory bean for producing instances of {@link LayeredConnectionSocketFactory} for use in {@link HttpClient}.
+ */
+public class TLSSocketFactoryFactoryBean extends AbstractFactoryBean<LayeredConnectionSocketFactory> {
+
+ /** The optional trust engine used in evaluating server TLS credentials. */
+ private TrustEngine<?> tlsTrustEngine;
+
+ /** The optional HttpClient security parameters instance that will be used with the HttpClient instance. */
+ private HttpClientSecurityParameters httpClientSecurityParameters;
+
+ /** Whether the responder's SSL/TLS certificate should be ignored. */
+ private boolean connectionDisregardTLSCertificate;
+
+ /**
+ * Sets the optional trust engine used in evaluating server TLS credentials.
+ *
+ * @deprecated use setHttpClientSecurityParameters instead
+ * @param engine the trust engine instance to use, or null
+ */
+ @Deprecated
+ public void setTLSTrustEngine(@Nullable final TrustEngine<? super X509Credential> engine) {
+ tlsTrustEngine = engine;
+ }
+
+ /**
+ * Sets the optional HttpClient security parameters instance that will be used with the HttpClient instance.
+ *
+ * @param params the parameters, or null
+ */
+ public void setHttpClientSecurityParameters(@Nullable final HttpClientSecurityParameters params) {
+ httpClientSecurityParameters = params;
+ }
+
+ /**
+ * Sets whether the responder's SSL/TLS certificate should be ignored.
+ *
+ * @param disregard whether the responder's SSL/TLS certificate should be ignored
+ */
+ public void setConnectionDisregardTLSCertificate(final boolean disregard) {
+ connectionDisregardTLSCertificate = disregard;
+ }
+
+
+ /** {@inheritDoc} */
+ @Override public Class<LayeredConnectionSocketFactory> getObjectType() {
+ return LayeredConnectionSocketFactory.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected LayeredConnectionSocketFactory createInstance() throws Exception {
+ final boolean haveTrustEngine = tlsTrustEngine != null
+ || (httpClientSecurityParameters != null && httpClientSecurityParameters.getTLSTrustEngine() != null);
+ final boolean haveClientTLSCred =
+ httpClientSecurityParameters != null && httpClientSecurityParameters.getClientTLSCredential() != null;
+ if (haveTrustEngine || haveClientTLSCred) {
+ return SecurityEnhancedHttpClientSupport.buildTLSSocketFactory(haveTrustEngine, haveClientTLSCred);
+ } else if (connectionDisregardTLSCertificate) {
+ return HttpClientSupport.buildNoTrustTLSSocketFactory();
+ } else {
+ return HttpClientSupport.buildStrictTLSSocketFactory();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/tls/package-info.java b/opensaml-spring/src/main/java/org/opensaml/spring/tls/package-info.java
new file mode 100644
index 000000000..81404861f
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/tls/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.
+ */
+
+/**
+ * Spring support for TLS configuration.
+ */
+
+package org.opensaml.spring.tls;
\ No newline at end of file
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/trust/AbstractBasicPKIXValidationInfoFactoryBean.java b/opensaml-spring/src/main/java/org/opensaml/spring/trust/AbstractBasicPKIXValidationInfoFactoryBean.java
new file mode 100644
index 000000000..97d0a8f18
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/trust/AbstractBasicPKIXValidationInfoFactoryBean.java
@@ -0,0 +1,103 @@
+/*
+ * 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 org.opensaml.spring.trust;
+
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.ext.spring.factory.AbstractComponentAwareFactoryBean;
+
+import org.opensaml.security.x509.impl.BasicPKIXValidationInformation;
+
+/**
+ * A factory bean to collect information to do with a {@link BasicPKIXValidationInformation}.
+ */
+public abstract class AbstractBasicPKIXValidationInfoFactoryBean extends
+ AbstractComponentAwareFactoryBean<BasicPKIXValidationInformation> {
+
+ /** Verification depth. */
+ @Nullable private Integer verifyDepth;
+
+ /** The description of the file with the configuration us. */
+ @Nonnull private String configDescription;
+
+ /**
+ * Get the verify Depth.
+ *
+ * @return Returns the depth.
+ */
+ public int getVerifyDepth() {
+ return verifyDepth;
+ }
+
+ /**
+ * Set the verify Depth.
+ *
+ * @param depth The value to set.
+ */
+ public void setVerifyDepth(final int depth) {
+ verifyDepth = depth;
+ }
+
+ /**
+ * For logging, get the description of the resource that defined this bean.
+ *
+ * @return Returns the description.
+ */
+ public String getConfigDescription() {
+ return configDescription;
+ }
+
+ /**
+ * For logging, set the description of the resource that defined this bean.
+ *
+ * @param desc what to set.
+ */
+ public void setConfigDescription(@Nonnull final String desc) {
+ configDescription = desc;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Class<?> getObjectType() {
+ return BasicPKIXValidationInformation.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected BasicPKIXValidationInformation doCreateInstance() throws Exception {
+ return new BasicPKIXValidationInformation(getCertificates(), getCRLs(), verifyDepth);
+ }
+
+ /**
+ * Get the configured certificates.
+ *
+ * @return the certificates.
+ */
+ @Nullable protected abstract List<X509Certificate> getCertificates();
+
+ /**
+ * Get the configured CRL list.
+ *
+ * @return the crls or null
+ */
+ @Nullable protected abstract List<X509CRL> getCRLs();
+
+}
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/trust/ChainingSignatureTrustEngineFactoryBean.java b/opensaml-spring/src/main/java/org/opensaml/spring/trust/ChainingSignatureTrustEngineFactoryBean.java
new file mode 100644
index 000000000..befba7c0d
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/trust/ChainingSignatureTrustEngineFactoryBean.java
@@ -0,0 +1,69 @@
+/*
+ * 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 org.opensaml.spring.trust;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.ext.spring.factory.AbstractComponentAwareFactoryBean;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+
+import org.opensaml.xmlsec.signature.support.SignatureTrustEngine;
+import org.opensaml.xmlsec.signature.support.impl.ChainingSignatureTrustEngine;
+
+/**
+ * Factory bean for {@link ChainingSignatureTrustEngine}. This finesses the issue that some parsers are not supported
+ * and return a bean of type object and these cannot be injected into the trust engine. This factory just filters the
+ * unsupported engines out. A warning has been issued at point of parse so no further logging is required.
+ */
+public class ChainingSignatureTrustEngineFactoryBean extends
+ AbstractComponentAwareFactoryBean<ChainingSignatureTrustEngine> {
+
+ /** The unfiltered list of putative trust engines. */
+ private final List<Object> engines;
+
+ /**
+ * Constructor.
+ *
+ * @param list the putative trust engines.
+ */
+ public ChainingSignatureTrustEngineFactoryBean(@Nonnull final List<Object> list) {
+ engines = Constraint.isNotNull(list, "Engine list must be non null");
+ }
+
+ /** {@inheritDoc} */
+ @Override public Class<?> getObjectType() {
+ return ChainingSignatureTrustEngine.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected ChainingSignatureTrustEngine doCreateInstance() throws Exception {
+ final List<SignatureTrustEngine> list = new ArrayList<>(engines.size());
+
+ for (final Object engine : engines) {
+ if (engine instanceof SignatureTrustEngine) {
+ list.add((SignatureTrustEngine) engine);
+
+ }
+ }
+ return new ChainingSignatureTrustEngine(list);
+ }
+
+}
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/trust/ChainingTrustEngineFactoryBean.java b/opensaml-spring/src/main/java/org/opensaml/spring/trust/ChainingTrustEngineFactoryBean.java
new file mode 100644
index 000000000..fd1085d9b
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/trust/ChainingTrustEngineFactoryBean.java
@@ -0,0 +1,70 @@
+/*
+ * 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 org.opensaml.spring.trust;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.ext.spring.factory.AbstractComponentAwareFactoryBean;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+
+import org.opensaml.security.trust.TrustEngine;
+import org.opensaml.security.trust.impl.ChainingTrustEngine;
+
+/**
+ * Factory bean for {@link ChainingTrustEngine}. This finesses the issue that some parsers are not supported
+ * and return a bean of type object and these cannot be injected into the trust engine. This factory just filters the
+ * unsupported engines out. A warning has been issued at point of parse so no further logging is required.
+ */
+public class ChainingTrustEngineFactoryBean extends
+ AbstractComponentAwareFactoryBean<ChainingTrustEngine<?>> {
+
+ /** The unfiltered list of putative trust engines. */
+ private final List<Object> engines;
+
+ /**
+ * Constructor.
+ *
+ * @param list the putative trust engines.
+ */
+ public ChainingTrustEngineFactoryBean(@Nonnull final List<Object> list) {
+ engines = Constraint.isNotNull(list, "Engine list must be non null");
+ }
+
+ /** {@inheritDoc} */
+ @Override public Class<?> getObjectType() {
+ return ChainingTrustEngine.class;
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ @Override protected ChainingTrustEngine<?> doCreateInstance() throws Exception {
+ final List<TrustEngine<?>> list = new ArrayList<>(engines.size());
+
+ for (final Object engine : engines) {
+ if (engine instanceof TrustEngine) {
+ list.add((TrustEngine<?>) engine);
+
+ }
+ }
+ return new ChainingTrustEngine(list);
+ }
+
+}
\ No newline at end of file
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/trust/PKIXInlineValidationInfoFactoryBean.java b/opensaml-spring/src/main/java/org/opensaml/spring/trust/PKIXInlineValidationInfoFactoryBean.java
new file mode 100644
index 000000000..36f4ec0ce
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/trust/PKIXInlineValidationInfoFactoryBean.java
@@ -0,0 +1,107 @@
+/*
+ * 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 org.opensaml.spring.trust;
+
+import java.security.cert.CRLException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.security.x509.X509Support;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.FatalBeanException;
+
+/**
+ * File system specific bean for PKIXValidationInfo.
+ */
+public class PKIXInlineValidationInfoFactoryBean extends AbstractBasicPKIXValidationInfoFactoryBean {
+
+ /** log. */
+ private Logger log = LoggerFactory.getLogger(PKIXInlineValidationInfoFactoryBean.class);
+
+ /** The strings to be turned into the certificates. */
+ private List<String> certificateFiles;
+
+ /** The strings to be turned into the crls. */
+ private List<String> crlStrings;
+
+ /**
+ * Set the file names which we will convert into certificates.
+ *
+ * @param certs the file names.
+ */
+ public void setCertificates(@Nullable final List<String> certs) {
+ certificateFiles = certs;
+ }
+
+ /**
+ * Set the file names which we will convert into crls.
+ *
+ * @param crls the file names.
+ */
+ public void setCRLs(@Nullable final List<String> crls) {
+ crlStrings = crls;
+ }
+
+ /**
+ * Get the configured certificates.
+ *
+ * @return the certificates null
+ */
+ @Override @Nullable protected List<X509Certificate> getCertificates() {
+ if (null == certificateFiles) {
+ return null;
+ }
+ final List<X509Certificate> certificates = new ArrayList<>(certificateFiles.size());
+ for (final String cert : certificateFiles) {
+ try {
+ certificates.add(X509Support.decodeCertificate(cert.trim()));
+ } catch (final CertificateException e) {
+ log.error("{}: Could not decode provided Certificate: {}", getConfigDescription(), e.getMessage());
+ throw new FatalBeanException("Could not decode provided Certificate", e);
+ }
+ }
+ return certificates;
+ }
+
+ /**
+ * Get the configured CRL list.
+ *
+ * @return the crls or null
+ */
+ @Override @Nullable protected List<X509CRL> getCRLs() {
+ if (null == crlStrings) {
+ return null;
+ }
+ final List<X509CRL> crls = new ArrayList<>(crlStrings.size());
+ for (final String crl : crlStrings) {
+ try {
+ crls.add(X509Support.decodeCRL(crl));
+ } catch (final CRLException | CertificateException e) {
+ log.error("{}: Could not decode provided CRL: {}", getConfigDescription(), e.getMessage());
+ throw new FatalBeanException("Could not decode provided CRL", e);
+ }
+ }
+ return crls;
+ }
+}
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/trust/PKIXResourceValidationInfoFactoryBean.java b/opensaml-spring/src/main/java/org/opensaml/spring/trust/PKIXResourceValidationInfoFactoryBean.java
new file mode 100644
index 000000000..52371d63e
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/trust/PKIXResourceValidationInfoFactoryBean.java
@@ -0,0 +1,112 @@
+/*
+ * 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 org.opensaml.spring.trust;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.cert.CRLException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.security.x509.X509Support;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.core.io.Resource;
+
+/**
+ * File system specific bean for PKIXValidationInfo.
+ */
+public class PKIXResourceValidationInfoFactoryBean extends AbstractBasicPKIXValidationInfoFactoryBean {
+
+ /** log. */
+ private Logger log = LoggerFactory.getLogger(PKIXResourceValidationInfoFactoryBean.class);
+
+ /** The file to be turned into the certificates. */
+ private List<Resource> certificateFiles;
+
+ /** The file to be turned into the crls. */
+ private List<Resource> crlFiles;
+
+ /**
+ * Set the file names which we will convert into certificates.
+ *
+ * @param certs the file names.
+ */
+ public void setCertificates(@Nullable final List<Resource> certs) {
+ certificateFiles = certs;
+ }
+
+ /**
+ * Set the file names which we will convert into crls.
+ *
+ * @param crls the file names.
+ */
+ public void setCRLs(@Nullable final List<Resource> crls) {
+ crlFiles = crls;
+ }
+
+ /**
+ * Get the configured certificates.
+ *
+ * @return the certificates null
+ */
+ @Override @Nullable protected List<X509Certificate> getCertificates() {
+ if (null == certificateFiles) {
+ return null;
+ }
+ final List<X509Certificate> certificates = new ArrayList<>(certificateFiles.size());
+ for (final Resource f : certificateFiles) {
+ try(InputStream is = f.getInputStream()) {
+ certificates.addAll(X509Support.decodeCertificates(is));
+ } catch (final CertificateException | IOException e) {
+ log.error("{}: Could not decode Certificate at {}: {}", getConfigDescription(), f.getDescription(),
+ e.getMessage());
+ throw new FatalBeanException("Could not decode provided CertificateFile: " + f.getDescription(), e);
+ }
+ }
+ return certificates;
+ }
+
+ /**
+ * Get the configured CRL list.
+ *
+ * @return the crls or null
+ */
+ @Override @Nullable protected List<X509CRL> getCRLs() {
+ if (null == crlFiles) {
+ return null;
+ }
+ final List<X509CRL> crls = new ArrayList<>(crlFiles.size());
+ for (final Resource crlFile : crlFiles) {
+ try(InputStream is = crlFile.getInputStream()) {
+ crls.addAll(X509Support.decodeCRLs(is));
+ } catch (final CRLException | IOException e) {
+ log.error("{}: Could not decode CRL file at {}: {}", getConfigDescription(), crlFile.getDescription(),
+ e.getMessage());
+ throw new FatalBeanException("Could not decode provided CRL file " + crlFile.getDescription(), e);
+ }
+ }
+ return crls;
+ }
+}
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/trust/StaticExplicitKeyFactoryBean.java b/opensaml-spring/src/main/java/org/opensaml/spring/trust/StaticExplicitKeyFactoryBean.java
new file mode 100644
index 000000000..3d80d2747
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/trust/StaticExplicitKeyFactoryBean.java
@@ -0,0 +1,140 @@
+/*
+ * 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 org.opensaml.spring.trust;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.cryptacular.EncodingException;
+import org.cryptacular.StreamException;
+import org.cryptacular.util.KeyPairUtil;
+import org.opensaml.security.credential.BasicCredential;
+import org.opensaml.security.credential.Credential;
+import org.opensaml.security.credential.impl.StaticCredentialResolver;
+import org.opensaml.security.trust.impl.ExplicitKeyTrustEngine;
+import org.opensaml.security.x509.BasicX509Credential;
+import org.opensaml.security.x509.X509Support;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.core.io.Resource;
+
+import net.shibboleth.ext.spring.factory.AbstractComponentAwareFactoryBean;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+
+/**
+ * Factory bean for simple use cases involving the {@link ExplicitKeyTrustEngine} and static credentials.
+ *
+ * @since 3.3.0
+ */
+public class StaticExplicitKeyFactoryBean extends AbstractComponentAwareFactoryBean<ExplicitKeyTrustEngine> {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(StaticExplicitKeyFactoryBean.class);
+
+ /** The resources to be turned into keys. */
+ private List<Resource> keyResources;
+
+ /** The resources to be turned into certificates. */
+ private List<Resource> certificateResources;
+
+ /** Constructor. */
+ public StaticExplicitKeyFactoryBean() {
+ keyResources = Collections.emptyList();
+ certificateResources = Collections.emptyList();
+ }
+
+ /**
+ * Set the resources which we will convert into certificates.
+ *
+ * @param keys the resources
+ */
+ public void setPublicKeys(@Nullable final List<Resource> keys) {
+ keyResources = keys != null ? keys : Collections.emptyList();
+ }
+
+ /**
+ * Set the resources which we will convert into certificates.
+ *
+ * @param certs the resources
+ */
+ public void setCertificates(@Nullable final List<Resource> certs) {
+ certificateResources = certs != null ? certs : Collections.emptyList();
+ }
+
+ /**
+ * Get the configured certificates.
+ *
+ * @return the certificates null
+ */
+ @Nullable @NonnullElements protected List<Credential> getCredentials() {
+
+ final List<Credential> credentials = new ArrayList<>(keyResources.size() + certificateResources.size());
+
+ for (final Resource f : keyResources) {
+ try(final InputStream is = f.getInputStream()) {
+ credentials.add(new BasicCredential(KeyPairUtil.readPublicKey(is)));
+ } catch (final EncodingException|StreamException|IOException e) {
+ log.error("Could not decode public key from {}: {}", f.getDescription(), e.getMessage());
+ throw new FatalBeanException("Could not decode public key from " + f.getDescription(), e);
+ }
+ }
+
+ for (final Resource f : certificateResources) {
+ try(final InputStream is = f.getInputStream()) {
+ final Collection<X509Certificate> raw = X509Support.decodeCertificates(is);
+ if (raw != null) {
+ raw.forEach(x -> {
+ if (x != null) {
+ credentials.add(new BasicX509Credential(x));
+ }
+ }
+ );
+ }
+
+ } catch (final CertificateException | IOException e) {
+ log.error("Could not decode certificate from {}: {}", f.getDescription(), e.getMessage());
+ throw new FatalBeanException("Could not decode certificate from " + f.getDescription(), e);
+ }
+ }
+
+ return credentials;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Class<?> getObjectType() {
+ return ExplicitKeyTrustEngine.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected ExplicitKeyTrustEngine doCreateInstance() throws Exception {
+ return new ExplicitKeyTrustEngine(new StaticCredentialResolver(getCredentials()));
+ }
+
+}
\ No newline at end of file
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/trust/StaticPKIXFactoryBean.java b/opensaml-spring/src/main/java/org/opensaml/spring/trust/StaticPKIXFactoryBean.java
new file mode 100644
index 000000000..8a70ba357
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/trust/StaticPKIXFactoryBean.java
@@ -0,0 +1,277 @@
+/*
+ * 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 org.opensaml.spring.trust;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.Security;
+import java.security.cert.CRLException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.security.x509.PKIXTrustEvaluator;
+import org.opensaml.security.x509.X509Support;
+import org.opensaml.security.x509.impl.BasicPKIXValidationInformation;
+import org.opensaml.security.x509.impl.BasicX509CredentialNameEvaluator;
+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.opensaml.security.x509.impl.X509CredentialNameEvaluator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.core.io.Resource;
+
+
+import net.shibboleth.ext.spring.factory.AbstractComponentAwareFactoryBean;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+
+/**
+ * File system specific bean for PKIXX509CredentialTrustEngine.
+ *
+ * @since 3.3.0
+ */
+public class StaticPKIXFactoryBean extends AbstractComponentAwareFactoryBean<PKIXX509CredentialTrustEngine> {
+
+ /** log. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(StaticPKIXFactoryBean.class);
+
+ /** Certificate resources. */
+ @Nullable private List<Resource> certificateResources;
+
+ /** CRL resources. */
+ @Nullable private List<Resource> crlResources;
+
+ /** Verification depth. */
+ @Nullable private Integer verifyDepth;
+
+ /** Explicit subject name(s) to match. */
+ @Nullable private Set<String> trustedNames;
+
+ /** Whether to enable name checking. If true a default implementation will be used.
+ * See also: {@link #credentialNameEvaluator}. */
+ private boolean checkNames;
+
+ /** Custom instance of {@link PKIXTrustEvaluator} to use. */
+ private PKIXTrustEvaluator trustEvaluator;
+
+ /** Custom instance of {@link X509CredentialNameEvaluator} to use.
+ * A non-null value overrides {@link #checkNames}. */
+ private X509CredentialNameEvaluator credentialNameEvaluator;
+
+ /** Constructor. */
+ public StaticPKIXFactoryBean() {
+ checkNames = true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Class<?> getObjectType() {
+ return PKIXX509CredentialTrustEngine.class;
+ }
+
+ /**
+ * Set the resources which we will convert into certificates.
+ *
+ * @param certs the resources
+ */
+ public void setCertificates(@Nullable final List<Resource> certs) {
+ certificateResources = certs;
+ }
+
+ /**
+ * Set the resources which we will convert into CRLs.
+ *
+ * @param crls the resources
+ */
+ public void setCRLs(@Nullable final List<Resource> crls) {
+ crlResources = crls;
+ }
+
+ /**
+ * Set the verify depth.
+ *
+ * @param depth value to set
+ */
+ public void setVerifyDepth(final int depth) {
+ verifyDepth = depth;
+ }
+
+ /**
+ * Set whether the perform name checking in the PKIX layer.
+ *
+ * <p>
+ * Defaults to "true", should generally be disabled when used with an HTTP client
+ * that is already checking names.
+ * </p>
+ *
+ * <p>
+ * If true a default implementation will be used unless a specific name evaluator impl has been supplied.
+ * See also: {@link #setCredentialNameEvaluator(X509CredentialNameEvaluator)}.
+ * </p>
+ *
+ * @param flag flag to set
+ *
+ * @since 3.4.0
+ */
+ public void setCheckNames(final boolean flag) {
+ checkNames = flag;
+ }
+
+ /**
+ * Set explicitly trusted names to match against credential.
+ *
+ * @param names explicitly trusted names
+ *
+ * @since 3.4.0
+ */
+ public void setTrustedNames(@Nullable @NonnullElements final Collection<String> names) {
+ if (names != null) {
+ trustedNames = Set.copyOf(names);
+ } else {
+ trustedNames = null;
+ }
+ }
+
+ /**
+ * Set the custom instance of {@link PKIXTrustEvaluator} to use.
+ *
+ * @param evaluator The trustEvaluator to set.
+ */
+ public void setTrustEvaluator(@Nullable final PKIXTrustEvaluator evaluator) {
+ trustEvaluator = evaluator;
+ }
+
+ /**
+ * Set the custom instance of {@link X509CredentialNameEvaluator} to use.
+ *
+ * <p>
+ * A non-null value overrides {@link #setCheckNames(boolean)}.
+ * </p>
+ *
+ * @param evaluator The credentialNameEvaluator to set.
+ */
+ public void setCredentialNameEvaluator(@Nullable final X509CredentialNameEvaluator evaluator) {
+ credentialNameEvaluator = evaluator;
+ }
+
+ /**
+ * Get the configured certificates.
+ *
+ * @return the certificates
+ */
+ @Nonnull @NonnullElements protected List<X509Certificate> getCertificates() {
+ if (certificateResources == null) {
+ return Collections.emptyList();
+ }
+
+ final List<X509Certificate> certificates = new ArrayList<>(certificateResources.size());
+ for (final Resource f : certificateResources) {
+ try(final InputStream is = f.getInputStream()) {
+ certificates.addAll(X509Support.decodeCertificates(is));
+ } catch (final CertificateException | IOException e) {
+ log.error("Could not decode Certificate at {}: {}", f.getDescription(), e.getMessage());
+ throw new FatalBeanException("Could not decode provided CertificateFile: " + f.getDescription(), e);
+ }
+ }
+ return certificates;
+ }
+
+ /**
+ * Get the configured CRL list.
+ *
+ * @return the crls
+ */
+ @Nonnull @NonnullElements protected List<X509CRL> getCRLs() {
+ if (crlResources == null) {
+ return Collections.emptyList();
+ }
+
+ final List<X509CRL> crls = new ArrayList<>(crlResources.size());
+ for (final Resource crlFile : crlResources) {
+ try(final InputStream is = crlFile.getInputStream()) {
+ crls.addAll(X509Support.decodeCRLs(is));
+ } catch (final CRLException | IOException e) {
+ log.error("Could not decode CRL file at {}: {}", crlFile.getDescription(), e.getMessage());
+ throw new FatalBeanException("Could not decode provided CRL file " + crlFile.getDescription(), e);
+ }
+ }
+ return crls;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected PKIXX509CredentialTrustEngine doCreateInstance() throws Exception {
+ final BasicPKIXValidationInformation info =
+ new BasicPKIXValidationInformation(getCertificates(), getCRLs(), verifyDepth);
+
+ final StaticPKIXValidationInformationResolver resolver =
+ new StaticPKIXValidationInformationResolver(Collections.singletonList(info), trustedNames, checkNames);
+
+ final PKIXTrustEvaluator pkixTrustEvaluator =
+ trustEvaluator != null ? trustEvaluator : new CertPathPKIXTrustEvaluator();
+
+ final X509CredentialNameEvaluator credNameEvaluator =
+ credentialNameEvaluator != null ? credentialNameEvaluator :
+ (checkNames ? new BasicX509CredentialNameEvaluator() : null);
+
+ validateConfiguration(pkixTrustEvaluator);
+
+ return new PKIXX509CredentialTrustEngine(resolver, pkixTrustEvaluator, credNameEvaluator);
+ }
+
+ /**
+ * Validate the configuration of the effective {@link PKIXTrustEvaluator}.
+ *
+ * @param pkixTrustEvaluator the instance whose configuration is to be evaluated
+ *
+ * @throws Exception if configuration issues are encountered
+ */
+ protected void validateConfiguration(@Nonnull final PKIXTrustEvaluator pkixTrustEvaluator) throws Exception {
+ if (CertPathPKIXTrustEvaluator.class.isInstance(pkixTrustEvaluator)
+ && CertPathPKIXValidationOptions.class.isInstance(pkixTrustEvaluator.getPKIXValidationOptions())) {
+
+ final CertPathPKIXValidationOptions certPathOptions =
+ CertPathPKIXValidationOptions.class.cast(pkixTrustEvaluator.getPKIXValidationOptions());
+
+ if (certPathOptions.isForceRevocationEnabled() && certPathOptions.isRevocationEnabled()
+ && getCRLs().isEmpty()
+ && ! Boolean.getBoolean("com.sun.security.enableCRLDP")
+ && ! "true".equalsIgnoreCase(StringSupport.trimOrNull(Security.getProperty("oscp.enable"))) ) {
+
+ log.error("Certificate revocation checking was force enabled, "
+ + "but no static CRLs were supplied and both CRLDP and OCSP processing is disabled");
+
+ throw new FatalBeanException("Certificate revocation checking was force enabled, "
+ + "but no static CRLs were supplied and both CRLDP and OCSP processing is disabled");
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/opensaml-spring/src/main/java/org/opensaml/spring/trust/package-info.java b/opensaml-spring/src/main/java/org/opensaml/spring/trust/package-info.java
new file mode 100644
index 000000000..5bf1420a2
--- /dev/null
+++ b/opensaml-spring/src/main/java/org/opensaml/spring/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.
+ */
+
+/**
+ * Factory beans for trust engines.
+ */
+
+package org.opensaml.spring.trust;
\ No newline at end of file
diff --git a/opensaml-spring/src/test/java/org/opensaml/spring/credential/BasicX509CredentialFactoryBeanTest.java b/opensaml-spring/src/test/java/org/opensaml/spring/credential/BasicX509CredentialFactoryBeanTest.java
new file mode 100644
index 000000000..adf7a4478
--- /dev/null
+++ b/opensaml-spring/src/test/java/org/opensaml/spring/credential/BasicX509CredentialFactoryBeanTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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 org.opensaml.spring.credential;
+
+import org.opensaml.security.x509.BasicX509Credential;
+import org.springframework.context.support.GenericApplicationContext;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.ext.spring.context.FilesystemGenericApplicationContext;
+import net.shibboleth.ext.spring.util.SchemaTypeAwareXMLBeanDefinitionReader;
+
+/**
+ * Unit test for {@link BasicX509CredentialFactoryBean}.
+ */
+public class BasicX509CredentialFactoryBeanTest {
+
+ @Test public void bean() {
+ final GenericApplicationContext context = new FilesystemGenericApplicationContext();
+ context.setDisplayName("ApplicationContext: X509Credential");
+ final SchemaTypeAwareXMLBeanDefinitionReader beanDefinitionReader =
+ new SchemaTypeAwareXMLBeanDefinitionReader(context);
+
+ beanDefinitionReader.loadBeanDefinitions("org/opensaml/spring/credential/bean.xml");
+
+ context.refresh();
+
+ final BasicX509Credential cred1 = context.getBean("Credential", BasicX509Credential.class);
+
+ final BasicX509Credential cred2 = context.getBean("EncCredential", BasicX509Credential.class);
+
+ Assert.assertEquals("http://example.org/enc", cred2.getEntityId());
+
+ final byte[] cb1 = cred1.getPrivateKey().getEncoded();
+ final byte[] cb2 = cred2.getPrivateKey().getEncoded();
+
+ Assert.assertEquals(cb1.length, cb2.length);
+
+ for (int i = 0; i< cb1.length; i++)Assert.assertEquals(cb1[i], cb2[i]);
+
+ Assert.assertEquals(cred2.getPublicKey(), cred2.getPublicKey());
+
+ }
+
+}
\ No newline at end of file
diff --git a/opensaml-spring/src/test/java/org/opensaml/spring/trust/AbstractSecurityTest.java b/opensaml-spring/src/test/java/org/opensaml/spring/trust/AbstractSecurityTest.java
new file mode 100644
index 000000000..5cf006221
--- /dev/null
+++ b/opensaml-spring/src/test/java/org/opensaml/spring/trust/AbstractSecurityTest.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 org.opensaml.spring.trust;
+
+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 tests using Spring.
+ */
+ at SuppressWarnings("javadoc")
+public class AbstractSecurityTest {
+
+ private static final String PATH = "/org/opensaml/spring/";
+
+ 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/opensaml-spring/src/test/java/org/opensaml/spring/trust/MockTrustEngine.java b/opensaml-spring/src/test/java/org/opensaml/spring/trust/MockTrustEngine.java
new file mode 100644
index 000000000..fc3481353
--- /dev/null
+++ b/opensaml-spring/src/test/java/org/opensaml/spring/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 org.opensaml.spring.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/opensaml-spring/src/test/java/org/opensaml/spring/trust/StaticExplicitKeyFactoryBeanTest.java b/opensaml-spring/src/test/java/org/opensaml/spring/trust/StaticExplicitKeyFactoryBeanTest.java
new file mode 100644
index 000000000..47f1cb271
--- /dev/null
+++ b/opensaml-spring/src/test/java/org/opensaml/spring/trust/StaticExplicitKeyFactoryBeanTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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 org.opensaml.spring.trust;
+
+import java.io.IOException;
+import java.time.Instant;
+import java.util.Iterator;
+
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+import org.opensaml.security.credential.Credential;
+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.X509Credential;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Test for StaticExplicitKey factory bean.
+ */
+ at SuppressWarnings("javadoc")
+public class StaticExplicitKeyFactoryBeanTest extends AbstractSecurityTest {
+
+ static private String TESTPATH = "trust/staticExplicitNative.xml";
+
+ @Test public void singleKey() throws IOException, ResolverException {
+ final ExplicitKeyTrustEngine engine = (ExplicitKeyTrustEngine) getBean("staticKeySingle", TrustEngine.class, TESTPATH);
+
+ final StaticCredentialResolver resolver = (StaticCredentialResolver) engine.getCredentialResolver();
+ Credential credential = resolver.resolveSingle(null);
+
+ Assert.assertNotNull(credential.getPublicKey());
+ }
+
+ @Test public void singleCert() throws IOException, ResolverException {
+ final ExplicitKeyTrustEngine engine = (ExplicitKeyTrustEngine) getBean("staticX509Single", TrustEngine.class, TESTPATH);
+
+ final StaticCredentialResolver resolver = (StaticCredentialResolver) engine.getCredentialResolver();
+ X509Credential credential = (X509Credential) 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());
+ }
+
+ @Test public void multipleCert() throws IOException, ResolverException {
+ final ExplicitKeyTrustEngine engine = (ExplicitKeyTrustEngine) getBean("staticX509Multiple", TrustEngine.class, TESTPATH);
+
+ final StaticCredentialResolver resolver = (StaticCredentialResolver) engine.getCredentialResolver();
+
+ Iterator<Credential> credentials = resolver.resolve(null).iterator();
+
+ Assert.assertTrue(credentials.hasNext());
+ final X509Credential first = (X509Credential) credentials.next();
+ Assert.assertEquals(first.getEntityCertificateChain().size(), 1);
+
+ Assert.assertTrue(credentials.hasNext());
+ final X509Credential second = (X509Credential) credentials.next();
+ Assert.assertEquals(second.getEntityCertificateChain().size(), 1);
+ }
+
+ @Test public void mixed() throws IOException, ResolverException {
+ final ExplicitKeyTrustEngine engine = (ExplicitKeyTrustEngine) getBean("staticMixed", TrustEngine.class, TESTPATH);
+
+ final StaticCredentialResolver resolver = (StaticCredentialResolver) engine.getCredentialResolver();
+
+ Iterator<Credential> credentials = resolver.resolve(null).iterator();
+
+ Assert.assertTrue(credentials.hasNext());
+ final Credential first = credentials.next();
+ Assert.assertNotNull(first.getPublicKey());
+ Assert.assertFalse(first instanceof X509Credential);
+
+ Assert.assertTrue(credentials.hasNext());
+ final X509Credential second = (X509Credential) credentials.next();
+ Assert.assertEquals(second.getEntityCertificateChain().size(), 1);
+ Assert.assertEquals(second.getEntityCertificate().getNotAfter().getTime(), Instant.parse("2024-04-08T13:39:18Z").toEpochMilli());
+ }
+}
\ No newline at end of file
diff --git a/opensaml-spring/src/test/java/org/opensaml/spring/trust/StaticPKIXFactoryBeanTest.java b/opensaml-spring/src/test/java/org/opensaml/spring/trust/StaticPKIXFactoryBeanTest.java
new file mode 100644
index 000000000..e8fa28717
--- /dev/null
+++ b/opensaml-spring/src/test/java/org/opensaml/spring/trust/StaticPKIXFactoryBeanTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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 org.opensaml.spring.trust;
+
+import java.util.Set;
+
+import org.opensaml.security.SecurityException;
+import org.opensaml.security.x509.PKIXTrustEvaluator;
+import org.opensaml.security.x509.PKIXValidationInformation;
+import org.opensaml.security.x509.PKIXValidationOptions;
+import org.opensaml.security.x509.X509Credential;
+import org.opensaml.security.x509.impl.BasicX509CredentialNameEvaluator;
+import org.opensaml.security.x509.impl.CertPathPKIXTrustEvaluator;
+import org.opensaml.security.x509.impl.PKIXX509CredentialTrustEngine;
+import org.opensaml.security.x509.impl.StaticPKIXValidationInformationResolver;
+import org.opensaml.security.x509.impl.X509CredentialNameEvaluator;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.context.support.GenericApplicationContext;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.ext.spring.context.FilesystemGenericApplicationContext;
+import net.shibboleth.ext.spring.util.SchemaTypeAwareXMLBeanDefinitionReader;
+import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
+
+/**
+ * Unit test for {@link StaticPKIXFactoryBean}.
+ */
+public class StaticPKIXFactoryBeanTest {
+
+ @Test
+ public void defaults() {
+ final GenericApplicationContext context = new FilesystemGenericApplicationContext();
+ context.setDisplayName("ApplicationContext: X509Credential");
+ final SchemaTypeAwareXMLBeanDefinitionReader beanDefinitionReader =
+ new SchemaTypeAwareXMLBeanDefinitionReader(context);
+
+ beanDefinitionReader.loadBeanDefinitions("org/opensaml/spring/trust/static-pkix-factory-defaults.xml");
+
+ context.refresh();
+
+ final PKIXX509CredentialTrustEngine trustEngine = context.getBean("StaticPKIXX509CredentialTrustEngine",
+ PKIXX509CredentialTrustEngine.class);
+
+ Assert.assertNotNull(trustEngine);
+
+ Assert.assertTrue(StaticPKIXValidationInformationResolver.class.isInstance((trustEngine.getPKIXResolver())));
+
+ Assert.assertTrue(CertPathPKIXTrustEvaluator.class.isInstance((trustEngine.getPKIXTrustEvaluator())));
+
+ Assert.assertTrue(BasicX509CredentialNameEvaluator.class.isInstance((trustEngine.getX509CredentialNameEvaluator())));
+ }
+
+ @Test
+ public void customPropertiesSuccess() {
+ final GenericApplicationContext context = new FilesystemGenericApplicationContext();
+ context.setDisplayName("ApplicationContext: X509Credential");
+ final SchemaTypeAwareXMLBeanDefinitionReader beanDefinitionReader =
+ new SchemaTypeAwareXMLBeanDefinitionReader(context);
+
+ beanDefinitionReader.loadBeanDefinitions("org/opensaml/spring/trust/static-pkix-factory-custom-success.xml");
+
+ context.refresh();
+
+ final PKIXX509CredentialTrustEngine trustEngine = context.getBean("StaticPKIXX509CredentialTrustEngine",
+ PKIXX509CredentialTrustEngine.class);
+
+ Assert.assertNotNull(trustEngine);
+
+ Assert.assertTrue(StaticPKIXValidationInformationResolver.class.isInstance((trustEngine.getPKIXResolver())));
+
+ Assert.assertTrue(MockPKIXTrustEvaluator.class.isInstance((trustEngine.getPKIXTrustEvaluator())));
+
+ Assert.assertTrue(MockX509CredentialNameEvaluator.class.isInstance((trustEngine.getX509CredentialNameEvaluator())));
+ }
+
+ @Test(expectedExceptions=FatalBeanException.class)
+ public void customPropertiesFailsValidation() {
+ final GenericApplicationContext context = new FilesystemGenericApplicationContext();
+ context.setDisplayName("ApplicationContext: X509Credential");
+ final SchemaTypeAwareXMLBeanDefinitionReader beanDefinitionReader =
+ new SchemaTypeAwareXMLBeanDefinitionReader(context);
+
+ beanDefinitionReader.loadBeanDefinitions("org/opensaml/spring/trust/static-pkix-factory-custom-failsValidation.xml");
+
+ context.refresh();
+ }
+
+
+ //
+ // Helpers
+ //
+
+ public static class MockPKIXTrustEvaluator extends AbstractInitializableComponent implements PKIXTrustEvaluator {
+
+ /** {@inheritDoc} */
+ public boolean validate(PKIXValidationInformation validationInfo, X509Credential untrustedCredential)
+ throws SecurityException {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ public PKIXValidationOptions getPKIXValidationOptions() {
+ return null;
+ }
+
+ }
+
+ public static class MockX509CredentialNameEvaluator extends AbstractInitializableComponent implements X509CredentialNameEvaluator {
+
+ /** {@inheritDoc} */
+ public boolean evaluate(X509Credential credential, Set<String> trustedNames) throws SecurityException {
+ return false;
+ }
+
+ }
+}
diff --git a/opensaml-spring/src/test/resources/org/opensaml/spring/credential/bean.xml b/opensaml-spring/src/test/resources/org/opensaml/spring/credential/bean.xml
new file mode 100644
index 000000000..9a2d0d2d2
--- /dev/null
+++ b/opensaml-spring/src/test/resources/org/opensaml/spring/credential/bean.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="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"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <bean id="Credential"
+ class="org.opensaml.spring.credential.BasicX509CredentialFactoryBean"
+ p:privateKeyResource="org/opensaml/spring/credential/idp-signing.key"
+ p:certificateResource="org/opensaml/spring/credential/idp-signing.crt"
+ p:entityId="http://example.org/plain" />
+
+ <bean id="EncCredential"
+ class="org.opensaml.spring.credential.BasicX509CredentialFactoryBean"
+ p:privateKeyResource="org/opensaml/spring/credential/idp-signing.key.pass"
+ p:certificateResource="org/opensaml/spring/credential/idp-signing.crt"
+ p:privateKeyPassword="pass"
+ p:entityId="http://example.org/enc" />
+
+</beans>
\ No newline at end of file
diff --git a/opensaml-spring/src/test/resources/org/opensaml/spring/credential/cert.pem b/opensaml-spring/src/test/resources/org/opensaml/spring/credential/cert.pem
new file mode 100644
index 000000000..c0df65bc9
--- /dev/null
+++ b/opensaml-spring/src/test/resources/org/opensaml/spring/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/opensaml-spring/src/test/resources/org/opensaml/spring/credential/certificate.pem b/opensaml-spring/src/test/resources/org/opensaml/spring/credential/certificate.pem
new file mode 100644
index 000000000..d9e8f8606
--- /dev/null
+++ b/opensaml-spring/src/test/resources/org/opensaml/spring/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/opensaml-spring/src/test/resources/org/opensaml/spring/credential/idp-signing.crt b/opensaml-spring/src/test/resources/org/opensaml/spring/credential/idp-signing.crt
new file mode 100644
index 000000000..c0df65bc9
--- /dev/null
+++ b/opensaml-spring/src/test/resources/org/opensaml/spring/credential/idp-signing.crt
@@ -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/opensaml-spring/src/test/resources/org/opensaml/spring/credential/idp-signing.key b/opensaml-spring/src/test/resources/org/opensaml/spring/credential/idp-signing.key
new file mode 100644
index 000000000..951462f0d
--- /dev/null
+++ b/opensaml-spring/src/test/resources/org/opensaml/spring/credential/idp-signing.key
@@ -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/opensaml-spring/src/test/resources/org/opensaml/spring/credential/idp-signing.key.pass b/opensaml-spring/src/test/resources/org/opensaml/spring/credential/idp-signing.key.pass
new file mode 100644
index 000000000..cde1772f7
--- /dev/null
+++ b/opensaml-spring/src/test/resources/org/opensaml/spring/credential/idp-signing.key.pass
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-256-CBC,167811113CA00D40A7A46A79F0133598
+
+lzqV3Xcehk1mnsq4ZRXqiGZXIhYPWA7KqjqJYEHd10JvJoNUwZ7l6VmyZUtny1Xq
+nPPLjWsZ5rOVQkULOX/ZCmXCAW3YgvoIXmdjcenRlZTlbi7vNqongiNGgRleWRlS
+V/E+KrQXlt0jfV1KdW/PDe712mytL7akWoIE39rI0Z78EhD5YfGsA6J6azLmB5zS
+Ffu+wUfND7/gTR3roVlj8Vs1GWxdyNNLI3yUnK6aRd8zO/eTeTcMullSRpT1ORsI
+qhEMfTIBhG+yqC+NhDv1UJ8r8N6jiD63ciKwrt31SOGamdZNRdgxm1sCOcH/akN4
+w9DStPCx809gw46g/ZAi2V2sa0FguS8Jed/LFGwHG/6FVK/nLONzdFIzNF4gZ+B0
+rIPhrdK2kWpEHbMzPZG2KQack9mDv63HNTAJ8Xu1Sf9oHjJyEpdR7bczS+WeZNjd
+YyM6fR7z9n+UWhqa2+2VtAX5KsnNy5BP1SI2h3rVdpW7+hZO74O31Jj6j0QFe0ks
+e20X3ldx/EPJpJunLv46wLsSEoxfuooFj0bxpPEIjb76q9jOXJHr7M+57pdH6Z17
+lPZQ+nCUvUyfIDZ66EfMYpR6nGpYizhpRlvc5U35sU1ZEtngKwJ1rcwFkYD6THKG
+3Y+UVXd9Ft7EbuI7ArB3MOEsOgrw37IvIT3bAI3pvmdezs6H+j5cfb4F7cIGVXWM
+GB00ahK+qNnL0TaC2+qKuGT4bCxeUYkf8fY21JDnIVpZotjeau5qE32AfjWTjPBJ
+RRTyzVvAS3IjeA/LvsMVailUhZTv0sbgudGh14GKp1HWwLQKs4SXAgGCNCNEOaWu
+vKQT2srL5v0d9SBrVhZBi2u1zIiTREy8JIucX2fNvaDPJ9ZJDqxcEVZUnfaXui0u
+y0cinJ5OJQKM99hK6jVimchdJ+viGc4RRZPatkY/ZSiISJwVtrF/VbsAGN45SI+9
+GbAAD4PKOPDxeQ7qMck/OHQAFi3gUDeRsw//13lHOd3KvsWFQIuOcKJPusdU4jJV
+vBUBVtAJxlESJbjfyN1z6vM8mhm5k63apTuSDmzJfU9hMv7eKV7PIhH48RBNqtWl
+atTukx4eex56Jv54u+kKMVZC8AkrCukYrdho+QVdXJ9J0ZqGW0o9BscE4qBpm16K
+/7EL9IfmqZPK5JyxAJPINYeuBu8RPLhbRDFXCr9hMI1VX24O6S3jJWcQmAU8kOki
+UhnYwOUS98cgecyuLmEnzdvogQXFt81jrfFBNLoQ6v/SS1BIJpkDzTWAz+1qjKpR
+1IFdL8omj9SqVPHelUC5s0LKmhI6NLSC/RGFlSaAJ5FcbPTTdaNKH9dDrfQ+yylN
+bINRkbkWBrsVtMdw42Rba4WTSU7iNFQ8/UdNnHOLmfz4yR4x/g++8YusJys4OfD5
+rxr6Y8bAkhO/ebO1ERGmubZQO4AmdLllNXvgfxjY0M4Mpq6DCMLSFfz5Wc+lpX0E
+5ZRDbOBPZcGjJwJKXDDWPAQ95nbHotg/wNy+MeVXylpPgg+NCncdxqikIb/5gx91
+loYi7X4XgaXf6J4VPZDcaQiQul8YLaOk/BCMLopAGIzT+cDxsOi/zKkAICuuMiIn
+-----END RSA PRIVATE KEY-----
diff --git a/opensaml-spring/src/test/resources/org/opensaml/spring/credential/publicKey.pem b/opensaml-spring/src/test/resources/org/opensaml/spring/credential/publicKey.pem
new file mode 100644
index 000000000..5c4e2e78c
--- /dev/null
+++ b/opensaml-spring/src/test/resources/org/opensaml/spring/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/opensaml-spring/src/test/resources/org/opensaml/spring/trust/static-pkix-factory-custom-failsValidation.xml b/opensaml-spring/src/test/resources/org/opensaml/spring/trust/static-pkix-factory-custom-failsValidation.xml
new file mode 100644
index 000000000..7f0823a8c
--- /dev/null
+++ b/opensaml-spring/src/test/resources/org/opensaml/spring/trust/static-pkix-factory-custom-failsValidation.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="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"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <bean id="StaticPKIXX509CredentialTrustEngine"
+ class="org.opensaml.spring.trust.StaticPKIXFactoryBean">
+ <property name="certificates">
+ <list>
+ <value>org/opensaml/spring/credential/idp-signing.crt</value>
+ </list>
+ </property>
+ <property name="trustEvaluator">
+ <bean class="org.opensaml.security.x509.impl.CertPathPKIXTrustEvaluator" destroy-method="">
+ <property name="PKIXValidationOptions">
+ <bean class="org.opensaml.security.x509.impl.CertPathPKIXValidationOptions"
+ p:forceRevocationEnabled="true"
+ p:revocationEnabled="true"
+ destroy-method="" />
+ </property>
+ </bean>
+ </property>
+ </bean>
+
+</beans>
\ No newline at end of file
diff --git a/opensaml-spring/src/test/resources/org/opensaml/spring/trust/static-pkix-factory-custom-success.xml b/opensaml-spring/src/test/resources/org/opensaml/spring/trust/static-pkix-factory-custom-success.xml
new file mode 100644
index 000000000..22e93f04c
--- /dev/null
+++ b/opensaml-spring/src/test/resources/org/opensaml/spring/trust/static-pkix-factory-custom-success.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="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"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <bean id="StaticPKIXX509CredentialTrustEngine"
+ class="org.opensaml.spring.trust.StaticPKIXFactoryBean">
+ <property name="certificates">
+ <list>
+ <value>org/opensaml/spring/credential/idp-signing.crt</value>
+ </list>
+ </property>
+ <property name="trustEvaluator">
+ <bean class="org.opensaml.spring.trust.StaticPKIXFactoryBeanTest.MockPKIXTrustEvaluator" />
+ </property>
+ <property name="credentialNameEvaluator">
+ <bean class="org.opensaml.spring.trust.StaticPKIXFactoryBeanTest.MockX509CredentialNameEvaluator" />
+ </property>
+ </bean>
+
+</beans>
\ No newline at end of file
diff --git a/opensaml-spring/src/test/resources/org/opensaml/spring/trust/static-pkix-factory-defaults.xml b/opensaml-spring/src/test/resources/org/opensaml/spring/trust/static-pkix-factory-defaults.xml
new file mode 100644
index 000000000..cf186faec
--- /dev/null
+++ b/opensaml-spring/src/test/resources/org/opensaml/spring/trust/static-pkix-factory-defaults.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="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"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <bean id="StaticPKIXX509CredentialTrustEngine"
+ class="org.opensaml.spring.trust.StaticPKIXFactoryBean">
+ <property name="certificates">
+ <list>
+ <value>org/opensaml/spring/credential/idp-signing.crt</value>
+ </list>
+ </property>
+ </bean>
+
+</beans>
\ No newline at end of file
diff --git a/opensaml-spring/src/test/resources/org/opensaml/spring/trust/staticExplicitNative.xml b/opensaml-spring/src/test/resources/org/opensaml/spring/trust/staticExplicitNative.xml
new file mode 100644
index 000000000..655606a74
--- /dev/null
+++ b/opensaml-spring/src/test/resources/org/opensaml/spring/trust/staticExplicitNative.xml
@@ -0,0 +1,28 @@
+<?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:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="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"
+ default-init-method="initialize" default-destroy-method="destroy">
+
+ <bean id="staticKeySingle"
+ class="org.opensaml.spring.trust.StaticExplicitKeyFactoryBean"
+ p:publicKeys="classpath:/org/opensaml/spring/credential/publicKey.pem" />
+
+ <bean id="staticX509Single"
+ class="org.opensaml.spring.trust.StaticExplicitKeyFactoryBean"
+ p:certificates="classpath:/org/opensaml/spring/credential/cert.pem" />
+
+ <bean id="staticX509Multiple"
+ class="org.opensaml.spring.trust.StaticExplicitKeyFactoryBean"
+ p:certificates="classpath:/org/opensaml/spring/credential/certificate.pem" />
+
+ <bean id="staticMixed"
+ class="org.opensaml.spring.trust.StaticExplicitKeyFactoryBean"
+ p:publicKeys="classpath:/org/opensaml/spring/credential/publicKey.pem"
+ p:certificates="classpath:/org/opensaml/spring/credential/cert.pem" />
+
+</beans>
diff --git a/opensaml-storage-api/.classpath b/opensaml-storage-api/.classpath
index 77be441ed..8c2ac107c 100644
--- a/opensaml-storage-api/.classpath
+++ b/opensaml-storage-api/.classpath
@@ -32,6 +32,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-storage-api/.project b/opensaml-storage-api/.project
index f2eb3de06..1188543d3 100644
--- a/opensaml-storage-api/.project
+++ b/opensaml-storage-api/.project
@@ -1,23 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
- <name>opensaml-storage-api</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- </buildCommand>
- <buildCommand>
- <name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.m2e.core.maven2Builder</name>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.jdt.core.javanature</nature>
- <nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
- <nature>org.eclipse.m2e.core.maven2Nature</nature>
- </natures>
-</projectDescription>
\ No newline at end of file
+ <name>opensaml-storage-api</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
+ </natures>
+</projectDescription>
diff --git a/opensaml-storage-api/.settings/org.eclipse.wst.common.component b/opensaml-storage-api/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..79f602947
--- /dev/null
+++ b/opensaml-storage-api/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-storage-api">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-storage-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-storage-api/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-storage-api/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
diff --git a/opensaml-storage-impl/.classpath b/opensaml-storage-impl/.classpath
index 77be441ed..8c2ac107c 100644
--- a/opensaml-storage-impl/.classpath
+++ b/opensaml-storage-impl/.classpath
@@ -32,6 +32,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-storage-impl/.project b/opensaml-storage-impl/.project
index 94ba85ac2..af2293e36 100644
--- a/opensaml-storage-impl/.project
+++ b/opensaml-storage-impl/.project
@@ -5,6 +5,11 @@
<projects>
</projects>
<buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
@@ -25,11 +30,18 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
diff --git a/opensaml-storage-impl/.settings/org.eclipse.wst.common.component b/opensaml-storage-impl/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..1af0866c6
--- /dev/null
+++ b/opensaml-storage-impl/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-storage-impl">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-storage-impl/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-storage-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-storage-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
diff --git a/opensaml-tests-bom/pom.xml b/opensaml-tests-bom/pom.xml
index 2649e3e57..19866bda5 100644
--- a/opensaml-tests-bom/pom.xml
+++ b/opensaml-tests-bom/pom.xml
@@ -95,6 +95,13 @@
<type>test-jar</type>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>opensaml-spring</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>opensaml-storage-api</artifactId>
diff --git a/opensaml-xmlsec-api/.classpath b/opensaml-xmlsec-api/.classpath
index 77be441ed..8c2ac107c 100644
--- a/opensaml-xmlsec-api/.classpath
+++ b/opensaml-xmlsec-api/.classpath
@@ -32,6 +32,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-xmlsec-api/.project b/opensaml-xmlsec-api/.project
index e8b9746ff..fb48bc1ae 100644
--- a/opensaml-xmlsec-api/.project
+++ b/opensaml-xmlsec-api/.project
@@ -5,6 +5,11 @@
<projects>
</projects>
<buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
@@ -20,10 +25,17 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
diff --git a/opensaml-xmlsec-api/.settings/org.eclipse.wst.common.component b/opensaml-xmlsec-api/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..6e7682521
--- /dev/null
+++ b/opensaml-xmlsec-api/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-xmlsec-api">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-xmlsec-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-xmlsec-api/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-xmlsec-api/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
diff --git a/opensaml-xmlsec-impl/.classpath b/opensaml-xmlsec-impl/.classpath
index 77be441ed..8c2ac107c 100644
--- a/opensaml-xmlsec-impl/.classpath
+++ b/opensaml-xmlsec-impl/.classpath
@@ -32,6 +32,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
diff --git a/opensaml-xmlsec-impl/.project b/opensaml-xmlsec-impl/.project
index cd8ef9240..572d9ca39 100644
--- a/opensaml-xmlsec-impl/.project
+++ b/opensaml-xmlsec-impl/.project
@@ -5,6 +5,11 @@
<projects>
</projects>
<buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
@@ -20,10 +25,17 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
diff --git a/opensaml-xmlsec-impl/.settings/org.eclipse.wst.common.component b/opensaml-xmlsec-impl/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..f1178b3dc
--- /dev/null
+++ b/opensaml-xmlsec-impl/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="opensaml-xmlsec-impl">
+ <wb-resource deploy-path="/" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/" source-path="/src/main/resources"/>
+ </wb-module>
+</project-modules>
diff --git a/opensaml-xmlsec-impl/.settings/org.eclipse.wst.common.project.facet.core.xml b/opensaml-xmlsec-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..9ba61b70c
--- /dev/null
+++ b/opensaml-xmlsec-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="17"/>
+ <installed facet="jst.utility" version="1.0"/>
+</faceted-project>
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list