Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: Sign signature on xml that included tag <![CDATA[.....]]> #474

Closed
Alexiserist opened this issue Jul 31, 2024 · 8 comments
Closed

Comments

@Alexiserist
Copy link

Is your feature request related to a problem? Please describe...

I'm facing the issue of signing a xml signature.

Example XML of verify = false

<?xml version="1.0" encoding="UTF-8"?>
<HeaderDocument>
	<Payload>
		<![CDATA[<test>data<test>]]>
	</Payload>
</HeaderDocument>

but when I remove CDATA or content inside CDATA and try to verify it's work fine.

Example XML of verify = true

<?xml version="1.0" encoding="UTF-8"?>
<HeaderDocument>
	<Payload>Testing</Payload>
</HeaderDocument>

This is my code

    const sig = new SignedXml({ privateKey: pemPrivateKey,publicCert: pemCertificate });
    sig.addReference(
      {
      xpath: `//*[local-name(.)='${xmlRootName}']`,
      digestAlgorithm: "http://www.w3.org/2001/04/xmlenc#sha256",
      isEmptyUri: true,
      transforms: ["http://www.w3.org/2000/09/xmldsig#enveloped-signature"],
      }
    );
    sig.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
    sig.canonicalizationAlgorithm = 'http://www.w3.org/2001/10/xml-exc-c14n#';
    sig.computeSignature(xmlContent);

    const xmlSignedContent = sig.getSignedXml();
    const sig2 = new SignedXml({publicCert: pemCertificate});
    const signature = sig.getSignatureXml();
    sig2.loadSignature(signature);
    const verify = sig2.checkSignature(xmlSignedContent);

Describe teh solution you'd like...

I have change a canonicalizationAlgorithm to every single one, but it isn't work.

Describe the alternatives you've considered...

I guess it would be a problem when on signing.

@cjbarth
Copy link
Contributor

cjbarth commented Aug 24, 2024

Have you tried it by signing something other than the root?

@srd90
Copy link

srd90 commented Aug 24, 2024

I'm facing the issue of signing a xml signature.

Could you be more specific. Is the issue that signature validation fails at some other system which uses some other xml-crypto library for verification or is your issue perhaps some stacktrace during signing of xml? Perhaps something like "Unable to canoni... node type..."?

Quote from 6.0.0's codebase that contains handlers for different DOM node element types for one of the C14N implementations:

if (isDomNode.isCommentNode(node)) {
return this.renderComment(node);
}
if (node.data) {
return utils.encodeSpecialCharactersInText(node.data);
}
if (isDomNode.isElementNode(node)) {
let i;
let pfxCopy;
const ns = this.renderNs(
node,
prefixesInScope,
defaultNs,
defaultNsForPrefix,
ancestorNamespaces,
);
const res = ["<", node.tagName, ns.rendered, this.renderAttrs(node), ">"];
for (i = 0; i < node.childNodes.length; ++i) {
pfxCopy = prefixesInScope.slice(0);
res.push(
this.processInner(node.childNodes[i], pfxCopy, ns.newDefaultNs, defaultNsForPrefix, []),
);
}
res.push("</", node.tagName, ">");
return res.join("");
}
throw new Error(`Unable to canonicalize node type: ${node.nodeType}`);

Note: I didn't bother to spend time to run example code due lack of e.g. xml-crypto version information, package.json and due example code not being immedialy runnable.

Note2: IF it turns out that C14N implementations of this project for example skip content of CDATA and because output of C14N is used to calculate checksum then there could be even more serious problem if signature is also verified with library which does the same skipping because then e.g. <isAdmin><![CDATA[false]]></isAdmin> could be changed by MITM to true without being spotted by receiving side's signature validation.

@Alexiserist
Copy link
Author

Have you tried it by signing something other than the root?

No, because I want to ensure that the content of my XML remains unchanged after signing complete.

@Alexiserist
Copy link
Author

I'm facing the issue of signing a xml signature.

Could you be more specific. Is the issue that signature validation fails at some other system which uses some other xml-crypto library for verification or is your issue perhaps some stacktrace during signing of xml? Perhaps something like "Unable to canoni... node type..."?

Quote from 6.0.0's codebase that contains handlers for different DOM node element types for one of the C14N implementations:

if (isDomNode.isCommentNode(node)) {
return this.renderComment(node);
}
if (node.data) {
return utils.encodeSpecialCharactersInText(node.data);
}
if (isDomNode.isElementNode(node)) {
let i;
let pfxCopy;
const ns = this.renderNs(
node,
prefixesInScope,
defaultNs,
defaultNsForPrefix,
ancestorNamespaces,
);
const res = ["<", node.tagName, ns.rendered, this.renderAttrs(node), ">"];
for (i = 0; i < node.childNodes.length; ++i) {
pfxCopy = prefixesInScope.slice(0);
res.push(
this.processInner(node.childNodes[i], pfxCopy, ns.newDefaultNs, defaultNsForPrefix, []),
);
}
res.push("</", node.tagName, ">");
return res.join("");
}
throw new Error(`Unable to canonicalize node type: ${node.nodeType}`);

