I have a WS-Security implementation based on xml-security and am testing
interop. When testing against WSS4J (which also uses xml-security) - both
using version 1.3.0 - I am having problems because of what appears to be
different results of Excl C14N depending on whether the input is a NodeSet
or a root node. The problem occurs when using InclusiveNamespaces.

The issue appears to be that when the input is a NodeSet, the
InclusiveNamespaces value is ignored. What happens is the following sequence
of calls:

TransformC14NExclusive.enginePerformTransform(inputWithNodeSet)
 -> Canonicalizer20010315Excl.engineCanonicalize(inputWithNodeSet, "env ns0
xsi wsu")
   -> _inclusiveNSSet = "env ns0 xsi wsu"
   -> CanonicalizerBase.engineCanonicalize(inputWithNodeSet)
     ->
Canonicalizer20010315Excl.engineCanonicalizeXPathNodeSet(xpathNodeSet)
       ->
Canonicalizer20010315Excl.engineCanonicalizeXPathNodeSet(xpathNodeSet, "")
       -> _inclusiveNSSet = ""

So the inclusive namespaces passed in originally are forgotten to be
replaced by an empty list.

When passing a root node instead of a node set, the inclusive namespace list
is used and so the result is different. In the XML below, the document
element is env:Envelope and env:Body is that target node for C14N. For the
nodeset the result on the SOAP body is (formatting added)

<env:Body 
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"; 
 
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurit
y-utility-1.0.xsd" 
    wsu:Id="body">
  <ns0:Ping 
      xmlns:ns0="http://xmlsoap.org/Ping"; 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
      xsi:type="ns0:ping">
    <ns0:text xsi:type="xsd:string">hello</ns0:text>
  </ns0:Ping>
</env:Body>

and for a root node (being the body element in this case)

<env:Body 
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/";
    xmlns:ns0="http://xmlsoap.org/Ping"; 
 
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurit
y-utility-1.0.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
    wsu:Id="body">
  <ns0:Ping xsi:type="ns0:ping">
    <ns0:text xsi:type="xsd:string">hello</ns0:text>
  </ns0:Ping>
</env:Body>

I attach a test program that compares the 2 ways of doing this on the same
document and shows the results (the nodeset result differs from the one
above as it does not include any namespace declarations).

Is this a bug or am I not understanding the difference between processing
based on a nodeset and processing based on a root node?

Pete
/**
 * Copyright Notice
 *
 * Copyright (c) 2000-2004, Cape Clear Software.
 * All Rights Reserved
 *
 * This software is protected by copyright and other intellectual
 * property rights and by international treaties. Any unauthorised
 * reproduction or distribution of this software or any portion
 * thereof is strictly prohibited.
 */
package client.wss4j;

import java.io.StringReader;
import java.util.Set;
import java.util.HashSet;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;

import org.xml.sax.InputSource;
import org.w3c.dom.Document;
import org.apache.xml.security.signature.XMLSignatureInput;
import org.apache.xml.security.c14n.implementations.Canonicalizer20010315Excl;
import org.apache.xml.security.c14n.implementations.Canonicalizer20010315ExclOmitComments;
import org.apache.xml.security.utils.XMLUtils;


/**
 * @author Pete Hendry
 * @version $Id$
 */
public class DemoINProblem {

    private static final String XML =
        "<env:Envelope"
        + " xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"";
        + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"";
        + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";
        + " xmlns:ns0=\"http://xmlsoap.org/Ping\"";
        + " xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\";>"
        + "<env:Body wsu:Id=\"body\">"
        + "<ns0:Ping xsi:type=\"ns0:ping\">"
        + "<ns0:text xsi:type=\"xsd:string\">hello</ns0:text>"
        + "</ns0:Ping>"
        + "</env:Body>"
        + "</env:Envelope>";


    public static void main( String[] args )
        throws Exception {

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        factory.setValidating(false);

        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new InputSource(new StringReader(XML)));
        XMLSignatureInput input =
            new XMLSignatureInput(doc.getDocumentElement().getFirstChild());

        // called because this happens during tracing
        input.setNeedsToBeExpanded(true);
        Canonicalizer20010315Excl c14n = new Canonicalizer20010315ExclOmitComments();
        byte[] bytes = c14n.engineCanonicalize(input, "env ns0 xsi wsu");
        System.out.println("ROOT NODE:\n" + new String(bytes) + "\n=======\n");

        doc = builder.parse(new InputSource(new StringReader(XML)));
        Set nodeSet = new HashSet();
        XMLUtils.getSet(doc.getDocumentElement().getFirstChild(), nodeSet, null, false);

        input = new XMLSignatureInput(nodeSet);
        input.setNeedsToBeExpanded(true);
        c14n = new Canonicalizer20010315ExclOmitComments();

        bytes = c14n.engineCanonicalize(input, "env ns0 xsi wsu");
        System.out.println("NODE SET:\n" + new String(bytes) + "\n=======\n");
    }
}

Reply via email to