[java-oidc-common] branch main updated: Add relying party signing resolver test from RP

Phil Smart philip.smart at jisc.ac.uk
Wed Apr 26 13:32:59 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=55b9866e6ed1b07406b4bea351f0cbd472283740

The following commit(s) were added to refs/heads/main by this push:
     new 55b9866  Add relying party signing resolver test from RP
55b9866 is described below

commit 55b9866e6ed1b07406b4bea351f0cbd472283740
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Wed Apr 26 14:32:56 2023 +0100

    Add relying party signing resolver test from RP
    
     - Move in the test from the RP and update accordingly
---
 oidc-common-crypto-impl/pom.xml                    |   5 +
 .../RelyingPartySigningParametersResolver.java     |   1 -
 .../RelyingPartySigningParametersResolverTest.java | 327 +++++++++++++++++++++
 3 files changed, 332 insertions(+), 1 deletion(-)

diff --git a/oidc-common-crypto-impl/pom.xml b/oidc-common-crypto-impl/pom.xml
index 7a4ea09..4ee90be 100644
--- a/oidc-common-crypto-impl/pom.xml
+++ b/oidc-common-crypto-impl/pom.xml
@@ -29,6 +29,11 @@
             <artifactId>oidc-common-profile-api</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>oidc-common-profile-impl</artifactId>
+            <scope>provided</scope>
+        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>oidc-common-crypto-api</artifactId>
diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jose/impl/RelyingPartySigningParametersResolver.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jose/impl/RelyingPartySigningParametersResolver.java
index 572b948..cdbee16 100644
--- a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jose/impl/RelyingPartySigningParametersResolver.java
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jose/impl/RelyingPartySigningParametersResolver.java
@@ -37,7 +37,6 @@ import net.shibboleth.oidc.security.credential.ClientSecretCredential;
 import net.shibboleth.oidc.security.jose.SignatureSigningParameters;
 import net.shibboleth.oidc.security.jose.criterion.ClientSecretCredentialCriterion;
 import net.shibboleth.oidc.security.jose.criterion.ProviderMetadataCriterion;
-import net.shibboleth.oidc.security.jose.impl.BasicSignatureSigningParametersResolver;
 import net.shibboleth.utilities.java.support.logic.Constraint;
 import net.shibboleth.utilities.java.support.logic.FunctionSupport;
 import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
