jose 4.1.3 → 4.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +4 -1
  2. package/dist/browser/index.js +1 -0
  3. package/dist/browser/jwe/flattened/encrypt.js +15 -4
  4. package/dist/browser/jwe/general/decrypt.js +3 -0
  5. package/dist/browser/jwe/general/encrypt.js +156 -0
  6. package/dist/browser/jws/general/sign.js +6 -16
  7. package/dist/browser/key/import.js +2 -1
  8. package/dist/browser/lib/cek.js +5 -6
  9. package/dist/browser/lib/decrypt_key_management.js +1 -1
  10. package/dist/browser/lib/encrypt_key_management.js +1 -1
  11. package/dist/browser/lib/iv.js +4 -11
  12. package/dist/browser/runtime/aeskw.js +2 -1
  13. package/dist/browser/runtime/asn1.js +2 -1
  14. package/dist/browser/runtime/check_key_length.js +0 -7
  15. package/dist/browser/runtime/decrypt.js +2 -1
  16. package/dist/browser/runtime/ecdhes.js +5 -4
  17. package/dist/browser/runtime/encrypt.js +2 -1
  18. package/dist/browser/runtime/get_sign_verify_key.js +3 -2
  19. package/dist/browser/runtime/key_to_jwk.js +2 -1
  20. package/dist/browser/runtime/pbes2kw.js +2 -1
  21. package/dist/browser/runtime/rsaes.js +3 -2
  22. package/dist/node/cjs/index.js +9 -7
  23. package/dist/node/cjs/jwe/flattened/encrypt.js +16 -5
  24. package/dist/node/cjs/jwe/general/decrypt.js +3 -0
  25. package/dist/node/cjs/jwe/general/encrypt.js +160 -0
  26. package/dist/node/cjs/jws/general/sign.js +6 -16
  27. package/dist/node/cjs/key/import.js +2 -1
  28. package/dist/node/cjs/lib/cek.js +5 -6
  29. package/dist/node/cjs/lib/decrypt_key_management.js +1 -1
  30. package/dist/node/cjs/lib/encrypt_key_management.js +1 -1
  31. package/dist/node/cjs/lib/iv.js +4 -11
  32. package/dist/node/cjs/runtime/aeskw.js +4 -3
  33. package/dist/node/cjs/runtime/asn1.js +2 -1
  34. package/dist/node/cjs/runtime/decrypt.js +13 -10
  35. package/dist/node/cjs/runtime/ecdhes.js +5 -4
  36. package/dist/node/cjs/runtime/encrypt.js +7 -5
  37. package/dist/node/cjs/runtime/get_named_curve.js +2 -1
  38. package/dist/node/cjs/runtime/get_sign_verify_key.js +3 -2
  39. package/dist/node/cjs/runtime/key_to_jwk.js +2 -1
  40. package/dist/node/cjs/runtime/pbes2kw.js +2 -1
  41. package/dist/node/cjs/runtime/rsaes.js +4 -3
  42. package/dist/node/cjs/runtime/sign.js +0 -4
  43. package/dist/node/esm/index.js +1 -0
  44. package/dist/node/esm/jwe/flattened/encrypt.js +15 -4
  45. package/dist/node/esm/jwe/general/decrypt.js +3 -0
  46. package/dist/node/esm/jwe/general/encrypt.js +156 -0
  47. package/dist/node/esm/jws/general/sign.js +6 -16
  48. package/dist/node/esm/key/import.js +2 -1
  49. package/dist/node/esm/lib/cek.js +5 -6
  50. package/dist/node/esm/lib/decrypt_key_management.js +1 -1
  51. package/dist/node/esm/lib/encrypt_key_management.js +1 -1
  52. package/dist/node/esm/lib/iv.js +4 -11
  53. package/dist/node/esm/runtime/aeskw.js +4 -3
  54. package/dist/node/esm/runtime/asn1.js +2 -1
  55. package/dist/node/esm/runtime/decrypt.js +13 -10
  56. package/dist/node/esm/runtime/ecdhes.js +5 -4
  57. package/dist/node/esm/runtime/encrypt.js +7 -5
  58. package/dist/node/esm/runtime/get_named_curve.js +2 -1
  59. package/dist/node/esm/runtime/get_sign_verify_key.js +3 -2
  60. package/dist/node/esm/runtime/key_to_jwk.js +2 -1
  61. package/dist/node/esm/runtime/pbes2kw.js +2 -1
  62. package/dist/node/esm/runtime/rsaes.js +4 -3
  63. package/dist/node/esm/runtime/sign.js +0 -4
  64. package/dist/types/index.d.ts +3 -1
  65. package/dist/types/jwe/flattened/encrypt.d.ts +1 -0
  66. package/dist/types/jwe/general/encrypt.d.ts +17 -0
  67. package/dist/types/types.d.ts +2 -1
  68. package/package.json +1 -1
