Skip to content

Commit

Permalink
feat(fromHex): ssri.fromHex to make it easier to generate them from h…
Browse files Browse the repository at this point in the history
…ex valus
  • Loading branch information
zkat committed Apr 3, 2017
1 parent 1b29e6f commit 049b89e
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 5 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Integrity](https://w3c.github.io/webappsec/specs/subresourceintegrity/) hashes.
* [`Integrity#pickAlgorithm`](#integrity-pick-algorithm)
* [`IntegrityMetadata#hexDigest`](#integrity-metadata-hex-digest)
* Integrity Generation
* [`fromHex`](#from-hex)
* [`fromData`](#from-data)
* [`fromStream`](#from-stream)
* Integrity Verification
Expand Down Expand Up @@ -227,6 +228,33 @@ to a hex representation of the base64 data.
ssri.parse('sha1-deadbeef', {single: true}).hexDigest() // '75e69d6de79f'
```

#### <a name="from-hex"></a> `> ssri.fromHex(hexDigest, algorithm, [opts]) -> Integrity`

Creates an `Integrity` object with a single entry, based on a hex-formatted
hash. This is a utility function to help convert existing shasums to the
Integrity format, and is roughly equivalent to something like:

```javascript
algorithm + '-' + Buffer.from(hexDigest, 'hex').toString('base64')
```

`opts.options` may optionally be passed in: it must be an array of option
strings that will be added to all generated integrity metadata generated by
`fromData`. This is a loosely-specified feature of SRIs, and currently has no
specified semantics besides being `?`-separated. Use at your own risk, and
probably avoid if your integrity strings are meant to be used with browsers.

If `opts.strict` is true, the integrity object will be created using strict
parsing rules. See [`ssri.parse`](#parse).

If `opts.single` is true, a single `IntegrityMetadata` object will be returned.

##### Example

```javascript
ssri.fromHex('75e69d6de79f', 'sha1').toString() // 'sha1-deadbeef'
```

#### <a name="from-data"></a> `> ssri.fromData(data, [opts]) -> Integrity`

Creates an `Integrity` object from either string or `Buffer` data, calculating
Expand Down
22 changes: 17 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@ class IntegrityMetadata {
this.options = rawOpts ? rawOpts.slice(1).split('?') : []
}
hexDigest () {
return this.digest && (
Buffer.from
? Buffer.from(this.digest, 'base64')
: new Buffer(this.digest, 'base64')
).toString('hex')
return this.digest && bufFrom(this.digest, 'base64').toString('hex')
}
toString (opts) {
if (opts && opts.strict) {
Expand Down Expand Up @@ -136,6 +132,18 @@ function stringify (obj, opts) {
}
}

module.exports.fromHex = fromHex
function fromHex (hexDigest, algorithm, opts) {
const optString = (opts && opts.options && opts.options.length)
? `?${opts.options.join('?')}`
: ''
return parse(
`${algorithm}-${
bufFrom(hexDigest, 'hex').toString('base64')
}${optString}`, opts
)
}

module.exports.fromData = fromData
function fromData (data, opts) {
opts = opts || {}
Expand Down Expand Up @@ -254,3 +262,7 @@ function getPrioritizedHash (algo1, algo2) {
? algo1
: algo2
}

function bufFrom (data, enc) {
return Buffer.from ? Buffer.from(data, enc) : new Buffer(data, enc)
}
14 changes: 14 additions & 0 deletions test/from.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@ function fileStream () {
return fs.createReadStream(__filename)
}

test('fromHex', t => {
t.equal(
ssri.fromHex('deadbeef', 'sha1').toString(),
`sha1-3q2+7w==`,
'created an Integrity object from a given hex + sha'
)
t.equal(
ssri.fromHex('deadbeef', 'sha512', {options: ['a', 'b', 'c']}).toString(),
`sha512-3q2+7w==?a?b?c`,
'options added to entry'
)
t.done()
})

test('fromData', t => {
t.equal(
ssri.fromData(TEST_DATA).toString(),
Expand Down

0 comments on commit 049b89e

Please sign in to comment.