diff --git a/README.md b/README.md
index 8011418..a6c07e7 100644
--- a/README.md
+++ b/README.md
@@ -389,6 +389,9 @@ 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
@@ -396,6 +399,7 @@ 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
```
#### `> ssri.checkStream(stream, sri, [opts]) -> Promise`
diff --git a/index.js b/index.js
index 5418256..ff7881f 100644
--- a/index.js
+++ b/index.js
@@ -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
diff --git a/test/check.js b/test/check.js
index e099716..029c0ee 100644
--- a/test/check.js
+++ b/test/check.js
@@ -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,
@@ -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,
@@ -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',