Skip to content

Commit

Permalink
feat(checkData): optionally throw when checkData fails
Browse files Browse the repository at this point in the history
  • Loading branch information
zkat committed Mar 13, 2018
1 parent d0f7429 commit bf26b84
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 2 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,13 +389,17 @@ If `opts.pickAlgorithm` is provided, it will be used by
[`Integrity#pickAlgorithm`](#integrity-pick-algorithm) when deciding which of
the available digests to match against.

If `opts.error` is true, and verification fails, `checkData` will throw either
an `EBADSIZE` or an `EINTEGRITY` error, instead of just returning false.

##### Example

```javascript
const data = fs.readFileSync('index.js')
ssri.checkData(data, ssri.fromData(data)) // -> 'sha512'
ssri.checkData(data, 'sha256-l981iLWj8kurw4UbNy8Lpxqdzd7UOxS50Glhv8FwfZ0')
ssri.checkData(data, 'sha1-BaDDigEST') // -> false
ssri.checkData(data, 'sha1-BaDDigEST', {error: true}) // -> Error! EINTEGRITY
```

#### <a name="check-stream"></a> `> ssri.checkStream(stream, sri, [opts]) -> Promise<Hash>`
Expand Down
33 changes: 31 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,39 @@ module.exports.checkData = checkData
function checkData (data, sri, opts) {
opts = opts || {}
sri = parse(sri, opts)
if (!Object.keys(sri).length) { return false }
if (!Object.keys(sri).length) {
if (opts.error) {
throw Object.assign(
new Error('No valid integrity hashes to check against'), {
code: 'EINTEGRITY'
}
)
} else {
return false
}
}
const algorithm = sri.pickAlgorithm(opts)
const digest = crypto.createHash(algorithm).update(data).digest('base64')
return parse({algorithm, digest}).match(sri, opts)
const newSri = parse({algorithm, digest})
const match = newSri.match(sri, opts)
if (match || !opts.error) {
return match
} else if (typeof opts.size === 'number' && (data.length !== opts.size)) {
const err = new Error(`data size mismatch when checking ${sri}.\n Wanted: ${opts.size}\n Found: ${data.length}`)
err.code = 'EBADSIZE'
err.found = data.length
err.expected = opts.size
err.sri = sri
throw err
} else {
const err = new Error(`Integrity checksum failed when using ${algorithm}: Wanted ${sri}, but got ${newSri}. (${data.length} bytes)`)
err.code = 'EINTEGRITY'
err.found = newSri
err.expected = sri
err.algorithm = algorithm
err.sri = sri
throw err
}
}

module.exports.checkStream = checkStream
Expand Down
12 changes: 12 additions & 0 deletions test/check.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ test('checkData', t => {
meta,
'Buffer data successfully verified'
)
t.doesNotThrow(() => {
ssri.checkData(TEST_DATA, sri, {error: true})
}, 'error not thrown when error: true and data verifies')
t.deepEqual(
ssri.checkData(TEST_DATA, `sha512-${hash(TEST_DATA, 'sha512')}`),
meta,
Expand Down Expand Up @@ -59,6 +62,12 @@ test('checkData', t => {
false,
'returns false when verification fails'
)
t.throws(() => {
ssri.checkData('nope', sri, {error: true})
}, /Integrity checksum failed/, 'integrity error thrown when error: true with bad data')
t.throws(() => {
ssri.checkData('nope', sri, {error: true, size: 3})
}, /data size mismatch/, 'size error thrown when error: true with bad size')
t.equal(
ssri.checkData('nope', 'sha512-nope'),
false,
Expand All @@ -74,6 +83,9 @@ test('checkData', t => {
false,
'returns false on empty sri input'
)
t.throws(() => {
ssri.checkData('nope', '', {error: true})
}, /No valid integrity hashes/, 'errors on empty sri input if error: true')
t.deepEqual(
ssri.checkData(TEST_DATA, [
'sha512-nope',
Expand Down

0 comments on commit bf26b84

Please sign in to comment.