Repository: cxf
Updated Branches:
  refs/heads/master 50cb750c6 -> b5409a6d6


[CXF-5311] Optional support for auto-generating content-encryption key and IV


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

Branch: refs/heads/master
Commit: b5409a6d64ab223097456004fe05a5cad1dd1a4e
Parents: 50cb750
Author: Sergey Beryozkin <[email protected]>
Authored: Fri May 23 13:54:35 2014 +0100
Committer: Sergey Beryozkin <[email protected]>
Committed: Fri May 23 13:54:35 2014 +0100

----------------------------------------------------------------------
 .../rs/security/oauth2/jwe/JweEncryptor.java    | 57 +++++++++++++-------
 .../cxf/rs/security/oauth2/jwe/JweHeaders.java  | 11 +++-
 .../rs/security/oauth2/jwe/RSAJweEncryptor.java | 10 ++--
 .../cxf/rs/security/oauth2/jwt/Algorithm.java   | 30 ++++++-----
 .../oauth2/utils/crypto/CryptoUtils.java        |  7 +++
 5 files changed, 79 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/b5409a6d/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptor.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptor.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptor.java
index cb6aabb..98a8f73 100644
--- 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptor.java
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptor.java
@@ -29,24 +29,36 @@ import 
org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
 import org.apache.cxf.rs.security.oauth2.utils.crypto.KeyProperties;
 
 public class JweEncryptor {
+    protected static final int DEFAULT_IV_SIZE = 96;
+    protected static final int DEFAULT_AUTH_TAG_LENGTH = 128;
     private Key cekEncryptionKey;
     private JweHeaders headers;
     private JwtHeadersWriter writer = new JwtTokenReaderWriter();
     private byte[] cek;
     private byte[] iv;
-    private int authTagLen;
+    private int authTagLen = DEFAULT_AUTH_TAG_LENGTH;
     private boolean wrap;
     
-    public JweEncryptor(JweHeaders headers, byte[] iv, int authTagLen) {
+    public JweEncryptor(String contentEncryptionAlgo, byte[] cek) {
+        this(new JweHeaders(contentEncryptionAlgo), cek);
+    }
+    public JweEncryptor(JweHeaders headers, byte[] cek) {
         this.headers = headers;
+        this.cek = cek;
+    }
+    public JweEncryptor(JweHeaders headers, byte[] cek, byte[] iv, int 
authTagLen) {
+        this(headers, cek);
         this.iv = iv;
         this.authTagLen = authTagLen;
     }
+    public JweEncryptor(JweHeaders headers, Key cekEncryptionKey) {
+        this.headers = headers;
+        this.cekEncryptionKey = cekEncryptionKey;
+    }
     public JweEncryptor(JweHeaders headers, Key cekEncryptionKey, byte[] cek, 
byte[] iv, 
                                    int authTagLen, boolean wrap) {
-        this(headers, iv, authTagLen);
+        this(headers, cek, iv, authTagLen);
         this.cekEncryptionKey = cekEncryptionKey;
-        this.cek = cek;
         this.wrap = wrap;
     }
     public JweEncryptor(JweHeaders headers, Key cekEncryptionKey, byte[] cek, 
byte[] iv, int authTagLen, 
@@ -57,28 +69,32 @@ public class JweEncryptor {
         }
     }
     
-    protected AlgorithmParameterSpec getContentEncryptionCipherSpec() {
-        return CryptoUtils.getContentEncryptionCipherSpec(getAuthTagLen(), 
getIv());
+    protected AlgorithmParameterSpec getContentEncryptionCipherSpec(byte[] 
theIv) {
+        return CryptoUtils.getContentEncryptionCipherSpec(getAuthTagLen(), 
theIv);
     }
     
-    protected byte[] getIv() {
-        return iv;
+    protected byte[] getContentEncryptionCipherInitVector() {
+        return iv == null ? 
CryptoUtils.generateSecureRandomBytes(DEFAULT_IV_SIZE) : iv;
     }
     
-    protected byte[] cek() {
-        return cek;
+    protected byte[] getContentEncryptionKey() {
+        if (cek == null && cekEncryptionKey != null) {
+            String algo = headers.getContentEncryptionAlgorithm();
+            return 
CryptoUtils.generateSecureRandomBytes(Algorithm.valueOf(algo).getKeySizeBits() 
/ 8);
+        } else {
+            return cek;
+        }
     }
     
-    protected byte[] getEncryptedContentEncryptionKey() {
-        if (cekEncryptionKey == null) {
-            // direct key encryption
+    protected byte[] getEncryptedContentEncryptionKey(byte[] theCek) {
+        if (theCek == null) {
             return new byte[]{};
         } else  {
             KeyProperties secretKeyProperties = new 
KeyProperties(getContentEncryptionKeyEncryptionAlgo());
             if (!wrap) {
-                return CryptoUtils.encryptBytes(cek, cekEncryptionKey, 
secretKeyProperties);
+                return CryptoUtils.encryptBytes(theCek, cekEncryptionKey, 
secretKeyProperties);
             } else {
-                return CryptoUtils.wrapSecretKey(cek, 
getContentEncryptionAlgo(), cekEncryptionKey, 
+                return CryptoUtils.wrapSecretKey(theCek, 
getContentEncryptionAlgo(), cekEncryptionKey, 
                                                  
secretKeyProperties.getKeyAlgo());
             }
         }
@@ -96,23 +112,26 @@ public class JweEncryptor {
     }
     
     public String getJweContent(byte[] content) {
-        byte[] jweContentEncryptionKey = getEncryptedContentEncryptionKey();
+        byte[] theCek = getContentEncryptionKey();
+        byte[] jweContentEncryptionKey = 
getEncryptedContentEncryptionKey(theCek);
         
         String contentEncryptionAlgoJavaName = 
Algorithm.toJavaName(headers.getContentEncryptionAlgorithm());
         KeyProperties keyProps = new 
KeyProperties(contentEncryptionAlgoJavaName);
         byte[] additionalEncryptionParam = 
headers.toCipherAdditionalAuthData(writer);
         keyProps.setAdditionalData(additionalEncryptionParam);
-        AlgorithmParameterSpec specParams = getContentEncryptionCipherSpec();
+        
+        byte[] theIv = getContentEncryptionCipherInitVector();
+        AlgorithmParameterSpec specParams = 
getContentEncryptionCipherSpec(theIv);
         keyProps.setAlgoSpec(specParams);
         
         byte[] cipherText = CryptoUtils.encryptBytes(
             content, 
-            CryptoUtils.createSecretKeySpec(cek, 
contentEncryptionAlgoJavaName),
+            CryptoUtils.createSecretKeySpec(theCek, 
contentEncryptionAlgoJavaName),
             keyProps);
         
         JweCompactProducer producer = new JweCompactProducer(headers, 
                                              jweContentEncryptionKey,
-                                             iv,
+                                             theIv,
                                              cipherText,
                                              getAuthTagLen());
         return producer.getJweContent();

http://git-wip-us.apache.org/repos/asf/cxf/blob/b5409a6d/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweHeaders.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweHeaders.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweHeaders.java
index de4395e..d3806c8 100644
--- 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweHeaders.java
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweHeaders.java
@@ -41,12 +41,19 @@ public class JweHeaders extends JwtHeaders {
     public JweHeaders(String keyEncAlgo, String ctEncAlgo) {
         this(keyEncAlgo, ctEncAlgo, false);
     }
+    public JweHeaders(String ctEncAlgo) {
+        this(null, ctEncAlgo, false);
+    }
+    public JweHeaders(String ctEncAlgo, boolean deflate) {
+        this(null, ctEncAlgo, deflate);
+    }
     public JweHeaders(String keyEncAlgo, String ctEncAlgo, boolean deflate) {
         init(keyEncAlgo, ctEncAlgo, deflate);
     }
-    
     private void init(String keyEncAlgo, String ctEncAlgo, boolean deflate) {
-        setKeyEncryptionAlgorithm(keyEncAlgo);
+        if (keyEncAlgo != null) {
+            setKeyEncryptionAlgorithm(keyEncAlgo);    
+        }
         setContentEncryptionAlgorithm(ctEncAlgo);
         if (deflate) {
             setZipAlgorithm(JwtConstants.DEFLATE_ZIP_ALGORITHM);

http://git-wip-us.apache.org/repos/asf/cxf/blob/b5409a6d/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweEncryptor.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweEncryptor.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweEncryptor.java
index 44557b8..387a19e 100644
--- 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweEncryptor.java
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweEncryptor.java
@@ -26,14 +26,18 @@ import org.apache.cxf.rs.security.oauth2.jwt.Algorithm;
 import org.apache.cxf.rs.security.oauth2.jwt.JwtHeadersWriter;
 
 public class RSAJweEncryptor extends JweEncryptor {
+    public RSAJweEncryptor(RSAPrivateKey privateKey, String 
contentEncryptionAlgo) {
+        super(new JweHeaders(Algorithm.RSA_OAEP_ALGO.getJwtName(),
+                             contentEncryptionAlgo), privateKey);
+    }
     public RSAJweEncryptor(RSAPrivateKey privateKey, JweHeaders headers, 
byte[] cek, byte[] iv) {
-        this(privateKey, headers, cek, iv, 128, true);
+        this(privateKey, headers, cek, iv, DEFAULT_AUTH_TAG_LENGTH, true);
     }
     public RSAJweEncryptor(RSAPrivateKey privateKey, SecretKey secretKey, 
byte[] iv) {
         this(privateKey, 
              new JweHeaders(Algorithm.RSA_OAEP_ALGO.getJwtName(),
                             Algorithm.toJwtName(secretKey.getAlgorithm())), 
-             secretKey.getEncoded(), iv, 128, true);
+             secretKey.getEncoded(), iv, DEFAULT_AUTH_TAG_LENGTH, true);
     }
     
     public RSAJweEncryptor(RSAPrivateKey privateKey, JweHeaders headers, 
byte[] cek, byte[] iv, 
@@ -43,7 +47,7 @@ public class RSAJweEncryptor extends JweEncryptor {
     
     public RSAJweEncryptor(RSAPrivateKey privateKey, JweHeaders headers, 
byte[] cek, byte[] iv, 
                               JwtHeadersWriter writer) {
-        this(privateKey, headers, cek, iv, 128, true, null);
+        this(privateKey, headers, cek, iv, DEFAULT_AUTH_TAG_LENGTH, true, 
null);
     }
     public RSAJweEncryptor(RSAPrivateKey privateKey, JweHeaders headers, 
byte[] cek, byte[] iv, 
                               int authTagLen, boolean wrap, JwtHeadersWriter 
writer) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/b5409a6d/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 3856eeb..3c08e8e 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
@@ -27,18 +27,18 @@ import java.util.Map;
 
 public enum Algorithm {
     // Signature
-    HmacSHA256(JwtConstants.HMAC_SHA_256_ALGO),
-    HmacSHA384(JwtConstants.HMAC_SHA_384_ALGO),
-    HmacSHA512(JwtConstants.HMAC_SHA_512_ALGO),
+    HmacSHA256(JwtConstants.HMAC_SHA_256_ALGO, 256),
+    HmacSHA384(JwtConstants.HMAC_SHA_384_ALGO, 384),
+    HmacSHA512(JwtConstants.HMAC_SHA_512_ALGO, 512),
     
-    SHA256withRSA(JwtConstants.RS_SHA_256_ALGO),
-    SHA384withRSA(JwtConstants.RS_SHA_384_ALGO),
-    SHA512withRSA(JwtConstants.RS_SHA_512_ALGO),
+    SHA256withRSA(JwtConstants.RS_SHA_256_ALGO, 256),
+    SHA384withRSA(JwtConstants.RS_SHA_384_ALGO, 384),
+    SHA512withRSA(JwtConstants.RS_SHA_512_ALGO, 512),
     
     // Key Encryption
-    RSA_OAEP_ALGO(JwtConstants.RSA_OAEP_ALGO, 
"RSA/ECB/OAEPWithSHA-1AndMGF1Padding"),
+    RSA_OAEP_ALGO(JwtConstants.RSA_OAEP_ALGO, 
"RSA/ECB/OAEPWithSHA-1AndMGF1Padding", -1),
     // Content Encryption
-    A256GCM_ALGO(JwtConstants.A256GCM_ALGO, "AES/GCM/NoPadding");
+    A256GCM_ALGO(JwtConstants.A256GCM_ALGO, "AES/GCM/NoPadding", 256);
     
     public static final String HMAC_SHA_256_JAVA = "HmacSHA256";
     public static final String HMAC_SHA_384_JAVA = "HmacSHA384";
@@ -73,13 +73,15 @@ public enum Algorithm {
     }
     private final String jwtName;
     private final String javaName;
-
-    private Algorithm(String jwtName) {
-        this(jwtName, null);
+    private final int keySizeBits;
+    
+    private Algorithm(String jwtName, int keySizeBits) {
+        this(jwtName, null, keySizeBits);
     }
-    private Algorithm(String jwtName, String javaName) {
+    private Algorithm(String jwtName, String javaName, int keySizeBits) {
         this.jwtName = jwtName;
         this.javaName = javaName;
+        this.keySizeBits = keySizeBits;
     }
 
     public String getJwtName() {
@@ -90,6 +92,10 @@ public enum Algorithm {
         return javaName == null ? name() : javaName;
     }
 
+    public int getKeySizeBits() {
+        return keySizeBits;
+    }
+    
     public static String toJwtName(String javaName) {    
         return JAVA_TO_JWT_NAMES.get(javaName);
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/b5409a6d/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 1039d9e..0a408fc 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
@@ -71,6 +71,13 @@ public final class CryptoUtils {
         return encodeBytes(encryptedBytes);
     }
     
+    public static byte[] generateSecureRandomBytes(int size) {
+        SecureRandom sr = new SecureRandom();
+        byte[] bytes = new byte[size];
+        sr.nextBytes(bytes);
+        return bytes;
+    }
+    
     public static RSAPublicKey getRSAPublicKey(String encodedModulus,
                                                String encodedPublicExponent) {
         try {

Reply via email to