diff --git a/lib/signed-xml.js b/lib/signed-xml.js index 18e3d369..57b3fad2 100644 --- a/lib/signed-xml.js +++ b/lib/signed-xml.js @@ -295,12 +295,34 @@ SignedXml.prototype.validateReferences = function(doc) { ref.uri + " but could not find such element in the xml") return false } - var canonXml = this.getCanonXml(ref.transforms, elem[0], { inclusiveNamespacesPrefixList: ref.inclusiveNamespacesPrefixList }); - var hash = this.findHashAlgorithm(ref.digestAlgorithm) - var digest = hash.getHash(canonXml) + var canonXml = this.getCanonXml(ref.transforms, elem[0], { inclusiveNamespacesPrefixList: ref.inclusiveNamespacesPrefixList }); + var hash = this.findHashAlgorithm(ref.digestAlgorithm); + var digest = hash.getHash(canonXml); - if (digest!=ref.digestValue) { + if (digest!=ref.digestValue) { + if (ref.inclusiveNamespacesPrefixList) { + // fallback: apply InclusiveNamespaces workaround (https://github.com/yaronn/xml-crypto/issues/72) + var prefixList = ref.inclusiveNamespacesPrefixList instanceof Array ? ref.inclusiveNamespacesPrefixList : ref.inclusiveNamespacesPrefixList.split(' '); + var supported_definitions = { + 'xs': 'http://www.w3.org/2001/XMLSchema', + 'xsi': 'http://www.w3.org/2001/XMLSchema-instance', + 'saml': 'urn:oasis:names:tc:SAML:2.0:assertion' + } + + prefixList.forEach(function (prefix) { + if (supported_definitions[prefix]) { + elem[0].setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' + prefix, supported_definitions[prefix]); + } + }); + + canonXml = this.getCanonXml(ref.transforms, elem[0], { inclusiveNamespacesPrefixList: ref.inclusiveNamespacesPrefixList }); + digest = hash.getHash(canonXml); + if (digest === ref.digestValue) { + return true; + } + } + this.validationErrors.push("invalid signature: for uri " + ref.uri + " calculated digest is " + digest + " but the xml to validate supplies digest " + ref.digestValue + ". XML: [[" + this.signedXml + "]]. Cannon XML: [[" + canonXml + "]]"); diff --git a/lib/utils.js b/lib/utils.js index da8d2d3c..265ae6fa 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -19,6 +19,7 @@ function findFirst(doc, xpath) { } function findChilds(node, localName, namespace) { + node = node.documentElement || node; var res = [] for (var i = 0; i