cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject cxf git commit: Finishing JWS JSON unencoded payload test, still some work to do for JWS compact
Date Fri, 04 Sep 2015 16:04:15 GMT
Repository: cxf
Updated Branches:
  refs/heads/master 38a805ac4 -> d57cebc10


Finishing JWS JSON unencoded payload test, still some work to do for JWS compact


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

Branch: refs/heads/master
Commit: d57cebc10b34ae3fc8b6cca0c6e61c8fb10e0a60
Parents: 38a805a
Author: Sergey Beryozkin <sberyozkin@gmail.com>
Authored: Fri Sep 4 17:04:01 2015 +0100
Committer: Sergey Beryozkin <sberyozkin@gmail.com>
Committed: Fri Sep 4 17:04:01 2015 +0100

----------------------------------------------------------------------
 .../cxf/jaxrs/provider/json/JsonMapObject.java  |  4 ++
 .../cxf/rs/security/jose/JoseConstants.java     |  4 +-
 .../cxf/rs/security/jose/JoseHeaders.java       |  4 ++
 .../jose/jaxrs/JwsJsonWriterInterceptor.java    | 23 +++++++-
 .../jose/jwe/AbstractJweDecryption.java         |  2 +-
 .../jose/jwe/AbstractJweEncryption.java         |  2 +-
 .../cxf/rs/security/jose/jwe/JweHeaders.java    |  2 +-
 .../cxf/rs/security/jose/jws/JwsHeaders.java    |  5 +-
 .../rs/security/jose/jws/JwsJsonConsumer.java   | 61 ++++++++++++--------
 .../rs/security/jose/jws/JwsJsonProducer.java   | 56 ++++++++++++++----
 .../jose/jws/JwsJsonSignatureEntry.java         | 30 +++++-----
 .../jose/jws/JwsCompactReaderWriterTest.java    | 14 ++++-
 .../security/jose/jws/JwsJsonConsumerTest.java  | 11 ++++
 .../security/jose/jws/JwsJsonProducerTest.java  |  6 +-
 14 files changed, 162 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/d57cebc1/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JsonMapObject.java
----------------------------------------------------------------------
diff --git a/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JsonMapObject.java
b/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JsonMapObject.java
index 88094c6..5740f73 100644
--- a/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JsonMapObject.java
+++ b/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JsonMapObject.java
@@ -46,6 +46,10 @@ public class JsonMapObject {
         values.put(name, value);
     }
     
+    public boolean containsProperty(String name) {
+        return values.containsKey(name);
+    }
+    
     public Object getProperty(String name) {
         return values.get(name);
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/d57cebc1/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
index c5f3e03..0c04791 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
@@ -36,7 +36,9 @@ public final class JoseConstants {
     public static final String JWE_HEADER_KEY_ENC_ALGORITHM = HEADER_ALGORITHM;
     public static final String JWE_HEADER_CONTENT_ENC_ALGORITHM = "enc";
     public static final String JWE_HEADER_ZIP_ALGORITHM = "zip";
-    public static final String DEFLATE_ZIP_ALGORITHM = "DEF";
+    public static final String JWE_DEFLATE_ZIP_ALGORITHM = "DEF";
+    
+    public static final String JWS_HEADER_B64_STATUS_HEADER = "b64";
     
     public static final String TYPE_JWT = "JWT";
     public static final String TYPE_JOSE = "JOSE";

http://git-wip-us.apache.org/repos/asf/cxf/blob/d57cebc1/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java
index fd111e6..add5408 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java
@@ -172,4 +172,8 @@ public abstract class JoseHeaders extends JsonMapObject {
         return getLongProperty(name);
     }
     
+    public boolean containsHeader(String name) {
+        return containsProperty(name);
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/d57cebc1/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
index 722ae59..89b611d 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
@@ -48,6 +48,7 @@ public class JwsJsonWriterInterceptor extends AbstractJwsJsonWriterProvider
impl
     private JsonMapObjectReaderWriter writer = new JsonMapObjectReaderWriter();
     private boolean contentTypeRequired = true;
     private boolean useJwsOutputStream;
+    private boolean encodePayload = true;
     @Override
     public void aroundWriteTo(WriterInterceptorContext ctx) throws IOException, WebApplicationException
{
         if (ctx.getEntity() == null) {
@@ -71,10 +72,18 @@ 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);
-            Base64UrlOutputStream base64Stream = new Base64UrlOutputStream(jwsStream);
-            ctx.setOutputStream(base64Stream);
+            
+            Base64UrlOutputStream base64Stream = null;
+            if (encodePayload) {
+                base64Stream = new Base64UrlOutputStream(jwsStream);
+                ctx.setOutputStream(base64Stream);
+            } else {
+                ctx.setOutputStream(jwsStream);
+            }
             ctx.proceed();
-            base64Stream.flush();
+            if (encodePayload) {
+                base64Stream.flush();
+            }
             jwsStream.flush();
         } else {
             CachedOutputStream cos = new CachedOutputStream(); 
@@ -96,6 +105,9 @@ public class JwsJsonWriterInterceptor extends AbstractJwsJsonWriterProvider
impl
         JwsHeaders headers = new JwsHeaders();
         headers.setSignatureAlgorithm(signer.getAlgorithm());
         setContentTypeIfNeeded(headers, ctx);
+        if (!encodePayload) {
+            headers.setPayloadEncodingStatus(false);
+        }
         return headers;
     }
     
@@ -118,4 +130,9 @@ public class JwsJsonWriterInterceptor extends AbstractJwsJsonWriterProvider
impl
             }
         }
     }
