cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject cxf git commit: Changes to JwsJson to support flattened and detached mode for Daniel's work
Date Thu, 15 Jan 2015 22:45:03 GMT
Repository: cxf
Updated Branches:
  refs/heads/master bdcc48de5 -> 85ebf3f70


Changes to JwsJson to support flattened and detached mode for Daniel's work


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

Branch: refs/heads/master
Commit: 85ebf3f701d6c2127c7ec761638cafc6c086fc1c
Parents: bdcc48d
Author: Sergey Beryozkin <sberyozkin@talend.com>
Authored: Thu Jan 15 22:44:44 2015 +0000
Committer: Sergey Beryozkin <sberyozkin@talend.com>
Committed: Thu Jan 15 22:44:44 2015 +0000

----------------------------------------------------------------------
 .../rs/security/jose/jws/JwsJsonConsumer.java   | 55 +++++++++++++-------
 .../rs/security/jose/jws/JwsJsonProducer.java   | 51 +++++++++++-------
 .../jose/jws/JwsJsonSignatureEntry.java         | 11 +++-
 .../security/jose/jws/JwsJsonProducerTest.java  | 18 +++++++
 4 files changed, 94 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/85ebf3f7/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 90fe02a..c1690d8 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
@@ -19,7 +19,6 @@
 package org.apache.cxf.rs.security.jose.jws;
 
 import java.security.interfaces.RSAPublicKey;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
