From 02b211f5f3314991f3d3b907b39a1cc9af5d5125 Mon Sep 17 00:00:00 2001 From: Robert Kawecki Date: Wed, 18 Dec 2019 12:25:17 +0100 Subject: [PATCH 1/2] Prevent the enveloped signature transform from eating up nested signatures This change fixes a case where an overly-general XPath expression would find all instances of ds:Signature nodes wherever they appeared, which would make nested signing impossible. Nested signing, where some node inside the document is signed, and then the entire document also gets a signature which includes the node's signature, is commonly used with SAML, where the Assertion is signed first, and then the Response (root node) that contains the Assertion must also be signed. This bug was causing the contained Signature to be stripped, resulting in invalid digest values. --- src/xml/transforms/enveloped_signature.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xml/transforms/enveloped_signature.ts b/src/xml/transforms/enveloped_signature.ts index 5126440..ea3dd50 100644 --- a/src/xml/transforms/enveloped_signature.ts +++ b/src/xml/transforms/enveloped_signature.ts @@ -18,7 +18,7 @@ export class XmlDsigEnvelopedSignatureTransform extends Transform { throw new XmlError(XE.PARAM_REQUIRED, "innerXml"); } - const signature = Select(this.innerXml, ".//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']")[0]; + const signature = Select(this.innerXml, "./*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']")[0]; if (signature) { signature.parentNode!.removeChild(signature); } From 99ef05627dc7174827afa4c9ec600c42dc5071d6 Mon Sep 17 00:00:00 2001 From: Robert Kawecki Date: Wed, 18 Dec 2019 12:36:58 +0100 Subject: [PATCH 2/2] Add a regression test for enveloped transform with nested Signature --- test/scripts/transforms.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/scripts/transforms.js b/test/scripts/transforms.js index 6cf1756..a730bfd 100644 --- a/test/scripts/transforms.js +++ b/test/scripts/transforms.js @@ -178,6 +178,17 @@ describe("Transforms", () => { assert.equal(new XMLSerializer().serializeToString(out), ""); }); + it("GetOutput with nested signature should leave it alone", () => { + let transform = new xmldsig.XmlDsigEnvelopedSignatureTransform(); + let node = xmldsig.Parse(``).documentElement; + + transform.LoadInnerXml(node); + + let out = transform.GetOutput(); + + assert.equal(new XMLSerializer().serializeToString(out), ``); + }); + }) }); \ No newline at end of file