[java-oidfed-common] 02/03: Refactor trust mark SignedJWT references into exploiting our TrustMark interface

Codeberg noreply at shibboleth.net
Thu Jun 4 14:13:07 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/a792328928ad88cd943d8c5496d7bac1d54a305a

commit a792328928ad88cd943d8c5496d7bac1d54a305a
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Thu Jun 4 17:09:49 2026 +0300

    Refactor trust mark SignedJWT references into exploiting our TrustMark interface
---
 .../context/RelyingPartyTrustChainContext.java     |   9 +-
 .../oidfed/profile/impl/CallResolveEntityApi.java  |  35 ++++----
 .../oidfed/profile/impl/ResolveTrustMarks.java     | 100 ++++++++-------------
 .../oidfed/profile/impl/ValidateTrustMarks.java    |  15 ++--
 ...DefaultTrustChainTrustMarksParsingStrategy.java |  61 ++++++++++---
 5 files changed, 111 insertions(+), 109 deletions(-)

diff --git a/oidfed-common-api/src/main/java/net/shibboleth/oidfed/profile/context/RelyingPartyTrustChainContext.java b/oidfed-common-api/src/main/java/net/shibboleth/oidfed/profile/context/RelyingPartyTrustChainContext.java
index 5329012..f96b529 100644
--- a/oidfed-common-api/src/main/java/net/shibboleth/oidfed/profile/context/RelyingPartyTrustChainContext.java
+++ b/oidfed-common-api/src/main/java/net/shibboleth/oidfed/profile/context/RelyingPartyTrustChainContext.java
@@ -24,9 +24,8 @@ import javax.annotation.Nullable;
 
 import org.opensaml.messaging.context.BaseContext;
 
-import com.nimbusds.jwt.SignedJWT;
-
 import net.shibboleth.oidfed.metadata.EntityStatement;
+import net.shibboleth.oidfed.metadata.TrustMark;
 import net.shibboleth.oidfed.profile.TrustedRemoteResolverEntity;
 import net.shibboleth.shared.annotation.constraint.Live;
 