Note: I didn't bother to spend time to run example code due lack of e.g. xml-crypto version information, package.json and due example code not being immedialy runnable.

Note2: IF it turns out that C14N implementations of this project for example skip content of CDATA and because output of C14N is used to calculate checksum then there could be even more serious problem if signature is also verified with library which does the same skipping because then e.g. <isAdmin><![CDATA[false]]></isAdmin> could be changed by MITM to true without being spotted by receiving side's signature validation.

I believe the issue lies with the XML signing function, specifically with the canonicalization algorithm that might be skipping parts of CDATA. The signing function completes successfully, but when I try to validate the signature, it still fails. I've tried every canonicalization algorithm available.

The verification function works perfectly fine. I also tested verification using different frameworks, such as the Go library goxmldsig and the Chilkat Online Tools website. However, any XML containing CDATA tags always fails verification if it was signed using xml-crypto. I know this because I have an XML file with a CDATA tag signed by an unknown method, and when I verify it with xml-crypto , golang and website, it passes.

My package.json
"xml-crypto": "^2.1.5"

@srd90
Copy link

srd90 commented Aug 26, 2024

Just out of curiosity checking (and sharing) this quick test about CDATA handling against what spec says (comparing various tools).

tl;dr; CDATA content is handled similarly between various implementations (including xml-crypto's C14N implementation).


I.e. see how this algorithm works in

"http://www.w3.org/TR/2001/REC-xml-c14n-20010315": c14n.C14nCanonicalization,

NOTE: 0ed7ab2 == v6.0.0
NOTE2: you mentioned that you use ^2.1.5. AFAIK 2.x series is not maintained anymore so it doesn't matter if it has some bugs.


First lets see what C14N spec says.

https://www.w3.org/TR/2001/REC-xml-c14n-20010315 has example of input document with CDATA and corresponding canonnical form at chapter 3.4 Character Modifications and Character References.

Here is copy paste of input document from aforementioned spec:

<doc>
  <text>First line&#x0d;&#10;Second line</text>
  <value>&#x32;</value>
  <compute><![CDATA[value>"0" && value<"10" ?"valid":"error"]]></compute>
  <compute expr='value>"0" &amp;&amp; value&lt;"10" ?"valid":"error"'>valid</compute>
  <norm attr=' &apos;   &#x20;&#13;&#xa;&#9;   &apos; '/>
  <normNames attr='   A   &#x20;&#13;&#xa;&#9;   B   '/>
  <normId id=' &apos;   &#x20;&#13;&#xa;&#9;   &apos; '/>
</doc>

and here is copy paste of canonical form from that specification:

<doc>
  <text>First line&#xD;
Second line</text>
  <value>2</value>
  <compute>value&gt;"0" &amp;&amp; value&lt;"10" ?"valid":"error"</compute>
  <compute expr="value>&quot;0&quot; &amp;&amp; value&lt;&quot;10&quot; ?&quot;valid&quot;:&quot;error&quot;">valid</compute>
  <norm attr=" '    &#xD;&#xA;&#x9;   ' "></norm>
  <normNames attr="A &#xD;&#xA;&#x9; B"></normNames>
  <normId id="' &#xD;&#xA;&#x9; '"></normId>
</doc> 

We are especially interested how this line is canonicalized by various tools:

...
  <compute><![CDATA[value>"0" && value<"10" ?"valid":"error"]]></compute>
...

Lets see how https://tools.chilkat.io/XmlCanonicalize canonicalize aforementioned input document from C14N spec. Using C14N type C14N without comments. Ouput of chilkat is:

<doc>
   <text>First line&#xD;
Second line</text>
   <value>2</value>
   <compute>value&gt;"0" &amp;&amp; value&lt;"10" ?"valid":"error"</compute>
   <compute expr="value>&quot;0&quot; &amp;&amp; value&lt;&quot;10&quot; ?&quot;valid&quot;:&quot;error&quot;">valid</compute>
   <norm attr=" '    &#xD;&#xA;&#x9;   ' "></norm>
   <normNames attr="   A    &#xD;&#xA;&#x9;   B   "></normNames>
   <normId id=" '    &#xD;&#xA;&#x9;   ' "></normId>
</doc>

diff between canonicalized version from spec and chilkats output

-   <normNames attr="A &#xD;&#xA;&#x9; B"></normNames>
-   <normId id="' &#xD;&#xA;&#x9; '"></normId>
+   <normNames attr="   A    &#xD;&#xA;&#x9;   B   "></normNames>
+   <normId id=" '    &#xD;&#xA;&#x9;   ' "></normId>

dunno why normNames and normId are different but atleast CDATA was canonicalized same way.


Lets see how xmllint --c14n canonicalize input document from spec.

xmllint --c14n - <<EOF
<doc>
   <text>First line&#x0d;&#10;Second line</text>
   <value>&#x32;</value>
   <compute><![CDATA[value>"0" && value<"10" ?"valid":"error"]]></compute>
   <compute expr='value>"0" &amp;&amp; value&lt;"10" ?"valid":"error"'>valid</compute>
   <norm attr=' &apos;   &#x20;&#13;&#xa;&#9;   &apos; '/>
   <normNames attr='   A   &#x20;&#13;&#xa;&#9;   B   '/>
   <normId id=' &apos;   &#x20;&#13;&#xa;&#9;   &apos; '/>
</doc>
EOF

Result is

<doc>
   <text>First line&#xD;
Second line</text>
   <value>2</value>
   <compute>value&gt;"0" &amp;&amp; value&lt;"10" ?"valid":"error"</compute>
   <compute expr="value>&quot;0&quot; &amp;&amp; value&lt;&quot;10&quot; ?&quot;valid&quot;:&quot;error&quot;">valid</compute>
   <norm attr=" '    &#xD;&#xA;&#x9;   ' "></norm>
   <normNames attr="   A    &#xD;&#xA;&#x9;   B   "></normNames>
   <normId id=" '    &#xD;&#xA;&#x9;   ' "></normId>
</doc>

diff between canonizalized version from spec and xmllint's c14n implementation:

-   <normNames attr="A &#xD;&#xA;&#x9; B"></normNames>
-   <normId id="' &#xD;&#xA;&#x9; '"></normId>
+   <normNames attr="   A    &#xD;&#xA;&#x9;   B   "></normNames>
+   <normId id=" '    &#xD;&#xA;&#x9;   ' "></normId>

again...dunno why there is whitespace difference between what spec says and what - in this case - xmllint says but at least CDATA was canonicalized same way as spec says.


Finally lets see how xml-crypto 6.0.0 canonicalized input document from spec.

/*

git clone https://github.com/node-saml/xml-crypto.git
cd xml-crypto
git checkout v6.0.0
npm install
npm run build

put content of this file to e.g. dummy_c14n_test.js

*/
const C14nCanonicalization = require('./lib/c14n-canonicalization').C14nCanonicalization 
const DOMParser = require("@xmldom/xmldom").DOMParser
const inputDocumentFromSpec = `
<doc>
   <text>First line&#x0d;&#10;Second line</text>
   <value>&#x32;</value>
   <compute><![CDATA[value>"0" && value<"10" ?"valid":"error"]]></compute>
   <compute expr='value>"0" &amp;&amp; value&lt;"10" ?"valid":"error"'>valid</compute>
   <norm attr=' &apos;   &#x20;&#13;&#xa;&#9;   &apos; '/>
   <normNames attr='   A   &#x20;&#13;&#xa;&#9;   B   '/>
   <normId id=' &apos;   &#x20;&#13;&#xa;&#9;   &apos; '/>
</doc>
`
const documentElement= (new DOMParser()).parseFromString(inputDocumentFromSpec).documentElement

console.log( (new C14nCanonicalization()).process(documentElement, {}).toString() )

/*
end execute:
node dummy_c14n_test.js
*/

Output is:

<doc>
   <text>First line&#xD;
Second line</text>
   <value>2</value>
   <compute>value&gt;"0" &amp;&amp; value&lt;"10" ?"valid":"error"</compute>
   <compute expr="value>&quot;0&quot; &amp;&amp; value&lt;&quot;10&quot; ?&quot;valid&quot;:&quot;error&quot;">valid</compute>
   <norm attr=" '    &#xD;&#xA;&#x9;   ' "></norm>
   <normNames attr="   A    &#xD;&#xA;&#x9;   B   "></normNames>
   <normId id=" '    &#xD;&#xA;&#x9;   ' "></normId>
</doc>

and diff between canonicalized form from spec is similar with other two tools.

And whats important CDATA similar what spec says.

@srd90
Copy link

srd90 commented Aug 26, 2024

Now that I'm reading (but not trying to test / run) your example code again it seems that your code which uses ^2.1.5 version of xml-crypto lists only one transformation while signing.

xml-crypto 1.5.3 (and maybe newer ones) do not apply implicit transformation during signing. You have used just one transformation thus implicit c14n is not applied e.g. in this case (copied from issue description): transforms: ["http://www.w3.org/2000/09/xmldsig#enveloped-signature"].

Read more about this "non-symmetric behavior" from these two comments:

  1. Wrong Digest Value generated. Actual XML and Expected XML is not matching. Working from last three nights. #212 (comment)
  2. Wrong Digest Value generated. Actual XML and Expected XML is not matching. Working from last three nights. #212 (comment)

So try to add http://www.w3.org/TR/2001/REC-xml-c14n-20010315 to the list of transformations at your example code and test again.

@srd90
Copy link

srd90 commented Aug 27, 2024

You say at one of the commets that:

My package.json
"xml-crypto": "^2.1.5"

but at the code snippet at issue description you use various parameter names e.g. for SignedXml constructor which were not introduced before xml-crypto 4.0.0 (like privateKey which was at 2.1.5 signingKey).

Word of advice for the future: consider trying to replicate issue with same information that you provide for others.

Rest of this comment assumes that you are actually using 6.0.0


Here example is code snippet provided at issue description wrapped with extra stuff to enable easier replication/debugging:

/*

Related to https://github.com/node-saml/xml-crypto/issues/474

package.json
{
  "name": "foo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "xml-crypto": "^6.0.0"
  }
}

*/

// Wrapping example code from issue with stuff to make it runnable/debuggable
//
const SignedXml = require("xml-crypto").SignedXml;

// https://raw.githubusercontent.com/node-saml/xml-crypto/v2.1.5/test/static/client.pem
const pemPrivateKey = `
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL4vpoH3H3byehjj
7RAGxefGRATiq4mXtzc9Q91W7uT0DTaFEbjzVch9aGsNjmLs4QHsoZbuoUmi0st4
x5z9SQpTAKC/dW8muzacT3E7dJJYh03MAO6RiH4LG34VRTq1SQN6qDt2rCK85eG4
5NHI4jceptZNu6Zot1zyO5/PYuFpAgMBAAECgYAhspeyF3M/xB7WIixy1oBiXMLY
isESFAumgfhwU2LotkVRD6rgNl1QtMe3kCNWa9pCWQcYkxeI0IzA+JmFu2shVvoR
oL7eV4VCe1Af33z24E46+cY5grxNhHt/LyCnZKcitvCcrzXExUc5n6KngX0mMKgk
W7skZDwsnKzhyUV8wQJBAN2bQMeASQVOqdfqBdFgC/NPnKY2cuDi6h659QN1l+kg
X3ywdZ7KKftJo1G9l45SN9YpkyEd9zEO6PMFaufJvZUCQQDbtAWxk0i8BT3UTNWC
T/9bUQROPcGZagwwnRFByX7gpmfkf1ImIvbWVXSpX68/IjbjSkTw1nj/Yj1NwFZ0
nxeFAkEAzPhRpXVBlPgaXkvlz7AfvY+wW4hXHyyi0YK8XdPBi25XA5SPZiylQfjt
Z6iN6qSfYqYXoPT/c0/QJR+orvVJNQJBANhRPNXljVTK2GDCseoXd/ZiI5ohxg+W
UaA/1fDvQsRQM7TQA4NXI7BO/YmSk4rW1jIeOxjiIspY4MFAIh+7UL0CQFL6zTg6
wfeMlEZzvgqwCGoLuvTnqtvyg45z7pfcrg2cHdgCXIy9kErcjwGiu6BOevEA1qTW
Rk+bv0tknWvcz/s=
-----END PRIVATE KEY-----
`;

// https://raw.githubusercontent.com/node-saml/xml-crypto/v2.1.5/test/static/client_public.pem
const pemCertificate = `
-----BEGIN CERTIFICATE-----
MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAW
MRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEy
MzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqG
SIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPd
Vu7k9A02hRG481XIfWhrDY5i7OEB7KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9x
O3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8juf
z2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEU
MBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcN
AQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5
sT/txBnVJGziyO8DPYdu2fPMER8ajJfl
-----END CERTIFICATE-----
`;

const xmlRootName = "HeaderDocument";

// example document from issue report
const xmlContent = `
<?xml version="1.0" encoding="UTF-8"?>
<HeaderDocument>
	<Payload>
		<![CDATA[<test>data<test>]]>
	</Payload>
</HeaderDocument>
`;

// -------------------------------------------------
// Start example code from issue report:

const sig = new SignedXml({ privateKey: pemPrivateKey,publicCert: pemCertificate });
sig.addReference(
  {
  xpath: `//*[local-name(.)='${xmlRootName}']`,
  digestAlgorithm: "http://www.w3.org/2001/04/xmlenc#sha256",
  isEmptyUri: true,
  transforms: ["http://www.w3.org/2000/09/xmldsig#enveloped-signature"],
  }
);
sig.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
sig.canonicalizationAlgorithm = 'http://www.w3.org/2001/10/xml-exc-c14n#';
sig.computeSignature(xmlContent);

const xmlSignedContent = sig.getSignedXml();
const sig2 = new SignedXml({publicCert: pemCertificate});
const signature = sig.getSignatureXml();
sig2.loadSignature(signature);
const verify = sig2.checkSignature(xmlSignedContent);

// End example code from issue report
// -------------------------------------------------

console.log("-------------------------");
console.log(xmlSignedContent);
console.log("-------------------------");
console.log("Check signature = " + verify);

Output xmlSignedContent:

<?xml version="1.0" encoding="UTF-8"?>
<HeaderDocument>
	<Payload>
		<![CDATA[<test>data<test>]]>
	</Payload>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><DigestValue>fpYnSQR900fNoPES7LrTO9DC3h0A3YI/YRW1Qyy88V8=</DigestValue></Reference></SignedInfo><SignatureValue>KScOwudyPkYZ2gAlDC3nbFm75gFHHO39pckTVGxCf3jRG9RmFCGdPf2IyEQfCUXUzMxWhgK/9IQ0okSShQ+wKVNernCSduTIzWkOhlT0rwMwFMtTYZsm+V6Ogyy9YDUtOlaOtM9sVgsJMPuizGaPsLgQsjmnb2GLWtG8OzY+gTE=</SignatureValue><KeyInfo><X509Data><X509Certificate>MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAWMRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEyMzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPdVu7k9A02hRG481XIfWhrDY5i7OEB7KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9xO3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8jufz2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcNAQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5sT/txBnVJGziyO8DPYdu2fPMER8ajJfl</X509Certificate></X509Data></KeyInfo></Signature></HeaderDocument>

and script reports that signature is not valid (as expected)

When signed XML is pasted to https://tools.chilkat.io/xmlDsigVerify.cshtml it says that: "digest is invalid because the computed digest differs from the digest in the XML".


Same script as above but with excplicitly added C14N transformation in addition to enveloped transformation. I.e. diff to aforementioned script is:

-  transforms: ["http://www.w3.org/2000/09/xmldsig#enveloped-signature"],
+//
+// added http://www.w3.org/TR/2001/REC-xml-c14n-20010315 due reason
+// described at https://github.com/node-saml/xml-crypto/issues/474#issuecomment-2311181715
+//
+  transforms: [
+    "http://www.w3.org/2000/09/xmldsig#enveloped-signature",
+    "http://www.w3.org/TR/2001/REC-xml-c14n-20010315",
+  ],
/*

Related to https://github.com/node-saml/xml-crypto/issues/474

package.json
{
  "name": "foo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "xml-crypto": "^6.0.0"
  }
}

*/

// Wrapping example code from issue with stuff to make it runnable/debuggable
//
const SignedXml = require("xml-crypto").SignedXml;

// https://raw.githubusercontent.com/node-saml/xml-crypto/v2.1.5/test/static/client.pem
const pemPrivateKey = `
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL4vpoH3H3byehjj
7RAGxefGRATiq4mXtzc9Q91W7uT0DTaFEbjzVch9aGsNjmLs4QHsoZbuoUmi0st4
x5z9SQpTAKC/dW8muzacT3E7dJJYh03MAO6RiH4LG34VRTq1SQN6qDt2rCK85eG4
5NHI4jceptZNu6Zot1zyO5/PYuFpAgMBAAECgYAhspeyF3M/xB7WIixy1oBiXMLY
isESFAumgfhwU2LotkVRD6rgNl1QtMe3kCNWa9pCWQcYkxeI0IzA+JmFu2shVvoR
oL7eV4VCe1Af33z24E46+cY5grxNhHt/LyCnZKcitvCcrzXExUc5n6KngX0mMKgk
W7skZDwsnKzhyUV8wQJBAN2bQMeASQVOqdfqBdFgC/NPnKY2cuDi6h659QN1l+kg
X3ywdZ7KKftJo1G9l45SN9YpkyEd9zEO6PMFaufJvZUCQQDbtAWxk0i8BT3UTNWC
T/9bUQROPcGZagwwnRFByX7gpmfkf1ImIvbWVXSpX68/IjbjSkTw1nj/Yj1NwFZ0
nxeFAkEAzPhRpXVBlPgaXkvlz7AfvY+wW4hXHyyi0YK8XdPBi25XA5SPZiylQfjt
Z6iN6qSfYqYXoPT/c0/QJR+orvVJNQJBANhRPNXljVTK2GDCseoXd/ZiI5ohxg+W
UaA/1fDvQsRQM7TQA4NXI7BO/YmSk4rW1jIeOxjiIspY4MFAIh+7UL0CQFL6zTg6
wfeMlEZzvgqwCGoLuvTnqtvyg45z7pfcrg2cHdgCXIy9kErcjwGiu6BOevEA1qTW
Rk+bv0tknWvcz/s=
-----END PRIVATE KEY-----
`;

// https://raw.githubusercontent.com/node-saml/xml-crypto/v2.1.5/test/static/client_public.pem
const pemCertificate = `
-----BEGIN CERTIFICATE-----
MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAW
MRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEy
MzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqG
SIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPd
Vu7k9A02hRG481XIfWhrDY5i7OEB7KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9x
O3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8juf
z2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEU
MBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcN
AQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5
sT/txBnVJGziyO8DPYdu2fPMER8ajJfl
-----END CERTIFICATE-----
`;

const xmlRootName = "HeaderDocument";

// example document from issue report
const xmlContent = `
<?xml version="1.0" encoding="UTF-8"?>
<HeaderDocument>
	<Payload>
		<![CDATA[<test>data<test>]]>
	</Payload>
</HeaderDocument>
`;

// -------------------------------------------------
// Start example code from issue report:

const sig = new SignedXml({ privateKey: pemPrivateKey,publicCert: pemCertificate });
sig.addReference(
  {
  xpath: `//*[local-name(.)='${xmlRootName}']`,
  digestAlgorithm: "http://www.w3.org/2001/04/xmlenc#sha256",
  isEmptyUri: true,
//
// added http://www.w3.org/TR/2001/REC-xml-c14n-20010315 due reason
// described at https://github.com/node-saml/xml-crypto/issues/474#issuecomment-2311181715
//
  transforms: [
    "http://www.w3.org/2000/09/xmldsig#enveloped-signature",
    "http://www.w3.org/TR/2001/REC-xml-c14n-20010315",
  ],
  }
);
sig.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
sig.canonicalizationAlgorithm = 'http://www.w3.org/2001/10/xml-exc-c14n#';
sig.computeSignature(xmlContent);

const xmlSignedContent = sig.getSignedXml();
const sig2 = new SignedXml({publicCert: pemCertificate});
const signature = sig.getSignatureXml();
sig2.loadSignature(signature);
const verify = sig2.checkSignature(xmlSignedContent);

// End example code from issue report
// -------------------------------------------------

console.log("-------------------------");
console.log(xmlSignedContent);
console.log("-------------------------");
console.log("Check signature = " + verify);

Output xmlSignedContent:

<?xml version="1.0" encoding="UTF-8"?>
<HeaderDocument>
	<Payload>
		<![CDATA[<test>data<test>]]>
	</Payload>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><DigestValue>pppiemIj4Se2Xa6nB3eChKIyCL3CWC3qk/L/xF1vAQ4=</DigestValue></Reference></SignedInfo><SignatureValue>UiJxY52MZf+k4GUG3Dlb+sgKcPmP4KP7KpIDDrU5SzFeGzNjvFV26fRyoRRd/oAJTXn1EHbn0r/wDg9k+/muC6HE02mX+p2xUIBzJ8mgDA73hRINOSDBLl4GpAI/eZlJrb77SnNZWLoDnvJVJQEabxcuzjWMUZIhcw2OcnuHirE=</SignatureValue><KeyInfo><X509Data><X509Certificate>MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAWMRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEyMzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPdVu7k9A02hRG481XIfWhrDY5i7OEB7 KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9xO3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8jufz2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcNAQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5sT/txBnVJGziyO8DPYdu2fPMER8ajJfl</X509Certificate></X509Data></KeyInfo></Signature></HeaderDocument>

and script reports that signature is valid.

When signed XML is pasted to https://tools.chilkat.io/xmlDsigVerify.cshtml it says that "digest is valid".


However, any XML containing CDATA tags always fails verification if it was signed using xml-crypto.

IMHO based on evidence above root cause is not CDATA but issue described at these comments

  1. Wrong Digest Value generated. Actual XML and Expected XML is not matching. Working from last three nights. #212 (comment)
  2. Wrong Digest Value generated. Actual XML and Expected XML is not matching. Working from last three nights. #212 (comment)

@Alexiserist
Copy link
Author

You say at one of the commets that:

My package.json
"xml-crypto": "^2.1.5"

but at the code snippet at issue description you use various parameter names e.g. for SignedXml constructor which were not introduced before xml-crypto 4.0.0 (like privateKey which was at 2.1.5 signingKey).

Word of advice for the future: consider trying to replicate issue with same information that you provide for others.

Rest of this comment assumes that you are actually using 6.0.0

Here example is code snippet provided at issue description wrapped with extra stuff to enable easier replication/debugging:

/*

Related to https://github.com/node-saml/xml-crypto/issues/474

package.json
{
  "name": "foo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "xml-crypto": "^6.0.0"
  }
}

*/

// Wrapping example code from issue with stuff to make it runnable/debuggable
//
const SignedXml = require("xml-crypto").SignedXml;

// https://raw.githubusercontent.com/node-saml/xml-crypto/v2.1.5/test/static/client.pem
const pemPrivateKey = `
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL4vpoH3H3byehjj
7RAGxefGRATiq4mXtzc9Q91W7uT0DTaFEbjzVch9aGsNjmLs4QHsoZbuoUmi0st4
x5z9SQpTAKC/dW8muzacT3E7dJJYh03MAO6RiH4LG34VRTq1SQN6qDt2rCK85eG4
5NHI4jceptZNu6Zot1zyO5/PYuFpAgMBAAECgYAhspeyF3M/xB7WIixy1oBiXMLY
isESFAumgfhwU2LotkVRD6rgNl1QtMe3kCNWa9pCWQcYkxeI0IzA+JmFu2shVvoR
oL7eV4VCe1Af33z24E46+cY5grxNhHt/LyCnZKcitvCcrzXExUc5n6KngX0mMKgk
W7skZDwsnKzhyUV8wQJBAN2bQMeASQVOqdfqBdFgC/NPnKY2cuDi6h659QN1l+kg
X3ywdZ7KKftJo1G9l45SN9YpkyEd9zEO6PMFaufJvZUCQQDbtAWxk0i8BT3UTNWC
T/9bUQROPcGZagwwnRFByX7gpmfkf1ImIvbWVXSpX68/IjbjSkTw1nj/Yj1NwFZ0
nxeFAkEAzPhRpXVBlPgaXkvlz7AfvY+wW4hXHyyi0YK8XdPBi25XA5SPZiylQfjt
Z6iN6qSfYqYXoPT/c0/QJR+orvVJNQJBANhRPNXljVTK2GDCseoXd/ZiI5ohxg+W
UaA/1fDvQsRQM7TQA4NXI7BO/YmSk4rW1jIeOxjiIspY4MFAIh+7UL0CQFL6zTg6
wfeMlEZzvgqwCGoLuvTnqtvyg45z7pfcrg2cHdgCXIy9kErcjwGiu6BOevEA1qTW
Rk+bv0tknWvcz/s=
-----END PRIVATE KEY-----
`;

// https://raw.githubusercontent.com/node-saml/xml-crypto/v2.1.5/test/static/client_public.pem
const pemCertificate = `
-----BEGIN CERTIFICATE-----
MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAW
MRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEy
MzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqG
SIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPd
Vu7k9A02hRG481XIfWhrDY5i7OEB7KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9x
O3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8juf
z2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEU
MBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcN
AQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5
sT/txBnVJGziyO8DPYdu2fPMER8ajJfl
-----END CERTIFICATE-----
`;

const xmlRootName = "HeaderDocument";

// example document from issue report
const xmlContent = `
<?xml version="1.0" encoding="UTF-8"?>
<HeaderDocument>
	<Payload>
		<![CDATA[<test>data<test>]]>
	</Payload>
</HeaderDocument>
`;

// -------------------------------------------------
// Start example code from issue report:

const sig = new SignedXml({ privateKey: pemPrivateKey,publicCert: pemCertificate });
sig.addReference(
  {
  xpath: `//*[local-name(.)='${xmlRootName}']`,
  digestAlgorithm: "http://www.w3.org/2001/04/xmlenc#sha256",
  isEmptyUri: true,
  transforms: ["http://www.w3.org/2000/09/xmldsig#enveloped-signature"],
  }
);
sig.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
sig.canonicalizationAlgorithm = 'http://www.w3.org/2001/10/xml-exc-c14n#';
sig.computeSignature(xmlContent);

const xmlSignedContent = sig.getSignedXml();
const sig2 = new SignedXml({publicCert: pemCertificate});
const signature = sig.getSignatureXml();
sig2.loadSignature(signature);
const verify = sig2.checkSignature(xmlSignedContent);

// End example code from issue report
// -------------------------------------------------

console.log("-------------------------");
console.log(xmlSignedContent);
console.log("-------------------------");
console.log("Check signature = " + verify);

Output xmlSignedContent:

<?xml version="1.0" encoding="UTF-8"?>
<HeaderDocument>
	<Payload>
		<![CDATA[<test>data<test>]]>
	</Payload>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><DigestValue>fpYnSQR900fNoPES7LrTO9DC3h0A3YI/YRW1Qyy88V8=</DigestValue></Reference></SignedInfo><SignatureValue>KScOwudyPkYZ2gAlDC3nbFm75gFHHO39pckTVGxCf3jRG9RmFCGdPf2IyEQfCUXUzMxWhgK/9IQ0okSShQ+wKVNernCSduTIzWkOhlT0rwMwFMtTYZsm+V6Ogyy9YDUtOlaOtM9sVgsJMPuizGaPsLgQsjmnb2GLWtG8OzY+gTE=</SignatureValue><KeyInfo><X509Data><X509Certificate>MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAWMRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEyMzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPdVu7k9A02hRG481XIfWhrDY5i7OEB7KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9xO3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8jufz2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcNAQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5sT/txBnVJGziyO8DPYdu2fPMER8ajJfl</X509Certificate></X509Data></KeyInfo></Signature></HeaderDocument>

and script reports that signature is not valid (as expected)

When signed XML is pasted to https://tools.chilkat.io/xmlDsigVerify.cshtml it says that: "digest is invalid because the computed digest differs from the digest in the XML".

Same script as above but with excplicitly added C14N transformation in addition to enveloped transformation. I.e. diff to aforementioned script is:

-  transforms: ["http://www.w3.org/2000/09/xmldsig#enveloped-signature"],
+//
+// added http://www.w3.org/TR/2001/REC-xml-c14n-20010315 due reason
+// described at https://github.com/node-saml/xml-crypto/issues/474#issuecomment-2311181715
+//
+  transforms: [
+    "http://www.w3.org/2000/09/xmldsig#enveloped-signature",
+    "http://www.w3.org/TR/2001/REC-xml-c14n-20010315",
+  ],
/*

Related to https://github.com/node-saml/xml-crypto/issues/474

package.json
{
  "name": "foo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "xml-crypto": "^6.0.0"
  }
}

*/

// Wrapping example code from issue with stuff to make it runnable/debuggable
//
const SignedXml = require("xml-crypto").SignedXml;

// https://raw.githubusercontent.com/node-saml/xml-crypto/v2.1.5/test/static/client.pem
const pemPrivateKey = `
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL4vpoH3H3byehjj
7RAGxefGRATiq4mXtzc9Q91W7uT0DTaFEbjzVch9aGsNjmLs4QHsoZbuoUmi0st4
x5z9SQpTAKC/dW8muzacT3E7dJJYh03MAO6RiH4LG34VRTq1SQN6qDt2rCK85eG4
5NHI4jceptZNu6Zot1zyO5/PYuFpAgMBAAECgYAhspeyF3M/xB7WIixy1oBiXMLY
isESFAumgfhwU2LotkVRD6rgNl1QtMe3kCNWa9pCWQcYkxeI0IzA+JmFu2shVvoR
oL7eV4VCe1Af33z24E46+cY5grxNhHt/LyCnZKcitvCcrzXExUc5n6KngX0mMKgk
W7skZDwsnKzhyUV8wQJBAN2bQMeASQVOqdfqBdFgC/NPnKY2cuDi6h659QN1l+kg
X3ywdZ7KKftJo1G9l45SN9YpkyEd9zEO6PMFaufJvZUCQQDbtAWxk0i8BT3UTNWC
T/9bUQROPcGZagwwnRFByX7gpmfkf1ImIvbWVXSpX68/IjbjSkTw1nj/Yj1NwFZ0
nxeFAkEAzPhRpXVBlPgaXkvlz7AfvY+wW4hXHyyi0YK8XdPBi25XA5SPZiylQfjt
Z6iN6qSfYqYXoPT/c0/QJR+orvVJNQJBANhRPNXljVTK2GDCseoXd/ZiI5ohxg+W
UaA/1fDvQsRQM7TQA4NXI7BO/YmSk4rW1jIeOxjiIspY4MFAIh+7UL0CQFL6zTg6
wfeMlEZzvgqwCGoLuvTnqtvyg45z7pfcrg2cHdgCXIy9kErcjwGiu6BOevEA1qTW
Rk+bv0tknWvcz/s=
-----END PRIVATE KEY-----
`;

// https://raw.githubusercontent.com/node-saml/xml-crypto/v2.1.5/test/static/client_public.pem
const pemCertificate = `
-----BEGIN CERTIFICATE-----
MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAW
MRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEy
MzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqG
SIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPd
Vu7k9A02hRG481XIfWhrDY5i7OEB7KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9x
O3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8juf
z2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEU
MBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcN
AQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5
sT/txBnVJGziyO8DPYdu2fPMER8ajJfl
-----END CERTIFICATE-----
`;

const xmlRootName = "HeaderDocument";

// example document from issue report
const xmlContent = `
<?xml version="1.0" encoding="UTF-8"?>
<HeaderDocument>
	<Payload>
		<![CDATA[<test>data<test>]]>
	</Payload>
</HeaderDocument>
`;

// -------------------------------------------------
// Start example code from issue report:

const sig = new SignedXml({ privateKey: pemPrivateKey,publicCert: pemCertificate });
sig.addReference(
  {
  xpath: `//*[local-name(.)='${xmlRootName}']`,
  digestAlgorithm: "http://www.w3.org/2001/04/xmlenc#sha256",
  isEmptyUri: true,
//
// added http://www.w3.org/TR/2001/REC-xml-c14n-20010315 due reason
// described at https://github.com/node-saml/xml-crypto/issues/474#issuecomment-2311181715
//
  transforms: [
    "http://www.w3.org/2000/09/xmldsig#enveloped-signature",
    "http://www.w3.org/TR/2001/REC-xml-c14n-20010315",
  ],
  }
);
sig.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
sig.canonicalizationAlgorithm = 'http://www.w3.org/2001/10/xml-exc-c14n#';
sig.computeSignature(xmlContent);

const xmlSignedContent = sig.getSignedXml();
const sig2 = new SignedXml({publicCert: pemCertificate});
const signature = sig.getSignatureXml();
sig2.loadSignature(signature);
const verify = sig2.checkSignature(xmlSignedContent);

// End example code from issue report
// -------------------------------------------------

console.log("-------------------------");
console.log(xmlSignedContent);
console.log("-------------------------");
console.log("Check signature = " + verify);

Output xmlSignedContent:

<?xml version="1.0" encoding="UTF-8"?>
<HeaderDocument>
	<Payload>
		<![CDATA[<test>data<test>]]>
	</Payload>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><DigestValue>pppiemIj4Se2Xa6nB3eChKIyCL3CWC3qk/L/xF1vAQ4=</DigestValue></Reference></SignedInfo><SignatureValue>UiJxY52MZf+k4GUG3Dlb+sgKcPmP4KP7KpIDDrU5SzFeGzNjvFV26fRyoRRd/oAJTXn1EHbn0r/wDg9k+/muC6HE02mX+p2xUIBzJ8mgDA73hRINOSDBLl4GpAI/eZlJrb77SnNZWLoDnvJVJQEabxcuzjWMUZIhcw2OcnuHirE=</SignatureValue><KeyInfo><X509Data><X509Certificate>MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAWMRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEyMzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPdVu7k9A02hRG481XIfWhrDY5i7OEB7 KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9xO3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8jufz2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcNAQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5sT/txBnVJGziyO8DPYdu2fPMER8ajJfl</X509Certificate></X509Data></KeyInfo></Signature></HeaderDocument>

and script reports that signature is valid.

When signed XML is pasted to https://tools.chilkat.io/xmlDsigVerify.cshtml it says that "digest is valid".

However, any XML containing CDATA tags always fails verification if it was signed using xml-crypto.

IMHO based on evidence above root cause is not CDATA but issue described at these comments

  1. Wrong Digest Value generated. Actual XML and Expected XML is not matching. Working from last three nights. #212 (comment)
  2. Wrong Digest Value generated. Actual XML and Expected XML is not matching. Working from last three nights. #212 (comment)

This works! Thanks a lot for all the information.
To handle CDATA sections, try adding this to a transform -> http://www.w3.org/TR/2001/REC-xml-c14n-20010315

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants