From 113df6145ff385e8cc93ce2d35b1d8ce830fab8e Mon Sep 17 00:00:00 2001 From: Andrew Jaqua Date: Tue, 17 Jan 2023 10:47:52 -0500 Subject: [PATCH 1/3] make FileKeyInfo extensible for compatibility with TypeScript --- lib/signed-xml.js | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/lib/signed-xml.js b/lib/signed-xml.js index 7b236944..9d7e1cae 100644 --- a/lib/signed-xml.js +++ b/lib/signed-xml.js @@ -16,18 +16,40 @@ exports.FileKeyInfo = FileKeyInfo */ function FileKeyInfo(file) { this.file = file +} - this.getKeyInfo = function(key, prefix) { - prefix = prefix || '' - prefix = prefix ? prefix + ':' : prefix - return "<" + prefix + "X509Data>" - } - this.getKey = function(keyInfo) { - return fs.readFileSync(this.file) - } +/** + * Builds the contents of a KeyInfo element as an XML string. + * + * Currently, this returns exactly one empty X509Data element + * (e.g. ""). The resultant X509Data element will be + * prefaced with a namespace alias if a value for the prefix argument + * is provided. In example, if the value of the prefix argument is 'foo', then + * the resultant XML string will be "" + * + * @param key (not used) the signing/private key as a string + * @param prefix an optional namespace alias to be used for the generated XML + * @return an XML string representation of the contents of a KeyInfo element + */ +FileKeyInfo.prototype.getKeyInfo = function(key, prefix) { + prefix = prefix || '' + prefix = prefix ? prefix + ':' : prefix + return "<" + prefix + "X509Data>" } +/** + * Returns the value of the signing certificate based on the contents of the + * specified KeyInfo. + * + * @param keyInfo (not used) an array with exactly one KeyInfo element + * @return the signing certificate as a string + */ +FileKeyInfo.prototype.getKey = function(keyInfo) { + return fs.readFileSync(this.file) +} + + /** * Hash algorithm implementation * From 3005be4d5fb2a80b112bbde2bd8d0577da6e4f0c Mon Sep 17 00:00:00 2001 From: Andrew Jaqua Date: Fri, 20 Jan 2023 19:54:09 -0500 Subject: [PATCH 2/3] extract FileKeyInfo into new file; add StringKeyInfo --- lib/file-key-info.js | 17 ++++++++++++++++ lib/signed-xml.js | 44 +++--------------------------------------- lib/string-key-info.js | 40 ++++++++++++++++++++++++++++++++++++++ test/document-test.js | 15 +++++++++++++- 4 files changed, 74 insertions(+), 42 deletions(-) create mode 100644 lib/file-key-info.js create mode 100644 lib/string-key-info.js diff --git a/lib/file-key-info.js b/lib/file-key-info.js new file mode 100644 index 00000000..3accb30d --- /dev/null +++ b/lib/file-key-info.js @@ -0,0 +1,17 @@ +var StringKeyInfo = require("./string-key-info") + , fs = require("fs") + +/** + * A key info provider implementation + * + * @param {string} file path to public certificate + */ +function FileKeyInfo(file) { + var key = fs.readFileSync(file) + StringKeyInfo.apply(this, [key]) +} + +FileKeyInfo.prototype = StringKeyInfo.prototype +FileKeyInfo.prototype.constructor = FileKeyInfo + +module.exports = FileKeyInfo diff --git a/lib/signed-xml.js b/lib/signed-xml.js index 9d7e1cae..cb99702b 100644 --- a/lib/signed-xml.js +++ b/lib/signed-xml.js @@ -4,52 +4,14 @@ var xpath = require('xpath') , c14n = require('./c14n-canonicalization') , execC14n = require('./exclusive-canonicalization') , EnvelopedSignature = require('./enveloped-signature').EnvelopedSignature + , StringKeyInfo = require('./string-key-info') + , FileKeyInfo = require('./file-key-info') , crypto = require('crypto') - , fs = require('fs') exports.SignedXml = SignedXml +exports.StringKeyInfo = StringKeyInfo exports.FileKeyInfo = FileKeyInfo -/** - * A key info provider implementation - * - */ -function FileKeyInfo(file) { - this.file = file -} - - -/** - * Builds the contents of a KeyInfo element as an XML string. - * - * Currently, this returns exactly one empty X509Data element - * (e.g. ""). The resultant X509Data element will be - * prefaced with a namespace alias if a value for the prefix argument - * is provided. In example, if the value of the prefix argument is 'foo', then - * the resultant XML string will be "" - * - * @param key (not used) the signing/private key as a string - * @param prefix an optional namespace alias to be used for the generated XML - * @return an XML string representation of the contents of a KeyInfo element - */ -FileKeyInfo.prototype.getKeyInfo = function(key, prefix) { - prefix = prefix || '' - prefix = prefix ? prefix + ':' : prefix - return "<" + prefix + "X509Data>" -} - -/** - * Returns the value of the signing certificate based on the contents of the - * specified KeyInfo. - * - * @param keyInfo (not used) an array with exactly one KeyInfo element - * @return the signing certificate as a string - */ -FileKeyInfo.prototype.getKey = function(keyInfo) { - return fs.readFileSync(this.file) -} - - /** * Hash algorithm implementation * diff --git a/lib/string-key-info.js b/lib/string-key-info.js new file mode 100644 index 00000000..7fd70195 --- /dev/null +++ b/lib/string-key-info.js @@ -0,0 +1,40 @@ +/** + * A basic string based implementation of a FileInfoProvider + * + * @param {string} key the string contents of a public certificate + */ +function StringKeyInfo(key) { + this.key = key; +} + +/** + * Builds the contents of a KeyInfo element as an XML string. + * + * Currently, this returns exactly one empty X509Data element + * (e.g. ""). The resultant X509Data element will be + * prefaced with a namespace alias if a value for the prefix argument + * is provided. In example, if the value of the prefix argument is 'foo', then + * the resultant XML string will be "" + * + * @param key (not used) the signing/private key as a string + * @param prefix an optional namespace alias to be used for the generated XML + * @return an XML string representation of the contents of a KeyInfo element + */ +StringKeyInfo.prototype.getKeyInfo = function (key, prefix) { + prefix = prefix || ""; + prefix = prefix ? prefix + ":" : prefix; + return "<" + prefix + "X509Data>"; +}; + +/** + * Returns the value of the signing certificate based on the contents of the + * specified KeyInfo. + * + * @param keyInfo (not used) an array with exactly one KeyInfo element + * @return the signing certificate as a string + */ +StringKeyInfo.prototype.getKey = function (keyInfo) { + return this.key; +}; + +module.exports = StringKeyInfo; diff --git a/test/document-test.js b/test/document-test.js index fd7f12d9..be36a9d8 100644 --- a/test/document-test.js +++ b/test/document-test.js @@ -3,7 +3,7 @@ var xpath = require('xpath'); var xmldom = require('@xmldom/xmldom'); var fs = require('fs'); -exports['test with a document '] = function (test) { +exports['test with a document (using FileKeyInfo)'] = function (test) { var xml = fs.readFileSync('./test/static/valid_saml.xml', 'utf-8'); var doc = new xmldom.DOMParser().parseFromString(xml); var signature = new xmldom.DOMParser().parseFromString(xpath.select("/*/*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", doc)[0].toString()); @@ -15,3 +15,16 @@ exports['test with a document '] = function (test) { test.done(); }; +exports['test with a document (using StringKeyInfo)'] = function (test) { + var xml = fs.readFileSync('./test/static/valid_saml.xml', 'utf-8'); + var doc = new xmldom.DOMParser().parseFromString(xml); + var signature = new xmldom.DOMParser().parseFromString(xpath.select("/*/*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", doc)[0].toString()); + var sig = new crypto.SignedXml(); + var feidePublicCert = fs.readFileSync('./test/static/feide_public.pem'); + sig.keyInfoProvider = new crypto.StringKeyInfo(feidePublicCert); + sig.loadSignature(signature); + var result = sig.checkSignature(xml); + test.equal(result, true); + test.done(); +}; + From 5975475143dfd7bfa08e5ed41c207ed52e5aaa59 Mon Sep 17 00:00:00 2001 From: Andrew Jaqua Date: Sat, 18 Feb 2023 10:47:35 -0500 Subject: [PATCH 3/3] fix comment in StringKeyInfo --- lib/string-key-info.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/string-key-info.js b/lib/string-key-info.js index 7fd70195..86b6c6ea 100644 --- a/lib/string-key-info.js +++ b/lib/string-key-info.js @@ -14,7 +14,7 @@ function StringKeyInfo(key) { * (e.g. ""). The resultant X509Data element will be * prefaced with a namespace alias if a value for the prefix argument * is provided. In example, if the value of the prefix argument is 'foo', then - * the resultant XML string will be "" + * the resultant XML string will be "" * * @param key (not used) the signing/private key as a string * @param prefix an optional namespace alias to be used for the generated XML