You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by gi...@apache.org on 2012/07/14 16:38:54 UTC

svn commit: r1361553 - in /santuario/xml-security-java/trunk/src: main/java/org/apache/xml/security/stax/ext/ main/java/org/apache/xml/security/stax/impl/ main/java/org/apache/xml/security/stax/impl/processor/output/ test/java/org/apache/xml/security/t...

Author: giger
Date: Sat Jul 14 14:38:54 2012
New Revision: 1361553

URL: http://svn.apache.org/viewvc?rev=1361553&view=rev
Log:
fix for SANTUARIO-325

Modified:
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/SecurePart.java
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/SignaturePartDef.java
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureEndingOutputProcessor.java
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureOutputProcessor.java
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureOutputProcessor.java
    santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationReferenceURIResolverTest.java
    santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/SecurePart.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/SecurePart.java?rev=1361553&r1=1361552&r2=1361553&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/SecurePart.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/SecurePart.java Sat Jul 14 14:38:54 2012
@@ -64,17 +64,31 @@ public class SecurePart {
     private String idToSign;
     private String idToReference;
     private String externalReference;
+    private String c14nMethod = XMLSecurityConstants.NS_C14N_EXCL;
+    private String digestMethod = XMLSecurityConstants.NS_XMLDSIG_SHA1;
 
     public SecurePart(QName name, Modifier modifier) {
         this(name, false, modifier);
     }
 
+    public SecurePart(QName name, Modifier modifier, String c14nMethod, String digestMethod) {
+        this(name, false, modifier, c14nMethod, digestMethod);
+    }
+
     public SecurePart(QName name, boolean generateXPointer, Modifier modifier) {
         this.name = name;
         this.generateXPointer = generateXPointer;
         this.modifier = modifier;
     }
 
+    public SecurePart(QName name, boolean generateXPointer, Modifier modifier, String c14nMethod, String digestMethod) {
+        this.name = name;
+        this.generateXPointer = generateXPointer;
+        this.modifier = modifier;
+        this.c14nMethod = c14nMethod;
+        this.digestMethod = digestMethod;
+    }
+
     public SecurePart(QName name, String idToSign, String idToReference, Modifier modifier) {
         this.name = name;
         this.idToSign = idToSign;
@@ -86,6 +100,12 @@ public class SecurePart {
         this.externalReference = externalReference;
     }
 
+    public SecurePart(String externalReference, String c14nMethod, String digestMethod) {
+        this.externalReference = externalReference;
+        this.c14nMethod = c14nMethod;
+        this.digestMethod = digestMethod;
+    }
+
     /**
      * The name of the element to be secured
      *
@@ -143,4 +163,20 @@ public class SecurePart {
     public void setExternalReference(String externalReference) {
         this.externalReference = externalReference;
     }
+
+    public String getC14nMethod() {
+        return c14nMethod;
+    }
+
+    public void setC14nMethod(String c14nMethod) {
+        this.c14nMethod = c14nMethod;
+    }
+
+    public String getDigestMethod() {
+        return digestMethod;
+    }
+
+    public void setDigestMethod(String digestMethod) {
+        this.digestMethod = digestMethod;
+    }
 }

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/SignaturePartDef.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/SignaturePartDef.java?rev=1361553&r1=1361552&r2=1361553&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/SignaturePartDef.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/SignaturePartDef.java Sat Jul 14 14:38:54 2012
@@ -30,6 +30,7 @@ public class SignaturePartDef {
     private String digestValue;
     private String transformAlgo;
     private String c14nAlgo;
+    private String digestAlgo;
     private String inclusiveNamespaces;
     private boolean externalResource;
     private boolean generateXPointer;
@@ -66,6 +67,14 @@ public class SignaturePartDef {
         this.c14nAlgo = c14nAlgo;
     }
 
+    public String getDigestAlgo() {
+        return digestAlgo;
+    }
+
+    public void setDigestAlgo(String digestAlgo) {
+        this.digestAlgo = digestAlgo;
+    }
+
     public String getInclusiveNamespaces() {
         return inclusiveNamespaces;
     }

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureEndingOutputProcessor.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureEndingOutputProcessor.java?rev=1361553&r1=1361552&r2=1361553&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureEndingOutputProcessor.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureEndingOutputProcessor.java Sat Jul 14 14:38:54 2012
@@ -156,7 +156,7 @@ public abstract class AbstractSignatureE
             createTransformsStructureForSignature(subOutputProcessorChain, signaturePartDef);
 
             attributes = new ArrayList<XMLSecAttribute>(1);
-            attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, getSecurityProperties().getSignatureDigestAlgorithm()));
+            attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, signaturePartDef.getDigestAlgo()));
             createStartElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_dsig_DigestMethod, false, attributes);
             createEndElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_dsig_DigestMethod);
             createStartElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_dsig_DigestValue, false, null);

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureOutputProcessor.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureOutputProcessor.java?rev=1361553&r1=1361552&r2=1361553&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureOutputProcessor.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/AbstractSignatureOutputProcessor.java Sat Jul 14 14:38:54 2012
@@ -75,13 +75,14 @@ public abstract class AbstractSignatureO
         Iterator<Map.Entry<Object, SecurePart>> securePartsMapIterator = dynamicSecureParts.entrySet().iterator();
         while (securePartsMapIterator.hasNext()) {
             Map.Entry<Object, SecurePart> securePartEntry = securePartsMapIterator.next();
-            final String externalReference = securePartEntry.getValue().getExternalReference();
+            final SecurePart securePart = securePartEntry.getValue();
+            final String externalReference = securePart.getExternalReference();
             if (externalReference != null) {
                 ResourceResolver resourceResolver = ResourceResolverMapper.getResourceResolver(externalReference);
 
                 DigestOutputStream digestOutputStream = null;
                 try {
-                    digestOutputStream = createMessageDigestOutputStream();
+                    digestOutputStream = createMessageDigestOutputStream(securePart.getDigestMethod());
                 } catch (NoSuchAlgorithmException e) {
                     throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, e);
                 } catch (NoSuchProviderException e) {
@@ -89,6 +90,9 @@ public abstract class AbstractSignatureO
                 }
 
                 InputStream inputStream = resourceResolver.getInputStreamFromExternalReference();
+
+                //todo transformers
+
                 try {
                     IOUtils.copy(inputStream, digestOutputStream);
                 } catch (IOException e) {
@@ -99,11 +103,16 @@ public abstract class AbstractSignatureO
                     logger.debug("Calculated Digest: " + calculatedDigest);
                 }
 
-                //todo we need a per SecurePart C14N and Digest algorithm property
                 SignaturePartDef signaturePartDef = new SignaturePartDef();
                 signaturePartDef.setSigRefId(externalReference);
                 signaturePartDef.setDigestValue(calculatedDigest);
                 signaturePartDef.setExternalResource(true);
+                signaturePartDef.setC14nAlgo(securePart.getC14nMethod());
+                String digestMethod = securePart.getDigestMethod();
+                if (digestMethod == null) {
+                    digestMethod = getSecurityProperties().getSignatureDigestAlgorithm();
+                }
+                signaturePartDef.setDigestAlgo(digestMethod);
                 getSignaturePartDefList().add(signaturePartDef);
             }
         }
@@ -120,13 +129,16 @@ public abstract class AbstractSignatureO
         this.activeInternalSignatureOutputProcessor = activeInternalSignatureOutputProcessor;
     }
 
-    private DigestOutputStream createMessageDigestOutputStream() throws NoSuchAlgorithmException, NoSuchProviderException {
-        AlgorithmType algorithmID = JCEAlgorithmMapper.getAlgorithmMapping(getSecurityProperties().getSignatureDigestAlgorithm());
+    private DigestOutputStream createMessageDigestOutputStream(String digestAlgorithm) throws XMLSecurityException, NoSuchAlgorithmException, NoSuchProviderException {
+        AlgorithmType algorithmType = JCEAlgorithmMapper.getAlgorithmMapping(digestAlgorithm);
+        if (algorithmType == null) {
+            throw new XMLSecurityException(XMLSecurityException.ErrorCode.UNSUPPORTED_ALGORITHM, "unknownSignatureAlgorithm", digestAlgorithm);
+        }
         MessageDigest messageDigest;
-        if (algorithmID.getJCEProvider() != null) {
-            messageDigest = MessageDigest.getInstance(algorithmID.getJCEName(), algorithmID.getJCEProvider());
+        if (algorithmType.getJCEProvider() != null) {
+            messageDigest = MessageDigest.getInstance(algorithmType.getJCEName(), algorithmType.getJCEProvider());
         } else {
-            messageDigest = MessageDigest.getInstance(algorithmID.getJCEName());
+            messageDigest = MessageDigest.getInstance(algorithmType.getJCEName());
         }
         return new DigestOutputStream(messageDigest);
     }
@@ -152,7 +164,7 @@ public abstract class AbstractSignatureO
         @Override
         public void init(OutputProcessorChain outputProcessorChain) throws XMLSecurityException {
             try {
-                this.digestOutputStream = createMessageDigestOutputStream();
+                this.digestOutputStream = createMessageDigestOutputStream(signaturePartDef.getDigestAlgo());
                 this.bufferedDigestOutputStream = new BufferedOutputStream(digestOutputStream);
 
                 if (signaturePartDef.getTransformAlgo() != null) {

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureOutputProcessor.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureOutputProcessor.java?rev=1361553&r1=1361552&r2=1361553&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureOutputProcessor.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureOutputProcessor.java Sat Jul 14 14:38:54 2012
@@ -73,10 +73,16 @@ public class XMLSignatureOutputProcessor
                     InternalSignatureOutputProcessor internalSignatureOutputProcessor = null;
                     try {
                         SignaturePartDef signaturePartDef = new SignaturePartDef();
+                        signaturePartDef.setC14nAlgo(securePart.getC14nMethod());
+                        String digestMethod = securePart.getDigestMethod();
+                        if (digestMethod == null) {
+                            digestMethod = getSecurityProperties().getSignatureDigestAlgorithm();
+                        }
+                        signaturePartDef.setDigestAlgo(digestMethod);
+
                         if (securePart.getIdToSign() == null) {
                             signaturePartDef.setGenerateXPointer(securePart.isGenerateXPointer());
                             signaturePartDef.setSigRefId(IDGenerator.generateID(null));
-                            signaturePartDef.setC14nAlgo(getSecurityProperties().getSignatureCanonicalizationAlgorithm());
 
                             Attribute attribute = xmlSecStartElement.getAttributeByName(XMLSecurityConstants.ATT_NULL_Id);
                             if (attribute != null) {
@@ -97,8 +103,7 @@ public class XMLSignatureOutputProcessor
                             }
                         } else {
                             signaturePartDef.setSigRefId(securePart.getIdToSign());
-                            signaturePartDef.setC14nAlgo(getSecurityProperties().getSignatureCanonicalizationAlgorithm());
-                            String signatureAppendId = 
+                            String signatureAppendId =
                                     outputProcessorChain.getSecurityContext().get(
                                             XMLSecurityConstants.PROP_APPEND_SIGNATURE_ON_THIS_ID);
                             if (signatureAppendId == null || "".equals(signatureAppendId)) {

Modified: santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationReferenceURIResolverTest.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationReferenceURIResolverTest.java?rev=1361553&r1=1361552&r2=1361553&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationReferenceURIResolverTest.java (original)
+++ santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationReferenceURIResolverTest.java Sat Jul 14 14:38:54 2012
@@ -66,7 +66,8 @@ public class SignatureCreationReferenceU
                 new SecurePart(new QName("urn:example:po", "PaymentInfo"), SecurePart.Modifier.Element);
         properties.addSignaturePart(securePart);
 
-        securePart = new SecurePart("file://" + BASEDIR + "/src/test/resources/ie/baltimore/merlin-examples/merlin-xmlenc-five/plaintext.xml");
+        //todo remove null-c14n when external transformation is implemented
+        securePart = new SecurePart("file://" + BASEDIR + "/src/test/resources/ie/baltimore/merlin-examples/merlin-xmlenc-five/plaintext.xml", null, XMLSecurityConstants.NS_XMLDSIG_SHA1);
         properties.addSignaturePart(securePart);
 
         OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);
@@ -111,7 +112,7 @@ public class SignatureCreationReferenceU
                 new SecurePart(new QName("urn:example:po", "PaymentInfo"), SecurePart.Modifier.Element);
         properties.addSignaturePart(securePart);
 
-        securePart = new SecurePart("file://" + BASEDIR + "/target/test-classes/org/apache/xml/security/test/stax/signature/SignatureVerificationReferenceURIResolverTest.class");
+        securePart = new SecurePart("file://" + BASEDIR + "/target/test-classes/org/apache/xml/security/test/stax/signature/SignatureVerificationReferenceURIResolverTest.class", null, XMLSecurityConstants.NS_XMLDSIG_SHA1);
         properties.addSignaturePart(securePart);
 
         OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);
@@ -158,7 +159,7 @@ public class SignatureCreationReferenceU
                 new SecurePart(new QName("urn:example:po", "PaymentInfo"), SecurePart.Modifier.Element);
         properties.addSignaturePart(securePart);
 
-        securePart = new SecurePart("http://gigerstyle.homelinux.com/wp-content/themes/twentyeleven/images/headers/willow.jpg");
+        securePart = new SecurePart("http://www.apache.org/images/feather-small.gif", null, XMLSecurityConstants.NS_XMLDSIG_SHA1);
         properties.addSignaturePart(securePart);
 
         OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);

Modified: santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java?rev=1361553&r1=1361552&r2=1361553&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java (original)
+++ santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java Sat Jul 14 14:38:54 2012
@@ -20,8 +20,11 @@ package org.apache.xml.security.test.sta
 
 import org.apache.xml.security.stax.ext.*;
 import org.apache.xml.security.test.stax.utils.XmlReaderToWriter;
+import org.junit.Assert;
 import org.junit.Test;
 import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
 
 import javax.crypto.SecretKey;
 import javax.crypto.spec.SecretKeySpec;
@@ -351,6 +354,138 @@ public class SignatureCreationTest exten
         // Verify using DOM
         verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
     }
+
+    @Test
+    public void testDifferentC14nMethodForReference() throws Exception {
+        // Set up the Configuration
+        XMLSecurityProperties properties = new XMLSecurityProperties();
+        XMLSecurityConstants.Action[] actions =
+                new XMLSecurityConstants.Action[]{XMLSecurityConstants.SIGNATURE};
+        properties.setOutAction(actions);
+
+        // Set the key up
+        KeyStore keyStore = KeyStore.getInstance("jks");
+        keyStore.load(
+                this.getClass().getClassLoader().getResource("transmitter.jks").openStream(),
+                "default".toCharArray()
+        );
+        Key key = keyStore.getKey("transmitter", "default".toCharArray());
+        properties.setSignatureKey(key);
+        X509Certificate cert = (X509Certificate)keyStore.getCertificate("transmitter");
+        properties.setSignatureCerts(new X509Certificate[]{cert});
+
+        SecurePart securePart = new SecurePart(
+                new QName("urn:example:po", "PaymentInfo"),
+                SecurePart.Modifier.Content,
+                "http://www.w3.org/TR/2001/REC-xml-c14n-20010315",
+                "http://www.w3.org/2000/09/xmldsig#sha1");
+        properties.addSignaturePart(securePart);
+
+        OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        XMLStreamWriter xmlStreamWriter = outboundXMLSec.processOutMessage(baos, "UTF-8");
+
+        InputStream sourceDocument =
+                this.getClass().getClassLoader().getResourceAsStream(
+                        "ie/baltimore/merlin-examples/merlin-xmlenc-five/plaintext.xml");
+        XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(sourceDocument);
+
+        XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
+        xmlStreamWriter.close();
+
+        // System.out.println("Got:\n" + new String(baos.toByteArray(), "UTF-8"));
+        Document document =
+                documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
+
+        NodeList nodeList = document.getElementsByTagNameNS(XMLSecurityConstants.TAG_dsig_CanonicalizationMethod.getNamespaceURI(), XMLSecurityConstants.TAG_dsig_CanonicalizationMethod.getLocalPart());
+        Assert.assertEquals(1, nodeList.getLength());
+        Element element = (Element)nodeList.item(0);
+        Assert.assertEquals(XMLSecurityConstants.NS_C14N_EXCL, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
+
+        nodeList = document.getElementsByTagNameNS(XMLSecurityConstants.TAG_dsig_Transform.getNamespaceURI(), XMLSecurityConstants.TAG_dsig_Transform.getLocalPart());
+        Assert.assertEquals(1, nodeList.getLength());
+        element = (Element)nodeList.item(0);
+        Assert.assertEquals("http://www.w3.org/TR/2001/REC-xml-c14n-20010315", element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
+
+        nodeList = document.getElementsByTagNameNS(XMLSecurityConstants.TAG_dsig_SignatureMethod.getNamespaceURI(), XMLSecurityConstants.TAG_dsig_SignatureMethod.getLocalPart());
+        Assert.assertEquals(1, nodeList.getLength());
+        element = (Element)nodeList.item(0);
+        Assert.assertEquals(XMLSecurityConstants.NS_XMLDSIG_RSASHA1, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
+
+        nodeList = document.getElementsByTagNameNS(XMLSecurityConstants.TAG_dsig_DigestMethod.getNamespaceURI(), XMLSecurityConstants.TAG_dsig_DigestMethod.getLocalPart());
+        Assert.assertEquals(1, nodeList.getLength());
+        element = (Element)nodeList.item(0);
+        Assert.assertEquals(XMLSecurityConstants.NS_XMLDSIG_SHA1, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
+
+        // Verify using DOM
+        verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+    }
+
+    @Test
+    public void testDifferentDigestMethodForReference() throws Exception {
+        // Set up the Configuration
+        XMLSecurityProperties properties = new XMLSecurityProperties();
+        XMLSecurityConstants.Action[] actions =
+                new XMLSecurityConstants.Action[]{XMLSecurityConstants.SIGNATURE};
+        properties.setOutAction(actions);
+
+        // Set the key up
+        KeyStore keyStore = KeyStore.getInstance("jks");
+        keyStore.load(
+                this.getClass().getClassLoader().getResource("transmitter.jks").openStream(),
+                "default".toCharArray()
+        );
+        Key key = keyStore.getKey("transmitter", "default".toCharArray());
+        properties.setSignatureKey(key);
+        X509Certificate cert = (X509Certificate)keyStore.getCertificate("transmitter");
+        properties.setSignatureCerts(new X509Certificate[]{cert});
+
+        SecurePart securePart = new SecurePart(
+                new QName("urn:example:po", "PaymentInfo"),
+                SecurePart.Modifier.Content,
+                "http://www.w3.org/2001/10/xml-exc-c14n#",
+                "http://www.w3.org/2001/04/xmlenc#sha256");
+        properties.addSignaturePart(securePart);
+
+        OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        XMLStreamWriter xmlStreamWriter = outboundXMLSec.processOutMessage(baos, "UTF-8");
+
+        InputStream sourceDocument =
+                this.getClass().getClassLoader().getResourceAsStream(
+                        "ie/baltimore/merlin-examples/merlin-xmlenc-five/plaintext.xml");
+        XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(sourceDocument);
+
+        XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
+        xmlStreamWriter.close();
+
+        // System.out.println("Got:\n" + new String(baos.toByteArray(), "UTF-8"));
+        Document document =
+                documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
+
+        NodeList nodeList = document.getElementsByTagNameNS(XMLSecurityConstants.TAG_dsig_CanonicalizationMethod.getNamespaceURI(), XMLSecurityConstants.TAG_dsig_CanonicalizationMethod.getLocalPart());
+        Assert.assertEquals(1, nodeList.getLength());
+        Element element = (Element)nodeList.item(0);
+        Assert.assertEquals(XMLSecurityConstants.NS_C14N_EXCL, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
+
+        nodeList = document.getElementsByTagNameNS(XMLSecurityConstants.TAG_dsig_Transform.getNamespaceURI(), XMLSecurityConstants.TAG_dsig_Transform.getLocalPart());
+        Assert.assertEquals(1, nodeList.getLength());
+        element = (Element)nodeList.item(0);
+        Assert.assertEquals(XMLSecurityConstants.NS_C14N_EXCL, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
+
+        nodeList = document.getElementsByTagNameNS(XMLSecurityConstants.TAG_dsig_SignatureMethod.getNamespaceURI(), XMLSecurityConstants.TAG_dsig_SignatureMethod.getLocalPart());
+        Assert.assertEquals(1, nodeList.getLength());
+        element = (Element)nodeList.item(0);
+        Assert.assertEquals(XMLSecurityConstants.NS_XMLDSIG_RSASHA1, element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
+
+        nodeList = document.getElementsByTagNameNS(XMLSecurityConstants.TAG_dsig_DigestMethod.getNamespaceURI(), XMLSecurityConstants.TAG_dsig_DigestMethod.getLocalPart());
+        Assert.assertEquals(1, nodeList.getLength());
+        element = (Element)nodeList.item(0);
+        Assert.assertEquals("http://www.w3.org/2001/04/xmlenc#sha256", element.getAttribute(XMLSecurityConstants.ATT_NULL_Algorithm.getLocalPart()));
+
+        // Verify using DOM
+        verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+    }
     
     @Test
     public void testC14n11Method() throws Exception {