From d763a954da5e13d42851ba0e085cdf8f0e710ce3 Mon Sep 17 00:00:00 2001 From: William Kim Date: Mon, 26 Aug 2013 11:33:21 -0400 Subject: [PATCH] placeholder --- .../org/mitre/jwt/signer/PlainSigner.java | 2 +- .../org/mitre/jwt/signer/PlainVerifier.java | 14 +++- ...DefaultJwtSigningAndValidationService.java | 75 +++++++++++++++---- 3 files changed, 76 insertions(+), 15 deletions(-) diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/PlainSigner.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/PlainSigner.java index 1252a79ee..bd47401ae 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/PlainSigner.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/signer/PlainSigner.java @@ -33,7 +33,7 @@ import com.nimbusds.jose.util.Base64URL; * @author wkim * */ -public class PlainSigner implements JWSSigner { +public final class PlainSigner implements JWSSigner { @Override diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/PlainVerifier.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/PlainVerifier.java index b689eb54d..56486d14c 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/PlainVerifier.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/signer/PlainVerifier.java @@ -28,6 +28,7 @@ import com.nimbusds.jose.PlainHeader; import com.nimbusds.jose.ReadOnlyJWSHeader; import com.nimbusds.jose.Requirement; import com.nimbusds.jose.util.Base64URL; +import com.nimbusds.jwt.PlainJWT; /** * Verifier to support "alg:none" JWS signing option (no signature). @@ -35,7 +36,7 @@ import com.nimbusds.jose.util.Base64URL; * @author wkim * */ -public class PlainVerifier implements JWSVerifier { +public final class PlainVerifier implements JWSVerifier { // the NONE alg constant lives in the Algorithm superclass of JWSAlgorithm, not allowing its use as a JWSAlgorithm object. // redefining the constant here for convenience. @@ -77,5 +78,16 @@ public class PlainVerifier implements JWSVerifier { } } + + /** + * Verifies that the third signature component of the JWT is null. + * + * @param jwt + * @return + */ + public static boolean verify(PlainJWT jwt) { + + return jwt.getParsedParts()[2] == null; + } } diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/DefaultJwtSigningAndValidationService.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/DefaultJwtSigningAndValidationService.java index cd1f083b5..468396003 100644 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/DefaultJwtSigningAndValidationService.java +++ b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/DefaultJwtSigningAndValidationService.java @@ -27,6 +27,8 @@ import java.util.Set; import javax.annotation.PostConstruct; import org.mitre.jose.keystore.JWKSetKeyStore; +import org.mitre.jwt.signer.PlainSigner; +import org.mitre.jwt.signer.PlainVerifier; import org.mitre.jwt.signer.service.JwtSigningAndValidationService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,6 +38,7 @@ import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.JWSSigner; import com.nimbusds.jose.JWSVerifier; +import com.nimbusds.jose.PlainHeader; import com.nimbusds.jose.crypto.MACSigner; import com.nimbusds.jose.crypto.MACVerifier; import com.nimbusds.jose.crypto.RSASSASigner; @@ -44,10 +47,14 @@ import com.nimbusds.jose.jwk.ECKey; import com.nimbusds.jose.jwk.JWK; import com.nimbusds.jose.jwk.OctetSequenceKey; import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jwt.JWT; +import com.nimbusds.jwt.PlainJWT; import com.nimbusds.jwt.SignedJWT; public class DefaultJwtSigningAndValidationService implements JwtSigningAndValidationService { + public static final String ALG_NONE = "none"; // TODO storing a default "alg:none" id smells a bit.. + // map of identifier to signer private Map signers = new HashMap(); @@ -156,6 +163,11 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid * @throws NoSuchAlgorithmException If there is no appropriate algorithm to tie the keys to. */ private void buildSignersAndVerifiers() throws NoSuchAlgorithmException, InvalidKeySpecException { + + signers.put(ALG_NONE, new PlainSigner()); + verifiers.put(ALG_NONE, new PlainVerifier()); + + for (Map.Entry jwkEntry : keys.entrySet()) { String id = jwkEntry.getKey(); @@ -199,7 +211,7 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid * Sign a jwt in place using the configured default signer. */ @Override - public void signJwt(SignedJWT jwt) { + public void signJwt(JWT jwt) { if (getDefaultSignerKeyId() == null) { throw new IllegalStateException("Tried to call default signing with no default signer ID set"); } @@ -207,7 +219,22 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid JWSSigner signer = signers.get(getDefaultSignerKeyId()); try { - jwt.sign(signer); + + // the sign() method is not a part of the JWT interface, + // hence this if/else structure. + if (signer instanceof PlainSigner) { + + if (!(jwt instanceof PlainJWT)) { + throw new JOSEException("This JWT object is not a plain JWT."); + } + + // At this point, this is a plain JWT and is already good-to-go. + + } else { // we have a signable JWS at this point. + + ((SignedJWT) jwt).sign(signer); + + } } catch (JOSEException e) { logger.error("Failed to sign JWT, error was: ", e); @@ -216,7 +243,7 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid } @Override - public void signJwt(SignedJWT jwt, JWSAlgorithm alg) { + public void signJwt(JWT jwt, JWSAlgorithm alg) { JWSSigner signer = null; @@ -227,23 +254,43 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid } } - if (signer == null) { - //If we can't find an algorithm that matches, we can't sign - logger.error("No matching algirthm found for alg=" + alg); - - } - try { - jwt.sign(signer); + + if (signer == null) { + //If we can't find an algorithm that matches, we can't sign + logger.error("No matching algirthm found for alg=" + alg); + + } else if (signer instanceof PlainSigner) { + + if (!(jwt.getHeader() instanceof PlainHeader)) { + + throw new JOSEException("Invalid header. This signer is for use with Plain JWTs only."); + + } + + // do nothing because PlainJWT is good already. + + } else { // we have a signable JWS at this point. + + ((SignedJWT) jwt).sign(signer); + + } + } catch (JOSEException e) { - + logger.error("Failed to sign JWT, error was: ", e); } - } @Override - public boolean validateSignature(SignedJWT jwt) { + public boolean validateSignature(JWT jwt) { + + if (getDefaultSigningAlgorithm().equals(JWSAlgorithm.NONE) { + + if (jwt instanceof PlainJWT) { + return + } + } for (JWSVerifier verifier : verifiers.values()) { try { @@ -281,6 +328,8 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid public Collection getAllSigningAlgsSupported() { Set algs = new HashSet(); + + //TODO add 'none' for (JWSSigner signer : signers.values()) { algs.addAll(signer.supportedAlgorithms());