[java-oidfed-common] branch main updated: Refactor trust mark fetching and validation

Codeberg noreply at shibboleth.net
Wed Sep 23 17:03:49 UTC 2026


This is an automated email from the git hooks/post-receive script.

codeberg pushed a commit to branch main
in repository java-oidfed-common.

View the commit online:
https://codeberg.org/Shibboleth/java-oidfed-common/commit/1f34880826278f79670cb98f8059825df86cc897

The following commit(s) were added to refs/heads/main by this push:
     new 1f34880  Refactor trust mark fetching and validation
1f34880 is described below

commit 1f34880826278f79670cb98f8059825df86cc897
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Wed Sep 23 20:03:08 2026 +0300

    Refactor trust mark fetching and validation
    
    - Harmonise the trust mark issuer configuration fetching and validation
      - Similar now between trust mark fetching for entity configuration and trust mark resolution for other entities
      - Configurable for the flows
        - idp.oidfed.admin.resolvertest.EntityConfigurationMetadataCache
        - idp.oidfed.admin.resolvertest.LocalTrustAnchorsMetadataCache
        - idp.oidfed.resolveEntity.EntityConfigurationMetadataCache
        - idp.oidfed.resolveEntity.LocalTrustAnchorsMetadataCache
    - Wire properties for requiring trust_mark_issuers from the trust anchor, defaults to shibboleth.Conditions.TRUE
      - idp.oidfed.admin.resolvertest.TrustedTrustMarkIssuersOnlyCondition
      - idp.oidfed.resolveEntity.TrustedTrustMarkIssuersOnlyCondition
---
 .../META-INF/net.shibboleth.idp/postconfig.xml     |  60 ++++----
 .../test-trust-chain-resolution-beans.xml          |  20 ++-
 .../oidfed/resolve-entity/resolve-entity-beans.xml |  20 ++-
 ...stMarkIssuerConfigurationFetchingStrategy.java} |  60 +++-----
 ...ustMarkValidationCriteriaSetLookupFunction.java | 152 +++------------------
 .../oidfed/profile/impl/ResolveTrustMarks.java     |  57 ++++----
 .../oidfed/conf/oidfed/oidfed.properties           |   6 +
 7 files changed, 143 insertions(+), 232 deletions(-)

diff --git a/oidfed-common-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/oidfed-common-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index 42bd010..155c061 100644
--- a/oidfed-common-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/oidfed-common-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -602,19 +602,23 @@
                                  </bean>
                             </property>
                             <property name="criteriaSetLookupStrategy">
-                                <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkValidationCriteriaSetLookupFunction"
-                                    p:trustChainCache-ref="shibboleth.oidfed.TrustChainMetadataCache"
-                                    p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"
-                                    p:localTrustAnchorsCache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache">
-                                    <property name="trustEngine">
-                                        <bean class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
-                                            <constructor-arg index="0">
-                                                <bean class="net.shibboleth.oidfed.security.credential.DefaultLocalTrustAnchorCredentialResolver"
-                                                    c:cache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache" />
-                                            </constructor-arg>
-                                            <constructor-arg index="1">
-                                                <bean class="net.shibboleth.oidfed.security.credential.DefaultPayloadJOSEObjectCredentialResolver" />
-                                            </constructor-arg>
+                                <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkValidationCriteriaSetLookupFunction">
+                                    <property name="trustMarkIssuerConfigurationFetchingStrategy">
+                                        <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkIssuerConfigurationFetchingStrategy"
+                                            p:trustChainCache-ref="shibboleth.oidfed.TrustChainMetadataCache"
+                                            p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"
+                                            p:localTrustAnchorsCache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache">
+                                            <property name="trustEngine">
+                                                <bean class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+                                                    <constructor-arg index="0">
+                                                        <bean class="net.shibboleth.oidfed.security.credential.DefaultLocalTrustAnchorCredentialResolver"
+                                                            c:cache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache" />
+                                                    </constructor-arg>
+                                                    <constructor-arg index="1">
+                                                        <bean class="net.shibboleth.oidfed.security.credential.DefaultPayloadJOSEObjectCredentialResolver" />
+                                                    </constructor-arg>
+                                                </bean>
+                                            </property>
                                         </bean>
                                     </property>
                                 </bean>
@@ -718,19 +722,23 @@
                         <bean class="net.shibboleth.oidfed.metadata.cache.DefaultEntityStatementSignatureValidationCondition"
                             p:trustEngine-ref="shibboleth.oidfed.DefaultSubordinateStatementTrustEngine">
                             <property name="criteriaSetLookupStrategy">
