Repository: camel
Updated Branches:
  refs/heads/master a342ef7df -> afd273710


CAMEL-9306: XML Signature: Header for Transform Methods

Change-Id: I0a313c24841dd806f1a13f9daec1cf85f9142a4e


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

Branch: refs/heads/master
Commit: afd273710f5487162b83f72ef071cf1716858373
Parents: a342ef7
Author: Franz Forsthofer <franz.forstho...@sap.com>
Authored: Tue Nov 10 13:39:12 2015 +0100
Committer: Franz Forsthofer <franz.forstho...@sap.com>
Committed: Tue Nov 10 13:43:28 2015 +0100

----------------------------------------------------------------------
 .../xmlsecurity/api/XmlSignatureConstants.java  | 14 +++++
 .../processor/XmlSignerProcessor.java           | 60 ++++++++++++--------
 .../component/xmlsecurity/XmlSignatureTest.java | 22 ++++++-
 3 files changed, 72 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/afd27371/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureConstants.java
----------------------------------------------------------------------
diff --git 
a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureConstants.java
 
b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureConstants.java
index 5fecbcf..1b65c2d 100644
--- 
a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureConstants.java
+++ 
b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/api/XmlSignatureConstants.java
@@ -61,6 +61,20 @@ public final class XmlSignatureConstants {
     public static final String HEADER_SCHEMA_RESOURCE_URI = 
"CamelXmlSignatureSchemaResourceUri";
     
     public static final String HEADER_XPATHS_TO_ID_ATTRIBUTES = 
"CamelXmlSignatureXpathsToIdAttributes";
+    
+    /**
+     * Header for dynamic specifying the transform methods of the reference to 
the
+     * signed data. The value of the header must be a comma separated list with
+     * the transform algorithms, for example:
+     * 
"http://www.w3.org/2000/09/xmldsig#enveloped-signature,http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
+     * <p>
+     * Used for the XML signer. This header will overwrite the configuration
+     * property "transformMethods". You cannot use transform algorithms, which
+     * need parameters like http://www.w3.org/TR/1999/REC-xslt-19991116,
+     * http://www.w3.org/2002/06/xmldsig-filter2, or
+     * http://www.w3.org/TR/1999/REC-xpath-19991116.
+     */
+    public static final String HEADER_TRANSFORM_METHODS = 
"CamelXmlSignatureTransformMethods";
 
     /*------------------------- headers for XAdES signer 
----------------------------------------------------------*/
     /**

http://git-wip-us.apache.org/repos/asf/camel/blob/afd27371/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerProcessor.java
----------------------------------------------------------------------
diff --git 
a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerProcessor.java
 
b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerProcessor.java
index 0122b45..8a7f567 100644
--- 
a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerProcessor.java
+++ 
b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/processor/XmlSignerProcessor.java
@@ -569,7 +569,7 @@ public class XmlSignerProcessor extends 
XmlSignatureProcessor {
         String referenceId = properties == null ? null : 
properties.getContentReferenceId();
         // Create Reference with URI="#<objectId>" for enveloping signature, 
URI="" for enveloped signature, and URI = <value from configuration> for 
detached signature and the transforms
         Reference ref = createReference(input.getSignatureFactory(), 
input.getContentReferenceUri(),
-                getContentReferenceType(input.getMessage()), 
input.getSignatureType(), referenceId);
+                getContentReferenceType(input.getMessage()), 
input.getSignatureType(), referenceId, input.getMessage());
         Reference keyInfoRef = 
createKeyInfoReference(input.getSignatureFactory(), keyInfoId, 
input.getContentDigestAlgorithm());
 
         int propsRefsSize = properties == null || properties.getReferences() 
== null || properties.getReferences().isEmpty() ? 0
@@ -646,10 +646,10 @@ public class XmlSignerProcessor extends 
XmlSignatureProcessor {
         }
     }
 
-    protected Reference createReference(XMLSignatureFactory fac, String uri, 
String type, SignatureType sigType, String id)
+    protected Reference createReference(XMLSignatureFactory fac, String uri, 
String type, SignatureType sigType, String id, Message message)
         throws InvalidAlgorithmParameterException, XmlSignatureException {
         try {
-            List<Transform> transforms = getTransforms(fac, sigType);
+            List<Transform> transforms = getTransforms(fac, sigType, message);
             Reference ref = fac.newReference(uri, 
fac.newDigestMethod(getDigestAlgorithmUri(), null), transforms, type, id);
             return ref;
         } catch (NoSuchAlgorithmException e) {
@@ -766,32 +766,46 @@ public class XmlSignerProcessor extends 
XmlSignatureProcessor {
         return fac.newXMLObject(Collections.singletonList(new 
DOMStructure(node)), id, null, null);
     }
 
-    private List<Transform> getTransforms(XMLSignatureFactory fac, 
SignatureType sigType) throws NoSuchAlgorithmException,
+    private List<Transform> getTransforms(XMLSignatureFactory fac, 
SignatureType sigType, Message message) throws NoSuchAlgorithmException,
             InvalidAlgorithmParameterException {
-        List<AlgorithmMethod> configuredTrafos = 
getConfiguration().getTransformMethods();
-        if (SignatureType.enveloped == sigType) {
-            // add enveloped transform if necessary
-            if (configuredTrafos.size() > 0) {
-                if (!containsEnvelopedTransform(configuredTrafos)) {
-                    configuredTrafos = new 
ArrayList<AlgorithmMethod>(configuredTrafos.size() + 1);
+        String transformMethodsHeaderValue = 
message.getHeader(XmlSignatureConstants.HEADER_TRANSFORM_METHODS, String.class);
+        if (transformMethodsHeaderValue == null) {
+            List<AlgorithmMethod> configuredTrafos = 
getConfiguration().getTransformMethods();
+            if (SignatureType.enveloped == sigType) {
+                // add enveloped transform if necessary
+                if (configuredTrafos.size() > 0) {
+                    if (!containsEnvelopedTransform(configuredTrafos)) {
+                        configuredTrafos = new 
ArrayList<AlgorithmMethod>(configuredTrafos.size() + 1);
+                        
configuredTrafos.add(XmlSignatureHelper.getEnvelopedTransform());
+                        
configuredTrafos.addAll(getConfiguration().getTransformMethods());
+                    }
+                } else {
+                    // add enveloped and C14N trafo
+                    configuredTrafos = new ArrayList<AlgorithmMethod>(2);
                     
configuredTrafos.add(XmlSignatureHelper.getEnvelopedTransform());
-                    
configuredTrafos.addAll(getConfiguration().getTransformMethods());
+                    
configuredTrafos.add(XmlSignatureHelper.getCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE));
                 }
-            } else {
-                // add enveloped and C14N trafo
-                configuredTrafos = new ArrayList<AlgorithmMethod>(2);
-                
configuredTrafos.add(XmlSignatureHelper.getEnvelopedTransform());
-                
configuredTrafos.add(XmlSignatureHelper.getCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE));
             }
-        }
 
-        List<Transform> transforms = new 
ArrayList<Transform>(configuredTrafos.size());
-        for (AlgorithmMethod trafo : configuredTrafos) {
-            Transform transform = fac.newTransform(trafo.getAlgorithm(), 
(TransformParameterSpec) trafo.getParameterSpec());
-            transforms.add(transform);
-            LOG.debug("Transform method: {}", trafo.getAlgorithm());
+            List<Transform> transforms = new 
ArrayList<Transform>(configuredTrafos.size());
+            for (AlgorithmMethod trafo : configuredTrafos) {
+                Transform transform = fac.newTransform(trafo.getAlgorithm(), 
(TransformParameterSpec) trafo.getParameterSpec());
+                transforms.add(transform);
+                LOG.debug("Transform method: {}", trafo.getAlgorithm());
+            }
+            return transforms;
+        } else {
+            LOG.debug("Header {} with value '{}' found", 
XmlSignatureConstants.HEADER_TRANSFORM_METHODS, transformMethodsHeaderValue);
+            String[] transformAlgorithms = 
transformMethodsHeaderValue.split(",");
+            List<Transform> transforms = new 
ArrayList<Transform>(transformAlgorithms.length);
+            for (String transformAlgorithm : transformAlgorithms) {
+                transformAlgorithm = transformAlgorithm.trim();
+                Transform transform = fac.newTransform(transformAlgorithm, 
(TransformParameterSpec) null);
+                transforms.add(transform);
+                LOG.debug("Transform method: {}", transformAlgorithm);
+            }
+            return transforms;
         }
-        return transforms;
     }
 
     private boolean containsEnvelopedTransform(List<AlgorithmMethod> 
configuredTrafos) {

http://git-wip-us.apache.org/repos/asf/camel/blob/afd27371/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java
 
b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java
index fa62b2e..cd1d2c9 100644
--- 
a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java
+++ 
b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java
@@ -386,6 +386,14 @@ public class XmlSignatureTest extends CamelTestSupport {
         sendBody("direct:enveloping", payload);
         assertMockEndpointsSatisfied();
     }
+    
+    @Test
+    public void testEnvelopedSignatureWithTransformHeader() throws Exception {
+        setupMock(payload);
+        sendBody("direct:enveloped", payload, Collections.<String, 
Object>singletonMap(XmlSignatureConstants.HEADER_TRANSFORM_METHODS, 
+                
"http://www.w3.org/2000/09/xmldsig#enveloped-signature,http://www.w3.org/TR/2001/REC-xml-c14n-20010315";));
+        assertMockEndpointsSatisfied();
+    }
 
     @Test
     public void testEnvelopingSignatureWithPlainText() throws Exception {
@@ -808,6 +816,12 @@ public class XmlSignatureTest extends CamelTestSupport {
     public void testDetachedSignature() throws Exception {
         testDetachedSignatureInternal();
     }
+    
+    @Test
+    public void testDetachedSignatureWitTransformHeader() throws Exception {
+        
testDetachedSignatureInternal(Collections.singletonMap(XmlSignatureConstants.HEADER_TRANSFORM_METHODS,
 
+                
(Object)"http://www.w3.org/2000/09/xmldsig#enveloped-signature,http://www.w3.org/TR/2001/REC-xml-c14n-20010315";));
+    }
 
     @Test
     public void testSignatureIdAtributeNull() throws Exception {
@@ -842,6 +856,12 @@ public class XmlSignatureTest extends CamelTestSupport {
 
     private Element testDetachedSignatureInternal() throws 
InterruptedException, XPathExpressionException, SAXException, IOException,
             ParserConfigurationException {
+        return testDetachedSignatureInternal(Collections.<String, 
Object>emptyMap());
+    }
+    
+    private Element testDetachedSignatureInternal(Map<String, Object> headers) 
throws InterruptedException, XPathExpressionException, SAXException, 
IOException,
+         ParserConfigurationException {
+
         String detachedPayload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 
                 + (includeNewLine ? "\n" : "")
                 + "<ns:root xmlns:ns=\"http://test\";><a 
ID=\"myID\"><b>bValue</b></a></ns:root>";
@@ -849,7 +869,7 @@ public class XmlSignatureTest extends CamelTestSupport {
         mock.expectedMessageCount(1);
         MockEndpoint mockVerified = getMockEndpoint("mock:verified");
         mockVerified.expectedBodiesReceived(detachedPayload);
-        sendBody("direct:detached", detachedPayload);
+        sendBody("direct:detached", detachedPayload, headers);
         assertMockEndpointsSatisfied();
         Map<String, String> namespaceMap = new TreeMap<String, String>();
         namespaceMap.put("ns", "http://test";);

Reply via email to