[java-idp-oidc] branch main updated: JCOMOIDC-41 - Move OIDC Signature Validation resolvers and parameter classes to commons

Henri Mikkonen henri.mikkonen at iki.fi
Thu Feb 2 16:45:07 UTC 2023


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

hjmikkon pushed a commit to branch main
in repository java-idp-oidc.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-oidc.git;a=commit;h=41515237a12ec3069706274c6195c680e631fc88

The following commit(s) were added to refs/heads/main by this push:
     new 41515237 JCOMOIDC-41 - Move OIDC Signature Validation resolvers and parameter classes to commons
41515237 is described below

commit 41515237a12ec3069706274c6195c680e631fc88
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Thu Feb 2 18:44:16 2023 +0200

    JCOMOIDC-41 - Move OIDC Signature Validation resolvers and parameter classes to commons
    
    https://shibboleth.atlassian.net/browse/JCOMOIDC-41
    
    Improved flow tests for signed request objects with varying configurations
---
 .../AbstractOidcClientAuthenticationFlowTest.java  |  24 +-
 .../oidc/op/profile/flow/AbstractOidcFlowTest.java |  94 ++++++-
 .../oidc/op/profile/flow/AuthorizeFlowTest.java    | 312 ++++++++++++++++++++-
 3 files changed, 385 insertions(+), 45 deletions(-)

diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcClientAuthenticationFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcClientAuthenticationFlowTest.java
index 34a73319..bea1af10 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcClientAuthenticationFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcClientAuthenticationFlowTest.java
@@ -19,18 +19,14 @@ package net.shibboleth.idp.plugin.oidc.op.profile.flow;
 
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
 import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
 import java.time.Instant;
 import java.util.Date;
 import java.util.Map;
 
 import org.opensaml.profile.action.EventIds;
 import org.springframework.webflow.executor.FlowExecutionResult;
-import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 import com.nimbusds.jose.JOSEException;
@@ -61,26 +57,10 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
 
     String jwtAud = "http://localhost";
     
-    RSAPrivateKey rsaPrivateKey;
-    RSAPublicKey rsaPublicKey;
-    
     public AbstractOidcClientAuthenticationFlowTest(final String flowId) {
         super(flowId);
     }
 