-                                <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkValidationCriteriaSetLookupFunction"
-                                    p:trustChainCache-ref="shibboleth.oidfed.TrustChainMetadataCache"
-                                    p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"
-                                    p:localTrustAnchorsCache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache">
-                                    <property name="trustEngine">
-                                        <bean class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
-                                            <constructor-arg index="0">
-                                                <bean class="net.shibboleth.oidfed.security.credential.DefaultLocalTrustAnchorCredentialResolver"
-                                                    c:cache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache" />
-                                            </constructor-arg>
-                                            <constructor-arg index="1">
-                                                <bean class="net.shibboleth.oidfed.security.credential.DefaultPayloadJOSEObjectCredentialResolver" />
-                                            </constructor-arg>
+                                <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkValidationCriteriaSetLookupFunction">
+                                    <property name="trustMarkIssuerConfigurationFetchingStrategy">
+                                        <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkIssuerConfigurationFetchingStrategy"
+                                            p:trustChainCache-ref="shibboleth.oidfed.TrustChainMetadataCache"
+                                            p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"
+                                            p:localTrustAnchorsCache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache">
+                                            <property name="trustEngine">
+                                                <bean class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+                                                    <constructor-arg index="0">
+                                                        <bean class="net.shibboleth.oidfed.security.credential.DefaultLocalTrustAnchorCredentialResolver"
+                                                            c:cache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache" />
+                                                    </constructor-arg>
+                                                    <constructor-arg index="1">
+                                                        <bean class="net.shibboleth.oidfed.security.credential.DefaultPayloadJOSEObjectCredentialResolver" />
+                                                    </constructor-arg>
+                                                </bean>
+                                            </property>
                                         </bean>
                                     </property>
                                 </bean>
diff --git a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-beans.xml b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-beans.xml
index 18ce67e..c2f0bc5 100644
--- a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-beans.xml
+++ b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-beans.xml
@@ -55,7 +55,7 @@
 
     <bean id="ResolveTrustMarks" class="net.shibboleth.oidfed.profile.impl.ResolveTrustMarks"
         scope="prototype"
-        p:trustChainCache-ref="#{'%{idp.oidfed.admin.resolvertest.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
+        p:trustedTrustMarkIssuersOnlyCondition-ref="#{'%{idp.oidfed.admin.resolvertest.TrustedTrustMarkIssuersOnlyCondition:shibboleth.Conditions.TRUE}'.trim()}"
         p:trustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.TrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
         p:delegatedTrustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.DelegatedTrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultDelegatedTrustMarkClaimsValidationLookupStrategy')}"
         p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"
@@ -70,6 +70,24 @@
         <property name="trustedTrustMarkOwnersLookupStrategy">
             <bean class="net.shibboleth.oidfed.profile.navigate.DefaultTrustChainTrustedTrustMarkOwnersLookupStrategy"/>
         </property>
+        <property name="trustMarkIssuerConfigurationFetchingStrategy">
+            <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkIssuerConfigurationFetchingStrategy"
+                p:trustChainCache-ref="#{'%{idp.oidfed.admin.resolvertest.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
+                p:entityConfigurationCache-ref="#{'%{idp.oidfed.admin.resolvertest.EntityConfigurationMetadataCache:shibboleth.oidfed.EntityConfigurationMetadataCache}'.trim()}"
+                p:localTrustAnchorsCache-ref="#{'%{idp.oidfed.admin.resolvertest.LocalTrustAnchorsMetadataCache:shibboleth.oidfed.LocalTrustAnchorsMetadataCache}'.trim()}">
+                <property name="trustEngine">
+                    <bean class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+                        <constructor-arg index="0">
+                            <bean class="net.shibboleth.oidfed.security.credential.DefaultLocalTrustAnchorCredentialResolver"
+                                c:cache-ref="#{'%{idp.oidfed.admin.resolvertest.LocalTrustAnchorsMetadataCache:shibboleth.oidfed.LocalTrustAnchorsMetadataCache}'.trim()}" />
+                        </constructor-arg>
+                        <constructor-arg index="1">
+                            <bean class="net.shibboleth.oidfed.security.credential.DefaultPayloadJOSEObjectCredentialResolver" />
+                        </constructor-arg>
+                    </bean>
+                </property>
+            </bean>
+        </property>
     </bean>
 
     <bean id="ValidateTrustMarks" class="net.shibboleth.oidfed.profile.impl.ValidateTrustMarks"
diff --git a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml
index 5c34d90..8ed1b1a 100644
--- a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml
+++ b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml
@@ -174,7 +174,7 @@
 
     <bean id="ResolveTrustMarks" class="net.shibboleth.oidfed.profile.impl.ResolveTrustMarks"
         scope="prototype"
-        p:trustChainCache-ref="#{'%{idp.oidfed.resolveEntity.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
+        p:trustedTrustMarkIssuersOnlyCondition-ref="#{'%{idp.oidfed.resolveEntity.TrustedTrustMarkIssuersOnlyCondition:shibboleth.Conditions.TRUE}'.trim()}"
         p:trustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.TrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
         p:delegatedTrustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.DelegatedTrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultDelegatedTrustMarkClaimsValidationLookupStrategy')}"
         p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"
@@ -189,6 +189,24 @@
         <property name="trustedTrustMarkOwnersLookupStrategy">
             <bean class="net.shibboleth.oidfed.profile.navigate.DefaultTrustChainTrustedTrustMarkOwnersLookupStrategy"/>
         </property>
