Skip to content

Commit

Permalink
make FileKeyInfo extensible for compatibility with TypeScript (#273)
Browse files Browse the repository at this point in the history
* make FileKeyInfo extensible for compatibility with TypeScript

* extract FileKeyInfo into new file; add StringKeyInfo

* fix comment in StringKeyInfo

---------

Co-authored-by: Andrew Jaqua <andrew@trazi.com>
Co-authored-by: LoneRifle <LoneRifle@users.noreply.github.com>
  • Loading branch information
3 people committed Feb 26, 2023
1 parent 04e1e78 commit 5abf8fc
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 28 deletions.
17 changes: 17 additions & 0 deletions lib/file-key-info.js
Original file line number Diff line number Diff line change
@@ -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
30 changes: 3 additions & 27 deletions lib/signed-xml.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +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

this.getKeyInfo = function(key, prefix) {
var currentPrefix = prefix || ''
currentPrefix = currentPrefix ? currentPrefix + ':' : currentPrefix
var signingCert = '';
if (key) {
var certArray = [].concat(key);
for(var i = 0; i < certArray.length; ++i) {
var cert = certArray[i]
signingCert += "<" + currentPrefix + "X509Certificate>" + cert + "</" + currentPrefix + "X509Certificate>"
}
}
return "<" + currentPrefix + "X509Data>" + signingCert + "</" + currentPrefix + "X509Data>"
}

this.getKey = function(keyInfo) {
return fs.readFileSync(this.file)
}
}

/**
* Hash algorithm implementation
*
Expand Down
40 changes: 40 additions & 0 deletions lib/string-key-info.js
Original file line number Diff line number Diff line change
@@ -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. "<X509Data></X509Data>"). 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 "<foo:X509Data></foo:X509Data>"
*
* @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></" + 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;
15 changes: 14 additions & 1 deletion test/document-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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();
};

0 comments on commit 5abf8fc

Please sign in to comment.