[java-oidfed-common] branch main updated: Do not require trust chains for trust mark validation of locally trusted issuers

Codeberg noreply at shibboleth.net
Tue Sep 15 16:38:01 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/28c17f456a0e13a1b7ac198fec53b9a118c56390

The following commit(s) were added to refs/heads/main by this push:
     new 28c17f4  Do not require trust chains for trust mark validation of locally trusted issuers
28c17f4 is described below

commit 28c17f456a0e13a1b7ac198fec53b9a118c56390
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Tue Sep 15 19:37:12 2026 +0300

    Do not require trust chains for trust mark validation of locally trusted issuers
    
    This enables trust anchors to act as trust mark issuers
---
 .../META-INF/net.shibboleth.idp/postconfig.xml     |  8 ++-
 ...ustMarkValidationCriteriaSetLookupFunction.java | 83 ++++++++++++++++++++--
 2 files changed, 83 insertions(+), 8 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 f9bee42..4000cd5 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
@@ -589,7 +589,9 @@
                             </property>
                             <property name="criteriaSetLookupStrategy">
                                 <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkValidationCriteriaSetLookupFunction"
-                                    p:trustChainCache-ref="shibboleth.oidfed.TrustChainMetadataCache"/>
+                                    p:trustChainCache-ref="shibboleth.oidfed.TrustChainMetadataCache"
+                                    p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"
+                                    p:localTrustAnchorsCache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache"/>
                             </property>
                         </bean>
                         <bean class="net.shibboleth.oidfed.metadata.cache.DefaultEntityStatementContentValidationCondition"
@@ -691,7 +693,9 @@
                             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:trustChainCache-ref="shibboleth.oidfed.TrustChainMetadataCache"
+                                    p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"
+                                    p:localTrustAnchorsCache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache"/>
                             </property>
                         </bean>
                         <bean class="net.shibboleth.oidfed.metadata.cache.DefaultEntityStatementContentValidationCondition"
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 5d2af21..7567bd5 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
@@ -15,6 +15,7 @@
 package net.shibboleth.oidfed.metadata.cache.trustmark;
 
 import java.util.List;
+import java.util.Map;
 import java.util.function.Function;
 
 import javax.annotation.Nonnull;
@@ -25,11 +26,14 @@ 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.BaseExpirableStatementContainer;
 import net.shibboleth.oidfed.metadata.cache.IssuerEntityStatementCriterion;
 import net.shibboleth.oidfed.metadata.cache.SubjectEntityIDCriterion;
 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;
@@ -41,7 +45,7 @@ import net.shibboleth.shared.resolver.CriteriaSet;
 
 /**
  * Default criteria set lookup strategy for {@link BaseExpirableStatementContainer} that fetches the issuer
- * entity statement via trust chain cache.
+ * entity statement via trust chain cache or via entity configuration cache if the entity is locally trusted.
  */
 @ThreadSafeAfterInit
 public class DefaultTrustMarkValidationCriteriaSetLookupFunction
@@ -52,19 +56,44 @@ public class DefaultTrustMarkValidationCriteriaSetLookupFunction
     @Nonnull
     private Logger log = LoggerFactory.getLogger(DefaultTrustMarkValidationCriteriaSetLookupFunction.class);
 
-    /** Cache used to fetch the issuer entity configuration from. */
+    /** Cache used to fetch the issuer entity configuration of non-locally trusted entities. */
     @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 trust chain for the trust mark issuer from.
+     * Set the cache used to fetch the issuer entity configuration of non-locally trusted entities.
      * 
-     * @param cache cache used to fetch the trust chain for the trust mark issuer from
+     * @param cache cache used to fetch the issuer entity configuration of non-locally trusted entities.
      */
     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");
+    }
+
+    /**
+     * Set the cache containing local copies of trusted trust anchor keys.
+     * 
+     * @param cache cache containing local copies of trusted trust anchor keys.
+     */
+    public void setLocalTrustAnchorsCache(@Nonnull final MetadataCache<Map<String, LocalKeyContainer>> cache) {
+        checkSetterPreconditions();
+        localTrustAnchorsCache = Constraint.isNotNull(cache, "Local Trust Anchor cache cannot be null");
+    }
 
     /** {@inheritDoc} */
     @Override
@@ -73,7 +102,12 @@ public class DefaultTrustMarkValidationCriteriaSetLookupFunction
         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");
+        }
     }
 
     /** {@inheritDoc} */
@@ -104,6 +138,19 @@ public class DefaultTrustMarkValidationCriteriaSetLookupFunction
             @Nonnull final BaseJWTWrapper<?> statement) {
         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();
+                    assert issuerStatement != null;
+                    return new IssuerEntityStatementCriterion(issuerStatement);
+                }
+            } 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()) {
@@ -117,8 +164,32 @@ public class DefaultTrustMarkValidationCriteriaSetLookupFunction
         } catch (final MetadataCacheException e) {
             log.debug("Error while fetching issuer trust chain for {}", issuer, e);
         }
-        log.warn("Could not fetch entity configuration for {}", issuer);
+        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;
+    }
+
 }

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


More information about the commits mailing list