+        <property name="trustMarkIssuerConfigurationFetchingStrategy">
+            <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkIssuerConfigurationFetchingStrategy"
+                p:trustChainCache-ref="#{'%{idp.oidfed.resolveEntity.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
+                p:entityConfigurationCache-ref="#{'%{idp.oidfed.resolveEntity.EntityConfigurationMetadataCache:shibboleth.oidfed.EntityConfigurationMetadataCache}'.trim()}"
+                p:localTrustAnchorsCache-ref="#{'%{idp.oidfed.resolveEntity.LocalTrustAnchorsMetadataCache:shibboleth.oidfed.LocalTrustAnchorsMetadataCache}'.trim()}">
+                <property name="trustEngine">
+                    <bean class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+                        <constructor-arg index="0">
+                            <bean class="net.shibboleth.oidfed.security.credential.DefaultLocalTrustAnchorCredentialResolver"
+                                c:cache-ref="#{'%{idp.oidfed.resolveEntity.LocalTrustAnchorsMetadataCache:shibboleth.oidfed.LocalTrustAnchorsMetadataCache}'.trim()}" />
+                        </constructor-arg>
+                        <constructor-arg index="1">
+                            <bean class="net.shibboleth.oidfed.security.credential.DefaultPayloadJOSEObjectCredentialResolver" />
+                        </constructor-arg>
+                    </bean>
+                </property>
+            </bean>
+        </property>
     </bean>
 
     <bean id="ValidateTrustMarks" class="net.shibboleth.oidfed.profile.impl.ValidateTrustMarks"
diff --git a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkValidationCriteriaSetLookupFunction.java b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkIssuerConfigurationFetchingStrategy.java
similarity index 71%
copy from oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkValidationCriteriaSetLookupFunction.java
copy to oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkIssuerConfigurationFetchingStrategy.java
index 1058e04..6ba1fbd 100644
--- a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkValidationCriteriaSetLookupFunction.java
+++ b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkIssuerConfigurationFetchingStrategy.java
@@ -29,11 +29,8 @@ import net.shibboleth.oidfed.metadata.BaseJWTWrapper;
 import net.shibboleth.oidfed.metadata.EntityConfiguration;
 import net.shibboleth.oidfed.metadata.EntityStatement;
 import net.shibboleth.oidfed.metadata.cache.AbstractTrustEngineSignatureValidationComponent;
-import net.shibboleth.oidfed.metadata.cache.BaseExpirableStatementContainer;
-import net.shibboleth.oidfed.metadata.cache.IssuerEntityStatementCriterion;
 import net.shibboleth.oidfed.metadata.cache.SubjectEntityIDCriterion;
 import net.shibboleth.oidfed.metadata.cache.SubjectEntityStatementCriterion;
-import net.shibboleth.oidfed.metadata.cache.SubjectStatementCriterion;
 import net.shibboleth.oidfed.metadata.cache.configuration.EntityConfigurationContainer;
 import net.shibboleth.oidfed.metadata.cache.local.LocalKeyContainer;
 import net.shibboleth.oidfed.metadata.cache.trustchain.TrustChainsContainer;
@@ -45,23 +42,23 @@ import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
 /**
- * Default criteria set lookup strategy for {@link BaseExpirableStatementContainer} that fetches the issuer
- * entity statement via trust chain cache or via entity configuration cache if the entity is locally trusted. In that
- * case the entity configuration is verified against the local trust anchor cache.
+ * Default fetching strategy for trust marks that fetches the issuer entity configuration via trust chain cache or via
+ * entity configuration cache if the entity is locally trusted. In that case the entity configuration is verified
+ * against the local trust anchor cache using the configurable trust engine.
  */
 @ThreadSafeAfterInit
-public class DefaultTrustMarkValidationCriteriaSetLookupFunction
+public class DefaultTrustMarkIssuerConfigurationFetchingStrategy
     extends AbstractTrustEngineSignatureValidationComponent
