1

I have an XML document where I need to verify a signature. The SignedInfo element has the element CanonicalizationMethod which specifies the algorithm "http://www.w3.org/2001/10/xml-exc-c14n#" and also has a child element InclusiveNamespaces with a populated PrefixList attribute, like so:

<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
    <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="soapenv"></ec:InclusiveNamespaces>
  </ds:CanonicalizationMethod>...

I use the following code to create my C14Transform object:

XmlDsigExcC14NTransform cn14Transform = new XmlDsigExcC14NTransform(false, "soapenv");

where "soapenv" comes from the PrefixList attribute.

When Canonicalizing the above XML (ignoring whitespaces) it should come out like this (note the xmlns:soapenv="..." part on line 2):

<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
        xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
    <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="soapenv"></ec:InclusiveNamespaces>
</ds:CanonicalizationMethod>
...

The issue I have is that the xmlns:soapenv="..." part is not included when canonicalizing, causing the signature verification to fail.

I can get around this by inserting it programmatically, but that is a pain as there will be variations of the PrefixList content.

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
elSeten
  • 38
  • 1
  • 8
  • I doubt there's much you can do. Where would it magically infer the uri for the namespace declaration its supposed to add? Shouldn't the original have this attribute if it's required to verify the signature? – Charles Mager Jun 18 '15 at 07:33
  • The namespace declaration does exist in the xml document already, just somewhere else. I was hoping there was some setting on the transform object that I had to turn on so that the canonical version comes out right. I have confirmation that this works correctly in other languages, at least php. Also, InclusiveNamespaces is a part of the Exclusive Canonicalization W3C standard so I would assume Microsoft has it covered. – elSeten Jun 18 '15 at 11:00

1 Answers1

1

Maybe this post form Microsoft can help you out: https://support.microsoft.com/en-us/kb/2639079

They show you how to register a custom transform for the canonicalization algorithm. It is used to remove a namespace, but I think you can also use this to add one.

public class  MyXmlDsigExcC14NTransform : XmlDsigExcC14NTransform 
{ 
   public MyXmlDsigExcC14NTransform() {} 

   public override  void LoadInput(Object obj) 
   {            
      XmlElement root = ((XmlDocument)obj).DocumentElement; 
      if (root.Name == "SignedInfo") root.RemoveAttribute("xml:id");            
      base.LoadInput(obj);                      
   } 
}

At the beginning of your application MyXmlDsigExcC14NTransform can be registered with the following call:

CryptoConfig.AddAlgorithm(typeof(MyXmlDsigExcC14NTransform), "http://www.w3.org/2001/10/xml-exc-c14n#"); 
Patrick Koorevaar
  • 1,219
  • 15
  • 24
  • 1
    Hey thanks for that. That is cleaner than what I am currently doing, however I had still secretly hoped Microsoft's library would handle prefixlists correctly. – elSeten Jul 23 '15 at 02:00