Repository: cxf
Updated Branches:
  refs/heads/master fa37d8722 -> 1b944b5e2


[CXF-5902] Completing AesCbcHmac encryption/decryption test, some cleanup to 
follow


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

Branch: refs/heads/master
Commit: 1b944b5e20fec5032653748c99ca7b287df361fb
Parents: fa37d87
Author: Sergey Beryozkin <sberyoz...@talend.com>
Authored: Tue Aug 12 16:33:43 2014 +0100
Committer: Sergey Beryozkin <sberyoz...@talend.com>
Committed: Tue Aug 12 16:33:43 2014 +0100

----------------------------------------------------------------------
 .../oauth2/jwe/AbstractJweDecryption.java       | 25 ++++---
 .../oauth2/jwe/AbstractJweEncryption.java       | 13 ++--
 .../oauth2/jwe/AesCbcHmacJweDecryption.java     | 76 ++++++++++++++++++++
 .../oauth2/jwe/AesCbcHmacJweEncryption.java     | 53 ++++++++------
 .../jwe/AesGcmContentDecryptionAlgorithm.java   |  8 ++-
 .../jwe/AesWrapKeyDecryptionAlgorithm.java      | 34 +++++++++
 .../oauth2/jwe/ContentDecryptionAlgorithm.java  | 24 +++++++
 .../oauth2/jwe/DirectKeyJweDecryption.java      |  2 +-
 .../security/oauth2/jwe/JweCompactConsumer.java | 22 ++++--
 .../rs/security/oauth2/jwe/JweDecryption.java   | 26 -------
 .../oauth2/jwe/JweDecryptionProvider.java       | 26 +++++++
 .../oauth2/jwe/WrappedKeyJweDecryption.java     |  2 +-
 .../jwt/jaxrs/AbstractJweDecryptingFilter.java  | 10 +--
 .../oauth2/jwe/JweCompactReaderWriterTest.java  | 14 ++--
 14 files changed, 250 insertions(+), 85 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweDecryption.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweDecryption.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweDecryption.java
index 04bcde6..4d451d2 100644
--- 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweDecryption.java
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweDecryption.java
@@ -28,21 +28,21 @@ import 
org.apache.cxf.rs.security.oauth2.jwt.JwtTokenReaderWriter;
 import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
 import org.apache.cxf.rs.security.oauth2.utils.crypto.KeyProperties;
 