-    @BeforeClass
-    public void initKeys() throws NoSuchAlgorithmException {
-        final KeyPair keyPair = generateNewKeyPair();
-        rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
-        rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
-    }
-
-    protected KeyPair generateNewKeyPair() throws NoSuchAlgorithmException {
-        final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
-        keyGen.initialize(2048);
-        return keyGen.genKeyPair();        
-    }
-
     protected void populateClientAssertionParams(final Map<String, String> requestParameters, 
             final JWT jwt) {
         requestParameters.put("client_assertion", jwt.serialize());
@@ -359,7 +339,7 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
     
     protected PrivateKeyJWT buildPrivateKeyJwtAuth() throws JOSEException, URISyntaxException {
         return new PrivateKeyJWT(new ClientID(clientId), new URI(jwtAud),
-                JWSAlgorithm.RS256, rsaPrivateKey, null, null);   
+                JWSAlgorithm.RS256, (PrivateKey) rsaPrivateKey, null, null);   
     }
     
     protected void populateClientAssertionParams(final Map<String, String> requestParameters, 
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcFlowTest.java
index 4db032a9..118e9deb 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcFlowTest.java
@@ -20,6 +20,12 @@ package net.shibboleth.idp.plugin.oidc.op.profile.flow;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
 import java.security.interfaces.RSAPrivateKey;
 import java.security.interfaces.RSAPublicKey;
 import java.time.Instant;
@@ -42,6 +48,7 @@ import org.springframework.test.context.ContextConfiguration;
 import org.springframework.webflow.executor.FlowExecutionResult;
 import org.springframework.webflow.test.MockExternalContext;
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 
 import com.nimbusds.jose.EncryptionMethod;
@@ -49,10 +56,14 @@ import com.nimbusds.jose.JOSEException;
 import com.nimbusds.jose.JWEAlgorithm;
 import com.nimbusds.jose.JWSAlgorithm;
 import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jose.crypto.ECDSASigner;
 import com.nimbusds.jose.crypto.MACSigner;
 import com.nimbusds.jose.crypto.RSASSASigner;
+import com.nimbusds.jose.jwk.Curve;
+import com.nimbusds.jose.jwk.ECKey;
 import com.nimbusds.jose.jwk.JWKSet;
 import com.nimbusds.jose.jwk.RSAKey;
+import com.nimbusds.jose.jwk.gen.ECKeyGenerator;
 import com.nimbusds.jwt.JWTClaimsSet;
 import com.nimbusds.jwt.SignedJWT;
 import com.nimbusds.oauth2.sdk.ErrorResponse;
@@ -86,7 +97,12 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
     @Autowired
     @Qualifier("shibboleth.oidc.TokenSealer")
     private DataSealer dataSealer;
+
+    RSAPrivateKey rsaPrivateKey;
+    RSAPublicKey rsaPublicKey;
     
+    ECKey ecKey;
+
     protected AbstractOidcFlowTest(final String id) {
         this(id, END_STATE_ID);
     }
@@ -115,6 +131,33 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
     @BeforeMethod public void initializeThreadLocals() {
         HttpServletRequestResponseContext.loadCurrent((HttpServletRequest) request, (HttpServletResponse) response);
     }
+
+    @BeforeClass
+    public void initKeys() throws NoSuchAlgorithmException, JOSEException {
+        final KeyPair keyPair = generateNewKeyPair();
+        rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
+        rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
+        ecKey = initializeECKey(Curve.P_256, "123");
+    }
+
+    protected ECKey initializeECKey(final Curve curve, final String kid) {
+        try {
+            return new ECKeyGenerator(curve).keyID(kid).generate();
+        } catch (JOSEException e) {
+            Assert.fail();
+            return null;
+        }
+    }
+    
+    protected KeyPair generateNewKeyPair() throws NoSuchAlgorithmException {
+        return generateNewKeyPair("RSA", 2048);
+    }
+
+    protected KeyPair generateNewKeyPair(final String algorithm, final int size) throws NoSuchAlgorithmException {
+        final KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm);
+        keyGen.initialize(size);
+        return keyGen.genKeyPair();        
+    }
     
     protected DataSealer getDataSealer() {
         return dataSealer;
@@ -184,11 +227,26 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
                 null, null, redirectUri);
     }
 
+    protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
+            final Scope scope, final JWSAlgorithm requestObjectSigAlg, final String... redirectUri) throws IOException {
+        storeMetadata(storageService, clientId, secret, scope, null, null, null,
+                ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
+                null, null, false, requestObjectSigAlg, redirectUri);
+    }
+
+    protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
+            final Scope scope, final JWSAlgorithm requestObjectSigAlg, final PublicKey publicKey,
+            final String... redirectUri) throws IOException {
+        storeMetadata(storageService, clientId, secret, scope, null, null, null,
+                ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
+                null, publicKey, false, requestObjectSigAlg, redirectUri);
+    }
+
     protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
             final Scope scope, final boolean addResources, final String... redirectUri) throws IOException {
         storeMetadata(storageService, clientId, secret, scope, null, null, null,
                 ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
-                null, null, addResources, redirectUri);
+                null, null, addResources, null, redirectUri);
     }
 
 // Checkstyle: ParameterNumber OFF    
@@ -210,7 +268,7 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
     protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
             final Scope scope, final JWSAlgorithm tokenEndpointSigAlg,
             final ClientAuthenticationMethod tokenEndpointMethod, final JWSAlgorithm userInfoSigAlg,
-            final RSAPublicKey publicKey, final String... redirectUri) throws IOException {
+            final PublicKey publicKey, final String... redirectUri) throws IOException {
         storeMetadata(storageService, clientId, secret, scope, tokenEndpointSigAlg, null, null, tokenEndpointMethod,
                 userInfoSigAlg, publicKey, redirectUri);
     }
@@ -218,16 +276,16 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
     protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
             final Scope scope, final JWSAlgorithm tokenEndpointSigAlg, final JWEAlgorithm tokenEncAlg,
             final EncryptionMethod encMethod, final ClientAuthenticationMethod tokenEndpointMethod,
