cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject git commit: [CXF-5311] Adding a signature test with EC keys
Date Tue, 22 Jul 2014 15:22:28 GMT
Repository: cxf
Updated Branches:
  refs/heads/master 903b25083 -> a46e5d411


[CXF-5311] Adding a signature test with EC keys


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/a46e5d41
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/a46e5d41
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/a46e5d41

Branch: refs/heads/master
Commit: a46e5d4114a59763d550d1cc80a4b57a4d7bba82
Parents: 903b250
Author: Sergey Beryozkin <sberyozkin@talend.com>
Authored: Tue Jul 22 18:22:08 2014 +0300
Committer: Sergey Beryozkin <sberyozkin@talend.com>
Committed: Tue Jul 22 18:22:08 2014 +0300

----------------------------------------------------------------------
 .../oauth2/jws/EcDsaJwsSignatureProvider.java   | 45 ++++++++++++++++
 .../jws/PrivateKeyJwsSignatureProvider.java     | 11 +++-
 .../cxf/rs/security/oauth2/jwt/Algorithm.java   | 13 +++++
 .../rs/security/oauth2/jwt/JwtConstants.java    |  3 ++
 .../oauth2/jws/JwsCompactReaderWriterTest.java  | 27 +++++++++-
 .../oauth2/utils/crypto/CryptoUtils.java        | 57 +++++++++++++++++++-
 6 files changed, 152 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/a46e5d41/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/EcDsaJwsSignatureProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/EcDsaJwsSignatureProvider.java
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/EcDsaJwsSignatureProvider.java
new file mode 100644
index 0000000..8077cf3
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/EcDsaJwsSignatureProvider.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.oauth2.jws;
+
+import java.security.SecureRandom;
+import java.security.interfaces.ECPrivateKey;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.cxf.rs.security.oauth2.jwt.Algorithm;
+
+public class EcDsaJwsSignatureProvider extends PrivateKeyJwsSignatureProvider {
+    private static final Set<String> SUPPORTED_ALGORITHMS = new HashSet<String>(
+        Arrays.asList(Algorithm.SHA256withECDSA.getJwtName(),
+                      Algorithm.SHA384withECDSA.getJwtName(),
+                      Algorithm.SHA512withECDSA.getJwtName())); 
+    
+    public EcDsaJwsSignatureProvider(ECPrivateKey key) {
+        this(key, null);
+    }
+    public EcDsaJwsSignatureProvider(ECPrivateKey key, AlgorithmParameterSpec spec) {
+        this(key, null, spec);
+    }
+    public EcDsaJwsSignatureProvider(ECPrivateKey key, SecureRandom random, AlgorithmParameterSpec
spec) {
+        super(key, random, spec, SUPPORTED_ALGORITHMS);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/a46e5d41/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/PrivateKeyJwsSignatureProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/PrivateKeyJwsSignatureProvider.java
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/PrivateKeyJwsSignatureProvider.java
index aebc1e4..62efdf0 100644
--- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/PrivateKeyJwsSignatureProvider.java
+++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/PrivateKeyJwsSignatureProvider.java
@@ -46,8 +46,15 @@ public class PrivateKeyJwsSignatureProvider extends AbstractJwsSignatureProvider
     public PrivateKeyJwsSignatureProvider(PrivateKey key, AlgorithmParameterSpec spec) {
         this(key, null, spec);
     }
-    public PrivateKeyJwsSignatureProvider(PrivateKey key, SecureRandom random, AlgorithmParameterSpec
spec) {
-        super(SUPPORTED_ALGORITHMS);
+    public PrivateKeyJwsSignatureProvider(PrivateKey key, SecureRandom random, 
+                                          AlgorithmParameterSpec spec) {
+        this(key, random, spec, SUPPORTED_ALGORITHMS);
+    }
+    protected PrivateKeyJwsSignatureProvider(PrivateKey key, 
+                                             SecureRandom random, 
+                                             AlgorithmParameterSpec spec,
+                                             Set<String> supportedAlgorithms) {
+        super(supportedAlgorithms);
         this.key = key;
         this.random = random;
         this.signatureSpec = spec;

http://git-wip-us.apache.org/repos/asf/cxf/blob/a46e5d41/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/Algorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/Algorithm.java
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/Algorithm.java
index c6c7afc..19382db 100644
--- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/Algorithm.java
+++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/Algorithm.java
@@ -35,6 +35,10 @@ public enum Algorithm {
     SHA384withRSA(JwtConstants.RS_SHA_384_ALGO, 384),
     SHA512withRSA(JwtConstants.RS_SHA_512_ALGO, 512),
     
+    SHA256withECDSA(JwtConstants.ES_SHA_256_ALGO, 256),
+    SHA384withECDSA(JwtConstants.ES_SHA_384_ALGO, 384),
+    SHA512withECDSA(JwtConstants.ES_SHA_512_ALGO, 512),
+    
     // Key Encryption
     RSA_OAEP(JwtConstants.RSA_OAEP_ALGO, "RSA/ECB/OAEPWithSHA-1AndMGF1Padding", -1),
     // Content Encryption
@@ -48,6 +52,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 ES_SHA_256_JAVA = "SHA256withECDSA";
+    public static final String ES_SHA_384_JAVA = "SHA384withECDSA";
+    public static final String ES_SHA_512_JAVA = "SHA512withECDSA";
     public static final String RSA_OAEP_ALGO_JAVA = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding";
     public static final String RSA_OAEP_256_ALGO_JAVA = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
     public static final String RSA_1_5_ALGO_JAVA = "RSA/ECB/PKCS1Padding";
@@ -64,6 +71,9 @@ public enum Algorithm {
         JAVA_TO_JWT_NAMES.put(RS_SHA_256_JAVA, JwtConstants.RS_SHA_256_ALGO);
         JAVA_TO_JWT_NAMES.put(RS_SHA_384_JAVA, JwtConstants.RS_SHA_384_ALGO);
         JAVA_TO_JWT_NAMES.put(RS_SHA_512_JAVA, JwtConstants.RS_SHA_512_ALGO);
+        JAVA_TO_JWT_NAMES.put(ES_SHA_256_JAVA, JwtConstants.ES_SHA_256_ALGO);
+        JAVA_TO_JWT_NAMES.put(ES_SHA_384_JAVA, JwtConstants.ES_SHA_384_ALGO);
+        JAVA_TO_JWT_NAMES.put(ES_SHA_512_JAVA, JwtConstants.ES_SHA_512_ALGO);
         JAVA_TO_JWT_NAMES.put(RSA_OAEP_ALGO_JAVA, JwtConstants.RSA_OAEP_ALGO);
         JAVA_TO_JWT_NAMES.put(RSA_OAEP_256_ALGO_JAVA, JwtConstants.RSA_OAEP_256_ALGO);
         JAVA_TO_JWT_NAMES.put(RSA_1_5_ALGO_JAVA, JwtConstants.RSA_1_5_ALGO);
@@ -74,6 +84,9 @@ public enum Algorithm {
         JWT_TO_JAVA_NAMES.put(JwtConstants.RS_SHA_256_ALGO, RS_SHA_256_JAVA);
         JWT_TO_JAVA_NAMES.put(JwtConstants.RS_SHA_384_ALGO, RS_SHA_384_JAVA);
         JWT_TO_JAVA_NAMES.put(JwtConstants.RS_SHA_512_ALGO, RS_SHA_512_JAVA);
+        JWT_TO_JAVA_NAMES.put(JwtConstants.ES_SHA_256_ALGO, ES_SHA_256_JAVA);
+        JWT_TO_JAVA_NAMES.put(JwtConstants.ES_SHA_384_ALGO, ES_SHA_384_JAVA);
+        JWT_TO_JAVA_NAMES.put(JwtConstants.ES_SHA_512_ALGO, ES_SHA_512_JAVA);
         JWT_TO_JAVA_NAMES.put(JwtConstants.RSA_OAEP_ALGO, RSA_OAEP_ALGO_JAVA);
         JWT_TO_JAVA_NAMES.put(JwtConstants.RSA_OAEP_256_ALGO, RSA_OAEP_256_ALGO_JAVA);
         JWT_TO_JAVA_NAMES.put(JwtConstants.RSA_1_5_ALGO, RSA_1_5_ALGO_JAVA);

http://git-wip-us.apache.org/repos/asf/cxf/blob/a46e5d41/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtConstants.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtConstants.java
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtConstants.java
index 25ab366..e6eee3d 100644
--- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtConstants.java
+++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtConstants.java
@@ -57,6 +57,9 @@ public final class JwtConstants {
     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 ES_SHA_256_ALGO = "ES256";
+    public static final String ES_SHA_384_ALGO = "ES384";
+    public static final String ES_SHA_512_ALGO = "ES512";
     public static final String RSA_OAEP_ALGO = "RSA-OAEP";
     public static final String RSA_OAEP_256_ALGO = "RSA-OAEP-256";
     public static final String RSA_1_5_ALGO = "RSA1_5";

http://git-wip-us.apache.org/repos/asf/cxf/blob/a46e5d41/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jws/JwsCompactReaderWriterTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jws/JwsCompactReaderWriterTest.java
b/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jws/JwsCompactReaderWriterTest.java
index 83e3c86..026575a 100644
--- a/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jws/JwsCompactReaderWriterTest.java
+++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jws/JwsCompactReaderWriterTest.java
@@ -19,6 +19,8 @@
 package org.apache.cxf.rs.security.oauth2.jws;
 
 import java.security.PrivateKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
 import java.security.interfaces.RSAPublicKey;
 import java.util.Arrays;
 import java.util.LinkedHashMap;
@@ -82,6 +84,12 @@ public class JwsCompactReaderWriterTest extends Assert {
         + "hJ1phCnvWh6IeYI2w9QOYEUipUTI8np6LbgGY9Fs98rqVt5AXLIhWkWywlVmtVrB"
         + "p0igcN_IoypGlUPQGe77Rw";
      
+    private static final String EC_PRIVATE_KEY_ENCODED = 
+        "jpsQnnGQmL-YBIffH1136cspYG6-0iY7X1fCE9-E9LI";
+    private static final String EC_X_POINT_ENCODED = 
+        "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU";
+    private static final String EC_Y_POINT_ENCODED = 
+        "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0";
     @Test
     public void testWriteJwsSignedByMacSpecExample() throws Exception {
         JwtHeaders headers = new JwtHeaders(Algorithm.HmacSHA256.getJwtName());
@@ -186,7 +194,7 @@ public class JwsCompactReaderWriterTest extends Assert {
     }
     
     @Test
-    public void testWriteReadJwsSignedByPrivateKey() throws Exception {
+    public void testWriteJwsSignedByPrivateKey() throws Exception {
         JwtHeaders headers = new JwtHeaders();
         headers.setAlgorithm(Algorithm.SHA256withRSA.getJwtName());
         JwsCompactProducer jws = initSpecJwtTokenWriter(headers);
@@ -197,6 +205,23 @@ public class JwsCompactReaderWriterTest extends Assert {
     }
     
     @Test
+    public void testWriteReadJwsSignedByESPrivateKey() throws Exception {
+        JwtHeaders headers = new JwtHeaders();
+        headers.setAlgorithm(Algorithm.SHA256withECDSA.getJwtName());
+        JwsCompactProducer jws = initSpecJwtTokenWriter(headers);
+        ECPrivateKey privateKey = CryptoUtils.getECPrivateKey(EC_PRIVATE_KEY_ENCODED);
+        jws.signWith(new EcDsaJwsSignatureProvider(privateKey));
+        String signedJws = jws.getSignedEncodedJws();
+        ECPublicKey publicKey = CryptoUtils.getECPublicKey(EC_X_POINT_ENCODED, EC_Y_POINT_ENCODED);
+        JwsJwtCompactConsumer jwsConsumer = new JwsJwtCompactConsumer(signedJws);
+        assertTrue(jwsConsumer.verifySignatureWith(new PublicKeyJwsSignatureVerifier(publicKey)));
+        JwtToken token = jwsConsumer.getJwtToken();
+        JwtHeaders headersReceived = token.getHeaders();
+        assertEquals(Algorithm.SHA256withECDSA.getJwtName(), headersReceived.getAlgorithm());
+        validateSpecClaim(token.getClaims());
+    }
+    
+    @Test
     public void testReadJwsSignedByPrivateKey() throws Exception {
         JwsJwtCompactConsumer jws = new JwsJwtCompactConsumer(ENCODED_TOKEN_SIGNED_BY_PRIVATE_KEY);
         RSAPublicKey key = CryptoUtils.getRSAPublicKey(RSA_MODULUS_ENCODED, RSA_PUBLIC_EXPONENT_ENCODED);

http://git-wip-us.apache.org/repos/asf/cxf/blob/a46e5d41/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java
index 23cc8b7..69edbfc 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java
@@ -25,6 +25,7 @@ import java.lang.reflect.Method;
 import java.math.BigInteger;
 import java.security.Key;
 import java.security.KeyFactory;
+import java.security.KeyPairGenerator;
 import java.security.KeyStore;
 import java.security.Principal;
 import java.security.PrivateKey;
@@ -32,9 +33,16 @@ import java.security.PublicKey;
 import java.security.SecureRandom;
 import java.security.Signature;
 import java.security.cert.Certificate;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
 import java.security.interfaces.RSAPrivateKey;
 import java.security.interfaces.RSAPublicKey;
 import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPrivateKeySpec;
+import java.security.spec.ECPublicKeySpec;
 import java.security.spec.RSAPrivateKeySpec;
 import java.security.spec.RSAPublicKeySpec;
 import java.util.Properties;
@@ -284,7 +292,54 @@ public final class CryptoUtils {
             throw new SecurityException(ex);
         }
     }
-     
+    public static ECPrivateKey getECPrivateKey(String encodedPrivateKey) {
+        try {
+            return getECPrivateKey(Base64UrlUtility.decode(encodedPrivateKey));
+        } catch (Exception ex) { 
+            throw new SecurityException(ex);
+        }
+    }
+    public static ECPrivateKey getECPrivateKey(byte[] privateKey) {
+        try {
+            KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
+            ECGenParameterSpec kpgparams = new ECGenParameterSpec("secp256r1");
+            kpg.initialize(kpgparams);
+            ECParameterSpec params = ((ECPublicKey) kpg.generateKeyPair().getPublic()).getParams();
+
+            ECPrivateKeySpec keySpec = new ECPrivateKeySpec(
+                                           new BigInteger(1, privateKey), params);
+            KeyFactory kf = KeyFactory.getInstance("EC");
+            return (ECPrivateKey) kf.generatePrivate(keySpec);
+
+        } catch (Exception ex) { 
+            throw new SecurityException(ex);
+        }    
+    }
+    public static ECPublicKey getECPublicKey(String encodedXPoint, String encodedYPoint)
{
+        try {
+            return getECPublicKey(Base64UrlUtility.decode(encodedXPoint),
+                                  Base64UrlUtility.decode(encodedYPoint));
+        } catch (Exception ex) { 
+            throw new SecurityException(ex);
+        }
+    }
+    public static ECPublicKey getECPublicKey(byte[] xPoint, byte[] yPoint) {
+        try {
+            KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
+            ECGenParameterSpec kpgparams = new ECGenParameterSpec("secp256r1");
+            kpg.initialize(kpgparams);
+            ECParameterSpec params = ((ECPublicKey) kpg.generateKeyPair().getPublic()).getParams();
+
+            ECPoint ecPoint = new ECPoint(new BigInteger(1, xPoint),
+                                          new BigInteger(1, yPoint));
+            ECPublicKeySpec keySpec = new ECPublicKeySpec(ecPoint, params);
+            KeyFactory kf = KeyFactory.getInstance("EC");
+            return (ECPublicKey) kf.generatePublic(keySpec);
+
+        } catch (Exception ex) { 
+            throw new SecurityException(ex);
+        }    
+    }
     public static AlgorithmParameterSpec getContentEncryptionCipherSpec(int authTagLength,
byte[] iv) {
         // this can be overridden if needed
         if (authTagLength > 0) {


Mime
View raw message