You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@santuario.apache.org by Eric Heath <eh...@interchange.ubc.ca> on 2002/10/08 05:14:16 UTC

Xerces NS Declarations and Canonicalization

Hi,

I have a project that uses xerces 2.0.1 and Apache XML Security 1.05D2 
to write
out the canonical form of an XML document using 
org.apache.xml.security.c14n.Canonicalizer
(specifically the implementation for 
http://www.w3.org/TR/2001/REC-xml-c14n-20010315, I
suppose).

I'm having a problem in that my XML document's namespace declarations 
are not being
displayed in the canonical format in a certain scenario.

When I use the javax.xml.parsers.DocumentBuilderFactory,
javax.xml.parsers.DocumentBuilder dynamic duo to create a new document via
DocumentBuild.newDocument() I get back a org.apache.xerces.dom.DocumentImpl
just as expected.

Now I build up this Document including some elements that contain 
namespace declarations,
no big deal.

Finally use Canonicalizer to canonicalize my DOM with 
Canonicalizer.canonicalizeSubtree(domDoc)
and the namespace declarations are *not* shown in the output!  <-- This 
is my problem.

If, on the other hand, I read in an existing document I get back an 
object typed as
org.apache.xerces.dom.DeferredDocumentImpl and the canonical form of 
this DOM has the NS
declarations included (like I want).

I've done a little searching around, but haven't run into any solutions 
for this problem.  Any ideas
on why the NS declarations would be omitted from the canonical form when 
I start from an empty
Document?

Regards,
Eric




Re: Xerces NS Declarations and Canonicalization

Posted by Eric Heath <eh...@interchange.ubc.ca>.
Christian Geuer-Pollmann wrote:
> Hi Eric,
> 
> now I know what the problem is. First how it works, then why:
> 
> Element rootElement =
>  domDocument.createElementNS("http://myNamespaceURI",
>     "nsPrefix:elementName");
> 
> // you have to *manually* add the namespace
> // definition attribute here:
> rootElement.setAttributeNS(
>  "http://www.w3.org/2000/xmlns/",
>  "xmlns:nsPrefix",
>  "http://myNamespaceURI");
> 
> Why: The XMLSerializer from Xerces is so gently to traverse the document 
> and add namespace attributes whereever needed. XMLUtils (which is called 
> internally before c14n) doesn't do this at the moment. So the below code 
> goes to c14nize a tree which in fact *has* no namespace attribute at 
> that point. But we can change the XMLUtils#circumventBug2650 method so 
> that it also adds this stuff.
> 
> Christian
> 

That would probably be a nice feature.  Thanks for the insight.

I think I was just unsure of the behaviour of the Canonicalizer because 
I have two
cases in my code:
1) The situation that is illustrated in my example below where I start 
from an empty
     Document.
2) Similar to my example, except that I use DocumentBuilder.parse(...) 
to create the DOM
     Document.
        - In this case SAX probably creates the namespaces as attributes 
as I do
          see them in the c14n output.

Thanks again,
Eric

> 
> 
> --On Tuesday, October 08, 2002 11:54 AM -0700 Eric Heath 
> <eh...@interchange.ubc.ca> wrote:
> 
>> The actual sign/verify process works correctly for me, I just have a
>> problem displaying the DOM in canonical form.
>>
>> Here's some code that hopefully illustrates my problem:
>>
>> import java.io.*;
>>
>> import javax.xml.parsers.DocumentBuilder;
>> import javax.xml.parsers.DocumentBuilderFactory;
>> import org.w3c.dom.Document;
>> import org.w3c.dom.Element;
>>
>> import org.apache.xml.security.c14n.Canonicalizer;
>> import org.apache.xml.serialize.XMLSerializer;
>> import org.apache.xml.serialize.OutputFormat;
>>
>> public class Test
>> {
>>      public static void main(String[] args)
>>      {
>>          final String CANONICALIZATION_METHOD =
>> "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
>>
>>          try
>>          {
>>              // Construct an empty DOM document
>>              DocumentBuilderFactory docBuilderFactory =
>> DocumentBuilderFactory.newInstance();
>> docBuilderFactory.setNamespaceAware(true);
>>              DocumentBuilder docBuilder =
>> docBuilderFactory.newDocumentBuilder();              Document domDocument
>> = docBuilder.newDocument();
>>
>>              // Create the root element and add it to the DOM
>>              Element rootElement =
>> domDocument.createElementNS("http://myNamespaceURI",
>> "nsPrefix:elementName");
>> domDocument.appendChild(rootElement);
>>
>>              // Add a child elements for flavour
>>              Element childElement =
>> domDocument.createElementNS("http://myNamespaceURI", "nsPrefix:child1");
>>              rootElement.appendChild(childElement);
>>
>>              // Get a Canonicalizer and write the canonical form of the
>> DOM to stdout              Canonicalizer canonicalizer =
>> Canonicalizer.getInstance(CANONICALIZATION_METHOD);              byte[]
>> buffer = canonicalizer.canonicalizeSubtree(domDocument);
>> System.out.println("Canonical form of DOM:");
>>              System.out.println(new String(buffer));
>>
>>              // Compare the output to the serialized version
>>              ByteArrayOutputStream baos = new ByteArrayOutputStream();
>>              OutputFormat outputFormat = new OutputFormat("XML", "UTF-8",
>> false); // false == no pretty printing              XMLSerializer
>> xmlSerializer = new XMLSerializer(baos, outputFormat);
>> xmlSerializer.serialize(domDocument);
>>              System.out.println("Serialized form of DOM:");
>>              System.out.println(baos.toString());
>>          }
>>          catch (Throwable t)
>>          {
>>              t.printStackTrace(System.out);
>>          }
>>      }
>> }
>>
>> As you can see, the namespace declaration
>> xmlns:nsPrefix="http://myNamespaceURI" is not displayed in the canonical
>> form of the DOM.
>>
>> I hope this illustrates my problem a little more clearly.
>>
>> Cheers,
>> Eric
>>
>>
>>
> 
> 
> 





