From c2c262b72a2ac5cafea0a99c816e30ab20b1ea24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kat=20March=C3=A1n?= Date: Wed, 24 May 2017 16:38:45 -0700 Subject: [PATCH] fix(check): handle various bad hash corner cases better --- index.js | 13 +++++++++---- test/check.js | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 9c84dbc..f01986f 100644 --- a/index.js +++ b/index.js @@ -95,7 +95,9 @@ class Integrity { const pickAlgorithm = (opts && opts.pickAlgorithm) || getPrioritizedHash const keys = Object.keys(this) if (!keys.length) { - throw new Error(`No algorithms available for ${this}`) + throw new Error(`No algorithms available for ${ + JSON.stringify(this.toString()) + }`) } return keys.reduce((acc, algo) => { return pickAlgorithm(acc, algo) || acc @@ -199,8 +201,9 @@ module.exports.checkData = checkData function checkData (data, sri, opts) { opts = opts || {} sri = parse(sri, opts) + if (!Object.keys(sri).length) { return false } const algorithm = sri.pickAlgorithm(opts) - const digests = sri[algorithm] + const digests = sri[algorithm] || [] const digest = crypto.createHash(algorithm).update(data).digest('base64') return digests.find(hash => hash.digest === digest) || false } @@ -231,8 +234,9 @@ function integrityStream (opts) { opts = opts || {} // For verification const sri = opts.integrity && parse(opts.integrity, opts) - const algorithm = sri && sri.pickAlgorithm(opts) - const digests = sri && sri[algorithm] + const goodSri = sri && Object.keys(sri).length + const algorithm = goodSri && sri.pickAlgorithm(opts) + const digests = goodSri && sri[algorithm] // Calculating stream const algorithms = opts.algorithms || [algorithm || 'sha512'] const hashes = algorithms.map(crypto.createHash) @@ -253,6 +257,7 @@ function integrityStream (opts) { const match = ( // Integrity verification mode opts.integrity && + digests && digests.find(hash => { return newSri[algorithm].find(newhash => { return hash.digest === newhash.digest diff --git a/test/check.js b/test/check.js index 96f0d4d..7628cf8 100644 --- a/test/check.js +++ b/test/check.js @@ -59,6 +59,21 @@ test('checkData', t => { false, 'returns false when verification fails' ) + t.equal( + ssri.checkData('nope', 'sha512-nope'), + false, + 'returns false on invalid sri hash' + ) + t.equal( + ssri.checkData('nope', 'garbage'), + false, + 'returns false on garbage sri input' + ) + t.equal( + ssri.checkData('nope', ''), + false, + 'returns false on empty sri input' + ) t.deepEqual( ssri.checkData(TEST_DATA, [ 'sha512-nope', @@ -129,6 +144,24 @@ test('checkStream', t => { }, err => { t.equal(err.code, 'EINTEGRITY', 'checksum failure rejects the promise') }) + }).then(() => { + return ssri.checkStream( + fs.createReadStream(path.join(__dirname, '..', 'package.json')), + 'garbage' + ).then(() => { + throw new Error('unexpected success') + }, err => { + t.equal(err.code, 'EINTEGRITY', 'checksum failure if sri is garbage') + }) + }).then(() => { + return ssri.checkStream( + fs.createReadStream(path.join(__dirname, '..', 'package.json')), + 'sha512-nope' + ).then(() => { + throw new Error('unexpected success') + }, err => { + t.equal(err.code, 'EINTEGRITY', 'checksum failure if sri has bad hash') + }) }).then(() => { return ssri.checkStream(fileStream(), [ 'sha512-nope',