Repository: cxf Updated Branches: refs/heads/3.0.x-fixes ecf962521 -> b491cea02
Adding a JWS PSSHA test Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/b491cea0 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/b491cea0 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/b491cea0 Branch: refs/heads/3.0.x-fixes Commit: b491cea028d7f86edc849c52edeadc1aa99f70c5 Parents: ecf9625 Author: Sergey Beryozkin <[email protected]> Authored: Thu Dec 11 13:05:59 2014 +0000 Committer: Sergey Beryozkin <[email protected]> Committed: Thu Dec 11 13:06:49 2014 +0000 ---------------------------------------------------------------------- .../cxf/rs/security/jose/JoseConstants.java | 3 +++ .../cxf/rs/security/jose/jwa/Algorithm.java | 23 ++++++++++++++++-- .../jws/PrivateKeyJwsSignatureProvider.java | 3 ++- .../jose/jws/PublicKeyJwsSignatureVerifier.java | 2 +- .../jose/jws/JwsCompactReaderWriterTest.java | 25 ++++++++++++++++++++ 5 files changed, 52 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/b491cea0/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java index b268129..cd719d4 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java @@ -51,6 +51,9 @@ public final class JoseConstants { public static final String RS_SHA_256_ALGO = "RS256"; public static final String RS_SHA_384_ALGO = "RS384"; public static final String RS_SHA_512_ALGO = "RS512"; + public static final String PS_SHA_256_ALGO = "PS256"; + public static final String PS_SHA_384_ALGO = "PS384"; + public static final String PS_SHA_512_ALGO = "PS512"; public static final String ES_SHA_256_ALGO = "ES256"; public static final String ES_SHA_384_ALGO = "ES384"; public static final String ES_SHA_512_ALGO = "ES512"; http://git-wip-us.apache.org/repos/asf/cxf/blob/b491cea0/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/Algorithm.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/Algorithm.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/Algorithm.java index 6de807d..056ddc4 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/Algorithm.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/Algorithm.java @@ -73,6 +73,9 @@ public enum Algorithm { public static final String RS_SHA_256_JAVA = "SHA256withRSA"; public static final String RS_SHA_384_JAVA = "SHA384withRSA"; public static final String RS_SHA_512_JAVA = "SHA512withRSA"; + public static final String PS_SHA_256_JAVA = "SHA256withRSAandMGF1"; + public static final String PS_SHA_384_JAVA = "SHA384withRSAandMGF1"; + public static final String PS_SHA_512_JAVA = "SHA512withRSAandMGF1"; public static final String ES_SHA_256_JAVA = "SHA256withECDSA"; public static final String ES_SHA_384_JAVA = "SHA384withECDSA"; public static final String ES_SHA_512_JAVA = "SHA512withECDSA"; @@ -90,6 +93,10 @@ public enum Algorithm { public static final Set<String> RSA_SHA_SIGN_SET = new HashSet<String>(Arrays.asList(JoseConstants.RS_SHA_256_ALGO, JoseConstants.RS_SHA_384_ALGO, JoseConstants.RS_SHA_512_ALGO)); + public static final Set<String> RSA_SHA_PS_SIGN_SET = + new HashSet<String>(Arrays.asList(JoseConstants.PS_SHA_256_ALGO, + JoseConstants.PS_SHA_384_ALGO, + JoseConstants.PS_SHA_512_ALGO)); public static final Set<String> EC_SHA_SIGN_SET = new HashSet<String>(Arrays.asList(JoseConstants.ES_SHA_256_ALGO, JoseConstants.ES_SHA_384_ALGO, JoseConstants.ES_SHA_512_ALGO)); @@ -124,6 +131,9 @@ public enum Algorithm { JAVA_TO_JWT_NAMES.put(RS_SHA_256_JAVA, JoseConstants.RS_SHA_256_ALGO); JAVA_TO_JWT_NAMES.put(RS_SHA_384_JAVA, JoseConstants.RS_SHA_384_ALGO); JAVA_TO_JWT_NAMES.put(RS_SHA_512_JAVA, JoseConstants.RS_SHA_512_ALGO); + JAVA_TO_JWT_NAMES.put(PS_SHA_256_JAVA, JoseConstants.PS_SHA_256_ALGO); + JAVA_TO_JWT_NAMES.put(PS_SHA_384_JAVA, JoseConstants.PS_SHA_384_ALGO); + JAVA_TO_JWT_NAMES.put(PS_SHA_512_JAVA, JoseConstants.PS_SHA_512_ALGO); JAVA_TO_JWT_NAMES.put(ES_SHA_256_JAVA, JoseConstants.ES_SHA_256_ALGO); JAVA_TO_JWT_NAMES.put(ES_SHA_384_JAVA, JoseConstants.ES_SHA_384_ALGO); JAVA_TO_JWT_NAMES.put(ES_SHA_512_JAVA, JoseConstants.ES_SHA_512_ALGO); @@ -146,6 +156,9 @@ public enum Algorithm { JWT_TO_JAVA_NAMES.put(JoseConstants.RS_SHA_256_ALGO, RS_SHA_256_JAVA); JWT_TO_JAVA_NAMES.put(JoseConstants.RS_SHA_384_ALGO, RS_SHA_384_JAVA); JWT_TO_JAVA_NAMES.put(JoseConstants.RS_SHA_512_ALGO, RS_SHA_512_JAVA); + JWT_TO_JAVA_NAMES.put(JoseConstants.PS_SHA_256_ALGO, PS_SHA_256_JAVA); + JWT_TO_JAVA_NAMES.put(JoseConstants.PS_SHA_384_ALGO, PS_SHA_384_JAVA); + JWT_TO_JAVA_NAMES.put(JoseConstants.PS_SHA_512_ALGO, PS_SHA_512_JAVA); JWT_TO_JAVA_NAMES.put(JoseConstants.ES_SHA_256_ALGO, ES_SHA_256_JAVA); JWT_TO_JAVA_NAMES.put(JoseConstants.ES_SHA_384_ALGO, ES_SHA_384_JAVA); JWT_TO_JAVA_NAMES.put(JoseConstants.ES_SHA_512_ALGO, ES_SHA_512_JAVA); @@ -221,7 +234,7 @@ public enum Algorithm { return javaName; } public static boolean isRsa(String algo) { - return isRsa(algo) || isRsaShaSign(algo); + return isRsaKeyWrap(algo) || isRsaSign(algo); } public static boolean isRsaKeyWrap(String algo) { return RSA_CEK_SET.contains(algo); @@ -250,10 +263,16 @@ public enum Algorithm { || isAesGcm(algo) || isAesGcmKeyWrap(algo) || isAesKeyWrap(algo); - } + } + public static boolean isRsaSign(String algo) { + return isRsaShaSign(algo) || isRsaShaPsSign(algo); + } public static boolean isRsaShaSign(String algo) { return RSA_SHA_SIGN_SET.contains(algo); } + public static boolean isRsaShaPsSign(String algo) { + return RSA_SHA_PS_SIGN_SET.contains(algo); + } public static boolean isEcDsaSign(String algo) { return EC_SHA_SIGN_SET.contains(algo); } http://git-wip-us.apache.org/repos/asf/cxf/blob/b491cea0/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PrivateKeyJwsSignatureProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PrivateKeyJwsSignatureProvider.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PrivateKeyJwsSignatureProvider.java index 1f38972..2f84f54 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PrivateKeyJwsSignatureProvider.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PrivateKeyJwsSignatureProvider.java @@ -62,10 +62,11 @@ public class PrivateKeyJwsSignatureProvider extends AbstractJwsSignatureProvider if (!isValidAlgorithmFamily(algo)) { throw new SecurityException(); } + //TODO: validate "A key of size 2048 bits or larger MUST be used" for PS-SHA algorithms } protected boolean isValidAlgorithmFamily(String algo) { - return Algorithm.isRsaShaSign(algo); + return Algorithm.isRsaSign(algo); } protected static class PrivateKeyJwsSignature implements JwsSignature { http://git-wip-us.apache.org/repos/asf/cxf/blob/b491cea0/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PublicKeyJwsSignatureVerifier.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PublicKeyJwsSignatureVerifier.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PublicKeyJwsSignatureVerifier.java index 3ff9d66..70842cf 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PublicKeyJwsSignatureVerifier.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PublicKeyJwsSignatureVerifier.java @@ -60,7 +60,7 @@ public class PublicKeyJwsSignatureVerifier implements JwsSignatureVerifier { return algo; } protected boolean isValidAlgorithmFamily(String algo) { - return Algorithm.isRsaShaSign(algo); + return Algorithm.isRsaSign(algo); } @Override public String getAlgorithm() { http://git-wip-us.apache.org/repos/asf/cxf/blob/b491cea0/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsCompactReaderWriterTest.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsCompactReaderWriterTest.java b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsCompactReaderWriterTest.java index 6b34b94..df709d6 100644 --- a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsCompactReaderWriterTest.java +++ b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsCompactReaderWriterTest.java @@ -19,6 +19,7 @@ package org.apache.cxf.rs.security.jose.jws; import java.security.PrivateKey; +import java.security.Security; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.interfaces.RSAPublicKey; @@ -36,6 +37,7 @@ import org.apache.cxf.rs.security.jose.jwt.JwtClaims; import org.apache.cxf.rs.security.jose.jwt.JwtToken; import org.apache.cxf.rs.security.jose.jwt.JwtTokenReaderWriter; import org.apache.cxf.rs.security.jose.jwt.JwtTokenWriter; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.junit.Assert; import org.junit.Test; @@ -210,6 +212,29 @@ public class JwsCompactReaderWriterTest extends Assert { assertEquals(ENCODED_TOKEN_SIGNED_BY_PRIVATE_KEY, jws.getSignedEncodedJws()); } + @Test + public void testJwsPsSha() throws Exception { + Security.addProvider(new BouncyCastleProvider()); + try { + JoseHeaders outHeaders = new JoseHeaders(); + outHeaders.setAlgorithm(JoseConstants.PS_SHA_256_ALGO); + JwsCompactProducer producer = initSpecJwtTokenWriter(outHeaders); + PrivateKey privateKey = CryptoUtils.getRSAPrivateKey(RSA_MODULUS_ENCODED, RSA_PRIVATE_EXPONENT_ENCODED); + String signed = producer.signWith( + new PrivateKeyJwsSignatureProvider(privateKey, JoseConstants.PS_SHA_256_ALGO)); + + JwsJwtCompactConsumer jws = new JwsJwtCompactConsumer(signed); + RSAPublicKey key = CryptoUtils.getRSAPublicKey(RSA_MODULUS_ENCODED, RSA_PUBLIC_EXPONENT_ENCODED); + assertTrue(jws.verifySignatureWith(new PublicKeyJwsSignatureVerifier(key, + JoseConstants.PS_SHA_256_ALGO))); + JwtToken token = jws.getJwtToken(); + JoseHeaders inHeaders = token.getHeaders(); + assertEquals(JoseConstants.PS_SHA_256_ALGO, inHeaders.getAlgorithm()); + validateSpecClaim(token.getClaims()); + } finally { + Security.removeProvider(BouncyCastleProvider.class.getName()); + } + } @Test public void testWriteReadJwsSignedByESPrivateKey() throws Exception {