-public abstract class AbstractJweDecryption implements JweDecryption {
+public abstract class AbstractJweDecryption implements JweDecryptionProvider {
     private JweCryptoProperties props;
     private KeyDecryptionAlgorithm keyDecryptionAlgo;
-    private ContentEncryptionCipherProperties contentEncryptionProps;
+    private ContentDecryptionAlgorithm contentDecryptionAlgo;
     private JwtHeadersReader reader = new JwtTokenReaderWriter();
     protected AbstractJweDecryption(JweCryptoProperties props, 
                                     JwtHeadersReader theReader,
                                     KeyDecryptionAlgorithm keyDecryptionAlgo,
-                                    ContentEncryptionCipherProperties 
contentEncryptionProps) {
+                                    ContentDecryptionAlgorithm 
contentDecryptionAlgo) {
         this.props = props;
         if (theReader != null) {
             reader = theReader;
         }
         this.keyDecryptionAlgo = keyDecryptionAlgo;
-        this.contentEncryptionProps = contentEncryptionProps;
+        this.contentDecryptionAlgo = contentDecryptionAlgo;
     }
     
     protected byte[] getContentEncryptionKey(JweCompactConsumer consumer) {
@@ -60,6 +60,9 @@ public abstract class AbstractJweDecryption implements 
JweDecryption {
     protected JweDecryptionOutput doDecrypt(JweCompactConsumer consumer) {
         consumer.enforceJweCryptoProperties(props);
         byte[] cek = getContentEncryptionKey(consumer);
+        return doDecrypt(consumer, cek);
+    }
+    protected JweDecryptionOutput doDecrypt(JweCompactConsumer consumer, 
byte[] cek) {
         KeyProperties keyProperties = new 
KeyProperties(getContentEncryptionAlgorithm(consumer));
         
keyProperties.setAdditionalData(getContentEncryptionCipherAAD(consumer));
         AlgorithmParameterSpec spec = getContentEncryptionCipherSpec(consumer);
@@ -67,7 +70,8 @@ public abstract class AbstractJweDecryption implements 
JweDecryption {
         boolean compressionSupported = 
             
JwtConstants.DEFLATE_ZIP_ALGORITHM.equals(consumer.getJweHeaders().getZipAlgorithm());
         keyProperties.setCompressionSupported(compressionSupported);
-        Key secretKey = CryptoUtils.createSecretKeySpec(cek, 
keyProperties.getKeyAlgo());
+        byte[] actualCek = getActualCek(cek, 
consumer.getJweHeaders().getContentEncryptionAlgorithm());
+        Key secretKey = CryptoUtils.createSecretKeySpec(actualCek, 
keyProperties.getKeyAlgo());
         byte[] bytes = 
             CryptoUtils.decryptBytes(getEncryptedContentWithAuthTag(consumer), 
secretKey, keyProperties);
         return new JweDecryptionOutput(consumer.getJweHeaders(), bytes);
@@ -76,16 +80,17 @@ public abstract class AbstractJweDecryption implements 
JweDecryption {
         return consumer.getEncryptedContentEncryptionKey();
     }
     protected AlgorithmParameterSpec 
getContentEncryptionCipherSpec(JweCompactConsumer consumer) {
-        return 
contentEncryptionProps.getAlgorithmParameterSpec(getContentEncryptionCipherInitVector(consumer));
+        return 
contentDecryptionAlgo.getAlgorithmParameterSpec(getContentEncryptionCipherInitVector(consumer));
     }
     protected String getContentEncryptionAlgorithm(JweCompactConsumer 
consumer) {
         return 
Algorithm.toJavaName(consumer.getJweHeaders().getContentEncryptionAlgorithm());
     }
     protected byte[] getContentEncryptionCipherAAD(JweCompactConsumer 
consumer) {
-        return 
contentEncryptionProps.getAdditionalAuthenticationData(consumer.getDecodedJsonHeaders());
+        return 
contentDecryptionAlgo.getAdditionalAuthenticationData(consumer.getDecodedJsonHeaders());
     }
     protected byte[] getEncryptedContentWithAuthTag(JweCompactConsumer 
consumer) {
-        return consumer.getEncryptedContentWithAuthTag();
+        return 
contentDecryptionAlgo.getEncryptedSequence(consumer.getEncryptedContent(), 
+                                                          
getEncryptionAuthenticationTag(consumer));
     }
     protected byte[] getContentEncryptionCipherInitVector(JweCompactConsumer 
consumer) { 
         return consumer.getContentDecryptionCipherInitVector();
@@ -96,6 +101,8 @@ public abstract class AbstractJweDecryption implements 
JweDecryption {
     protected int getEncryptionAuthenticationTagLenBits(JweCompactConsumer 
consumer) {
         return getEncryptionAuthenticationTag(consumer).length * 8;
     }
-    
+    protected byte[] getActualCek(byte[] theCek, String algoJwt) {
+        return theCek;
+    }
     
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryption.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryption.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryption.java
index 357a300..167d04e 100644
--- 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryption.java
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryption.java
@@ -31,7 +31,7 @@ import 
org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
 import org.apache.cxf.rs.security.oauth2.utils.crypto.KeyProperties;
 
 public abstract class AbstractJweEncryption implements JweEncryptionProvider {
-    private static final int DEFAULT_AUTH_TAG_LENGTH = 128;
+    protected static final int DEFAULT_AUTH_TAG_LENGTH = 128;
     private JweHeaders headers;
     private JwtHeadersWriter writer;
     private ContentEncryptionAlgorithm contentEncryptionAlgo;
@@ -80,10 +80,6 @@ public abstract class AbstractJweEncryption implements 
JweEncryptionProvider {
     protected String getContentEncryptionAlgoJava() {
         return Algorithm.toJavaName(getContentEncryptionAlgoJwt());
     }
-    
-    protected int getAuthTagLen() {
-        return DEFAULT_AUTH_TAG_LENGTH;
-    }
     protected byte[] getAAD(JweHeaders theHeaders) {
         return 
contentEncryptionAlgo.getAdditionalAuthenticationData(writer.headersToJson(theHeaders));
     }
@@ -103,7 +99,7 @@ public abstract class AbstractJweEncryption implements 
JweEncryptionProvider {
                                       state.jweContentEncryptionKey,
                                       state.theIv,
                                       cipher,
-                                      getAuthTagLen());
+                                      DEFAULT_AUTH_TAG_LENGTH);
     }
     
     protected JwtHeadersWriter getJwtHeadersWriter() {
@@ -128,10 +124,11 @@ public abstract class AbstractJweEncryption implements 
JweEncryptionProvider {
         return null;
     }
     protected SecretKey createCekSecretKey(JweEncryptionInternal state) {
-        return CryptoUtils.createSecretKeySpec(getActualCek(state.secretKey), 
state.keyProps.getKeyAlgo());
+        return CryptoUtils.createSecretKeySpec(getActualCek(state.secretKey, 
this.getContentEncryptionAlgoJwt()), 
+                                               state.keyProps.getKeyAlgo());
     }
     
-    protected byte[] getActualCek(byte[] theCek) {
+    protected byte[] getActualCek(byte[] theCek, String algoJwt) {
         return theCek;
     }
     

http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweDecryption.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweDecryption.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweDecryption.java
new file mode 100644
index 0000000..5aef222
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweDecryption.java
@@ -0,0 +1,76 @@
+/**
+ * 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.jwe;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+
+import javax.crypto.spec.IvParameterSpec;
+
+import org.apache.cxf.rs.security.oauth2.jwt.JwtHeadersReader;
+
+public class AesCbcHmacJweDecryption extends AbstractJweDecryption {
+    public AesCbcHmacJweDecryption(KeyDecryptionAlgorithm keyDecryptionAlgo) {
+        this(keyDecryptionAlgo, null, null);
+    }
+    public AesCbcHmacJweDecryption(KeyDecryptionAlgorithm keyDecryptionAlgo,
+                                   JweCryptoProperties props, 
+                                   JwtHeadersReader reader) {
+        super(props, reader, keyDecryptionAlgo, new 
AesCbcContentDecryptionAlgorithm());
+    }
+    protected JweDecryptionOutput doDecrypt(JweCompactConsumer consumer, 
byte[] cek) {
+        validateAuthenticationTag(consumer, cek);
+        return super.doDecrypt(consumer, cek);
+    }
+    @Override
+    protected byte[] getActualCek(byte[] theCek, String algoJwt) {
+        return AesCbcHmacJweEncryption.doGetActualCek(theCek, algoJwt);
+    }
+    protected void validateAuthenticationTag(JweCompactConsumer consumer, 
byte[] theCek) {
+        byte[] actualAuthTag = consumer.getEncryptionAuthenticationTag();
+        
+        final AesCbcHmacJweEncryption.MacState macState = 
+            AesCbcHmacJweEncryption.getInitializedMacState(theCek, 
+                                                           
consumer.getContentDecryptionCipherInitVector(),
+                                                           
consumer.getJweHeaders(),
+                                                           
consumer.getDecodedJsonHeaders());
+        macState.mac.update(consumer.getEncryptedContent());
+        byte[] expectedAuthTag = 
AesCbcHmacJweEncryption.signAndGetTag(macState);
+        if (!Arrays.equals(actualAuthTag, expectedAuthTag)) {
+            throw new SecurityException();
+        }
+        
+    }
+    private static class AesCbcContentDecryptionAlgorithm extends 
AbstractContentEncryptionCipherProperties
+        implements ContentDecryptionAlgorithm {
+        @Override
+        public AlgorithmParameterSpec getAlgorithmParameterSpec(byte[] theIv) {
+            return new IvParameterSpec(theIv);
+        }
+        @Override
+        public byte[] getAdditionalAuthenticationData(String headersJson) {
+            return null;
+        }
+        @Override
+        public byte[] getEncryptedSequence(byte[] cipher, byte[] authTag) {
+            return cipher;
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweEncryption.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweEncryption.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweEncryption.java
index d79452a..0489819 100644
--- 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweEncryption.java
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweEncryption.java
@@ -69,26 +69,25 @@ public class AesCbcHmacJweEncryption extends 
AbstractJweEncryption {
             throw new SecurityException();
         }
     }
-    
-    protected byte[] getActualCek(byte[] theCek) {
-        int size = getCekKeySize() / 2;
+    @Override
+    protected byte[] getActualCek(byte[] theCek, String algoJwt) {
+        return doGetActualCek(theCek, algoJwt);
+    }
+    protected static byte[] doGetActualCek(byte[] theCek, String algoJwt) {
+        int size = getCekKeySize(algoJwt) / 2;
         byte[] actualCek = new byte[size];
         System.arraycopy(theCek, size, actualCek, 0, size);
         return actualCek;
     }
     
-    protected int getCekKeySize() {
-        return AES_CEK_SIZE_MAP.get(super.getContentEncryptionAlgoJwt());
+    protected static int getCekKeySize(String algoJwt) {
+        return AES_CEK_SIZE_MAP.get(algoJwt);
     }
     
     protected JweCompactProducer getJweCompactProducer(JweEncryptionInternal 
state, byte[] cipher) {
         final MacState macState = getInitializedMacState(state);
-        
         macState.mac.update(cipher);
-        macState.mac.update(macState.al);
-        byte[] sig = macState.mac.doFinal();
-        byte[] authTag = getTagFromSignature(sig);
-        
+        byte[] authTag = signAndGetTag(macState);
         return new JweCompactProducer(macState.headersJson,
                                       state.jweContentEncryptionKey,
                                       state.theIv,
@@ -96,28 +95,38 @@ public class AesCbcHmacJweEncryption extends 
AbstractJweEncryption {
                                       authTag);
     }
     
-    private byte[] getTagFromSignature(byte[] sig) {
-        int authTagLen = getAuthTagLen() / 8;
+    protected static byte[] signAndGetTag(MacState macState) {
+        macState.mac.update(macState.al);
+        byte[] sig = macState.mac.doFinal();
+        
+        int authTagLen = DEFAULT_AUTH_TAG_LENGTH / 8;
         byte[] authTag = new byte[authTagLen];
         System.arraycopy(sig, 0, authTag, 0, authTagLen);
         return authTag;
     }
-    
     private MacState getInitializedMacState(final JweEncryptionInternal state) 
{
-        int size = getCekKeySize() / 2;
+        String headersJson = 
getJwtHeadersWriter().headersToJson(state.theHeaders);
+        return getInitializedMacState(state.secretKey, state.theIv, 
state.theHeaders, headersJson);
+    }
+    protected static MacState getInitializedMacState(byte[] secretKey,
+                                                     byte[] theIv,
+                                                     JweHeaders theHeaders, 
+                                                     String headersJson) {
+        String algoJwt = theHeaders.getContentEncryptionAlgorithm();
+        int size = getCekKeySize(algoJwt) / 2;
         byte[] macKey = new byte[size];
-        System.arraycopy(state.secretKey, 0, macKey, 0, size);
+        System.arraycopy(secretKey, 0, macKey, 0, size);
         
-        String hmacAlgoJava = 
AES_HMAC_MAP.get(super.getContentEncryptionAlgoJwt());
+        String hmacAlgoJava = AES_HMAC_MAP.get(algoJwt);
         Mac mac = HmacUtils.getInitializedMac(macKey, hmacAlgoJava, null);
         
-        String headersJson = 
getJwtHeadersWriter().headersToJson(state.theHeaders);
+        
         byte[] aad = JweHeaders.toCipherAdditionalAuthData(headersJson);
         ByteBuffer buf = ByteBuffer.allocate(8);
         final byte[] al = buf.putInt(0).putInt(aad.length * 8).array();
         
         mac.update(aad);
-        mac.update(state.theIv);
+        mac.update(theIv);
         MacState macState = new MacState();
         macState.mac = mac;
         macState.al = al;
@@ -138,9 +147,7 @@ public class AesCbcHmacJweEncryption extends 
AbstractJweEncryption {
 
             @Override
             public byte[] getTag() {
-                macState.mac.update(macState.al);
-                byte[] sig = macState.mac.doFinal();
-                return getTagFromSignature(sig);
+                return signAndGetTag(macState);
             }
             
         };
@@ -164,8 +171,8 @@ public class AesCbcHmacJweEncryption extends 
AbstractJweEncryption {
         }
     }
     
-    private static class MacState {
-        private Mac mac;
+    protected static class MacState {
+        protected Mac mac;
         private byte[] al;
         private String headersJson;
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesGcmContentDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesGcmContentDecryptionAlgorithm.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesGcmContentDecryptionAlgorithm.java
index 9397bd4..7c3f3ca 100644
--- 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesGcmContentDecryptionAlgorithm.java
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesGcmContentDecryptionAlgorithm.java
@@ -20,5 +20,11 @@ package org.apache.cxf.rs.security.oauth2.jwe;
 
 
 
-public class AesGcmContentDecryptionAlgorithm extends 
AbstractContentEncryptionCipherProperties {
+public class AesGcmContentDecryptionAlgorithm extends 
AbstractContentEncryptionCipherProperties
+    implements ContentDecryptionAlgorithm {
+
+    @Override
+    public byte[] getEncryptedSequence(byte[] cipher, byte[] authTag) {
+        return JweCompactConsumer.getEncryptedContentWithAuthTag(cipher, 
authTag);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesWrapKeyDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesWrapKeyDecryptionAlgorithm.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesWrapKeyDecryptionAlgorithm.java
new file mode 100644
index 0000000..ec99447
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesWrapKeyDecryptionAlgorithm.java
@@ -0,0 +1,34 @@
+/**
+ * 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.jwe;
+
+import javax.crypto.SecretKey;
+
+import org.apache.cxf.rs.security.oauth2.jwt.Algorithm;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
+
+public class AesWrapKeyDecryptionAlgorithm extends 
WrappedKeyDecryptionAlgorithm {
+    public AesWrapKeyDecryptionAlgorithm(byte[] secretKey) {    
+        this(CryptoUtils.createSecretKeySpec(secretKey, 
Algorithm.AES_WRAP_ALGO_JAVA));
+    }
+    public AesWrapKeyDecryptionAlgorithm(SecretKey secretKey) {    
+        super(secretKey, true);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/ContentDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/ContentDecryptionAlgorithm.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/ContentDecryptionAlgorithm.java
new file mode 100644
index 0000000..71c20c4
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/ContentDecryptionAlgorithm.java
@@ -0,0 +1,24 @@
+/**
+ * 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.jwe;
+
+
+interface ContentDecryptionAlgorithm extends ContentEncryptionCipherProperties 
{
+    byte[] getEncryptedSequence(byte[] cipher, byte[] authTag);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweDecryption.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweDecryption.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweDecryption.java
index 9ef9ae1..d76db24 100644
--- 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweDecryption.java
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweDecryption.java
@@ -37,7 +37,7 @@ public class DirectKeyJweDecryption extends 
AbstractJweDecryption {
     public DirectKeyJweDecryption(Key contentDecryptionKey, 
                                   JweCryptoProperties props, 
                                   JwtHeadersReader reader,
-                                  ContentEncryptionCipherProperties 
cipherProps) {    
+                                  ContentDecryptionAlgorithm cipherProps) {    
         super(props, reader, new 
DirectKeyDecryptionAlgorithm(contentDecryptionKey),
               cipherProps);
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactConsumer.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactConsumer.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactConsumer.java
index 6a1954f..24631ed 100644
--- 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactConsumer.java
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactConsumer.java
@@ -31,7 +31,7 @@ public class JweCompactConsumer {
     private String headersJson;
     private byte[] encryptedCEK;
     private byte[] initVector;
-    private byte[] encryptedContentWithTag;
+    private byte[] encryptedContent;
     private byte[] authTag;
     private JweHeaders jweHeaders;
     public JweCompactConsumer(String jweContent) {
@@ -47,11 +47,8 @@ public class JweCompactConsumer {
             encryptedCEK = Base64UrlUtility.decode(parts[1]);
             initVector = Base64UrlUtility.decode(parts[2]);
             
-            byte[] cipherText = Base64UrlUtility.decode(parts[3]);
+            encryptedContent = Base64UrlUtility.decode(parts[3]);
             authTag = Base64UrlUtility.decode(parts[4]);
-            encryptedContentWithTag = new byte[cipherText.length + 
authTag.length];
-            System.arraycopy(cipherText, 0, encryptedContentWithTag, 0, 
cipherText.length);
-            System.arraycopy(authTag, 0, encryptedContentWithTag, 
cipherText.length, authTag.length);
             jweHeaders = new 
JweHeaders(reader.fromJsonHeaders(headersJson).asMap());
         } catch (Base64Exception ex) {
             throw new SecurityException(ex);
@@ -88,14 +85,25 @@ public class JweCompactConsumer {
         return authTag;
     }
     
+    public byte[] getEncryptedContent() {
+        return encryptedContent;
+    }
+    
     public byte[] getEncryptedContentWithAuthTag() {
+        return getEncryptedContentWithAuthTag(encryptedContent, authTag);
+    }
+    
+    public static byte[] getEncryptedContentWithAuthTag(byte[] cipher, byte[] 
authTag) {
+        byte[] encryptedContentWithTag = new byte[cipher.length + 
authTag.length];
+        System.arraycopy(cipher, 0, encryptedContentWithTag, 0, cipher.length);
+        System.arraycopy(authTag, 0, encryptedContentWithTag, cipher.length, 
authTag.length);  
         return encryptedContentWithTag;
     }
     
-    public byte[] getDecryptedContent(JweDecryption decryption) {
+    public byte[] getDecryptedContent(JweDecryptionProvider decryption) {
         return decryption.decrypt(this);
     }
-    public String getDecryptedContentText(JweDecryption decryption) {
+    public String getDecryptedContentText(JweDecryptionProvider decryption) {
         try {
             return new String(getDecryptedContent(decryption), "UTF-8");
         } catch (UnsupportedEncodingException ex) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryption.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryption.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryption.java
deleted file mode 100644
index e910884..0000000
--- 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryption.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * 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.jwe;
-
-
-
-public interface JweDecryption {
-    JweDecryptionOutput decrypt(String jweContent);
-    byte[] decrypt(JweCompactConsumer consumer);
-}

http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptionProvider.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptionProvider.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptionProvider.java
new file mode 100644
index 0000000..ebf2cd8
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptionProvider.java
@@ -0,0 +1,26 @@
+/**
+ * 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.jwe;
+
+
+
+public interface JweDecryptionProvider {
+    JweDecryptionOutput decrypt(String jweContent);
+    byte[] decrypt(JweCompactConsumer consumer);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweDecryption.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweDecryption.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweDecryption.java
index 05d1098..45164bf 100644
--- 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweDecryption.java
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweDecryption.java
@@ -47,7 +47,7 @@ public class WrappedKeyJweDecryption extends 
AbstractJweDecryption {
     }
     public WrappedKeyJweDecryption(WrappedKeyDecryptionAlgorithm 
keyDecryptionAlgo,
                                    JweCryptoProperties props, JwtHeadersReader 
reader,
-                                   ContentEncryptionCipherProperties 
cipherProps) {    
+                                   ContentDecryptionAlgorithm cipherProps) {   
 
         super(props, reader, keyDecryptionAlgo, cipherProps);
     }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJweDecryptingFilter.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJweDecryptingFilter.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJweDecryptingFilter.java
index 38052cc..d42d7b2 100644
--- 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJweDecryptingFilter.java
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJweDecryptingFilter.java
@@ -25,8 +25,8 @@ import java.security.PrivateKey;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
 import org.apache.cxf.rs.security.oauth2.jwe.JweCryptoProperties;
-import org.apache.cxf.rs.security.oauth2.jwe.JweDecryption;
 import org.apache.cxf.rs.security.oauth2.jwe.JweDecryptionOutput;
+import org.apache.cxf.rs.security.oauth2.jwe.JweDecryptionProvider;
 import org.apache.cxf.rs.security.oauth2.jwe.JweHeaders;
 import org.apache.cxf.rs.security.oauth2.jwe.WrappedKeyJweDecryption;
 import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
@@ -35,11 +35,11 @@ public class AbstractJweDecryptingFilter {
     private static final String RSSEC_ENCRYPTION_IN_PROPS = 
"rs.security.encryption.in.properties";
     private static final String RSSEC_ENCRYPTION_PROPS = 
"rs.security.encryption.properties";
         
-    private JweDecryption decryption;
+    private JweDecryptionProvider decryption;
     private JweCryptoProperties cryptoProperties;
     private String defaultMediaType;
     protected JweDecryptionOutput decrypt(InputStream is) throws IOException {
-        JweDecryption theDecryptor = getInitializedDecryption();
+        JweDecryptionProvider theDecryptor = getInitializedDecryption();
         JweDecryptionOutput out = theDecryptor.decrypt(new 
String(IOUtils.readBytesFromStream(is), "UTF-8"));
         validateHeaders(out.getHeaders());
         return out;
@@ -48,10 +48,10 @@ public class AbstractJweDecryptingFilter {
     protected void validateHeaders(JweHeaders headers) {
         // complete
     }
-    public void setDecryption(JweDecryption decryptor) {
+    public void setDecryption(JweDecryptionProvider decryptor) {
         this.decryption = decryptor;
     }
-    protected JweDecryption getInitializedDecryption() {
+    protected JweDecryptionProvider getInitializedDecryption() {
         if (decryption != null) {
             return decryption;    
         } 

http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java
index c5d2bce..cd7312b 100644
--- 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java
@@ -99,15 +99,21 @@ public class JweCompactReaderWriterTest extends Assert {
         headers.setAlgorithm(Algorithm.A128KW.getJwtName());
         
headers.setContentEncryptionAlgorithm(Algorithm.A128CBC_HS256.getJwtName());
         
+        byte[] cekEncryptionKey = 
Base64UrlUtility.decode(KEY_ENCRYPTION_KEY_A3);
+        
         AesWrapKeyEncryptionAlgorithm keyEncryption = 
-            new 
AesWrapKeyEncryptionAlgorithm(Base64UrlUtility.decode(KEY_ENCRYPTION_KEY_A3), 
-                                    Algorithm.A128KW.getJwtName());
+            new AesWrapKeyEncryptionAlgorithm(cekEncryptionKey, 
Algorithm.A128KW.getJwtName());
         JweEncryptionProvider encryption = new AesCbcHmacJweEncryption(headers,
                                                            
CONTENT_ENCRYPTION_KEY_A3, 
                                                            INIT_VECTOR_A3,
                                                            keyEncryption);
-        String encryptedText = 
encryption.encrypt(specPlainText.getBytes("UTF-8"), null);
-        assertEquals(JWE_OUTPUT_A3, encryptedText);
+        String jweContent = 
encryption.encrypt(specPlainText.getBytes("UTF-8"), null);
+        assertEquals(JWE_OUTPUT_A3, jweContent);
+        
+        AesWrapKeyDecryptionAlgorithm keyDecryption = new 
AesWrapKeyDecryptionAlgorithm(cekEncryptionKey);
+        JweDecryptionProvider decryption = new 
AesCbcHmacJweDecryption(keyDecryption);
+        String decryptedText = decryption.decrypt(jweContent).getContentText();
+        assertEquals(specPlainText, decryptedText);
     }
     
     @Test

Reply via email to