[java-oidc-common] branch main updated: JCOMOIDC-41 - Move OIDC Signature Validation resolvers and parameter classes to commons
Henri Mikkonen
henri.mikkonen at iki.fi
Fri Jan 27 15:27:00 UTC 2023
This is an automated email from the git hooks/post-receive script.
hjmikkon 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=a07f33a6a226a6d52a4ce2d230bf1833ea8d5995
The following commit(s) were added to refs/heads/main by this push:
new a07f33a JCOMOIDC-41 - Move OIDC Signature Validation resolvers and parameter classes to commons
a07f33a is described below
commit a07f33a6a226a6d52a4ce2d230bf1833ea8d5995
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Jan 27 17:25:54 2023 +0200
JCOMOIDC-41 - Move OIDC Signature Validation resolvers and parameter classes to commons
https://shibboleth.atlassian.net/browse/JCOMOIDC-41
Extended signature signing and validation to honor algorithm set in the client metadata.
---
.../impl/ClientInformationJWTTrustEngine.java | 134 ++++++++++
...ormationSignatureSigningParametersResolver.java | 128 +++++++++
.../impl/ClientInformationJWTTrustEngineTest.java | 286 +++++++++++++++++++++
.../impl/ExplicitKeySignedJWTTrustEngineTest.java | 12 +-
4 files changed, 554 insertions(+), 6 deletions(-)
diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/ClientInformationJWTTrustEngine.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/ClientInformationJWTTrustEngine.java
new file mode 100644
index 0000000..49037e9
--- /dev/null
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/ClientInformationJWTTrustEngine.java
@@ -0,0 +1,134 @@
+/*
+ * 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.impl;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.security.SecurityException;
+import org.opensaml.security.credential.CredentialResolver;
+import org.opensaml.security.trust.TrustedCredentialTrustEngine;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.nimbusds.jose.JOSEObject;
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
+
+import net.shibboleth.oidc.security.credential.JOSEObjectCredentialResolver;
+import net.shibboleth.oidc.security.jose.criterion.ClientInformationCriterion;
+import net.shibboleth.utilities.java.support.annotation.ParameterName;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+
+/**
+ * An implementation of {@link org.opensaml.xmlsec.signature.support.SignatureTrustEngine} which evaluates the validity
+ * and trustworthiness of JWT signatures.
+ *
+ * <p>
+ * This extends {@link ExplicitKeySignedJWTTrustEngine} by adding a configurable lookup strategy for the signature
+ * algorithm that must be used in the incoming token. Also a default value can be set if the function returns no
+ * value. If neither function is returning value nor the default value is set, then any signature accepted by the
+ * parent class is accepted.
+ * </p>
+ */
+public class ClientInformationJWTTrustEngine extends ExplicitKeySignedJWTTrustEngine
+ implements TrustedCredentialTrustEngine<SignedJWT> {
+
+ /** Class logger. */
+ private final Logger log = LoggerFactory.getLogger(ClientInformationJWTTrustEngine.class);
+
+ /** A lookup function for the signature algorithm in the client metadata. */
+ @Nonnull private final Function<OIDCClientInformation, String> signatureAlgorithmLookupStrategy;
+
+ /** The default algorithm value used if lookup strategy returned null. */
+ @Nullable private final String defaultAlgorithmValue;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param resolver credential resolver used to resolve trusted credentials.
+ * @param joseObjectResolver resolver which resolve credentials from the headers of a {@link JOSEObject} instance.
+ * @param strategy lookup strategy for the signature algorithm in the client metadata.
+ * @param defaultValue the default signature algorithm value.
+ */
+ public ClientInformationJWTTrustEngine(@Nonnull final @ParameterName(name="resolver") CredentialResolver resolver,
+ @Nonnull final @ParameterName(name="JOSEObjectResolver") JOSEObjectCredentialResolver joseObjectResolver,
+ @Nonnull @ParameterName(name="signatureAlgorithmLookupStrategy")
+ final Function<OIDCClientInformation, String> strategy,
+ @Nullable @ParameterName(name = "defaultAlgorithmValue") final String defaultValue) {
+ super(resolver, joseObjectResolver);
+ signatureAlgorithmLookupStrategy = Constraint.isNotNull(strategy, "Signature algorithm lookup cannot be null");
+ defaultAlgorithmValue = StringSupport.trimOrNull(defaultValue);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doValidate(@Nonnull final SignedJWT signedJWT, @Nonnull final CriteriaSet trustBasisCriteria)
+ throws SecurityException {
+ if (super.doValidate(signedJWT, trustBasisCriteria)) {
+ final String tokenAlgorithm = signedJWT.getHeader().getAlgorithm().getName();
+ final String expectedAlgorithm;
+ if (trustBasisCriteria.contains(ClientInformationCriterion.class)) {
+ expectedAlgorithm = getExpectedAlgorithm(trustBasisCriteria.get(ClientInformationCriterion.class));
+ } else {
+ log.debug("No client information given, using default value {}", defaultAlgorithmValue);
+ expectedAlgorithm = defaultAlgorithmValue;
+ }
+ if (expectedAlgorithm == null) {
+ log.debug("No expected algorithm defined, accepting {} from the token", tokenAlgorithm);
+ return true;
+ }
+ if (tokenAlgorithm.equals(expectedAlgorithm)) {
+ log.debug("The algorithnm specified in the token was expected {}", tokenAlgorithm);
+ return true;
+ }
+ log.warn("The algorithnm specified in the token {} was not expected {}", tokenAlgorithm, expectedAlgorithm);
+ return false;
+ }
+ return false;
+ }
+
+ /**
+ * Fetches the expected signature algorithm from the {@link OIDCClientInformation}.
+ *
+ * @param criterion criterion containing the client information/metadata.
+ * @return the expected algorithm value.
+ */
+ @Nullable protected String getExpectedAlgorithm(@Nonnull final ClientInformationCriterion criterion) {
+ final OIDCClientInformation metadata = criterion.getOidcClientInformation();
+ if (metadata != null) {
+ final String storedAlgorithm = signatureAlgorithmLookupStrategy.apply(metadata);
+ if (StringSupport.trimOrNull(storedAlgorithm) == null) {
+ log.debug("No algorithm value specified in metadata, using default value {}", defaultAlgorithmValue);
+ return defaultAlgorithmValue;
+ } else {
+ log.debug("Found the expected algorithm from metadata: {}", storedAlgorithm);
+ return storedAlgorithm;
+ }
+ } else {
+ log.debug("No client information given, using default value {}", defaultAlgorithmValue);
+ return defaultAlgorithmValue;
+ }
+
+ }
+}
diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jose/impl/ClientInformationSignatureSigningParametersResolver.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jose/impl/ClientInformationSignatureSigningParametersResolver.java
new file mode 100644
index 0000000..564f1a3
--- /dev/null
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jose/impl/ClientInformationSignatureSigningParametersResolver.java
@@ -0,0 +1,128 @@
+/*
+ * 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 java.util.Collections;
+import java.util.List;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
+
+import net.shibboleth.oidc.security.jose.SignatureSigningParametersResolver;
+import net.shibboleth.oidc.security.jose.criterion.ClientInformationCriterion;
+import net.shibboleth.utilities.java.support.annotation.ParameterName;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+
+/**
+ * An implementation of an {@link SignatureSigningParametersResolver} that extends the {@link
+ * BasicSignatureSigningParametersResolver} functionality by adding a configurable lookup strategy for fetching
+ * the desired algorithm value from {@link OIDCClientInformation}. It is expected to be found from the criteria set.
+ */
+public class ClientInformationSignatureSigningParametersResolver
+ extends BasicSignatureSigningParametersResolver
+ implements SignatureSigningParametersResolver {
+
+ /** Class logger.*/
+ private final Logger log = LoggerFactory.getLogger(ClientInformationSignatureSigningParametersResolver.class);
+
+ /** A lookup function for the signature algorithm. */
+ private final Function<OIDCClientInformation, String> signatureAlgorithmLookupStrategy;
+
+ /** The default algorithm value used if lookup strategy returned null. */
+ private final String defaultAlgorithmValue;
+
+ /**
+ * Constructor.
+ *
+ * @param strategy a lookup function for the signature algorithm
+ * @param defaultValue the default algorithm value used if lookup strategy returned null
+ */
+ public ClientInformationSignatureSigningParametersResolver(
+ @Nonnull @ParameterName(name="signatureAlgorithmLookupStrategy")
+ final Function<OIDCClientInformation, String> strategy,
+ @Nullable @ParameterName(name = "defaultAlgorithmValue") final String defaultValue) {
+ super();
+ signatureAlgorithmLookupStrategy = Constraint.isNotNull(strategy, "The signature algorithm lookup strategy "
+ + "can not be null");
+ defaultAlgorithmValue = defaultValue;
+ }
+
+
+ /**
+ * Get the effective list of signature algorithm URIs to consider, including application of
+ * include/exclude policy.
+ *
+ * @param criteria the input criteria being evaluated
+ * @param includeExcludePredicate the include/exclude predicate to use
+ * @return the list of effective algorithm URIs
+ */
+ @Override
+ @Nonnull protected List<String> getEffectiveSignatureAlgorithms(@Nonnull final CriteriaSet criteria,
+ @Nonnull final Predicate<String> includeExcludePredicate) {
+ final List<String> accumulator = super.getEffectiveSignatureAlgorithms(criteria, includeExcludePredicate);
+ OIDCClientInformation metadata = null;
+ if (criteria.contains(ClientInformationCriterion.class)) {
+ metadata = criteria.get(ClientInformationCriterion.class).getOidcClientInformation();
+ }
+ if (metadata == null) {
+ if (StringSupport.trimOrNull(defaultAlgorithmValue) != null) {
+ log.debug("No client information found from the criteria set, using default");
+ return convertIntoListIfEnabled(defaultAlgorithmValue, accumulator);
+ }
+ log.error("No client information found from the criteria set");
+ return Collections.emptyList();
+ }
+ final String algorithm = signatureAlgorithmLookupStrategy.apply(metadata);
+ if (StringSupport.trimOrNull(algorithm) == null) {
+ if (StringSupport.trimOrNull(defaultAlgorithmValue) != null) {
+ log.debug("No signature algorithm specified in the metadata, using default");
+ return convertIntoListIfEnabled(defaultAlgorithmValue, accumulator);
+ }
+ log.error("No signature algorith or default value specified, returning empty list");
+ return Collections.emptyList();
+ }
+ return convertIntoListIfEnabled(algorithm, accumulator);
+ }
+
+ /**
+ * Returns the given algorithm in a {@link List} if it was enabled in the list of enabled algorithms. An empty
+ * list is returned if the algorithm was not enabled.
+ *
+ * @param algorithm the algorithm to be checked against the list
+ * @param enabledAlgorithms the list of enabled algorithms
+ * @return the given algorithm as list if it was enabled, or an empty list if not
+ */
+ @Nonnull protected List<String> convertIntoListIfEnabled(@Nonnull final String algorithm,
+ @Nonnull final List<String> enabledAlgorithms) {
+ if (enabledAlgorithms.contains(algorithm)) {
+ return List.of(algorithm);
+ } else {
+ log.warn("The algorithm {} is not enabled, returning empty list");
+ return Collections.emptyList();
+ }
+ }
+}
diff --git a/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/ClientInformationJWTTrustEngineTest.java b/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/ClientInformationJWTTrustEngineTest.java
new file mode 100644
index 0000000..57c8fae
--- /dev/null
+++ b/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/ClientInformationJWTTrustEngineTest.java
@@ -0,0 +1,286 @@
+/*
+ * 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.impl;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.security.KeyException;
+import java.util.List;
+import java.util.function.Function;
+
+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.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.ECKey;
+import com.nimbusds.jose.jwk.gen.ECKeyGenerator;
+import com.nimbusds.oauth2.sdk.id.ClientID;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
+
+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.criterion.ClientInformationCriterion;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+/**
+ * Tests for the {@link ClientInformationJWTTrustEngine}.
+ */
+public class ClientInformationJWTTrustEngineTest {
+
+ private ClientInformationJWTTrustEngine engine;
+
+ private ECKey key;
+
+ /** The client_secret.*/
+ private static final String CLIENT_SECRET = "Xp2s5v8y/B?E(H+MbQeThWmYq3t6w9z$";
+
+ @BeforeMethod
+ public void setup() throws JOSEException {
+ setup(null, info -> "RS256");
+ }
+
+ public void setup(final String defaultAlgValue) throws JOSEException {
+ setup(defaultAlgValue, info -> "RS256");
+ }
+
+ public void setup(final String defaultAlgValue, Function<OIDCClientInformation, String> sigAlgLookup)
+ throws JOSEException {
+ key = new ECKeyGenerator(Curve.P_256).keyID("123").generate();
+
+ final CredentialResolver 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));
+ }
+ };
+
+ final JOSEObjectCredentialResolver joseObjectCredResolver = new BasicJOSEObjectCredentialResolver();
+
+ engine = new ClientInformationJWTTrustEngine(credResolver, joseObjectCredResolver, sigAlgLookup,
+ defaultAlgValue);
+ }
+
+ public void setupSymmetric(final String defaultAlgValue, Function<OIDCClientInformation, String> sigAlgLookup) {
+ final CredentialResolver 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;
+ }
+ }
+
+ @Override
+ public Iterable<Credential> resolve(final CriteriaSet criteria) throws ResolverException {
+ return List.of(resolveSingle(criteria));
+ }
+ };
+
+ final JOSEObjectCredentialResolver joseObjectCredResolver = new BasicJOSEObjectCredentialResolver();
+
+ engine = new ClientInformationJWTTrustEngine(credResolver, joseObjectCredResolver, sigAlgLookup,
+ defaultAlgValue);
+ }
+
+ @Test
+ public void testValid_WithTrustedCredential_NoValueNorDefault() throws JOSEException, SecurityException {
+
+ final CriteriaSet criteria = new CriteriaSet();
+ criteria.add(new UsageCriterion(UsageType.SIGNING));
+
+ final var valid = engine.validate(ExplicitKeySignedJWTTrustEngineTest.createECSignedJWT(key, key.getKeyID(),
+ JWSAlgorithm.ES256, "https://op.example.com/", "https://rp.example.com"), criteria);
+ assertTrue(valid);
+ }
+
+ @Test
+ public void testValid_WithTrustedCredential_NoValueDefaultMatch() throws JOSEException, SecurityException {
+ setup(JWSAlgorithm.ES256.getName());
+ final CriteriaSet criteria = new CriteriaSet();
+ criteria.add(new UsageCriterion(UsageType.SIGNING));
+
+ final var valid = engine.validate(ExplicitKeySignedJWTTrustEngineTest.createECSignedJWT(key, key.getKeyID(),
+ JWSAlgorithm.ES256,
+ "https://op.example.com/", "https://rp.example.com"),
+ criteria);
+ assertTrue(valid);
+ }
+
+ @Test
+ public void testValid_WithTrustedCredential_NoValueDefaultNotMatching() throws JOSEException, SecurityException {
+ setup(JWSAlgorithm.ES512.getName());
+ final CriteriaSet criteria = new CriteriaSet();
+ criteria.add(new UsageCriterion(UsageType.SIGNING));
+
+ final var valid = engine.validate(ExplicitKeySignedJWTTrustEngineTest.createECSignedJWT(key, key.getKeyID(),
+ JWSAlgorithm.ES256,
+ "https://op.example.com/", "https://rp.example.com"),
+ criteria);
+ assertFalse(valid);
+ }
+
+ @Test
+ public void testValid_WithTrustedCredential_ValueMatch() throws JOSEException, SecurityException {
+ setup(null, info -> "ES256");
+ final CriteriaSet criteria = new CriteriaSet();
+ criteria.add(buildClientInformationCriterion());
+ criteria.add(new UsageCriterion(UsageType.SIGNING));
+
+ final var valid = engine.validate(ExplicitKeySignedJWTTrustEngineTest.createECSignedJWT(key, key.getKeyID(),
+ JWSAlgorithm.ES256,
+ "https://op.example.com/", "https://rp.example.com"),
+ criteria);
+ assertTrue(valid);
+ }
+
+ @Test
+ public void testValid_WithTrustedCredential_ValueNotMatching() throws JOSEException, SecurityException {
+ setup(null, info -> "ES512");
+ final CriteriaSet criteria = new CriteriaSet();
+ criteria.add(buildClientInformationCriterion());
+ criteria.add(new UsageCriterion(UsageType.SIGNING));
+
+ final var valid = engine.validate(ExplicitKeySignedJWTTrustEngineTest.createECSignedJWT(key, key.getKeyID(),
+ JWSAlgorithm.ES256,
+ "https://op.example.com/", "https://rp.example.com"),
+ criteria);
+ assertFalse(valid);
+ }
+
+ @Test
+ public void testValid_WithSymmetricKeyCredential_NoValueNorDefault() throws JOSEException, SecurityException {
+ setupSymmetric(null, info -> "HS256");
+
+ final CriteriaSet criteria = new CriteriaSet();
+ criteria.add(new UsageCriterion(UsageType.SIGNING));
+
+ final var valid = engine.validate(ExplicitKeySignedJWTTrustEngineTest.createMACSignedJWT(CLIENT_SECRET,
+ key.getKeyID(), JWSAlgorithm.HS256,
+ "https://op.example.com/", "https://rp.example.com"),
+ criteria);
+ assertTrue(valid);
+ }
+
+ @Test
+ public void testValid_WithSymmetricKeyCredential_NoValueDefaultMatching() throws JOSEException, SecurityException {
+ setupSymmetric("HS256", info -> "HS256");
+
+ final CriteriaSet criteria = new CriteriaSet();
+ criteria.add(new UsageCriterion(UsageType.SIGNING));
+
+ final var valid = engine.validate(ExplicitKeySignedJWTTrustEngineTest.createMACSignedJWT(CLIENT_SECRET,
+ key.getKeyID(), JWSAlgorithm.HS256,
+ "https://op.example.com/", "https://rp.example.com"),
+ criteria);
+ assertTrue(valid);
+ }
+
+ @Test
+ public void testValid_WithSymmetricKeyCredential_NoValueDefaultNotMatching() throws JOSEException,
+ SecurityException {
+ setupSymmetric("HS512", info -> "HS512");
+
+ final CriteriaSet criteria = new CriteriaSet();
+ criteria.add(new UsageCriterion(UsageType.SIGNING));
+
+ final var valid = engine.validate(ExplicitKeySignedJWTTrustEngineTest.createMACSignedJWT(CLIENT_SECRET,
+ key.getKeyID(), JWSAlgorithm.HS256,
+ "https://op.example.com/", "https://rp.example.com"),
+ criteria);
+ assertFalse(valid);
+ }
+
+ @Test
+ public void testValid_WithSymmetricKeyCredential_ValueMatch() throws JOSEException, SecurityException {
+ setupSymmetric(null, info -> "HS256");
+
+ final CriteriaSet criteria = new CriteriaSet();
+ criteria.add(buildClientInformationCriterion());
+ criteria.add(new UsageCriterion(UsageType.SIGNING));
+
+ final var valid = engine.validate(ExplicitKeySignedJWTTrustEngineTest.createMACSignedJWT(CLIENT_SECRET,
+ key.getKeyID(), JWSAlgorithm.HS256,
+ "https://op.example.com/", "https://rp.example.com"),
+ criteria);
+ assertTrue(valid);
+ }
+
+ @Test
+ public void testValid_WithSymmetricKeyCredential_ValueNotNatching() throws JOSEException, SecurityException {
+ setupSymmetric(null, info -> "HS512");
+
+ final CriteriaSet criteria = new CriteriaSet();
+ criteria.add(buildClientInformationCriterion());
+ criteria.add(new UsageCriterion(UsageType.SIGNING));
+
+ final var valid = engine.validate(ExplicitKeySignedJWTTrustEngineTest.createMACSignedJWT(CLIENT_SECRET,
+ key.getKeyID(), JWSAlgorithm.HS256,
+ "https://op.example.com/", "https://rp.example.com"),
+ criteria);
+ assertFalse(valid);
+ }
+
+ @Test
+ public void testValid_WithInlineJWK() throws JOSEException, SecurityException {
+
+ final CriteriaSet criteria = new CriteriaSet();
+ criteria.add(new UsageCriterion(UsageType.SIGNING));
+ final var valid = engine.validate(ExplicitKeySignedJWTTrustEngineTest.createECSignedJWTWithInlineJWK(key,
+ key.getKeyID(), JWSAlgorithm.ES256,
+ "https://op.example.com/", "https://rp.example.com"),
+ criteria);
+ assertTrue(valid);
+ }
+
+ protected static ClientInformationCriterion buildClientInformationCriterion() {
+ return new ClientInformationCriterion(new OIDCClientInformation(new ClientID("mockClient"),
+ new OIDCClientMetadata()));
+ }
+
+}
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 5112c6a..9701fa9 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
@@ -353,7 +353,7 @@ public class ExplicitKeySignedJWTTrustEngineTest {
*
* @return the constructed claims set
*/
- private JWTClaimsSet buildStandardClaims( final String issuer, final String audience) {
+ protected static JWTClaimsSet buildStandardClaims( final String issuer, final String audience) {
return new JWTClaimsSet.Builder()
.issuer(issuer)
@@ -376,7 +376,7 @@ public class ExplicitKeySignedJWTTrustEngineTest {
* @return the signed JWT
* @throws JOSEException on error.
*/
- private SignedJWT createECSignedJWT(final ECKey key, final String keyId,
+ protected static SignedJWT createECSignedJWT(final ECKey key, final String keyId,
final JWSAlgorithm algo, final String issuer,
final String audience) throws JOSEException {
@@ -403,7 +403,7 @@ public class ExplicitKeySignedJWTTrustEngineTest {
* @return the signed JWT
* @throws JOSEException on error.
*/
- private SignedJWT createMACSignedJWT(final String key, final String keyId,
+ protected static SignedJWT createMACSignedJWT(final String key, final String keyId,
final JWSAlgorithm algo, final String issuer,
final String audience) throws JOSEException {
@@ -430,7 +430,7 @@ public class ExplicitKeySignedJWTTrustEngineTest {
* @return the signed JWT
* @throws JOSEException on error.
*/
- private SignedJWT createECSignedJWTWithJKU(final ECKey key, final String keyId,
+ protected static SignedJWT createECSignedJWTWithJKU(final ECKey key, final String keyId,
final URI jku, final JWSAlgorithm algo, final String issuer,
final String audience) throws JOSEException, URISyntaxException {
@@ -457,7 +457,7 @@ public class ExplicitKeySignedJWTTrustEngineTest {
* @return the signed JWT
* @throws JOSEException on error.
*/
- private SignedJWT createECSignedJWTWithInlineJWK(final ECKey key, final String keyId,
+ protected static SignedJWT createECSignedJWTWithInlineJWK(final ECKey key, final String keyId,
final JWSAlgorithm algo, final String issuer,
final String audience) throws JOSEException {
@@ -486,7 +486,7 @@ public class ExplicitKeySignedJWTTrustEngineTest {
* @return the signed JWT
* @throws JOSEException on error.
*/
- private SignedJWT createECSignedJWTWithDifferentInlineJWK(final ECKey key, final String keyId,
+ protected static SignedJWT createECSignedJWTWithDifferentInlineJWK(final ECKey key, final String keyId,
final JWSAlgorithm algo, final ECKey signingKey, final String issuer,
final String audience) throws JOSEException {
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list