Repository: cxf Updated Branches: refs/heads/master ca1f38bcb -> 8847306b7
Enforcing that a minimum key size of 2048 bits is used with RSA keys Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/8847306b Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/8847306b Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/8847306b Branch: refs/heads/master Commit: 8847306b7ff58589fd7e990a990b6b3a2797a9ac Parents: ca1f38b Author: Colm O hEigeartaigh <[email protected]> Authored: Tue Oct 20 15:11:23 2015 +0100 Committer: Colm O hEigeartaigh <[email protected]> Committed: Tue Oct 20 15:11:23 2015 +0100 ---------------------------------------------------------------------- .../cxf/rs/security/jose/jwe/JweUtils.java | 11 +++- .../jose/jwe/RSAKeyDecryptionAlgorithm.java | 1 + .../cxf/rs/security/jose/jws/JwsUtils.java | 10 +++ .../jose/jws/PublicKeyJwsSignatureVerifier.java | 1 + .../jaxrs/security/jwt/JweJwsAlgorithmTest.java | 61 ++++++++++++++++++- .../jaxrs/security/jwt/algorithms-server.xml | 37 +++++++++++ .../jaxrs/security/certs/smallkeysize.jks | Bin 0 -> 1309 bytes 7 files changed, 119 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/8847306b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java index 5032518..5e6aece 100644 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java +++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java @@ -19,11 +19,13 @@ package org.apache.cxf.rs.security.jose.jwe; import java.nio.ByteBuffer; +import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.X509Certificate; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; +import java.security.interfaces.RSAKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.Arrays; @@ -658,5 +660,12 @@ public final class JweUtils { JoseConstants.RSSEC_ENCRYPTION_PROPS); KeyManagementUtils.validateCertificateChain(props, certs); } - + + public static void checkEncryptionKeySize(Key key) { + if (key instanceof RSAKey && ((RSAKey)key).getModulus().bitLength() < 2048) { + LOG.fine("A key of size: " + ((RSAKey)key).getModulus().bitLength() + + " was used with an RSA encryption algorithm. 2048 is the minimum size that is accepted"); + throw new JweException(JweException.Error.KEY_DECRYPTION_FAILURE); + } + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/8847306b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/RSAKeyDecryptionAlgorithm.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/RSAKeyDecryptionAlgorithm.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/RSAKeyDecryptionAlgorithm.java index d29b442..6950b3d 100644 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/RSAKeyDecryptionAlgorithm.java +++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/RSAKeyDecryptionAlgorithm.java @@ -32,6 +32,7 @@ public class RSAKeyDecryptionAlgorithm extends WrappedKeyDecryptionAlgorithm { } public RSAKeyDecryptionAlgorithm(RSAPrivateKey privateKey, KeyAlgorithm supportedAlgo, boolean unwrap) { super(privateKey, supportedAlgo, unwrap); + JweUtils.checkEncryptionKeySize(privateKey); } protected int getKeyCipherBlockSize() { return ((RSAPrivateKey)getCekDecryptionKey()).getModulus().toByteArray().length; http://git-wip-us.apache.org/repos/asf/cxf/blob/8847306b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java index 02a4940..27e2e0f 100644 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java +++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java @@ -18,11 +18,13 @@ */ package org.apache.cxf.rs.security.jose.jws; +import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.X509Certificate; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; +import java.security.interfaces.RSAKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.ArrayList; @@ -412,4 +414,12 @@ public final class JwsUtils { public static boolean isPayloadUnencoded(JwsHeaders jwsHeaders) { return jwsHeaders.getPayloadEncodingStatus() == Boolean.FALSE; } + + public static void checkSignatureKeySize(Key key) { + if (key instanceof RSAKey && ((RSAKey)key).getModulus().bitLength() < 2048) { + LOG.fine("A key of size: " + ((RSAKey)key).getModulus().bitLength() + + " was used with an RSA signature algorithm. 2048 is the minimum size that is accepted"); + throw new JwsException(JwsException.Error.INVALID_KEY); + } + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/8847306b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/PublicKeyJwsSignatureVerifier.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/PublicKeyJwsSignatureVerifier.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/PublicKeyJwsSignatureVerifier.java index 917890f..65a2a15 100644 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/PublicKeyJwsSignatureVerifier.java +++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/PublicKeyJwsSignatureVerifier.java @@ -41,6 +41,7 @@ public class PublicKeyJwsSignatureVerifier implements JwsSignatureVerifier { this.key = key; this.signatureSpec = spec; this.supportedAlgo = supportedAlgo; + JwsUtils.checkSignatureKeySize(key); } @Override public boolean verify(JwsHeaders headers, String unsignedText, byte[] signature) { http://git-wip-us.apache.org/repos/asf/cxf/blob/8847306b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/JweJwsAlgorithmTest.java ---------------------------------------------------------------------- diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/JweJwsAlgorithmTest.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/JweJwsAlgorithmTest.java index eab8f62..fcdaafb 100644 --- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/JweJwsAlgorithmTest.java +++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/JweJwsAlgorithmTest.java @@ -204,6 +204,35 @@ public class JweJwsAlgorithmTest extends AbstractBusClientServerTestBase { assertNotEquals(response.getStatus(), 200); } + // 1024 bits not allowed with RSA according to the spec + @org.junit.Test + public void testSmallEncryptionKeySize() throws Exception { + URL busFile = JweJwsAlgorithmTest.class.getResource("client.xml"); + + List<Object> providers = new ArrayList<Object>(); + providers.add(new JacksonJsonProvider()); + providers.add(new JweWriterInterceptor()); + + String address = "http://localhost:" + PORT + "/jwesmallkey/bookstore/books"; + WebClient client = + WebClient.create(address, providers, busFile.toString()); + client.type("application/json").accept("application/json"); + + Map<String, Object> properties = new HashMap<String, Object>(); + properties.put("rs.security.keystore.type", "jks"); + properties.put("rs.security.keystore.alias", "smallkey"); + properties.put("rs.security.keystore.password", "security"); + properties.put("rs.security.keystore.file", + "org/apache/cxf/systest/jaxrs/security/certs/smallkeysize.jks"); + properties.put("rs.security.encryption.content.algorithm", "A128GCM"); + properties.put("rs.security.encryption.key.algorithm", "RSA-OAEP"); + WebClient.getConfig(client).getRequestContext().putAll(properties); + + Response response = client.post(new Book("book", 123L)); + assertNotEquals(response.getStatus(), 200); + } + + // // Signature tests // @@ -318,7 +347,7 @@ public class JweJwsAlgorithmTest extends AbstractBusClientServerTestBase { Response response = client.post(new Book("book", 123L)); assertNotEquals(response.getStatus(), 200); } - + @org.junit.Test public void testSignatureEllipticCurve() throws Exception { @@ -389,4 +418,34 @@ public class JweJwsAlgorithmTest extends AbstractBusClientServerTestBase { response = client.post(header + "." + payload + "." + sig2); assertNotEquals(response.getStatus(), 200); } + + // 1024 bits not allowed with RSA according to the spec + @org.junit.Test + public void testSmallSignatureKeySize() throws Exception { + + URL busFile = JweJwsAlgorithmTest.class.getResource("client.xml"); + + List<Object> providers = new ArrayList<Object>(); + providers.add(new JacksonJsonProvider()); + providers.add(new JwsWriterInterceptor()); + + String address = "http://localhost:" + PORT + "/jwssmallkey/bookstore/books"; + WebClient client = + WebClient.create(address, providers, busFile.toString()); + client.type("application/json").accept("application/json"); + + Map<String, Object> properties = new HashMap<String, Object>(); + properties.put("rs.security.keystore.type", "jks"); + properties.put("rs.security.keystore.alias", "smallkey"); + properties.put("rs.security.keystore.password", "security"); + properties.put("rs.security.key.password", "security"); + properties.put("rs.security.keystore.file", + "org/apache/cxf/systest/jaxrs/security/certs/smallkeysize.jks"); + properties.put("rs.security.signature.algorithm", "RS256"); + WebClient.getConfig(client).getRequestContext().putAll(properties); + + Response response = client.post(new Book("book", 123L)); + assertNotEquals(response.getStatus(), 200); + } + } http://git-wip-us.apache.org/repos/asf/cxf/blob/8847306b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/algorithms-server.xml ---------------------------------------------------------------------- diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/algorithms-server.xml b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/algorithms-server.xml index 39dfbac..faa2e35 100644 --- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/algorithms-server.xml +++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/algorithms-server.xml @@ -42,6 +42,25 @@ under the License. </jaxrs:properties> </jaxrs:server> + <jaxrs:server address="http://localhost:${testutil.ports.jaxrs-jwejws-algorithms}/jwesmallkey"> + <jaxrs:serviceBeans> + <ref bean="serviceBean"/> + </jaxrs:serviceBeans> + <jaxrs:providers> + <ref bean="jweInFilter"/> + </jaxrs:providers> + <jaxrs:properties> + <entry key="rs.security.keystore.type" value="jks"/> + <entry key="rs.security.keystore.alias" value="smallkey"/> + <entry key="rs.security.keystore.password" value="security"/> + <entry key="rs.security.key.password" value="security"/> + <entry key="rs.security.keystore.file" + value="org/apache/cxf/systest/jaxrs/security/certs/smallkeysize.jks"/> + <entry key="rs.security.encryption.content.algorithm" value="A128GCM"/> + <entry key="rs.security.encryption.key.algorithm" value="RSA-OAEP"/> + </jaxrs:properties> + </jaxrs:server> + <bean id="jwsInFilter" class="org.apache.cxf.rs.security.jose.jaxrs.JwsContainerRequestFilter"/> <jaxrs:server address="http://localhost:${testutil.ports.jaxrs-jwejws-algorithms}/jws"> @@ -73,4 +92,22 @@ under the License. </jaxrs:properties> </jaxrs:server> + <jaxrs:server address="http://localhost:${testutil.ports.jaxrs-jwejws-algorithms}/jwssmallkey"> + <jaxrs:serviceBeans> + <ref bean="serviceBean"/> + </jaxrs:serviceBeans> + <jaxrs:providers> + <ref bean="jwsInFilter"/> + </jaxrs:providers> + <jaxrs:properties> + <entry key="rs.security.keystore.type" value="jks"/> + <entry key="rs.security.keystore.alias" value="smallkey"/> + <entry key="rs.security.keystore.password" value="security"/> + <entry key="rs.security.key.password" value="security"/> + <entry key="rs.security.keystore.file" + value="org/apache/cxf/systest/jaxrs/security/certs/smallkeysize.jks"/> + <entry key="rs.security.signature.algorithm" value="RS256"/> + </jaxrs:properties> + </jaxrs:server> + </beans> http://git-wip-us.apache.org/repos/asf/cxf/blob/8847306b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/smallkeysize.jks ---------------------------------------------------------------------- diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/smallkeysize.jks b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/smallkeysize.jks new file mode 100644 index 0000000..4968921 Binary files /dev/null and b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/smallkeysize.jks differ