package/README.md CHANGED
@@ -37,7 +37,7 @@ If you or your business use `jose`, please consider becoming a [sponsor][support
37
37
  - [Public Key Import (X.509 Certificate)](docs/functions/key_import.importX509.md#readme)
38
38
  - [Private Key Import (PKCS #8)](docs/functions/key_import.importPKCS8.md#readme)
39
39
  - JSON Web Encryption (JWE)
40
- - Encryption - [Compact](docs/classes/jwe_compact_encrypt.CompactEncrypt.md#readme), [Flattened](docs/classes/jwe_flattened_encrypt.FlattenedEncrypt.md#readme)
40
+ - Encryption - [Compact](docs/classes/jwe_compact_encrypt.CompactEncrypt.md#readme), [Flattened](docs/classes/jwe_flattened_encrypt.FlattenedEncrypt.md#readme), [General](docs/classes/jwe_general_encrypt.GeneralEncrypt.md#readme)
41
41
  - Decryption - [Compact](docs/functions/jwe_compact_decrypt.compactDecrypt.md#readme), [Flattened](docs/functions/jwe_flattened_decrypt.flattenedDecrypt.md#readme), [General](docs/functions/jwe_general_decrypt.generalDecrypt.md#readme)
42
42
  - JSON Web Signature (JWS)
43
43
  - Signing - [Compact](docs/classes/jws_compact_sign.CompactSign.md#readme), [Flattened](docs/classes/jws_flattened_sign.FlattenedSign.md#readme), [General](docs/classes/jws_general_sign.GeneralSign.md#readme)
@@ -65,6 +65,7 @@ If you or your business use `jose`, please consider becoming a [sponsor][support
65
65
  - [Cloudflare Workers Support][]
66
66
  - [Deno Support][]
67
67
  - [Electron Support][]
68
+ - [Next.js Middleware / Vercel Edge Functions Support][]
68
69
  - [Node.js Support][]
69
70
 
70
71
  ## FAQ
@@ -133,8 +134,10 @@ install size should not be a cause for concern.
133
134
  [webcrypto]: https://www.w3.org/TR/WebCryptoAPI/
134
135
  [nodewebcrypto]: https://nodejs.org/docs/latest-v15.x/api/webcrypto.html
135
136
  [deno.land/x/jose]: https://deno.land/x/jose
137
+
136
138
  [Browser Support]: https://github.com/panva/jose/issues/263
137
139
  [Cloudflare Workers Support]: https://github.com/panva/jose/issues/265
138
140
  [Deno Support]: https://github.com/panva/jose/issues/266
139
141
  [Electron Support]: https://github.com/panva/jose/issues/264
142
+ [Next.js Middleware / Vercel Edge Functions Support]: https://github.com/panva/jose/issues/301
140
143
  [Node.js Support]: https://github.com/panva/jose/issues/262
@@ -1,6 +1,7 @@
1
1
  export { compactDecrypt } from './jwe/compact/decrypt.js';
2
2
  export { flattenedDecrypt } from './jwe/flattened/decrypt.js';
3
3
  export { generalDecrypt } from './jwe/general/decrypt.js';
4
+ export { GeneralEncrypt } from './jwe/general/encrypt.js';
4
5
  export { compactVerify } from './jws/compact/verify.js';
5
6
  export { flattenedVerify } from './jws/flattened/verify.js';
6
7
  export { generalVerify } from './jws/general/verify.js';
@@ -7,6 +7,7 @@ import { JOSENotSupported, JWEInvalid } from '../../util/errors.js';
7
7
  import isDisjoint from '../../lib/is_disjoint.js';
8
8
  import { encoder, decoder, concat } from '../../lib/buffer_utils.js';
9
9
  import validateCrit from '../../lib/validate_crit.js';
10
+ export const unprotected = Symbol();
10
11
  export class FlattenedEncrypt {
11
12
  constructor(plaintext) {
12
13
  if (!(plaintext instanceof Uint8Array)) {
@@ -65,7 +66,7 @@ export class FlattenedEncrypt {
65
66
  throw new JWEInvalid('either setProtectedHeader, setUnprotectedHeader, or sharedUnprotectedHeader must be called before #encrypt()');
66
67
  }
67
68
  if (!isDisjoint(this._protectedHeader, this._unprotectedHeader, this._sharedUnprotectedHeader)) {
68
- throw new JWEInvalid('JWE Shared Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint');
69
+ throw new JWEInvalid('JWE Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint');
69
70
  }
70
71
  const joseHeader = {
71
72
  ...this._protectedHeader,
@@ -104,11 +105,21 @@ export class FlattenedEncrypt {
104
105
  let parameters;
105
106
  ({ cek, encryptedKey, parameters } = await encryptKeyManagement(alg, enc, key, this._cek, this._keyManagementParameters));
106
107
  if (parameters) {
107
- if (!this._protectedHeader) {
108
- this.setProtectedHeader(parameters);
108
+ if (options && unprotected in options) {
109
+ if (!this._unprotectedHeader) {
110
+ this.setUnprotectedHeader(parameters);
111
+ }
112
+ else {
113
+ this._unprotectedHeader = { ...this._unprotectedHeader, ...parameters };
114
+ }
109
115
  }
110
116
  else {
111
- this._protectedHeader = { ...this._protectedHeader, ...parameters };
117
+ if (!this._protectedHeader) {
118
+ this.setProtectedHeader(parameters);
119
+ }
120
+ else {
121
+ this._protectedHeader = { ...this._protectedHeader, ...parameters };
122
+ }
112
123
  }
113
124
  }
114
125
  }
@@ -8,6 +8,9 @@ export async function generalDecrypt(jwe, key, options) {
8
8
  if (!Array.isArray(jwe.recipients) || !jwe.recipients.every(isObject)) {
9
9
  throw new JWEInvalid('JWE Recipients missing or incorrect type');
10
10
  }
11
+ if (!jwe.recipients.length) {
12
+ throw new JWEInvalid('JWE Recipients has no members');
13
+ }
11
14
  for (const recipient of jwe.recipients) {
12
15
  try {
13
16
  return await flattenedDecrypt({
@@ -0,0 +1,156 @@
1
+ import { FlattenedEncrypt, unprotected } from '../flattened/encrypt.js';
2
+ import { JWEInvalid } from '../../util/errors.js';
3
+ import generateCek from '../../lib/cek.js';
4
+ import isDisjoint from '../../lib/is_disjoint.js';
5
+ import encryptKeyManagement from '../../lib/encrypt_key_management.js';
6
+ import { encode as base64url } from '../../runtime/base64url.js';
7
+ import validateCrit from '../../lib/validate_crit.js';
8
+ const recipientRef = new WeakMap();
9
+ class IndividualRecipient {
10
+ setUnprotectedHeader(unprotectedHeader) {
11
+ const ref = recipientRef.get(this);
12
+ if (ref.unprotectedHeader) {
13
+ throw new TypeError('setUnprotectedHeader can only be called once');
14
+ }
15
+ ref.unprotectedHeader = unprotectedHeader;
16
+ return this;
17
+ }
18
+ }
19
+ export class GeneralEncrypt {
20
+ constructor(plaintext) {
21
+ this._recipients = [];
22
+ this._plaintext = plaintext;
23
+ }
24
+ addRecipient(key, options) {
25
+ const recipient = new IndividualRecipient();
26
+ recipientRef.set(recipient, { key, options: { crit: options === null || options === void 0 ? void 0 : options.crit } });
27
+ this._recipients.push(recipient);
28
+ return recipient;
29
+ }
30
+ setProtectedHeader(protectedHeader) {
31
+ if (this._protectedHeader) {
32
+ throw new TypeError('setProtectedHeader can only be called once');
33
+ }
34
+ this._protectedHeader = protectedHeader;
35
+ return this;
36
+ }
37
+ setSharedUnprotectedHeader(sharedUnprotectedHeader) {
38
+ if (this._unprotectedHeader) {
39
+ throw new TypeError('setSharedUnprotectedHeader can only be called once');
40
+ }
41
+ this._unprotectedHeader = sharedUnprotectedHeader;
42
+ return this;
43
+ }
44
+ setAdditionalAuthenticatedData(aad) {
45
+ this._aad = aad;
46
+ return this;
47
+ }
48
+ async encrypt(options) {
49
+ var _a, _b;
50
+ if (!this._recipients.length) {
51
+ throw new JWEInvalid('at least one recipient must be added');
52
+ }
53
+ options = { deflateRaw: options === null || options === void 0 ? void 0 : options.deflateRaw };
54
+ if (this._recipients.length === 1) {
55
+ const { unprotectedHeader, options: recipientOpts, key, } = recipientRef.get(this._recipients[0]);
56
+ const flattened = await new FlattenedEncrypt(this._plaintext)
57
+ .setAdditionalAuthenticatedData(this._aad)
58
+ .setProtectedHeader(this._protectedHeader)
59
+ .setSharedUnprotectedHeader(this._unprotectedHeader)
60
+ .setUnprotectedHeader(unprotectedHeader)
61
+ .encrypt(key, { ...recipientOpts, ...options });
62
+ let jwe = {
63
+ ciphertext: flattened.ciphertext,
64
+ iv: flattened.iv,
65
+ recipients: [{}],
66
+ tag: flattened.tag,
67
+ };
68
+ if (flattened.aad)
69
+ jwe.aad = flattened.aad;
70
+ if (flattened.protected)
71
+ jwe.protected = flattened.protected;
72
+ if (flattened.unprotected)
73
+ jwe.unprotected = flattened.unprotected;
74
+ if (flattened.encrypted_key)
75
+ jwe.recipients[0].encrypted_key = flattened.encrypted_key;
76
+ if (flattened.header)
77
+ jwe.recipients[0].header = flattened.header;
78
+ return jwe;
79
+ }
80
+ let enc;
81
+ for (let i = 0; i < this._recipients.length; i++) {
82
+ const recipient = this._recipients[i];
83
+ const { unprotectedHeader, options: recipientOpts } = recipientRef.get(recipient);
84
+ if (!isDisjoint(this._protectedHeader, this._unprotectedHeader, unprotectedHeader)) {
85
+ throw new JWEInvalid('JWE Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint');
86
+ }
87
+ const joseHeader = {
88
+ ...this._protectedHeader,
89
+ ...this._unprotectedHeader,
90
+ ...unprotectedHeader,
91
+ };
92
+ const { alg } = joseHeader;
93
+ if (typeof alg !== 'string' || !alg) {
94
+ throw new JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing or invalid');
95
+ }
96
+ if (alg === 'dir' || alg === 'ECDH-ES') {
97
+ throw new JWEInvalid('"dir" and "ECDH-ES" alg may only be used with a single recipient');
98
+ }
99
+ if (typeof joseHeader.enc !== 'string' || !joseHeader.enc) {
100
+ throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing or invalid');
101
+ }
102
+ if (!enc) {
103
+ enc = joseHeader.enc;
104
+ }
105
+ else if (enc !== joseHeader.enc) {
106
+ throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter must be the same for all recipients');
107
+ }
108
+ validateCrit(JWEInvalid, new Map(), recipientOpts === null || recipientOpts === void 0 ? void 0 : recipientOpts.crit, this._protectedHeader, joseHeader);
109
+ if (joseHeader.zip !== undefined) {
110
+ if (!this._protectedHeader || !this._protectedHeader.zip) {
111
+ throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');
112
+ }
113
+ }
114
+ }
115
+ const cek = generateCek(enc);
116
+ let jwe = {
117
+ ciphertext: '',
118
+ iv: '',
119
+ recipients: [],
120
+ tag: '',
121
+ };
122
+ for (let i = 0; i < this._recipients.length; i++) {
123
+ const recipient = this._recipients[i];
124
+ const target = {};
125
+ jwe.recipients.push(target);
126
+ const { unprotectedHeader, options: recipientOpts, key } = recipientRef.get(recipient);
127
+ if (i === 0) {
128
+ const flattened = await new FlattenedEncrypt(this._plaintext)
129
+ .setAdditionalAuthenticatedData(this._aad)
130
+ .setContentEncryptionKey(cek)
131
+ .setProtectedHeader(this._protectedHeader)
132
+ .setSharedUnprotectedHeader(this._unprotectedHeader)
133
+ .setUnprotectedHeader(unprotectedHeader)
134
+ .encrypt(key, { ...recipientOpts, ...options, [unprotected]: true });
135
+ jwe.ciphertext = flattened.ciphertext;
136
+ jwe.iv = flattened.iv;
137
+ jwe.tag = flattened.tag;
138
+ if (flattened.aad)
139
+ jwe.aad = flattened.aad;
140
+ if (flattened.protected)
141
+ jwe.protected = flattened.protected;
142
+ if (flattened.unprotected)
143
+ jwe.unprotected = flattened.unprotected;
144
+ target.encrypted_key = flattened.encrypted_key;
145
+ if (flattened.header)
146
+ target.header = flattened.header;
147
+ continue;
148
+ }
149
+ const { encryptedKey, parameters } = await encryptKeyManagement((unprotectedHeader === null || unprotectedHeader === void 0 ? void 0 : unprotectedHeader.alg) || ((_a = this._protectedHeader) === null || _a === void 0 ? void 0 : _a.alg) || ((_b = this._unprotectedHeader) === null || _b === void 0 ? void 0 : _b.alg), enc, key, cek);
150
+ target.encrypted_key = base64url(encryptedKey);
151
+ if (unprotectedHeader || parameters)
152
+ target.header = { ...unprotectedHeader, ...parameters };
153
+ }
154
+ return jwe;
155
+ }
156
+ }
@@ -3,31 +3,21 @@ import { JWSInvalid } from '../../util/errors.js';
3
3
  const signatureRef = new WeakMap();
4
4
  class IndividualSignature {
5
5
  setProtectedHeader(protectedHeader) {
6
- if (this._protectedHeader) {
6
+ const ref = signatureRef.get(this);
7
+ if (ref.protectedHeader) {
7
8
  throw new TypeError('setProtectedHeader can only be called once');
8
9
  }
9
- this._protectedHeader = protectedHeader;
10
+ ref.protectedHeader = protectedHeader;
10
11
  return this;
11
12
  }
12
13
  setUnprotectedHeader(unprotectedHeader) {
13
- if (this._unprotectedHeader) {
14
+ const ref = signatureRef.get(this);
15
+ if (ref.unprotectedHeader) {
14
16
  throw new TypeError('setUnprotectedHeader can only be called once');
15
17
  }
16
- this._unprotectedHeader = unprotectedHeader;
18
+ ref.unprotectedHeader = unprotectedHeader;
17
19
  return this;
18
20
  }
19
- set _protectedHeader(value) {
20
- signatureRef.get(this).protectedHeader = value;
21
- }
22
- get _protectedHeader() {
23
- return signatureRef.get(this).protectedHeader;
24
- }
25
- set _unprotectedHeader(value) {
26
- signatureRef.get(this).unprotectedHeader = value;
27
- }
28
- get _unprotectedHeader() {
29
- return signatureRef.get(this).unprotectedHeader;
30
- }
31
21
  }
32
22
  export class GeneralSign {
33
23
  constructor(payload) {
@@ -62,7 +62,8 @@ function parseElement(bytes) {
62
62
  };
63
63
  }
64
64
  function spkiFromX509(buf) {
65
- return encodeBase64(getElement(getElement(parseElement(buf).contents)[0].contents)[6].raw);
65
+ const tbsCertificate = getElement(getElement(parseElement(buf).contents)[0].contents);
66
+ return encodeBase64(tbsCertificate[tbsCertificate[0].raw[0] === 0xa0 ? 6 : 5].raw);
66
67
  }
67
68
  function getSPKI(x509) {
68
69
  const pem = x509.replace(/(?:-----(?:BEGIN|END) CERTIFICATE-----|\s)/g, '');
@@ -2,18 +2,17 @@ import { JOSENotSupported } from '../util/errors.js';
2
2
  import random from '../runtime/random.js';
3
3
  export function bitLength(alg) {
4
4
  switch (alg) {
5
- case 'A128CBC-HS256':
6
- return 256;
7
- case 'A192CBC-HS384':
8
- return 384;
9
- case 'A256CBC-HS512':
10
- return 512;
11
5
  case 'A128GCM':
12
6
  return 128;
13
7
  case 'A192GCM':
14
8
  return 192;
15
9
  case 'A256GCM':
10
+ case 'A128CBC-HS256':
16
11
  return 256;
12
+ case 'A192CBC-HS384':
13
+ return 384;
14
+ case 'A256CBC-HS512':
15
+ return 512;
17
16
  default:
18
17
  throw new JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`);
19
18
  }
@@ -40,7 +40,7 @@ async function decryptKeyManagement(alg, key, encryptedKey, joseHeader) {
40
40
  throw new JWEInvalid(`JOSE Header "apv" (Agreement PartyVInfo) invalid`);
41
41
  partyVInfo = base64url(joseHeader.apv);
42
42
  }
43
- const sharedSecret = await ECDH.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, parseInt(alg.substr(-5, 3), 10) || cekLength(joseHeader.enc), partyUInfo, partyVInfo);
43
+ const sharedSecret = await ECDH.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, alg === 'ECDH-ES' ? cekLength(joseHeader.enc) : parseInt(alg.substr(-5, 3), 10), partyUInfo, partyVInfo);
44
44
  if (alg === 'ECDH-ES')
45
45
  return sharedSecret;
46
46
  if (encryptedKey === undefined)
@@ -29,7 +29,7 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
29
29
  let { epk: ephemeralKey } = providedParameters;
30
30
  ephemeralKey || (ephemeralKey = await ECDH.generateEpk(key));
31
31
  const { x, y, crv, kty } = await exportJWK(ephemeralKey);
32
- const sharedSecret = await ECDH.deriveKey(key, ephemeralKey, alg === 'ECDH-ES' ? enc : alg, parseInt(alg.substr(-5, 3), 10) || cekLength(enc), apu, apv);
32
+ const sharedSecret = await ECDH.deriveKey(key, ephemeralKey, alg === 'ECDH-ES' ? enc : alg, alg === 'ECDH-ES' ? cekLength(enc) : parseInt(alg.substr(-5, 3), 10), apu, apv);
33
33
  parameters = { epk: { x, y, crv, kty } };
34
34
  if (apu)
35
35
  parameters.apu = base64url(apu);
@@ -2,24 +2,17 @@ import { JOSENotSupported } from '../util/errors.js';
2
2
  import random from '../runtime/random.js';
3
3
  export function bitLength(alg) {
4
4
  switch (alg) {
5
- case 'A128CBC-HS256':
6
- return 128;
7
5
  case 'A128GCM':
8
- return 96;
9
6
  case 'A128GCMKW':
10
- return 96;
11
- case 'A192CBC-HS384':
12
- return 128;
13
7
  case 'A192GCM':
14
- return 96;
15
8
  case 'A192GCMKW':
16
- return 96;
17
- case 'A256CBC-HS512':
18
- return 128;
19
9
  case 'A256GCM':
20
- return 96;
21
10
  case 'A256GCMKW':
22
11
  return 96;
12
+ case 'A128CBC-HS256':
13
+ case 'A192CBC-HS384':
14
+ case 'A256CBC-HS512':
15
+ return 128;
23
16
  default:
24
17
  throw new JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`);
25
18
  }
@@ -2,6 +2,7 @@ import bogusWebCrypto from './bogus.js';
2
2
  import crypto, { isCryptoKey } from './webcrypto.js';
3
3
  import { checkEncCryptoKey } from '../lib/crypto_key.js';
4
4
  import invalidKeyInput from '../lib/invalid_key_input.js';
5
+ import { types } from './is_key_like.js';
5
6
  function checkKeySize(key, alg) {
6
7
  if (key.algorithm.length !== parseInt(alg.substr(1, 3), 10)) {
7
8
  throw new TypeError(`Invalid key size for alg: ${alg}`);
@@ -15,7 +16,7 @@ function getCryptoKey(key, alg, usage) {
15
16
  if (key instanceof Uint8Array) {
16
17
  return crypto.subtle.importKey('raw', key, 'AES-KW', true, [usage]);
17
18
  }
18
- throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'Uint8Array'));
19
+ throw new TypeError(invalidKeyInput(key, ...types, 'Uint8Array'));
19
20
  }
20
21
  export const wrap = async (alg, key, cek) => {
21
22
  const cryptoKey = await getCryptoKey(key, alg, 'wrapKey');
@@ -4,9 +4,10 @@ import invalidKeyInput from '../lib/invalid_key_input.js';
4
4
  import { encodeBase64 } from './base64url.js';
5
5
  import formatPEM from '../lib/format_pem.js';
6
6
  import { JOSENotSupported } from '../util/errors.js';
7
+ import { types } from './is_key_like.js';
7
8
  const genericExport = async (keyType, keyFormat, key) => {
8
9
  if (!isCryptoKey(key)) {
9
- throw new TypeError(invalidKeyInput(key, 'CryptoKey'));
10
+ throw new TypeError(invalidKeyInput(key, ...types));
10
11
  }
11
12
  if (!key.extractable) {
12
13
  throw new TypeError('CryptoKey is not extractable');
@@ -1,11 +1,4 @@
1
1
  export default (alg, key) => {
2
- if (alg.startsWith('HS')) {
3
- const bitlen = parseInt(alg.substr(-3), 10);
4
- const { length } = key.algorithm;
5
- if (typeof length !== 'number' || length < bitlen) {
6
- throw new TypeError(`${alg} requires symmetric keys to be ${bitlen} bits or larger`);
7
- }
8
- }
9
2
  if (alg.startsWith('RS') || alg.startsWith('PS')) {
10
3
  const { modulusLength } = key.algorithm;
11
4
  if (typeof modulusLength !== 'number' || modulusLength < 2048) {
@@ -6,6 +6,7 @@ import { JOSENotSupported, JWEDecryptionFailed } from '../util/errors.js';
6
6
  import crypto, { isCryptoKey } from './webcrypto.js';
7
7
  import { checkEncCryptoKey } from '../lib/crypto_key.js';
8
8
  import invalidKeyInput from '../lib/invalid_key_input.js';
9
+ import { types } from './is_key_like.js';
9
10
  async function cbcDecrypt(enc, cek, ciphertext, iv, tag, aad) {
10
11
  if (!(cek instanceof Uint8Array)) {
11
12
  throw new TypeError(invalidKeyInput(cek, 'Uint8Array'));
@@ -61,7 +62,7 @@ async function gcmDecrypt(enc, cek, ciphertext, iv, tag, aad) {
61
62
  }
62
63
  const decrypt = async (enc, cek, ciphertext, iv, tag, aad) => {
63
64
  if (!isCryptoKey(cek) && !(cek instanceof Uint8Array)) {
64
- throw new TypeError(invalidKeyInput(cek, 'CryptoKey', 'Uint8Array'));
65
+ throw new TypeError(invalidKeyInput(cek, ...types, 'Uint8Array'));
65
66
  }
66
67
  checkIvLength(enc, iv);
67
68
  switch (enc) {
@@ -3,13 +3,14 @@ import crypto, { isCryptoKey } from './webcrypto.js';
3
3
  import { checkEncCryptoKey } from '../lib/crypto_key.js';
4
4
  import digest from './digest.js';
5
5
  import invalidKeyInput from '../lib/invalid_key_input.js';
6
+ import { types } from './is_key_like.js';
6
7
  export const deriveKey = async (publicKey, privateKey, algorithm, keyLength, apu = new Uint8Array(0), apv = new Uint8Array(0)) => {
7
8
  if (!isCryptoKey(publicKey)) {
8
- throw new TypeError(invalidKeyInput(publicKey, 'CryptoKey'));
9
+ throw new TypeError(invalidKeyInput(publicKey, ...types));
9
10
  }
10
11
  checkEncCryptoKey(publicKey, 'ECDH-ES');
11
12
  if (!isCryptoKey(privateKey)) {
12
- throw new TypeError(invalidKeyInput(privateKey, 'CryptoKey'));
13
+ throw new TypeError(invalidKeyInput(privateKey, ...types));
13
14
  }
14
15
  checkEncCryptoKey(privateKey, 'ECDH-ES', 'deriveBits', 'deriveKey');
15
16
  const value = concat(lengthAndInput(encoder.encode(algorithm)), lengthAndInput(apu), lengthAndInput(apv), uint32be(keyLength));
@@ -25,13 +26,13 @@ export const deriveKey = async (publicKey, privateKey, algorithm, keyLength, apu
25
26
  };
26
27
  export const generateEpk = async (key) => {
27
28
  if (!isCryptoKey(key)) {
28
- throw new TypeError(invalidKeyInput(key, 'CryptoKey'));
29
+ throw new TypeError(invalidKeyInput(key, ...types));
29
30
  }
30
31
  return (await crypto.subtle.generateKey({ name: 'ECDH', namedCurve: key.algorithm.namedCurve }, true, ['deriveBits'])).privateKey;
31
32
  };
32
33
  export const ecdhAllowed = (key) => {
33
34
  if (!isCryptoKey(key)) {
34
- throw new TypeError(invalidKeyInput(key, 'CryptoKey'));
35
+ throw new TypeError(invalidKeyInput(key, ...types));
35
36
  }
36
37
  return ['P-256', 'P-384', 'P-521'].includes(key.algorithm.namedCurve);
37
38
  };
@@ -5,6 +5,7 @@ import crypto, { isCryptoKey } from './webcrypto.js';
5
5
  import { checkEncCryptoKey } from '../lib/crypto_key.js';
6
6
  import invalidKeyInput from '../lib/invalid_key_input.js';
7
7
  import { JOSENotSupported } from '../util/errors.js';
8
+ import { types } from './is_key_like.js';
8
9
  async function cbcEncrypt(enc, plaintext, cek, iv, aad) {
9
10
  if (!(cek instanceof Uint8Array)) {
10
11
  throw new TypeError(invalidKeyInput(cek, 'Uint8Array'));
@@ -44,7 +45,7 @@ async function gcmEncrypt(enc, plaintext, cek, iv, aad) {
44
45
  }
45
46
  const encrypt = async (enc, plaintext, cek, iv, aad) => {
46
47
  if (!isCryptoKey(cek) && !(cek instanceof Uint8Array)) {
47
- throw new TypeError(invalidKeyInput(cek, 'CryptoKey', 'Uint8Array'));
48
+ throw new TypeError(invalidKeyInput(cek, ...types, 'Uint8Array'));
48
49
  }
49
50
  checkIvLength(enc, iv);
50
51
  switch (enc) {
@@ -1,6 +1,7 @@
1
1
  import crypto, { isCryptoKey } from './webcrypto.js';
2
2
  import { checkSigCryptoKey } from '../lib/crypto_key.js';
3
3
  import invalidKeyInput from '../lib/invalid_key_input.js';
4
+ import { types } from './is_key_like.js';
4
5
  export default function getCryptoKey(alg, key, usage) {
5
6
  if (isCryptoKey(key)) {
6
7
  checkSigCryptoKey(key, alg, usage);
@@ -8,9 +9,9 @@ export default function getCryptoKey(alg, key, usage) {
8
9
  }
9
10
  if (key instanceof Uint8Array) {
10
11
  if (!alg.startsWith('HS')) {
11
- throw new TypeError(invalidKeyInput(key, 'CryptoKey'));
12
+ throw new TypeError(invalidKeyInput(key, ...types));
12
13
  }
13
14
  return crypto.subtle.importKey('raw', key, { hash: `SHA-${alg.substr(-3)}`, name: 'HMAC' }, false, [usage]);
14
15
  }
15
- throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'Uint8Array'));
16
+ throw new TypeError(invalidKeyInput(key, ...types, 'Uint8Array'));
16
17
  }
@@ -1,6 +1,7 @@
1
1
  import crypto, { isCryptoKey } from './webcrypto.js';
2
2
  import invalidKeyInput from '../lib/invalid_key_input.js';
3
3
  import { encode as base64url } from './base64url.js';
4
+ import { types } from './is_key_like.js';
4
5
  const keyToJWK = async (key) => {
5
6
  if (key instanceof Uint8Array) {
6
7
  return {
@@ -9,7 +10,7 @@ const keyToJWK = async (key) => {
9
10
  };
10
11
  }
11
12
  if (!isCryptoKey(key)) {
12
- throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'Uint8Array'));
13
+ throw new TypeError(invalidKeyInput(key, ...types, 'Uint8Array'));
13
14
  }
14
15
  if (!key.extractable) {
15
16
  throw new TypeError('non-extractable CryptoKey cannot be exported as a JWK');
@@ -6,6 +6,7 @@ import checkP2s from '../lib/check_p2s.js';
6
6
  import crypto, { isCryptoKey } from './webcrypto.js';
7
7
  import { checkEncCryptoKey } from '../lib/crypto_key.js';
8
8
  import invalidKeyInput from '../lib/invalid_key_input.js';
9
+ import { types } from './is_key_like.js';
9
10
  function getCryptoKey(key, alg) {
10
11
  if (key instanceof Uint8Array) {
11
12
  return crypto.subtle.importKey('raw', key, 'PBKDF2', false, ['deriveBits']);
@@ -14,7 +15,7 @@ function getCryptoKey(key, alg) {
14
15
  checkEncCryptoKey(key, alg, 'deriveBits', 'deriveKey');
15
16
  return key;
16
17
  }
17
- throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'Uint8Array'));
18
+ throw new TypeError(invalidKeyInput(key, ...types, 'Uint8Array'));
18
19
  }
19
20
  async function deriveKey(p2s, alg, p2c, key) {
20
21
  checkP2s(p2s);
@@ -4,9 +4,10 @@ import crypto, { isCryptoKey } from './webcrypto.js';
4
4
  import { checkEncCryptoKey } from '../lib/crypto_key.js';
5
5
  import checkKeyLength from './check_key_length.js';
6
6
  import invalidKeyInput from '../lib/invalid_key_input.js';
7
+ import { types } from './is_key_like.js';
7
8
  export const encrypt = async (alg, key, cek) => {
8
9
  if (!isCryptoKey(key)) {
9
- throw new TypeError(invalidKeyInput(key, 'CryptoKey'));
10
+ throw new TypeError(invalidKeyInput(key, ...types));
10
11
  }
11
12
  checkEncCryptoKey(key, alg, 'encrypt', 'wrapKey');
12
13
  checkKeyLength(alg, key);
@@ -21,7 +22,7 @@ export const encrypt = async (alg, key, cek) => {
21
22
  };
22
23
  export const decrypt = async (alg, key, encryptedKey) => {
23
24
  if (!isCryptoKey(key)) {
24
- throw new TypeError(invalidKeyInput(key, 'CryptoKey'));
25
+ throw new TypeError(invalidKeyInput(key, ...types));
25
26
  }
26
27
  checkEncCryptoKey(key, alg, 'decrypt', 'unwrapKey');
27
28
  checkKeyLength(alg, key);
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.base64url = exports.generateSecret = exports.generateKeyPair = exports.errors = exports.decodeProtectedHeader = exports.importJWK = exports.importX509 = exports.importPKCS8 = exports.importSPKI = exports.exportJWK = exports.exportSPKI = exports.exportPKCS8 = exports.UnsecuredJWT = exports.createRemoteJWKSet = exports.EmbeddedJWK = exports.calculateJwkThumbprint = exports.EncryptJWT = exports.SignJWT = exports.GeneralSign = exports.FlattenedSign = exports.CompactSign = exports.FlattenedEncrypt = exports.CompactEncrypt = exports.jwtDecrypt = exports.jwtVerify = exports.generalVerify = exports.flattenedVerify = exports.compactVerify = exports.generalDecrypt = exports.flattenedDecrypt = exports.compactDecrypt = void 0;
3
+ exports.base64url = exports.generateSecret = exports.generateKeyPair = exports.errors = exports.decodeProtectedHeader = exports.importJWK = exports.importX509 = exports.importPKCS8 = exports.importSPKI = exports.exportJWK = exports.exportSPKI = exports.exportPKCS8 = exports.UnsecuredJWT = exports.createRemoteJWKSet = exports.EmbeddedJWK = exports.calculateJwkThumbprint = exports.EncryptJWT = exports.SignJWT = exports.GeneralSign = exports.FlattenedSign = exports.CompactSign = exports.FlattenedEncrypt = exports.CompactEncrypt = exports.jwtDecrypt = exports.jwtVerify = exports.generalVerify = exports.flattenedVerify = exports.compactVerify = exports.GeneralEncrypt = exports.generalDecrypt = exports.flattenedDecrypt = exports.compactDecrypt = void 0;
4
4
  var decrypt_js_1 = require("./jwe/compact/decrypt.js");
5
5
  Object.defineProperty(exports, "compactDecrypt", { enumerable: true, get: function () { return decrypt_js_1.compactDecrypt; } });
6
6
  var decrypt_js_2 = require("./jwe/flattened/decrypt.js");
7
7
  Object.defineProperty(exports, "flattenedDecrypt", { enumerable: true, get: function () { return decrypt_js_2.flattenedDecrypt; } });
8
8
  var decrypt_js_3 = require("./jwe/general/decrypt.js");
9
9
  Object.defineProperty(exports, "generalDecrypt", { enumerable: true, get: function () { return decrypt_js_3.generalDecrypt; } });
10
+ var encrypt_js_1 = require("./jwe/general/encrypt.js");
11
+ Object.defineProperty(exports, "GeneralEncrypt", { enumerable: true, get: function () { return encrypt_js_1.GeneralEncrypt; } });
10
12
  var verify_js_1 = require("./jws/compact/verify.js");
11
13
  Object.defineProperty(exports, "compactVerify", { enumerable: true, get: function () { return verify_js_1.compactVerify; } });
12
14
  var verify_js_2 = require("./jws/flattened/verify.js");
@@ -17,10 +19,10 @@ var verify_js_4 = require("./jwt/verify.js");
17
19
  Object.defineProperty(exports, "jwtVerify", { enumerable: true, get: function () { return verify_js_4.jwtVerify; } });
18
20
  var decrypt_js_4 = require("./jwt/decrypt.js");
19
21
  Object.defineProperty(exports, "jwtDecrypt", { enumerable: true, get: function () { return decrypt_js_4.jwtDecrypt; } });
20
- var encrypt_js_1 = require("./jwe/compact/encrypt.js");
21
- Object.defineProperty(exports, "CompactEncrypt", { enumerable: true, get: function () { return encrypt_js_1.CompactEncrypt; } });
22
- var encrypt_js_2 = require("./jwe/flattened/encrypt.js");
23
- Object.defineProperty(exports, "FlattenedEncrypt", { enumerable: true, get: function () { return encrypt_js_2.FlattenedEncrypt; } });
22
+ var encrypt_js_2 = require("./jwe/compact/encrypt.js");
23
+ Object.defineProperty(exports, "CompactEncrypt", { enumerable: true, get: function () { return encrypt_js_2.CompactEncrypt; } });
24
+ var encrypt_js_3 = require("./jwe/flattened/encrypt.js");
25
+ Object.defineProperty(exports, "FlattenedEncrypt", { enumerable: true, get: function () { return encrypt_js_3.FlattenedEncrypt; } });
24
26
  var sign_js_1 = require("./jws/compact/sign.js");
25
27
  Object.defineProperty(exports, "CompactSign", { enumerable: true, get: function () { return sign_js_1.CompactSign; } });
26
28
  var sign_js_2 = require("./jws/flattened/sign.js");
@@ -29,8 +31,8 @@ var sign_js_3 = require("./jws/general/sign.js");
29
31
  Object.defineProperty(exports, "GeneralSign", { enumerable: true, get: function () { return sign_js_3.GeneralSign; } });
30
32
  var sign_js_4 = require("./jwt/sign.js");
31
33
  Object.defineProperty(exports, "SignJWT", { enumerable: true, get: function () { return sign_js_4.SignJWT; } });
32
- var encrypt_js_3 = require("./jwt/encrypt.js");
33
- Object.defineProperty(exports, "EncryptJWT", { enumerable: true, get: function () { return encrypt_js_3.EncryptJWT; } });
34
+ var encrypt_js_4 = require("./jwt/encrypt.js");
35
+ Object.defineProperty(exports, "EncryptJWT", { enumerable: true, get: function () { return encrypt_js_4.EncryptJWT; } });
34
36
  var thumbprint_js_1 = require("./jwk/thumbprint.js");
35
37
  Object.defineProperty(exports, "calculateJwkThumbprint", { enumerable: true, get: function () { return thumbprint_js_1.calculateJwkThumbprint; } });
36
38
  var embedded_js_1 = require("./jwk/embedded.js");