Wrong canonicalization (c14n) made by SignedXml - it removes line breaks (
) - is it a .NET bug?
Asked Answered
O

0

11

We are receiving signed xmls from third parties which are using java. Our .NET implementation validates correctly the signatures, except when the xml contain the 
 character reference.

It looks like .NET removes that line break character somewhere in the process of c14n.

I have run some tests in c# with the next xml:

var xml = "<a>something&#13;\nsomething\r\n</a>";

Using the next code for c14n:

    public static void c14n(string xml)
    {
        using (MemoryStream msIn = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
        {
            var t = new XmlDsigExcC14NTransform(false);
            t.LoadInput(msIn);
            var o = t.GetOutput() as MemoryStream;
            var c14n = Encoding.UTF8.GetString((o as MemoryStream).ToArray());
            Console.WriteLine(c14n);
        }
    }

will result in the next xml, which is accordingly to w3org specifications (each line ends with LF char):

<a>something&#xD;
something
</a>

However, when using the next code to see what canonical form has the xml which is signed with SignedXml .NET class:

public static void SignXml(string xml)
{
    var doc = new XmlDocument { PreserveWhitespace = true };
    doc.LoadXml(xml);

    var cspParams = new CspParameters { KeyContainerName = "XML_DSIG_RSA_KEY" };
    var rsaKey = new RSACryptoServiceProvider(cspParams);

    var signedXml = new SignedXml(doc);
    signedXml.SigningKey = rsaKey;
    var reference = new Reference { Uri = "" };

    var env = new XmlDsigEnvelopedSignatureTransform();
    var excC14NTransform = new XmlDsigExcC14NTransform(false);
    reference.AddTransform(env);
    reference.AddTransform(excC14NTransform);
    reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
    signedXml.AddReference(reference);
    signedXml.ComputeSignature();
    var c14n = Encoding.UTF8.GetString((excC14NTransform.GetOutput() as MemoryStream).ToArray());
    Console.WriteLine(c14n);
}

will result in a different xml (each line ends with LF char), and we can see that the line break (&#13;) was removed:

<a>something
something
</a>

Is there a way of using SignedXml class so that the correct canonical form to be used? Could be the xml parsing (when creating XmlDocument) the cause of this issue?

I wonder if that's a bug in .NET, and whether there is a workaround for it.

Outleap answered 7/12, 2017 at 11:53 Comment(4)
Did you ever find a solution for this?Listerism
no - at least not in .net framework; maybe something was changed in .net core...Outleap
I can confirm that nothing has changed. The problem is still there in .NET 6Listerism
Hi there, we have the same issue. Does anyone found a way to be able to sign those xml messages with C# ?Zoster

© 2022 - 2024 — McMap. All rights reserved.