Re: Xerces NS Declarations and Canonicalization

Posted by Christian Geuer-Pollmann <ge...@nue.et-inf.uni-siegen.de>.
Hi Eric,

now I know what the problem is. First how it works, then why:

Element rootElement =
  domDocument.createElementNS("http://myNamespaceURI",
     "nsPrefix:elementName");

// you have to *manually* add the namespace
// definition attribute here:
rootElement.setAttributeNS(
  "http://www.w3.org/2000/xmlns/",
  "xmlns:nsPrefix",
  "http://myNamespaceURI");

Why: The XMLSerializer from Xerces is so gently to traverse the document 
and add namespace attributes whereever needed. XMLUtils (which is called 
internally before c14n) doesn't do this at the moment. So the below code 
goes to c14nize a tree which in fact *has* no namespace attribute at that 
point. But we can change the XMLUtils#circumventBug2650 method so that it 
also adds this stuff.

Christian



--On Tuesday, October 08, 2002 11:54 AM -0700 Eric Heath 
<eh...@interchange.ubc.ca> wrote:

> The actual sign/verify process works correctly for me, I just have a
> problem displaying the DOM in canonical form.
>
> Here's some code that hopefully illustrates my problem:
>
> import java.io.*;
>
> import javax.xml.parsers.DocumentBuilder;
> import javax.xml.parsers.DocumentBuilderFactory;
> import org.w3c.dom.Document;
> import org.w3c.dom.Element;
>
> import org.apache.xml.security.c14n.Canonicalizer;
> import org.apache.xml.serialize.XMLSerializer;
> import org.apache.xml.serialize.OutputFormat;
>
> public class Test
> {
>      public static void main(String[] args)
>      {
>          final String CANONICALIZATION_METHOD =
> "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
>
>          try
>          {
>              // Construct an empty DOM document
>              DocumentBuilderFactory docBuilderFactory =
> DocumentBuilderFactory.newInstance();
> docBuilderFactory.setNamespaceAware(true);
>              DocumentBuilder docBuilder =
> docBuilderFactory.newDocumentBuilder();              Document domDocument
> = docBuilder.newDocument();
>
>              // Create the root element and add it to the DOM
>              Element rootElement =
> domDocument.createElementNS("http://myNamespaceURI",
> "nsPrefix:elementName");
> domDocument.appendChild(rootElement);
>
>              // Add a child elements for flavour
>              Element childElement =
> domDocument.createElementNS("http://myNamespaceURI", "nsPrefix:child1");
>              rootElement.appendChild(childElement);
>
>              // Get a Canonicalizer and write the canonical form of the
> DOM to stdout              Canonicalizer canonicalizer =
> Canonicalizer.getInstance(CANONICALIZATION_METHOD);              byte[]
> buffer = canonicalizer.canonicalizeSubtree(domDocument);
> System.out.println("Canonical form of DOM:");
>              System.out.println(new String(buffer));
>
>              // Compare the output to the serialized version
>              ByteArrayOutputStream baos = new ByteArrayOutputStream();
>              OutputFormat outputFormat = new OutputFormat("XML", "UTF-8",
> false); // false == no pretty printing              XMLSerializer
> xmlSerializer = new XMLSerializer(baos, outputFormat);
> xmlSerializer.serialize(domDocument);
>              System.out.println("Serialized form of DOM:");
>              System.out.println(baos.toString());
>          }
>          catch (Throwable t)
>          {
>              t.printStackTrace(System.out);
>          }
>      }
> }
>
> As you can see, the namespace declaration
> xmlns:nsPrefix="http://myNamespaceURI" is not displayed in the canonical
> form of the DOM.
>
> I hope this illustrates my problem a little more clearly.
>
> Cheers,
> Eric
>
>
>



