[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
Fri Feb 3 08:16:16 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=1bfd07fee0c64aaf6a3a6dc4f98d004c6d90bd1f

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

commit 1bfd07fee0c64aaf6a3a6dc4f98d004c6d90bd1f
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Feb 3 10:15:35 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 JWTs in client authentication with varying configurations
---
 .../AbstractOidcClientAuthenticationFlowTest.java  | 298 ++++++++++++++++++++-
 .../flow/ClientCredentialsTokenFlowTest.java       |   5 +-
 .../op/profile/flow/IntrospectionFlowTest.java     |   8 +-
 .../oidc/op/profile/flow/RevocationFlowTest.java   |   8 +-
 .../plugin/oidc/op/profile/flow/TokenFlowTest.java |   7 +-
 5 files changed, 299 insertions(+), 27 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 bea1af10..1b5b56b8 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
@@ -20,6 +20,7 @@ package net.shibboleth.idp.plugin.oidc.op.profile.flow;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.security.PrivateKey;
+import java.security.PublicKey;
 import java.security.interfaces.RSAPrivateKey;
 import java.time.Instant;
 import java.util.Date;
@@ -31,6 +32,8 @@ 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;
@@ -51,7 +54,7 @@ import net.shibboleth.utilities.java.support.collection.Pair;
 public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractOidcApiFlowTest {
     
     String clientId = "mockClientId";
-    String clientSecret = "1234567890mockClientSecretmockClientSecretmockClientSecret";
+    String clientSecret = "mockClientSecretmockClientSecretmockClientSecretmockClientSecretmockClientSecret";
     String clientIdSaml = "mockSamlClientId";
     String clientSecretSaml = "mockClientSecretmockClientSecretmockClientSecret";
 
@@ -150,18 +153,85 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
     }
 
     @Test
-    public void testValidSecretJWT() throws Exception {
-        final SignedJWT jwt = createSecretJWT(validClaimsSet(), clientSecret);
+    public void testValidSecretJWTHS256_noRegisteredAlg() throws Exception {
+        final SignedJWT jwt = createSecretJWT(validClaimsSet(), clientSecret, JWSAlgorithm.HS256);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, null,
+                ClientAuthenticationMethod.CLIENT_SECRET_JWT);
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testValidSecretJWTHS256_HS256Registered() throws Exception {
+        final SignedJWT jwt = createSecretJWT(validClaimsSet(), clientSecret, JWSAlgorithm.HS256);
         final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.HS256,
                 ClientAuthenticationMethod.CLIENT_SECRET_JWT);
         assertSuccessResponse(result);
     }
 
+    @Test
+    public void testValidSecretJWTH384_noRegisteredAlg() throws Exception {
+        final SignedJWT jwt = createSecretJWT(validClaimsSet(), clientSecret, JWSAlgorithm.HS384);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, null,
+                ClientAuthenticationMethod.CLIENT_SECRET_JWT);
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testValidSecretJWTHS384_HS384Registered() throws Exception {
+        final SignedJWT jwt = createSecretJWT(validClaimsSet(), clientSecret, JWSAlgorithm.HS384);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.HS384,
+                ClientAuthenticationMethod.CLIENT_SECRET_JWT);
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testValidSecretJWTHS512_noRegisteredAlg() throws Exception {
+        final SignedJWT jwt = createSecretJWT(validClaimsSet(), clientSecret, JWSAlgorithm.HS512);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, null,
+                ClientAuthenticationMethod.CLIENT_SECRET_JWT);
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testValidSecretJWTHS512_HS512Registered() throws Exception {
+        final SignedJWT jwt = createSecretJWT(validClaimsSet(), clientSecret, JWSAlgorithm.HS512);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.HS512,
+                ClientAuthenticationMethod.CLIENT_SECRET_JWT);
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testInvalidSecretJWTHS256_algNotMatchingRegistered() throws Exception {
+        final SignedJWT jwt = createSecretJWT(validClaimsSet(), clientSecret, JWSAlgorithm.HS256);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.HS512,
+                ClientAuthenticationMethod.CLIENT_SECRET_JWT);
+        assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
+        assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
+    }
+
+    @Test
+    public void testInvalidSecretJWTHS384_algNotMatchingRegistered() throws Exception {
+        final SignedJWT jwt = createSecretJWT(validClaimsSet(), clientSecret, JWSAlgorithm.HS384);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.HS512,
+                ClientAuthenticationMethod.CLIENT_SECRET_JWT);
+        assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
+        assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
+    }
+
+    @Test
+    public void testInvalidSecretJWTHS512_algNotMatchingRegistered() throws Exception {
+        final SignedJWT jwt = createSecretJWT(validClaimsSet(), clientSecret, JWSAlgorithm.HS512);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.HS384,
+                ClientAuthenticationMethod.CLIENT_SECRET_JWT);
+        assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
+        assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
+    }
+
     @Test
     public void testInvalidPrivateKeyJWT_missingSub() throws Exception {
         final SignedJWT jwt = createPrivateKeyJWT(claimsSetMissingSub(), rsaPrivateKey);
         final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS256,
-                ClientAuthenticationMethod.PRIVATE_KEY_JWT);
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
         assertErrorCode(result, "invalid_request");
         assertErrorDescriptionContains(result, "UnableToDecode");
     }
