Skip to content

Commit

Permalink
fix: ensure "b64" is the same for all recipients edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Aug 4, 2020
1 parent 1695423 commit d56ec9f
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 13 deletions.
11 changes: 11 additions & 0 deletions lib/jws/serializers.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,20 @@ const generalSerializer = (payload, recipients) => {
}
}
generalSerializer.validate = (jws, recipients) => {
let validateB64 = false
recipients.forEach(({ protectedHeader, unprotectedHeader }) => {
if (protectedHeader && !validateB64 && 'b64' in protectedHeader) {
validateB64 = true
}
validateCrit(protectedHeader, unprotectedHeader, protectedHeader ? protectedHeader.crit : undefined)
})

if (validateB64) {
const values = recipients.map(({ protectedHeader }) => protectedHeader && protectedHeader.b64)
if (!values.every((actual, i, [expected]) => actual === expected)) {
throw new JWSInvalid('the "b64" Header Parameter value MUST be the same for all recipients')
}
}
}

const isJSON = (input) => {
Expand Down
6 changes: 0 additions & 6 deletions lib/jws/sign.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,6 @@ class Sign {

let toBeSigned
if (joseHeader.protected.crit && joseHeader.protected.crit.includes('b64')) {
if (this._b64 !== undefined && this._b64 !== joseHeader.protected.b64) {
throw new JWSInvalid('the "b64" Header Parameter value MUST be the same for all recipients')
} else {
this._b64 = joseHeader.protected.b64
}

if (first && !joseHeader.protected.b64) {
if (this._binary) {
this._payload = base64url.decodeToBuffer(this._payload)
Expand Down
52 changes: 45 additions & 7 deletions test/jws/b64.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,49 @@ test('b64 must be a boolean', t => {
})

test('b64 must be the same for all recipients', t => {
const sign = new JWS.Sign('$.02')
sign.recipient(k, { crit: ['b64'], b64: false })
sign.recipient(k, { crit: ['b64'], b64: true })

t.throws(() => {
sign.sign('general')
}, { instanceOf: errors.JWSInvalid, code: 'ERR_JWS_INVALID', message: 'the "b64" Header Parameter value MUST be the same for all recipients' })
{
const sign = new JWS.Sign('$.02')
sign.recipient(k, { crit: ['b64'], b64: false })
sign.recipient(k, { crit: ['b64'], b64: true })

t.throws(() => {
sign.sign('general')
}, { instanceOf: errors.JWSInvalid, code: 'ERR_JWS_INVALID', message: 'the "b64" Header Parameter value MUST be the same for all recipients' })
}

{
const sign = new JWS.Sign('$.02')
sign.recipient(k)
sign.recipient(k, { crit: ['b64'], b64: true })
t.throws(() => {
sign.sign('general')
}, { instanceOf: errors.JWSInvalid, code: 'ERR_JWS_INVALID', message: 'the "b64" Header Parameter value MUST be the same for all recipients' })
}

{
const sign = new JWS.Sign('$.02')
sign.recipient(k, { crit: ['b64'], b64: true })
sign.recipient(k)
t.throws(() => {
sign.sign('general')
}, { instanceOf: errors.JWSInvalid, code: 'ERR_JWS_INVALID', message: 'the "b64" Header Parameter value MUST be the same for all recipients' })
}

{
const sign = new JWS.Sign('$.02')
sign.recipient(k)
sign.recipient(k, { crit: ['b64'], b64: false })
t.throws(() => {
sign.sign('general')
}, { instanceOf: errors.JWSInvalid, code: 'ERR_JWS_INVALID', message: 'the "b64" Header Parameter value MUST be the same for all recipients' })
}

{
const sign = new JWS.Sign('$.02')
sign.recipient(k, { crit: ['b64'], b64: false })
sign.recipient(k)
t.throws(() => {
sign.sign('general')
}, { instanceOf: errors.JWSInvalid, code: 'ERR_JWS_INVALID', message: 'the "b64" Header Parameter value MUST be the same for all recipients' })
}
})

0 comments on commit d56ec9f

Please sign in to comment.