[java-oidc-common] branch main updated: Add signature algorithm include and exclude checking to sig validation

Phil Smart philip.smart at jisc.ac.uk
Mon Feb 6 11:38:39 UTC 2023


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

philsmart pushed a commit to branch main
in repository java-oidc-common.

View the commit online:
http://git.shibboleth.net/view/?p=java-oidc-common.git;a=commit;h=410f94cb6317cc1908fd19e0b140962e75699e6f

The following commit(s) were added to refs/heads/main by this push:
     new 410f94c  Add signature algorithm include and exclude checking to sig validation
410f94c is described below

commit 410f94cb6317cc1908fd19e0b140962e75699e6f
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Mon Feb 6 11:38:37 2023 +0000

    Add signature algorithm include and exclude checking to sig validation
    
     - Add algorithm lookup to the validation function of the
    BaseSignedJWTTrustEngine
     - Add SecurityValidationParameters to a new
    SignatureValidationParametersCriterion inside the
    BaseJWTSignatureSecurityHandler. This is then pulled out by the trust
    engine and the algorithm of the JWS is checked against the include and
    excludes list.
     - Add and cleanup tests
---
 .../SignatureValidationParametersCriterion.java    |  90 ++++++++++
 .../impl/BaseJWTSignatureSecurityHandler.java      |  34 +++-
 .../security/impl/BaseSignedJWTTrustEngine.java    |  22 +--
 .../impl/ExplicitKeySignedJWTTrustEngineTest.java  | 200 ++++++++++-----------
 .../impl/MockEmptyListCredentialResolver.java      |  28 +++
 .../impl/MockFunctionalCredentialResolver.java     |  24 +++
 6 files changed, 280 insertions(+), 118 deletions(-)

diff --git a/oidc-common-crypto-api/src/main/java/net/shibboleth/oidc/security/jose/criterion/SignatureValidationParametersCriterion.java b/oidc-common-crypto-api/src/main/java/net/shibboleth/oidc/security/jose/criterion/SignatureValidationParametersCriterion.java
new file mode 100644
index 0000000..d060e08
--- /dev/null
+++ b/oidc-common-crypto-api/src/main/java/net/shibboleth/oidc/security/jose/criterion/SignatureValidationParametersCriterion.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.security.jose.criterion;
+
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.oidc.security.jose.SignatureValidationParameters;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.resolver.Criterion;
+
+/**
+ * Criterion which holds an instance of {@link SignatureValidationParameters}.
+ * 
+ * <p>This criterion is often used with implementations of the {@link BaseSignedJWTTrustEngine}.</p>
+ */
+public class SignatureValidationParametersCriterion implements Criterion {
+    
+    /** The SignatureValidationParameters instance. */
+    private final SignatureValidationParameters params;
+    
+    /**
+     * Constructor.
+     *
+     * @param validationParams the signature validation parameters instance to wrap
+     */
+    public SignatureValidationParametersCriterion(@Nonnull final SignatureValidationParameters validationParams) {
+       params = Constraint.isNotNull(validationParams, "SignatureValidationParameters instance was null"); 
+    }
+    
+    /**
+     * Get the signature validation parameters instance.
+     * 
+     * @return the parameters instance
+     */
+    @Nonnull public SignatureValidationParameters getSignatureValidationParameters() {
+        return params;
+    }
+    
+    
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("SignatureValidationParametersCriterion [params=");
+        builder.append(params);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        return params.hashCode();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj == null) {
+            return false;
+        }
+
+        if (obj instanceof SignatureValidationParametersCriterion) {
+            return params.equals(((SignatureValidationParametersCriterion) obj).getSignatureValidationParameters());
+        }
+
+        return false;
+    }
+
+}
diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/BaseJWTSignatureSecurityHandler.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/BaseJWTSignatureSecurityHandler.java
index d9c4c0d..1c68ff7 100644
--- a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/BaseJWTSignatureSecurityHandler.java
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/BaseJWTSignatureSecurityHandler.java
@@ -45,6 +45,7 @@ import net.shibboleth.oidc.security.jose.context.SecurityParametersContext;
 import net.shibboleth.oidc.security.jose.criterion.ClientInformationCriterion;
 import net.shibboleth.oidc.security.jose.criterion.ClientSecretCredentialCriterion;
 import net.shibboleth.oidc.security.jose.criterion.ProviderMetadataCriterion;
