cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject [2/2] cxf git commit: [CXF-7434] JweJson and other related improvements
Date Fri, 30 Jun 2017 15:41:06 GMT
[CXF-7434] JweJson and other related improvements


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

Branch: refs/heads/3.1.x-fixes
Commit: 91a5375ab63181521f36cda127de8baec7f620b7
Parents: 7c159a7
Author: Sergey Beryozkin <sberyozkin@gmail.com>
Authored: Fri Jun 30 15:17:38 2017 +0100
Committer: Sergey Beryozkin <sberyozkin@gmail.com>
Committed: Fri Jun 30 16:40:38 2017 +0100

----------------------------------------------------------------------
 .../cxf/jaxrs/json/basic/JsonMapObject.java     |   4 +
 .../jaxrs/AbstractJweJsonWriterProvider.java    | 104 ++++++-
 .../jaxrs/AbstractJwsJsonWriterProvider.java    |  31 +-
 .../jose/jaxrs/JweJsonWriterInterceptor.java    |  45 +--
 .../jose/jaxrs/JwsJsonWriterInterceptor.java    |  47 +--
 .../JwsMultipartSignatureInFilter.java          |   2 +-
 .../cxf/rs/security/jose/common/JoseUtils.java  |  12 +
 .../jose/common/KeyManagementUtils.java         |  13 +
 .../cxf/rs/security/jose/jwa/KeyAlgorithm.java  |   3 +
 .../jose/jwe/DirectKeyDecryptionAlgorithm.java  |   2 +-
 .../jose/jwe/DirectKeyEncryptionAlgorithm.java  |   5 +-
 .../rs/security/jose/jwe/JweJsonConsumer.java   |   5 +-
 .../jose/jwe/JweJsonEncryptionEntry.java        |   2 +-
 .../rs/security/jose/jwe/JweJsonProducer.java   |  15 +-
 .../cxf/rs/security/jose/jwe/JweUtils.java      | 287 ++++++++++---------
 .../cxf/rs/security/jose/jws/JwsUtils.java      | 121 ++------
 .../security/jose/jwe/JweJsonConsumerTest.java  |  14 +-
 .../cxf/rs/security/jose/jws/JwsUtilsTest.java  |   3 +-
 .../token/provider/jwt/JWTTokenProvider.java    |   2 +-
 .../token/provider/JWTTokenProviderTest.java    |   9 +-
 .../jaxrs/JAXRSClientServerBookTest.java        |   2 +-
 .../systest/jaxrs/security/jose/BookStore.java  |  48 ++++
 .../security/jose/jwejws/JAXRSJweJsonTest.java  |  61 ++--
 .../security/jose/jwejws/JAXRSJweJwsTest.java   |  29 ++
 .../security/jose/jwejws/JAXRSJwsJsonTest.java  |  18 +-
 .../jaxrs/security/certs/jwkPrivateSet.txt      |  11 +
 .../jaxrs/security/jose/jwejws/server.xml       |  12 +
 .../security/jose/jwejws/serverJweJson.xml      |  25 +-
 .../jaxrs/security/jwe.direct.properties        |  21 ++
 .../systest/jaxrs/security/jwejson1.properties  |  22 ++
 .../systest/jaxrs/security/jwejson2.properties  |  22 ++
 .../jaxrs/security/secret.jwk.hmac2.properties  |  19 --
 32 files changed, 630 insertions(+), 386 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/extensions/json-basic/src/main/java/org/apache/cxf/jaxrs/json/basic/JsonMapObject.java
