Skip to content

Commit

Permalink
+ use existingPrefixes while lookup for references
Browse files Browse the repository at this point in the history
+ appropriate test
  • Loading branch information
paulish committed Oct 19, 2020
1 parent 3d9db71 commit 4e8d41e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
16 changes: 12 additions & 4 deletions lib/signed-xml.js
Expand Up @@ -211,10 +211,11 @@ function HMACSHA1() {
*
* @param {object} doc - Usually a product from `new DOMParser().parseFromString()`
* @param {string} docSubsetXpath - xpath query to get document subset being canonicalized
* @param {object} namespaceResolver - xpath namespace resolver
* @returns {Array} i.e. [{prefix: "saml", namespaceURI: "urn:oasis:names:tc:SAML:2.0:assertion"}]
*/
function findAncestorNs(doc, docSubsetXpath){
var docSubset = xpath.select(docSubsetXpath, doc);
function findAncestorNs(doc, docSubsetXpath, namespaceResolver){
var docSubset = xpath.selectWithResolver(docSubsetXpath, doc, namespaceResolver);

if(!Array.isArray(docSubset) || docSubset.length < 1){
return [];
Expand Down Expand Up @@ -442,7 +443,7 @@ SignedXml.prototype.getCanonReferenceXml = function(doc, ref, node) {
* Search for ancestor namespaces before canonicalization.
*/
if(Array.isArray(ref.transforms)){
ref.ancestorNamespaces = findAncestorNs(doc, ref.xpath)
ref.ancestorNamespaces = findAncestorNs(doc, ref.xpath, this.namespaceResolver)
}

var c14nOptions = {
Expand Down Expand Up @@ -732,6 +733,13 @@ SignedXml.prototype.computeSignature = function(xml, opts, callback) {
attrs = opts.attrs || {};
location = opts.location || {};
var existingPrefixes = opts.existingPrefixes || {};

this.namespaceResolver = {
lookupNamespaceURI: function(prefix) {
return existingPrefixes[prefix];
}
}

// defaults to the root node
location.reference = location.reference || "/*";
// defaults to append action
Expand Down Expand Up @@ -874,7 +882,7 @@ SignedXml.prototype.createReferences = function(doc, prefix) {
if (!this.references.hasOwnProperty(n)) continue;

var ref = this.references[n]
, nodes = xpath.select(ref.xpath, doc)
, nodes = xpath.selectWithResolver(ref.xpath, doc, this.namespaceResolver)

if (nodes.length==0) {
throw new Error('the following xpath cannot be signed because it was not found: ' + ref.xpath)
Expand Down
25 changes: 25 additions & 0 deletions test/signature-unit-tests.js
Expand Up @@ -13,6 +13,11 @@ module.exports = {
test.done();
},

"signer adds references with namespaces": function(test) {
verifyReferenceNS(test);
test.done();
},

"signer does not duplicate existing id attributes": function (test) {
verifyDoesNotDuplicateIdAttributes(test, null, "")
verifyDoesNotDuplicateIdAttributes(test, "wssecurity", "wsu:")
Expand Down Expand Up @@ -778,6 +783,26 @@ function verifyAddsAttrs(test) {
test.strictEqual(signatureNode.getAttribute("xmlns"), "http://www.w3.org/2000/09/xmldsig#", "xmlns attribute is not equal to the expected value: \"http://www.w3.org/2000/09/xmldsig#\"")
}

function verifyReferenceNS(test) {
var xml = "<root xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"><name wsu:Id=\"_1\">xml-crypto</name><repository wsu:Id=\"_2\">github</repository></root>"
var sig = new SignedXml("wssecurity")

sig.signingKey = fs.readFileSync("./test/static/client.pem")

sig.addReference("//*[@wsu:Id]")

sig.computeSignature(xml, {
existingPrefixes: {
wsu: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
}
})

var signedXml = sig.getSignatureXml()
var doc = new dom().parseFromString(signedXml)
var references = select("//*[local-name(.)='Reference']", doc)
test.equal(references.length, 2)
}

function nodeExists(test, doc, xpath) {
if (!doc && !xpath) return
var node = select(xpath, doc)
Expand Down

0 comments on commit 4e8d41e

Please sign in to comment.