You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@santuario.apache.org by bu...@apache.org on 2005/11/30 08:51:31 UTC

DO NOT REPLY [Bug 37708] New: - Different behaviour with NodeSet and RootNode with InclusiveNamespaces

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG�
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=37708>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND�
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=37708

           Summary: Different behaviour with NodeSet and RootNode with
                    InclusiveNamespaces
           Product: Security
           Version: unspecified
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: critical
          Priority: P1
         Component: Canonicalization
        AssignedTo: security-dev@xml.apache.org
        ReportedBy: peter.hendry@capeclear.com


This is in version 1.3.0 (version has not been added to available version list
in Bugzilla).

Below is a complete description of the problem and how to reproduce it. This is
from an email I sent to the xml-security list and the followup to that email.
Also attached is a short program that demonstrates the different behaviors.

I have made this P1 as, in toolkits like WSS4J that use xml-security, iterop is
a primary concern and this problem breaks signature interop completely.

----------------
First email:

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-wssecurity-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-wssecurity-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?

----------------
Response:
raul.benito.garcia@gmail.com; on behalf of; Raul Benito [raul@apache.org]

You need to XMLUtils.circumventBug* before calling the c14n with nodesets...

----------------
My followup with full description of the test cases that show the problem:

Thanks for the reply. However, the line in my demo

    input.setNeedsToBeExpanded(true);

causes the following code in CanonicalizerBase to be called

    if (input.isNeedsToBeExpanded()) {
        XMLUtils.circumventBug2650(doc);
    } 

which does call XMLUtils.circumventBug2650 (I traced it) on the nodeset. Still
the namespaces in PrefixList are not output in the root element.

I have investigated some more and have managed to get the result I want but it
has made me more convinced there is a bug in xml-security's Excl C14N processing
(or that I really don't understand it ;) ).

There are 3 test cases which each produce different output but which I suspect
should produce the same output. 

1) 

INPUT: 
  XMLSignatureInput with nodeSet and set "needsToBeExpanded" to true. 

DESCRIPTION: 
  In this case XMLUtils.circumventBug2650() is called in CanonicalizerBase
  because "needsToBeExpanded" is set in the input.

CODE:
  input = new XMLSignatureInput(nodeSet);
  input.setNeedsToBeExpanded(true);
  bytes = c14n.engineCanonicalize(input, "env ns0 xsi wsu");

OUTPUT (formatted):
  <env:Body wsu:Id="body">
    <ns0:Ping xsi:type="ns0:ping">
      <ns0:text xsi:type="xsd:string">hello</ns0:text>
    </ns0:Ping>
  </env:Body>

COMMENT: 
  missing namespace declarations on Body. The call to circumventBug2650
  is done by the canonicalizer after the nodeset is created. Doing another
  test, where the nodeset is created and then circumventBug2650 is called
  explicitely before C14N, produces the same result.

2)

INPUT: 
  XMLSignatureInput with nodeSet on which circumventBug2650 was called before 
  the nodeSet was created from the document.

DESCRIPTION: 
  the Document is created, circumventBug2650 called and then the nodeSet
  is created. The input is again an XMLSignatureInput with a nodeSet but
  this time "needsToBeExpanded" is not set to true because the circumvent
  was already called.

CODE:
  XMLUtils.circumventBug2650(doc);
  XMLUtils.getSet(doc.getDocumentElement().getFirstChild(), nodeSet, null, false);
  input = new XMLSignatureInput(nodeSet);
  bytes = c14n.engineCanonicalize(input, "env ns0 xsi wsu");

OUTPUT:
  <env:Body 
      xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
     
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-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>

COMMENT: 
  This is the output that would be expected if InclusiveNamespaces="".
  However, the value "env ns0 xsi wsu" is passed as the prefix list.
  Tracing the code in the Canonicalizer shows that the prefix list is
  lost.

3)

INPUT: 
  NodeSet with circumventBug2650 called on the document before the 
  nodeset is created. 

DESCRIPTION: 
  The method "engineCanonicalizeXPathNodeSet() is called directly
  here instead of indirectly as in the previous cases so the 
  InclusiveNamespaces value is assured to be passed correctly to 
  the method.

CODE:
  XMLUtils.circumventBug2650(doc);
  XMLUtils.getSet(doc.getDocumentElement().getFirstChild(), nodeSet, null, false);
  bytes = c14n.engineCanonicalizeXPathNodeSet(nodeSet, "env ns0 xsi wsu");

OUTPUT:
  <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-wssecurity-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>

COMMENT: 
  this is the output I was expecting from all of the above cases. 
  The InclusiveNamespaces value means those namespace prefix 
  declarations should appear on the root node as they do here.

4)

INPUT: 
  root node

DESCRIPTION:
  circumventBug2650 may or may not be called and "needsToBeExpanded" 
  can be true or false. The same result is obtained in each case.

CODE:
  input = new XMLSignatureInput(doc.getDocumentElement().getFirstChild());
  byte[] bytes = c14n.engineCanonicalize(input, "env ns0 xsi wsu");

OUTPUT:
  Same as case 3)

COMMENT: 
  the result using a root node is consistent no matter the settings. 
  Should this also be the case for using nodesets?

Cases 3 and 4 produce the same (correct I think) output. Cases 1 and 2 produce
different output from each other and from 3 and 4. Is this the expected
behaviour is cases 1 and 2 and, if so, why?

Or if someone could tell me where my logic/expectations are in error that would
also be great.

I have attached an updated class that demonstrates each of the above cases.

Pete

-- 
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.