@@ -38,44 +37,58 @@ public class JwsJsonConsumer {
 
     private String jwsSignedDocument;
     private String encodedJwsPayload;
-    private List<JwsJsonSignatureEntry> signatureEntries;
+    private List<JwsJsonSignatureEntry> signatureEntries = new LinkedList<JwsJsonSignatureEntry>();
     
     /**
      * @param jwsSignedDocument
      *            signed JWS Document
      */
     public JwsJsonConsumer(String jwsSignedDocument) {
+        this(jwsSignedDocument, null);
+    }
+    public JwsJsonConsumer(String jwsSignedDocument, String encodedDetachedPayload) {
         this.jwsSignedDocument = jwsSignedDocument;
-        prepare();
+        prepare(encodedDetachedPayload);
     }
 
-    private void prepare() {
+    private void prepare(String encodedDetachedPayload) {
         JsonMapObject jsonObject = new JsonMapObject();
         new JsonMapObjectReaderWriter().fromJson(jsonObject, jwsSignedDocument);
-        encodedJwsPayload = (String)jsonObject.asMap().get("payload");
+        
+        Map<String, Object> jsonObjectMap = jsonObject.asMap(); 
+        encodedJwsPayload = (String)jsonObjectMap.get("payload");
+        if (encodedJwsPayload == null) {
+            encodedJwsPayload = encodedDetachedPayload;
+        }
         if (encodedJwsPayload == null) {
             throw new SecurityException("Invalid JWS JSON sequence: no payload is available");
         }
         
-        List<Map<String, Object>> signatureArray = CastUtils.cast((List<?>)jsonObject.asMap().get("signatures"));
-        
-        this.signatureEntries = new ArrayList<JwsJsonSignatureEntry>(signatureArray.size());
-        
-        for (Map<String, Object> signatureEntry : signatureArray) {
-            String protectedHeader = (String)signatureEntry.get("protected");
-            Map<String, Object> header = CastUtils.cast((Map<?, ?>)signatureEntry.get("header"));
-            String signature = (String)signatureEntry.get("signature");
-            JwsJsonSignatureEntry signatureObject = 
-                new JwsJsonSignatureEntry(encodedJwsPayload, 
-                                          protectedHeader, 
-                                          signature, 
-                                          header != null ? new JwsJsonUnprotectedHeader(header)
: null);
-            this.signatureEntries.add(signatureObject);
+        List<Map<String, Object>> signatureArray = CastUtils.cast((List<?>)jsonObjectMap.get("signatures"));
+        if (signatureArray != null) {
+            if (jsonObjectMap.containsKey("signature")) {
+                throw new SecurityException("Invalid JWS JSON sequence");
+            }
+            for (Map<String, Object> signatureEntry : signatureArray) {
+                this.signatureEntries.add(getSignatureObject(signatureEntry));
+            }
+        } else {
+            this.signatureEntries.add(getSignatureObject(jsonObjectMap));
         }
         if (signatureEntries.isEmpty()) {
             throw new SecurityException("Invalid JWS JSON sequence: no signatures are available");
         }
     }
+    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, 
+                                      protectedHeader, 
+                                      signature, 
+                                      header != null ? new JwsJsonUnprotectedHeader(header)
: null);
+    }
     public String getSignedDocument() {
         return this.jwsSignedDocument;
     }
@@ -159,6 +172,8 @@ public class JwsJsonConsumer {
         return verifySignatureWith(JwsUtils.getSignatureVerifier(key));
     }
     public JwsJsonProducer toProducer() {
-        return new JwsJsonProducer(getDecodedJwsPayload(), signatureEntries);
+        JwsJsonProducer p = new JwsJsonProducer(getDecodedJwsPayload());
+        p.getSignatureEntries().addAll(signatureEntries);
+        return p;
     }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/85ebf3f7/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 c9c2387..2d11072 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
@@ -30,37 +30,58 @@ import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.rs.security.jose.JoseHeaders;
 import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
 public class JwsJsonProducer {
+    private boolean supportFlattened;
     private String plainPayload;
     private String encodedPayload;
-    private StringBuilder jwsJsonSignedDocBuilder = new StringBuilder();
     private List<JwsJsonSignatureEntry> signatures = new LinkedList<JwsJsonSignatureEntry>();
     public JwsJsonProducer(String tbsDocument) {
+        this(tbsDocument, false);
+    }
+    public JwsJsonProducer(String tbsDocument, boolean supportFlattened) {
+        this.supportFlattened = supportFlattened;
         this.plainPayload = tbsDocument;
         this.encodedPayload = Base64UrlUtility.encode(tbsDocument);
     }
-    public JwsJsonProducer(String tbsDocument, List<JwsJsonSignatureEntry> signatures)
{
-        this(tbsDocument);
-        for (JwsJsonSignatureEntry entry : signatures) {
-            updateJwsJsonSignedDocument(entry);
-        }
-    }
-
+    
     public String getPlainPayload() {
         return plainPayload;
     }
     public String getUnsignedEncodedPayload() {
         return encodedPayload;
     }
-
     public String getJwsJsonSignedDocument() {
+        return getJwsJsonSignedDocument(false);
+    }
+    public String getJwsJsonSignedDocument(boolean detached) {
         if (signatures.isEmpty()) { 
             throw new SecurityException("Signature is not available");
         }
-        return jwsJsonSignedDocBuilder.toString() + "]}";
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        if (!detached) {
+            sb.append("\"payload\":\"" + encodedPayload + "\"");
+            sb.append(",");
+        }
+        if (!supportFlattened || signatures.size() > 1) {
+            sb.append("\"signatures\":[");
+            for (int i = 0; i < signatures.size(); i++) {
+                JwsJsonSignatureEntry signature = signatures.get(i);
+                if (i > 0) {
+                    sb.append(",");
+                }
+                sb.append(signature.toJson());
+            }
+            sb.append("]");
+        } else {
+            sb.append(signatures.get(0).toJson(true));
+        }
+        sb.append("}");
+        return sb.toString();
     }
     public List<JwsJsonSignatureEntry> getSignatureEntries() {
-        return Collections.unmodifiableList(signatures);
+        return signatures;
     }
+    
     public MultivaluedMap<String, JwsJsonSignatureEntry> getSignatureEntryMap() {
         return JwsUtils.getJwsJsonSignatureMap(signatures);
     }
@@ -122,15 +143,7 @@ public class JwsJsonProducer {
     }
     
     private String updateJwsJsonSignedDocument(JwsJsonSignatureEntry signature) {
-        if (signatures.isEmpty()) {
-            jwsJsonSignedDocBuilder.append("{\"payload\":\"" + encodedPayload + "\"");
-            jwsJsonSignedDocBuilder.append(",\"signatures\":[");
-        } else {
-            jwsJsonSignedDocBuilder.append(",");    
-        }
-        jwsJsonSignedDocBuilder.append(signature.toJson());
         signatures.add(signature);
-        
         return getJwsJsonSignedDocument();
     }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/85ebf3f7/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 1e75ff9..279ea31 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
@@ -119,8 +119,13 @@ public class JwsJsonSignatureEntry {
         return JwsUtils.validateCriticalHeaders(getUnionHeader());
     }
     public String toJson() {
+        return toJson(false);
+    }
+    public String toJson(boolean flattenedMode) {
         StringBuilder sb = new StringBuilder();
-        sb.append("{");
+        if (!flattenedMode) {
+            sb.append("{");
+        }
         if (protectedHeader != null) {
             sb.append("\"protected\":\"" + protectedHeader.getEncodedHeaderEntries() + "\"");
         }
@@ -132,7 +137,9 @@ public class JwsJsonSignatureEntry {
         }
         sb.append(",");
         sb.append("\"signature\":\"" + encodedSignature + "\"");
-        sb.append("}");
+        if (!flattenedMode) {
+            sb.append("}");
+        }
         return sb.toString();
     }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/85ebf3f7/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 d6a5fd0..3b5b492 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
@@ -44,6 +44,12 @@ public class JwsJsonProducerTest extends Assert {
                        + UNSIGNED_PLAIN_JSON_DOCUMENT_AS_B64URL
                        + "\",\"signatures\":[{\"protected\":\"eyJhbGciOiJIUzI1NiJ9\",\"signature\":"
                        + "\"NNksREOsFCI1nUQEqzCe6XZFa-bRAge2XXMMAU2Jj2I\"}]}";
+    
+    public static final String SIGNED_JWS_JSON_FLAT_DOCUMENT = "{"
+        + "\"payload\":\""
+        + UNSIGNED_PLAIN_JSON_DOCUMENT_AS_B64URL
+        + "\",\"protected\":\"eyJhbGciOiJIUzI1NiJ9\",\"signature\":"
+        + "\"NNksREOsFCI1nUQEqzCe6XZFa-bRAge2XXMMAU2Jj2I\"}";
        
     public static final String DUAL_SIGNED_JWS_JSON_DOCUMENT = "{"
                        + "\"payload\":\""
@@ -75,6 +81,18 @@ public class JwsJsonProducerTest extends Assert {
                      producer.getJwsJsonSignedDocument());
     }
     @Test
+    public void testSignWithProtectedHeaderOnlyFlat() {
+        JwsJsonProducer producer = new JwsJsonProducer(UNSIGNED_PLAIN_JSON_DOCUMENT, true);
+        JoseHeaders headerEntries = new JoseHeaders();
+        headerEntries.setAlgorithm(JoseConstants.HMAC_SHA_256_ALGO);
+               
+        producer.signWith(new HmacJwsSignatureProvider(ENCODED_MAC_KEY_1,
+                          JoseConstants.HMAC_SHA_256_ALGO),
+                          new JwsJsonProtectedHeader(headerEntries));
+        assertEquals(SIGNED_JWS_JSON_FLAT_DOCUMENT,
+                     producer.getJwsJsonSignedDocument());
+    }
+    @Test
     public void testDualSignWithProtectedHeaderOnly() {
         JwsJsonProducer producer = new JwsJsonProducer(UNSIGNED_PLAIN_JSON_DOCUMENT);
         JoseHeaders headerEntries = new JoseHeaders();


Mime
View raw message