xml-crypto
Advanced tools
Comparing version 1.4.1 to 1.5.0
@@ -336,3 +336,7 @@ var xpath = require('xpath') | ||
SignedXml.prototype.checkSignature = function(xml) { | ||
SignedXml.prototype.checkSignature = function(xml, callback) { | ||
if (callback != null && typeof callback !== 'function') { | ||
throw new Error("Last paramater must be a callback function") | ||
} | ||
this.validationErrors = [] | ||
@@ -342,7 +346,21 @@ this.signedXml = xml | ||
if (!this.keyInfoProvider) { | ||
throw new Error("cannot validate signature since no key info resolver was provided") | ||
var err = new Error("cannot validate signature since no key info resolver was provided") | ||
if (!callback) { | ||
throw err | ||
} else { | ||
callback(err) | ||
return | ||
} | ||
} | ||
this.signingKey = this.keyInfoProvider.getKey(this.keyInfo) | ||
if (!this.signingKey) throw new Error("key info provider could not resolve key info " + this.keyInfo) | ||
if (!this.signingKey) { | ||
var err = new Error("key info provider could not resolve key info " + this.keyInfo) | ||
if (!callback) { | ||
throw err | ||
} else { | ||
callback(err) | ||
return | ||
} | ||
} | ||
@@ -352,10 +370,28 @@ var doc = new Dom().parseFromString(xml) | ||
if (!this.validateReferences(doc)) { | ||
return false; | ||
if (!callback) { | ||
return false; | ||
} else { | ||
callback(new Error('Could not validate references')) | ||
return | ||
} | ||
} | ||
if (!this.validateSignatureValue(doc)) { | ||
return false; | ||
if (!callback) { | ||
//Syncronous flow | ||
if (!this.validateSignatureValue(doc)) { | ||
return false | ||
} | ||
return true | ||
} else { | ||
//Asyncronous flow | ||
this.validateSignatureValue(doc, function (err, isValidSignature) { | ||
if (err) { | ||
this.validationErrors.push("invalid signature: the signature value " + | ||
this.signatureValue + " is incorrect") | ||
callback(err) | ||
} else { | ||
callback(null, isValidSignature) | ||
} | ||
}) | ||
} | ||
return true | ||
} | ||
@@ -405,7 +441,7 @@ | ||
SignedXml.prototype.validateSignatureValue = function(doc) { | ||
SignedXml.prototype.validateSignatureValue = function(doc, callback) { | ||
var signedInfoCanon = this.getCanonSignedInfoXml(doc) | ||
var signer = this.findSignatureAlgorithm(this.signatureAlgorithm) | ||
var res = signer.verifySignature(signedInfoCanon, this.signingKey, this.signatureValue) | ||
if (!res) this.validationErrors.push("invalid signature: the signature value " + | ||
var res = signer.verifySignature(signedInfoCanon, this.signingKey, this.signatureValue, callback) | ||
if (!res && !callback) this.validationErrors.push("invalid signature: the signature value " + | ||
this.signatureValue + " is incorrect") | ||
@@ -415,6 +451,6 @@ return res | ||
SignedXml.prototype.calculateSignatureValue = function(doc) { | ||
SignedXml.prototype.calculateSignatureValue = function(doc, callback) { | ||
var signedInfoCanon = this.getCanonSignedInfoXml(doc) | ||
var signer = this.findSignatureAlgorithm(this.signatureAlgorithm) | ||
this.signatureValue = signer.getSignature(signedInfoCanon, this.signingKey) | ||
this.signatureValue = signer.getSignature(signedInfoCanon, this.signingKey, callback) | ||
} | ||
@@ -662,3 +698,11 @@ | ||
*/ | ||
SignedXml.prototype.computeSignature = function(xml, opts) { | ||
SignedXml.prototype.computeSignature = function(xml, opts, callback) { | ||
if (typeof opts === 'function' && callback == null) { | ||
callback = opts | ||
} | ||
if (callback != null && typeof callback !== 'function') { | ||
throw new Error("Last paramater must be a callback function") | ||
} | ||
var doc = new Dom().parseFromString(xml), | ||
@@ -685,4 +729,10 @@ xmlNsAttr = "xmlns", | ||
if (validActions.indexOf(location.action) === -1) { | ||
throw new Error("location.action option has an invalid action: " + location.action + | ||
", must be any of the following values: " + validActions.join(", ")); | ||
var err = new Error("location.action option has an invalid action: " + location.action + | ||
", must be any of the following values: " + validActions.join(", ")); | ||
if (!callback) { | ||
throw err; | ||
} else { | ||
callback(err, null) | ||
return | ||
} | ||
} | ||
@@ -729,3 +779,9 @@ | ||
if (!referenceNode || referenceNode.length === 0) { | ||
throw new Error("the following xpath cannot be used because it was not found: " + location.reference); | ||
var err = new Error("the following xpath cannot be used because it was not found: " + location.reference); | ||
if (!callback) { | ||
throw err | ||
} else { | ||
callback(err, null) | ||
return | ||
} | ||
} | ||
@@ -746,12 +802,35 @@ | ||
this.signatureNode = signatureDoc | ||
this.calculateSignatureValue(doc) | ||
var signedInfoNode = utils.findChilds(this.signatureNode, "SignedInfo") | ||
if (signedInfoNode.length==0) throw new Error("could not find SignedInfo element in the message") | ||
if (signedInfoNode.length == 0) { | ||
var err = new Error("could not find SignedInfo element in the message") | ||
if (!callback) { | ||
throw err | ||
} else { | ||
callback(err) | ||
return | ||
} | ||
} | ||
signedInfoNode = signedInfoNode[0]; | ||
signatureDoc.insertBefore(this.createSignature(prefix), signedInfoNode.nextSibling) | ||
this.signatureXml = signatureDoc.toString() | ||
this.signedXml = doc.toString() | ||
if (!callback) { | ||
//Synchronous flow | ||
this.calculateSignatureValue(doc) | ||
signatureDoc.insertBefore(this.createSignature(prefix), signedInfoNode.nextSibling) | ||
this.signatureXml = signatureDoc.toString() | ||
this.signedXml = doc.toString() | ||
} else { | ||
var self = this | ||
//Asynchronous flow | ||
this.calculateSignatureValue(doc, function(err, signature) { | ||
if (err) { | ||
callback(err) | ||
} else { | ||
self.signatureValue = signature | ||
signatureDoc.insertBefore(self.createSignature(prefix), signedInfoNode.nextSibling) | ||
self.signatureXml = signatureDoc.toString() | ||
self.signedXml = doc.toString() | ||
callback() | ||
} | ||
}) | ||
} | ||
} | ||
@@ -758,0 +837,0 @@ |
{ | ||
"name": "xml-crypto", | ||
"version": "1.4.1", | ||
"version": "1.5.0", | ||
"description": "Xml digital signature and encryption library for Node.js", | ||
@@ -5,0 +5,0 @@ "engines": { |
@@ -368,3 +368,30 @@ ## xml-crypto | ||
## Asynchronous signing and verification | ||
If the private key is not stored locally and you wish to use a signing server or Hardware Security Module (HSM) to sign documents you can create a custom signing algorithm that uses an asynchronous callback. | ||
`````javascript | ||
function AsyncSignatureAlgorithm() { | ||
this.getSignature = function (signedInfo, signingKey, callback) { | ||
var signer = crypto.createSign("RSA-SHA1") | ||
signer.update(signedInfo) | ||
var res = signer.sign(signingKey, 'base64') | ||
//Do some asynchronous things here | ||
callback(null, res) | ||
} | ||
this.getAlgorithmName = function () { | ||
return "http://www.w3.org/2000/09/xmldsig#rsa-sha1" | ||
} | ||
} | ||
SignedXml.SignatureAlgorithms["http://asyncSignatureAlgorithm"] = AsyncSignatureAlgorithm | ||
var sig = new SignedXml() | ||
sig.signatureAlgorithm = "http://asyncSignatureAlgorithm" | ||
sig.computeSignature(xml, opts, function(err){ | ||
var signedResponse = sig.getSignedXml() | ||
}) | ||
````` | ||
The function `sig.checkSignature` may also use a callback if asynchronous verification is needed. | ||
## X.509 / Key formats | ||
@@ -371,0 +398,0 @@ Xml-Crypto internally relies on node's crypto module. This means pem encoded certificates are supported. So to sign an xml use key.pem that looks like this (only the begining of the key content is shown): |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
NPM Shrinkwrap
Supply chain riskPackage contains a shrinkwrap file. This may allow the package to bypass normal install procedures.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
151185
15
3376
483
1