UNPKG

2.25 kBJavaScriptView Raw
1const isDisjoint = require('../help/is_disjoint')
2const base64url = require('../help/base64url')
3let validateCrit = require('../help/validate_crit')
4const { JWEInvalid, JOSENotSupported } = require('../errors')
5
6validateCrit = validateCrit.bind(undefined, JWEInvalid)
7
8module.exports = (prot, unprotected, recipients, checkAlgorithms, crit) => {
9 if (typeof prot === 'string') {
10 try {
11 prot = base64url.JSON.decode(prot)
12 } catch (err) {
13 throw new JWEInvalid('could not parse JWE protected header')
14 }
15 }
16
17 let alg = []
18 const enc = new Set()
19 if (!isDisjoint(prot, unprotected) || !recipients.every(({ header }) => {
20 if (typeof header === 'object') {
21 alg.push(header.alg)
22 enc.add(header.enc)
23 }
24 const combined = { ...unprotected, ...header }
25 validateCrit(prot, combined, crit)
26 if ('zip' in combined) {
27 throw new JWEInvalid('"zip" Header Parameter MUST be integrity protected')
28 } else if (prot && 'zip' in prot && prot.zip !== 'DEF') {
29 throw new JOSENotSupported('only "DEF" compression algorithm is supported')
30 }
31 return isDisjoint(header, prot) && isDisjoint(header, unprotected)
32 })) {
33 throw new JWEInvalid('JWE Shared Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint')
34 }
35
36 if (typeof prot === 'object') {
37 alg.push(prot.alg)
38 enc.add(prot.enc)
39 }
40 if (typeof unprotected === 'object') {
41 alg.push(unprotected.alg)
42 enc.add(unprotected.enc)
43 }
44
45 alg = alg.filter(Boolean)
46 enc.delete(undefined)
47
48 if (recipients.length !== 1) {
49 if (alg.includes('dir') || alg.includes('ECDH-ES')) {
50 throw new JWEInvalid('dir and ECDH-ES alg may only be used with a single recipient')
51 }
52 }
53
54 if (checkAlgorithms) {
55 if (alg.length !== recipients.length) {
56 throw new JWEInvalid('missing Key Management algorithm')
57 }
58 if (enc.size === 0) {
59 throw new JWEInvalid('missing Content Encryption algorithm')
60 } else if (enc.size !== 1) {
61 throw new JWEInvalid('there must only be one Content Encryption algorithm')
62 }
63 } else {
64 if (enc.size > 1) {
65 throw new JWEInvalid('there must only be one Content Encryption algorithm')
66 }
67 }
68
69 return [...enc][0]
70}