1
Vote

XmlDsigXPathWithNamespacesTransform is not preserving whitespace

description

When using the provided XmlDsigXPathWithNamespacesTransform class to verify a signature, the whitespace is stripped out of the document when loading into a XmlDocument before canonicalization.

This leads to invalid signature, because hashs end up being different. The whitespace is preserved during canonicalization when signing with other libraries as per the specs (summary here: http://www.di-mgt.com.au/xmldsig.html#c14n).

The PreserveWhitespace property of the XmlDocument class having a default value of false, it needs to be set explicitely to true when loading the input document to process.
        /// <summary>
        ///     Load input nodes to process
        /// </summary>
        public override void LoadInput(object obj)
        {
            if (obj == null)
                throw new ArgumentNullException("obj");

            // Canonicalize the input into a stream
            XmlDsigC14NTransform canonicalization = new XmlDsigC14NTransform(true);
            canonicalization.LoadInput(obj);
            Stream canonicalizedInput = canonicalization.GetOutput(typeof(Stream)) as Stream;

            // Load the canonicalized input into a document to transform
            XmlDocument document = new XmlDocument();
            document.PreserveWhitespace = true;   // <----- this is necessary
            document.Load(canonicalizedInput);
            m_inputNodes = document;
        }
With this fix applied the transformed reference contents become correct, therefore the hash matches what's been calculated during the signature creation and the validation succeeds.

comments