+import net.shibboleth.oidc.security.jose.criterion.SignatureValidationParametersCriterion;
 import net.shibboleth.utilities.java.support.component.ComponentSupport;
 import net.shibboleth.utilities.java.support.logic.Constraint;
 import net.shibboleth.utilities.java.support.logic.FunctionSupport;
@@ -52,6 +53,14 @@ import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
 
 /**
  * Base class for security message handlers which evaluate a JWT signature with a signature trust engine.
+ * 
+ * <p>Criterion are constructed from the following sources:</p>
+ * <ol>
+ * <li>(Optional) Provider metadata.</li>
+ * <li>(Optional) Client information.</li>
+ * <li>(Optional) Client secret credentials.</li>
+ * <li>(Required) The SecurityParametersContext.</li>
+ * </ol>
  */
 public abstract class BaseJWTSignatureSecurityHandler extends BaseTrustEngineSecurityHandler<SignedJWT> {    
     
@@ -78,6 +87,9 @@ public abstract class BaseJWTSignatureSecurityHandler extends BaseTrustEngineSec
     /** Lookup function for relying party context. */
     @Nonnull private Function<ProfileRequestContext,RelyingPartyContext> relyingPartyContextLookupStrategy;
     
+    /** Strategy used to look up the {@link SecurityParametersContext}. */
+    @Nonnull private Function<MessageContext,SecurityParametersContext> securityParametersContextLookupStrategy;
+    
     /** Applicable stashed profile configuration. */
     @Nullable private OIDCAuthorizationConfiguration profileConfiguration;
     
@@ -92,6 +104,20 @@ public abstract class BaseJWTSignatureSecurityHandler extends BaseTrustEngineSec
         providerMetadataLookupStrategy = FunctionSupport.constant(null);
         clientInformationLookupStrategy = FunctionSupport.constant(null);
         relyingPartyContextLookupStrategy = new ChildContextLookup<>(RelyingPartyContext.class);
+        securityParametersContextLookupStrategy = new ChildContextLookup<>(SecurityParametersContext.class, true);
+    }
+    
+    /**
+     * Set the strategy used to look up the {@link SecurityParametersContext} to set the parameters for.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setSecurityParametersContextLookupStrategy(
+            @Nonnull final Function<MessageContext, SecurityParametersContext> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        securityParametersContextLookupStrategy = Constraint.isNotNull(strategy,
+                "SecurityParametersContext lookup strategy cannot be null");
     }
     
     /**
@@ -186,7 +212,13 @@ public abstract class BaseJWTSignatureSecurityHandler extends BaseTrustEngineSec
             }
         }
        
-        criteriaSet.add( new UsageCriterion(UsageType.SIGNING));
+        criteriaSet.add( new UsageCriterion(UsageType.SIGNING));        
+       
+        final SecurityParametersContext secParams = securityParametersContextLookupStrategy.apply(messageContext);
+        if (secParams == null) {
+            throw new MessageHandlerException("Security parameters context could not be found, must be set");
+        }
+        criteriaSet.add(new SignatureValidationParametersCriterion(secParams.getSignatureValidationParameters()));
         
         return criteriaSet;
     }
diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/BaseSignedJWTTrustEngine.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/BaseSignedJWTTrustEngine.java
index 0d0c798..db17de8 100644
--- a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/BaseSignedJWTTrustEngine.java
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/BaseSignedJWTTrustEngine.java
@@ -29,6 +29,7 @@ import javax.annotation.Nullable;
 import org.opensaml.security.SecurityException;
 import org.opensaml.security.credential.Credential;
 import org.opensaml.security.trust.TrustEngine;
+import org.opensaml.xmlsec.algorithm.AlgorithmSupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -44,6 +45,7 @@ import com.nimbusds.jwt.SignedJWT;
 import net.shibboleth.oidc.security.credential.JOSEObjectCredentialResolver;
 import net.shibboleth.oidc.security.credential.JWKCredential;
 import net.shibboleth.oidc.security.jose.criterion.JOSEObjectCriterion;
+import net.shibboleth.oidc.security.jose.criterion.SignatureValidationParametersCriterion;
 import net.shibboleth.utilities.java.support.logic.Constraint;
 import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
 import net.shibboleth.utilities.java.support.resolver.ResolverException;
@@ -66,7 +68,7 @@ public abstract class BaseSignedJWTTrustEngine<TrustBasisType> implements TrustE
      * 
      * @param joseObjectResolver resolver of credentials from JOSEObject headers.
      */
