From 126449e33dd9d123c66343e8659fbeba451ea90f Mon Sep 17 00:00:00 2001 From: r03 Date: Sat, 2 Feb 2019 23:34:13 +0100 Subject: [PATCH 1/3] Fix for https://github.com/yaronn/xml-crypto/issues/170 --- README.md | 1 + lib/signed-xml.js | 21 +++++++++++++----- package-lock.json | 2 +- package.json | 2 +- test/signature-unit-tests.js | 43 ++++++++++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e4aafa72..f806e017 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,7 @@ To sign xml documents: - `prefix` - adds this value as a prefix for the generated signature tags - `attrs` - a hash of attributes and values `attrName: value` to add to the signature root node - `location` - customize the location of the signature, pass an object with a `reference` key which should contain a XPath expression to a reference node, an `action` key which should contain one of the following values: `append`, `prepend`, `before`, `after` + - `existingPrefixes` - A hash of prefixes and namespaces `prefix: namespace` that shouldn't be in the signature because they already exist in the xml - `getSignedXml()` - returns the original xml document with the signature in it, **must be called only after `computeSignature`** - `getSignatureXml()` - returns just the signature part, **must be called only after `computeSignature`** - `getOriginalXmlWithIds()` - returns the original xml with Id attributes added on relevant elements (required for validation), **must be called only after `computeSignature`** diff --git a/lib/signed-xml.js b/lib/signed-xml.js index 4ce40ccf..7988d656 100644 --- a/lib/signed-xml.js +++ b/lib/signed-xml.js @@ -637,6 +637,7 @@ SignedXml.prototype.addReference = function(xpath, transforms, digestAlgorithm, * - `prefix` {String} Adds a prefix for the generated signature tags * - `attrs` {Object} A hash of attributes and values `attrName: value` to add to the signature root node * - `location` {{ reference: String, action: String }} + * - `existingPrefixes` {Object} A hash of prefixes and namespaces `prefix: namespace` already in the xml * An object with a `reference` key which should * contain a XPath expression, an `action` key which * should contain one of the following values: @@ -658,6 +659,7 @@ SignedXml.prototype.computeSignature = function(xml, opts) { prefix = opts.prefix; attrs = opts.attrs || {}; location = opts.location || {}; + existingPrefixes = opts.existingPrefixes || {}; // defaults to the root node location.reference = location.reference || "/*"; // defaults to append action @@ -695,7 +697,16 @@ SignedXml.prototype.computeSignature = function(xml, opts) { this.originalXmlWithIds = doc.toString() - var signatureDoc = new Dom().parseFromString(this.signatureXml) + var existingPrefixesString = "" + Object.keys(existingPrefixes).forEach(function(key) { + existingPrefixesString += "xmlns:" + key + '="' + existingPrefixes[key] + '" ' + }); + + // A trick to remove the namespaces that already exist in the xml + // This only works if the prefix and namespace match with those in te xml + var dummySignatureWrapper = "" + this.signatureXml + "" + var xml = new Dom().parseFromString(dummySignatureWrapper) + var signatureDoc = xml.documentElement.firstChild; var referenceNode = xpath.select(location.reference, doc); @@ -706,13 +717,13 @@ SignedXml.prototype.computeSignature = function(xml, opts) { referenceNode = referenceNode[0]; if (location.action === "append") { - referenceNode.appendChild(signatureDoc.documentElement); + referenceNode.appendChild(signatureDoc); } else if (location.action === "prepend") { - referenceNode.insertBefore(signatureDoc.documentElement, referenceNode.firstChild); + referenceNode.insertBefore(signatureDoc, referenceNode.firstChild); } else if (location.action === "before") { - referenceNode.parentNode.insertBefore(signatureDoc.documentElement, referenceNode); + referenceNode.parentNode.insertBefore(signatureDoc, referenceNode); } else if (location.action === "after") { - referenceNode.parentNode.insertBefore(signatureDoc.documentElement, referenceNode.nextSibling); + referenceNode.parentNode.insertBefore(signatureDoc, referenceNode.nextSibling); } this.signedXml = doc.toString() diff --git a/package-lock.json b/package-lock.json index c036f448..48fbebc2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "xml-crypto", - "version": "1.1.1", + "version": "1.1.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 45936847..1f11ed44 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xml-crypto", - "version": "1.1.1", + "version": "1.1.2", "description": "Xml digital signature and encryption library for Node.js", "engines": { "node": ">=0.4.0" diff --git a/test/signature-unit-tests.js b/test/signature-unit-tests.js index dff41c29..5cb39f4c 100644 --- a/test/signature-unit-tests.js +++ b/test/signature-unit-tests.js @@ -539,6 +539,49 @@ module.exports = { test.ok(!(err instanceof TypeError)); } test.done(); + }, + + "signer adds existing prefixes": function(test) { + function AssertionKeyInfo(assertionId) { + this.getKeyInfo = function(key, prefix) { + return ` + ${assertionId} + `; + }; + } + + var xml = + ` + + + + + + ` + + var sig = new SignedXml(); + sig.keyInfoProvider = new AssertionKeyInfo( + "_81d5fba5c807be9e9cf60c58566349b1" + ); + sig.signingKey = fs.readFileSync("./test/static/client.pem"); + sig.computeSignature(xml, { + prefix: "ds", + location: { + reference: "//Assertion", + action: "after" + }, + existingPrefixes: { + wsse: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", + wsu: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" + } + }); + result = sig.getSignedXml(); + test.equal((result.match(/xmlns:wsu=/g) || []).length, 1) + test.equal((result.match(/xmlns:wsse=/g) || []).length, 1) + test.done(); } } From 19e211de94160e704194e19b74f4acc39354dcff Mon Sep 17 00:00:00 2001 From: r03 Date: Sun, 3 Feb 2019 19:24:25 +0100 Subject: [PATCH 2/3] travis: more recent node version --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e5ad3c2b..a94ccc91 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,8 @@ sudo: false language: node_js node_js: - - "0.12" - - "0.10" + - "8.15.0" + - "10.15.1" before_script: - npm install From 84c373647c4bb03737250f2e5c0eeb48bd28bbd7 Mon Sep 17 00:00:00 2001 From: r03 Date: Thu, 21 Feb 2019 10:38:16 +0100 Subject: [PATCH 3/3] I forgot to reset the travis file --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a94ccc91..e5ad3c2b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,8 @@ sudo: false language: node_js node_js: - - "8.15.0" - - "10.15.1" + - "0.12" + - "0.10" before_script: - npm install