Re: Xerces NS Declarations and Canonicalization

Posted by Eric Heath <eh...@interchange.ubc.ca>.
The actual sign/verify process works correctly for me, I just have a
problem displaying the DOM in canonical form.

Here's some code that hopefully illustrates my problem:

import java.io.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.apache.xml.security.c14n.Canonicalizer;
import org.apache.xml.serialize.XMLSerializer;
import org.apache.xml.serialize.OutputFormat;

public class Test
{
     public static void main(String[] args)
     {
         final String CANONICALIZATION_METHOD = 
"http://www.w3.org/TR/2001/REC-xml-c14n-20010315";

         try
         {
             // Construct an empty DOM document
             DocumentBuilderFactory docBuilderFactory = 
DocumentBuilderFactory.newInstance();
             docBuilderFactory.setNamespaceAware(true);
             DocumentBuilder docBuilder = 
docBuilderFactory.newDocumentBuilder();
             Document domDocument = docBuilder.newDocument();

             // Create the root element and add it to the DOM
             Element rootElement = 
domDocument.createElementNS("http://myNamespaceURI", 
"nsPrefix:elementName");
             domDocument.appendChild(rootElement);

             // Add a child elements for flavour
             Element childElement = 
domDocument.createElementNS("http://myNamespaceURI", "nsPrefix:child1");
             rootElement.appendChild(childElement);

             // Get a Canonicalizer and write the canonical form of the 
DOM to stdout
             Canonicalizer canonicalizer = 
Canonicalizer.getInstance(CANONICALIZATION_METHOD);
             byte[] buffer = canonicalizer.canonicalizeSubtree(domDocument);
             System.out.println("Canonical form of DOM:");
             System.out.println(new String(buffer));

             // Compare the output to the serialized version
             ByteArrayOutputStream baos = new ByteArrayOutputStream();
             OutputFormat outputFormat = new OutputFormat("XML", 
"UTF-8", false); // false == no pretty printing
             XMLSerializer xmlSerializer = new XMLSerializer(baos, 
outputFormat);
             xmlSerializer.serialize(domDocument);
             System.out.println("Serialized form of DOM:");
             System.out.println(baos.toString());
         }
         catch (Throwable t)
         {
             t.printStackTrace(System.out);
         }
     }
}

As you can see, the namespace declaration 
xmlns:nsPrefix="http://myNamespaceURI" is not displayed in the canonical 
form of the DOM.

I hope this illustrates my problem a little more clearly.

Cheers,
Eric




Re: Xerces NS Declarations and Canonicalization

Posted by Christian Geuer-Pollmann <ge...@nue.et-inf.uni-siegen.de>.

--On Tuesday, October 08, 2002 1:12 AM -0700 Eric Heath 
<eh...@interchange.ubc.ca> wrote:

> Hi Christian,
>
> I poked around in the Apache XML Security source and it looks to me like
> namespaces are only processed in the DOM if they are represented as
> attributes during c14n canonicalization (let me know if I missed something
> in the canonicalization method).

I'm not sure whether I understand you correctly? When you sign (or verify) 
a document, the namespaces are 'expanded' in 
XMLUtils.circumventBug2650(Document). So there will be many namespace 
'attributes' spreading over the document.

<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2650>

> It seems strange that the DeferredDocumentImpl converts namespace
> declarations to attribute format at some stage while the superclass
> DocumentImpl does not.

I really have a problem to understand what your problem is. Can you supply 
source code which illustrates the problem?

> A work around on my end is to use JAXP's getNamespaceURI() and
> getNamespacePrefix() to manually add the namespace declarations as
> attributes, but doing this isn't the most graceful bit of code that I've
> had to write.
>
> I'm not sure what the history is behind DOM implementations supporting
> namespaces or if there is a standard anywhere that suggests that they
> represent namespace declarations as attributes, but it sure would be nice
> if the implementation of, say xerces, was consistent. :+)
>
> Would it be worth while for Apach XML Sec to also check the values of
> getNamespaceURI() and getNamespacePrefix() during canonicalization?

It does ;-))

Christian

Re: Xerces NS Declarations and Canonicalization

Posted by Eric Heath <eh...@interchange.ubc.ca>.
Hi Christian,

I poked around in the Apache XML Security source and it looks to me like
namespaces are only processed in the DOM if they are represented as
attributes during c14n canonicalization (let me know if I missed something
in the canonicalization method).