@@ -170,7 +240,7 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
     public void testInvalidPrivateKeyJWT_missingIss() throws Exception {
         final SignedJWT jwt = createPrivateKeyJWT(claimsSetMissingIss(), rsaPrivateKey);
         final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS256,
-                ClientAuthenticationMethod.PRIVATE_KEY_JWT);
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
         assertErrorCode(result, "invalid_request");
         assertErrorDescriptionContains(result, "UnableToDecode");
     }
@@ -179,7 +249,7 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
     public void testInvalidPrivateKeyJWT_missingAud() throws Exception {
         final SignedJWT jwt = createPrivateKeyJWT(claimsSetMissingAud(), rsaPrivateKey);
         final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS256,
-                ClientAuthenticationMethod.PRIVATE_KEY_JWT);
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
         assertErrorCode(result, "invalid_request");
         assertErrorDescriptionContains(result, "UnableToDecode");
     }
@@ -188,7 +258,7 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
     public void testInvalidPrivateKeyJWT_missingExp() throws Exception {
         final SignedJWT jwt = createPrivateKeyJWT(claimsSetMissingExp(), rsaPrivateKey);
         final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS256,
-                ClientAuthenticationMethod.PRIVATE_KEY_JWT);
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
         assertErrorCode(result, "invalid_request");
         assertErrorDescriptionContains(result, "UnableToDecode");
     }
@@ -197,7 +267,7 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
     public void testInvalidPrivateKeyJWT_expiredExp() throws Exception {
         final SignedJWT jwt = createPrivateKeyJWT(claimsSetExpiredExp(), rsaPrivateKey);
         final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS256,
-                ClientAuthenticationMethod.PRIVATE_KEY_JWT);
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
         assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
         assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
     }
@@ -206,7 +276,7 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
     public void testInvalidPrivateKeyJWT_issuedInTheFuture() throws Exception {
         final SignedJWT jwt = createPrivateKeyJWT(claimsSetIssuedInTheFuture(), rsaPrivateKey);
         final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS256,
-                ClientAuthenticationMethod.PRIVATE_KEY_JWT);
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
         assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
         assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
     }
@@ -215,7 +285,7 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
     public void testInvalidPrivateKeyJWT_missingJti() throws Exception {
         final SignedJWT jwt = createPrivateKeyJWT(claimsSetMissingJti(), rsaPrivateKey);
         final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS256,
-                ClientAuthenticationMethod.PRIVATE_KEY_JWT);
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
         assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
         assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
     }
@@ -225,14 +295,23 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
         final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), rsaPrivateKey);
         launchWithJwtAuthentication(jwt, JWSAlgorithm.RS256, ClientAuthenticationMethod.PRIVATE_KEY_JWT);
         final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS256,
-                ClientAuthenticationMethod.PRIVATE_KEY_JWT);
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
         assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
         assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
     }
 
     @Test
-    public void testInvalidPrivateKeyJWT_invalidSignerKey() throws Exception {
+    public void testInvalidPrivateKeyRSJWT_invalidSignerKey() throws Exception {
         final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), (RSAPrivateKey)generateNewKeyPair().getPrivate());
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS256,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
+        assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
+        assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
+    }
+
+    @Test
+    public void testInvalidPrivateKeyRSJWT_noTrustedKey() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), rsaPrivateKey);
         final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS256,
                 ClientAuthenticationMethod.PRIVATE_KEY_JWT);
         assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
@@ -240,13 +319,198 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
     }
 
     @Test
-    public void testValidPrivateKeyJWT() throws Exception {
+    public void testInvalidPrivateKeyRSJWT_wrongKey() throws Exception {
         final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), rsaPrivateKey);
         final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS256,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, super.generateNewKeyPair().getPublic());