@@ -54,7 +53,7 @@ public final class RelyingPartyTrustChainContext extends BaseContext {
     @Nullable private Map<String, List<String>> verifiedTrustMarkIds;
 
     /** Verified trust marks for the selected trust chain. */
-    @Nullable private Map<String, List<SignedJWT>> verifiedTrustMarks;
+    @Nullable private Map<String, List<TrustMark>> verifiedTrustMarks;
 
     /** Verified trust mark issuers. */
     @Nonnull @Live private Map<String, EntityStatement<?>> verifiedTrustMarkIssuers;
@@ -208,7 +207,7 @@ public final class RelyingPartyTrustChainContext extends BaseContext {
      * 
      * @return verified trust marks
      */
-    @Nullable public Map<String, List<SignedJWT>> getVerifiedTrustMarks() {
+    @Nullable public Map<String, List<TrustMark>> getVerifiedTrustMarks() {
         return verifiedTrustMarks;
     }
 
@@ -220,7 +219,7 @@ public final class RelyingPartyTrustChainContext extends BaseContext {
      * @return this context
      */
     @Nonnull public RelyingPartyTrustChainContext setVerifiedTrustMarks(
-            @Nullable final Map<String, List<SignedJWT>> trustMarks) {
+            @Nullable final Map<String, List<TrustMark>> trustMarks) {
         verifiedTrustMarks = trustMarks;
         return this;
     }
diff --git a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/CallResolveEntityApi.java b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/CallResolveEntityApi.java
index fd49db6..a710cb2 100644
--- a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/CallResolveEntityApi.java
+++ b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/CallResolveEntityApi.java
@@ -39,6 +39,7 @@ import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
 import org.slf4j.Logger;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.nimbusds.jwt.SignedJWT;
 
@@ -49,6 +50,7 @@ import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
 import net.shibboleth.oidfed.metadata.EntityConfiguration;
 import net.shibboleth.oidfed.metadata.EntityStatement;
 import net.shibboleth.oidfed.metadata.ResolveEntityResponse;
+import net.shibboleth.oidfed.metadata.TrustMark;
 import net.shibboleth.oidfed.metadata.cache.FederationEndpointEntityStatementCriterion;
 import net.shibboleth.oidfed.metadata.cache.ResponseContainerExpirationCriterion;
 import net.shibboleth.oidfed.metadata.cache.SubjectEntityIDCriterion;
@@ -57,6 +59,7 @@ import net.shibboleth.oidfed.metadata.cache.configuration.EntityConfigurationCon
 import net.shibboleth.oidfed.metadata.cache.resolver.ResolveEntityCacheContainerIdentifier;
 import net.shibboleth.oidfed.metadata.cache.resolver.ResolveEntityCacheIdentifierCriterion;
 import net.shibboleth.oidfed.metadata.cache.resolver.ResolveEntityResponseContainer;
+import net.shibboleth.oidfed.metadata.impl.TrustMarkImpl;
 import net.shibboleth.oidfed.metadata.payload.ResolveEntityResponsePayload;
 import net.shibboleth.oidfed.metadata.payload.claim.Metadata;
 import net.shibboleth.oidfed.metadata.util.EntityStatementHelper;
@@ -460,7 +463,7 @@ public class CallResolveEntityApi extends AbstractProfileAction {
                 trustChainContext.setPolicyCompliantTrustChains(policyCompliantChains);
                 log.debug("{} Populated policy compliant trust chains with {}", getLogPrefix(), policyCompliantChains);
 
-                final List<SignedJWT> trustMarks = rawTrustMarks == null ? null : rawTrustMarks
+                final List<TrustMark> trustMarks = rawTrustMarks == null ? null : rawTrustMarks
                         .stream()
                         .filter(Map.class::isInstance)
                         .map(Map.class::cast)
@@ -468,16 +471,11 @@ public class CallResolveEntityApi extends AbstractProfileAction {
                         .filter(Objects::nonNull)
                         .toList();
                 if (trustMarks != null) {
-                    final Map<String, List<SignedJWT>> trustMarksByEntity = new HashMap<>();
+                    final Map<String, List<TrustMark>> trustMarksByEntity = new HashMap<>();
                     for (final String entity : chain.stream().map(entity -> entity.getSubject()).toList()) {
-                        final List<SignedJWT> trustMarksForEntity = trustMarks.stream()
-                                .filter(jwt -> {
-                                    try {
-                                        return entity.equals(jwt.getJWTClaimsSet().getSubject());
-                                    } catch (final ParseException e1) {
-                                        return false;
-                                    }
-                                }).toList();
+                        final List<TrustMark> trustMarksForEntity = trustMarks.stream()
+                                .filter(trustMark -> entity.equals(trustMark.getParsedPayload().getSubject()))
+                                .toList();
                         if (!trustMarksForEntity.isEmpty()) {
                             trustMarksByEntity.put(entity, trustMarksForEntity);
                         }
@@ -486,14 +484,7 @@ public class CallResolveEntityApi extends AbstractProfileAction {
                         trustChainContext.setVerifiedTrustMarks(trustMarksByEntity);
                         final Map<String, List<String>> trustMarkIds = trustMarksByEntity.entrySet().stream()
                                 .collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue().stream()
-                                        .map(jwt -> {
-                                            try {
-                                                return jwt.getJWTClaimsSet().getStringClaim("trust_mark_type");
-                                            } catch (final ParseException e1) {
-                                                return null;
-                                            }
-                                        })
-                                        .filter(Objects::nonNull)
+                                        .map(trustMark -> trustMark.getParsedPayload().getTrustMarkType())
                                         .toList()));
                         log.debug("{} The following trust marks are included: {}", getLogPrefix(), trustMarkIds);
                         trustChainContext.setVerifiedTrustMarkIds(trustMarkIds);
@@ -520,12 +511,16 @@ public class CallResolveEntityApi extends AbstractProfileAction {
      * @param trustMark trust mark to be verified, expected to be parseable from string
      * @return trust mark JWT if valid, null otherwise
      */
-    @Nullable private SignedJWT parseTrustMark(@Nullable final Object trustMark) {
+    @Nullable private TrustMark parseTrustMark(@Nullable final Object trustMark) {
         if (trustMark instanceof String string) {
             try {
-                return SignedJWT.parse(string);
+                final SignedJWT jwt = SignedJWT.parse(string);
+                assert jwt != null; assert objectMapper != null;
+                return TrustMarkImpl.parse(jwt, objectMapper);
             } catch (final ParseException e) {
                 log.error("{} Could not parse the trust mark into a JWT", getLogPrefix(), e);
+            } catch (final JsonProcessingException e) {
+                log.error("{} Could not parse JWT payload into a trust mark", getLogPrefix(), e);
             }
         }
         return null;
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 cadb3b9..f082794 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
@@ -45,10 +45,12 @@ 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.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;
 import net.shibboleth.oidfed.profile.context.VerifiedTrustChain;
@@ -80,7 +82,7 @@ public class ResolveTrustMarks extends AbstractProfileAction {
 
     /** Strategy used to parse trust marks from the selected trust chain. */
     @NonnullAfterInit
-    private Function<List<EntityStatement<?>>,Map<String,List<SignedJWT>>> trustChainTrustMarksParsingStrategy;
+    private Function<List<EntityStatement<?>>,Map<String,List<TrustMark>>> trustChainTrustMarksParsingStrategy;
 
     /** Strategy used to lookup trusted trust mark issuers for the trust chain. */
     @NonnullAfterInit
@@ -151,7 +153,7 @@ public class ResolveTrustMarks extends AbstractProfileAction {
      * @param strategy parsing strategy
      */
     public void setTrustChainTrustMarksParsingStrategy(
-            @Nonnull final Function<List<EntityStatement<?>>,Map<String,List<SignedJWT>>> strategy) {
+            @Nonnull final Function<List<EntityStatement<?>>,Map<String,List<TrustMark>>> strategy) {
         checkSetterPreconditions();
         trustChainTrustMarksParsingStrategy =
                 Constraint.isNotNull(strategy, "TrustChainTrustMarksParsingStrategy cannot be null");
@@ -328,14 +330,15 @@ public class ResolveTrustMarks extends AbstractProfileAction {
         trustChainContext.setVerifiedTrustMarks(CollectionSupport.emptyMap());
         trustChainContext.setVerifiedTrustMarkIds(CollectionSupport.emptyMap());
 
-        final Map<String, List<SignedJWT>> chainTrustMarks =
+        final Map<String, List<TrustMark>> chainTrustMarks =
                 Optional.ofNullable(trustChainTrustMarksParsingStrategy.apply(selectedTrustChain))
                     .orElseGet(NonnullSupplier.of(CollectionSupport.emptyMap()))
                     .entrySet().stream()
                     .collect(Collectors.toMap(entry -> entry.getKey(),
                             entry -> entry.getValue().stream()
                                 .filter(trustMark ->
-                                        validateClaims(trustMarkClaimsValidator, trustMark, profileRequestContext))
+                                        validateClaims(trustMarkClaimsValidator, trustMark.getJwt(),
+                                                profileRequestContext))
                             .toList()));
         if (chainTrustMarks == null || chainTrustMarks.isEmpty()) {
             log.debug("{} No valid trust marks found from the selected trust chain", getLogPrefix());
@@ -354,9 +357,9 @@ public class ResolveTrustMarks extends AbstractProfileAction {
         log.debug("{} Trusted trust mark owners {}", getLogPrefix(), trustedOwners);
         assert trustedOwners != null;
         
-        final Map<String, List<SignedJWT>> verifiedTrustMarks = new HashMap<>();
+        final Map<String, List<TrustMark>> verifiedTrustMarks = new HashMap<>();
         for (final EntityStatement<?> statement : selectedTrustChain) {
-            final List<SignedJWT> trustMarks = chainTrustMarks.get(statement.getSubject());
+            final List<TrustMark> trustMarks = chainTrustMarks.get(statement.getSubject());
             if (trustMarks == null || trustMarks.isEmpty()) {
                 break;
             }
@@ -373,7 +376,7 @@ public class ResolveTrustMarks extends AbstractProfileAction {
         trustChainContext.setVerifiedTrustMarks(verifiedTrustMarks);
         final Map<String, List<String>> verifiedTrustMarkIds = verifiedTrustMarks.entrySet().stream()
                 .collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue().stream()
-                        .map(list -> getTrustMarkId(list))
+                        .map(trustMark -> trustMark.getParsedPayload().getTrustMarkType())
                         .collect(Collectors.toList())));
         log.debug("{} The following trust marks are validated: {}", getLogPrefix(), verifiedTrustMarkIds);
         trustChainContext.setVerifiedTrustMarkIds(verifiedTrustMarkIds);
@@ -406,43 +409,36 @@ public class ResolveTrustMarks extends AbstractProfileAction {
     /**
      * Verifies the given trust mark meets configuration for trusted trust mark issuers.
      * 
-     * @param jwt the trust mark to be verified
+     * @param trustMark the trust mark to be verified
      * @param trustedIssuers the trusted trust mark issuers
      * @param trustedOwners the trusted trust mark owners
      * @return true if the trust mark meets configuration, false otherwise
      */
-    protected boolean checkTrustedIssuer(@Nullable final SignedJWT jwt,
+    protected boolean checkTrustedIssuer(@Nullable final TrustMark trustMark,
             @Nonnull final Map<String, List<String>> trustedIssuers,
             @Nonnull final Map<String, TrustMarkOwner> trustedOwners) {
-        if (jwt == null) {
+        if (trustMark == null) {
             return false;
         }
-        try {
-            final JWTClaimsSet claimsSet = jwt.getJWTClaimsSet();
-            final String id = StringSupport.trimOrNull(getTrustMarkId(jwt));
-            if (id == null) {
+        final String id = StringSupport.trimOrNull(trustMark.getParsedPayload().getTrustMarkType());
+        if (id == null) {
+            return false;
+        }
+        if (trustedIssuers.containsKey(id)) {
+            final String issuer = trustMark.getIssuer();
+            final List<String> validIssuers = trustedIssuers.get(id);
+            if (validIssuers == null || !validIssuers.contains(issuer)) {
+                log.debug("{} Issuer {} is not valid trust mark issuer", getLogPrefix(), issuer);
                 return false;
             }
-            if (trustedIssuers.containsKey(id)) {
-                final String issuer = claimsSet.getIssuer();
-                assert issuer != null;
-                final List<String> validIssuers = trustedIssuers.get(id);
-                if (validIssuers == null || !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 (claimsSet.getStringClaim("delegation") == null) {
-                    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);
+        } 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);
                 return false;
             }
-        } catch (final ParseException e) {
-            log.error("{} Could not parse TrustMark JWT contents", getLogPrefix(), e);
+        } else {
+            log.debug("{} Trust mark ID {} is not included in the trusted issuers", getLogPrefix(), id);
             return false;
         }
         return true;
@@ -452,27 +448,20 @@ public class ResolveTrustMarks extends AbstractProfileAction {
      * Verifies the given trust mark by exploiting (1) the trust chain cache for fetching the trust chain for the issuer
      * entity configuration and (2) the trust engine for validating the trust mark signature.
      * 
-     * @param jwt the trust mark to be verified
+     * @param trustMark the trust mark to be verified
      * @param trustedOwners the trusted trust mark owners
      * @param profileRequestContext the profile request context
      * @param trustedTrustMarkIssuers the map of trusted issuers that will be populated if issuer was verified
      * @return true if trust mark verification was successful, false otherwise
      */
-    protected boolean verifyTrustMark(@Nullable final SignedJWT jwt,
+    protected boolean verifyTrustMark(@Nullable final TrustMark trustMark,
             @Nonnull final Map<String, TrustMarkOwner> trustedOwners,
             @Nonnull final ProfileRequestContext profileRequestContext,
             @Nonnull @Live final Map<String, EntityStatement<?>> trustedTrustMarkIssuers) {
-        if (jwt == null) {
+        if (trustMark == null) {
             return false;
         }
-        final JWTClaimsSet trustMarkClaims;
-        try {
-            trustMarkClaims = jwt.getJWTClaimsSet();
-        } catch (final ParseException e) {
-            log.error("{} Could not parse the TrustMark JWT contents", getLogPrefix(), e);
-            return false;
-        }
-        final String issuer = trustMarkClaims.getIssuer();
+        final String issuer = trustMark.getIssuer();
         assert issuer != null;
         log.debug("{} Resolving trust chain for {}", getLogPrefix(), issuer);
         final List<TrustChainsContainer> cacheResult;
@@ -493,12 +482,12 @@ public class ResolveTrustMarks extends AbstractProfileAction {
         trustedTrustMarkIssuers.put(trustMarkIssuer.getSubject(), trustMarkIssuer);
         log.trace("{} Validating entity statement {}", getLogPrefix(), trustMarkIssuer.getJwt().serialize());
         try {
-            if (trustEngine.validate(jwt, criteria)) {
-                final String id = getTrustMarkId(jwt);
+            if (trustEngine.validate(trustMark.getJwt(), criteria)) {
+                final String id = trustMark.getParsedPayload().getTrustMarkType();
                 assert id != null;
                 log.debug("{} Successfully validated trust mark {} issued by {}", getLogPrefix(), id, issuer);
                 if (trustedOwners.containsKey(id)) {
-                    return validateDelegatedTrustMark(trustMarkClaims, id, trustedOwners, profileRequestContext);
+                    return validateDelegatedTrustMark(trustMark.getParsedPayload(), id, trustedOwners, profileRequestContext);
                 } else {
                     return true;
                 }
@@ -518,13 +507,13 @@ public class ResolveTrustMarks extends AbstractProfileAction {
      * @param profileRequestContext the profile request context
      * @return true if delegation JWT was valid, false otherwise
      */
-    protected boolean validateDelegatedTrustMark(@Nonnull final JWTClaimsSet trustMarkClaims,
+    protected boolean validateDelegatedTrustMark(@Nonnull final TrustMarkPayload trustMarkClaims,
             @Nonnull final String id,
             @Nonnull final Map<String, TrustMarkOwner> trustedOwners,
             @Nonnull final ProfileRequestContext profileRequestContext) {
         log.debug("{} Validating delegated trust mark {}", getLogPrefix(), id);
         try {
-            final SignedJWT delegationJwt = SignedJWT.parse(trustMarkClaims.getStringClaim("delegation"));
+            final SignedJWT delegationJwt = SignedJWT.parse(trustMarkClaims.getDelegation());
             final CriteriaSet delegationCriteria = new CriteriaSet(
                     new TrustMarkOwnersCriterion(trustedOwners),
                     new SubjectEntityIDCriterion(id));
@@ -551,19 +540,4 @@ public class ResolveTrustMarks extends AbstractProfileAction {
         }
         return false;
     }
-
-    /**
-     * Parses the trust mark ID for the given trust mark.
-     * 
-     * @param trustMark the trust mark
-     * @return the ID, or null if it could not be parsed
-     */
-    @Nullable private String getTrustMarkId(@Nullable final SignedJWT trustMark) {
-        try {
-            return trustMark == null ? null : trustMark.getJWTClaimsSet().getStringClaim("trust_mark_type");
-        } catch (final ParseException e) {
-            log.error("{} Could not parse the TrustMark JWT contents", getLogPrefix(), e);
-        }
-        return null;
-    }
 }
\ No newline at end of file
diff --git a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/ValidateTrustMarks.java b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/ValidateTrustMarks.java
index d3e7e88..2500e82 100644
--- a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/ValidateTrustMarks.java
+++ b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/ValidateTrustMarks.java
@@ -36,6 +36,7 @@ import net.shibboleth.idp.profile.AbstractProfileAction;
 import net.shibboleth.oidc.metadata.cache.MetadataCache;
 import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
 import net.shibboleth.oidfed.metadata.EntityStatement;
+import net.shibboleth.oidfed.metadata.TrustMark;
 import net.shibboleth.oidfed.metadata.cache.trustmark.TrustMarkStatusCacheIdentifier;
 import net.shibboleth.oidfed.metadata.cache.trustmark.TrustMarkStatusContainer;
 import net.shibboleth.oidfed.metadata.cache.trustmark.TrustMarkStatusIdentifierCriterion;
@@ -165,10 +166,10 @@ public class ValidateTrustMarks extends AbstractProfileAction {
     /** {@inheritDoc} */
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        final Map<String, List<SignedJWT>> verifiedTrustMarks = trustChainContext.getVerifiedTrustMarks();
+        final Map<String, List<TrustMark>> verifiedTrustMarks = trustChainContext.getVerifiedTrustMarks();
         final Map<String, List<String>> verifiedTrustMarkIds = trustChainContext.getVerifiedTrustMarkIds();
         final String subject = selectedTrustChain.get(0).getSubject();
-        final List<SignedJWT> subjectTrustMarks = verifiedTrustMarks != null ? verifiedTrustMarks.get(subject) : null;
+        final List<TrustMark> subjectTrustMarks = verifiedTrustMarks != null ? verifiedTrustMarks.get(subject) : null;
         final List<String> subjectTrustMarkIds =
                 verifiedTrustMarkIds != null ? verifiedTrustMarkIds.get(subject) : null;
         if (subjectTrustMarks == null || subjectTrustMarks.isEmpty()) {
@@ -181,12 +182,12 @@ public class ValidateTrustMarks extends AbstractProfileAction {
             return;
         }
         log.trace("{} Subject trust marks before validation {}", getLogPrefix(), subjectTrustMarks);
-        for (final SignedJWT trustMark : CollectionSupport.copyToList(subjectTrustMarks)) {
+        for (final TrustMark trustMark : CollectionSupport.copyToList(subjectTrustMarks)) {
             assert trustMark != null;
             try {
-                final String issuer = trustMark.getJWTClaimsSet().getIssuer();
-                final String trustMarkSubject = trustMark.getJWTClaimsSet().getSubject();
-                final String trustMarkType = trustMark.getJWTClaimsSet().getStringClaim("trust_mark_type");
+                final String issuer = trustMark.getIssuer();
+                final String trustMarkSubject = trustMark.getParsedPayload().getSubject();
+                final String trustMarkType = trustMark.getParsedPayload().getTrustMarkType();
                 final EntityStatement<?> issuerStatement = trustChainContext.getVerifiedTrustMarkIssuers().get(issuer);
                 if (issuerStatement == null) {
                     log.warn("{} Could not resolve trust mark issuer statement for {}", getLogPrefix(), issuer);
@@ -205,7 +206,7 @@ public class ValidateTrustMarks extends AbstractProfileAction {
                     continue;
                 }
                 final TrustMarkStatusCacheIdentifier cacheIdentifier =
-                        new TrustMarkStatusCacheIdentifier(uri, trustMark);
+                        new TrustMarkStatusCacheIdentifier(uri, trustMark.getJwt());
                 final CriteriaSet criteria = new CriteriaSet(new TrustMarkStatusIdentifierCriterion(cacheIdentifier));
                 final List<TrustMarkStatusContainer> cacheResult = trustMarkStatusCache.get(criteria);
                 if (cacheResult.isEmpty()) {
diff --git a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/navigate/DefaultTrustChainTrustMarksParsingStrategy.java b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/navigate/DefaultTrustChainTrustMarksParsingStrategy.java
index f0529ba..f5e2d08 100644
--- a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/navigate/DefaultTrustChainTrustMarksParsingStrategy.java
+++ b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/navigate/DefaultTrustChainTrustMarksParsingStrategy.java
@@ -26,13 +26,19 @@ import javax.annotation.Nullable;
 
 import org.slf4j.Logger;
 
-import com.nimbusds.jwt.JWTClaimsSet;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.nimbusds.jwt.SignedJWT;
 
 import net.shibboleth.oidfed.metadata.EntityStatement;
+import net.shibboleth.oidfed.metadata.TrustMark;
+import net.shibboleth.oidfed.metadata.impl.TrustMarkImpl;
 import net.shibboleth.oidfed.metadata.payload.EntityConfigurationPayload;
+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;
 import net.shibboleth.shared.primitive.StringSupport;
 
@@ -42,21 +48,45 @@ import net.shibboleth.shared.primitive.StringSupport;
  */
 @ThreadSafeAfterInit
 public class DefaultTrustChainTrustMarksParsingStrategy extends AbstractIdentifiableInitializableComponent
-        implements Function<List<EntityStatement<?>>,Map<String,List<SignedJWT>>> {
+        implements Function<List<EntityStatement<?>>,Map<String,List<TrustMark>>> {
 
     /** Class logger. */
     @Nonnull private Logger log = LoggerFactory.getLogger(DefaultTrustChainTrustMarksParsingStrategy.class);
 
+    /** JSON object mapper used for decoding JSON into Map. */
+    @NonnullAfterInit protected ObjectMapper objectMapper;
+
+    /**
+
+     * Set the JSON {@link ObjectMapper} used for decoding JSON into Map.
+     * 
+     * @param mapper object mapper
+     */
+    public void setObjectMapper(@Nonnull final ObjectMapper mapper) {
+        checkSetterPreconditions();
+
+        objectMapper = Constraint.isNotNull(mapper, "Object mapper cannot be null");
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void doInitialize() throws ComponentInitializationException {
+        super.doInitialize();
+        if (objectMapper == null) {
+            throw new ComponentInitializationException("Object mapper cannot be null");
+        }
+    }
+
     /** {@inheritDoc} */
     @Override @Nullable
-    public Map<String, List<SignedJWT>> apply(@Nullable final List<EntityStatement<?>> trustChain) {
+    public Map<String, List<TrustMark>> apply(@Nullable final List<EntityStatement<?>> trustChain) {
         checkComponentActive();
         if (trustChain == null || trustChain.size() < 3) {
             log.error("Unexpected length in the trust chain: {}", trustChain == null ? "null" : trustChain.size());
             return null;
         }
         
-        final Map<String, List<SignedJWT>> result = new HashMap<>();
+        final Map<String, List<TrustMark>> result = new HashMap<>();
         for (final EntityStatement<?> statement : trustChain) {
             assert statement != null;
             if (statement.getParsedPayload() instanceof EntityConfigurationPayload ecp) {
@@ -67,7 +97,7 @@ public class DefaultTrustChainTrustMarksParsingStrategy extends AbstractIdentifi
 
                 if (rawTrustMarks != null && !rawTrustMarks.isEmpty()) {
                     log.trace("Transforming the trust mark into a JWT");
-                    final List<SignedJWT> trustMarks = rawTrustMarks
+                    final List<TrustMark> trustMarks = rawTrustMarks
                             .stream()
                             .map(entry -> parseTrustMark(entry))
                             .filter(Objects::nonNull)
@@ -88,7 +118,7 @@ public class DefaultTrustChainTrustMarksParsingStrategy extends AbstractIdentifi
      * @param trustMarkEntry trust mark entry as Strign to be parsed into a JWT
      * @return trust mark JWT if valid, null otherwise
      */
-    @Nullable private SignedJWT parseTrustMark(@Nullable final Map<String, String> trustMarkEntry) {
+    @Nullable private TrustMark parseTrustMark(@Nullable final Map<String, String> trustMarkEntry) {
         if (trustMarkEntry == null) {
             return null;
         }
@@ -100,28 +130,31 @@ public class DefaultTrustChainTrustMarksParsingStrategy extends AbstractIdentifi
      * 
      * @param trustMark trust mark to be verified
      * @param id the id to be verified from the JWT claims set
-     * @return trust mark JWT if valid, null otherwise
+     * @return trust mark if valid, null otherwise
      */
-    @Nullable private SignedJWT verifyTrustMark(@Nullable final String trustMark, @Nullable final String id) {
+    @Nullable private TrustMark verifyTrustMark(@Nullable final String trustMark, @Nullable final String id) {
         if (trustMark == null || id == null) {
             log.trace("Could not parse trust mark {} with trust_mark_type {}", trustMark, id);
             return null;
         }
         try {
             final SignedJWT jwt = SignedJWT.parse((String) trustMark);
-            final JWTClaimsSet trustMarkClaims = jwt.getJWTClaimsSet();
-            if (StringSupport.trimOrNull(trustMarkClaims.getIssuer()) == null) {
+            assert jwt != null; assert objectMapper != null;
+            final TrustMarkImpl result = TrustMarkImpl.parse(jwt, objectMapper);
+            if (StringSupport.trimOrNull(result.getIssuer()) == null) {
                 log.error("Trust Mark {} is missing mandatory issuer",
-                        trustMarkClaims.getStringClaim("trust_mark_type"));
+                        result.getParsedPayload().getTrustMarkType());
                 return null;
             }
-            if (id.equals(trustMarkClaims.getStringClaim("trust_mark_type"))) {
-                return jwt;
+            if (id.equals(result.getParsedPayload().getTrustMarkType())) {
+                return result;
             }
             log.error("The id {} is not matching with the trust_mark_type-claim {}", id,
-                    trustMarkClaims.getStringClaim("trust_mark_type"));
+                    result.getParsedPayload().getTrustMarkType());
         } catch (final ParseException e) {
             log.error("Could not parse id-claim from the trust mark", e);
+        } catch (final JsonProcessingException e) {
+            log.error("Could not parse trust mark from the JWT", e);
         }
         return null;
     }

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


More information about the commits mailing list