+
+    public void setEncodePayload(boolean encodePayload) {
+        this.encodePayload = encodePayload;
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/d57cebc1/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweDecryption.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweDecryption.java
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweDecryption.java
index 4be6c48..1af9424 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweDecryption.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweDecryption.java
@@ -61,7 +61,7 @@ public abstract class AbstractJweDecryption implements JweDecryptionProvider
{
         AlgorithmParameterSpec spec = getContentEncryptionCipherSpec(jweDecryptionInput);
         keyProperties.setAlgoSpec(spec);
         boolean compressionSupported = 
-            JoseConstants.DEFLATE_ZIP_ALGORITHM.equals(jweDecryptionInput.getJweHeaders().getZipAlgorithm());
+            JoseConstants.JWE_DEFLATE_ZIP_ALGORITHM.equals(jweDecryptionInput.getJweHeaders().getZipAlgorithm());
         keyProperties.setCompressionSupported(compressionSupported);
         byte[] actualCek = getActualCek(cek, 
                                jweDecryptionInput.getJweHeaders().getContentEncryptionAlgorithm().getJwaName());

http://git-wip-us.apache.org/repos/asf/cxf/blob/d57cebc1/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
index 3edaeee..07e60c4 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
@@ -226,7 +226,7 @@ public abstract class AbstractJweEncryption implements JweEncryptionProvider
{
         return state;
     }
     private boolean compressionRequired(JweHeaders theHeaders) {
-        return JoseConstants.DEFLATE_ZIP_ALGORITHM.equals(theHeaders.getZipAlgorithm());
+        return JoseConstants.JWE_DEFLATE_ZIP_ALGORITHM.equals(theHeaders.getZipAlgorithm());
     }
     protected KeyEncryptionProvider getKeyEncryptionAlgo() {
         return keyEncryptionAlgo;

http://git-wip-us.apache.org/repos/asf/cxf/blob/d57cebc1/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweHeaders.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweHeaders.java
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweHeaders.java
index e276ce2..be28f1c 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweHeaders.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweHeaders.java
@@ -65,7 +65,7 @@ public class JweHeaders extends JoseHeaders {
         }
         setContentEncryptionAlgorithm(ctEncAlgo);
         if (deflate) {
-            setZipAlgorithm(JoseConstants.DEFLATE_ZIP_ALGORITHM);
+            setZipAlgorithm(JoseConstants.JWE_DEFLATE_ZIP_ALGORITHM);
         }
     }
     

http://git-wip-us.apache.org/repos/asf/cxf/blob/d57cebc1/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsHeaders.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsHeaders.java
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsHeaders.java
index 6d80513..c883a9c 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsHeaders.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsHeaders.java
@@ -20,6 +20,7 @@ package org.apache.cxf.rs.security.jose.jws;
 
 import java.util.Map;
 
+import org.apache.cxf.rs.security.jose.JoseConstants;
 import org.apache.cxf.rs.security.jose.JoseHeaders;
 import org.apache.cxf.rs.security.jose.JoseType;
 import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
@@ -57,9 +58,9 @@ public class JwsHeaders extends JoseHeaders {
         return algo == null ? null : SignatureAlgorithm.getAlgorithm(algo);
     }
     public void setPayloadEncodingStatus(Boolean status) {
-        super.setProperty("b64", status);
+        super.setProperty(JoseConstants.JWS_HEADER_B64_STATUS_HEADER, status);
     }
     public Boolean getPayloadEncodingStatus() {
-        return super.getBooleanProperty("b64");
+        return super.getBooleanProperty(JoseConstants.JWS_HEADER_B64_STATUS_HEADER);
     }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/d57cebc1/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumer.java
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumer.java
index bf15ace..d1ca673 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumer.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumer.java
@@ -39,9 +39,9 @@ import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
 public class JwsJsonConsumer {
     protected static final Logger LOG = LogUtils.getL7dLogger(JwsJsonConsumer.class);
     private String jwsSignedDocument;
-    private String encodedJwsPayload;
-    private List<JwsJsonSignatureEntry> signatureEntries = new LinkedList<JwsJsonSignatureEntry>();
-    
+    private String jwsPayload;
+    private List<JwsJsonSignatureEntry> signatures = new LinkedList<JwsJsonSignatureEntry>();
+    private boolean detached;
     /**
      * @param jwsSignedDocument
      *            signed JWS Document
@@ -49,28 +49,28 @@ public class JwsJsonConsumer {
     public JwsJsonConsumer(String jwsSignedDocument) {
         this(jwsSignedDocument, null);
     }
-    public JwsJsonConsumer(String jwsSignedDocument, String encodedDetachedPayload) {
+    public JwsJsonConsumer(String jwsSignedDocument, String detachedPayload) {
         this.jwsSignedDocument = jwsSignedDocument;
-        prepare(encodedDetachedPayload);
+        prepare(detachedPayload);
     }
 
-    private void prepare(String encodedDetachedPayload) {
+    private void prepare(String detachedPayload) {
         JsonMapObject jsonObject = new JsonMapObject();
         new JsonMapObjectReaderWriter().fromJson(jsonObject, jwsSignedDocument);
         
         Map<String, Object> jsonObjectMap = jsonObject.asMap(); 
-        encodedJwsPayload = (String)jsonObjectMap.get("payload");
-        if (encodedJwsPayload == null) {
-            encodedJwsPayload = encodedDetachedPayload;
-        } else if (encodedDetachedPayload != null) {
+        jwsPayload = (String)jsonObjectMap.get("payload");
+        if (jwsPayload == null) {
+            jwsPayload = detachedPayload;
+        } else if (detachedPayload != null) {
             LOG.warning("JSON JWS includes a payload expected to be detached");
             throw new JwsException(JwsException.Error.INVALID_JSON_JWS);
         }
-        if (encodedJwsPayload == null) {
+        if (jwsPayload == null) {
             LOG.warning("JSON JWS has no payload");
             throw new JwsException(JwsException.Error.INVALID_JSON_JWS);
         }
-        
+        detached = detachedPayload != null;
         List<Map<String, Object>> signatureArray = CastUtils.cast((List<?>)jsonObjectMap.get("signatures"));
         if (signatureArray != null) {
             if (jsonObjectMap.containsKey("signature")) {
@@ -78,22 +78,33 @@ public class JwsJsonConsumer {
                 throw new JwsException(JwsException.Error.INVALID_JSON_JWS);
             }
             for (Map<String, Object> signatureEntry : signatureArray) {
-                this.signatureEntries.add(getSignatureObject(signatureEntry));
+                this.signatures.add(getSignatureObject(signatureEntry));
             }
         } else {
-            this.signatureEntries.add(getSignatureObject(jsonObjectMap));
+            this.signatures.add(getSignatureObject(jsonObjectMap));
         }
-        if (signatureEntries.isEmpty()) {
+        if (signatures.isEmpty()) {
             LOG.warning("JSON JWS has no signatures");
             throw new JwsException(JwsException.Error.INVALID_JSON_JWS);
         }
+        validateB64Status();
+        
+        
+    }
+    private Boolean validateB64Status() {
+        if (!detached) {
+            return JwsJsonProducer.validateb64Status(signatures);    
+        } else {
+            return Boolean.TRUE;
+        }
+        
     }
     protected JwsJsonSignatureEntry getSignatureObject(Map<String, Object> signatureEntry)
{
         String protectedHeader = (String)signatureEntry.get("protected");
         Map<String, Object> header = CastUtils.cast((Map<?, ?>)signatureEntry.get("header"));
         String signature = (String)signatureEntry.get("signature");
         return 
-            new JwsJsonSignatureEntry(encodedJwsPayload, 
+            new JwsJsonSignatureEntry(jwsPayload, 
                                       protectedHeader, 
                                       signature, 
                                       header != null ? new JwsHeaders(header) : null);
@@ -101,20 +112,24 @@ public class JwsJsonConsumer {
     public String getSignedDocument() {
         return this.jwsSignedDocument;
     }
-    public String getEncodedJwsPayload() {
-        return this.encodedJwsPayload;
+    public String getJwsPayload() {
+        return this.jwsPayload;
     }
     public String getDecodedJwsPayload() {
-        return JoseUtils.decodeToString(encodedJwsPayload);
+        if (validateB64Status()) {
+            return JoseUtils.decodeToString(jwsPayload);
+        } else {
+            return jwsPayload;
+        }
     }
     public byte[] getDecodedJwsPayloadBytes() {
         return StringUtils.toBytesUTF8(getDecodedJwsPayload());
     }
     public List<JwsJsonSignatureEntry> getSignatureEntries() {
-        return Collections.unmodifiableList(signatureEntries);
+        return Collections.unmodifiableList(signatures);
     }
     public MultivaluedMap<SignatureAlgorithm, JwsJsonSignatureEntry> getSignatureEntryMap()
{
-        return JwsUtils.getJwsJsonSignatureMap(signatureEntries);
+        return JwsUtils.getJwsJsonSignatureMap(signatures);
     }
     public boolean verifySignatureWith(JwsSignatureVerifier validator) {
         List<JwsJsonSignatureEntry> theSignatureEntries = 
@@ -161,7 +176,7 @@ public class JwsJsonConsumer {
             }
         }
         List<JwsJsonSignatureEntry> nonValidatedSignatures = new LinkedList<JwsJsonSignatureEntry>();
-        for (JwsJsonSignatureEntry sigEntry : signatureEntries) {
+        for (JwsJsonSignatureEntry sigEntry : signatures) {
             if (!validatedSignatures.contains(sigEntry)) {        
                 nonValidatedSignatures.add(sigEntry);
             }
@@ -177,7 +192,7 @@ public class JwsJsonConsumer {
     }
     public JwsJsonProducer toProducer() {
         JwsJsonProducer p = new JwsJsonProducer(getDecodedJwsPayload());
-        p.getSignatureEntries().addAll(signatureEntries);
+        p.getSignatureEntries().addAll(signatures);
         return p;
     }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/d57cebc1/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonProducer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonProducer.java
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonProducer.java
index 4d2a827..554f340 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonProducer.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonProducer.java
@@ -20,8 +20,10 @@ package org.apache.cxf.rs.security.jose.jws;
 
 import java.security.PrivateKey;
 import java.util.Collections;
+import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Set;
 import java.util.logging.Logger;
 
 import javax.ws.rs.core.MultivaluedMap;
@@ -47,13 +49,15 @@ public class JwsJsonProducer {
     public JwsJsonProducer(String tbsDocument, boolean supportFlattened) {
         this.supportFlattened = supportFlattened;
         this.plainPayload = tbsDocument;
-        this.encodedPayload = Base64UrlUtility.encode(tbsDocument);
     }
     
     public String getPlainPayload() {
         return plainPayload;
     }
     public String getUnsignedEncodedPayload() {
+        if (encodedPayload == null) { 
+            encodedPayload = Base64UrlUtility.encode(getPlainPayload());
+        }
         return encodedPayload;
     }
     public String getJwsJsonSignedDocument() {
@@ -61,13 +65,12 @@ public class JwsJsonProducer {
     }
     public String getJwsJsonSignedDocument(boolean detached) {
         if (signatures.isEmpty()) { 
-            LOG.warning("Signature is not available");
-            throw new JwsException(JwsException.Error.INVALID_JSON_JWS);
+            return null;
         }
         StringBuilder sb = new StringBuilder();
         sb.append("{");
         if (!detached) {
-            sb.append("\"payload\":\"" + encodedPayload + "\"");
+            sb.append("\"payload\":\"" + getActualPayload() + "\"");
             sb.append(",");
         }
         if (!supportFlattened || signatures.size() > 1) {
@@ -86,6 +89,9 @@ public class JwsJsonProducer {
         sb.append("}");
         return sb.toString();
     }
+    private String getActualPayload() {
+        return getActualPayload(validateb64Status(signatures));
+    }
     public List<JwsJsonSignatureEntry> getSignatureEntries() {
         return signatures;
     }
@@ -126,7 +132,9 @@ public class JwsJsonProducer {
             unionHeaders.asMap().putAll(protectedHeader.asMap());
         }
         if (unprotectedHeader != null) {
-            checkCriticalHeaders(unprotectedHeader);
+            checkUnprotectedHeaders(unprotectedHeader, 
+                                    JoseConstants.HEADER_CRITICAL,
+                                    JoseConstants.JWS_HEADER_B64_STATUS_HEADER);
             if (!Collections.disjoint(unionHeaders.asMap().keySet(), 
                                      unprotectedHeader.asMap().keySet())) {
                 LOG.warning("Protected and unprotected headers have duplicate values");
@@ -139,9 +147,12 @@ public class JwsJsonProducer {
             throw new JwsException(JwsException.Error.INVALID_JSON_JWS);
         }
         String sequenceToBeSigned;
+        String actualPayload = protectedHeader != null 
+            ? getActualPayload(protectedHeader.getPayloadEncodingStatus()) 
+            : getUnsignedEncodedPayload();
         if (protectedHeader != null) {
             sequenceToBeSigned = Base64UrlUtility.encode(writer.toJson(protectedHeader))
-                    + "." + getUnsignedEncodedPayload();
+                    + "." + actualPayload;
         } else {
             sequenceToBeSigned = "." + getUnsignedEncodedPayload();
         }
@@ -152,26 +163,49 @@ public class JwsJsonProducer {
         String encodedSignatureBytes = Base64UrlUtility.encode(signatureBytes);
         JwsJsonSignatureEntry signature;
         if (protectedHeader != null) {
-            signature = new JwsJsonSignatureEntry(encodedPayload,
+            signature = new JwsJsonSignatureEntry(actualPayload,
                     Base64UrlUtility.encode(writer.toJson(protectedHeader)),
                     encodedSignatureBytes,
                     unprotectedHeader);
         } else {
-            signature = new JwsJsonSignatureEntry(encodedPayload,
+            signature = new JwsJsonSignatureEntry(getUnsignedEncodedPayload(),
                     null,
                     encodedSignatureBytes,
                     unprotectedHeader);
         }
         return updateJwsJsonSignedDocument(signature);
     }
+    private String getActualPayload(Boolean payloadEncodingStatus) {
+        return Boolean.FALSE == payloadEncodingStatus 
+            ? getPlainPayload() : this.getUnsignedEncodedPayload();
+    }
     private String updateJwsJsonSignedDocument(JwsJsonSignatureEntry signature) {
         signatures.add(signature);
         return getJwsJsonSignedDocument();
     }
-    private static void checkCriticalHeaders(JoseHeaders unprotected) {
-        if (unprotected.asMap().containsKey(JoseConstants.HEADER_CRITICAL)) {
-            LOG.warning("Unprotected headers contain critical headers");
+    private static void checkUnprotectedHeaders(JoseHeaders unprotected, String... headerNames)
{
+        for (String headerName : headerNames) {
+            if (unprotected.containsHeader(headerName)) {
+                LOG.warning("Unprotected headers contain a header \"" 
+                    + headerName + "\" which must be protected");
+                throw new JwsException(JwsException.Error.INVALID_JSON_JWS);
+            }
+        }
+    }
+    static Boolean validateb64Status(List<JwsJsonSignatureEntry> signatures) {
+        Set<Boolean> b64Set = new LinkedHashSet<Boolean>();
+        for (JwsJsonSignatureEntry entry : signatures) {
+            JwsHeaders headers = entry.getProtectedHeader();
+            Boolean status = headers != null ? headers.getPayloadEncodingStatus() : null;
+            if (status == null) {
+                status = Boolean.TRUE;
+            }
+            b64Set.add(status);
+        }
+        if (b64Set.size() > 1) {
+            LOG.warning("Each signature entry can sign only encoded or only unencoded payload");
             throw new JwsException(JwsException.Error.INVALID_JSON_JWS);
         }
+        return b64Set.iterator().next();
     }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/d57cebc1/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonSignatureEntry.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonSignatureEntry.java
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonSignatureEntry.java
index 054c3d3..4a2de5f 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonSignatureEntry.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonSignatureEntry.java
@@ -26,14 +26,13 @@ import org.apache.cxf.common.util.Base64UrlUtility;
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.jaxrs.provider.json.JsonMapObjectReaderWriter;
 import org.apache.cxf.rs.security.jose.JoseConstants;
-import org.apache.cxf.rs.security.jose.JoseHeaders;
 import org.apache.cxf.rs.security.jose.JoseUtils;
 import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
 
 
 public class JwsJsonSignatureEntry {
     protected static final Logger LOG = LogUtils.getL7dLogger(JwsJsonSignatureEntry.class);
-    private String encodedJwsPayload;
+    private String jwsPayload;
     private String encodedProtectedHeader;
     private String encodedSignature;
     private JwsHeaders protectedHeader;
@@ -41,7 +40,7 @@ public class JwsJsonSignatureEntry {
     private JwsHeaders unionHeaders;
     private JsonMapObjectReaderWriter writer = new JsonMapObjectReaderWriter();
       
-    public JwsJsonSignatureEntry(String encodedJwsPayload,
+    public JwsJsonSignatureEntry(String jwsPayload,
                                  String encodedProtectedHeader,
                                  String encodedSignature,
                                  JwsHeaders unprotectedHeader) {
@@ -50,7 +49,7 @@ public class JwsJsonSignatureEntry {
             throw new JwsException(JwsException.Error.INVALID_JSON_JWS);
         }
         
-        this.encodedJwsPayload = encodedJwsPayload;
+        this.jwsPayload = jwsPayload;
         this.encodedProtectedHeader = encodedProtectedHeader;
         this.encodedSignature = encodedSignature;
         this.unprotectedHeader = unprotectedHeader;
@@ -74,11 +73,16 @@ public class JwsJsonSignatureEntry {
             unionHeaders.asMap().putAll(unprotectedHeader.asMap());
         }
     }
-    public String getEncodedJwsPayload() {
-        return encodedJwsPayload;
+    public String getJwsPayload() {
+        return jwsPayload;
     }
     public String getDecodedJwsPayload() {
-        return JoseUtils.decodeToString(encodedJwsPayload);
+        if (protectedHeader == null 
+            || protectedHeader.getPayloadEncodingStatus() != Boolean.FALSE) {
+            return JoseUtils.decodeToString(jwsPayload);
+        } else {
+            return jwsPayload;
+        }
     }
     public byte[] getDecodedJwsPayloadBytes() {
         return StringUtils.toBytesUTF8(getDecodedJwsPayload());
@@ -86,10 +90,10 @@ public class JwsJsonSignatureEntry {
     public String getEncodedProtectedHeader() {
         return encodedProtectedHeader;
     }
-    public JoseHeaders getProtectedHeader() {
+    public JwsHeaders getProtectedHeader() {
         return protectedHeader;
     }
-    public JoseHeaders getUnprotectedHeader() {
+    public JwsHeaders getUnprotectedHeader() {
         return unprotectedHeader;
     }
     public JwsHeaders getUnionHeader() {
@@ -101,11 +105,11 @@ public class JwsJsonSignatureEntry {
     public byte[] getDecodedSignature() {
         return JoseUtils.decode(getEncodedSignature());
     }
-    public String getUnsignedEncodedSequence() {
+    public String getUnsignedSequence() {
         if (getEncodedProtectedHeader() != null) {
-            return getEncodedProtectedHeader() + "." + getEncodedJwsPayload();
+            return getEncodedProtectedHeader() + "." + getJwsPayload();
         } else {
-            return "." + getEncodedJwsPayload();
+            return "." + getJwsPayload();
         }
     }
     public String getKeyId() {
@@ -114,7 +118,7 @@ public class JwsJsonSignatureEntry {
     public boolean verifySignatureWith(JwsSignatureVerifier validator) {
         try {
             if (validator.verify(getUnionHeader(),
-                                 getUnsignedEncodedSequence(),
+                                 getUnsignedSequence(),
                                  getDecodedSignature())) {
                 return true;
             }

http://git-wip-us.apache.org/repos/asf/cxf/blob/d57cebc1/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsCompactReaderWriterTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsCompactReaderWriterTest.java
b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsCompactReaderWriterTest.java
index 49bacd9..0759c61 100644
--- a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsCompactReaderWriterTest.java
+++ b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsCompactReaderWriterTest.java
@@ -42,10 +42,15 @@ import org.apache.cxf.rt.security.crypto.CryptoUtils;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 
 import org.junit.Assert;
+import org.junit.Ignore;
 import org.junit.Test;
 
 public class JwsCompactReaderWriterTest extends Assert {
     
+    public static final String TOKEN_WITH_DETACHED_UNENCODED_PAYLOAD =
+        "eyJhbGciOiJIUzI1NiJ9..GsyM6AQJbQHY8aQKCbZSPJHzMRWo3HKIlcDuXof7nqs";
+    public static final String UNSIGNED_PLAIN_DOCUMENT = "$.02";
+    
     public static final String ENCODED_TOKEN_SIGNED_BY_MAC = 
         "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9"
         + ".eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ"
@@ -103,9 +108,14 @@ public class JwsCompactReaderWriterTest extends Assert {
         jws.signWith(new HmacJwsSignatureProvider(ENCODED_MAC_KEY, SignatureAlgorithm.HS256));
         
         assertEquals(ENCODED_TOKEN_SIGNED_BY_MAC, jws.getSignedEncodedJws());
-        
     }
-    
+    @Test
+    @Ignore
+    public void testWriteReadJwsUnencodedPayload() throws Exception {
+        JwsHeaders headers = new JwsHeaders(SignatureAlgorithm.HS256);
+        headers.setPayloadEncodingStatus(false);
+        //JwsCompactProducer producer = new JwsCompactProducer(UNSIGNED_PLAIN_DOCUMENT);
+    }
     @Test
     public void testWriteReadJwsUnsigned() throws Exception {
         JwsHeaders headers = new JwsHeaders(JoseType.JWT);

http://git-wip-us.apache.org/repos/asf/cxf/blob/d57cebc1/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumerTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumerTest.java
b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumerTest.java
index ce611e2..0faed8b 100644
--- a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumerTest.java
+++ b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumerTest.java
@@ -21,6 +21,7 @@ package org.apache.cxf.rs.security.jose.jws;
 import java.io.InputStream;
 import java.util.List;
 
+import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
 import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
 import org.apache.cxf.rs.security.jose.jwk.JsonWebKeys;
 import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
@@ -52,6 +53,16 @@ public class JwsJsonConsumerTest extends Assert {
     private static final String KID_OF_THE_SECOND_SIGNER = "e9bc097a-ce51-4036-9562-d2ade882db0d";
     
     @Test
+    public void testVerifySignedWithProtectedHeaderOnlyUnencodedPayload() {
+        JwsJsonConsumer consumer = 
+            new JwsJsonConsumer(JwsJsonProducerTest.SIGNED_JWS_JSON_FLAT_UNENCODED_DOCUMENT);
+        assertEquals(JwsJsonProducerTest.UNSIGNED_PLAIN_DOCUMENT, consumer.getJwsPayload());
+        assertEquals(JwsJsonProducerTest.UNSIGNED_PLAIN_DOCUMENT, consumer.getDecodedJwsPayload());
+        assertTrue(consumer.verifySignatureWith(
+            new HmacJwsSignatureVerifier(JwsJsonProducerTest.ENCODED_MAC_KEY_1, SignatureAlgorithm.HS256)));
+    }
+    
+    @Test
     public void testVerifyDualSignedDocument() throws Exception {
         JwsJsonConsumer consumer = new JwsJsonConsumer(DUAL_SIGNED_DOCUMENT); 
         JsonWebKeys jwks = readKeySet("jwkPublicJsonConsumerSet.txt");

http://git-wip-us.apache.org/repos/asf/cxf/blob/d57cebc1/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsJsonProducerTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsJsonProducerTest.java
b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsJsonProducerTest.java
index f3a24c8..5895dcb 100644
--- a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsJsonProducerTest.java
+++ b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsJsonProducerTest.java
@@ -20,7 +20,6 @@ package org.apache.cxf.rs.security.jose.jws;
 import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
 
 import org.junit.Assert;
-import org.junit.Ignore;
 import org.junit.Test;
 
 public class JwsJsonProducerTest extends Assert {
@@ -53,7 +52,7 @@ public class JwsJsonProducerTest extends Assert {
         + "\",\"protected\":\"eyJhbGciOiJIUzI1NiJ9\",\"signature\":"
         + "\"NNksREOsFCI1nUQEqzCe6XZFa-bRAge2XXMMAU2Jj2I\"}";
        
-    public static final String SIGNED_JWS_JSON_FLAT_DOCUMENT_2 = "{"
+    public static final String SIGNED_JWS_JSON_FLAT_UNENCODED_DOCUMENT = "{"
         + "\"payload\":\"" + UNSIGNED_PLAIN_DOCUMENT + "\","
         + "\"protected\":\"eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2V9\","
         + "\"signature\":" + "\"GsyM6AQJbQHY8aQKCbZSPJHzMRWo3HKIlcDuXof7nqs\"}";
@@ -87,7 +86,6 @@ public class JwsJsonProducerTest extends Assert {
                      producer.getJwsJsonSignedDocument());
     }
     @Test
-    @Ignore
     public void testSignWithProtectedHeaderOnlyUnencodedPayload() {
         JwsJsonProducer producer = new JwsJsonProducer(UNSIGNED_PLAIN_DOCUMENT, true);
         JwsHeaders headers = new JwsHeaders();
@@ -97,7 +95,7 @@ public class JwsJsonProducerTest extends Assert {
                
         producer.signWith(new HmacJwsSignatureProvider(ENCODED_MAC_KEY_1, SignatureAlgorithm.HS256),
                           headers);
-        assertEquals(SIGNED_JWS_JSON_FLAT_DOCUMENT_2,
+        assertEquals(SIGNED_JWS_JSON_FLAT_UNENCODED_DOCUMENT,
                      producer.getJwsJsonSignedDocument());
     }
     @Test


Mime
View raw message