+        assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
+        assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
+    }
+
+    @Test
+    public void testValidPrivateKeyJWTRS256_noRegisteredAlg() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), rsaPrivateKey, JWSAlgorithm.RS256);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, null,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testValidPrivateKeyJWTRS256_RS256Registered() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), rsaPrivateKey, JWSAlgorithm.RS256);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS256,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testValidPrivateKeyJWTRS384_noRegisteredAlg() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), rsaPrivateKey, JWSAlgorithm.RS384);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, null,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testValidPrivateKeyJWTRS384_RS384Registered() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), rsaPrivateKey, JWSAlgorithm.RS384);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS384,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testValidPrivateKeyJWTRS512_noRegisteredAlg() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), rsaPrivateKey, JWSAlgorithm.RS512);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, null,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testValidPrivateKeyJWTRS512_RS512Registered() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), rsaPrivateKey, JWSAlgorithm.RS512);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS512,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testInvalidPrivateKeyJWTRS256_algNotMatchingRegistered() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), rsaPrivateKey, JWSAlgorithm.RS256);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS512,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
+        assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
+        assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
+    }
+
+    @Test
+    public void testInvalidPrivateKeyJWTRS384_algNotMatchingRegistered() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), rsaPrivateKey, JWSAlgorithm.RS384);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS512,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
+        assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
+        assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
+    }
+
+    @Test
+    public void testInvalidPrivateKeyJWTRS512_algNotMatchingRegistered() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), rsaPrivateKey, JWSAlgorithm.RS512);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.RS384,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, rsaPublicKey);
+        assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
+        assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
+    }
+
+    @Test
+    public void testInvalidPrivateKeyESJWT_invalidSignerKey() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(),
+                initializeECKey(Curve.P_256, "mock").toECPrivateKey(), JWSAlgorithm.ES256);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.ES256,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, ecKey.toECPublicKey());
+        assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
+        assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
+    }
+
+    @Test
+    public void testInvalidPrivateKeyESJWT_noTrustedKey() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), ecKey.toECPrivateKey(), JWSAlgorithm.ES256);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.ES256,
                 ClientAuthenticationMethod.PRIVATE_KEY_JWT);
+        assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
+        assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
+    }
+
+    @Test
+    public void testInvalidPrivateKeyESJWT_wrongKey() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), ecKey.toECPrivateKey(), JWSAlgorithm.ES256);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.ES384,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, initializeECKey(Curve.P_384, "mock").toECPublicKey());
+        assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
+        assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
+    }
+
+    @Test
+    public void testValidPrivateKeyJWTES256_noRegisteredAlg() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), ecKey.toECPrivateKey(), JWSAlgorithm.ES256);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, null,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, ecKey.toECPublicKey());
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testValidPrivateKeyJWTES256_ES256Registered() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), ecKey.toECPrivateKey(), JWSAlgorithm.ES256);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.ES256,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, ecKey.toECPublicKey());
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testValidPrivateKeyJWTES384_noRegisteredAlg() throws Exception {
+        final ECKey ecKey = initializeECKey(Curve.P_384, "384");
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), ecKey.toECPrivateKey(), JWSAlgorithm.ES384);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, null,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, ecKey.toECPublicKey());
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testValidPrivateKeyJWTES384_ES384Registered() throws Exception {
+        final ECKey ecKey = initializeECKey(Curve.P_384, "384");
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), ecKey.toECPrivateKey(), JWSAlgorithm.ES384);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.ES384,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, ecKey.toECPublicKey());
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testValidPrivateKeyJWTES512_noRegisteredAlg() throws Exception {
+        final ECKey ecKey = initializeECKey(Curve.P_521, "521");
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), ecKey.toECPrivateKey(), JWSAlgorithm.ES512);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, null,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, ecKey.toECPublicKey());
+        assertSuccessResponse(result);
+    }
+
+    @Test
+    public void testValidPrivateKeyJWTES512_ES512Registered() throws Exception {
+        final ECKey ecKey = initializeECKey(Curve.P_521, "521");
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), ecKey.toECPrivateKey(), JWSAlgorithm.ES512);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.ES512,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, ecKey.toECPublicKey());
         assertSuccessResponse(result);
     }
 