diff --git a/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/jose/impl/RelyingPartySigningParametersResolverTest.java b/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/jose/impl/RelyingPartySigningParametersResolverTest.java
new file mode 100644
index 0000000..af1d57d
--- /dev/null
+++ b/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/jose/impl/RelyingPartySigningParametersResolverTest.java
@@ -0,0 +1,327 @@
+/*
+ * 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.impl;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.time.Duration;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.opensaml.core.config.InitializationException;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.security.credential.UsageType;
+import org.opensaml.xmlsec.config.GlobalAlgorithmRegistryInitializer;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.jwk.AsymmetricJWK;
+import com.nimbusds.jose.jwk.Curve;
+import com.nimbusds.jose.jwk.JWK;
+import com.nimbusds.jose.jwk.KeyUse;
+import com.nimbusds.jose.jwk.gen.ECKeyGenerator;
+import com.nimbusds.jose.jwk.gen.RSAKeyGenerator;
+import com.nimbusds.oauth2.sdk.id.Issuer;
+import com.nimbusds.openid.connect.sdk.SubjectType;
+import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
+
+import net.shibboleth.idp.profile.context.RelyingPartyContext;
+import net.shibboleth.idp.relyingparty.RelyingPartyConfiguration;
+import net.shibboleth.oidc.jwa.support.SignatureConstants;
+import net.shibboleth.oidc.profile.config.impl.DefaultOIDCAuthorizationConfiguration;
+import net.shibboleth.oidc.security.credential.BasicExpiringJWKCredential;
+import net.shibboleth.oidc.security.credential.DefaultClientSecretCredential;
+import net.shibboleth.oidc.security.credential.JWKCredential;
+import net.shibboleth.oidc.security.jose.SignatureSigningParameters;
+import net.shibboleth.oidc.security.jose.criterion.ClientSecretCredentialCriterion;
+import net.shibboleth.oidc.security.jose.criterion.ProviderMetadataCriterion;
+import net.shibboleth.oidc.security.jose.criterion.SignatureSigningConfigurationCriterion;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+/** Tests for RelyingPartyProxySigningParametersResolver.*/
+public class RelyingPartySigningParametersResolverTest {
+    
+    /** A 256 bit client_secret.*/
+    private static final String CLIENT_SECRET_256 = "!A%D*G-KaPdSgVkYp3s6v8y/B?E(H+Mb";
+    
+    private RelyingPartySigningParametersResolver resolver;
+    
+    private RelyingPartyContext rpc;
+    
+    /** The profile request context to use.*/
+    protected ProfileRequestContext prc;
+    
+    private DefaultOIDCAuthorizationConfiguration oidcAuthzConfig;   
+    
+    @BeforeMethod
+    public void setup() throws Exception {   
+        prc = new ProfileRequestContext();
+        resolver = new RelyingPartySigningParametersResolver(); 
+        rpc = prc.getSubcontext(RelyingPartyContext.class, true); 
+        oidcAuthzConfig = new DefaultOIDCAuthorizationConfiguration();
+        final RelyingPartyConfiguration rpConfig = new RelyingPartyConfiguration();
+        rpc.setProfileConfig(oidcAuthzConfig);
+        rpc.setConfiguration(rpConfig);
+
+        //resolver.setAlgorithmRegistry(new AlgorithmRegistry());
+        resolver.setProviderMetadataAlgorithmLookupStrategy(
+                m -> m.getRequestObjectJWSAlgs().stream().map(JWSAlgorithm::getName).collect(Collectors.toList()));
+        
+      //Create an algorithm registry here, as opensaml init will not take place for these tests      
+        try {
+            final GlobalAlgorithmRegistryInitializer gar = new GlobalAlgorithmRegistryInitializer();
+            gar.init();
+        } catch (final InitializationException e) {           
+            fail();
+        }
+    }
+    
+    
+    @Test
+    public void testResolveSuccess_StaticCredentials() throws ResolverException {
+        final CriteriaSet criteria = buildCriteria(List.of(SignatureConstants.ALGO_ID_SIGNATURE_HS_256));
+        criteria.add(new ClientSecretCredentialCriterion(
+                new DefaultClientSecretCredential(CLIENT_SECRET_256)));
+        final Iterable<SignatureSigningParameters> params = resolver.resolve(criteria);
+        assertNotNull(params);
+        assertTrue(params.iterator().hasNext());
+        assertNotNull(params.iterator().next().getSigningCredential());
+        assertNotNull(params.iterator().next().getSigningCredential().getSecretKey());
+    }
+    
+    @Test
+    public void testResolveFail_StaticCredentials_UnsupportedMethod() throws ResolverException {
+        final CriteriaSet criteria = buildCriteria(List.of(SignatureConstants.ALGO_ID_SIGNATURE_RS_256));
+        criteria.add(new ClientSecretCredentialCriterion(
+                new DefaultClientSecretCredential(CLIENT_SECRET_256)));
+        final Iterable<SignatureSigningParameters> params = resolver.resolve(criteria);
+        assertNotNull(params);
+        assertFalse(params.iterator().hasNext());
+    }
+    
+    @Test
+    public void testResolveSuccess_StaticCredentials_ConfigSupportsOne() throws ResolverException {
+        final CriteriaSet criteria = buildCriteria(List.of(SignatureConstants.ALGO_ID_SIGNATURE_RS_256, 
+                SignatureConstants.ALGO_ID_SIGNATURE_HS_256));
+        criteria.add(new ClientSecretCredentialCriterion(
+                new DefaultClientSecretCredential(CLIENT_SECRET_256)));;
+        final Iterable<SignatureSigningParameters> params = resolver.resolve(criteria);
+        assertNotNull(params);
+        assertTrue(params.iterator().hasNext());
+        assertNotNull(params.iterator().next().getSigningCredential());
+        assertNotNull(params.iterator().next().getSigningCredential().getSecretKey());
+    }
+    
+    @Test
+    public void testResolveSuccess_StaticCredentials_OPSupportsOne() throws ResolverException, URISyntaxException {
+        final CriteriaSet criteria = buildCriteria(List.of(SignatureConstants.ALGO_ID_SIGNATURE_RS_256, 
+                SignatureConstants.ALGO_ID_SIGNATURE_HS_256));
+        criteria.add(new ClientSecretCredentialCriterion(
+                new DefaultClientSecretCredential(CLIENT_SECRET_256)));
+        
+        // Now let the OP support one of those which matches the credential
+        final OIDCProviderMetadata metadata = 
+                new OIDCProviderMetadata(new Issuer("test"), List.of(SubjectType.PUBLIC), new URI("nowhere"));
+        metadata.setRequestObjectJWSAlgs(List.of(JWSAlgorithm.HS256));
+        criteria.add(new ProviderMetadataCriterion(metadata));
+        
+        final Iterable<SignatureSigningParameters> params = resolver.resolve(criteria);
+        assertNotNull(params);
+        assertTrue(params.iterator().hasNext());
+        assertNotNull(params.iterator().next().getSigningCredential());
+        assertNotNull(params.iterator().next().getSigningCredential().getSecretKey());
+    }
+    
+    @Test
+    public void testResolveSuccess_StaticCredentials_OPSupportsNone() throws ResolverException, URISyntaxException {
+        final CriteriaSet criteria = buildCriteria(List.of(SignatureConstants.ALGO_ID_SIGNATURE_RS_256, 
+                SignatureConstants.ALGO_ID_SIGNATURE_HS_256));
+        criteria.add(new ClientSecretCredentialCriterion(
+                new DefaultClientSecretCredential(CLIENT_SECRET_256)));
+        
+        // Now let the OP support none of those supported by the config
+        final OIDCProviderMetadata metadata = 
+                new OIDCProviderMetadata(new Issuer("test"), List.of(SubjectType.PUBLIC), new URI("nowhere"));
+        metadata.setRequestObjectJWSAlgs(List.of(JWSAlgorithm.EdDSA));
+        criteria.add(new ProviderMetadataCriterion(metadata));
+        
+        final Iterable<SignatureSigningParameters> params = resolver.resolve(criteria);
+        assertNotNull(params);
+        assertFalse(params.iterator().hasNext());
+    }
+    
+    @Test
+    public void testResolveSuccess_RSACredentials_OPSupportsOne() throws Exception {
+        final CriteriaSet criteria = buildCriteria(List.of(SignatureConstants.ALGO_ID_SIGNATURE_RS_256, 
+                SignatureConstants.ALGO_ID_SIGNATURE_HS_256));
+        
+        // Create the normal client_secret
+        criteria.add(new ClientSecretCredentialCriterion(
+                new DefaultClientSecretCredential(CLIENT_SECRET_256)));
+        
+        // Add an RSA type to the security config
+        final BasicSignatureSigningConfiguration config = 
+                (BasicSignatureSigningConfiguration) 
+                criteria.get(SignatureSigningConfigurationCriterion.class).getConfigurations().get(0);
+        
+        config.setSigningCredentials(List.of(createRSASigningCredential(new RSAKeyGenerator(2048)
+                .keyID("1")
+                .keyUse(KeyUse.SIGNATURE)
+                .generate())));
+        
+        // Now let the OP support one of those which matches one of the credentials
+        final OIDCProviderMetadata metadata = 
+                new OIDCProviderMetadata(new Issuer("test"), List.of(SubjectType.PUBLIC), new URI("nowhere"));
+        metadata.setRequestObjectJWSAlgs(List.of(JWSAlgorithm.RS256));
+        criteria.add(new ProviderMetadataCriterion(metadata));
+        
+        final Iterable<SignatureSigningParameters> params = resolver.resolve(criteria);
+        assertNotNull(params);
+        assertTrue(params.iterator().hasNext());
+        assertNotNull(params.iterator().next().getSigningCredential());
+        assertNotNull(params.iterator().next().getSigningCredential().getPrivateKey());
+        assertTrue(params.iterator().next().getSigningCredential().getPrivateKey() instanceof RSAPrivateKey);
+    }
+   
+    /* Also should preserve alg order from the config.*/
+    @Test
+    public void testResolveSuccess_ECCredentials_OPSupportsTwo() throws Exception {
+        final CriteriaSet criteria = buildCriteria(List.of(SignatureConstants.ALGO_ID_SIGNATURE_RS_256, 
+                SignatureConstants.ALGO_ID_SIGNATURE_HS_256, SignatureConstants.ALGO_ID_SIGNATURE_ES_256));
+        
+        // Create the normal client_secret
+        criteria.add(new ClientSecretCredentialCriterion(
+                new DefaultClientSecretCredential(CLIENT_SECRET_256)));
+        
+        // Add an RSA type to the security config
+        final BasicSignatureSigningConfiguration config = 
+                (BasicSignatureSigningConfiguration) 
+                criteria.get(SignatureSigningConfigurationCriterion.class).getConfigurations().get(0);
+        
+        config.setSigningCredentials(List.of(createRSASigningCredential(
+                new ECKeyGenerator(Curve.P_256).keyID("123").generate())));
+        
+        // Now let the OP support one of those which matches one of the credentials
+        final OIDCProviderMetadata metadata = 
+                new OIDCProviderMetadata(new Issuer("test"), List.of(SubjectType.PUBLIC), new URI("nowhere"));
+        metadata.setRequestObjectJWSAlgs(List.of(JWSAlgorithm.ES256, JWSAlgorithm.RS256));
+        criteria.add(new ProviderMetadataCriterion(metadata));
+        
+        final Iterable<SignatureSigningParameters> params = resolver.resolve(criteria);
+        assertNotNull(params);
+        assertTrue(params.iterator().hasNext());
+        assertNotNull(params.iterator().next().getSigningCredential());
+        assertNotNull(params.iterator().next().getSigningCredential().getPrivateKey());
+        assertTrue(params.iterator().next().getSigningCredential().getPrivateKey() instanceof ECPrivateKey);
+    }
+    
+    @Test
+    public void testResolveFail_AlgorithmExcluded() throws Exception {
+        
+        final CriteriaSet criteria = buildCriteria(List.of(SignatureConstants.ALGO_ID_SIGNATURE_HS_256));
+        
+        // Create the normal client_secret
+        criteria.add(new ClientSecretCredentialCriterion(
+                new DefaultClientSecretCredential(CLIENT_SECRET_256)));
+        
+        final BasicSignatureSigningConfiguration config = 
+                (BasicSignatureSigningConfiguration) 
+                criteria.get(SignatureSigningConfigurationCriterion.class).getConfigurations().get(0);
+        
+        // Explicitly exclude the algorithm
+        config.setExcludedAlgorithms(List.of(SignatureConstants.ALGO_ID_SIGNATURE_HS_256));
+        
+        final OIDCProviderMetadata metadata = 
+                new OIDCProviderMetadata(new Issuer("test"), List.of(SubjectType.PUBLIC), new URI("nowhere"));
+        metadata.setRequestObjectJWSAlgs(List.of(JWSAlgorithm.HS256));
+        criteria.add(new ProviderMetadataCriterion(metadata));
+        
+        final Iterable<SignatureSigningParameters> params = resolver.resolve(criteria);
+        assertNotNull(params);
+        assertFalse(params.iterator().hasNext());
+    }
+    
+    @Test
+    public void testResolveFail_AlgorithmNotInIncludeList() throws Exception {
+        
+        final CriteriaSet criteria = buildCriteria(List.of(SignatureConstants.ALGO_ID_SIGNATURE_HS_256));
+        
+        // Create the normal client_secret
+        criteria.add(new ClientSecretCredentialCriterion(
+                new DefaultClientSecretCredential(CLIENT_SECRET_256)));
+        
+        final BasicSignatureSigningConfiguration config = 
+                (BasicSignatureSigningConfiguration) 
+                criteria.get(SignatureSigningConfigurationCriterion.class).getConfigurations().get(0);
+        
+        // Do not include the algorithm
+        config.setIncludedAlgorithms(List.of(SignatureConstants.ALGO_ID_SIGNATURE_HS_512));
+        
+        final OIDCProviderMetadata metadata = 
+                new OIDCProviderMetadata(new Issuer("test"), List.of(SubjectType.PUBLIC), new URI("nowhere"));
+        metadata.setRequestObjectJWSAlgs(List.of(JWSAlgorithm.HS256));
+        criteria.add(new ProviderMetadataCriterion(metadata));
+        
+        final Iterable<SignatureSigningParameters> params = resolver.resolve(criteria);
+        assertNotNull(params);
+        assertFalse(params.iterator().hasNext());
+    }
+    
+    
+    private CriteriaSet buildCriteria(final List<String> supportedSigningAlgos) {
+        final CriteriaSet crit = new CriteriaSet();
+        final BasicSignatureSigningConfiguration config = new BasicSignatureSigningConfiguration();
+        config.setSignatureAlgorithms(supportedSigningAlgos);
+        crit.add(new SignatureSigningConfigurationCriterion(List.of(config)));
+        return crit;
+    }
+    
+    
+    /**
+     * Create an AsymmetricJWK credential from the given key.
+     * 
+     * @param secret the key to convert to a {@link JWKCredential}.
+     * 
+     * @return the credential
+     * @throws JOSEException 
+     */
+    private JWKCredential createRSASigningCredential(final JWK secret) throws JOSEException {
+        assertTrue(secret instanceof AsymmetricJWK);
+        final BasicExpiringJWKCredential jwkCredential = new BasicExpiringJWKCredential();
+        jwkCredential.setPrivateKey(((AsymmetricJWK)secret).toPrivateKey());
+        jwkCredential.setPublicKey(((AsymmetricJWK)secret).toPublicKey());
+        jwkCredential.setCredentialExpiresAt(Duration.ZERO);
+        jwkCredential.setUsageType(UsageType.SIGNING);
+        
+        jwkCredential.setKid(secret.getKeyID());
+        jwkCredential.getKeyNames().add("mockKey");
+        jwkCredential.setAlgorithm(secret.getAlgorithm());
+        return jwkCredential;
+    }
+
+}

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


More information about the commits mailing list