jsonld-signatures
Advanced tools
Comparing version 1.1.5 to 1.2.0
{ | ||
"name": "jsonld-signatures", | ||
"version": "1.1.5", | ||
"moduleType": [ | ||
@@ -5,0 +4,0 @@ "amd" |
@@ -10,3 +10,3 @@ /** | ||
* BSD 3-Clause License | ||
* Copyright (c) 2014-2015 Digital Bazaar, Inc. | ||
* Copyright (c) 2014-2016 Digital Bazaar, Inc. | ||
* All rights reserved. | ||
@@ -23,3 +23,3 @@ * | ||
* documentation and/or other materials provided with the distribution. | ||
*.now | ||
* | ||
* Neither the name of the Digital Bazaar, Inc. nor the names of its | ||
@@ -72,2 +72,7 @@ * contributors may be used to endorse or promote products derived from | ||
api.SECURITY_CONTEXT_URL = 'https://w3id.org/security/v1'; | ||
api.SUPPORTED_ALGORITHMS = [ | ||
'EcdsaKoblitzSignature2016', | ||
'GraphSignature2012', | ||
'LinkedDataSignature2015' | ||
]; | ||
@@ -98,4 +103,7 @@ /* Core API */ | ||
if(!libs[name]) { | ||
// alias `forge` to `node-forge`, `jsonld` to `jsonldjs` | ||
var requireName = (name === 'forge' ? 'node-forge' : name); | ||
var requireAliases = { | ||
'forge': 'node-forge', | ||
'bitcoreMessage': 'bitcore-message' | ||
}; | ||
var requireName = requireAliases[name] || name; | ||
var globalName = (name === 'jsonld' ? 'jsonldjs' : name); | ||
@@ -134,2 +142,3 @@ libs[name] = global[globalName] || (_nodejs && require(requireName)); | ||
var privateKeyPem = options.privateKeyPem; | ||
var privateKeyWif = options.privateKeyWif; | ||
var creator = options.creator; | ||
@@ -141,6 +150,19 @@ var date = options.date || new Date(); | ||
if(typeof privateKeyPem !== 'string') { | ||
if(api.SUPPORTED_ALGORITHMS.indexOf(algorithm) === -1) { | ||
return callback(new Error( | ||
'[jsigs.sign] Unsupported algorithm "' + algorithm + '"; ' + | ||
'options.algorithm must be one of: ' + | ||
JSON.stringify(api.SUPPORTED_ALGORITHMS))); | ||
} | ||
if(algorithm === 'EcdsaKoblitzSignature2016') { | ||
if(typeof privateKeyWif !== 'string') { | ||
return callback(new TypeError( | ||
'[jsig.sign] options.privateKeyWif must be a base 58 formatted string.')); | ||
} | ||
} else if(typeof privateKeyPem !== 'string') { | ||
return callback(new TypeError( | ||
'[jsig.sign] options.privateKeyPem must be a PEM formatted string.')); | ||
} | ||
if(typeof creator !== 'string') { | ||
@@ -158,8 +180,2 @@ return callback(new TypeError( | ||
} | ||
if(['GraphSignature2012', 'LinkedDataSignature2015'].indexOf( | ||
algorithm) === -1) { | ||
return callback(new Error( | ||
'[jsig.sign] options.algorithm must be ' + | ||
'`GraphSignature2012` or `LinkedDataSignature2015`.')); | ||
} | ||
@@ -178,3 +194,3 @@ // create W3C-formatted date | ||
normalizeAlgorithm = 'URGNA2012'; | ||
} else if(algorithm === 'LinkedDataSignature2015') { | ||
} else { | ||
normalizeAlgorithm = 'URDNA2015'; | ||
@@ -196,4 +212,4 @@ } | ||
return callback(new Error('[jsig.sign] ' + | ||
'The data to sign is empty. This error may be caused because ' + | ||
'a "@context" was not supplied in the input which would cause ' + | ||
'The data to sign is empty. This error may be because a ' + | ||
'"@context" was not supplied in the input thereby causing ' + | ||
'any terms or prefixes to be undefined. ' + | ||
@@ -206,2 +222,3 @@ 'Input:\n' + inputJson)); | ||
privateKeyPem: privateKeyPem, | ||
privateKeyWif: privateKeyWif, | ||
date: date, | ||
@@ -294,12 +311,9 @@ nonce: nonce, | ||
var algorithm = jsonld.getValues(signature, 'type')[0] || ''; | ||
if(['GraphSignature2012', 'LinkedDataSignature2015'].indexOf( | ||
algorithm) === -1) { | ||
return callback(new Error('[jsigs.verify] Unsupported signature type.')); | ||
if(api.SUPPORTED_ALGORITHMS.indexOf(algorithm) === -1) { | ||
return callback(new Error( | ||
'[jsigs.verify] Unsupported signature algorithm "' + algorithm + '"; ' + | ||
'supported algorithms are: ' + | ||
JSON.stringify(api.SUPPORTED_ALGORITHMS))); | ||
} | ||
if(algorithm === 'GraphSignature2012') { | ||
return _verifyGraphSignature2012(input, options, callback); | ||
} | ||
if(algorithm === 'LinkedDataSignature2015') { | ||
return _verifyLinkedDataSignature2015(input, options, callback); | ||
} | ||
return _verify(algorithm, input, options, callback); | ||
}); | ||
@@ -481,3 +495,3 @@ }; | ||
function _verifyGraphSignature2012(input, options, callback) { | ||
function _verify(algorithm, input, options, callback) { | ||
var checkTimestamp = ( | ||
@@ -495,37 +509,55 @@ 'checkTimestamp' in options ? options.checkTimestamp : false); | ||
// frame message to retrieve signature | ||
var frame = { | ||
'@context': api.SECURITY_CONTEXT_URL, | ||
signature: { | ||
type: 'GraphSignature2012', | ||
created: {}, | ||
creator: {}, | ||
signatureValue: {} | ||
// TODO: `frame` also needs to be run for other algorithms once | ||
// any named graph issues are sorted out with the framing algorithm | ||
if(algorithm === 'GraphSignature2012') { | ||
var frame = { | ||
'@context': api.SECURITY_CONTEXT_URL, | ||
signature: { | ||
type: algorithm, | ||
created: {}, | ||
creator: {}, | ||
signatureValue: {} | ||
} | ||
}; | ||
if(options.id) { | ||
frame.id = options.id; | ||
} | ||
}; | ||
if(options.id) { | ||
frame.id = options.id; | ||
jsonld.frame(input, frame, function(err, framed) { | ||
if(err) { | ||
return callback(err); | ||
} | ||
var graphs = framed['@graph']; | ||
if(graphs.length === 0) { | ||
return callback(new Error('[jsigs.verify] ' + | ||
'No signed data found in the provided input.')); | ||
} | ||
if(graphs.length > 1) { | ||
return callback(new Error('[jsigs.verify] ' + | ||
'More than one signed graph found.')); | ||
} | ||
var graph = graphs[0]; | ||
// copy the top level framed data context | ||
graph['@context'] = framed['@context']; | ||
var signature = graph.signature; | ||
if(!signature) { | ||
return callback(new Error('[jsigs.verify] ' + | ||
'The message is not digitally signed using a known algorithm.')); | ||
} | ||
callback(null, graph); | ||
}); | ||
} else { | ||
// TODO: remove and use `frame` once named graph issues with framing | ||
// are sorted out | ||
jsonld.compact(input, api.SECURITY_CONTEXT_URL, function(err, framed) { | ||
if(err) { | ||
return callback(err); | ||
} | ||
var signatures = jsonld.getValues(framed, 'signature'); | ||
if(signatures.length > 1) { | ||
return callback(new Error('[jsigs.verify] ' + | ||
'More than one signed graph found.')); | ||
} | ||
callback(null, framed); | ||
}); | ||
} | ||
jsonld.frame(input, frame, function(err, framed) { | ||
if(err) { | ||
return callback(err); | ||
} | ||
var graphs = framed['@graph']; | ||
if(graphs.length === 0) { | ||
return callback(new Error('[jsigs.verify] ' + | ||
'No signed data found in the provided input.')); | ||
} | ||
if(graphs.length > 1) { | ||
return callback(new Error('[jsigs.verify] ' + | ||
'More than one signed graph found.')); | ||
} | ||
var graph = graphs[0]; | ||
// copy the top level framed data context | ||
graph['@context'] = framed['@context']; | ||
var signature = graph.signature; | ||
if(!signature) { | ||
return callback(new Error('[jsigs.verify] ' + | ||
'The message is not digitally signed using a known algorithm.')); | ||
} | ||
callback(null, graph); | ||
}); | ||
}, | ||
@@ -589,8 +621,6 @@ checkNonce: ['frame', function(callback, results) { | ||
getPublicKey: ['frame', function(callback, results) { | ||
var signature = results.frame.signature; | ||
if(options.publicKey) { | ||
return callback(null, options.publicKey); | ||
} | ||
var signature = results.frame.signature; | ||
api.getPublicKey(signature.creator, options, callback); | ||
@@ -624,11 +654,13 @@ }], | ||
delete result.signature; | ||
var normalizeAlgorithm = (algorithm === 'GraphSignature2012' ? | ||
'URGNA2012' : 'URDNA2015'); | ||
jsonld.normalize( | ||
result, {algorithm: 'URGNA2012', format: 'application/nquads'}, | ||
result, {algorithm: normalizeAlgorithm, format: 'application/nquads'}, | ||
function(err, normalized) { | ||
if(err) { | ||
return callback(err); | ||
if(err) { | ||
return callback(err); | ||
} | ||
callback(null, {data: normalized, signature: signature}); | ||
} | ||
callback(null, {data: normalized, signature: signature}); | ||
}); | ||
); | ||
}], | ||
@@ -639,4 +671,5 @@ verifySignature: ['normalize', function(callback, results) { | ||
_verifySignature(results.normalize.data, signature.signatureValue, { | ||
algorithm: 'GraphSignature2012', | ||
algorithm: algorithm, | ||
publicKeyPem: key.publicKeyPem, | ||
publicKeyWif: key.publicKeyWif, | ||
nonce: signature.nonce, | ||
@@ -652,155 +685,2 @@ date: signature.created, | ||
function _verifyLinkedDataSignature2015(input, options, callback) { | ||
var checkTimestamp = ( | ||
'checkTimestamp' in options ? options.checkTimestamp : false); | ||
var maxTimestampDelta = ( | ||
'maxTimestampDelta' in options ? options.maxTimestampDelta : (15 * 60)); | ||
var jsonld = api.use('jsonld'); | ||
var async = api.use('async'); | ||
// TODO: better merge this code with GraphSignature2012 (make more DRY) | ||
async.auto({ | ||
// FIXME: add support for multiple signatures | ||
// : for many signers of an object, can just check all sigs | ||
// FIXME: frame to get signature, compacting for now because framing | ||
// requires @graph framing support in jsonld.js | ||
frame: function(callback) { | ||
/* var frame = { | ||
'@context': api.SECURITY_CONTEXT_URL, | ||
signature: { | ||
type: 'LinkedDataSignature2015', | ||
created: {}, | ||
creator: {}, | ||
signatureValue: {} | ||
} | ||
}; | ||
if(options.id) { | ||
frame.id = options.id; | ||
}*/ | ||
jsonld.compact(input, api.SECURITY_CONTEXT_URL, function(err, framed) { | ||
if(err) { | ||
return callback(err); | ||
} | ||
var signatures = jsonld.getValues(framed, 'signature'); | ||
if(signatures.length > 1) { | ||
return callback(new Error('[jsigs.verify] ' + | ||
'More than one signed graph found.')); | ||
} | ||
callback(null, framed); | ||
}); | ||
}, | ||
checkNonce: ['frame', function(callback, results) { | ||
var signature = results.frame.signature; | ||
var cb = function(err, valid) { | ||
if(err) { | ||
return callback(err); | ||
} | ||
if(!valid) { | ||
return callback(new Error('[jsigs.verify] ' + | ||
'The message nonce is invalid.')); | ||
} | ||
callback(); | ||
}; | ||
if(!options.checkNonce) { | ||
return cb( | ||
null, (signature.nonce === null || signature.nonce === undefined)); | ||
} | ||
options.checkNonce(signature.nonce, options, cb); | ||
}], | ||
checkDomain: ['frame', function(callback, results) { | ||
var signature = results.frame.signature; | ||
var cb = function(err, valid) { | ||
if(err) { | ||
return callback(err); | ||
} | ||
if(!valid) { | ||
return callback(new Error('[jsigs.verify] ' + | ||
'The message domain is invalid.')); | ||
} | ||
callback(); | ||
}; | ||
if(!options.checkDomain) { | ||
return cb( | ||
null, (signature.domain === null || signature.domain === undefined)); | ||
} | ||
options.checkDomain(signature.domain, options, cb); | ||
}], | ||
checkDate: ['frame', function(callback, results) { | ||
if(!checkTimestamp) { | ||
return callback(); | ||
} | ||
// ensure signature timestamp within a valid range | ||
var now = new Date().getTime(); | ||
var delta = maxTimestampDelta * 1000; | ||
try { | ||
var signature = results.frame.signature; | ||
var created = Date.parse(signature.created); | ||
if(created < (now - delta) || created > (now + delta)) { | ||
throw new Error('[jsigs.verify] ' + | ||
'The message digital signature timestamp is out of range.'); | ||
} | ||
} catch(ex) { | ||
return callback(ex); | ||
} | ||
callback(); | ||
}], | ||
getPublicKey: ['frame', function(callback, results) { | ||
var signature = results.frame.signature; | ||
if(options.publicKey) { | ||
return callback(null, options.publicKey); | ||
} | ||
api.getPublicKey(signature.creator, options, callback); | ||
}], | ||
checkKey: ['getPublicKey', function(callback, results) { | ||
if('revoked' in results.getPublicKey) { | ||
return callback(new Error('[jsigs.verify] ' + | ||
'The message was signed with a key that has been revoked.')); | ||
} | ||
var cb = function(err, trusted) { | ||
if(err) { | ||
return callback(err); | ||
} | ||
if(!trusted) { | ||
throw new Error('[jsigs.verify] ' + | ||
'The message was not signed with a trusted key.'); | ||
} | ||
callback(); | ||
}; | ||
if(options.checkKey) { | ||
return options.checkKey(results.getPublicKey, options, cb); | ||
} | ||
api.checkKey(results.getPublicKey, options, cb); | ||
}], | ||
normalize: [ | ||
'checkNonce', 'checkDate', 'checkKey', function(callback, results) { | ||
// remove signature property from object | ||
var result = results.frame; | ||
var signature = result.signature; | ||
delete result.signature; | ||
jsonld.normalize( | ||
result, {algorithm: 'URDNA2015', format: 'application/nquads'}, | ||
function(err, normalized) { | ||
if(err) { | ||
return callback(err); | ||
} | ||
callback(null, {data: normalized, signature: signature}); | ||
}); | ||
}], | ||
verifySignature: ['normalize', function(callback, results) { | ||
var key = results.getPublicKey; | ||
var signature = results.normalize.signature; | ||
_verifySignature(results.normalize.data, signature.signatureValue, { | ||
algorithm: 'LinkedDataSignature2015', | ||
publicKeyPem: key.publicKeyPem, | ||
nonce: signature.nonce, | ||
date: signature.created, | ||
domain: signature.domain | ||
}, callback); | ||
}] | ||
}, function(err, results) { | ||
callback(err, results.verifySignature); | ||
}); | ||
} | ||
/** | ||
@@ -819,33 +699,45 @@ * Implements the node.js/browser-specific code for creating a digital | ||
*/ | ||
var _createSignature = (function() { | ||
var _createSignature = function(input, options, callback) { | ||
var signature, privateKey; | ||
if(options.algorithm === 'EcdsaKoblitzSignature2016') { | ||
// works same in any environment | ||
try { | ||
var bitcoreMessage = api.use('bitcoreMessage'); | ||
var bitcore = bitcoreMessage.Bitcore; | ||
privateKey = bitcore.PrivateKey.fromWIF(options.privateKeyWif); | ||
var message = bitcoreMessage(_getDataToHash(input, options)); | ||
signature = message.sign(privateKey); | ||
} catch(err) { | ||
return callback(err); | ||
} | ||
return callback(null, signature); | ||
} | ||
if(_nodejs) { | ||
return function(input, options, callback) { | ||
var signature; | ||
try { | ||
var crypto = api.use('crypto'); | ||
var signer = crypto.createSign('RSA-SHA256'); | ||
signer.update(_getDataToHash(input, options), 'utf8'); | ||
signature = signer.sign(options.privateKeyPem, 'base64'); | ||
} catch(err) { | ||
return callback(err); | ||
} | ||
callback(null, signature); | ||
}; | ||
} else if(_browser) { | ||
return function(input, options, callback) { | ||
var signature; | ||
try { | ||
var forge = api.use('forge'); | ||
var privateKey = forge.pki.privateKeyFromPem(options.privateKeyPem); | ||
var md = forge.md.sha256.create(); | ||
md.update(_getDataToHash(input, options), 'utf8'); | ||
signature = forge.util.encode64(privateKey.sign(md)); | ||
} catch(err) { | ||
return callback(err); | ||
} | ||
callback(null, signature); | ||
}; | ||
// optimize using node libraries | ||
try { | ||
var crypto = api.use('crypto'); | ||
var signer = crypto.createSign('RSA-SHA256'); | ||
signer.update(_getDataToHash(input, options), 'utf8'); | ||
signature = signer.sign(options.privateKeyPem, 'base64'); | ||
} catch(err) { | ||
return callback(err); | ||
} | ||
return callback(null, signature); | ||
} | ||
})(); | ||
// browser or other environment | ||
try { | ||
var forge = api.use('forge'); | ||
privateKey = forge.pki.privateKeyFromPem(options.privateKeyPem); | ||
var md = forge.md.sha256.create(); | ||
md.update(_getDataToHash(input, options), 'utf8'); | ||
signature = forge.util.encode64(privateKey.sign(md)); | ||
} catch(err) { | ||
return callback(err); | ||
} | ||
callback(null, signature); | ||
}; | ||
/** | ||
@@ -865,24 +757,36 @@ * Implements the node.js/browser-specific code for creating a digital | ||
*/ | ||
var _verifySignature = (function() { | ||
var _verifySignature = function(input, signature, options, callback) { | ||
var verified; | ||
if(options.algorithm === 'EcdsaKoblitzSignature2016') { | ||
// works same in any environment | ||
try { | ||
var bitcoreMessage = api.use('bitcoreMessage'); | ||
var message = bitcoreMessage(_getDataToHash(input, options)); | ||
verified = message.verify(options.publicKeyWif, signature); | ||
} catch (err) { | ||
return callback(err); | ||
} | ||
return callback(null, verified); | ||
} | ||
if(_nodejs) { | ||
return function(input, signature, options, callback) { | ||
var crypto = api.use('crypto'); | ||
var verifier = crypto.createVerify('RSA-SHA256'); | ||
verifier.update(_getDataToHash(input, options), 'utf8'); | ||
var verified = verifier.verify(options.publicKeyPem, signature, 'base64'); | ||
callback(null, verified); | ||
}; | ||
} else if(_browser) { | ||
return function(input, signature, options, callback) { | ||
var forge = api.use('forge'); | ||
var publicKey = forge.pki.publicKeyFromPem(options.publicKeyPem); | ||
var md = forge.md.sha256.create(); | ||
md.update(_getDataToHash(input, options), 'utf8'); | ||
var verified = publicKey.verify( | ||
md.digest().bytes(), forge.util.decode64(signature)); | ||
callback(null, verified); | ||
}; | ||
// optimize using node libraries | ||
var crypto = api.use('crypto'); | ||
var verifier = crypto.createVerify('RSA-SHA256'); | ||
verifier.update(_getDataToHash(input, options), 'utf8'); | ||
verified = verifier.verify(options.publicKeyPem, signature, 'base64'); | ||
return callback(null, verified); | ||
} | ||
})(); | ||
// browser or other environment | ||
var forge = api.use('forge'); | ||
var publicKey = forge.pki.publicKeyFromPem(options.publicKeyPem); | ||
var md = forge.md.sha256.create(); | ||
md.update(_getDataToHash(input, options), 'utf8'); | ||
verified = publicKey.verify( | ||
md.digest().bytes(), forge.util.decode64(signature)); | ||
callback(null, verified); | ||
}; | ||
function _getDataToHash(input, options) { | ||
@@ -899,3 +803,3 @@ var toHash = ''; | ||
} | ||
} else if(options.algorithm === 'LinkedDataSignature2015') { | ||
} else { | ||
var headers = { | ||
@@ -902,0 +806,0 @@ 'http://purl.org/dc/elements/1.1/created': options.date, |
{ | ||
"name": "jsonld-signatures", | ||
"version": "1.1.5", | ||
"version": "1.2.0", | ||
"description": "An implementation of the Linked Data Signatures specification for JSON-LD in node.js.", | ||
@@ -36,22 +36,23 @@ "homepage": "http://github.com/digitalbazaar/jsonld-signatures", | ||
"dependencies": { | ||
"async": "^1.4.2", | ||
"commander": "~1.3.0", | ||
"es6-promise": "~2.0.1", | ||
"jsonld": "~0.4.2", | ||
"node-forge": "~0.6.18", | ||
"underscore": "~1.7.0" | ||
"async": "^1.5.2", | ||
"bitcore-message": "github:CoMakery/bitcore-message#dist", | ||
"commander": "~2.9.0", | ||
"es6-promise": "~4.0.5", | ||
"jsonld": "0.4.3", | ||
"node-forge": "~0.6.45" | ||
}, | ||
"devDependencies": { | ||
"chai": "^3.2.0", | ||
"grunt": "~0.4.2", | ||
"grunt-cli": "~0.1.9", | ||
"grunt-contrib-jshint": "~0.11.3", | ||
"grunt-jscs": "^2.1.0", | ||
"grunt-mocha-test": "~0.12.4", | ||
"grunt-release": "~0.13.0", | ||
"grunt-shell": "~1.1.1", | ||
"istanbul": "~0.3.2", | ||
"chai": "^3.5.0", | ||
"grunt": "~1.0.1", | ||
"grunt-cli": "~1.2.0", | ||
"grunt-contrib-jshint": "~1.1.0", | ||
"grunt-jscs": "^3.0.1", | ||
"grunt-mocha-test": "~0.13.2", | ||
"grunt-release": "~0.14.0", | ||
"grunt-shell": "~1.3.1", | ||
"istanbul": "~0.4.5", | ||
"mocha": "^2.3.2", | ||
"mocha-phantomjs": "~3.5.0", | ||
"phantomjs": "~1.9.0" | ||
"npm-run-all": "^3.1.1", | ||
"phantomjs": "~1.9.20" | ||
}, | ||
@@ -71,5 +72,5 @@ "engines": { | ||
"scripts": { | ||
"ci-lint": "grunt jshint --mode=ci || exit 0", | ||
"lint": "grunt jshint", | ||
"jscs": "grunt jscs", | ||
"test-all": "npm-run-all --silent test lint jscs", | ||
"test-node": "grunt mochaTest", | ||
@@ -76,0 +77,0 @@ "test-browser": "grunt shell:testBrowser", |
@@ -9,3 +9,3 @@ jsonld-signatures | ||
An implementation of the Linked Data Signatures specification for JSON-LD. | ||
This software works in all modern browsers as well as node.js. | ||
This software works in all modern browsers as well as node.js via [npm](https://www.npmjs.com/package/jsonld-signatures). | ||
@@ -12,0 +12,0 @@ Introduction |
@@ -20,5 +20,3 @@ // Function.bind polyfill for phantomjs from: | ||
fBound = function() { | ||
return fToBind.apply(this instanceof fNOP | ||
? this | ||
: oThis, | ||
return fToBind.apply(this instanceof fNOP ? this : oThis, | ||
aArgs.concat(Array.prototype.slice.call(arguments))); | ||
@@ -25,0 +23,0 @@ }; |
@@ -17,8 +17,10 @@ /** | ||
var _jsdir, jsonld, jsigs, assert, program; | ||
if(_nodejs) { | ||
var _jsdir = process.env.JSDIR || 'lib'; | ||
var jsonld = require('../node_modules/jsonld'); | ||
var jsigs = require('../' + _jsdir + '/jsonld-signatures')(); | ||
var assert = require('assert'); | ||
var program = require('commander'); | ||
_jsdir = process.env.JSDIR || 'lib'; | ||
jsonld = require('../node_modules/jsonld'); | ||
jsigs = require('../' + _jsdir + '/jsonld-signatures')(); | ||
assert = require('assert'); | ||
program = require('commander'); | ||
program | ||
@@ -31,13 +33,14 @@ .option('--bail', 'Bail when a test fails') | ||
require('./setImmediate'); | ||
var _jsdir = system.env.JSDIR || 'lib'; | ||
var async = require('async'); | ||
window.async = async; | ||
_jsdir = system.env.JSDIR || 'lib'; | ||
window.async = require('async'); | ||
var forge = require('../node_modules/node-forge'); | ||
window.forge = forge; | ||
var bitcoreMessage = require('../node_modules/bitcore-message/dist/bitcore-message.js'); | ||
window.bitcoreMessage = bitcoreMessage; | ||
require('../node_modules/jsonld'); | ||
var jsonld = jsonldjs; | ||
jsonld = jsonldjs; | ||
require('../' + _jsdir + '/jsonld-signatures'); | ||
var jsigs = window.jsigs; | ||
jsigs = window.jsigs; | ||
window.Promise = require('es6-promise').Promise; | ||
var assert = require('chai').assert; | ||
assert = require('chai').assert; | ||
require('mocha/mocha'); | ||
@@ -59,3 +62,3 @@ require('mocha-phantomjs/lib/mocha-phantomjs/core_extensions'); | ||
var program = {}; | ||
program = {}; | ||
for(var i = 0; i < system.args.length; ++i) { | ||
@@ -78,2 +81,7 @@ var arg = system.args[i]; | ||
// helper: | ||
function clone(obj) { | ||
return JSON.parse(JSON.stringify(obj)); | ||
} | ||
// run tests | ||
@@ -117,3 +125,3 @@ describe('JSON-LD Signatures', function() { | ||
describe('signing and verify Graph2012 w/o security context', function() { | ||
context('with NO security context', function() { | ||
// the test document that will be signed | ||
@@ -133,227 +141,292 @@ var testDocument = { | ||
it('should successfully sign a local document', function(done) { | ||
jsigs.sign(testDocument, { | ||
algorithm: 'GraphSignature2012', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}, function(err, signedDocument) { | ||
assert.ifError(err); | ||
assert.notEqual( | ||
signedDocument['https://w3id.org/security#signature'], undefined, | ||
'signature was not created'); | ||
assert.equal( | ||
signedDocument['https://w3id.org/security#signature'] | ||
['http://purl.org/dc/terms/creator']['@id'], testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
done(); | ||
describe('signing and verify Graph2012', function() { | ||
it('should successfully sign a local document', function(done) { | ||
jsigs.sign(testDocument, { | ||
algorithm: 'GraphSignature2012', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}, function(err, signedDocument) { | ||
assert.ifError(err); | ||
assert.notEqual( | ||
signedDocument['https://w3id.org/security#signature'], undefined, | ||
'signature was not created'); | ||
assert.equal( | ||
signedDocument['https://w3id.org/security#signature'] | ||
['http://purl.org/dc/terms/creator']['@id'], testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should successfully verify a local signed document', function(done) { | ||
jsigs.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}, function(err, verified) { | ||
assert.ifError(err); | ||
assert.equal(verified, true, 'signature verification failed'); | ||
done(); | ||
it('should successfully verify a local signed document', function(done) { | ||
jsigs.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}, function(err, verified) { | ||
assert.ifError(err); | ||
assert.equal(verified, true, 'signature verification failed'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should successfully sign a local document w/promises API', function(done) { | ||
jsigs.promises.sign(testDocument, { | ||
algorithm: 'GraphSignature2012', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}).then(function(signedDocument) { | ||
assert.notEqual( | ||
signedDocument['https://w3id.org/security#signature'], undefined, | ||
'signature was not created'); | ||
assert.equal( | ||
signedDocument['https://w3id.org/security#signature'] | ||
['http://purl.org/dc/terms/creator']['@id'], testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
it('should successfully sign a local document w/promises API', function(done) { | ||
jsigs.promises.sign(testDocument, { | ||
algorithm: 'GraphSignature2012', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}).then(function(signedDocument) { | ||
assert.notEqual( | ||
signedDocument['https://w3id.org/security#signature'], undefined, | ||
'signature was not created'); | ||
assert.equal( | ||
signedDocument['https://w3id.org/security#signature'] | ||
['http://purl.org/dc/terms/creator']['@id'], testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should successfully verify a local signed document w/promises API', function(done) { | ||
jsigs.promises.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}).then(function(verified) { | ||
assert.equal(verified, true, 'signature verification failed'); | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
it('should successfully verify a local signed document w/promises API', function(done) { | ||
jsigs.promises.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}).then(function(verified) { | ||
assert.equal(verified, true, 'signature verification failed'); | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('signing and verify Graph2015', function() { | ||
it('should successfully sign a local document', function(done) { | ||
jsigs.sign(testDocument, { | ||
algorithm: 'LinkedDataSignature2015', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}, function(err, signedDocument) { | ||
assert.ifError(err); | ||
assert.notEqual( | ||
signedDocument['https://w3id.org/security#signature'], undefined, | ||
'signature was not created'); | ||
assert.equal( | ||
signedDocument['https://w3id.org/security#signature'] | ||
['http://purl.org/dc/terms/creator']['@id'], testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
done(); | ||
}); | ||
}); | ||
describe('signing and verify Graph2015 w/o security context', function() { | ||
// the test document that will be signed | ||
var testDocument = { | ||
'@context': { | ||
schema: 'http://schema.org/', | ||
name: 'schema:name', | ||
homepage: 'schema:url', | ||
image: 'schema:image' | ||
}, | ||
name: 'Manu Sporny', | ||
homepage: 'https://manu.sporny.org/', | ||
image: 'https://manu.sporny.org/images/manu.png' | ||
}; | ||
var testDocumentSigned = {}; | ||
it('should successfully verify a local signed document', function(done) { | ||
jsigs.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}, function(err, verified) { | ||
assert.ifError(err); | ||
assert.equal(verified, true, 'signature verification failed'); | ||
done(); | ||
}); | ||
}); | ||
it('should successfully sign a local document', function(done) { | ||
jsigs.sign(testDocument, { | ||
algorithm: 'LinkedDataSignature2015', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}, function(err, signedDocument) { | ||
assert.ifError(err); | ||
assert.notEqual( | ||
signedDocument['https://w3id.org/security#signature'], undefined, | ||
'signature was not created'); | ||
assert.equal( | ||
signedDocument['https://w3id.org/security#signature'] | ||
['http://purl.org/dc/terms/creator']['@id'], testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
done(); | ||
it('should successfully sign a local document w/promises API', function(done) { | ||
jsigs.promises.sign(testDocument, { | ||
algorithm: 'LinkedDataSignature2015', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}).then(function(signedDocument) { | ||
assert.notEqual( | ||
signedDocument['https://w3id.org/security#signature'], undefined, | ||
'signature was not created'); | ||
assert.equal( | ||
signedDocument['https://w3id.org/security#signature'] | ||
['http://purl.org/dc/terms/creator']['@id'], testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should successfully verify a local signed document', function(done) { | ||
jsigs.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}, function(err, verified) { | ||
assert.ifError(err); | ||
assert.equal(verified, true, 'signature verification failed'); | ||
done(); | ||
it('should successfully verify a local signed document w/promises API', function(done) { | ||
jsigs.promises.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}).then(function(verified) { | ||
assert.equal(verified, true, 'signature verification failed'); | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should successfully sign a local document w/promises API', function(done) { | ||
jsigs.promises.sign(testDocument, { | ||
algorithm: 'LinkedDataSignature2015', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}).then(function(signedDocument) { | ||
assert.notEqual( | ||
signedDocument['https://w3id.org/security#signature'], undefined, | ||
'signature was not created'); | ||
assert.equal( | ||
signedDocument['https://w3id.org/security#signature'] | ||
['http://purl.org/dc/terms/creator']['@id'], testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
describe('signing and verify EcdsaKoblitzSignature2016', function() { | ||
var testDocument; | ||
var testDocumentSigned; | ||
var testPrivateKeyWif; | ||
var testPublicKeyWif; | ||
var testPublicKeyFriendly; | ||
var testPublicKeyBtc; | ||
var testPublicKeyBtcOwner; | ||
var invalidPublicKeyWif; | ||
var testDocumentSignedAltered; | ||
beforeEach(function() { | ||
testDocument = { | ||
'@context': { | ||
schema: 'http://schema.org/', | ||
name: 'schema:name', | ||
homepage: 'schema:url', | ||
image: 'schema:image' | ||
}, | ||
name: 'Manu Sporny', | ||
homepage: 'https://manu.sporny.org/', | ||
image: 'https://manu.sporny.org/images/manu.png' | ||
}; | ||
testDocumentSigned = clone(testDocument); | ||
testDocumentSigned["https://w3id.org/security#signature"] = { | ||
"@type": "EcdsaKoblitzSignature2016", | ||
"http://purl.org/dc/terms/created": { | ||
"@type": "http://www.w3.org/2001/XMLSchema#dateTime", | ||
"@value": "2017-03-25T22:01:04Z" | ||
}, | ||
"http://purl.org/dc/terms/creator": { | ||
"@id": "ecdsa-koblitz-pubkey:1LGpGhGK8whX23ZNdxrgtjKrek9rP4xWER" | ||
}, | ||
"https://w3id.org/security#signatureValue": "IOoF0rMmpcdxNZFoirTpRMCyLr8kGHLqXFl7v+m3naetCx+OLNhVY/6SCUwDGZfFs4yPXeAl6Tj1WgtLIHOVZmw=" | ||
}; | ||
testDocumentSignedAltered = clone(testDocumentSigned); | ||
testDocumentSignedAltered.name = 'Manu Spornoneous'; | ||
testPrivateKeyWif = 'L4mEi7eEdTNNFQEWaa7JhUKAbtHdVvByGAqvpJKC53mfiqunjBjw'; | ||
testPublicKeyWif = '1LGpGhGK8whX23ZNdxrgtjKrek9rP4xWER'; | ||
testPublicKeyFriendly = 'ecdsa-koblitz-pubkey:' + testPublicKeyWif; | ||
testPublicKeyBtc = { | ||
'@context': jsigs.SECURITY_CONTEXT_URL, | ||
id: testPublicKeyFriendly, | ||
type: 'CryptographicKey', | ||
owner: 'https://example.com/i/alice', | ||
publicKeyWif: testPublicKeyWif | ||
}; | ||
testPublicKeyBtcOwner = { | ||
'@context': jsigs.SECURITY_CONTEXT_URL, | ||
id: 'https://example.com/i/alice', | ||
publicKey: [testPublicKeyFriendly] | ||
}; | ||
invalidPublicKeyWif = '1BHdCBqQ1GQLfHVEnoXtYf44T97aEHodwe'; | ||
}); | ||
}); | ||
it('should successfully verify a local signed document w/promises API', function(done) { | ||
jsigs.promises.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}).then(function(verified) { | ||
assert.equal(verified, true, 'signature verification failed'); | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
it('should successfully sign a local document', function(done) { | ||
jsigs.sign(testDocument, { | ||
algorithm: 'EcdsaKoblitzSignature2016', | ||
privateKeyWif: testPrivateKeyWif, | ||
creator: testPublicKeyFriendly | ||
}, function(err, signedDocument) { | ||
assert.ifError(err); | ||
assert.notEqual( | ||
signedDocument['https://w3id.org/security#signature'], undefined, | ||
'signature was not created'); | ||
assert.equal( | ||
signedDocument['https://w3id.org/security#signature'] | ||
['http://purl.org/dc/terms/creator']['@id'], testPublicKeyFriendly, | ||
'creator key for signature is wrong'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
it('should successfully verify a local signed document', function(done) { | ||
jsigs.verify(testDocumentSigned, { | ||
publicKey: testPublicKeyBtc, | ||
publicKeyOwner: testPublicKeyBtcOwner | ||
}, function(err, verified) { | ||
assert.ifError(err); | ||
assert.equal(verified, true, 'signature verification failed'); | ||
done(); | ||
}); | ||
}); | ||
describe('signing and verify GraphSignature2012 w/security context', function() { | ||
it('verify should return false if the document was signed by a different private key', function(done) { | ||
testPublicKeyBtc.publicKeyWif = invalidPublicKeyWif; | ||
// the test document that will be signed | ||
var testDocument = { | ||
'@context': [{ | ||
schema: 'http://schema.org/', | ||
name: 'schema:name', | ||
homepage: 'schema:url', | ||
image: 'schema:image' | ||
}, jsigs.SECURITY_CONTEXT_URL], | ||
name: 'Manu Sporny', | ||
homepage: 'https://manu.sporny.org/', | ||
image: 'https://manu.sporny.org/images/manu.png' | ||
}; | ||
var testDocumentSigned = {}; | ||
jsigs.verify(testDocumentSigned, { | ||
publicKey: testPublicKeyBtc, | ||
publicKeyOwner: testPublicKeyBtcOwner | ||
}, function(err, verified) { | ||
assert.ifError(err); | ||
assert.equal(verified, false, 'signature verification should have failed'); | ||
done(); | ||
}); | ||
}); | ||
it('should successfully sign a local document', function(done) { | ||
jsigs.sign(testDocument, { | ||
algorithm: 'GraphSignature2012', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}, function(err, signedDocument) { | ||
assert.ifError(err); | ||
assert.notEqual(signedDocument.signature, undefined, | ||
'signature was not created'); | ||
assert.equal(signedDocument.signature.creator, testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
done(); | ||
it('verify should return false if the document was altered after signing', function(done) { | ||
jsigs.verify(testDocumentSignedAltered, { | ||
publicKey: testPublicKeyBtc, | ||
publicKeyOwner: testPublicKeyBtcOwner | ||
}, function(err, verified) { | ||
assert.ifError(err); | ||
assert.equal(verified, false, 'signature verification should have failed'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should successfully verify a local signed document', function(done) { | ||
jsigs.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}, function(err, verified) { | ||
assert.ifError(err); | ||
assert.equal(verified, true, 'signature verification failed'); | ||
done(); | ||
it('should successfully sign a local document' + | ||
' w/promises API', function(done) { | ||
jsigs.promises.sign(testDocument, { | ||
algorithm: 'EcdsaKoblitzSignature2016', | ||
privateKeyWif: testPrivateKeyWif, | ||
creator: testPublicKeyFriendly | ||
}).then(function(signedDocument) { | ||
assert.notEqual( | ||
signedDocument['https://w3id.org/security#signature'], undefined, | ||
'signature was not created'); | ||
assert.equal( | ||
signedDocument['https://w3id.org/security#signature'] | ||
['http://purl.org/dc/terms/creator']['@id'], testPublicKeyFriendly, | ||
'creator key for signature is wrong'); | ||
}).then(done).catch(done); | ||
}); | ||
}); | ||
it('should successfully sign a local document w/promises API', function(done) { | ||
jsigs.promises.sign(testDocument, { | ||
algorithm: 'GraphSignature2012', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}).then(function(signedDocument) { | ||
assert.notEqual(signedDocument.signature, undefined, | ||
'signature was not created'); | ||
assert.equal(signedDocument.signature.creator, testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
it('should successfully verify a local signed document' + | ||
' w/promises API', function(done) { | ||
jsigs.promises.verify(testDocumentSigned, { | ||
publicKey: testPublicKeyBtc, | ||
publicKeyOwner: testPublicKeyBtcOwner | ||
}).then(function(verified) { | ||
assert.equal(verified, true, 'signature verification failed'); | ||
}).then(done).catch(done); | ||
}); | ||
}); | ||
it('should successfully verify a local signed document w/promises API', function(done) { | ||
jsigs.promises.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}).then(function(verified) { | ||
assert.equal(verified, true, 'signature verification failed'); | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
it('verify should return false if the document was signed by' + | ||
' a different private key w/promises API', function(done) { | ||
testPublicKeyBtc.publicKeyWif = invalidPublicKeyWif; | ||
jsigs.promises.verify(testDocumentSigned, { | ||
publicKey: testPublicKeyBtc, | ||
publicKeyOwner: testPublicKeyBtcOwner | ||
}).then(function(verified) { | ||
assert.equal(verified, false, | ||
'signature verification should have failed but did not'); | ||
}).then(done).catch(done); | ||
}); | ||
}); | ||
}); | ||
describe('signing and verify LinkedDataSignature2015 w/security context', function() { | ||
context('with security context', function() { | ||
// the test document that will be signed | ||
@@ -373,58 +446,272 @@ var testDocument = { | ||
it('should successfully sign a local document', function(done) { | ||
jsigs.sign(testDocument, { | ||
algorithm: 'LinkedDataSignature2015', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}, function(err, signedDocument) { | ||
assert.ifError(err); | ||
assert.notEqual(signedDocument.signature, undefined, | ||
'signature was not created'); | ||
assert.equal(signedDocument.signature.creator, testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
done(); | ||
describe('signing and verify GraphSignature2012 w/security context', function() { | ||
it('should successfully sign a local document', function(done) { | ||
jsigs.sign(testDocument, { | ||
algorithm: 'GraphSignature2012', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}, function(err, signedDocument) { | ||
assert.ifError(err); | ||
assert.notEqual(signedDocument.signature, undefined, | ||
'signature was not created'); | ||
assert.equal(signedDocument.signature.creator, testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should successfully verify a local signed document', function(done) { | ||
jsigs.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}, function(err, verified) { | ||
assert.ifError(err); | ||
assert.equal(verified, true, 'signature verification failed'); | ||
done(); | ||
it('should successfully verify a local signed document', function(done) { | ||
jsigs.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}, function(err, verified) { | ||
assert.ifError(err); | ||
assert.equal(verified, true, 'signature verification failed'); | ||
done(); | ||
}); | ||
}); | ||
it('should successfully sign a local document w/promises API', function(done) { | ||
jsigs.promises.sign(testDocument, { | ||
algorithm: 'GraphSignature2012', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}).then(function(signedDocument) { | ||
assert.notEqual(signedDocument.signature, undefined, | ||
'signature was not created'); | ||
assert.equal(signedDocument.signature.creator, testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
}); | ||
}); | ||
it('should successfully verify a local signed document w/promises API', function(done) { | ||
jsigs.promises.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}).then(function(verified) { | ||
assert.equal(verified, true, 'signature verification failed'); | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should successfully sign a local document w/promises', function(done) { | ||
jsigs.promises.sign(testDocument, { | ||
algorithm: 'LinkedDataSignature2015', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}).then(function(signedDocument) { | ||
assert.notEqual(signedDocument.signature, undefined, | ||
'signature was not created'); | ||
assert.equal(signedDocument.signature.creator, testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
describe('signing and verify LinkedDataSignature2015 w/security context', function() { | ||
it('should successfully sign a local document', function(done) { | ||
jsigs.sign(testDocument, { | ||
algorithm: 'LinkedDataSignature2015', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}, function(err, signedDocument) { | ||
assert.ifError(err); | ||
assert.notEqual(signedDocument.signature, undefined, | ||
'signature was not created'); | ||
assert.equal(signedDocument.signature.creator, testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
done(); | ||
}); | ||
}); | ||
it('should successfully verify a local signed document', function(done) { | ||
jsigs.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}, function(err, verified) { | ||
assert.ifError(err); | ||
assert.equal(verified, true, 'signature verification failed'); | ||
done(); | ||
}); | ||
}); | ||
it('should successfully sign a local document w/promises', function(done) { | ||
jsigs.promises.sign(testDocument, { | ||
algorithm: 'LinkedDataSignature2015', | ||
privateKeyPem: testPrivateKeyPem, | ||
creator: testPublicKeyUrl | ||
}).then(function(signedDocument) { | ||
assert.notEqual(signedDocument.signature, undefined, | ||
'signature was not created'); | ||
assert.equal(signedDocument.signature.creator, testPublicKeyUrl, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
}); | ||
}); | ||
it('should successfully verify a local signed document w/promises', function(done) { | ||
jsigs.promises.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}).then(function(verified) { | ||
assert.equal(verified, true, 'signature verification failed'); | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should successfully verify a local signed document w/promises', function(done) { | ||
jsigs.promises.verify(testDocumentSigned, { | ||
publicKey: testPublicKey, | ||
publicKeyOwner: testPublicKeyOwner | ||
}).then(function(verified) { | ||
assert.equal(verified, true, 'signature verification failed'); | ||
}).catch(function(err) { | ||
assert.ifError(err); | ||
}).then(function() { | ||
done(); | ||
describe('signing and verify EcdsaKoblitzSignature2016', function() { | ||
var testDocument; | ||
var testDocumentSigned; | ||
var testPrivateKeyWif; | ||
var testPublicKeyWif; | ||
var testPublicKeyFriendly; | ||
var testPublicKeyBtc; | ||
var testPublicKeyBtcOwner; | ||
var invalidPublicKeyWif; | ||
var testDocumentSignedAltered; | ||
beforeEach(function() { | ||
testDocument = { | ||
'@context': [{ | ||
schema: 'http://schema.org/', | ||
name: 'schema:name', | ||
homepage: 'schema:url', | ||
image: 'schema:image' | ||
}, jsigs.SECURITY_CONTEXT_URL], | ||
name: 'Manu Sporny', | ||
homepage: 'https://manu.sporny.org/', | ||
image: 'https://manu.sporny.org/images/manu.png' | ||
}; | ||
testDocumentSigned = clone(testDocument); | ||
testDocumentSigned["https://w3id.org/security#signature"] = { | ||
"@type": "EcdsaKoblitzSignature2016", | ||
"http://purl.org/dc/terms/created": { | ||
"@type": "http://www.w3.org/2001/XMLSchema#dateTime", | ||
"@value": "2017-03-25T22:01:04Z" | ||
}, | ||
"http://purl.org/dc/terms/creator": { | ||
"@id": "ecdsa-koblitz-pubkey:1LGpGhGK8whX23ZNdxrgtjKrek9rP4xWER" | ||
}, | ||
"https://w3id.org/security#signatureValue": "IOoF0rMmpcdxNZFoirTpRMCyLr8kGHLqXFl7v+m3naetCx+OLNhVY/6SCUwDGZfFs4yPXeAl6Tj1WgtLIHOVZmw=" | ||
}; | ||
testDocumentSignedAltered = clone(testDocumentSigned); | ||
testDocumentSignedAltered.name = 'Manu Spornoneous'; | ||
testPrivateKeyWif = 'L4mEi7eEdTNNFQEWaa7JhUKAbtHdVvByGAqvpJKC53mfiqunjBjw'; | ||
testPublicKeyWif = '1LGpGhGK8whX23ZNdxrgtjKrek9rP4xWER'; | ||
testPublicKeyFriendly = 'ecdsa-koblitz-pubkey:' + testPublicKeyWif; | ||
testPublicKeyBtc = { | ||
'@context': jsigs.SECURITY_CONTEXT_URL, | ||
id: testPublicKeyFriendly, | ||
type: 'CryptographicKey', | ||
owner: 'https://example.com/i/alice', | ||
publicKeyWif: testPublicKeyWif | ||
}; | ||
testPublicKeyBtcOwner = { | ||
'@context': jsigs.SECURITY_CONTEXT_URL, | ||
id: 'https://example.com/i/alice', | ||
publicKey: [testPublicKeyFriendly] | ||
}; | ||
invalidPublicKeyWif = '1BHdCBqQ1GQLfHVEnoXtYf44T97aEHodwe'; | ||
}); | ||
it('should successfully sign a local document', function(done) { | ||
jsigs.sign(testDocument, { | ||
algorithm: 'EcdsaKoblitzSignature2016', | ||
privateKeyWif: testPrivateKeyWif, | ||
creator: testPublicKeyFriendly | ||
}, function(err, signedDocument) { | ||
assert.ifError(err); | ||
assert.notEqual( | ||
signedDocument.signature, undefined, 'signature was not created'); | ||
assert.equal( | ||
signedDocument.signature.creator, testPublicKeyFriendly, | ||
'creator key for signature is wrong'); | ||
done(); | ||
}); | ||
}); | ||
it('should successfully verify a local signed document', function(done) { | ||
jsigs.verify(testDocumentSigned, { | ||
publicKey: testPublicKeyBtc, | ||
publicKeyOwner: testPublicKeyBtcOwner | ||
}, function(err, verified) { | ||
assert.ifError(err); | ||
assert.equal(verified, true, 'signature verification failed'); | ||
done(); | ||
}); | ||
}); | ||
it('verify should return false if the document was signed by a different private key', function(done) { | ||
testPublicKeyBtc.publicKeyWif = invalidPublicKeyWif; | ||
jsigs.verify(testDocumentSigned, { | ||
publicKey: testPublicKeyBtc, | ||
publicKeyOwner: testPublicKeyBtcOwner | ||
}, function(err, verified) { | ||
assert.ifError(err); | ||
assert.equal(verified, false, 'signature verification should have failed'); | ||
done(); | ||
}); | ||
}); | ||
it('should successfully sign a local document' + | ||
' w/promises API', function(done) { | ||
jsigs.promises.sign(testDocument, { | ||
algorithm: 'EcdsaKoblitzSignature2016', | ||
privateKeyWif: testPrivateKeyWif, | ||
creator: testPublicKeyFriendly | ||
}).then(function(signedDocument) { | ||
assert.notEqual(signedDocument.signature, undefined, | ||
'signature was not created'); | ||
assert.equal(signedDocument.signature.creator, testPublicKeyFriendly, | ||
'creator key for signature is wrong'); | ||
testDocumentSigned = signedDocument; | ||
}).then(done).catch(done); | ||
}); | ||
it('should successfully verify a local signed document' + | ||
' w/promises API', function(done) { | ||
jsigs.promises.verify(testDocumentSigned, { | ||
publicKey: testPublicKeyBtc, | ||
publicKeyOwner: testPublicKeyBtcOwner | ||
}).then(function(verified) { | ||
assert.equal(verified, true, 'signature verification failed'); | ||
}).then(done).catch(done); | ||
}); | ||
it('verify should return false if the document was signed by' + | ||
' a different private key w/promises API', function(done) { | ||
testPublicKeyBtc.publicKeyWif = invalidPublicKeyWif; | ||
jsigs.promises.verify(testDocumentSigned, { | ||
publicKey: testPublicKeyBtc, | ||
publicKeyOwner: testPublicKeyBtcOwner | ||
}).then(function(verified) { | ||
assert.equal(verified, false, | ||
'signature verification should have failed but did not'); | ||
}).then(done).catch(done); | ||
}); | ||
it('verify should return false if the document was altered after' + | ||
' signing w/promises API', function(done) { | ||
jsigs.promises.verify(testDocumentSignedAltered, { | ||
publicKey: testPublicKeyBtc, | ||
publicKeyOwner: testPublicKeyBtcOwner | ||
}).then(function(verified) { | ||
assert.equal(verified, false, | ||
'signature verification should have failed but did not'); | ||
}).then(done).catch(done); | ||
}); | ||
}); | ||
@@ -451,8 +738,11 @@ | ||
"EcdsaKoblitzSignature2016": "sec:EcdsaKoblitzSignature2016", | ||
"EncryptedMessage": "sec:EncryptedMessage", | ||
"GraphSignature2012": "sec:GraphSignature2012", | ||
"LinkedDataSignature2015": "sec:LinkedDataSignature2015", | ||
"LinkedDataSignature2016": "sec:LinkedDataSignature2016", | ||
"CryptographicKey": "sec:Key", | ||
"authenticationTag": "sec:authenticationTag", | ||
"canonicalizationAlgorithm": "sec:canonicalizationAlgorithm", | ||
"cipherAlgorithm": "sec:cipherAlgorithm", | ||
@@ -459,0 +749,0 @@ "cipherData": "sec:cipherData", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
GitHub dependency
Supply chain riskContains a dependency which resolves to a GitHub URL. Dependencies fetched from GitHub specifiers are not immutable can be used to inject untrusted code or reduce the likelihood of a reproducible install.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
82872
1914
13
1
2
+ Addedcommander@2.9.0(transitive)
+ Addedes6-promise@4.0.5(transitive)
+ Addedgraceful-readlink@1.0.1(transitive)
+ Addedjsonld@0.4.3(transitive)
+ Addedpkginfo@0.3.1(transitive)
- Removedunderscore@~1.7.0
- Removedcommander@1.3.2(transitive)
- Removedjsonld@0.4.12(transitive)
- Removedkeypress@0.1.0(transitive)
- Removedpkginfo@0.4.1(transitive)
- Removedunderscore@1.7.0(transitive)
Updatedasync@^1.5.2
Updatedcommander@~2.9.0
Updatedes6-promise@~4.0.5
Updatedjsonld@0.4.3
Updatednode-forge@~0.6.45