+    @Test
+    public void testInvalidPrivateKeyJWTES256_algNotMatchingRegistered() throws Exception {
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), ecKey.toECPrivateKey(), JWSAlgorithm.ES256);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.ES512,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, ecKey.toECPublicKey());
+        assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
+        assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
+    }
+
+    @Test
+    public void testInvalidPrivateKeyJWTES384_algNotMatchingRegistered() throws Exception {
+        final ECKey ecKey = initializeECKey(Curve.P_384, "384");
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), ecKey.toECPrivateKey(), JWSAlgorithm.ES384);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.ES512,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, ecKey.toECPublicKey());
+        assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
+        assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
+    }
+
+    @Test
+    public void testInvalidPrivateKeyJWTES512_algNotMatchingRegistered() throws Exception {
+        final ECKey ecKey = initializeECKey(Curve.P_521, "521");
+        final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(), ecKey.toECPrivateKey(), JWSAlgorithm.ES512);
+        final FlowExecutionResult result = launchWithJwtAuthentication(jwt, JWSAlgorithm.ES384,
+                ClientAuthenticationMethod.PRIVATE_KEY_JWT, ecKey.toECPublicKey());
+        assertErrorCode(result, getErrorDetaisForJWTValidation().getFirst());
+        assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
+    }
+
     @Test
     public void testPlainJWT() throws Exception {
         final PlainJWT jwt = new PlainJWT(validClaimsSet());
@@ -348,17 +612,23 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
         requestParameters.put("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer");
     }
 