-    public BaseSignedJWTTrustEngine(@Nonnull final JOSEObjectCredentialResolver joseObjectResolver) {
+    protected BaseSignedJWTTrustEngine(@Nonnull final JOSEObjectCredentialResolver joseObjectResolver) {
         joseObjectCredentialResolver = Constraint.isNotNull(joseObjectResolver,
                 "JOSEObject credential resolver cannot be null");
     }
@@ -77,22 +79,22 @@ public abstract class BaseSignedJWTTrustEngine<TrustBasisType> implements TrustE
         
         checkParams(signedJWT, trustBasisCriteria);
         
-        /* TODO - need correct components, and/or to account for diffs between XML and JOSE algorithm identifiers
-         * 
+        /* 
+         * TODO - need correct components, and/or to account for diffs between XML and JOSE algorithm identifiers
+         */ 
         final SignatureValidationParametersCriterion validationCriterion = 
                 trustBasisCriteria.get(SignatureValidationParametersCriterion.class);
         if (validationCriterion != null) {
             log.debug("Performing signature algorithm include/exclude validation using params from CriteriaSet");
-            final SignatureAlgorithmValidator algorithmValidator = 
-                    new SignatureAlgorithmValidator(validationCriterion.getSignatureValidationParameters());
-            try {
-                algorithmValidator.validate(signature);
-            } catch (final SignatureException e) {
-                log.warn("XML signature failed algorithm include/exclude validation");
+            // Algorithm can not be null on the header
+            final Algorithm algorithm = signedJWT.getHeader().getAlgorithm();
+            if (!AlgorithmSupport.validateAlgorithmURI(algorithm.getName(), 
+                    validationCriterion.getSignatureValidationParameters().getIncludedAlgorithms(), 
+                    validationCriterion.getSignatureValidationParameters().getExcludedAlgorithms())) {
+                log.warn("Algorithm failed include/exclude validation: {}", algorithm.getName());
                 return false;
             }
         }
-        */
         
         return doValidate(signedJWT, trustBasisCriteria);
     }
diff --git a/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/ExplicitKeySignedJWTTrustEngineTest.java b/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/ExplicitKeySignedJWTTrustEngineTest.java
index 1b1d2d5..3fca776 100644
--- a/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/ExplicitKeySignedJWTTrustEngineTest.java
+++ b/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/ExplicitKeySignedJWTTrustEngineTest.java
@@ -25,12 +25,9 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.security.KeyException;
 import java.text.ParseException;
-import java.util.Collections;
 import java.util.List;
 
 import org.opensaml.security.SecurityException;
-import org.opensaml.security.credential.Credential;
-import org.opensaml.security.credential.CredentialResolver;
 import org.opensaml.security.credential.UsageType;
 import org.opensaml.security.criteria.UsageCriterion;
 import org.opensaml.security.crypto.KeySupport;
@@ -50,11 +47,13 @@ import com.nimbusds.jose.jwk.gen.ECKeyGenerator;
 import com.nimbusds.jwt.JWTClaimsSet;
 import com.nimbusds.jwt.SignedJWT;
 
+import net.shibboleth.oidc.jwa.support.SignatureConstants;
 import net.shibboleth.oidc.security.credential.BasicJWKCredential;
 import net.shibboleth.oidc.security.credential.JOSEObjectCredentialResolver;
 import net.shibboleth.oidc.security.credential.impl.BasicJOSEObjectCredentialResolver;
+import net.shibboleth.oidc.security.jose.SignatureValidationParameters;
+import net.shibboleth.oidc.security.jose.criterion.SignatureValidationParametersCriterion;
 import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
-import net.shibboleth.utilities.java.support.resolver.ResolverException;
 
 /** 
  * Tests for the {@link ExplicitKeySignedJWTTrustEngine}.
@@ -72,7 +71,7 @@ public class ExplicitKeySignedJWTTrustEngineTest {
     
     private ECKey key;
     
-    private CredentialResolver credResolver;
+    private MockFunctionalCredentialResolver credResolver;
     
     private JOSEObjectCredentialResolver joseObjectCredResolver;
     
@@ -100,31 +99,39 @@ public class ExplicitKeySignedJWTTrustEngineTest {
     /** The client_secret.*/
     private static final String CLIENT_SECRET = "Xp2s5v8y/B?E(H+MbQeThWmYq3t6w9z$";
     
+    /** Signature params.*/
+    private SignatureValidationParameters params;
+    
+    /** The criteria set to use.*/
+    private CriteriaSet criteria;
+    
     @BeforeMethod
     public void setup() throws JOSEException {
+        
+        //Setup a standard security params context
+        params = new SignatureValidationParameters();
+        params.setSignatureTrustEngine(engine);
+        
+        // Setup standard criterion
+        criteria = new CriteriaSet();
+        criteria.add(new UsageCriterion(UsageType.SIGNING));
+        criteria.add(new SignatureValidationParametersCriterion(params));
+        
+        
         key = new ECKeyGenerator(Curve.P_256).keyID("123").generate();
-
-        credResolver = new CredentialResolver() {
-
-            @Override
-            public Credential resolveSingle(final CriteriaSet criteria) throws ResolverException {
-                final BasicJWKCredential jwkCredential = new BasicJWKCredential();
-                jwkCredential.setAlgorithm(key.getAlgorithm());
-                jwkCredential.setKid(key.getKeyID());
-                try {
-                    jwkCredential.setPublicKey(((AsymmetricJWK) key).toPublicKey());
-                } catch (final JOSEException e) {                    
-                    fail();
-                }
-                return jwkCredential;
-            }
-
-            @Override
-            public Iterable<Credential> resolve(final CriteriaSet criteria) throws ResolverException {
-                return List.of(resolveSingle(criteria));
+        
+        credResolver = cs -> {
+            final BasicJWKCredential jwkCredential = new BasicJWKCredential();
+            jwkCredential.setAlgorithm(key.getAlgorithm());
+            jwkCredential.setKid(key.getKeyID());
+            try {
+                jwkCredential.setPublicKey(((AsymmetricJWK) key).toPublicKey());
+            } catch (final JOSEException e) {                    
+                fail();
             }
+            return jwkCredential;
         };
-        
+
         joseObjectCredResolver = new BasicJOSEObjectCredentialResolver();
         
         engine = new ExplicitKeySignedJWTTrustEngine(credResolver, joseObjectCredResolver);
@@ -133,9 +140,6 @@ public class ExplicitKeySignedJWTTrustEngineTest {
     @Test
     public void testValid_WithTrustedCredential() throws JOSEException, SecurityException {
         
-        final CriteriaSet criteria = new CriteriaSet();
-        criteria.add(new UsageCriterion(UsageType.SIGNING));
-        
         final var valid = engine.validate(createECSignedJWT(key, key.getKeyID(), JWSAlgorithm.ES256, 
                 "https://op.example.com/", "https://rp.example.com"),
                 criteria);
@@ -145,35 +149,62 @@ public class ExplicitKeySignedJWTTrustEngineTest {
     @Test
     public void testValid_WithSymmetricKeyCredential() throws JOSEException, SecurityException {
         
-        credResolver = new CredentialResolver() {
-
-            @Override
-            public Credential resolveSingle(final CriteriaSet criteria) throws ResolverException {
-                try {
-                    return TestCredentialHelper
-                            .createClientSecretCredential(CLIENT_SECRET).toSigningCredential();
-                } catch (final KeyException e) {
-                    fail(e.getMessage());
-                    return null;
-                }
+        credResolver = cs -> {
+            try {
+                return TestCredentialHelper
+                        .createClientSecretCredential(CLIENT_SECRET).toSigningCredential();
+            } catch (final KeyException e) {
+                fail(e.getMessage());
+                return null;
             }
-
-            @Override
-            public Iterable<Credential> resolve(final CriteriaSet criteria) throws ResolverException {
-                return List.of(resolveSingle(criteria));
+        };
+        
+        engine = new ExplicitKeySignedJWTTrustEngine(credResolver, joseObjectCredResolver);
+        
+        final var valid = engine.validate(createMACSignedJWT(CLIENT_SECRET, key.getKeyID(), JWSAlgorithm.HS256, 
+                "https://op.example.com/", "https://rp.example.com"),
+                criteria);
+        assertTrue(valid);
+    }
+    
+    @Test
+    public void testValid_WithSymmetricKeyCredential_JWSAlgorithm_Excluded() throws JOSEException, SecurityException {
+        
+        credResolver = cs -> {
+            try {
+                return TestCredentialHelper
+                        .createClientSecretCredential(CLIENT_SECRET).toSigningCredential();
+            } catch (final KeyException e) {
+                fail(e.getMessage());
+                return null;
             }
         };
         
         engine = new ExplicitKeySignedJWTTrustEngine(credResolver, joseObjectCredResolver);
         
+        // Exclude the HS256 algorithm
+        params.setExcludedAlgorithms(List.of(SignatureConstants.ALGO_ID_SIGNATURE_HS_256));
         
-        final CriteriaSet criteria = new CriteriaSet();
-        criteria.add(new UsageCriterion(UsageType.SIGNING));
+        final var valid = engine.validate(createMACSignedJWT(CLIENT_SECRET, key.getKeyID(), JWSAlgorithm.HS256, 
+                "https://op.example.com/", "https://rp.example.com"),
+                criteria);
+        assertFalse(valid);
+    }
+    
+    @Test
+    public void testValid_WithSymmetricKeyCredential_JWSAlgorithm_NotIncluded() throws JOSEException, SecurityException {
+        
+        credResolver = cs -> null;
+        
+        engine = new ExplicitKeySignedJWTTrustEngine(credResolver, joseObjectCredResolver);
+        
+        // Exclude the HS256 algorithm
+        params.setIncludedAlgorithms(List.of(SignatureConstants.ALGO_ID_SIGNATURE_HS_512));
         
         final var valid = engine.validate(createMACSignedJWT(CLIENT_SECRET, key.getKeyID(), JWSAlgorithm.HS256, 
                 "https://op.example.com/", "https://rp.example.com"),
                 criteria);
-        assertTrue(valid);
+        assertFalse(valid);
     }
     
     
@@ -193,34 +224,22 @@ public class ExplicitKeySignedJWTTrustEngineTest {
     @Test
     public void testInvalid_CVE_2016_10555() throws Exception {
         
-        credResolver = new CredentialResolver() {
-
-            @Override
-            public Credential resolveSingle(final CriteriaSet criteria) throws ResolverException {
-                final BasicJWKCredential jwkCredential = new BasicJWKCredential();
-                jwkCredential.setAlgorithm(key.getAlgorithm());
-                jwkCredential.setKid(key.getKeyID());
-                try {
-                    final var publicRSAKey = 
-                            KeySupport.buildJavaRSAPublicKey(CVE_2016_10555_SIGNING_CERT_PUBLIC_KEY);
-                    jwkCredential.setPublicKey(publicRSAKey);
-                } catch (final Exception e) {                    
-                    fail();
-                }
-                return jwkCredential;
-            }
-
-            @Override
-            public Iterable<Credential> resolve(final CriteriaSet criteria) throws ResolverException {
-                return List.of(resolveSingle(criteria));
+        credResolver = cs -> {
+            final BasicJWKCredential jwkCredential = new BasicJWKCredential();
+            jwkCredential.setAlgorithm(key.getAlgorithm());
+            jwkCredential.setKid(key.getKeyID());
+            try {
+                final var publicRSAKey = 
+                        KeySupport.buildJavaRSAPublicKey(CVE_2016_10555_SIGNING_CERT_PUBLIC_KEY);
+                jwkCredential.setPublicKey(publicRSAKey);
+            } catch (final Exception e) {                    
+                fail();
             }
+            return jwkCredential;
         };
         
         engine = new ExplicitKeySignedJWTTrustEngine(credResolver, joseObjectCredResolver);
         
-        final CriteriaSet criteria = new CriteriaSet();
-        criteria.add(new UsageCriterion(UsageType.SIGNING));
-        
         // This is a crafted JWS (from jwt_tool) using the public RSA key bits to sign a MAC.
         // The server *might* if vulnerable valid it it using the RSA public
         // key it has using the a MAC validator.
@@ -238,8 +257,6 @@ public class ExplicitKeySignedJWTTrustEngineTest {
     @Test
     public void testValid_WithInlineJWK() throws JOSEException, SecurityException {       
         
-        final CriteriaSet criteria = new CriteriaSet();
-        criteria.add(new UsageCriterion(UsageType.SIGNING));
         final var valid = engine.validate(createECSignedJWTWithInlineJWK(key, key.getKeyID(), JWSAlgorithm.ES256, 
                 "https://op.example.com/", "https://rp.example.com"),
                 criteria);
@@ -263,9 +280,6 @@ public class ExplicitKeySignedJWTTrustEngineTest {
     @Test
     public void testInvalid_WithUntrustedInlineJWK_CVE_2018_0114() throws JOSEException, SecurityException {
         
-        final CriteriaSet criteria = new CriteriaSet();
-        criteria.add(new UsageCriterion(UsageType.SIGNING));
-        
         // Create a JWK which is different than that pulled back from the resolver. Is not trusted.
         final ECKey keyToUse = new ECKeyGenerator(Curve.P_256).keyID("123").generate();
         
@@ -281,23 +295,11 @@ public class ExplicitKeySignedJWTTrustEngineTest {
     public void testValid_WithInlineJKU() throws JOSEException, SecurityException, URISyntaxException { 
         
         // Create a new resolver which does not resolve any creds, the JKU ones need to be resolved.
-        credResolver = new CredentialResolver() {
-
-            @Override
-            public Credential resolveSingle(final CriteriaSet criteria) throws ResolverException {
-                return null;
-            }
-
-            @Override
-            public Iterable<Credential> resolve(final CriteriaSet criteria) throws ResolverException {
-                return Collections.emptyList();
-            }
-        };
-        engine = new ExplicitKeySignedJWTTrustEngine(credResolver, joseObjectCredResolver);
         
+        credResolver = cs -> null;
        
-        final CriteriaSet criteria = new CriteriaSet();
-        criteria.add(new UsageCriterion(UsageType.SIGNING));
+        engine = new ExplicitKeySignedJWTTrustEngine(credResolver, joseObjectCredResolver);
+        
         final var valid = engine.validate(createECSignedJWTWithJKU(key, key.getKeyID(), 
                 new URI("https://op.example.com/keys"), JWSAlgorithm.ES256, 
                 "https://op.example.com/", "https://rp.example.com"),
@@ -309,23 +311,9 @@ public class ExplicitKeySignedJWTTrustEngineTest {
     public void testInvalid_InlineJWKWrongKid() throws JOSEException, SecurityException {
         
         // Create a new resolver which does not resolve any creds, the kid JOSE headers are different
-        // than the one in the JWK, and should fail.
-        credResolver = new CredentialResolver() {
-
-            @Override
-            public Credential resolveSingle(final CriteriaSet criteria) throws ResolverException {
-                return null;
-            }
-
-            @Override
-            public Iterable<Credential> resolve(final CriteriaSet criteria) throws ResolverException {
-                return Collections.emptyList();
-            }
-        };
-        engine = new ExplicitKeySignedJWTTrustEngine(credResolver, joseObjectCredResolver);
+        // than the one in the JWK, and should fail.        
+        engine = new ExplicitKeySignedJWTTrustEngine(new MockEmptyListCredentialResolver(), joseObjectCredResolver);
         
-        final CriteriaSet criteria = new CriteriaSet();
-        criteria.add(new UsageCriterion(UsageType.SIGNING));
         final var valid = engine.validate(createECSignedJWTWithInlineJWK(key, "WRONG-KID", JWSAlgorithm.ES256, 
                 "https://op.example.com/", "https://rp.example.com"),
                 criteria);
@@ -335,8 +323,6 @@ public class ExplicitKeySignedJWTTrustEngineTest {
     @Test
     public void testInvalid_InlineJWKInvalidSignature() throws JOSEException, SecurityException {
         
-        final CriteriaSet criteria = new CriteriaSet();
-        criteria.add(new UsageCriterion(UsageType.SIGNING));
         final var valid = engine.validate(createECSignedJWTWithDifferentInlineJWK(key, key.getKeyID(),JWSAlgorithm.ES256,
                 // A new signing key, different to the one described in the header
                 new ECKeyGenerator(Curve.P_256).keyID("new").generate(),
diff --git a/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/MockEmptyListCredentialResolver.java b/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/MockEmptyListCredentialResolver.java
new file mode 100644
index 0000000..c30434e
--- /dev/null
+++ b/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/MockEmptyListCredentialResolver.java
@@ -0,0 +1,28 @@
+
+package net.shibboleth.oidc.security.impl;
+
+import java.util.Collections;
+
+import org.opensaml.security.credential.Credential;
+import org.opensaml.security.credential.CredentialResolver;
+
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+/** 
+ * A mock version of a credential resolver that returns an empty list, for quick injection into test methods that 
+ * need it.
+ */
+public class MockEmptyListCredentialResolver implements CredentialResolver {
+
+    @Override
+    public Iterable<Credential> resolve(final CriteriaSet criteria) throws ResolverException {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public Credential resolveSingle(final CriteriaSet criteria) throws ResolverException{
+        return null;
+    };
+
+}
diff --git a/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/MockFunctionalCredentialResolver.java b/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/MockFunctionalCredentialResolver.java
new file mode 100644
index 0000000..3f213c1
--- /dev/null
+++ b/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/MockFunctionalCredentialResolver.java
@@ -0,0 +1,24 @@
+
+package net.shibboleth.oidc.security.impl;
+
+import java.util.List;
+
+import org.opensaml.security.credential.Credential;
+import org.opensaml.security.credential.CredentialResolver;
+
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+/** A mock functional version of a credential resolver, for quick injection into test methods that need it.*/
+ at FunctionalInterface
+public interface MockFunctionalCredentialResolver extends CredentialResolver{
+
+    @Override
+    public default Iterable<Credential> resolve(final CriteriaSet criteria) throws ResolverException {
+        return List.of(resolveSingle(criteria));
+    }
+
+    @Override
+    public Credential resolveSingle(final CriteriaSet criteria) throws ResolverException;
+
+}

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


More information about the commits mailing list