It seems strange that the DeferredDocumentImpl converts namespace
declarations to attribute format at some stage while the superclass
DocumentImpl does not.

A work around on my end is to use JAXP's getNamespaceURI() and
getNamespacePrefix() to manually add the namespace declarations as
attributes, but doing this isn't the most graceful bit of code that I've had
to write.

I'm not sure what the history is behind DOM implementations supporting
namespaces or if there is a standard anywhere that suggests that they
represent namespace declarations as attributes, but it sure would be nice
if the implementation of, say xerces, was consistent. :+)

Would it be worth while for Apach XML Sec to also check the values of
getNamespaceURI() and getNamespacePrefix() during canonicalization?

- Eric

Christian Geuer-Pollmann wrote:
> Hi Eric,
> 
> I must admit that the only 'deeper' knowledge I have about Xerces is 
> used in the IdResolver class where I register ID-type attributes in 
> Xerces. At that class, I cast the Document to an 
> org.apache.xerces.dom.DocumentImpl which works.
> 
> DeferredDocumentImpl extends DocumentImpl
> 
> Christian
> 
> 
> --On Monday, October 07, 2002 8:14 PM -0700 Eric Heath 
> <eh...@interchange.ubc.ca> wrote:
> 
>> Hi,
>>
>> I have a project that uses xerces 2.0.1 and Apache XML Security 1.05D2 to
>> write out the canonical form of an XML document using
>> org.apache.xml.security.c14n.Canonicalizer (specifically the
>> implementation for http://www.w3.org/TR/2001/REC-xml-c14n-20010315, I
>> suppose).
>>
>> I'm having a problem in that my XML document's namespace declarations are
>> not being displayed in the canonical format in a certain scenario.
>>
>> When I use the javax.xml.parsers.DocumentBuilderFactory,
>> javax.xml.parsers.DocumentBuilder dynamic duo to create a new document 
>> via
>> DocumentBuild.newDocument() I get back a
>> org.apache.xerces.dom.DocumentImpl just as expected.
>>
>> Now I build up this Document including some elements that contain
>> namespace declarations, no big deal.
>>
>> Finally use Canonicalizer to canonicalize my DOM with
>> Canonicalizer.canonicalizeSubtree(domDoc) and the namespace declarations
>> are *not* shown in the output!  <-- This is my problem.
>>
>> If, on the other hand, I read in an existing document I get back an
>> object typed as org.apache.xerces.dom.DeferredDocumentImpl and the
>> canonical form of this DOM has the NS declarations included (like I 
>> want).
>>
>> I've done a little searching around, but haven't run into any solutions
>> for this problem.  Any ideas on why the NS declarations would be omitted
>> from the canonical form when I start from an empty Document?
>>
>> Regards,
>> Eric
> 
> 
> 





Re: Xerces NS Declarations and Canonicalization

Posted by Christian Geuer-Pollmann <ge...@nue.et-inf.uni-siegen.de>.
Hi Eric,

I must admit that the only 'deeper' knowledge I have about Xerces is used 
in the IdResolver class where I register ID-type attributes in Xerces. At 
that class, I cast the Document to an org.apache.xerces.dom.DocumentImpl 
which works.

DeferredDocumentImpl extends DocumentImpl

Christian


--On Monday, October 07, 2002 8:14 PM -0700 Eric Heath 
<eh...@interchange.ubc.ca> wrote:

> Hi,
>
> I have a project that uses xerces 2.0.1 and Apache XML Security 1.05D2 to
> write out the canonical form of an XML document using
> org.apache.xml.security.c14n.Canonicalizer (specifically the
> implementation for http://www.w3.org/TR/2001/REC-xml-c14n-20010315, I
> suppose).
>
> I'm having a problem in that my XML document's namespace declarations are
> not being displayed in the canonical format in a certain scenario.
>
> When I use the javax.xml.parsers.DocumentBuilderFactory,
> javax.xml.parsers.DocumentBuilder dynamic duo to create a new document via
> DocumentBuild.newDocument() I get back a
> org.apache.xerces.dom.DocumentImpl just as expected.
>
> Now I build up this Document including some elements that contain
> namespace declarations, no big deal.
>
> Finally use Canonicalizer to canonicalize my DOM with
> Canonicalizer.canonicalizeSubtree(domDoc) and the namespace declarations
> are *not* shown in the output!  <-- This is my problem.
>
> If, on the other hand, I read in an existing document I get back an
> object typed as org.apache.xerces.dom.DeferredDocumentImpl and the
> canonical form of this DOM has the NS declarations included (like I want).
>
> I've done a little searching around, but haven't run into any solutions
> for this problem.  Any ideas on why the NS declarations would be omitted
> from the canonical form when I start from an empty Document?
>
> Regards,
> Eric