http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweDecryption.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweDecryption.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweDecryption.java
new file mode 100644
index 0000000..e2e1ac7
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweDecryption.java
@@ -0,0 +1,108 @@
+/**
+ * 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.jose.jwe;
+
+import java.security.Key;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+import org.apache.cxf.rs.security.jose.jwt.JwtConstants;
+import org.apache.cxf.rs.security.jose.jwt.JwtHeadersReader;
+import org.apache.cxf.rs.security.jose.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 JweDecryptionProvider {
+    private JweCryptoProperties props;
+    private KeyDecryptionAlgorithm keyDecryptionAlgo;
+    private ContentDecryptionAlgorithm contentDecryptionAlgo;
+    private JwtHeadersReader reader = new JwtTokenReaderWriter();
+    protected AbstractJweDecryption(JweCryptoProperties props, 
+                                    JwtHeadersReader theReader,
+                                    KeyDecryptionAlgorithm keyDecryptionAlgo,
+                                    ContentDecryptionAlgorithm 
contentDecryptionAlgo) {
+        this.props = props;
+        if (theReader != null) {
+            reader = theReader;
+        }
+        this.keyDecryptionAlgo = keyDecryptionAlgo;
+        this.contentDecryptionAlgo = contentDecryptionAlgo;
+    }
+    
+    protected byte[] getContentEncryptionKey(JweCompactConsumer consumer) {
+        return 
this.keyDecryptionAlgo.getDecryptedContentEncryptionKey(consumer);
+    }
+    
+    public JweDecryptionOutput decrypt(String content) {
+        JweCompactConsumer consumer = new JweCompactConsumer(content, reader);
+        return doDecrypt(consumer);
+    }
+    public byte[] decrypt(JweCompactConsumer consumer) {
+        return doDecrypt(consumer).getContent();
+    }
+    
+    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);
+        keyProperties.setAlgoSpec(spec);
+        boolean compressionSupported = 
+            
JwtConstants.DEFLATE_ZIP_ALGORITHM.equals(consumer.getJweHeaders().getZipAlgorithm());
+        keyProperties.setCompressionSupported(compressionSupported);
+        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);
+    }
+    protected byte[] getEncryptedContentEncryptionKey(JweCompactConsumer 
consumer) {
+        return consumer.getEncryptedContentEncryptionKey();
+    }
+    protected AlgorithmParameterSpec 
getContentEncryptionCipherSpec(JweCompactConsumer consumer) {
+        return 
contentDecryptionAlgo.getAlgorithmParameterSpec(getContentEncryptionCipherInitVector(consumer));
+    }
+    protected String getContentEncryptionAlgorithm(JweCompactConsumer 
consumer) {
+        return 
Algorithm.toJavaName(consumer.getJweHeaders().getContentEncryptionAlgorithm());
+    }
+    protected byte[] getContentEncryptionCipherAAD(JweCompactConsumer 
consumer) {
+        return 
contentDecryptionAlgo.getAdditionalAuthenticationData(consumer.getDecodedJsonHeaders());
+    }
+    protected byte[] getEncryptedContentWithAuthTag(JweCompactConsumer 
consumer) {
+        return 
contentDecryptionAlgo.getEncryptedSequence(consumer.getEncryptedContent(), 
+                                                          
getEncryptionAuthenticationTag(consumer));
+    }
+    protected byte[] getContentEncryptionCipherInitVector(JweCompactConsumer 
consumer) { 
+        return consumer.getContentDecryptionCipherInitVector();
+    }
+    protected byte[] getEncryptionAuthenticationTag(JweCompactConsumer 
consumer) {
+        return consumer.getEncryptionAuthenticationTag();
+    }
+    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/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
new file mode 100644
index 0000000..747d996
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
@@ -0,0 +1,184 @@
+/**
+ * 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.jose.jwe;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+import org.apache.cxf.rs.security.jose.jwt.JwtConstants;
+import org.apache.cxf.rs.security.jose.jwt.JwtHeadersWriter;
+import org.apache.cxf.rs.security.jose.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 AbstractJweEncryption implements JweEncryptionProvider {
+    protected static final int DEFAULT_AUTH_TAG_LENGTH = 128;
+    private JweHeaders headers;
+    private JwtHeadersWriter writer;
+    private ContentEncryptionAlgorithm contentEncryptionAlgo;
+    private KeyEncryptionAlgorithm keyEncryptionAlgo;
+    
+    protected AbstractJweEncryption(JweHeaders headers, 
+                                    ContentEncryptionAlgorithm 
contentEncryptionAlgo,
+                                    KeyEncryptionAlgorithm keyEncryptionAlgo) {
+        this(headers, contentEncryptionAlgo, keyEncryptionAlgo, null);
+    }
+    protected AbstractJweEncryption(JweHeaders headers, 
+                                    ContentEncryptionAlgorithm 
contentEncryptionAlgo, 
+                                    KeyEncryptionAlgorithm keyEncryptionAlgo,
+                                    JwtHeadersWriter writer) {
+        this.headers = headers;
+        this.writer = writer;
+        if (this.writer == null) {
+            this.writer = new JwtTokenReaderWriter();
+        }
+        this.keyEncryptionAlgo = keyEncryptionAlgo;
+        this.contentEncryptionAlgo = contentEncryptionAlgo;
+    }
+    
+    protected AlgorithmParameterSpec getAlgorithmParameterSpec(byte[] theIv) {
+        return contentEncryptionAlgo.getAlgorithmParameterSpec(theIv);
+    }
+    
+    protected byte[] getContentEncryptionKey() {
+        byte[] cek = getProvidedContentEncryptionKey();
+        if (cek == null) {
+            String algoJava = getContentEncryptionAlgoJava();
+            String algoJwt = getContentEncryptionAlgoJwt();
+            cek = 
CryptoUtils.getSecretKey(Algorithm.stripAlgoProperties(algoJava), 
+                                           getCekSize(algoJwt)).getEncoded();
+        }
+        return cek;
+    }
+   
+    protected int getCekSize(String algoJwt) {
+        return Algorithm.valueOf(algoJwt.replace('-', '_')).getKeySizeBits();
+    }
+    
+    protected byte[] getProvidedContentEncryptionKey() {
+        return contentEncryptionAlgo.getContentEncryptionKey(headers);
+    }
+    
+    protected byte[] getEncryptedContentEncryptionKey(byte[] theCek) {
+        return keyEncryptionAlgo.getEncryptedContentEncryptionKey(headers, 
theCek);
+    }
+    
+    protected String getContentEncryptionAlgoJwt() {
+        return headers.getContentEncryptionAlgorithm();
+    }
+    protected String getContentEncryptionAlgoJava() {
+        return Algorithm.toJavaName(getContentEncryptionAlgoJwt());
+    }
+    protected byte[] getAAD(JweHeaders theHeaders) {
+        return 
contentEncryptionAlgo.getAdditionalAuthenticationData(writer.headersToJson(theHeaders));
+    }
+    public String encrypt(byte[] content, String contentType) {
+        JweEncryptionInternal state = getInternalState(contentType);
+        
+        byte[] cipher = CryptoUtils.encryptBytes(content, 
createCekSecretKey(state), state.keyProps);
+        
+        
+        JweCompactProducer producer = getJweCompactProducer(state, cipher);
+        return producer.getJweContent();
+    }
+    
+    protected JweCompactProducer getJweCompactProducer(JweEncryptionInternal 
state, byte[] cipher) {
+        return new JweCompactProducer(state.theHeaders, 
+                                      getJwtHeadersWriter(),                
+                                      state.jweContentEncryptionKey,
+                                      state.theIv,
+                                      cipher,
+                                      DEFAULT_AUTH_TAG_LENGTH);
+    }
+    
+    protected JwtHeadersWriter getJwtHeadersWriter() {
+        return writer;
+    }
+    protected JweHeaders getJweHeaders() {
+        return headers;
+    }
+    @Override
+    public JweEncryptionState createJweEncryptionState(String contentType) {
+        JweEncryptionInternal state = getInternalState(contentType);
+        Cipher c = CryptoUtils.initCipher(createCekSecretKey(state), 
state.keyProps, 
+                                          Cipher.ENCRYPT_MODE);
+        return new JweEncryptionState(c, 
+                                      state.theHeaders, 
+                                      state.jweContentEncryptionKey, 
+                                      state.theIv,
+                                      getAuthenticationTagProducer(state),
+                                      state.keyProps.isCompressionSupported());
+    }
+    protected AuthenticationTagProducer 
getAuthenticationTagProducer(JweEncryptionInternal state) {
+        return null;
+    }
+    protected SecretKey createCekSecretKey(JweEncryptionInternal state) {
+        return CryptoUtils.createSecretKeySpec(getActualCek(state.secretKey, 
this.getContentEncryptionAlgoJwt()), 
+                                               state.keyProps.getKeyAlgo());
+    }
+    
+    protected byte[] getActualCek(byte[] theCek, String algoJwt) {
+        return theCek;
+    }
+    
+    private JweEncryptionInternal getInternalState(String contentType) {
+        byte[] theCek = getContentEncryptionKey();
+        String contentEncryptionAlgoJavaName = 
Algorithm.toJavaName(headers.getContentEncryptionAlgorithm());
+        KeyProperties keyProps = new 
KeyProperties(contentEncryptionAlgoJavaName);
+        keyProps.setCompressionSupported(compressionRequired(headers));
+        
+        byte[] theIv = contentEncryptionAlgo.getInitVector();
+        AlgorithmParameterSpec specParams = getAlgorithmParameterSpec(theIv);
+        keyProps.setAlgoSpec(specParams);
+        byte[] jweContentEncryptionKey = 
getEncryptedContentEncryptionKey(theCek);
+        
+        JweHeaders theHeaders = headers;
+        if (contentType != null) {
+            theHeaders = new JweHeaders(theHeaders.asMap());
+            theHeaders.setContentType(contentType);
+        }
+        byte[] additionalEncryptionParam = getAAD(theHeaders);
+        keyProps.setAdditionalData(additionalEncryptionParam);
+        
+        
+        JweEncryptionInternal state = new JweEncryptionInternal();
+        state.theHeaders = theHeaders;
+        state.jweContentEncryptionKey = jweContentEncryptionKey;
+        state.keyProps = keyProps;
+        state.secretKey = theCek; 
+        state.theIv = theIv;
+        return state;
+    }
+    private boolean compressionRequired(JweHeaders theHeaders) {
+        return 
JwtConstants.DEFLATE_ZIP_ALGORITHM.equals(theHeaders.getZipAlgorithm());
+    }
+    protected KeyEncryptionAlgorithm getKeyEncryptionAlgo() {
+        return keyEncryptionAlgo;
+    }
+    protected static class JweEncryptionInternal {
+        JweHeaders theHeaders;
+        byte[] jweContentEncryptionKey;
+        byte[] theIv;
+        KeyProperties keyProps;
+        byte[] secretKey;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractWrapKeyEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractWrapKeyEncryptionAlgorithm.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractWrapKeyEncryptionAlgorithm.java
new file mode 100644
index 0000000..162a8df
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractWrapKeyEncryptionAlgorithm.java
@@ -0,0 +1,96 @@
+/**
+ * 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.jose.jwe;
+
+import java.security.Key;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Set;
+
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.KeyProperties;
+
+public abstract class AbstractWrapKeyEncryptionAlgorithm implements 
KeyEncryptionAlgorithm {
+    private Key keyEncryptionKey;
+    private boolean wrap;
+    private String algorithm;
+    private Set<String> supportedAlgorithms;
+    protected AbstractWrapKeyEncryptionAlgorithm(Key key, Set<String> 
supportedAlgorithms) {
+        this(key, null, true, supportedAlgorithms);
+    }
+    protected AbstractWrapKeyEncryptionAlgorithm(Key key, boolean wrap, 
Set<String> supportedAlgorithms) {
+        this(key, null, wrap, supportedAlgorithms);
+    }
+    protected AbstractWrapKeyEncryptionAlgorithm(Key key, String jweAlgo, 
Set<String> supportedAlgorithms) {
+        this(key, jweAlgo, true, supportedAlgorithms);
+    }
+    protected AbstractWrapKeyEncryptionAlgorithm(Key key, String jweAlgo, 
boolean wrap, 
+                                                 Set<String> 
supportedAlgorithms) {
+        this.keyEncryptionKey = key;
+        this.algorithm = jweAlgo;
+        this.wrap = wrap;
+        this.supportedAlgorithms = supportedAlgorithms;
+    }
+    @Override
+    public byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] 
cek) {
+        checkAlgorithms(headers, algorithm);
+        KeyProperties secretKeyProperties = new 
KeyProperties(getKeyEncryptionAlgoJava(headers));
+        AlgorithmParameterSpec spec = getAlgorithmParameterSpec(headers); 
+        if (spec != null) {
+            secretKeyProperties.setAlgoSpec(spec);
+        }
+        if (!wrap) {
+            return CryptoUtils.encryptBytes(cek, keyEncryptionKey, 
secretKeyProperties);
+        } else {
+            return CryptoUtils.wrapSecretKey(cek, 
+                                             
getContentEncryptionAlgoJava(headers),
+                                             keyEncryptionKey, 
+                                             secretKeyProperties);
+        }
+    }
+    protected String getKeyEncryptionAlgoJava(JweHeaders headers) {
+        return Algorithm.toJavaName(headers.getKeyEncryptionAlgorithm());
+    }
+    protected String getContentEncryptionAlgoJava(JweHeaders headers) {
+        return Algorithm.toJavaName(headers.getContentEncryptionAlgorithm());
+    }
+    protected AlgorithmParameterSpec getAlgorithmParameterSpec(JweHeaders 
headers) {
+        return null;
+    }
+    protected String checkAlgorithm(String algo) {
+        if (algo != null && !supportedAlgorithms.contains(algo)) {
+            throw new SecurityException();
+        }
+        return algo;
+    }
+    protected void checkAlgorithms(JweHeaders headers, String defaultAlgo) {
+        String providedAlgo = headers.getKeyEncryptionAlgorithm();
+        if ((providedAlgo == null && defaultAlgo == null)
+            || (providedAlgo != null && defaultAlgo != null && 
!providedAlgo.equals(defaultAlgo))) {
+            throw new SecurityException();
+        }
+        if (providedAlgo != null) {
+            checkAlgorithm(providedAlgo);
+        } else if (defaultAlgo != null) {
+            headers.setKeyEncryptionAlgorithm(defaultAlgo);
+            checkAlgorithm(defaultAlgo);
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesCbcHmacJweDecryption.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesCbcHmacJweDecryption.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesCbcHmacJweDecryption.java
new file mode 100644
index 0000000..518b006
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/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.jose.jwe;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+
+import javax.crypto.spec.IvParameterSpec;
+
+import org.apache.cxf.rs.security.jose.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/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesCbcHmacJweEncryption.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesCbcHmacJweEncryption.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesCbcHmacJweEncryption.java
new file mode 100644
index 0000000..40bba7d
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesCbcHmacJweEncryption.java
@@ -0,0 +1,194 @@
+/**
+ * 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.jose.jwe;
+
+import java.nio.ByteBuffer;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.IvParameterSpec;
+
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+import org.apache.cxf.rs.security.jose.jwt.JwtHeadersWriter;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.HmacUtils;
+
+public class AesCbcHmacJweEncryption extends AbstractJweEncryption {
+    private static final Set<String> SUPPORTED_CEK_ALGORITHMS = new 
HashSet<String>(
+        Arrays.asList(Algorithm.A128CBC_HS256.getJwtName(),
+                      Algorithm.A192CBC_HS384.getJwtName(),
+                      Algorithm.A256CBC_HS512.getJwtName()));
+    private static final Map<String, String> AES_HMAC_MAP;
+    private static final Map<String, Integer> AES_CEK_SIZE_MAP;
+    static {
+        AES_HMAC_MAP = new HashMap<String, String>();
+        AES_HMAC_MAP.put(Algorithm.A128CBC_HS256.getJwtName(), 
Algorithm.HMAC_SHA_256_JAVA);
+        AES_HMAC_MAP.put(Algorithm.A192CBC_HS384.getJwtName(), 
Algorithm.HMAC_SHA_384_JAVA);
+        AES_HMAC_MAP.put(Algorithm.A256CBC_HS512.getJwtName(), 
Algorithm.HMAC_SHA_512_JAVA);
+        
+        AES_CEK_SIZE_MAP = new HashMap<String, Integer>();
+        AES_CEK_SIZE_MAP.put(Algorithm.A128CBC_HS256.getJwtName(), 32);
+        AES_CEK_SIZE_MAP.put(Algorithm.A192CBC_HS384.getJwtName(), 48);
+        AES_CEK_SIZE_MAP.put(Algorithm.A256CBC_HS512.getJwtName(), 64);
+    }
+    public AesCbcHmacJweEncryption(String keyAlgo, 
+                                   String cekAlgoJwt, 
+                                   KeyEncryptionAlgorithm 
keyEncryptionAlgorithm) {
+        this(new JweHeaders(keyAlgo, validateCekAlgorithm(cekAlgoJwt)), 
+             null, null, keyEncryptionAlgorithm);
+    }
+    public AesCbcHmacJweEncryption(JweHeaders headers, 
+                                   KeyEncryptionAlgorithm 
keyEncryptionAlgorithm) {
+        this(headers, null, null, keyEncryptionAlgorithm);
+    }
+    public AesCbcHmacJweEncryption(JweHeaders headers, byte[] cek, 
+                                   byte[] iv, KeyEncryptionAlgorithm 
keyEncryptionAlgorithm) {
+        this(headers, cek, iv, keyEncryptionAlgorithm, null);
+    }
+    public AesCbcHmacJweEncryption(JweHeaders headers, 
+                                   byte[] cek, 
+                                   byte[] iv, 
+                                   KeyEncryptionAlgorithm 
keyEncryptionAlgorithm,
+                                   JwtHeadersWriter writer) {
+        super(headers, new AesCbcContentEncryptionAlgorithm(cek, iv), 
keyEncryptionAlgorithm, writer);
+        validateCekAlgorithm(headers.getContentEncryptionAlgorithm());
+    }
+    @Override
+    protected byte[] getActualCek(byte[] theCek, String algoJwt) {
+        return doGetActualCek(theCek, algoJwt);
+    }
+    @Override
+    protected int getCekSize(String algoJwt) {
+        return getFullCekKeySize(algoJwt) * 8;
+    }
+    protected static byte[] doGetActualCek(byte[] theCek, String algoJwt) {
+        int size = getFullCekKeySize(algoJwt) / 2;
+        byte[] actualCek = new byte[size];
+        System.arraycopy(theCek, size, actualCek, 0, size);
+        return actualCek;
+    }
+    
+    protected static int getFullCekKeySize(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);
+        byte[] authTag = signAndGetTag(macState);
+        return new JweCompactProducer(macState.headersJson,
+                                      state.jweContentEncryptionKey,
+                                      state.theIv,
+                                      cipher,
+                                      authTag);
+    }
+    
+    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) 
{
+        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 = getFullCekKeySize(algoJwt) / 2;
+        byte[] macKey = new byte[size];
+        System.arraycopy(secretKey, 0, macKey, 0, size);
+        
+        String hmacAlgoJava = AES_HMAC_MAP.get(algoJwt);
+        Mac mac = HmacUtils.getInitializedMac(macKey, hmacAlgoJava, null);
+        
+        
+        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(theIv);
+        MacState macState = new MacState();
+        macState.mac = mac;
+        macState.al = al;
+        macState.headersJson = headersJson;
+        return macState;
+    }
+    
+    protected AuthenticationTagProducer getAuthenticationTagProducer(final 
JweEncryptionInternal state) {
+        final MacState macState = getInitializedMacState(state);
+        
+        
+        return new AuthenticationTagProducer() {
+
+            @Override
+            public void update(byte[] cipher, int off, int len) {
+                macState.mac.update(cipher, off, len);
+            }
+
+            @Override
+            public byte[] getTag() {
+                return signAndGetTag(macState);
+            }
+            
+        };
+    }
+    
+    protected byte[] getEncryptedContentEncryptionKey(byte[] theCek) {
+        return 
getKeyEncryptionAlgo().getEncryptedContentEncryptionKey(getJweHeaders(), 
theCek);
+    }
+    
+    private static class AesCbcContentEncryptionAlgorithm extends 
AbstractContentEncryptionAlgorithm {
+        public AesCbcContentEncryptionAlgorithm(byte[] cek, byte[] iv) { 
+            super(cek, iv);    
+        }
+        @Override
+        public AlgorithmParameterSpec getAlgorithmParameterSpec(byte[] theIv) {
+            return new IvParameterSpec(theIv);
+        }
+        @Override
+        public byte[] getAdditionalAuthenticationData(String headersJson) {
+            return null;
+        }
+    }
+    
+    protected static class MacState {
+        protected Mac mac;
+        private byte[] al;
+        private String headersJson;
+    }
+    
+    private static String validateCekAlgorithm(String cekAlgo) {
+        if (!SUPPORTED_CEK_ALGORITHMS.contains(cekAlgo)) {
+            throw new SecurityException();
+        }
+        return cekAlgo;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentDecryptionAlgorithm.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentDecryptionAlgorithm.java
new file mode 100644
index 0000000..05d77ea
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentDecryptionAlgorithm.java
@@ -0,0 +1,30 @@
+/**
+ * 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.jose.jwe;
+
+
+
+public class AesGcmContentDecryptionAlgorithm extends 
AbstractContentEncryptionCipherProperties
+    implements ContentDecryptionAlgorithm {
+
+    @Override
+    public byte[] getEncryptedSequence(byte[] cipher, byte[] authTag) {
+        return JweCompactConsumer.getCipherWithAuthTag(cipher, authTag);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentEncryptionAlgorithm.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentEncryptionAlgorithm.java
new file mode 100644
index 0000000..87774e9
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentEncryptionAlgorithm.java
@@ -0,0 +1,43 @@
+/**
+ * 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.jose.jwe;
+
+import javax.crypto.SecretKey;
+
+import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
+
+
+public class AesGcmContentEncryptionAlgorithm extends 
AbstractContentEncryptionAlgorithm {
+    private static final int DEFAULT_IV_SIZE = 96;
+    public AesGcmContentEncryptionAlgorithm() {
+        this((byte[])null, null);
+    }
+    public AesGcmContentEncryptionAlgorithm(String encodedCek, String 
encodedIv) {
+        this((byte[])CryptoUtils.decodeSequence(encodedCek), 
CryptoUtils.decodeSequence(encodedIv));
+    }
+    public AesGcmContentEncryptionAlgorithm(SecretKey key, byte[] iv) { 
+        this(key.getEncoded(), iv);    
+    }
+    public AesGcmContentEncryptionAlgorithm(byte[] cek, byte[] iv) { 
+        super(cek, iv);    
+    }
+    protected int getIvSize() { 
+        return DEFAULT_IV_SIZE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyDecryptionAlgorithm.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyDecryptionAlgorithm.java
new file mode 100644
index 0000000..0b2c824
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyDecryptionAlgorithm.java
@@ -0,0 +1,57 @@
+/**
+ * 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.jose.jwe;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.SecretKey;
+
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
+
+public class AesGcmWrapKeyDecryptionAlgorithm extends 
WrappedKeyDecryptionAlgorithm {
+    public AesGcmWrapKeyDecryptionAlgorithm(String encodedKey) {    
+        this(CryptoUtils.decodeSequence(encodedKey));
+    }
+    public AesGcmWrapKeyDecryptionAlgorithm(byte[] secretKey) {    
+        this(CryptoUtils.createSecretKeySpec(secretKey, 
Algorithm.AES_ALGO_JAVA));
+    }
+    public AesGcmWrapKeyDecryptionAlgorithm(SecretKey secretKey) {    
+        super(secretKey, true);
+    }
+    @Override
+    protected byte[] getEncryptedContentEncryptionKey(JweCompactConsumer 
consumer) {
+        byte[] encryptedCekKey = 
super.getEncryptedContentEncryptionKey(consumer);
+        byte[] tag = getDecodedBytes(consumer, "tag");
+        return JweCompactConsumer.getCipherWithAuthTag(encryptedCekKey, tag);
+    }
+    protected AlgorithmParameterSpec 
getAlgorithmParameterSpec(JweCompactConsumer consumer) {
+        byte[] iv = getDecodedBytes(consumer, "iv");
+        return CryptoUtils.getContentEncryptionCipherSpec(128, iv);
+    }
+    private byte[] getDecodedBytes(JweCompactConsumer consumer, String 
headerName) {
+        try {
+            Object ivHeader = consumer.getJweHeaders().getHeader(headerName);
+            return Base64UrlUtility.decode(ivHeader.toString());
+        } catch (Exception ex) {
+            throw new SecurityException(ex);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyEncryptionAlgorithm.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyEncryptionAlgorithm.java
new file mode 100644
index 0000000..220763a
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyEncryptionAlgorithm.java
@@ -0,0 +1,64 @@
+/**
+ * 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.jose.jwe;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.crypto.SecretKey;
+
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
+
+public class AesGcmWrapKeyEncryptionAlgorithm extends 
AbstractWrapKeyEncryptionAlgorithm {
+    private static final Set<String> SUPPORTED_ALGORITHMS = new 
HashSet<String>(
+        Arrays.asList(Algorithm.A128GCMKW.getJwtName(),
+                      Algorithm.A192GCMKW.getJwtName(),
+                      Algorithm.A256GCMKW.getJwtName()));
+    public AesGcmWrapKeyEncryptionAlgorithm(String encodedKey, String 
keyAlgoJwt) {    
+        this(CryptoUtils.decodeSequence(encodedKey), keyAlgoJwt);
+    }
+    public AesGcmWrapKeyEncryptionAlgorithm(byte[] keyBytes, String 
keyAlgoJwt) {
+        this(CryptoUtils.createSecretKeySpec(keyBytes, 
Algorithm.AES_ALGO_JAVA),
+             keyAlgoJwt);
+    }
+    public AesGcmWrapKeyEncryptionAlgorithm(SecretKey key, String keyAlgoJwt) {
+        super(key, keyAlgoJwt, true, SUPPORTED_ALGORITHMS);
+    }
+    
+    @Override
+    public byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] 
cek) {
+        byte[] wrappedKeyAndTag = 
super.getEncryptedContentEncryptionKey(headers, cek);
+        byte[] wrappedKey = new byte[wrappedKeyAndTag.length - 128 / 8]; 
+        System.arraycopy(wrappedKeyAndTag, 0, wrappedKey, 0, 
wrappedKeyAndTag.length - 128 / 8);
+        String encodedTag = Base64UrlUtility.encodeChunk(wrappedKeyAndTag, 
+                                                         
wrappedKeyAndTag.length - 128 / 8, 128 / 8);
+        headers.setHeader("tag", encodedTag);
+        return wrappedKey;
+    }
+    protected AlgorithmParameterSpec getAlgorithmParameterSpec(JweHeaders 
headers) {
+        byte[] iv = CryptoUtils.generateSecureRandomBytes(96 / 8);
+        String encodedIv = Base64UrlUtility.encode(iv);
+        headers.setHeader("iv", encodedIv);
+        return CryptoUtils.getContentEncryptionCipherSpec(128, iv);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyDecryptionAlgorithm.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyDecryptionAlgorithm.java
new file mode 100644
index 0000000..14c273f
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyDecryptionAlgorithm.java
@@ -0,0 +1,38 @@
+/**
+ * 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.jose.jwe;
+
+import javax.crypto.SecretKey;
+
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
+
+public class AesWrapKeyDecryptionAlgorithm extends 
WrappedKeyDecryptionAlgorithm {
+    public AesWrapKeyDecryptionAlgorithm(String encodedKey) {    
+        this(CryptoUtils.decodeSequence(encodedKey));
+    }
+    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/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyEncryptionAlgorithm.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyEncryptionAlgorithm.java
new file mode 100644
index 0000000..a0b01b9
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyEncryptionAlgorithm.java
@@ -0,0 +1,48 @@
+/**
+ * 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.jose.jwe;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.crypto.SecretKey;
+
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
+
+public class AesWrapKeyEncryptionAlgorithm extends 
AbstractWrapKeyEncryptionAlgorithm {
+    private static final Set<String> SUPPORTED_ALGORITHMS = new 
HashSet<String>(
+        Arrays.asList(Algorithm.A128KW.getJwtName(),
+                      Algorithm.A192KW.getJwtName(),
+                      Algorithm.A256KW.getJwtName()));
+    public AesWrapKeyEncryptionAlgorithm(String encodedKey, String keyAlgoJwt) 
{    
+        this(CryptoUtils.decodeSequence(encodedKey), keyAlgoJwt);
+    }
+    public AesWrapKeyEncryptionAlgorithm(byte[] keyBytes, String keyAlgoJwt) {
+        this(CryptoUtils.createSecretKeySpec(keyBytes, 
Algorithm.toJavaName(keyAlgoJwt)),
+             keyAlgoJwt);
+    }
+    public AesWrapKeyEncryptionAlgorithm(SecretKey key, String keyAlgoJwt) {
+        super(key, keyAlgoJwt, SUPPORTED_ALGORITHMS);
+    }
+    
+    
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AuthenticationTagProducer.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AuthenticationTagProducer.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AuthenticationTagProducer.java
new file mode 100644
index 0000000..897e68c
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AuthenticationTagProducer.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.jose.jwe;
+
+public interface AuthenticationTagProducer {
+    void update(byte[] cipher, int off, int len);
+    byte[] getTag();
+}

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

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionAlgorithm.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionAlgorithm.java
new file mode 100644
index 0000000..6f53f53
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionAlgorithm.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.jose.jwe;
+
+
+
+public interface ContentEncryptionAlgorithm extends 
ContentEncryptionCipherProperties {
+    byte[] getInitVector();
+    byte[] getContentEncryptionKey(JweHeaders headers);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionCipherProperties.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionCipherProperties.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionCipherProperties.java
new file mode 100644
index 0000000..54da6fd
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionCipherProperties.java
@@ -0,0 +1,27 @@
+/**
+ * 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.jose.jwe;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+
+public interface ContentEncryptionCipherProperties {
+    byte[] getAdditionalAuthenticationData(String headersJson);
+    AlgorithmParameterSpec getAlgorithmParameterSpec(byte[] iv);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
new file mode 100644
index 0000000..c1803c6
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
@@ -0,0 +1,39 @@
+/**
+ * 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.jose.jwe;
+
+import java.security.Key;
+
+public class DirectKeyDecryptionAlgorithm implements KeyDecryptionAlgorithm {
+    private byte[] contentDecryptionKey;
+    public DirectKeyDecryptionAlgorithm(Key contentDecryptionKey) {    
+        this(contentDecryptionKey.getEncoded());
+    }
+    public DirectKeyDecryptionAlgorithm(byte[] contentDecryptionKey) {    
+        this.contentDecryptionKey = contentDecryptionKey;
+    }
+    @Override
+    public byte[] getDecryptedContentEncryptionKey(JweCompactConsumer 
consumer) {
+        byte[] encryptedCEK = consumer.getEncryptedContentEncryptionKey();
+        if (encryptedCEK != null && encryptedCEK.length > 0) {
+            throw new SecurityException();
+        }
+        return contentDecryptionKey;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
new file mode 100644
index 0000000..8bbfd29
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
@@ -0,0 +1,29 @@
+/**
+ * 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.jose.jwe;
+
+
+public class DirectKeyEncryptionAlgorithm implements KeyEncryptionAlgorithm {
+    public byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] 
theCek) {
+        if (headers.getKeyEncryptionAlgorithm() != null) {
+            throw new SecurityException();
+        }
+        return new byte[0];
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java
new file mode 100644
index 0000000..0f1611e
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.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.jose.jwe;
+
+import java.security.Key;
+
+import org.apache.cxf.rs.security.jose.jwt.JwtHeadersReader;
+
+public class DirectKeyJweDecryption extends AbstractJweDecryption {
+    public DirectKeyJweDecryption(Key contentDecryptionKey) {    
+        this(contentDecryptionKey, null);
+    }
+    public DirectKeyJweDecryption(Key contentDecryptionKey, 
JweCryptoProperties props) {    
+        this(contentDecryptionKey, props, null);
+    }
+    public DirectKeyJweDecryption(Key contentDecryptionKey, 
JweCryptoProperties props, 
+                                  JwtHeadersReader reader) {    
+        this(contentDecryptionKey, props, reader,
+             new AesGcmContentDecryptionAlgorithm());
+    }
+    public DirectKeyJweDecryption(Key contentDecryptionKey, 
+                                  JweCryptoProperties props, 
+                                  JwtHeadersReader reader,
+                                  ContentDecryptionAlgorithm cipherProps) {    
+        super(props, reader, new 
DirectKeyDecryptionAlgorithm(contentDecryptionKey),
+              cipherProps);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java
new file mode 100644
index 0000000..69e4ed9
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java
@@ -0,0 +1,47 @@
+/**
+ * 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.jose.jwe;
+
+import javax.crypto.SecretKey;
+
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+
+public class DirectKeyJweEncryption extends AbstractJweEncryption {
+    public DirectKeyJweEncryption(SecretKey cek, byte[] iv) {
+        this(new JweHeaders(Algorithm.toJwtName(cek.getAlgorithm(),
+                                                cek.getEncoded().length * 8)), 
cek.getEncoded(), iv);
+    }
+    public DirectKeyJweEncryption(JweHeaders headers, byte[] cek, byte[] iv) {
+        this(headers, new AesGcmContentEncryptionAlgorithm(cek, iv));
+    }
+    public DirectKeyJweEncryption(JweHeaders headers, 
ContentEncryptionAlgorithm ceAlgo) {
+        super(headers, ceAlgo, new DirectKeyEncryptionAlgorithm());
+    }
+    protected byte[] getProvidedContentEncryptionKey() {
+        return validateCek(super.getProvidedContentEncryptionKey());
+    }
+    private static byte[] validateCek(byte[] cek) {
+        if (cek == null) {
+            // to prevent the cek from being auto-generated which 
+            // does not make sense for the direct key case
+            throw new NullPointerException("CEK must not be null");
+        }
+        return cek;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactConsumer.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactConsumer.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactConsumer.java
new file mode 100644
index 0000000..5cfe012
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactConsumer.java
@@ -0,0 +1,113 @@
+/**
+ * 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.jose.jwe;
+
+import java.io.UnsupportedEncodingException;
+
+import org.apache.cxf.common.util.Base64Exception;
+import org.apache.cxf.rs.security.jose.jwt.JwtHeadersReader;
+import org.apache.cxf.rs.security.jose.jwt.JwtTokenReaderWriter;
+import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility;
+
+
+public class JweCompactConsumer {
+    private String headersJson;
+    private byte[] encryptedCEK;
+    private byte[] initVector;
+    private byte[] encryptedContent;
+    private byte[] authTag;
+    private JweHeaders jweHeaders;
+    public JweCompactConsumer(String jweContent) {
+        this(jweContent, new JwtTokenReaderWriter());
+    }
+    public JweCompactConsumer(String jweContent, JwtHeadersReader reader) {
+        String[] parts = jweContent.split("\\.");
+        if (parts.length != 5) {
+            throw new SecurityException("5 JWE parts are expected");
+        }
+        try {
+            headersJson = new String(Base64UrlUtility.decode(parts[0]));
+            encryptedCEK = Base64UrlUtility.decode(parts[1]);
+            initVector = Base64UrlUtility.decode(parts[2]);
+            
+            encryptedContent = Base64UrlUtility.decode(parts[3]);
+            authTag = Base64UrlUtility.decode(parts[4]);
+            jweHeaders = new 
JweHeaders(reader.fromJsonHeaders(headersJson).asMap());
+        } catch (Base64Exception ex) {
+            throw new SecurityException(ex);
+        }
+    }
+    
+    public void enforceJweCryptoProperties(JweCryptoProperties props) {
+        if (props != null) { 
+            //TODO
+        }
+    }
+    
+    public String getDecodedJsonHeaders() {
+        return headersJson;
+    }
+    
+    public JweHeaders getJweHeaders() {
+        return jweHeaders;
+    }
+    
+    public byte[] getEncryptedContentEncryptionKey() {
+        return encryptedCEK;
+    }
+    
+    public byte[] getContentDecryptionCipherInitVector() {
+        return initVector;
+    }
+    
+    public byte[] getContentEncryptionCipherAAD() {
+        return JweHeaders.toCipherAdditionalAuthData(headersJson);
+    }
+    
+    public byte[] getEncryptionAuthenticationTag() {
+        return authTag;
+    }
+    
+    public byte[] getEncryptedContent() {
+        return encryptedContent;
+    }
+    
+    public byte[] getEncryptedContentWithAuthTag() {
+        return getCipherWithAuthTag(encryptedContent, authTag);
+    }
+    
+    public static byte[] getCipherWithAuthTag(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(JweDecryptionProvider decryption) {
+        return decryption.decrypt(this);
+    }
+    public String getDecryptedContentText(JweDecryptionProvider decryption) {
+        try {
+            return new String(getDecryptedContent(decryption), "UTF-8");
+        } catch (UnsupportedEncodingException ex) {
+            throw new SecurityException(ex);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactProducer.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactProducer.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactProducer.java
new file mode 100644
index 0000000..ca0cda8
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCompactProducer.java
@@ -0,0 +1,155 @@
+/**
+ * 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.jose.jwe;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.cxf.rs.security.jose.jwt.JwtHeadersWriter;
+import org.apache.cxf.rs.security.jose.jwt.JwtTokenReaderWriter;
+import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility;
+
+
+public class JweCompactProducer {
+    private StringBuilder jweContentBuilder;
+    private String encodedEncryptedContent;
+    private String encodedAuthTag;
+    public JweCompactProducer(JweHeaders headers,
+                       byte[] encryptedContentEncryptionKey,
+                       byte[] cipherInitVector,
+                       byte[] encryptedContentNoTag,
+                       byte[] authenticationTag) {    
+        this(headers, null, encryptedContentEncryptionKey, 
+             cipherInitVector, encryptedContentNoTag, authenticationTag);
+    }
+    
+    public JweCompactProducer(JweHeaders headers,
+                       JwtHeadersWriter writer,
+                       byte[] encryptedContentEncryptionKey,
+                       byte[] cipherInitVector,
+                       byte[] encryptedContentNoTag,
+                       byte[] authenticationTag) {
+        this(getHeadersJson(headers, writer),
+             encryptedContentEncryptionKey,
+             cipherInitVector,
+             encryptedContentNoTag,
+             authenticationTag);
+    }
+    public JweCompactProducer(String headersJson,
+                              byte[] encryptedContentEncryptionKey,
+                              byte[] cipherInitVector,
+                              byte[] encryptedContentNoTag,
+                              byte[] authenticationTag) {
+        jweContentBuilder = startJweContent(new StringBuilder(), headersJson, 
+                                  encryptedContentEncryptionKey, 
cipherInitVector);
+        this.encodedEncryptedContent = 
Base64UrlUtility.encode(encryptedContentNoTag);
+        this.encodedAuthTag = Base64UrlUtility.encode(authenticationTag);
+       
+    }
+    
+    public JweCompactProducer(JweHeaders headers,
+                       byte[] encryptedContentEncryptionKey,
+                       byte[] cipherInitVector,
+                       byte[] encryptedContentWithTag,
+                       int authTagLengthBits) {    
+        this(headers, null, encryptedContentEncryptionKey, 
+             cipherInitVector, encryptedContentWithTag, authTagLengthBits);
+    }
+    public JweCompactProducer(JweHeaders headers,
+                       JwtHeadersWriter writer,
+                       byte[] encryptedContentEncryptionKey,
+                       byte[] cipherInitVector,
+                       byte[] encryptedContentWithTag,
+                       int authTagLengthBits) {
+        jweContentBuilder = startJweContent(new StringBuilder(), headers, 
writer,
+                                   encryptedContentEncryptionKey, 
cipherInitVector);
+        this.encodedEncryptedContent = Base64UrlUtility.encodeChunk(
+            encryptedContentWithTag, 
+            0, 
+            encryptedContentWithTag.length - authTagLengthBits / 8);
+        this.encodedAuthTag = Base64UrlUtility.encodeChunk(
+            encryptedContentWithTag, 
+            encryptedContentWithTag.length - authTagLengthBits / 8, 
+            authTagLengthBits / 8);
+        
+    }
+    public static String startJweContent(JweHeaders headers,
+                                                JwtHeadersWriter writer, 
+                                                byte[] 
encryptedContentEncryptionKey,
+                                                byte[] cipherInitVector) {
+        return startJweContent(new StringBuilder(), 
+                               headers, writer, encryptedContentEncryptionKey, 
cipherInitVector).toString();       
+    }
+    public static StringBuilder startJweContent(StringBuilder sb,
+                                        JweHeaders headers,
+                                        JwtHeadersWriter writer, 
+                                        byte[] encryptedContentEncryptionKey,
+                                        byte[] cipherInitVector) {
+        return startJweContent(sb, 
+                               getHeadersJson(headers, writer), 
+                               encryptedContentEncryptionKey, 
+                               cipherInitVector);
+    }
+    private static String getHeadersJson(JweHeaders headers,
+                                         JwtHeadersWriter writer) {
+        writer = writer == null ? new JwtTokenReaderWriter() : writer;
+        return writer.headersToJson(headers);
+        
+    }
+    public static StringBuilder startJweContent(StringBuilder sb,
+                                                String headersJson,
+                                                byte[] 
encryptedContentEncryptionKey,
+                                                byte[] cipherInitVector) {
+        String encodedHeaders = Base64UrlUtility.encode(headersJson);
+        String encodedContentEncryptionKey = 
Base64UrlUtility.encode(encryptedContentEncryptionKey);
+        String encodedInitVector = Base64UrlUtility.encode(cipherInitVector);
+        sb.append(encodedHeaders)
+            .append('.')
+            .append(encodedContentEncryptionKey == null ? "" : 
encodedContentEncryptionKey)
+            .append('.')
+            .append(encodedInitVector == null ? "" : encodedInitVector)
+            .append('.');
+        return sb;
+    }
+    
+    public static void startJweContent(OutputStream os,
+                                       JweHeaders headers,
+                                       JwtHeadersWriter writer, 
+                                       byte[] encryptedContentEncryptionKey,
+                                       byte[] cipherInitVector) throws 
IOException {
+        writer = writer == null ? new JwtTokenReaderWriter() : writer;
+        byte[] jsonBytes = writer.headersToJson(headers).getBytes("UTF-8");
+        Base64UrlUtility.encodeAndStream(jsonBytes, 0, jsonBytes.length, os);
+        byte[] dotBytes = new byte[]{'.'};
+        os.write(dotBytes);
+        Base64UrlUtility.encodeAndStream(encryptedContentEncryptionKey, 0, 
+                                         encryptedContentEncryptionKey.length, 
os);
+        os.write(dotBytes);
+        Base64UrlUtility.encodeAndStream(cipherInitVector, 0, 
cipherInitVector.length, os);
+        os.write(dotBytes);         
+    }
+    
+    public String getJweContent() {
+        return jweContentBuilder.append(encodedEncryptedContent)
+                 .append('.')
+                 .append(encodedAuthTag)
+                 .toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCryptoProperties.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCryptoProperties.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCryptoProperties.java
new file mode 100644
index 0000000..54150e4
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweCryptoProperties.java
@@ -0,0 +1,22 @@
+/**
+ * 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.jose.jwe;
+
+public class JweCryptoProperties {
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweDecryptionOutput.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweDecryptionOutput.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweDecryptionOutput.java
new file mode 100644
index 0000000..f3cf255
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweDecryptionOutput.java
@@ -0,0 +1,43 @@
+/**
+ * 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.jose.jwe;
+
+import java.io.UnsupportedEncodingException;
+
+public class JweDecryptionOutput {
+    private JweHeaders headers;
+    private byte[] content;
+    public JweDecryptionOutput(JweHeaders headers, byte[] content) {
+        this.headers = headers;
+        this.content = content;
+    }
+    public JweHeaders getHeaders() {
+        return headers;
+    }
+    public byte[] getContent() {
+        return content;
+    }
+    public String getContentText() {
+        try {
+            return new String(getContent(), "UTF-8");
+        } catch (UnsupportedEncodingException ex) {
+            throw new SecurityException(ex);
+        }
+    }
+}

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

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionProvider.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionProvider.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionProvider.java
new file mode 100644
index 0000000..5b9afee
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionProvider.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.jose.jwe;
+
+
+
+public interface JweEncryptionProvider {
+    String encrypt(byte[] jweContent, String contentType);
+    JweEncryptionState createJweEncryptionState(String contentType);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/30dec871/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionState.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionState.java
 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionState.java
new file mode 100644
index 0000000..0732250
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweEncryptionState.java
@@ -0,0 +1,63 @@
+/**
+ * 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.jose.jwe;
+
+import javax.crypto.Cipher;
+
+public class JweEncryptionState {
+    private Cipher cipher;
+    private JweHeaders headers;
+    private byte[] contentEncryptionKey;
+    private byte[] iv;
+    private boolean compressionSupported;
+    private AuthenticationTagProducer authTagProducer;
+    
+    public JweEncryptionState(Cipher cipher, 
+                              JweHeaders headers, 
+                              byte[] contentEncryptionKey, 
+                              byte[] iv, 
+                              AuthenticationTagProducer authTagProducer,
+                              boolean compressionSupported) {
+        this.cipher = cipher;
+        this.headers = headers;
+        this.contentEncryptionKey = contentEncryptionKey;
+        this.iv = iv;
+        this.authTagProducer = authTagProducer;
+        this.compressionSupported = compressionSupported;
+    }
+    public Cipher getCipher() {
+        return cipher;
+    }
+    public JweHeaders getHeaders() {
+        return headers;
+    }
+    public byte[] getContentEncryptionKey() {
+        return contentEncryptionKey;
+    }
+    public byte[] getIv() {
+        return iv;
+    }
+    public boolean isCompressionSupported() {
+        return compressionSupported;
+    }
+    public AuthenticationTagProducer getAuthTagProducer() {
+        return authTagProducer;
+    }
+    
+}

Reply via email to