71 lines
2.2 KiB
JavaScript
71 lines
2.2 KiB
JavaScript
const isDisjoint = require('../help/is_disjoint')
|
|
const base64url = require('../help/base64url')
|
|
let validateCrit = require('../help/validate_crit')
|
|
const { JWEInvalid, JOSENotSupported } = require('../errors')
|
|
|
|
validateCrit = validateCrit.bind(undefined, JWEInvalid)
|
|
|
|
module.exports = (prot, unprotected, recipients, checkAlgorithms, crit) => {
|
|
if (typeof prot === 'string') {
|
|
try {
|
|
prot = base64url.JSON.decode(prot)
|
|
} catch (err) {
|
|
throw new JWEInvalid('could not parse JWE protected header')
|
|
}
|
|
}
|
|
|
|
let alg = []
|
|
const enc = new Set()
|
|
if (!isDisjoint(prot, unprotected) || !recipients.every(({ header }) => {
|
|
if (typeof header === 'object') {
|
|
alg.push(header.alg)
|
|
enc.add(header.enc)
|
|
}
|
|
const combined = { ...unprotected, ...header }
|
|
validateCrit(prot, combined, crit)
|
|
if ('zip' in combined) {
|
|
throw new JWEInvalid('"zip" Header Parameter MUST be integrity protected')
|
|
} else if (prot && 'zip' in prot && prot.zip !== 'DEF') {
|
|
throw new JOSENotSupported('only "DEF" compression algorithm is supported')
|
|
}
|
|
return isDisjoint(header, prot) && isDisjoint(header, unprotected)
|
|
})) {
|
|
throw new JWEInvalid('JWE Shared Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint')
|
|
}
|
|
|
|
if (typeof prot === 'object') {
|
|
alg.push(prot.alg)
|
|
enc.add(prot.enc)
|
|
}
|
|
if (typeof unprotected === 'object') {
|
|
alg.push(unprotected.alg)
|
|
enc.add(unprotected.enc)
|
|
}
|
|
|
|
alg = alg.filter(Boolean)
|
|
enc.delete(undefined)
|
|
|
|
if (recipients.length !== 1) {
|
|
if (alg.includes('dir') || alg.includes('ECDH-ES')) {
|
|
throw new JWEInvalid('dir and ECDH-ES alg may only be used with a single recipient')
|
|
}
|
|
}
|
|
|
|
if (checkAlgorithms) {
|
|
if (alg.length !== recipients.length) {
|
|
throw new JWEInvalid('missing Key Management algorithm')
|
|
}
|
|
if (enc.size === 0) {
|
|
throw new JWEInvalid('missing Content Encryption algorithm')
|
|
} else if (enc.size !== 1) {
|
|
throw new JWEInvalid('there must only be one Content Encryption algorithm')
|
|
}
|
|
} else {
|
|
if (enc.size > 1) {
|
|
throw new JWEInvalid('there must only be one Content Encryption algorithm')
|
|
}
|
|
}
|
|
|
|
return [...enc][0]
|
|
}
|