+    protected FlowExecutionResult launchWithJwtAuthentication(final JWT jwt,
+            final JWSAlgorithm algorithm, final ClientAuthenticationMethod method) throws Exception {
+        return launchWithJwtAuthentication(jwt, algorithm, method, null);
+    }
     /**
      * Launch the flow with the JWT client authentication method.
      *
      * @param jwt The JWT to be used for client authentication.
      * @param algorithm The algorithm to be used in the client authentication.
      * @param method The client authentication method.
+     * @param publicKey The public key to store into the trusted metadata.
      * @return The flow execution result.
      * @throws Exception
      */
     protected abstract FlowExecutionResult launchWithJwtAuthentication(final JWT jwt,
-            final JWSAlgorithm algorithm, final ClientAuthenticationMethod method) throws Exception;
+            final JWSAlgorithm algorithm, final ClientAuthenticationMethod method,
+            final PublicKey publicKey) throws Exception;
 
     /**
      * Get the pair of error code and error description for the error produced via event
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/ClientCredentialsTokenFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/ClientCredentialsTokenFlowTest.java
index 1d7d40fc..3e39f5d5 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/ClientCredentialsTokenFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/ClientCredentialsTokenFlowTest.java
@@ -24,6 +24,7 @@ import static org.testng.Assert.assertTrue;
 
 import java.io.IOException;
 import java.security.PrivateKey;
+import java.security.PublicKey;
 import java.text.ParseException;
 import java.time.Instant;
 import java.util.Collection;
@@ -300,11 +301,11 @@ public class ClientCredentialsTokenFlowTest extends AbstractOidcClientAuthentica
     }
 
     protected FlowExecutionResult launchWithJwtAuthentication(final JWT jwt, final JWSAlgorithm algorithm,
-            final ClientAuthenticationMethod method) throws Exception {
+            final ClientAuthenticationMethod method, final PublicKey publicKey) throws Exception {
         if (ClientAuthenticationMethod.CLIENT_SECRET_JWT.equals(method)) {
             storeMetadata(storageService, clientId, clientSecret, scope, algorithm, method);
         } else {
-            storeMetadata(storageService, clientId, null, scope, algorithm, method, null, rsaPublicKey);
+            storeMetadata(storageService, clientId, null, scope, algorithm, method, null, publicKey);
         }
         final Map<String, String> requestParameters = createRequestParameters(clientId, scope, resource);
         populateClientAssertionParams(requestParameters, jwt);
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/IntrospectionFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/IntrospectionFlowTest.java
index d27d5a6a..387c6d2e 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/IntrospectionFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/IntrospectionFlowTest.java
@@ -20,6 +20,7 @@ package net.shibboleth.idp.plugin.oidc.op.profile.flow;
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
 import java.time.Instant;
 import java.util.Collections;
 import java.util.HashMap;
@@ -38,7 +39,6 @@ import org.testng.annotations.Test;
 import com.nimbusds.jose.JOSEException;
 import com.nimbusds.jose.JWSAlgorithm;
 import com.nimbusds.jwt.JWT;
-import com.nimbusds.jwt.SignedJWT;
 import com.nimbusds.oauth2.sdk.OAuth2Error;
 import com.nimbusds.oauth2.sdk.Scope;
 import com.nimbusds.oauth2.sdk.TokenIntrospectionErrorResponse;
@@ -411,11 +411,11 @@ public class IntrospectionFlowTest extends AbstractOidcClientAuthenticationFlowT
     }
     
     protected FlowExecutionResult launchWithJwtAuthentication(final JWT jwt, final JWSAlgorithm algorithm,
-            final ClientAuthenticationMethod method) throws Exception {
-        if (ClientAuthenticationMethod.CLIENT_SECRET_JWT.equals(method)) {
+            final ClientAuthenticationMethod method, final PublicKey publicKey) throws Exception {
+        if (publicKey == null) {
             storeMetadata(storageService, clientId, clientSecret, scope, algorithm, method);
         } else {
-            storeMetadata(storageService, clientId, null, scope, algorithm, method, null, rsaPublicKey);
+            storeMetadata(storageService, clientId, null, scope, algorithm, method, null, publicKey);
         }
         final String accessToken = 
                 buildToken(clientId, "sub", scope).toJSONObject().getAsString("access_token");
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RevocationFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RevocationFlowTest.java
index e0f9cc71..2d331456 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RevocationFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RevocationFlowTest.java
@@ -20,6 +20,7 @@ package net.shibboleth.idp.plugin.oidc.op.profile.flow;
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
 import java.time.Instant;
 import java.util.Collections;
 import java.util.HashMap;
@@ -38,7 +39,6 @@ import org.testng.annotations.Test;
 import com.nimbusds.jose.JOSEException;
 import com.nimbusds.jose.JWSAlgorithm;
 import com.nimbusds.jwt.JWT;
-import com.nimbusds.jwt.SignedJWT;
 import com.nimbusds.oauth2.sdk.OAuth2Error;
 import com.nimbusds.oauth2.sdk.ParseException;
 import com.nimbusds.oauth2.sdk.Scope;
@@ -197,11 +197,11 @@ public class RevocationFlowTest extends AbstractOidcClientAuthenticationFlowTest
     }
 
     protected FlowExecutionResult launchWithJwtAuthentication(final JWT jwt, final JWSAlgorithm algorithm,
-            final ClientAuthenticationMethod method) throws Exception {
-        if (ClientAuthenticationMethod.CLIENT_SECRET_JWT.equals(method)) {
+            final ClientAuthenticationMethod method, final PublicKey publicKey) throws Exception {
+        if (publicKey == null) {
             storeMetadata(storageService, clientId, clientSecret, scope, algorithm, method);
         } else {
-            storeMetadata(storageService, clientId, null, scope, algorithm, method, null, rsaPublicKey);
+            storeMetadata(storageService, clientId, null, scope, algorithm, method, null, publicKey);
         }
         final String accessToken =
                 super.buildToken(clientId, "sub", Scope.parse("openid")).toJSONObject().getAsString("access_token");
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java
index 5972fb9f..ce1def17 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java
@@ -19,6 +19,7 @@ package net.shibboleth.idp.plugin.oidc.op.profile.flow;
 
 import java.io.IOException;
 import java.net.URI;
+import java.security.PublicKey;
 import java.text.ParseException;
 import java.time.Duration;
 import java.time.Instant;
@@ -895,13 +896,13 @@ public class TokenFlowTest extends AbstractOidcClientAuthenticationFlowTest {
     }
 
     protected FlowExecutionResult launchWithJwtAuthentication(final JWT jwt, final JWSAlgorithm algorithm,
-            final ClientAuthenticationMethod method) throws Exception {
+            final ClientAuthenticationMethod method, final PublicKey publicKey) throws Exception {
         final String code = ValidateGrantTest.buildAuthorizationCode(clientId, "https://op.example.org", "jdoe", "mock",
                 redirectUri, scope.toString()).toString();
-        if (ClientAuthenticationMethod.CLIENT_SECRET_JWT.equals(method)) {
+        if (publicKey == null) {
             storeMetadata(storageService, clientId, clientSecret, scope, algorithm, method);
         } else {
-            storeMetadata(storageService, clientId, null, scope, algorithm, method, null, rsaPublicKey);
+            storeMetadata(storageService, clientId, null, scope, algorithm, method, null, publicKey);
         }
         final Map<String, String> requestParameters =
                 createRequestParameters(redirectUri, "authorization_code", code, clientId);

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


More information about the commits mailing list