[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