Trouble verifying XML signature with XmlDsigExcC14NTransform and InclusiveNamespaces

6k views Asked by At

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.

1

There are 1 answers

1
Patrick Koorevaar On

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#");