----------------------------------------------------------------------
diff --git a/rt/rs/extensions/json-basic/src/main/java/org/apache/cxf/jaxrs/json/basic/JsonMapObject.java b/rt/rs/extensions/json-basic/src/main/java/org/apache/cxf/jaxrs/json/basic/JsonMapObject.java
index 484853d..0783c5c 100644
--- a/rt/rs/extensions/json-basic/src/main/java/org/apache/cxf/jaxrs/json/basic/JsonMapObject.java
+++ b/rt/rs/extensions/json-basic/src/main/java/org/apache/cxf/jaxrs/json/basic/JsonMapObject.java
@@ -121,4 +121,8 @@ public class JsonMapObject implements Serializable {
     public Map<String, Object> getUpdateCount() {
         return updateCount == null ? null : Collections.<String, Object>unmodifiableMap(updateCount);
     }
+    
+    public Object removeProperty(String name) {
+        return values.remove(name);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweJsonWriterProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweJsonWriterProvider.java b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweJsonWriterProvider.java
index ce9d2cb..e15ae9a 100644
--- a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweJsonWriterProvider.java
+++ b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweJsonWriterProvider.java
@@ -21,10 +21,14 @@ package org.apache.cxf.rs.security.jose.jaxrs;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Properties;
+import java.util.Set;
 import java.util.logging.Logger;
 
 import org.apache.cxf.common.logging.LogUtils;
@@ -35,9 +39,18 @@ import org.apache.cxf.jaxrs.utils.JAXRSUtils;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.rs.security.jose.common.JoseConstants;
+import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
+import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
+import org.apache.cxf.rs.security.jose.jwe.ContentEncryptionProvider;
+import org.apache.cxf.rs.security.jose.jwe.JweEncryption;
 import org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider;
+import org.apache.cxf.rs.security.jose.jwe.JweException;
+import org.apache.cxf.rs.security.jose.jwe.JweHeaders;
 import org.apache.cxf.rs.security.jose.jwe.JweUtils;
-import org.apache.cxf.rs.security.jose.jws.JwsException;
+import org.apache.cxf.rs.security.jose.jwe.KeyEncryptionProvider;
+import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
+import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
+import org.apache.cxf.rs.security.jose.jwk.KeyOperation;
 import org.apache.cxf.rs.security.jose.jws.JwsJsonProducer;
 
 public class AbstractJweJsonWriterProvider {
@@ -51,18 +64,19 @@ public class AbstractJweJsonWriterProvider {
     public void setEncryptionProviders(List<JweEncryptionProvider> providers) {
         this.encProviders = providers;
     }
-    
-    protected List<JweEncryptionProvider> getInitializedEncryptionProviders() {
-        if (encProviders != null) {
-            return encProviders;    
-        } 
+
+    protected List<String> getPropertyLocations() {
         Message m = JAXRSUtils.getCurrentMessage();
         Object propLocsProp = 
             MessageUtils.getContextualProperty(m, JoseConstants.RSSEC_ENCRYPTION_OUT_PROPS, 
                                                JoseConstants.RSSEC_ENCRYPTION_PROPS);
         if (propLocsProp == null) {
-            LOG.warning("JWE JSON init properties resource is not identified");
-            throw new JwsException(JwsException.Error.NO_INIT_PROPERTIES);
+            if (encProviders == null) {
+                LOG.warning("JWE JSON init properties resource is not identified");
+                throw new JweException(JweException.Error.NO_INIT_PROPERTIES);
+            } else {
+                return Collections.emptyList();
+            }
         }
         List<String> propLocs = null;
         if (propLocsProp instanceof String) {
@@ -71,9 +85,79 @@ public class AbstractJweJsonWriterProvider {
         } else {
             propLocs = CastUtils.cast((List<?>)propLocsProp);
         }
+        return propLocs;
+    }
+    
+    protected List<JweEncryptionProvider> getInitializedEncryptionProviders(List<String> propLocs,
+                                              JweHeaders sharedProtectedHeaders,
+                                              List<JweHeaders> perRecipientUnprotectedHeaders) {
+        if (encProviders != null) {
+            return encProviders;
+        }
+        // The task is to have a single ContentEncryptionProvider instance, 
+        // configured to generate CEK only once, paired with all the loaded
+        // KeyEncryptionProviders to have JweEncryptionProviders initialized
+        
+        Message m = JAXRSUtils.getCurrentMessage();
+        // Load all the properties
+        List<Properties> propsList = new ArrayList<Properties>(propLocs.size());
+        for (int i = 0; i < propLocs.size(); i++) {
+            propsList.add(JweUtils.loadJweProperties(m, propLocs.get(i)));
+        }
+        
+        
+        ContentAlgorithm ctAlgo = null;
+        // This set is to find out how many key encryption algorithms are used
+        // If only one then save it in the shared protected headers as opposed to
+        // per-recipient specific not protected ones
+        Set<KeyAlgorithm> keyAlgos = new HashSet<KeyAlgorithm>();
+        
+        List<KeyEncryptionProvider> keyProviders = new LinkedList<KeyEncryptionProvider>();
+        for (int i = 0; i < propLocs.size(); i++) {
+            Properties props = propsList.get(i);
+            ContentAlgorithm currentCtAlgo = JweUtils.getContentEncryptionAlgorithm(m, props, ContentAlgorithm.A128GCM);
+            if (ctAlgo == null) {
+                ctAlgo = currentCtAlgo;
+            } else if (currentCtAlgo != null && !ctAlgo.equals(currentCtAlgo)) {
+                // ctAlgo must be the same for all the recipients
+                throw new JweException(JweException.Error.INVALID_CONTENT_ALGORITHM);
+            }
+            
+            JweHeaders perRecipientUnprotectedHeader = perRecipientUnprotectedHeaders.get(i);
+            KeyEncryptionProvider keyEncryptionProvider = 
+                JweUtils.loadKeyEncryptionProvider(props, m, perRecipientUnprotectedHeader);
+            if (keyEncryptionProvider.getAlgorithm() == KeyAlgorithm.DIRECT && propLocs.size() > 1) {
+                throw new JweException(JweException.Error.INVALID_JSON_JWE);
+            }
+            keyProviders.add(keyEncryptionProvider);
+            
+            keyAlgos.add(perRecipientUnprotectedHeader.getKeyEncryptionAlgorithm());
+        }
+        if (ctAlgo == null) {
+            throw new JweException(JweException.Error.INVALID_CONTENT_ALGORITHM);
+        }
+        sharedProtectedHeaders.setContentEncryptionAlgorithm(ctAlgo);
+        
         List<JweEncryptionProvider> theEncProviders = new LinkedList<JweEncryptionProvider>();
-        for (String propLoc : propLocs) {
-            theEncProviders.addAll(JweUtils.loadJweEncryptionProviders(propLoc, m));
+        if (keyProviders.size() == 1 && keyProviders.get(0).getAlgorithm() == KeyAlgorithm.DIRECT) {
+            JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, propsList.get(0), KeyOperation.ENCRYPT);
+            if (jwk != null) {
+                ContentEncryptionProvider ctProvider = JweUtils.getContentEncryptionProvider(jwk, ctAlgo);
+                JweEncryptionProvider encProvider = new JweEncryption(keyProviders.get(0), ctProvider);
+                theEncProviders.add(encProvider);
+            }
+        } else {
+            ContentEncryptionProvider ctProvider = JweUtils.getContentEncryptionProvider(ctAlgo, true);
+            for (int i = 0; i < keyProviders.size(); i++) {
+                JweEncryptionProvider encProvider = new JweEncryption(keyProviders.get(0), ctProvider);
+                theEncProviders.add(encProvider);
+            }
+        }
+        if (keyAlgos.size() == 1) {
+            sharedProtectedHeaders.setKeyEncryptionAlgorithm(keyAlgos.iterator().next());
+            for (int i = 0; i < perRecipientUnprotectedHeaders.size(); i++) {
+                perRecipientUnprotectedHeaders.get(i).removeProperty(JoseConstants.JWE_HEADER_KEY_ENC_ALGORITHM);
+            }
         }
         return theEncProviders;
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonWriterProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonWriterProvider.java b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonWriterProvider.java
index 0bbe04c..29cfba5 100644
--- a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonWriterProvider.java
+++ b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonWriterProvider.java
@@ -25,6 +25,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Properties;
 import java.util.logging.Logger;
 
 import org.apache.cxf.common.logging.LogUtils;
@@ -36,6 +37,7 @@ import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.rs.security.jose.common.JoseConstants;
 import org.apache.cxf.rs.security.jose.jws.JwsException;
+import org.apache.cxf.rs.security.jose.jws.JwsHeaders;
 import org.apache.cxf.rs.security.jose.jws.JwsJsonProducer;
 import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider;
 import org.apache.cxf.rs.security.jose.jws.JwsUtils;
@@ -51,18 +53,19 @@ public class AbstractJwsJsonWriterProvider {
     public void setSignatureProviders(List<JwsSignatureProvider> signatureProviders) {
         this.sigProviders = signatureProviders;
     }
-    
-    protected List<JwsSignatureProvider> getInitializedSigProviders() {
-        if (sigProviders != null) {
-            return sigProviders;    
-        } 
+
+    protected List<String> getPropertyLocations() {
         Message m = JAXRSUtils.getCurrentMessage();
         Object propLocsProp = 
             MessageUtils.getContextualProperty(m, JoseConstants.RSSEC_SIGNATURE_OUT_PROPS, 
                                                JoseConstants.RSSEC_SIGNATURE_PROPS);
         if (propLocsProp == null) {
-            LOG.warning("JWS JSON init properties resource is not identified");
-            throw new JwsException(JwsException.Error.NO_INIT_PROPERTIES);
+            if (sigProviders == null) {
+                LOG.warning("JWS JSON init properties resource is not identified");
+                throw new JwsException(JwsException.Error.NO_INIT_PROPERTIES);
+            } else {
+                return Collections.emptyList();
+            }
         }
         List<String> propLocs = null;
         if (propLocsProp instanceof String) {
@@ -71,9 +74,19 @@ public class AbstractJwsJsonWriterProvider {
         } else {
             propLocs = CastUtils.cast((List<?>)propLocsProp);
         }
+        return propLocs;
+    }
+    
+    protected List<JwsSignatureProvider> getInitializedSigProviders(
+        List<String> propLocs, List<JwsHeaders> protectedHeaders) {
+        if (sigProviders != null) {
+            return sigProviders;
+        }
+        Message m = JAXRSUtils.getCurrentMessage();
         List<JwsSignatureProvider> theSigProviders = new LinkedList<JwsSignatureProvider>();
-        for (String propLoc : propLocs) {
-            theSigProviders.addAll(JwsUtils.loadSignatureProviders(propLoc, m));
+        for (int i = 0; i < propLocs.size(); i++) {
+            Properties props = JwsUtils.loadJwsProperties(m, propLocs.get(i));
+            theSigProviders.add(JwsUtils.loadSignatureProvider(props, protectedHeaders.get(i)));
         }
         return theSigProviders;
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonWriterInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonWriterInterceptor.java b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonWriterInterceptor.java
index 192be97..7bb9b8a 100644
--- a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonWriterInterceptor.java
+++ b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonWriterInterceptor.java
@@ -36,8 +36,6 @@ import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.io.CachedOutputStream;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
 import org.apache.cxf.rs.security.jose.common.JoseConstants;
-import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
-import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
 import org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider;
 import org.apache.cxf.rs.security.jose.jwe.JweHeaders;
 import org.apache.cxf.rs.security.jose.jwe.JweJsonProducer;
@@ -55,8 +53,16 @@ public class JweJsonWriterInterceptor extends AbstractJweJsonWriterProvider impl
             return;
         }
         OutputStream actualOs = ctx.getOutputStream();
-        List<JweEncryptionProvider> providers = getInitializedEncryptionProviders();
-        
+        JweHeaders sharedProtectedHeaders = new JweHeaders();
+        List<String> propLocs = getPropertyLocations();
+        List<JweHeaders> perRecipientUnprotectedHeaders = new ArrayList<JweHeaders>(propLocs.size());
+        for (int i = 0; i < propLocs.size(); i++) {
+            perRecipientUnprotectedHeaders.add(new JweHeaders());
+        }
+        List<JweEncryptionProvider> providers = getInitializedEncryptionProviders(propLocs,
+                                                                                  sharedProtectedHeaders,
+                                                                                  perRecipientUnprotectedHeaders);
+
         String ctString = null;
         MediaType contentMediaType = ctx.getMediaType();
         if (contentTypeRequired && contentMediaType != null) {
@@ -66,40 +72,19 @@ public class JweJsonWriterInterceptor extends AbstractJweJsonWriterProvider impl
                 ctString = JAXRSUtils.mediaTypeToString(contentMediaType);
             }
         }
-        JweHeaders protectedHeaders = new JweHeaders(ContentAlgorithm.A128GCM);
         if (ctString != null) {
-            protectedHeaders.setContentType(ctString);
-        }
-        protectHttpHeadersIfNeeded(ctx, protectedHeaders);
-        List<KeyAlgorithm> keyAlgos = new ArrayList<>();
-        for (JweEncryptionProvider p : providers) {
-            if (!keyAlgos.contains(p.getKeyAlgorithm())) {
-                keyAlgos.add(p.getKeyAlgorithm());    
-            }
-        }
-        List<JweHeaders> perRecipientUnprotectedHeaders = null;
-        if (keyAlgos.size() == 1) {
-            // Can be optionally set in shared unprotected headers 
-            // or per-recipient headers
-            protectedHeaders.setKeyEncryptionAlgorithm(keyAlgos.get(0));
-        } else {
-            perRecipientUnprotectedHeaders = new ArrayList<JweHeaders>();
-            for (KeyAlgorithm keyAlgo : keyAlgos) {
-                JweHeaders headers = new JweHeaders();
-                headers.setKeyEncryptionAlgorithm(keyAlgo);
-                perRecipientUnprotectedHeaders.add(headers);
-            }
+            sharedProtectedHeaders.setContentType(ctString);
         }
+        protectHttpHeadersIfNeeded(ctx, sharedProtectedHeaders);
         if (useJweOutputStream) {
             //TODO
         } else {
             CachedOutputStream cos = new CachedOutputStream(); 
             ctx.setOutputStream(cos);
             ctx.proceed();
-            
-            
-            
-            JweJsonProducer producer = new JweJsonProducer(protectedHeaders, cos.getBytes());
+
+            JweJsonProducer producer = new JweJsonProducer(sharedProtectedHeaders, cos.getBytes());
+
             String jweContent = producer.encryptWith(providers, perRecipientUnprotectedHeaders);
             
             setJoseMediaType(ctx);

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
index 54566db..beca463 100644
--- a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
+++ b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
@@ -59,15 +59,23 @@ public class JwsJsonWriterInterceptor extends AbstractJwsJsonWriterProvider impl
             ctx.proceed();
             return;
         }
-        List<JwsSignatureProvider> sigProviders = getInitializedSigProviders();
+        List<String> propLocs = getPropertyLocations();
+        List<JwsHeaders> protectedHeaders = new ArrayList<JwsHeaders>(propLocs.size());
+        for (int i = 0; i < propLocs.size(); i++) {
+            protectedHeaders.add(new JwsHeaders());
+        }
+        List<JwsSignatureProvider> sigProviders = getInitializedSigProviders(propLocs, protectedHeaders);
         OutputStream actualOs = ctx.getOutputStream();
         if (useJwsOutputStream) {
-            List<String> protectedHeaders = new ArrayList<String>(sigProviders.size());
-            List<JwsSignature> signatures = new ArrayList<JwsSignature>(sigProviders.size());
-            for (JwsSignatureProvider signer : sigProviders) {
-                JwsHeaders protectedHeader = prepareProtectedHeader(ctx, signer);
+            List<String> encodedProtectedHeaders = new ArrayList<>(sigProviders.size());
+            List<JwsSignature> signatures = new ArrayList<>(sigProviders.size());
+            int size = sigProviders.size();
+            for (int i = 0; i < size; i++) {
+                JwsSignatureProvider signer = sigProviders.get(i);
+                JwsHeaders protectedHeader = protectedHeaders.get(i);
+                prepareProtectedHeader(protectedHeader, ctx, signer, size == 1);
                 String encoded = Base64UrlUtility.encode(writer.toJson(protectedHeader));
-                protectedHeaders.add(encoded);
+                encodedProtectedHeaders.add(encoded);
                 JwsSignature signature = signer.createJwsSignature(protectedHeader);
                 byte[] start = StringUtils.toBytesUTF8(encoded + ".");
                 signature.update(start, 0, start.length);
@@ -75,8 +83,8 @@ public class JwsJsonWriterInterceptor extends AbstractJwsJsonWriterProvider impl
             }    
             ctx.setMediaType(JAXRSUtils.toMediaType(JoseConstants.MEDIA_TYPE_JOSE_JSON));
             actualOs.write(StringUtils.toBytesUTF8("{\"payload\":\""));
-            JwsJsonOutputStream jwsStream = new JwsJsonOutputStream(actualOs, protectedHeaders, signatures);
-            
+            JwsJsonOutputStream jwsStream = new JwsJsonOutputStream(actualOs, encodedProtectedHeaders, signatures);
+
             Base64UrlOutputStream base64Stream = null;
             if (encodePayload) {
                 base64Stream = new Base64UrlOutputStream(jwsStream);
@@ -94,26 +102,31 @@ public class JwsJsonWriterInterceptor extends AbstractJwsJsonWriterProvider impl
             ctx.setOutputStream(cos);
             ctx.proceed();
             JwsJsonProducer p = new JwsJsonProducer(new String(cos.getBytes(), StandardCharsets.UTF_8));
-            for (JwsSignatureProvider signer : sigProviders) {
-                JwsHeaders protectedHeader = prepareProtectedHeader(ctx, signer);
-                p.signWith(signer, protectedHeader, null);    
+            int size = sigProviders.size();
+            for (int i = 0; i < size; i++) {
+                JwsSignatureProvider signer = sigProviders.get(i);
+                JwsHeaders protectedHeader = protectedHeaders.get(i);
+                prepareProtectedHeader(protectedHeader, ctx, signer, size == 1);
+                p.signWith(signer, protectedHeader, null);
             }
             ctx.setMediaType(JAXRSUtils.toMediaType(JoseConstants.MEDIA_TYPE_JOSE_JSON));
             writeJws(p, actualOs);
         }
         
     }
-    
-    private JwsHeaders prepareProtectedHeader(WriterInterceptorContext ctx, 
-                                              JwsSignatureProvider signer) {
-        JwsHeaders headers = new JwsHeaders();
+
+    private void prepareProtectedHeader(JwsHeaders headers,
+                                        WriterInterceptorContext ctx,
+                                        JwsSignatureProvider signer,
+                                        boolean protectHttp) {
         headers.setSignatureAlgorithm(signer.getAlgorithm());
         setContentTypeIfNeeded(headers, ctx);
         if (!encodePayload) {
             headers.setPayloadEncodingStatus(false);
         }
-        protectHttpHeadersIfNeeded(ctx, headers);
-        return headers;
+        if (protectHttp) {
+            protectHttpHeadersIfNeeded(ctx, headers);
+        }
     }
     
     public void setContentTypeRequired(boolean contentTypeRequired) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/multipart/JwsMultipartSignatureInFilter.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/multipart/JwsMultipartSignatureInFilter.java b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/multipart/JwsMultipartSignatureInFilter.java
index e0a306d..2234850 100644
--- a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/multipart/JwsMultipartSignatureInFilter.java
+++ b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/multipart/JwsMultipartSignatureInFilter.java
@@ -103,7 +103,7 @@ public class JwsMultipartSignatureInFilter implements MultipartInputFilter {
                                                    JoseConstants.RSSEC_SIGNATURE_IN_PROPS,
                                                    JoseConstants.RSSEC_SIGNATURE_PROPS);
             
-            theVerifier = JwsUtils.loadSignatureVerifier(message, props, headers, false);
+            theVerifier = JwsUtils.loadSignatureVerifier(message, props, headers);
         } else {
             theVerifier = verifier;
         }

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseUtils.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseUtils.java
index 7752162..ee0a4bd 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseUtils.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseUtils.java
@@ -31,6 +31,7 @@ import java.util.logging.Logger;
 import org.apache.cxf.Bus;
 import org.apache.cxf.common.classloader.ClassLoaderUtils;
 import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PropertyUtils;
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.jaxrs.json.basic.JsonMapObjectReaderWriter;
 import org.apache.cxf.message.Message;
@@ -203,6 +204,17 @@ public final class JoseUtils {
         }
         return props;
     }
+
+    public static boolean checkBooleanProperty(JoseHeaders headers, Properties props, Message m,
+                                                String propertyName) {
+        if (headers == null) {
+            return false;
+        }
+        if (props.containsKey(propertyName)) {
+            return PropertyUtils.isTrue(props.get(propertyName));
+        }
+        return MessageUtils.getContextualBoolean(m, propertyName, false);
+    }
     
     //
     // <End> Copied from JAX-RS RT FRONTEND ResourceUtils

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java
index 10341e3..f900355 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java
@@ -505,4 +505,17 @@ public final class KeyManagementUtils {
         
         return null;
     }
+    
+    public static void setSha1DigestHeader(JoseHeaders headers, Message m, Properties props) {
+        String digest = loadDigestAndEncodeX509Certificate(m, props, MessageDigestUtils.ALGO_SHA_1);
+        if (digest != null) {
+            headers.setX509Thumbprint(digest);
+        }
+    }
+    public static void setSha256DigestHeader(JoseHeaders headers, Message m, Properties props) {
+        String digest = loadDigestAndEncodeX509Certificate(m, props, MessageDigestUtils.ALGO_SHA_256);
+        if (digest != null) {
+            headers.setX509ThumbprintSHA256(digest);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/KeyAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/KeyAlgorithm.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/KeyAlgorithm.java
index cff4ab8..9310320 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/KeyAlgorithm.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/KeyAlgorithm.java
@@ -71,6 +71,9 @@ public enum KeyAlgorithm {
         if (algo == null) {
             return null;
         }
+        if (KeyAlgorithm.DIRECT.getJwaName().equals(algo)) {
+            return KeyAlgorithm.DIRECT;
+        }
         return KeyAlgorithm.valueOf(algo.replace('-', '_')
                                     .replace('+', '_'));
         

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
index 3883dcd..c2893fb 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
@@ -44,7 +44,7 @@ public class DirectKeyDecryptionAlgorithm implements KeyDecryptionProvider {
     }
     @Override
     public KeyAlgorithm getAlgorithm() {
-        return null;
+        return KeyAlgorithm.DIRECT;
     }
     protected void validateKeyEncryptionKey(JweDecryptionInput jweDecryptionInput) {
         byte[] encryptedCEK = jweDecryptionInput.getEncryptedCEK();

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
index 2f038a9..584390a 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
@@ -30,13 +30,14 @@ public class DirectKeyEncryptionAlgorithm implements KeyEncryptionProvider {
         return new byte[0];
     }
     protected void checkKeyEncryptionAlgorithm(JweHeaders headers) {
-        if (headers.getKeyEncryptionAlgorithm() != null) {
+        KeyAlgorithm keyAlgo = headers.getKeyEncryptionAlgorithm();
+        if (keyAlgo != null && !KeyAlgorithm.DIRECT.equals(keyAlgo)) {
             LOG.warning("Key encryption algorithm header is set");
             throw new JweException(JweException.Error.INVALID_KEY_ALGORITHM);
         }
     }
     @Override
     public KeyAlgorithm getAlgorithm() {
-        return null;
+        return KeyAlgorithm.DIRECT;
     }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumer.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumer.java
index 6e3954b..b5170fd 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumer.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumer.java
@@ -94,8 +94,9 @@ public class JweJsonConsumer {
         for (Map.Entry<JweJsonEncryptionEntry, JweHeaders> entry : recipientsMap.entrySet()) {
             KeyAlgorithm keyAlgo = entry.getValue().getKeyEncryptionAlgorithm();
             if (keyAlgo != null && keyAlgo.equals(jwe.getKeyAlgorithm())
-                || keyAlgo == null && jwe.getKeyAlgorithm() == null) {
-                if (recipientProps != null 
+                || keyAlgo == null 
+                    && (jwe.getKeyAlgorithm() == null || KeyAlgorithm.DIRECT.equals(jwe.getKeyAlgorithm()))) {
+                if (recipientProps != null
                     && !entry.getValue().asMap().entrySet().containsAll(recipientProps.entrySet())) {
                     continue;
                 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonEncryptionEntry.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonEncryptionEntry.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonEncryptionEntry.java
index f13502e..55f9897 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonEncryptionEntry.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonEncryptionEntry.java
@@ -47,7 +47,7 @@ public class JweJsonEncryptionEntry implements JsonObject {
     public String toJson() {
         JsonMapObjectReaderWriter jsonWriter = new JsonMapObjectReaderWriter();
         Map<String, Object> recipientsEntry = new LinkedHashMap<String, Object>();
-        if (unprotectedHeader != null) {
+        if (unprotectedHeader != null && !unprotectedHeader.asMap().isEmpty()) {
             recipientsEntry.put("header", this.unprotectedHeader);
         }
         if (encodedEncryptedKey != null) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducer.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducer.java
index 4e8cf71..21c3ddd 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducer.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducer.java
@@ -31,6 +31,7 @@ import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.util.Base64UrlUtility;
 import org.apache.cxf.jaxrs.json.basic.JsonMapObjectReaderWriter;
 import org.apache.cxf.rs.security.jose.common.JoseConstants;
+import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
 
 public class JweJsonProducer {
     protected static final Logger LOG = LogUtils.getL7dLogger(JweJsonProducer.class);
@@ -106,7 +107,7 @@ public class JweJsonProducer {
             JweHeaders perRecipientUnprotected = 
                 recipientUnprotected == null ? null : recipientUnprotected.get(i);
             JweHeaders jsonHeaders = null;
-            if (perRecipientUnprotected != null) {
+            if (perRecipientUnprotected != null && !perRecipientUnprotected.asMap().isEmpty()) {
                 checkCriticalHeaders(perRecipientUnprotected);
                 if (!Collections.disjoint(unionHeaders.asMap().keySet(), 
                                           perRecipientUnprotected.asMap().keySet())) {
@@ -137,10 +138,12 @@ public class JweJsonProducer {
             }
             if (iv == null) {
                 iv = currentIv;
-            } 
-            
-            byte[] encryptedCek = state.getContentEncryptionKey(); 
-            if (encryptedCek.length == 0 && encryptor.getKeyAlgorithm() != null) {
+            }
+
+            byte[] encryptedCek = state.getContentEncryptionKey();
+            if (encryptedCek.length == 0 
+                && encryptor.getKeyAlgorithm() != null
+                && !KeyAlgorithm.DIRECT.equals(encryptor.getKeyAlgorithm())) {
                 LOG.warning("Unexpected key encryption algorithm");
                 throw new JweException(JweException.Error.INVALID_JSON_JWE);
             }
@@ -157,7 +160,7 @@ public class JweJsonProducer {
         }
         if (entries.size() == 1 && canBeFlat) {
             JweHeaders unprotectedEntryHeader = entries.get(0).getUnprotectedHeader();
-            if (unprotectedEntryHeader != null) {
+            if (unprotectedEntryHeader != null && !unprotectedEntryHeader.asMap().isEmpty()) {
                 jweJsonMap.put("header", unprotectedEntryHeader);
             }
             String encryptedKey = entries.get(0).getEncodedEncryptedKey();

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
index 104a532..5d3f523 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
@@ -32,7 +32,6 @@ import java.security.interfaces.RSAPublicKey;
 import java.security.spec.ECFieldFp;
 import java.security.spec.ECPoint;
 import java.security.spec.EllipticCurve;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
@@ -45,7 +44,6 @@ import javax.crypto.SecretKey;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.message.Message;
-import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.phase.PhaseInterceptorChain;
 import org.apache.cxf.rs.security.jose.common.JoseConstants;
 import org.apache.cxf.rs.security.jose.common.JoseHeaders;
@@ -303,8 +301,23 @@ public final class JweUtils {
         return ContentAlgorithm.getAlgorithm(algo);
     }
     public static JweEncryption getDirectKeyJweEncryption(JsonWebKey key) {
-        return getDirectKeyJweEncryption(JwkUtils.toSecretKey(key), 
-                                         getContentAlgo(key.getAlgorithm()));
+        if (AlgorithmUtils.isEcdhEsDirect(key.getAlgorithm())) {
+            return getEcDirectKeyJweEncryption(key, ContentAlgorithm.A128GCM);
+        } else {
+            return getDirectKeyJweEncryption(JwkUtils.toSecretKey(key), getContentAlgo(key.getAlgorithm()));
+        }
+    }
+    public static JweEncryption getEcDirectKeyJweEncryption(JsonWebKey key, ContentAlgorithm ctAlgo) {
+        if (AlgorithmUtils.isEcdhEsDirect(key.getAlgorithm())) {
+            String curve = key.getStringProperty(JsonWebKey.EC_CURVE);
+            if (curve == null) {
+                curve = JsonWebKey.EC_CURVE_P256;
+            }
+            ECPublicKey ecKey = JwkUtils.toECPublicKey(key);
+            return new EcdhDirectKeyJweEncryption(ecKey, curve, ctAlgo);
+        } else {
+            throw new JweException(JweException.Error.INVALID_KEY_ALGORITHM);
+        }
     }
     public static JweEncryption getDirectKeyJweEncryption(SecretKey key, ContentAlgorithm algo) {
         return getDirectKeyJweEncryption(key.getEncoded(), algo);
@@ -318,7 +331,11 @@ public final class JweUtils {
         }
     }
     public static JweDecryption getDirectKeyJweDecryption(JsonWebKey key) {
-        return getDirectKeyJweDecryption(JwkUtils.toSecretKey(key), getContentAlgo(key.getAlgorithm()));
+        if (AlgorithmUtils.isEcdhEsDirect(key.getAlgorithm())) {
+            return getEcDirectKeyJweDecryption(key, ContentAlgorithm.A128GCM);
+        } else {
+            return getDirectKeyJweDecryption(JwkUtils.toSecretKey(key), getContentAlgo(key.getAlgorithm()));
+        }
     }
     public static JweDecryption getDirectKeyJweDecryption(SecretKey key, ContentAlgorithm algorithm) {
         return getDirectKeyJweDecryption(key.getEncoded(), algorithm);
@@ -331,6 +348,18 @@ public final class JweUtils {
                                  getContentDecryptionProvider(algorithm));
         }
     }
+    public static JweDecryption getEcDirectKeyJweDecryption(JsonWebKey key, ContentAlgorithm ctAlgo) {
+        if (AlgorithmUtils.isEcdhEsDirect(key.getAlgorithm())) {
+            String curve = key.getStringProperty(JsonWebKey.EC_CURVE);
+            if (curve == null) {
+                curve = JsonWebKey.EC_CURVE_P256;
+            }
+            ECPrivateKey ecKey = JwkUtils.toECPrivateKey(key);
+            return new EcdhDirectKeyJweDecryption(ecKey, ctAlgo);
+        } else {
+            throw new JweException(JweException.Error.INVALID_KEY_ALGORITHM);
+        }
+    }
     public static JweEncryptionProvider loadEncryptionProvider(boolean required) {
         return loadEncryptionProvider(null, required);
     }
@@ -340,97 +369,109 @@ public final class JweUtils {
         if (props == null) {
             return null;
         }
-        return loadEncryptionProvider(props, headers, required);
+        return loadEncryptionProvider(props, headers);
     }
 
-    public static JweEncryptionProvider loadEncryptionProvider(Properties props, JweHeaders headers, boolean required) {
+    public static JweEncryptionProvider loadEncryptionProvider(Properties props, JweHeaders headers) {
         Message m = PhaseInterceptorChain.getCurrentMessage();
-        
-        boolean includeCert = 
-            headers != null && MessageUtils.getContextualBoolean(
-                m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_CERT, false);
-        boolean includeCertSha1 = headers != null && MessageUtils.getContextualBoolean(
-                m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_CERT_SHA1, false);
-        boolean includeCertSha256 = !includeCertSha1 && headers != null && MessageUtils.getContextualBoolean(
-                m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_CERT_SHA256, false);
+        return loadEncryptionProvider(props, m, headers);
+    }
+    
+    public static JweEncryptionProvider loadEncryptionProvider(Properties props, Message m, JweHeaders headers) {
+    
+        KeyEncryptionProvider keyEncryptionProvider = loadKeyEncryptionProvider(props, m, headers);
 
-        KeyEncryptionProvider keyEncryptionProvider = null;
-        KeyAlgorithm keyAlgo = getKeyEncryptionAlgorithm(m, props, null, null);
         ContentAlgorithm contentAlgo = getContentEncryptionAlgorithm(m, props, null, ContentAlgorithm.A128GCM);
         if (m != null) {
             m.put(JoseConstants.RSSEC_ENCRYPTION_CONTENT_ALGORITHM, contentAlgo.getJwaName());
         }
         ContentEncryptionProvider ctEncryptionProvider = null;
-        if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
+        if (KeyAlgorithm.DIRECT == keyEncryptionProvider.getAlgorithm()) {
             JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, KeyOperation.ENCRYPT);
-            if (KeyAlgorithm.DIRECT == keyAlgo) {
-                contentAlgo = getContentEncryptionAlgorithm(m, props, 
-                                            ContentAlgorithm.getAlgorithm(jwk.getAlgorithm()), 
-                                            ContentAlgorithm.A128GCM);
+            if (jwk != null) {
+                contentAlgo = getContentEncryptionAlgorithm(m, props,
+                    jwk.getAlgorithm() != null ? ContentAlgorithm.getAlgorithm(jwk.getAlgorithm()) : null,
+                    contentAlgo);
                 ctEncryptionProvider = getContentEncryptionProvider(jwk, contentAlgo);
+            }         
+        }
+        String compression = props.getProperty(JoseConstants.RSSEC_ENCRYPTION_ZIP_ALGORITHM);
+        return createJweEncryptionProvider(keyEncryptionProvider,
+                                    ctEncryptionProvider,
+                                    contentAlgo,
+                                    compression,
+                                    headers);
+    }
+    
+    public static KeyEncryptionProvider loadKeyEncryptionProvider(Properties props, Message m, JweHeaders headers) {
+        
+        KeyEncryptionProvider keyEncryptionProvider = null;
+        KeyAlgorithm keyAlgo = getKeyEncryptionAlgorithm(m, props, null, null);
+        if (KeyAlgorithm.DIRECT == keyAlgo) {
+            keyEncryptionProvider = new DirectKeyEncryptionAlgorithm();    
+        } else {
+            boolean includeCert = 
+                JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_CERT);
+            boolean includeCertSha1 = 
+                JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_CERT_SHA1);
+            boolean includeCertSha256 =  
+                JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_CERT_SHA256);
+            boolean includeKeyId = 
+                JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_KEY_ID);
+
+            if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
+                JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, KeyOperation.ENCRYPT);
+                if (jwk != null) {
+                    keyAlgo = getKeyEncryptionAlgorithm(m, props,
+                                                        KeyAlgorithm.getAlgorithm(jwk.getAlgorithm()),
+                                                        getDefaultKeyAlgorithm(jwk));
+                    keyEncryptionProvider = getKeyEncryptionProvider(jwk, keyAlgo);
+    
+                    boolean includePublicKey = 
+                        JoseUtils.checkBooleanProperty(headers, props, m, 
+                                                       JoseConstants.RSSEC_ENCRYPTION_INCLUDE_PUBLIC_KEY);
+                    if (includeCert) {
+                        JwkUtils.includeCertChain(jwk, headers, keyAlgo.getJwaName());
+                    }
+                    if (includeCertSha1) {
+                        KeyManagementUtils.setSha1DigestHeader(headers, m, props);
+                    } else if (includeCertSha256) {
+                        KeyManagementUtils.setSha256DigestHeader(headers, m, props);
+                    }
+                    if (includePublicKey) {
+                        JwkUtils.includePublicKey(jwk, headers, keyAlgo.getJwaName());
+                    }
+                    if (includeKeyId && jwk.getKeyId() != null) {
+                        headers.setKeyId(jwk.getKeyId());
+                    }
+                }
             } else {
-                keyAlgo = getKeyEncryptionAlgorithm(m, props, 
-                                                    KeyAlgorithm.getAlgorithm(jwk.getAlgorithm()), 
-                                                    getDefaultKeyAlgorithm(jwk));
-                keyEncryptionProvider = getKeyEncryptionProvider(jwk, keyAlgo);
-                
-                boolean includePublicKey = headers != null && MessageUtils.getContextualBoolean(
-                    m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_PUBLIC_KEY, false);
-                boolean includeKeyId = headers != null && MessageUtils.getContextualBoolean(
-                    m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_KEY_ID, false);
-                
+                keyEncryptionProvider = getPublicKeyEncryptionProvider(
+                    KeyManagementUtils.loadPublicKey(m, props),
+                    props,
+                    keyAlgo);
                 if (includeCert) {
-                    JwkUtils.includeCertChain(jwk, headers, keyAlgo.getJwaName());
+                    headers.setX509Chain(KeyManagementUtils.loadAndEncodeX509CertificateOrChain(m, props));
                 }
                 if (includeCertSha1) {
-                    String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m, 
-                                        props, MessageDigestUtils.ALGO_SHA_1);
-                    if (digest != null) {
-                        headers.setX509Thumbprint(digest);
-                    }
+                    KeyManagementUtils.setSha1DigestHeader(headers, m, props);
                 } else if (includeCertSha256) {
-                    String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m, 
-                                        props, MessageDigestUtils.ALGO_SHA_256);
-                    if (digest != null) {
-                        headers.setX509ThumbprintSHA256(digest);
-                    }
-                }
-                if (includePublicKey) {
-                    JwkUtils.includePublicKey(jwk, headers, keyAlgo.getJwaName());
-                }
-                if (includeKeyId && jwk.getKeyId() != null && headers != null) {
-                    headers.setKeyId(jwk.getKeyId());
-                }
-            }
-        } else {
-            keyEncryptionProvider = getPublicKeyEncryptionProvider(
-                KeyManagementUtils.loadPublicKey(m, props), 
-                props,
-                keyAlgo);
-            if (includeCert) {
-                headers.setX509Chain(KeyManagementUtils.loadAndEncodeX509CertificateOrChain(m, props));
-            }
-            if (includeCertSha1) {
-                String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m, 
-                                    props, MessageDigestUtils.ALGO_SHA_1);
-                if (digest != null) {
-                    headers.setX509Thumbprint(digest);
+                    KeyManagementUtils.setSha256DigestHeader(headers, m, props);
                 }
-            } else if (includeCertSha256) {
-                String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m, 
-                                    props, MessageDigestUtils.ALGO_SHA_256);
-                if (digest != null) {
-                    headers.setX509ThumbprintSHA256(digest);
+                if (includeKeyId && props.containsKey(JoseConstants.RSSEC_KEY_STORE_ALIAS)) {
+                    headers.setKeyId(props.getProperty(JoseConstants.RSSEC_KEY_STORE_ALIAS));
                 }
             }
         }
+        if (keyEncryptionProvider == null) {
+            throw new JweException(JweException.Error.INVALID_KEY_ALGORITHM);
+        }
+        headers.setKeyEncryptionAlgorithm(keyEncryptionProvider.getAlgorithm());
+        return keyEncryptionProvider;
         
-        String compression = props.getProperty(JoseConstants.RSSEC_ENCRYPTION_ZIP_ALGORITHM);
-        return createJweEncryptionProvider(keyEncryptionProvider,
-                                    ctEncryptionProvider,
-                                    contentAlgo.getJwaName(),
-                                    compression);
     }
+    
+    
     public static JweDecryptionProvider loadDecryptionProvider(boolean required) {
         return loadDecryptionProvider(null, required);
     }
@@ -438,15 +479,14 @@ public final class JweUtils {
         Properties props = loadEncryptionInProperties(required);
         if (props == null) {
             return null;
-        } 
-        
-        return loadDecryptionProvider(props, inHeaders, required);
+        }
+
+        return loadDecryptionProvider(props, inHeaders);
     }
-    
-    public static JweDecryptionProvider loadDecryptionProvider(Properties props, 
-                                                               JweHeaders inHeaders, 
-                                                               boolean required) {
-        
+
+    public static JweDecryptionProvider loadDecryptionProvider(Properties props,
+                                                               JweHeaders inHeaders) {
+
         Message m = PhaseInterceptorChain.getCurrentMessage();
         KeyDecryptionProvider keyDecryptionProvider = null;
         ContentAlgorithm contentAlgo = 
@@ -523,50 +563,6 @@ public final class JweUtils {
         return createJweDecryptionProvider(keyDecryptionProvider, ctDecryptionKey, 
                                            contentAlgo);
     }
-    public static List<JweEncryptionProvider> loadJweEncryptionProviders(String propLoc, Message m) {
-        Properties props = loadJweProperties(m, propLoc);
-        JweEncryptionProvider theEncProvider = loadEncryptionProvider(props, null, false);
-        if (theEncProvider != null) {
-            return Collections.singletonList(theEncProvider);
-        }
-        List<JweEncryptionProvider> theEncProviders = null; 
-        if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
-            List<JsonWebKey> jwks = JwkUtils.loadJsonWebKeys(m, props, KeyOperation.ENCRYPT);
-            if (jwks != null) {
-                theEncProviders = new ArrayList<JweEncryptionProvider>(jwks.size());
-                for (JsonWebKey jwk : jwks) {
-                    theEncProviders.add(getDirectKeyJweEncryption(jwk));
-                }
-            }
-        }
-        if (theEncProviders == null) {
-            LOG.warning("Providers are not available");
-            throw new JweException(JweException.Error.NO_ENCRYPTOR);
-        }
-        return theEncProviders;
-    }
-    public static List<JweDecryptionProvider> loadJweDecryptionProviders(String propLoc, Message m) {
-        Properties props = loadJweProperties(m, propLoc);
-        JweDecryptionProvider theDecProvider = loadDecryptionProvider(props, null, false);
-        if (theDecProvider != null) {
-            return Collections.singletonList(theDecProvider);
-        }
-        List<JweDecryptionProvider> theDecProviders = null; 
-        if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
-            List<JsonWebKey> jwks = JwkUtils.loadJsonWebKeys(m, props, KeyOperation.DECRYPT);
-            if (jwks != null) {
-                theDecProviders = new ArrayList<JweDecryptionProvider>(jwks.size());
-                for (JsonWebKey jwk : jwks) {
-                    theDecProviders.add(getDirectKeyJweDecryption(jwk));
-                }
-            }
-        }
-        if (theDecProviders == null) {
-            LOG.warning("Providers are not available");
-            throw new JweException(JweException.Error.NO_ENCRYPTOR);
-        }
-        return theDecProviders;
-    }
     public static JweEncryptionProvider createJweEncryptionProvider(PublicKey key,
                                                                     KeyAlgorithm keyAlgo,
                                                                     ContentAlgorithm contentEncryptionAlgo) {
@@ -620,17 +616,23 @@ public final class JweUtils {
                                                                     String compression) {
         JweHeaders headers = 
             prepareJweHeaders(keyEncryptionProvider != null ? keyEncryptionProvider.getAlgorithm().getJwaName() : null,
-                contentEncryptionAlgo.getJwaName(), compression);
+                contentEncryptionAlgo.getJwaName(), compression, null);
         return createJweEncryptionProvider(keyEncryptionProvider, headers);
     }
+    
     public static JweEncryptionProvider createJweEncryptionProvider(KeyEncryptionProvider keyEncryptionProvider,
                                                                     JweHeaders headers) {
+        return createJweEncryptionProvider(keyEncryptionProvider, headers, false);
+    }
+    public static JweEncryptionProvider createJweEncryptionProvider(KeyEncryptionProvider keyEncryptionProvider,
+                                                                    JweHeaders headers,
+                                                                    boolean generateCekOnce) {
         ContentAlgorithm contentEncryptionAlgo = headers.getContentEncryptionAlgorithm();
-        if (AlgorithmUtils.isAesCbcHmac(contentEncryptionAlgo.getJwaName())) { 
-            return new AesCbcHmacJweEncryption(contentEncryptionAlgo, keyEncryptionProvider);
+        if (AlgorithmUtils.isAesCbcHmac(contentEncryptionAlgo.getJwaName())) {
+            return new AesCbcHmacJweEncryption(contentEncryptionAlgo, keyEncryptionProvider, generateCekOnce);
         } else {
             return new JweEncryption(keyEncryptionProvider,
-                                     getContentEncryptionProvider(contentEncryptionAlgo));
+                                     getContentEncryptionProvider(contentEncryptionAlgo, generateCekOnce));
         }
     }
     public static JweDecryptionProvider createJweDecryptionProvider(PrivateKey key,
@@ -796,8 +798,9 @@ public final class JweUtils {
     }
     private static JweHeaders prepareJweHeaders(String keyEncryptionAlgo,
                                                 String contentEncryptionAlgo,
-                                                String compression) {
-        JweHeaders headers = new JweHeaders();
+                                                String compression,
+                                                JweHeaders headers) {
+        headers = headers != null ? headers : new JweHeaders();
         if (keyEncryptionAlgo != null) {
             headers.setKeyEncryptionAlgorithm(KeyAlgorithm.getAlgorithm(keyEncryptionAlgo));
         }
@@ -807,21 +810,23 @@ public final class JweUtils {
         }
         return headers;
     }
+    
     private static JweEncryptionProvider createJweEncryptionProvider(KeyEncryptionProvider keyEncryptionProvider,
                                                                      ContentEncryptionProvider ctEncryptionProvider,
-                                                                     String contentEncryptionAlgo,
-                                                                     String compression) {
+                                                                     ContentAlgorithm contentEncryptionAlgo,
+                                                                     String compression,
+                                                                     JweHeaders headers) {
         if (keyEncryptionProvider == null && ctEncryptionProvider == null) {
             LOG.warning("Key or content encryptor is not available");
             throw new JweException(JweException.Error.NO_ENCRYPTOR);
         }
-        JweHeaders headers = 
+        headers =
             prepareJweHeaders(keyEncryptionProvider != null ? keyEncryptionProvider.getAlgorithm().getJwaName() : null,
-                contentEncryptionAlgo, compression);
-        if (keyEncryptionProvider != null) {
+                contentEncryptionAlgo.getJwaName(), compression, headers);
+        if (ctEncryptionProvider == null) {
             return createJweEncryptionProvider(keyEncryptionProvider, headers);
         } else {
-            return new JweEncryption(new DirectKeyEncryptionAlgorithm(), ctEncryptionProvider);
+            return new JweEncryption(keyEncryptionProvider, ctEncryptionProvider);
         }
     }
     private static JweDecryptionProvider createJweDecryptionProvider(KeyDecryptionProvider keyDecryptionProvider,
@@ -873,6 +878,9 @@ public final class JweUtils {
         }
         return algo;
     }
+    public static ContentAlgorithm getContentEncryptionAlgorithm(Properties props) {
+        return getContentEncryptionAlgorithm(PhaseInterceptorChain.getCurrentMessage(), props, null); 
+    }
     public static ContentAlgorithm getContentEncryptionAlgorithm(Properties props,
                                                                  ContentAlgorithm defaultAlgo) {
         return getContentEncryptionAlgorithm(PhaseInterceptorChain.getCurrentMessage(), props, defaultAlgo);
@@ -941,7 +949,8 @@ public final class JweUtils {
             return new JsonWebKeys(jwk);
         }
     }
-    private static Properties loadJweProperties(Message m, String propLoc) {
+    
+    public static Properties loadJweProperties(Message m, String propLoc) {
         try {
             return JoseUtils.loadProperties(propLoc, m.getExchange().getBus());
         } catch (Exception ex) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
index 837caa4..7799e2f 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
@@ -28,7 +28,6 @@ import java.security.interfaces.RSAKey;
 import java.security.interfaces.RSAPrivateKey;
 import java.security.interfaces.RSAPublicKey;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -268,51 +267,6 @@ public final class JwsUtils {
         Properties props = loadSignatureInProperties(required);
         return loadSignatureVerifier(props, headers);
     }
-    public static List<JwsSignatureProvider> loadSignatureProviders(String propLoc, Message m) {
-        Properties props = loadJwsProperties(m, propLoc);
-        JwsSignatureProvider theSigProvider = loadSignatureProvider(m, props, null, true);
-        if (theSigProvider != null) {
-            return Collections.singletonList(theSigProvider);
-        }
-        List<JwsSignatureProvider> theSigProviders = null; 
-        if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
-            List<JsonWebKey> jwks = JwkUtils.loadJsonWebKeys(m, props, KeyOperation.SIGN);
-            if (jwks != null) {
-                theSigProviders = new ArrayList<JwsSignatureProvider>(jwks.size());
-                for (JsonWebKey jwk : jwks) {
-                    theSigProviders.add(JwsUtils.getSignatureProvider(jwk));
-                }
-            }
-        }
-        if (theSigProviders == null) {
-            LOG.warning("Providers are not available");
-            throw new JwsException(JwsException.Error.NO_PROVIDER);
-        }
-        return theSigProviders;
-    }
-    
-    public static List<JwsSignatureVerifier> loadSignatureVerifiers(String propLoc, Message m) {
-        Properties props = loadJwsProperties(m, propLoc);
-        JwsSignatureVerifier theVerifier = loadSignatureVerifier(m, props, null, true);
-        if (theVerifier != null) {
-            return Collections.singletonList(theVerifier);
-        }
-        List<JwsSignatureVerifier> theVerifiers = null; 
-        if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
-            List<JsonWebKey> jwks = JwkUtils.loadJsonWebKeys(m, props, KeyOperation.VERIFY);
-            if (jwks != null) {
-                theVerifiers = new ArrayList<JwsSignatureVerifier>(jwks.size());
-                for (JsonWebKey jwk : jwks) {
-                    theVerifiers.add(JwsUtils.getSignatureVerifier(jwk));
-                }
-            }
-        }
-        if (theVerifiers == null) {
-            LOG.warning("Verifiers are not available");
-            throw new JwsException(JwsException.Error.NO_VERIFIER);
-        }
-        return theVerifiers;
-    }
     public static boolean validateCriticalHeaders(JwsHeaders headers) {
         //TODO: validate JWS specific constraints
         return JoseUtils.validateCriticalHeaders(headers);
@@ -322,31 +276,24 @@ public final class JwsUtils {
         return loadSignatureProvider(PhaseInterceptorChain.getCurrentMessage(),
                                      props, headers);
     }
-    public static JwsSignatureProvider loadSignatureProvider(Message m, 
-                                                              Properties props,
-                                                              JwsHeaders headers) {
-        return loadSignatureProvider(m, props, headers, false);
-    }
     public static JwsSignatureProvider loadSignatureProvider(String propertiesLoc, Bus bus) {
         Properties props = loadSignatureProperties(propertiesLoc, bus);
         return loadSignatureProvider(props, null);
     }
-    
-    private static JwsSignatureProvider loadSignatureProvider(Message m, 
+    public static JwsSignatureProvider loadSignatureProvider(Message m,
                                                              Properties props,
-                                                             JwsHeaders headers,
-                                                             boolean ignoreNullProvider) {
+                                                             JwsHeaders headers) {
         JwsSignatureProvider theSigProvider = null;
-        
-        boolean includeCert = headers != null && MessageUtils.getContextualBoolean(
-                m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT, false);
-        boolean includeCertSha1 = headers != null && MessageUtils.getContextualBoolean(
-                m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT_SHA1, false);
-        boolean includeCertSha256 = !includeCertSha1 && headers != null && MessageUtils.getContextualBoolean(
-                                  m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT_SHA256, false);
-        boolean includeKeyId = headers != null && MessageUtils.getContextualBoolean(
-                m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_KEY_ID, false);
-                                                                                
+
+        boolean includeCert = 
+            JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT);
+        boolean includeCertSha1 = 
+            JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT_SHA1);
+        boolean includeCertSha256 =  
+            JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT_SHA256);
+        boolean includeKeyId =
+            JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_KEY_ID);
+
         if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
             JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, KeyOperation.SIGN);
             if (jwk != null) {
@@ -355,25 +302,18 @@ public final class JwsUtils {
                                                              SignatureAlgorithm.getAlgorithm(jwk.getAlgorithm()), 
                                                              getDefaultKeyAlgorithm(jwk));
                 theSigProvider = JwsUtils.getSignatureProvider(jwk, signatureAlgo);
-                
-                boolean includePublicKey = headers != null && MessageUtils.getContextualBoolean(
-                    m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_PUBLIC_KEY, false);
-                
+
+                boolean includePublicKey = 
+                    JoseUtils.checkBooleanProperty(headers, props, m, 
+                                                   JoseConstants.RSSEC_SIGNATURE_INCLUDE_PUBLIC_KEY);
+
                 if (includeCert) {
                     JwkUtils.includeCertChain(jwk, headers, signatureAlgo.getJwaName());
                 }
                 if (includeCertSha1) {
-                    String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m, 
-                                        props, MessageDigestUtils.ALGO_SHA_1);
-                    if (digest != null) {
-                        headers.setX509Thumbprint(digest);
-                    }
+                    KeyManagementUtils.setSha1DigestHeader(headers, m, props);
                 } else if (includeCertSha256) {
-                    String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m, 
-                                        props, MessageDigestUtils.ALGO_SHA_256);
-                    if (digest != null) {
-                        headers.setX509ThumbprintSHA256(digest);
-                    }
+                    KeyManagementUtils.setSha256DigestHeader(headers, m, props);
                 }
                 if (includePublicKey) {
                     JwkUtils.includePublicKey(jwk, headers, signatureAlgo.getJwaName());
@@ -397,24 +337,16 @@ public final class JwsUtils {
                     headers.setX509Chain(KeyManagementUtils.loadAndEncodeX509CertificateOrChain(m, props));
                 }
                 if (includeCertSha1) {
-                    String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m, 
-                                        props, MessageDigestUtils.ALGO_SHA_1);
-                    if (digest != null) {
-                        headers.setX509Thumbprint(digest);
-                    }
+                    KeyManagementUtils.setSha1DigestHeader(headers, m, props);
                 } else if (includeCertSha256) {
-                    String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m, 
-                                        props, MessageDigestUtils.ALGO_SHA_256);
-                    if (digest != null) {
-                        headers.setX509ThumbprintSHA256(digest);
-                    }
+                    KeyManagementUtils.setSha256DigestHeader(headers, m, props);
                 }  
                 if (includeKeyId && props.containsKey(JoseConstants.RSSEC_KEY_STORE_ALIAS)) {
                     headers.setKeyId(props.getProperty(JoseConstants.RSSEC_KEY_STORE_ALIAS));
                 }
             }
         }
-        if (theSigProvider == null && !ignoreNullProvider) {
+        if (theSigProvider == null) {
             LOG.warning("Provider is not available");
             throw new JwsException(JwsException.Error.NO_PROVIDER);
         }
@@ -423,12 +355,11 @@ public final class JwsUtils {
     public static JwsSignatureVerifier loadSignatureVerifier(Properties props,
                                                              JwsHeaders inHeaders) {
         return loadSignatureVerifier(PhaseInterceptorChain.getCurrentMessage(),
-                                     props, inHeaders, false);
+                                     props, inHeaders);
     }
     public static JwsSignatureVerifier loadSignatureVerifier(Message m,
                                                               Properties props,
-                                                              JwsHeaders inHeaders, 
-                                                              boolean ignoreNullVerifier) {
+                                                              JwsHeaders inHeaders) {
         JwsSignatureVerifier theVerifier = null;
         String inHeaderKid = null;
         if (inHeaders != null) {
@@ -489,13 +420,13 @@ public final class JwsUtils {
                 }
             }
         }
-        if (theVerifier == null && !ignoreNullVerifier) {
+        if (theVerifier == null) {
             LOG.warning("Verifier is not available");
             throw new JwsException(JwsException.Error.NO_VERIFIER);
         }
         return theVerifier;
     }
-    private static Properties loadJwsProperties(Message m, String propLoc) {
+    public static Properties loadJwsProperties(Message m, String propLoc) {
         try {
             return JoseUtils.loadProperties(propLoc, m.getExchange().getBus());
         } catch (Exception ex) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumerTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumerTest.java b/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumerTest.java
index 1ebdb9f..e699559 100644
--- a/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumerTest.java
+++ b/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumerTest.java
@@ -160,18 +160,18 @@ public class JweJsonConsumerTest extends Assert {
         JweEncryptionProvider jwe2 = new JweEncryption(keyEncryption2, contentEncryption);
         jweProviders.add(jwe1);
         jweProviders.add(jwe2);
-        
-        List<JweHeaders> perRecipientHeades = new LinkedList<JweHeaders>();
-        perRecipientHeades.add(new JweHeaders("key1"));
-        perRecipientHeades.add(new JweHeaders("key2"));
-        
+
+        List<JweHeaders> perRecipientHeaders = new LinkedList<JweHeaders>();
+        perRecipientHeaders.add(new JweHeaders("key1"));
+        perRecipientHeaders.add(new JweHeaders("key2"));
+
         JweJsonProducer p = new JweJsonProducer(protectedHeaders,
                                                 sharedUnprotectedHeaders,
                                                 StringUtils.toBytesUTF8(text),
                                                 StringUtils.toBytesUTF8(JweJsonProducerTest.EXTRA_AAD_SOURCE),
                                                 false);
-        
-        String jweJson = p.encryptWith(jweProviders, perRecipientHeades);
+
+        String jweJson = p.encryptWith(jweProviders, perRecipientHeaders);
         doTestMultipleRecipients(jweJson);
     }
     private void doTestMultipleRecipients(String jweJson) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsUtilsTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsUtilsTest.java b/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsUtilsTest.java
index 9faa4c0..be81fde 100644
--- a/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsUtilsTest.java
+++ b/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsUtilsTest.java
@@ -60,8 +60,7 @@ public class JwsUtilsTest extends Assert {
         p.put(JoseConstants.RSSEC_KEY_STORE_ALIAS, "alice");
         JwsSignatureVerifier jws = JwsUtils.loadSignatureVerifier(createMessage(),
                                                                   p,
-                                                                  new JwsHeaders(),
-                                                                  false);
+                                                                  new JwsHeaders());
         assertNotNull(jws);
     }
     @Test

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTTokenProvider.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTTokenProvider.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTTokenProvider.java
index 1a73d6c..e75c36b 100644
--- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTTokenProvider.java
+++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTTokenProvider.java
@@ -332,7 +332,7 @@ public class JWTTokenProvider implements TokenProvider {
         encProperties.put(JoseConstants.RSSEC_KEY_STORE, keystore);
 
         JweEncryptionProvider encProvider =
-            JweUtils.loadEncryptionProvider(encProperties, jweHeaders, false);
+            JweUtils.loadEncryptionProvider(encProperties, jweHeaders);
         // token.getJwsHeaders().setSignatureAlgorithm(sigProvider.getAlgorithm());
 
         return encProvider.encrypt(StringUtils.toBytesUTF8(token), null);

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderTest.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderTest.java
index a9e5491..0776bc4 100644
--- a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderTest.java
+++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderTest.java
@@ -228,8 +228,7 @@ public class JWTTokenProviderTest extends org.junit.Assert {
             decProperties.put(JoseConstants.RSSEC_KEY_PSWD, "skpass");
             
             JweDecryptionProvider decProvider =
-                JweUtils.loadDecryptionProvider(decProperties, jwtConsumer.getHeaders(), false);
-            
+                JweUtils.loadDecryptionProvider(decProperties, jwtConsumer.getHeaders());
             JweDecryptionOutput decOutput = decProvider.decrypt(token);
             String decToken = decOutput.getContentText();
             
@@ -279,7 +278,7 @@ public class JWTTokenProviderTest extends org.junit.Assert {
                               ContentAlgorithm.A128CBC_HS256.name());
             
             JweDecryptionProvider decProvider =
-                JweUtils.loadDecryptionProvider(decProperties, jwtConsumer.getHeaders(), false);
+                JweUtils.loadDecryptionProvider(decProperties, jwtConsumer.getHeaders());
             
             JweDecryptionOutput decOutput = decProvider.decrypt(token);
             String decToken = decOutput.getContentText();
@@ -324,8 +323,8 @@ public class JWTTokenProviderTest extends org.junit.Assert {
             decProperties.put(JoseConstants.RSSEC_KEY_PSWD, "skpass");
             
             JweDecryptionProvider decProvider =
-                JweUtils.loadDecryptionProvider(decProperties, jwtConsumer.getHeaders(), false);
-            
+                JweUtils.loadDecryptionProvider(decProperties, jwtConsumer.getHeaders());
+
             JweDecryptionOutput decOutput = decProvider.decrypt(token);
             String decToken = decOutput.getContentText();
             

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
----------------------------------------------------------------------
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
index e164d3b..c76674f 100644
--- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
@@ -123,7 +123,7 @@ public class JAXRSClientServerBookTest extends AbstractBusClientServerTestBase {
     }
     
     @Test
-    public void testBlockAndTrowException() throws Exception {
+    public void testBlockAndThrowException() throws Exception {
         String address = "http://localhost:" + PORT + "/bookstore/blockAndThrowException";
         WebClient wc = WebClient.create(address);
         Response r = wc.get();

http://git-wip-us.apache.org/repos/asf/cxf/blob/91a5375a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/BookStore.java
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/BookStore.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/BookStore.java
index 5d140ec..bca6df4 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/BookStore.java
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/BookStore.java
@@ -20,7 +20,9 @@
 package org.apache.cxf.systest.jaxrs.security.jose;
 
 
+import java.util.Collections;
 import java.util.List;
+import java.util.Properties;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.InternalServerErrorException;
@@ -29,6 +31,15 @@ import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 
 import org.apache.cxf.jaxrs.ext.multipart.Multipart;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
+import org.apache.cxf.rs.security.jose.jwe.JweDecryptionOutput;
+import org.apache.cxf.rs.security.jose.jwe.JweDecryptionProvider;
+import org.apache.cxf.rs.security.jose.jwe.JweJsonConsumer;
+import org.apache.cxf.rs.security.jose.jwe.JweUtils;
+import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
+import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
 import org.apache.cxf.systest.jaxrs.security.Book;
 
 @Path("/bookstore")
@@ -86,6 +97,43 @@ public class BookStore {
         return books;
     }
 
+    @POST
+    @Path("/books")
+    @Produces({"text/plain"})
+    @Consumes("application/jose+json")
+    public String echoTextJweJsonIn(String jweJson) {
+        
+        JweJsonConsumer consumer = new JweJsonConsumer(jweJson);
+        
+        // Recipient 1
+        final String recipient1PropLoc = "org/apache/cxf/systest/jaxrs/security/jwejson1.properties";
+        final String recipient1Kid = "AesWrapKey";
+        String recipient1DecryptedText = getRecipientText(consumer, recipient1PropLoc, recipient1Kid);
+        
+        // Recipient 2
+        final String recipient2PropLoc = "org/apache/cxf/systest/jaxrs/security/jwejson2.properties";
+        final String recipient2Kid = "AesWrapKey2";
+        String recipient2DecryptedText = getRecipientText(consumer, recipient2PropLoc, recipient2Kid);
+        return recipient1DecryptedText + recipient2DecryptedText;
+    }
+
+    private String getRecipientText(JweJsonConsumer consumer, String recipientPropLoc, String recipientKid) { 
+        Message message = JAXRSUtils.getCurrentMessage();
+        
+        
+        Properties recipientProps = JweUtils.loadJweProperties(message, recipientPropLoc);
+        JsonWebKey recipientKey = JwkUtils.loadJwkSet(message, recipientProps, null).getKey(recipientKid);
+        
+        ContentAlgorithm contentEncryptionAlgorithm = JweUtils.getContentEncryptionAlgorithm(recipientProps);
+        
+        JweDecryptionProvider jweRecipient = 
+            JweUtils.createJweDecryptionProvider(recipientKey, contentEncryptionAlgorithm);
+        
+        JweDecryptionOutput jweRecipientOutput = 
+            consumer.decryptWith(jweRecipient,
+                                 Collections.<String, Object>singletonMap("kid", recipientKid));
+        return jweRecipientOutput.getContentText();
+    }
 }
 
 


Mime
View raw message