[xmlsec] C14N 1.0 question and 1.1

Aleksey Sanin aleksey at aleksey.com
Thu Apr 10 14:08:27 PDT 2008

> First if you have any plans for c14n 1.1 implementation.

Yes, I know about this, I am participating in the w3c xmlsec
working group. At the moment, I don't have any definite plans
to implement 1.1 since I don't need it myself and I don't see
a lot of interest. But as usual, I would be glad to accept
patches :)

> Question 1:
> What does FillMissingPrefixes function? It seems to expand namespace 
> attributes to all children (and theirs children)
> <a xmlns="bla"><b/></a>
> to
> <a xmlns="bla"><b xmlns="bla"/></a>
> If that is the case why is there need inside WriteNamespacesAxis to 
> iterate for each node through all of its parents (if each node has 
> already all their namespace attribute). Well another thing is that 
> changing original xml is bad (well IMHO :) ). Apache xml security also 
> does that, but it cleans them after c14n. Older versions didn't do that 
> and you ended up with million namespaces all over xml and twice the 
> size after signing it.

I haven't looked at Mono code since the day I wrote it :) Sorry, but
I can't answer that. You know this code way better than I do now :)

> Question 2:
> Whould it be cleaner to just use xpath expression "namespace::*" (and 
> faster ??? and not needing xpath hack inside c14n.c in libxml2). With 
> precompiled xpath it could really work.
> As in (just some pseudo code): 
> foreach (node in xNode.selectNodes("namespace::*") {
>   if IsNamespaceRendered (node.prefix, node.Value) and 
> IsNodeVisible(node) ...
>   ...
> }

It might be a good idea. When I was working on the original
mono implementation the XPath there was pretty buggy and I was
trying to avoid it as much as I can. Most likely things have
changed now.

> Question 3:
> Another posibility is to stacking all namespaces along the way (and 
> without using XPath) ... as is done for rendered naspaces ... except it 
> could save all namespaces with additional allreadyRendered flag.
>     xmlNsPtr  *nsTab;     /* array of ns in no particular order */      
>     xmlNodePtr *nodeTab;   /* array of nodes in no particular order */
>     byte *allreadyRendered /* array of nodes */
> and then searching for matching xmlNsPtr backwards (nsCurEnd to 0 
> ...) ... and when finding ns element checking it if it was 
> allreadyRendered ... if not adding it to the output list and setting 
> allreadyrendered flag to true (before checking it with xmlC14NIsVisible 
> ...).

Hm... I am not sure I see the difference between searching
this structure and searching the node's parents axis. Unless...
you have many duplicate namespaces declarations on different
level in the xml tree. Then you can potentially optimize things
a little bit.

> According to our tests your xmlC14NProcessNamespacesAxis is the slowest 
> part of libxml2 c14n processing. And if I can help somehow to optimize 
> it ...

If you have a lot of namespaces then I can easily believe
you :) I did not run performance benchmarks but probably
the simplest way to optimize it is to change from a linear search
for a matching namespace to a simple binary search. I would
bet it will give you pretty nice speedup. Next, you can try to
cache search results (i.e. for nodes on the same level).


More information about the xmlsec mailing list