-    implements Function<BaseExpirableStatementContainer<?>, CriteriaSet> {
+    implements Function<BaseJWTWrapper<?>, EntityConfiguration> {
 
     /** Class logger. */
     @Nonnull
-    private Logger log = LoggerFactory.getLogger(DefaultTrustMarkValidationCriteriaSetLookupFunction.class);
+    private Logger log = LoggerFactory.getLogger(DefaultTrustMarkIssuerConfigurationFetchingStrategy.class);
 
     /** Cache used to fetch the issuer entity configuration of entities that are not locally trusted. */
     @NonnullAfterInit private MetadataCache<TrustChainsContainer> trustChainCache;
 
-    /** Cache used to fetch the isser entity configuration of locally trusted entities. */
+    /** Cache used to fetch the issuer entity configuration of locally trusted entities. */
     @NonnullAfterInit private MetadataCache<EntityConfigurationContainer> entityConfigurationCache;
 
     /** Cache containing local copies of trusted trust anchor keys. */
@@ -78,9 +75,9 @@ public class DefaultTrustMarkValidationCriteriaSetLookupFunction
     }
 
     /**
-     * Set the cache used to fetch the isser entity configuration of locally trusted entities.
+     * Set the cache used to fetch the issuer entity configuration of locally trusted entities.
      * 
-     * @param cache cache used to fetch the isser entity configuration of locally trusted entities
+     * @param cache cache used to fetch the issuer entity configuration of locally trusted entities
      */
     public void setEntityConfigurationCache(@Nonnull final MetadataCache<EntityConfigurationContainer> cache) {
         checkSetterPreconditions();
@@ -114,33 +111,13 @@ public class DefaultTrustMarkValidationCriteriaSetLookupFunction
 
     /** {@inheritDoc} */
     @Override @Nullable
-    public CriteriaSet apply(@Nullable final BaseExpirableStatementContainer<?> metadataContainer) {
-        if (metadataContainer != null && metadataContainer.getStatement() != null) {
-            final BaseJWTWrapper<?> statement = metadataContainer.getStatement();
-            assert statement != null;
-            final SubjectStatementCriterion subjectCriterion = new SubjectStatementCriterion(statement);
-            final IssuerEntityStatementCriterion issuerCriterion = getIssuerCriterion(statement, metadataContainer);
-            if (issuerCriterion == null) {
-                log.debug("Issuer statement could not be fetched, returning null");
-                return null;
-            }
-            return new CriteriaSet(subjectCriterion, issuerCriterion);
+    public EntityConfiguration apply(@Nullable final BaseJWTWrapper<?> wrapper) {
+        checkComponentActive();
+        if (wrapper == null) {
+            return null;
         }
-        log.debug("Entity statement is not found from the container, returning null");
-        return null;
-    }
 
-    /**
-     * Fetch the issuer entity configuration from the metadata cache and initialize the criterion.
-     * 
-     * @param statement the entity statement whose issuer is fetched
-     * @param metadataContainer the metadata container containing the statement
-     * @return the issuer entity configuration, or null if could not be fetched
-     */
-    @Nullable protected IssuerEntityStatementCriterion getIssuerCriterion(
-            @Nonnull final BaseJWTWrapper<?> statement,
-            @Nonnull final BaseExpirableStatementContainer<?> metadataContainer) {
-        final String issuer = statement.getIssuer();
+        final String issuer = wrapper.getIssuer();
         final CriteriaSet criteria = new CriteriaSet(new SubjectEntityIDCriterion(issuer));
         if (isLocallyTrusted(issuer)) {
             try {
@@ -150,8 +127,8 @@ public class DefaultTrustMarkValidationCriteriaSetLookupFunction
                     if (issuerStatement != null) {
                         final var anchorCriteria = new CriteriaSet(
                                 new SubjectEntityStatementCriterion(issuerStatement));
-                        if (validateJwt(statement.getJwt(), anchorCriteria, metadataContainer.getEntityId())) {
-                            return new IssuerEntityStatementCriterion(issuerStatement);
+                        if (validateJwt(wrapper.getJwt(), anchorCriteria, issuer)) {
+                            return issuerStatement;
                         }
                         log.warn("Could not validate the issuer entity configuration against trust engine");
                         return null;
@@ -168,8 +145,9 @@ public class DefaultTrustMarkValidationCriteriaSetLookupFunction
                 final List<List<EntityStatement<?>>> chains = result.get(0).getTrustChains();
                 if (!chains.isEmpty()) {
                     final EntityStatement<?> issuerStatement = chains.get(0).get(0);
-                    assert issuerStatement != null;
-                    return new IssuerEntityStatementCriterion(issuerStatement);
+                    if (issuerStatement instanceof EntityConfiguration configuration) {
+                        return configuration;
+                    }
                 }
             }
         } catch (final MetadataCacheException e) {
diff --git a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkValidationCriteriaSetLookupFunction.java b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkValidationCriteriaSetLookupFunction.java
index 1058e04..7c19094 100644
--- a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkValidationCriteriaSetLookupFunction.java
+++ b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkValidationCriteriaSetLookupFunction.java
@@ -14,8 +14,6 @@
 
 package net.shibboleth.oidfed.metadata.cache.trustmark;
 
-import java.util.List;
-import java.util.Map;
 import java.util.function.Function;
 
 import javax.annotation.Nonnull;
@@ -23,22 +21,14 @@ import javax.annotation.Nullable;
 
 import org.slf4j.Logger;
 
-import net.shibboleth.oidc.metadata.cache.MetadataCache;
-import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
 import net.shibboleth.oidfed.metadata.BaseJWTWrapper;
 import net.shibboleth.oidfed.metadata.EntityConfiguration;
-import net.shibboleth.oidfed.metadata.EntityStatement;
-import net.shibboleth.oidfed.metadata.cache.AbstractTrustEngineSignatureValidationComponent;
 import net.shibboleth.oidfed.metadata.cache.BaseExpirableStatementContainer;
 import net.shibboleth.oidfed.metadata.cache.IssuerEntityStatementCriterion;
-import net.shibboleth.oidfed.metadata.cache.SubjectEntityIDCriterion;
-import net.shibboleth.oidfed.metadata.cache.SubjectEntityStatementCriterion;
 import net.shibboleth.oidfed.metadata.cache.SubjectStatementCriterion;
-import net.shibboleth.oidfed.metadata.cache.configuration.EntityConfigurationContainer;
-import net.shibboleth.oidfed.metadata.cache.local.LocalKeyContainer;
-import net.shibboleth.oidfed.metadata.cache.trustchain.TrustChainsContainer;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
@@ -46,69 +36,41 @@ import net.shibboleth.shared.resolver.CriteriaSet;
 
 /**
  * Default criteria set lookup strategy for {@link BaseExpirableStatementContainer} that fetches the issuer
- * entity statement via trust chain cache or via entity configuration cache if the entity is locally trusted. In that
- * case the entity configuration is verified against the local trust anchor cache.
+ * entity configuration via configurable fetching strategy.
  */
 @ThreadSafeAfterInit
 public class DefaultTrustMarkValidationCriteriaSetLookupFunction
-    extends AbstractTrustEngineSignatureValidationComponent
+    extends AbstractIdentifiableInitializableComponent
     implements Function<BaseExpirableStatementContainer<?>, CriteriaSet> {
 
     /** Class logger. */
     @Nonnull
     private Logger log = LoggerFactory.getLogger(DefaultTrustMarkValidationCriteriaSetLookupFunction.class);
 
-    /** Cache used to fetch the issuer entity configuration of entities that are not locally trusted. */
-    @NonnullAfterInit private MetadataCache<TrustChainsContainer> trustChainCache;
-
-    /** Cache used to fetch the isser entity configuration of locally trusted entities. */
-    @NonnullAfterInit private MetadataCache<EntityConfigurationContainer> entityConfigurationCache;
-
-    /** Cache containing local copies of trusted trust anchor keys. */
-    @NonnullAfterInit private MetadataCache<Map<String, LocalKeyContainer>> localTrustAnchorsCache;
-
-    /**
-     * Set the cache used to fetch the issuer entity configuration of entities that are not locally trusted.
-     * 
-     * @param cache cache used to fetch the issuer entity configuration of entities that are not locally trusted
-     */
-    public void setTrustChainCache(@Nonnull final MetadataCache<TrustChainsContainer> cache) {
-        checkSetterPreconditions();
-        trustChainCache = Constraint.isNotNull(cache, "Trust Chain cache cannot be null");
-    }
-
-    /**
-     * Set the cache used to fetch the isser entity configuration of locally trusted entities.
-     * 
-     * @param cache cache used to fetch the isser entity configuration of locally trusted entities
-     */
-    public void setEntityConfigurationCache(@Nonnull final MetadataCache<EntityConfigurationContainer> cache) {
-        checkSetterPreconditions();
-        entityConfigurationCache = Constraint.isNotNull(cache, "Entity Configuration cache cannot be null");
-    }
+    /** Strategy used to fetch trust mark issuer entity configuration. */
+    @NonnullAfterInit
+    private Function<BaseJWTWrapper<?>, EntityConfiguration> trustMarkIssuerConfigurationFetchingStrategy;
 
     /**
-     * Set the cache containing local copies of trusted trust anchor keys.
+     * Set the strategy used to fetch the trust mark issuer entity configuration
      * 
-     * @param cache cache containing local copies of trusted trust anchor keys.
+     * @param strategy fetching strategy
      */
-    public void setLocalTrustAnchorsCache(@Nonnull final MetadataCache<Map<String, LocalKeyContainer>> cache) {
+    public void setTrustMarkIssuerConfigurationFetchingStrategy(
+            @Nonnull final Function<BaseJWTWrapper<?>, EntityConfiguration> strategy) {
         checkSetterPreconditions();
-        localTrustAnchorsCache = Constraint.isNotNull(cache, "Local Trust Anchor cache cannot be null");
+        trustMarkIssuerConfigurationFetchingStrategy = Constraint.isNotNull(strategy,
+                "TrustMarkIssuerConfigurationFetchingStrategy cannot be null");
     }
 
     /** {@inheritDoc} */
     @Override
     protected void doInitialize() throws ComponentInitializationException {
         super.doInitialize();
-        if (trustChainCache == null) {
-            throw new ComponentInitializationException("Trust Chain cache cannot be null");
-        }
-        if (entityConfigurationCache == null) {
-            throw new ComponentInitializationException("Entity configuration cache cannot be null");
-        }
-        if (localTrustAnchorsCache == null) {
-            throw new ComponentInitializationException("Local Trust Anchor cache cannot be null");
+        
+        if (trustMarkIssuerConfigurationFetchingStrategy == null) {
+            throw new ComponentInitializationException(
+                    "TrustMarkIssuerConfigurationFetchingStrategy cannot be null");
         }
     }
 
@@ -119,88 +81,16 @@ public class DefaultTrustMarkValidationCriteriaSetLookupFunction
             final BaseJWTWrapper<?> statement = metadataContainer.getStatement();
             assert statement != null;
             final SubjectStatementCriterion subjectCriterion = new SubjectStatementCriterion(statement);
-            final IssuerEntityStatementCriterion issuerCriterion = getIssuerCriterion(statement, metadataContainer);
-            if (issuerCriterion == null) {
+
+            final EntityConfiguration issuerConfiguration =
+                    trustMarkIssuerConfigurationFetchingStrategy.apply(statement);
+            if (issuerConfiguration == null) {
                 log.debug("Issuer statement could not be fetched, returning null");
                 return null;
             }
-            return new CriteriaSet(subjectCriterion, issuerCriterion);
+            return new CriteriaSet(subjectCriterion, new IssuerEntityStatementCriterion(issuerConfiguration));
         }
         log.debug("Entity statement is not found from the container, returning null");
         return null;
     }
-
-    /**
-     * Fetch the issuer entity configuration from the metadata cache and initialize the criterion.
-     * 
-     * @param statement the entity statement whose issuer is fetched
-     * @param metadataContainer the metadata container containing the statement
-     * @return the issuer entity configuration, or null if could not be fetched
-     */
-    @Nullable protected IssuerEntityStatementCriterion getIssuerCriterion(
-            @Nonnull final BaseJWTWrapper<?> statement,
-            @Nonnull final BaseExpirableStatementContainer<?> metadataContainer) {
-        final String issuer = statement.getIssuer();
-        final CriteriaSet criteria = new CriteriaSet(new SubjectEntityIDCriterion(issuer));
-        if (isLocallyTrusted(issuer)) {
-            try {
-                final List<EntityConfigurationContainer> result = entityConfigurationCache.get(criteria);
-                if (!result.isEmpty()) {
-                    final EntityConfiguration issuerStatement = result.get(0).getStatement();
-                    if (issuerStatement != null) {
-                        final var anchorCriteria = new CriteriaSet(
-                                new SubjectEntityStatementCriterion(issuerStatement));
-                        if (validateJwt(statement.getJwt(), anchorCriteria, metadataContainer.getEntityId())) {
-                            return new IssuerEntityStatementCriterion(issuerStatement);
-                        }
-                        log.warn("Could not validate the issuer entity configuration against trust engine");
-                        return null;
-                    }
-                }
-            } catch (final MetadataCacheException e) {
-                log.debug("Error while fetching issuer entity configuration for {}", issuer, e);
-            }
-            log.warn("Could not fetch entity configuration via entity configuration cache for {}", issuer);
-        }
-        try {
-            final List<TrustChainsContainer> result = trustChainCache.get(criteria);
-            if (!result.isEmpty()) {
-                final List<List<EntityStatement<?>>> chains = result.get(0).getTrustChains();
-                if (!chains.isEmpty()) {
-                    final EntityStatement<?> issuerStatement = chains.get(0).get(0);
-                    assert issuerStatement != null;
-                    return new IssuerEntityStatementCriterion(issuerStatement);
-                }
-            }
-        } catch (final MetadataCacheException e) {
-            log.debug("Error while fetching issuer trust chain for {}", issuer, e);
-        }
-        log.warn("Could not fetch entity configuration via trust chain cache for {}", issuer);
-        return null;
-
-    }
-
-    /**
-     * Checks whether the given entity is locally trusted via local trust anchors cache.
-     * 
-     * @param entity entity ID to be verified
-     * @return true if the entity is locally trusted, false otherwise
-     */
-    private boolean isLocallyTrusted(@Nonnull final String entity) {
-        final CriteriaSet criteria = new CriteriaSet(new SubjectEntityIDCriterion(entity));
-        final List<Map<String, LocalKeyContainer>> keyContainers;
-        try {
-            keyContainers = localTrustAnchorsCache.get(criteria);
-        } catch (final MetadataCacheException e) {
-            log.debug("Could not resolve local trust anchor keys from the cache for {}", entity, e);
-            return false;
-        }
-        if (keyContainers.isEmpty() || !keyContainers.get(0).containsKey(entity)) {
-            log.trace("No locally trusted keys found for {}", entity);
-            return false;
-        }
-        log.trace("Locally trusted keys configured for {}", entity);
-        return true;
-    }
-
 }
diff --git a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/ResolveTrustMarks.java b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/ResolveTrustMarks.java
index f082794..9c5e38d 100644
--- a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/ResolveTrustMarks.java
+++ b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/ResolveTrustMarks.java
@@ -42,14 +42,13 @@ import com.nimbusds.jwt.SignedJWT;
 import net.shibboleth.idp.profile.AbstractProfileAction;
 import net.shibboleth.oidc.jwt.claims.ClaimsValidator;
 import net.shibboleth.oidc.jwt.claims.JWTValidationException;
-import net.shibboleth.oidc.metadata.cache.MetadataCache;
-import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.oidfed.metadata.BaseJWTWrapper;
+import net.shibboleth.oidfed.metadata.EntityConfiguration;
 import net.shibboleth.oidfed.metadata.EntityStatement;
 import net.shibboleth.oidfed.metadata.TrustMark;
 import net.shibboleth.oidfed.metadata.cache.SubjectEntityIDCriterion;
 import net.shibboleth.oidfed.metadata.cache.SubjectEntityStatementCriterion;
 import net.shibboleth.oidfed.metadata.cache.TrustMarkOwnersCriterion;
-import net.shibboleth.oidfed.metadata.cache.trustchain.TrustChainsContainer;
 import net.shibboleth.oidfed.metadata.payload.TrustMarkPayload;
 import net.shibboleth.oidfed.metadata.payload.claim.TrustMarkOwner;
 import net.shibboleth.oidfed.profile.context.RelyingPartyTrustChainContext;
@@ -80,6 +79,10 @@ public class ResolveTrustMarks extends AbstractProfileAction {
     /** Strategy used to lookup the trust chain context. */
     @Nonnull private Function<ProfileRequestContext, RelyingPartyTrustChainContext> trustChainContextLookupStrategy;
 
+    /** Strategy used to fetch trust mark issuer entity configuration. */
+    @NonnullAfterInit
+    private Function<BaseJWTWrapper<?>, EntityConfiguration> trustMarkIssuerConfigurationFetchingStrategy;
+
     /** Strategy used to parse trust marks from the selected trust chain. */
     @NonnullAfterInit
     private Function<List<EntityStatement<?>>,Map<String,List<TrustMark>>> trustChainTrustMarksParsingStrategy;
@@ -95,9 +98,6 @@ public class ResolveTrustMarks extends AbstractProfileAction {
     /** Condition to solely take trusted trust mark issuers into account. */
     @Nonnull private Predicate<ProfileRequestContext> trustedTrustMarkIssuersOnlyCondition;
 
-    /** Metadata cache for trust chains (for trust mark issuers). */
-    @NonnullAfterInit private MetadataCache<TrustChainsContainer> trustChainCache;
-
     /** Trust engine used to validate a trust mark signature. */
     @NonnullAfterInit private TrustEngine<SignedJWT> trustEngine;
 
@@ -195,13 +195,15 @@ public class ResolveTrustMarks extends AbstractProfileAction {
     }
 
     /**
-     * Set the metadata cache for trust chains.
+     * Set the strategy used to fetch the trust mark issuer entity configuration
      * 
-     * @param cache metadata cache
+     * @param strategy fetching strategy
      */
-    public void setTrustChainCache(@Nonnull final MetadataCache<TrustChainsContainer> cache) {
+    public void setTrustMarkIssuerConfigurationFetchingStrategy(
+            @Nonnull final Function<BaseJWTWrapper<?>, EntityConfiguration> strategy) {
         checkSetterPreconditions();
-        trustChainCache = Constraint.isNotNull(cache, "TrustChainCache cannot be null");
+        trustMarkIssuerConfigurationFetchingStrategy = Constraint.isNotNull(strategy,
+                "TrustMarkIssuerConfigurationFetchingStrategy cannot be null");
     }
 
     /**
@@ -253,8 +255,9 @@ public class ResolveTrustMarks extends AbstractProfileAction {
     protected void doInitialize() throws ComponentInitializationException {
         super.doInitialize();
         
-        if (trustChainCache == null) {
-            throw new ComponentInitializationException("TrustChainCache cannot be null");
+        if (trustMarkIssuerConfigurationFetchingStrategy == null) {
+            throw new ComponentInitializationException(
+                    "TrustMarkIssuerConfigurationFetchingStrategy cannot be null");
         }
         if (trustEngine == null) {
             throw new ComponentInitializationException("Trust Engine cannot be null");
@@ -366,8 +369,7 @@ public class ResolveTrustMarks extends AbstractProfileAction {
             verifiedTrustMarks.put(
                     statement.getSubject(),
                     trustMarks.stream()
-                        .filter(entry -> onlyTrustedIssuers ?
-                                checkTrustedIssuer(entry, trustedIssuers, trustedOwners) : true)
+                        .filter(entry -> checkTrustedIssuer(entry, trustedIssuers, trustedOwners, onlyTrustedIssuers))
                         .filter(entry -> verifyTrustMark(entry, trustedOwners, profileRequestContext,
                                 trustChainContext.getVerifiedTrustMarkIssuers()))
                         .filter(Objects::nonNull)
@@ -412,11 +414,12 @@ public class ResolveTrustMarks extends AbstractProfileAction {
      * @param trustMark the trust mark to be verified
      * @param trustedIssuers the trusted trust mark issuers
      * @param trustedOwners the trusted trust mark owners
+     * @param onlyTrustedIssuers if only trusted issuers should be taken into account
      * @return true if the trust mark meets configuration, false otherwise
      */
     protected boolean checkTrustedIssuer(@Nullable final TrustMark trustMark,
             @Nonnull final Map<String, List<String>> trustedIssuers,
-            @Nonnull final Map<String, TrustMarkOwner> trustedOwners) {
+            @Nonnull final Map<String, TrustMarkOwner> trustedOwners, final boolean onlyTrustedIssuers) {
         if (trustMark == null) {
             return false;
         }
@@ -427,19 +430,20 @@ public class ResolveTrustMarks extends AbstractProfileAction {
         if (trustedIssuers.containsKey(id)) {
             final String issuer = trustMark.getIssuer();
             final List<String> validIssuers = trustedIssuers.get(id);
-            if (validIssuers == null || !validIssuers.contains(issuer)) {
+            if (validIssuers == null || (!validIssuers.isEmpty() && !validIssuers.contains(issuer))) {
                 log.debug("{} Issuer {} is not valid trust mark issuer", getLogPrefix(), issuer);
                 return false;
             }
         } else if (trustedOwners.containsKey(id)) {
             log.debug("{} Trust mark ID {} is included in trusted owners", getLogPrefix(), id);
             if (trustMark.getParsedPayload().getDelegation() == null) {
-                log.debug("(} Trust mark ID {} does not contain a delegation claim", getLogPrefix(), id);
+                log.debug("{} Trust mark ID {} does not contain a delegation claim", getLogPrefix(), id);
                 return false;
             }
         } else {
-            log.debug("{} Trust mark ID {} is not included in the trusted issuers", getLogPrefix(), id);
-            return false;
+            log.debug("{} Trust mark ID {} is not included in the trusted issuers, accepting {}", getLogPrefix(), id,
+                    !onlyTrustedIssuers);
+            return !onlyTrustedIssuers;
         }
         return true;
     }
@@ -463,21 +467,10 @@ public class ResolveTrustMarks extends AbstractProfileAction {
         }
         final String issuer = trustMark.getIssuer();
         assert issuer != null;
-        log.debug("{} Resolving trust chain for {}", getLogPrefix(), issuer);
-        final List<TrustChainsContainer> cacheResult;
-        try {
-            cacheResult = trustChainCache.get(new CriteriaSet(new SubjectEntityIDCriterion(issuer)));
-        } catch (final MetadataCacheException e) {
-            log.warn("{} Exception while fetching trust chains for {}", getLogPrefix(), issuer, e);
-            return false;
-        }
-        if (cacheResult.isEmpty() || cacheResult.get(0).getTrustChains().isEmpty()) {
-            log.warn("{} No trust chains resolved for {}", getLogPrefix(), issuer);
+        final EntityStatement<?> trustMarkIssuer = trustMarkIssuerConfigurationFetchingStrategy.apply(trustMark);
+        if (trustMarkIssuer == null) {
             return false;
         }
-        final List<EntityStatement<?>> trustMarkChain = cacheResult.get(0).getTrustChains().get(0);
-        final EntityStatement<?> trustMarkIssuer = trustMarkChain.get(0);
-        assert trustMarkIssuer != null;
         final CriteriaSet criteria = new CriteriaSet(new SubjectEntityStatementCriterion(trustMarkIssuer));
         trustedTrustMarkIssuers.put(trustMarkIssuer.getSubject(), trustMarkIssuer);
         log.trace("{} Validating entity statement {}", getLogPrefix(), trustMarkIssuer.getJwt().serialize());
diff --git a/oidfed-common-impl/src/main/resources/net/shibboleth/oidfed/conf/oidfed/oidfed.properties b/oidfed-common-impl/src/main/resources/net/shibboleth/oidfed/conf/oidfed/oidfed.properties
index c2e1c91..e5d1fec 100644
--- a/oidfed-common-impl/src/main/resources/net/shibboleth/oidfed/conf/oidfed/oidfed.properties
+++ b/oidfed-common-impl/src/main/resources/net/shibboleth/oidfed/conf/oidfed/oidfed.properties
@@ -129,7 +129,10 @@ idp.oidfed.entityConfiguration.authorityHints = https://your.authority.example.o
 #idp.oidfed.admin.resolvertest.postAuthenticationFlows
 #idp.oidfed.admin.resolvertest.defaultAuthenticationMethods
 #idp.oidfed.admin.resolvertest.TrustChainMetadataCache = shibboleth.oidfed.TrustChainMetadataCache
+#idp.oidfed.admin.resolvertest.EntityConfigurationMetadataCache = shibboleth.oidfed.EntityConfigurationMetadataCache
+#idp.oidfed.admin.resolvertest.LocalTrustAnchorsMetadataCache = shibboleth.oidfed.LocalTrustAnchorsMetadataCache
 #idp.oidfed.admin.resolvertest.TrustMarkStatusMetadataCache = shibboleth.oidfed.TrustMarkStatusMetadataCache
+#idp.oidfed.admin.resolvertest.TrustedTrustMarkIssuersOnlyCondition = shibboleth.Conditions.TRUE
 
 # resolve-entity-beans
 #idp.oidfed.resolveEntity.authn.flows = OAuth2Client
@@ -141,6 +144,8 @@ idp.oidfed.entityConfiguration.authorityHints = https://your.authority.example.o
 #idp.oidfed.resolveEntity.MetadataPolicyMergingStrategy = MetadataPolicyMergingStrategy
 #idp.oidfed.resolveEntity.LocalMetadataPolicyStrategy = DefaultLocalMetadataPolicyStrategy
 #idp.oidfed.resolveEntity.TrustChainMetadataCache = shibboleth.oidfed.TrustChainMetadataCache
+#idp.oidfed.resolveEntity.EntityConfigurationMetadataCache = shibboleth.oidfed.EntityConfigurationMetadataCache
+#idp.oidfed.resolveEntity.LocalTrustAnchorsMetadataCache = shibboleth.oidfed.LocalTrustAnchorsMetadataCache
 #idp.oidfed.resolveEntity.TrustMarkStatusMetadataCache = shibboleth.oidfed.TrustMarkStatusMetadataCache
 #idp.oidfed.resolveEntity.sigalg = RS256
 #idp.oidfed.resolveEntity.endpointAuthMethods = private_key_jwt
@@ -148,3 +153,4 @@ idp.oidfed.entityConfiguration.authorityHints = https://your.authority.example.o
 #idp.oidfed.resolveEntity.requireSingleJWTAudience = true
 #idp.oidfed.resolveEntity.trustchain.resolver.useResolverApiCondition = shibboleth.Conditions.FALSE
 #idp.oidfed.resolveEntity.trustchain.resolver.fallbackToLocalCondition = shibboleth.Conditions.TRUE
+#idp.oidfed.resolveEntity.TrustedTrustMarkIssuersOnlyCondition = shibboleth.Conditions.TRUE

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list