-            final JWSAlgorithm userInfoSigAlg, final RSAPublicKey publicKey, final String... redirectUri)
+            final JWSAlgorithm userInfoSigAlg, final PublicKey publicKey, final String... redirectUri)
                     throws IOException {
         storeMetadata(storageService, clientId, secret, scope, tokenEndpointSigAlg, tokenEncAlg, encMethod,
-                tokenEndpointMethod, userInfoSigAlg, publicKey, true, redirectUri);
+                tokenEndpointMethod, userInfoSigAlg, publicKey, true, null, redirectUri);
     }
     protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
             final Scope scope, final JWSAlgorithm tokenEndpointSigAlg, final JWEAlgorithm tokenEncAlg,
             final EncryptionMethod encMethod, final ClientAuthenticationMethod tokenEndpointMethod,
-            final JWSAlgorithm userInfoSigAlg, final RSAPublicKey publicKey,final boolean addResources,
-            final String... redirectUri)
+            final JWSAlgorithm userInfoSigAlg, final PublicKey publicKey,final boolean addResources,
+            final JWSAlgorithm requestObjectSigAlg, final String... redirectUri)
                     throws IOException {
         final OIDCClientMetadata metadata = new OIDCClientMetadata();
         metadata.setGrantTypes(new HashSet<GrantType>(List.of(GrantType.AUTHORIZATION_CODE,
@@ -259,6 +317,7 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
         metadata.setIDTokenJWEEnc(encMethod);
         metadata.setTokenEndpointAuthMethod(tokenEndpointMethod);
         metadata.setUserInfoJWSAlg(userInfoSigAlg);
+        metadata.setRequestObjectJWSAlg(requestObjectSigAlg);
         if (addResources) {
             metadata.setCustomField("audience", List.of("https://rp.example.org", "https://rp2.example.org",
                     "https://resource.example.org"));
@@ -268,8 +327,19 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
             information = new OIDCClientInformation(new ClientID(clientId), new Date(),
                     metadata, secret != null ? new Secret(secret) : null);
         } else {
-            final RSAKey rsaKey = new RSAKey.Builder(publicKey).build();
-            final JWKSet jwkSet = new JWKSet(rsaKey);
+            final JWKSet jwkSet;
+            if (publicKey instanceof RSAPublicKey) {
+                final RSAKey rsaKey = new RSAKey.Builder((RSAPublicKey) publicKey).build();
+                jwkSet = new JWKSet(rsaKey);
+            } else if (publicKey instanceof ECPublicKey) {
+                final ECPublicKey ecPublicKey = (ECPublicKey) publicKey;
+                final ECKey ecKey = new ECKey.Builder(Curve.forECParameterSpec(ecPublicKey.getParams()),
+                        ecPublicKey).build();
+                jwkSet = new JWKSet(ecKey);
+            } else {
+                Assert.fail();
+                return;
+            }
             metadata.setJWKSet(jwkSet);
             information = new OIDCClientInformation(new ClientID(clientId), new Date(),
                     metadata, secret != null ? new Secret(secret) : null);
@@ -345,4 +415,12 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
         return jwt;
     }    
 
+    protected static SignedJWT createPrivateKeyJWT(final JWTClaimsSet claimsSet, final ECPrivateKey ecPrivateKey,
+            final JWSAlgorithm algorithm) throws JOSEException {
+        final SignedJWT jwt = new SignedJWT(new JWSHeader(algorithm), claimsSet);
+        final ECDSASigner signer = new ECDSASigner(ecPrivateKey);
+        jwt.sign(signer);
+        return jwt;
+    }    
+
 }
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AuthorizeFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AuthorizeFlowTest.java
index 392f3de1..987d7ac9 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AuthorizeFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AuthorizeFlowTest.java
@@ -20,6 +20,9 @@ package net.shibboleth.idp.plugin.oidc.op.profile.flow;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.interfaces.RSAPublicKey;
 import java.text.ParseException;
 import java.time.Duration;
 import java.time.Instant;
@@ -37,6 +40,9 @@ 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.Curve;
+import com.nimbusds.jose.jwk.ECKey;
 import com.nimbusds.jwt.JWT;
 import com.nimbusds.jwt.JWTClaimsSet;
 import com.nimbusds.jwt.PlainJWT;
@@ -78,7 +84,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
     @Autowired
     @Qualifier("shibboleth.StorageService")
     StorageService storageService;
-    
+
     public AuthorizeFlowTest() {
         super(FLOW_ID);
     }
@@ -1210,7 +1216,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
     }
 
     @Test
-    public void testWithSignedReqObjectNoIssuer() throws IOException, SessionException,
+    public void testWithHS256SignedReqObjectNoIssuer() throws IOException, SessionException,
             JOSEException {
         final JWTClaimsSet ro = new JWTClaimsSet.Builder()
                 .audience(issuer)
@@ -1219,7 +1225,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
     }
 
     @Test
-    public void testWithSignedReqObjectNoAudience() throws IOException, SessionException,
+    public void testWithHS256SignedReqObjectNoAudience() throws IOException, SessionException,
             JOSEException {
         final JWTClaimsSet ro = new JWTClaimsSet.Builder()
                 .issuer(clientId)
@@ -1228,7 +1234,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
     }
 
     @Test
-    public void testWithSignedReqObjectWrongIssuer() throws IOException, SessionException,
+    public void testWithHS256SignedReqObjectWrongIssuer() throws IOException, SessionException,
             JOSEException {
         final JWTClaimsSet ro = new JWTClaimsSet.Builder()
                 .audience(issuer)
@@ -1238,7 +1244,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
     }
 
     @Test
-    public void testWithSignedReqObjectWrongAudience() throws IOException, SessionException,
+    public void testWithHS256SignedReqObjectWrongAudience() throws IOException, SessionException,
             JOSEException {
         final JWTClaimsSet ro = new JWTClaimsSet.Builder()
                 .audience("https://invalid.org")
@@ -1248,7 +1254,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
     }
 
     @Test
-    public void testWithSignedReqObjectWrongSecret() throws IOException, SessionException,
+    public void testWithHS256SignedReqObjectWrongSecret() throws IOException, SessionException,
             JOSEException {
         final JWTClaimsSet ro = new JWTClaimsSet.Builder()
                 .audience(issuer)
@@ -1258,7 +1264,49 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
     }
 
     @Test
-    public void testWithSignedReqObjectOverwriteRedirectUri() throws IOException, ParseException,
+    public void testWithRS256SignedReqObjectWrongKey() throws IOException, SessionException,
+            JOSEException, NoSuchAlgorithmException {
+        final JWTClaimsSet ro = new JWTClaimsSet.Builder()
+                .audience(issuer)
+                .issuer(clientId)
+                .build();
+        assertRequestObjectError(createPrivateKeyJWT(ro, rsaPrivateKey, JWSAlgorithm.RS256), null,
+                (RSAPublicKey) generateNewKeyPair().getPublic());
+    }
+
+    @Test
+    public void testWithRS256SignedReqObjectNoTrustedKey() throws IOException, SessionException,
+            JOSEException, NoSuchAlgorithmException {
+        final JWTClaimsSet ro = new JWTClaimsSet.Builder()
+                .audience(issuer)
+                .issuer(clientId)
+                .build();
+        assertRequestObjectError(createPrivateKeyJWT(ro, rsaPrivateKey, JWSAlgorithm.RS256));
+    }
+
+    @Test
+    public void testWithES256SignedReqObjectWrongKey() throws IOException, SessionException,
+            JOSEException, NoSuchAlgorithmException {
+        final JWTClaimsSet ro = new JWTClaimsSet.Builder()
+                .audience(issuer)
+                .issuer(clientId)
+                .build();
+        assertRequestObjectError(createPrivateKeyJWT(ro, ecKey.toECPrivateKey(), JWSAlgorithm.ES256), null,
+                initializeECKey(Curve.P_256, "321").toECPublicKey());
+    }
+
+    @Test
+    public void testWithES256SignedReqObjectNoTrustedKey() throws IOException, SessionException,
+            JOSEException, NoSuchAlgorithmException {
+        final JWTClaimsSet ro = new JWTClaimsSet.Builder()
+                .audience(issuer)
+                .issuer(clientId)
+                .build();
+        assertRequestObjectError(createPrivateKeyJWT(ro, ecKey.toECPrivateKey(), JWSAlgorithm.ES256));
+    }
+
+    @Test
+    public void testWithHS256SignedReqObjectOverwriteRedirectUri() throws IOException, ParseException,
             SessionException, JOSEException {
         final JWTClaimsSet ro = new JWTClaimsSet.Builder()
                 .audience(issuer)
@@ -1288,9 +1336,220 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
     }
 
     @Test
-    public void testWithSignedReqObjectClaimsRequest() throws IOException,
+    public void testWithHS256SignedReqObjectClaimsRequest() throws IOException,
             SessionException, JOSEException, DataSealerException, ParseException {
-        final String payload = "{\n"
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertSuccessRequestObjectWithClaimsRequestResponse(createSecretJWT(ro, clientSecret));
+    }
+
+    @Test
+    public void testWithHS384SignedReqObjectClaimsRequest() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertSuccessRequestObjectWithClaimsRequestResponse(createSecretJWT(ro, clientSecret, JWSAlgorithm.HS384));
+    }
+
+    @Test
+    public void testWithHS512SignedReqObjectClaimsRequest() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertSuccessRequestObjectWithClaimsRequestResponse(createSecretJWT(ro, clientSecret, JWSAlgorithm.HS512));
+    }
+
+    @Test
+    public void testWithHS256SignedReqObjectClaimsRequest_HS256Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertSuccessRequestObjectWithClaimsRequestResponse(createSecretJWT(ro, clientSecret), JWSAlgorithm.HS256);
+    }
+
+    @Test
+    public void testWithHS256SignedReqObjectClaimsRequest_HS384Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertRequestObjectError(createSecretJWT(ro, clientSecret), JWSAlgorithm.HS384);
+    }
+
+    @Test
+    public void testWithHS384SignedReqObjectClaimsRequest_HS384Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertSuccessRequestObjectWithClaimsRequestResponse(createSecretJWT(ro, clientSecret, JWSAlgorithm.HS384),
+                JWSAlgorithm.HS384);
+    }
+
+    @Test
+    public void testWithHS384SignedReqObjectClaimsRequest_HS512Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertRequestObjectError(createSecretJWT(ro, clientSecret, JWSAlgorithm.HS384), JWSAlgorithm.HS512);
+    }
+
+    @Test
+    public void testWithHS512SignedReqObjectClaimsRequest_HS512Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertSuccessRequestObjectWithClaimsRequestResponse(createSecretJWT(ro, clientSecret, JWSAlgorithm.HS512),
+                JWSAlgorithm.HS512);
+    }
+
+    @Test
+    public void testWithHS512SignedReqObjectClaimsRequest_HS384Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertRequestObjectError(createSecretJWT(ro, clientSecret, JWSAlgorithm.HS512), JWSAlgorithm.HS384);
+    }
+
+    @Test
+    public void testWithRS256SignedReqObjectClaimsRequest() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertSuccessRequestObjectWithClaimsRequestResponse(createPrivateKeyJWT(ro, rsaPrivateKey), null, rsaPublicKey);
+    }
+
+    @Test
+    public void testWithRS384SignedReqObjectClaimsRequest() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertSuccessRequestObjectWithClaimsRequestResponse(createPrivateKeyJWT(ro, rsaPrivateKey, JWSAlgorithm.RS384),
+                null, rsaPublicKey);
+    }
+
+    @Test
+    public void testWithRS512SignedReqObjectClaimsRequest() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertSuccessRequestObjectWithClaimsRequestResponse(createPrivateKeyJWT(ro, rsaPrivateKey, JWSAlgorithm.RS512),
+                null, rsaPublicKey);
+    }
+
+    @Test
+    public void testWithRS256SignedReqObjectClaimsRequest_RS256Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertSuccessRequestObjectWithClaimsRequestResponse(createPrivateKeyJWT(ro, rsaPrivateKey), JWSAlgorithm.RS256,
+                rsaPublicKey);
+    }
+
+    @Test
+    public void testWithRS256SignedReqObjectClaimsRequest_RS384Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertRequestObjectError(createPrivateKeyJWT(ro, rsaPrivateKey), JWSAlgorithm.RS384, rsaPublicKey);
+    }
+
+    @Test
+    public void testWithRS384SignedReqObjectClaimsRequest_RS384Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertSuccessRequestObjectWithClaimsRequestResponse(createPrivateKeyJWT(ro, rsaPrivateKey, JWSAlgorithm.RS384),
+                JWSAlgorithm.RS384, rsaPublicKey);
+    }
+
+    @Test
+    public void testWithRS384SignedReqObjectClaimsRequest_RS512Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertRequestObjectError(createPrivateKeyJWT(ro, rsaPrivateKey, JWSAlgorithm.RS384), JWSAlgorithm.RS512,
+                rsaPublicKey);
+    }
+
+    @Test
+    public void testWithRS512SignedReqObjectClaimsRequest_RS512Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertSuccessRequestObjectWithClaimsRequestResponse(createPrivateKeyJWT(ro, rsaPrivateKey, JWSAlgorithm.RS512),
+                JWSAlgorithm.RS512, rsaPublicKey);
+    }
+
+    @Test
+    public void testWithRS512SignedReqObjectClaimsRequest_RS384Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertRequestObjectError(createPrivateKeyJWT(ro, rsaPrivateKey, JWSAlgorithm.RS512), JWSAlgorithm.RS384,
+                rsaPublicKey);
+    }
+
+    @Test
+    public void testWithES256SignedReqObjectClaimsRequest() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertSuccessRequestObjectWithClaimsRequestResponse(createPrivateKeyJWT(ro, ecKey.toECPrivateKey(),
+                JWSAlgorithm.ES256), null, ecKey.toECPublicKey());
+    }
+
+    @Test
+    public void testWithES384SignedReqObjectClaimsRequest() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        final ECKey ecKey = initializeECKey(Curve.P_384, "384");
+        assertSuccessRequestObjectWithClaimsRequestResponse(createPrivateKeyJWT(ro, ecKey.toECPrivateKey(),
+                JWSAlgorithm.ES384), null, ecKey.toECPublicKey());
+    }
+
+    @Test
+    public void testWithES512SignedReqObjectClaimsRequest() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        final ECKey ecKey = initializeECKey(Curve.P_521, "512");
+        assertSuccessRequestObjectWithClaimsRequestResponse(createPrivateKeyJWT(ro, ecKey.toECPrivateKey(),
+                JWSAlgorithm.ES512), null, ecKey.toECPublicKey());
+    }
+
+    @Test
+    public void testWithES256SignedReqObjectClaimsRequest_ES256Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertSuccessRequestObjectWithClaimsRequestResponse(createPrivateKeyJWT(ro, ecKey.toECPrivateKey(),
+                JWSAlgorithm.ES256), JWSAlgorithm.ES256, ecKey.toECPublicKey());
+    }
+
+    @Test
+    public void testWithES256SignedReqObjectClaimsRequest_ES384Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        assertRequestObjectError(createPrivateKeyJWT(ro, ecKey.toECPrivateKey(), JWSAlgorithm.ES256),
+                JWSAlgorithm.ES384, ecKey.toECPublicKey());
+    }
+
+    @Test
+    public void testWithES384SignedReqObjectClaimsRequest_ES384Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        final ECKey ecKey = initializeECKey(Curve.P_384, "384");
+        assertSuccessRequestObjectWithClaimsRequestResponse(createPrivateKeyJWT(ro, ecKey.toECPrivateKey(),
+                JWSAlgorithm.ES384), JWSAlgorithm.ES384, ecKey.toECPublicKey());
+    }
+
+    @Test
+    public void testWithES384SignedReqObjectClaimsRequest_ES512Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        final ECKey ecKey = initializeECKey(Curve.P_384, "384");
+        assertRequestObjectError(createPrivateKeyJWT(ro, ecKey.toECPrivateKey(), JWSAlgorithm.ES384),
+                JWSAlgorithm.ES512, ecKey.toECPublicKey());
+    }
+
+    @Test
+    public void testWithES512SignedReqObjectClaimsRequest_ES512Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        final ECKey ecKey = initializeECKey(Curve.P_521, "521");
+        assertSuccessRequestObjectWithClaimsRequestResponse(createPrivateKeyJWT(ro, ecKey.toECPrivateKey(),
+                JWSAlgorithm.ES512), JWSAlgorithm.ES512, ecKey.toECPublicKey());
+    }
+
+    @Test
+    public void testWithES512SignedReqObjectClaimsRequest_ES384Configured() throws IOException,
+            SessionException, JOSEException, DataSealerException, ParseException {
+        final JWTClaimsSet ro = JWTClaimsSet.parse(getRequestObjectWithClaimsRequestPayload());
+        final ECKey ecKey = initializeECKey(Curve.P_521, "521");
+        assertRequestObjectError(createPrivateKeyJWT(ro, ecKey.toECPrivateKey(), JWSAlgorithm.ES512),
+                JWSAlgorithm.ES384, ecKey.toECPublicKey());
+    }
+
+    protected String getRequestObjectWithClaimsRequestPayload() {
+        return "{\n"
                 + "  \"iss\": \"" + clientId + "\",\n"
                 + "  \"response_type\": \"code\",\n"
                 + "  \"code_challenge_method\": \"S256\",\n"
@@ -1314,16 +1573,28 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
                 + "  \"state\": \"81c33d57-59c7-4b41-9a15-80e2ed1482e21646857349537\",\n"
                 + "  \"code_challenge\": \"MiAR-UxCj6oVyPatcUnrb3MGEZbwLKBmIRSoOKLLTl0\"\n"
                 + "}";
-        
-        final JWTClaimsSet ro = JWTClaimsSet.parse(payload);
-        final SignedJWT requestObject = createSecretJWT(ro, clientSecret);
+    }
+
+    protected void assertSuccessRequestObjectWithClaimsRequestResponse(final SignedJWT requestObject)
+            throws ParseException, DataSealerException, IOException {
+        assertSuccessRequestObjectWithClaimsRequestResponse(requestObject, null);
+    }
+
+    protected void assertSuccessRequestObjectWithClaimsRequestResponse(final SignedJWT requestObject,
+            final JWSAlgorithm requestObjectSigAlg) throws ParseException, DataSealerException, IOException {
+        assertSuccessRequestObjectWithClaimsRequestResponse(requestObject, requestObjectSigAlg, null);
+    }
+
+    protected void assertSuccessRequestObjectWithClaimsRequestResponse(final SignedJWT requestObject,
+            final JWSAlgorithm requestObjectSigAlg, final PublicKey publicKey)
+                    throws ParseException, DataSealerException, IOException {
         request.setMethod("GET");
         setRequestParameters(List.of(new Pair<>("client_id", "mockClientId"),
                 new Pair<>("response_type", "code"),
                 new Pair<>("scope", "openid profile"),
                 new Pair<>("redirect_uri", redirectUri),
                 new Pair<>("request", requestObject.serialize())));
-        storeMetadata(storageService, clientId, clientSecret, scope, redirectUri);
+        storeMetadata(storageService, clientId, clientSecret, scope, requestObjectSigAlg, publicKey, redirectUri);
 
         initializeThreadLocals();
 
@@ -1355,9 +1626,20 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
         Assert.assertEquals(givenName.getClaimName(), "given_name");
         Assert.assertEquals(givenName.getClaimRequirement(), ClaimRequirement.ESSENTIAL);
 
+        
     }
-
+    
     protected void assertRequestObjectError(final JWT requestObject) throws IOException {
+        assertRequestObjectError(requestObject, null);
+    }
+
+    protected void assertRequestObjectError(final JWT requestObject, final JWSAlgorithm requestObjectSigAlg)
+            throws IOException {
+        assertRequestObjectError(requestObject, requestObjectSigAlg, null);
+    }
+
+    protected void assertRequestObjectError(final JWT requestObject, final JWSAlgorithm requestObjectSigAlg,
+            final PublicKey publicKey) throws IOException {
         request.setMethod("GET");
         setRequestParameters(List.of(new Pair<>("client_id", "mockClientId"),
                 new Pair<>("response_type", "code"),
@@ -1365,7 +1647,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
                 new Pair<>("redirect_uri", redirectUri),
                 new Pair<>("request", requestObject.serialize())));
 
-        storeMetadata(storageService, clientId, clientSecret, scope, redirectUri);
+        storeMetadata(storageService, clientId, clientSecret, scope, requestObjectSigAlg, publicKey, redirectUri);
         initializeThreadLocals();
         
         final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);

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


More information about the commits mailing list