[java-oidc-common] branch main updated: Split signature validation API to accept a list of credentials
Phil Smart
philip.smart at jisc.ac.uk
Fri Feb 5 12:12:03 UTC 2021
This is an automated email from the git hooks/post-receive script.
philsmart pushed a commit to branch main
in repository java-oidc-common.
View the commit online:
http://git.shibboleth.net/view/?p=java-oidc-common.git;a=commit;h=977f490c30ffc30e3950b35a8fa5ccbd0ab61787
The following commit(s) were added to refs/heads/main by this push:
new 977f490 Split signature validation API to accept a list of credentials
977f490 is described below
commit 977f490c30ffc30e3950b35a8fa5ccbd0ab61787
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Fri Feb 5 12:12:00 2021 +0000
Split signature validation API to accept a list of credentials
In addition to an overloaded method with the existing security context.
---
.../security/impl/JWTSignatureValidationUtil.java | 49 +++++++++++++++++-----
.../impl/JWTSignatureValidationUtilTest.java | 26 +++++++++++-
2 files changed, 63 insertions(+), 12 deletions(-)
diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/JWTSignatureValidationUtil.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/JWTSignatureValidationUtil.java
index 0f1d4a9..9b5efdf 100644
--- a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/JWTSignatureValidationUtil.java
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/JWTSignatureValidationUtil.java
@@ -20,8 +20,10 @@ package net.shibboleth.oidc.security.impl;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Iterator;
+import java.util.List;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.opensaml.profile.action.EventIds;
import org.opensaml.security.credential.Credential;
@@ -52,19 +54,24 @@ public final class JWTSignatureValidationUtil {
private JWTSignatureValidationUtil() {
}
-
+
+
/**
* Validates the signature of the given JWT using the given security parameters context. If the validation fails for
* any reason, including insufficient prequisities in the context, an event identifier is returned. Successful
- * validation produces null result.
+ * validation produces a null result.
+ *
+ * <p>Overloads {@link #validateSignature(SecurityParametersContext, SignedJWT, String)}, but with a
+ * 'radically' different parameter.</p>
*
* @param secParamCtx The {@link SecurityParametersContext} to use for signature validation.
* @param signedJwt The signed JWT to be validated.
* @param invalidJwtEventId The event identifier describing the invalid JWT.
- * @return an event ID
+ * @return an event ID on failure, or {@literal null} if validation succeeds.
*/
- public static String validateSignature(final SecurityParametersContext secParamCtx, final SignedJWT signedJwt,
- final String invalidJwtEventId) {
+ @Nullable public static String validateSignature(@Nullable final SecurityParametersContext secParamCtx,
+ @Nonnull final SignedJWT signedJwt, @Nullable final String invalidJwtEventId) {
+
if (secParamCtx == null) {
log.error("No security parameters context is available");
return EventIds.INVALID_SEC_CFG;
@@ -79,9 +86,27 @@ public final class JWTSignatureValidationUtil {
if (signatureValidationParameters.getValidationCredentials().isEmpty()) {
log.error("Unable to find any keys to validate given JWT signature");
return EventIds.INVALID_SEC_CFG;
- }
+ }
+
+ return validateSignature(signatureValidationParameters.getValidationCredentials(),
+ signedJwt, invalidJwtEventId);
+ }
+
+ /**
+ * Validates the signature of the given JWS against the given list of credentials. If the validation fails for
+ * any reason, including insufficient prequisities in the context, an event identifier is returned. Successful
+ * validation produces null result.
+ *
+ * @param credentials The list of {@link JWKCredential credentials} to use for signature validation.
+ * @param signedJwt The signed JWT to be validated.
+ * @param invalidJwtEventId The event identifier describing the invalid JWT.
+ * @return an event ID on failure, or {@literal null} if validation succeeds.
+ */
+ public static String validateSignature(@Nonnull final List<JWKCredential> credentials,
+ @Nonnull final SignedJWT signedJwt, @Nullable final String invalidJwtEventId) {
+
final Algorithm algorithm = signedJwt.getHeader().getAlgorithm();
- final Iterator<?> it = signatureValidationParameters.getValidationCredentials().iterator();
+ final Iterator<?> it = credentials.iterator();
while (it.hasNext()) {
final JWKCredential credential = (JWKCredential) it.next();
if (!algorithm.equals(credential.getAlgorithm())) {
@@ -95,13 +120,15 @@ public final class JWTSignatureValidationUtil {
return EventIds.INVALID_SEC_CFG;
}
if (signedJwt.verify(verifier)) {
- log.debug("JWT {} verified using algorithm {} and key {}", signedJwt.serialize(),
- algorithm.getName(), credential.getKid());
+ log.debug("JWT {} verified using algorithm {} {}", signedJwt.serialize(),
+ algorithm.getName(),
+ credential.getKid() != null ? "and key " + credential.getKid() : "");
return null;
}
log.debug("Unable to validate given JWT with credential, picking next key");
- } catch (final JOSEException e) {
- log.warn("Exception catched when validating given JWT with credential {}", credential.getKid(), e);
+ } catch (final JOSEException | IllegalStateException e) {
+ log.warn("Exception caught when validating given JWT {}",
+ credential.getKid() != null ? "with credential " + credential.getKid() : "", e);
}
}
}
diff --git a/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/JWTSignatureValidationUtilTest.java b/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/JWTSignatureValidationUtilTest.java
index 9a14434..f645980 100644
--- a/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/JWTSignatureValidationUtilTest.java
+++ b/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/impl/JWTSignatureValidationUtilTest.java
@@ -24,6 +24,7 @@ import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.interfaces.ECPrivateKey;
import java.text.ParseException;
+import java.util.List;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
@@ -70,7 +71,14 @@ public class JWTSignatureValidationUtilTest {
@Test
public void validateSignature_shouldReturnInvalidSecCfgWhenNoSecCtx() {
- Assert.assertEquals(JWTSignatureValidationUtil.validateSignature(null, null, invalidJwtEventId),
+ Assert.assertEquals(JWTSignatureValidationUtil.validateSignature((SecurityParametersContext)null, null, invalidJwtEventId),
+ EventIds.INVALID_SEC_CFG);
+ }
+
+ @Test
+ public void validateSignature_shouldReturnInvalidSecCfgWhenNoSecCtxObject() {
+ final SecurityParametersContext secContext = null;
+ Assert.assertEquals(JWTSignatureValidationUtil.validateSignature(secContext, null, invalidJwtEventId),
EventIds.INVALID_SEC_CFG);
}
@@ -88,6 +96,7 @@ public class JWTSignatureValidationUtilTest {
Assert.assertEquals(JWTSignatureValidationUtil.validateSignature(secCtx, null, invalidJwtEventId),
EventIds.INVALID_SEC_CFG);
}
+
@Test
public void validateSignature_shouldReturnNullWhenValidRSASignature()
@@ -137,6 +146,21 @@ public class JWTSignatureValidationUtilTest {
signMAC(generateSecretKey()), invalidJwtEventId), invalidJwtEventId);
}
+
+ @Test
+ public void validateSignature_credentialOnly_shouldReturnNullWhenValidMACSignature()
+ throws JOSEException, ParseException {
+ Assert.assertNull(JWTSignatureValidationUtil.validateSignature(List.of(sharedCredential),
+ signMAC(sharedCredential.getSecretKey()), invalidJwtEventId));
+ }
+
+ @Test
+ public void validateSignature_credentialOnly_shouldReturnEventIdWhenInvalidMACSignature()
+ throws JOSEException, ParseException {
+ Assert.assertEquals(JWTSignatureValidationUtil.validateSignature(List.of(sharedCredential),
+ signMAC(generateSecretKey()), invalidJwtEventId), invalidJwtEventId);
+
+ }
protected SignedJWT signRSA(final PrivateKey privateKey) throws JOSEException, ParseException {
final JWSSigner signer = new RSASSASigner(privateKey);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list