jose 6.1.3 → 6.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 (52) hide show
  1. package/dist/types/jwe/general/decrypt.d.ts +7 -0
  2. package/dist/types/jws/general/verify.d.ts +8 -0
  3. package/dist/types/types.d.ts +15 -4
  4. package/dist/webapi/jwe/flattened/decrypt.js +28 -38
  5. package/dist/webapi/jwe/flattened/encrypt.js +21 -25
  6. package/dist/webapi/jwe/general/decrypt.js +1 -1
  7. package/dist/webapi/jwe/general/encrypt.js +13 -18
  8. package/dist/webapi/jwk/embedded.js +1 -1
  9. package/dist/webapi/jwk/thumbprint.js +2 -2
  10. package/dist/webapi/jwks/local.js +1 -1
  11. package/dist/webapi/jwks/remote.js +2 -2
  12. package/dist/webapi/jws/flattened/sign.js +5 -8
  13. package/dist/webapi/jws/flattened/verify.js +6 -16
  14. package/dist/webapi/jws/general/sign.js +3 -6
  15. package/dist/webapi/jws/general/verify.js +1 -1
  16. package/dist/webapi/jwt/encrypt.js +5 -12
  17. package/dist/webapi/key/import.js +1 -1
  18. package/dist/webapi/lib/aesgcmkw.js +1 -2
  19. package/dist/webapi/lib/check_key_type.js +1 -1
  20. package/dist/webapi/lib/content_encryption.js +217 -0
  21. package/dist/webapi/lib/crypto_key.js +9 -16
  22. package/dist/webapi/lib/deflate.js +44 -0
  23. package/dist/webapi/lib/ecdhes.js +1 -1
  24. package/dist/webapi/lib/helpers.js +19 -0
  25. package/dist/webapi/lib/jwk_to_key.js +9 -11
  26. package/dist/webapi/lib/jwt_claims_set.js +1 -1
  27. package/dist/webapi/lib/key_management.js +186 -0
  28. package/dist/webapi/lib/normalize_key.js +10 -20
  29. package/dist/webapi/lib/rsaes.js +1 -1
  30. package/dist/webapi/lib/signing.js +68 -0
  31. package/dist/webapi/lib/type_checks.js +40 -0
  32. package/dist/webapi/util/decode_jwt.js +1 -1
  33. package/dist/webapi/util/decode_protected_header.js +1 -1
  34. package/package.json +1 -1
  35. package/dist/webapi/lib/cek.js +0 -19
  36. package/dist/webapi/lib/check_cek_length.js +0 -7
  37. package/dist/webapi/lib/check_iv_length.js +0 -7
  38. package/dist/webapi/lib/check_key_length.js +0 -8
  39. package/dist/webapi/lib/decrypt.js +0 -106
  40. package/dist/webapi/lib/decrypt_key_management.js +0 -127
  41. package/dist/webapi/lib/digest.js +0 -4
  42. package/dist/webapi/lib/encrypt.js +0 -74
  43. package/dist/webapi/lib/encrypt_key_management.js +0 -92
  44. package/dist/webapi/lib/get_sign_verify_key.js +0 -12
  45. package/dist/webapi/lib/is_disjoint.js +0 -21
  46. package/dist/webapi/lib/is_jwk.js +0 -6
  47. package/dist/webapi/lib/is_object.js +0 -14
  48. package/dist/webapi/lib/iv.js +0 -19
  49. package/dist/webapi/lib/private_symbols.js +0 -1
  50. package/dist/webapi/lib/sign.js +0 -9
  51. package/dist/webapi/lib/subtle_dsa.js +0 -31
  52. package/dist/webapi/lib/verify.js +0 -14
@@ -16,6 +16,13 @@ export interface GeneralDecryptGetKey extends types.GetKeyFunction<types.JWEHead
16
16
  * This function is exported (as a named export) from the main `'jose'` module entry point as well
17
17
  * as from its subpath export `'jose/jwe/general/decrypt'`.
18
18
  *
19
+ * > [!NOTE]\
20
+ * > The function iterates over the `recipients` array in the General JWE and returns the decryption
21
+ * > result of the first recipient entry that can be successfully decrypted. The result only contains
22
+ * > the plaintext and headers of that successfully decrypted recipient entry. Other recipient entries
23
+ * > in the General JWE are not validated, and their headers are not included in the returned result.
24
+ * > Recipients of a General JWE should only rely on the returned (decrypted) data.
25
+ *
19
26
  * @param jwe General JWE.
20
27
  * @param key Private Key or Secret to decrypt the JWE with. See
21
28
  * {@link https://github.com/panva/jose/issues/210#jwe-alg Algorithm Key Requirements}.
@@ -18,6 +18,14 @@ export interface GeneralVerifyGetKey extends types.GenericGetKeyFunction<types.J
18
18
  * This function is exported (as a named export) from the main `'jose'` module entry point as well
19
19
  * as from its subpath export `'jose/jws/general/verify'`.
20
20
  *
21
+ * > [!NOTE]\
22
+ * > The function iterates over the `signatures` array in the General JWS and returns the verification
23
+ * > result of the first signature entry that can be successfully verified. The result only contains
24
+ * > the payload, protected header, and unprotected header of that successfully verified signature
25
+ * > entry. Other signature entries in the General JWS are not validated, and their headers are not
26
+ * > included in the returned result. Recipients of a General JWS should only rely on the returned
27
+ * > (verified) data.
28
+ *
21
29
  * @param jws General JWS.
22
30
  * @param key Key to verify the JWS with. See
23
31
  * {@link https://github.com/panva/jose/issues/210#jws-alg Algorithm Key Requirements}.
@@ -415,12 +415,12 @@ export interface JWEHeaderParameters extends JoseHeaderParameters {
415
415
  crit?: string[]
416
416
 
417
417
  /**
418
- * JWE "zip" (Compression Algorithm) Header Parameter. This parameter is not supported anymore.
418
+ * JWE "zip" (Compression Algorithm) Header Parameter.
419
419
  *
420
- * @deprecated Compression of data SHOULD NOT be done before encryption, because such compressed
421
- * data often reveals information about the plaintext.
420
+ * The only supported value is `"DEF"` (DEFLATE). Requires the `CompressionStream` /
421
+ * `DecompressionStream` APIs to be available in the runtime.
422
422
  *
423
- * @see {@link https://www.rfc-editor.org/rfc/rfc8725#name-avoid-compression-of-encryp Avoid Compression of Encryption Inputs}
423
+ * @see {@link https://www.rfc-editor.org/rfc/rfc7516#section-4.1.3 JWE "zip" Header Parameter}
424
424
  */
425
425
  zip?: string
426
426
 
@@ -474,6 +474,17 @@ export interface DecryptOptions extends CritOption {
474
474
  * this value is set to 10000.
475
475
  */
476
476
  maxPBES2Count?: number
477
+
478
+ /**
479
+ * Maximum allowed size (in bytes) of the decompressed plaintext when the JWE `"zip"` (Compression
480
+ * Algorithm) Header Parameter is present. By default this value is set to 250000 (250 KB). The
481
+ * value must be `0`, a positive safe integer, or `Infinity`.
482
+ *
483
+ * Set to `0` to reject all compressed JWEs during decryption.
484
+ *
485
+ * Set to `Infinity` to disable the decompressed size limit.
486
+ */
487
+ maxDecompressedLength?: number
477
488
  }
478
489
 
479
490
  /** JWE Encryption options. */
@@ -1,15 +1,17 @@
1
1
  import { decode as b64u } from '../../util/base64url.js';
2
- import { decrypt } from '../../lib/decrypt.js';
2
+ import { decrypt } from '../../lib/content_encryption.js';
3
+ import { decodeBase64url } from '../../lib/helpers.js';
3
4
  import { JOSEAlgNotAllowed, JOSENotSupported, JWEInvalid } from '../../util/errors.js';
4
- import { isDisjoint } from '../../lib/is_disjoint.js';
5
- import { isObject } from '../../lib/is_object.js';
6
- import { decryptKeyManagement } from '../../lib/decrypt_key_management.js';
5
+ import { isDisjoint } from '../../lib/type_checks.js';
6
+ import { isObject } from '../../lib/type_checks.js';
7
+ import { decryptKeyManagement } from '../../lib/key_management.js';
7
8
  import { decoder, concat, encode } from '../../lib/buffer_utils.js';
8
- import { generateCek } from '../../lib/cek.js';
9
+ import { generateCek } from '../../lib/content_encryption.js';
9
10
  import { validateCrit } from '../../lib/validate_crit.js';
10
11
  import { validateAlgorithms } from '../../lib/validate_algorithms.js';
11
12
  import { normalizeKey } from '../../lib/normalize_key.js';
12
13
  import { checkKeyType } from '../../lib/check_key_type.js';
14
+ import { decompress } from '../../lib/deflate.js';
13
15
  export async function flattenedDecrypt(jwe, key, options) {
14
16
  if (!isObject(jwe)) {
15
17
  throw new JWEInvalid('Flattened JWE must be an object');
@@ -60,8 +62,11 @@ export async function flattenedDecrypt(jwe, key, options) {
60
62
  ...jwe.unprotected,
61
63
  };
62
64
  validateCrit(JWEInvalid, new Map(), options?.crit, parsedProt, joseHeader);
63
- if (joseHeader.zip !== undefined) {
64
- throw new JOSENotSupported('JWE "zip" (Compression Algorithm) Header Parameter is not supported.');
65
+ if (joseHeader.zip !== undefined && joseHeader.zip !== 'DEF') {
66
+ throw new JOSENotSupported('Unsupported JWE "zip" (Compression Algorithm) Header Parameter value.');
67
+ }
68
+ if (joseHeader.zip !== undefined && !parsedProt?.zip) {
69
+ throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header Parameter MUST be in a protected header.');
65
70
  }
66
71
  const { alg, enc } = joseHeader;
67
72
  if (typeof alg !== 'string' || !alg) {
@@ -82,12 +87,7 @@ export async function flattenedDecrypt(jwe, key, options) {
82
87
  }
83
88
  let encryptedKey;
84
89
  if (jwe.encrypted_key !== undefined) {
85
- try {
86
- encryptedKey = b64u(jwe.encrypted_key);
87
- }
88
- catch {
89
- throw new JWEInvalid('Failed to base64url decode the encrypted_key');
90
- }
90
+ encryptedKey = decodeBase64url(jwe.encrypted_key, 'encrypted_key', JWEInvalid);
91
91
  }
92
92
  let resolvedKey = false;
93
93
  if (typeof key === 'function') {
@@ -109,20 +109,10 @@ export async function flattenedDecrypt(jwe, key, options) {
109
109
  let iv;
110
110
  let tag;
111
111
  if (jwe.iv !== undefined) {
112
- try {
113
- iv = b64u(jwe.iv);
114
- }
115
- catch {
116
- throw new JWEInvalid('Failed to base64url decode the iv');
117
- }
112
+ iv = decodeBase64url(jwe.iv, 'iv', JWEInvalid);
118
113
  }
119
114
  if (jwe.tag !== undefined) {
120
- try {
121
- tag = b64u(jwe.tag);
122
- }
123
- catch {
124
- throw new JWEInvalid('Failed to base64url decode the tag');
125
- }
115
+ tag = decodeBase64url(jwe.tag, 'tag', JWEInvalid);
126
116
  }
127
117
  const protectedHeader = jwe.protected !== undefined ? encode(jwe.protected) : new Uint8Array();
128
118
  let additionalData;
@@ -132,25 +122,25 @@ export async function flattenedDecrypt(jwe, key, options) {
132
122
  else {
133
123
  additionalData = protectedHeader;
134
124
  }
135
- let ciphertext;
136
- try {
137
- ciphertext = b64u(jwe.ciphertext);
138
- }
139
- catch {
140
- throw new JWEInvalid('Failed to base64url decode the ciphertext');
141
- }
125
+ const ciphertext = decodeBase64url(jwe.ciphertext, 'ciphertext', JWEInvalid);
142
126
  const plaintext = await decrypt(enc, cek, ciphertext, iv, tag, additionalData);
143
127
  const result = { plaintext };
128
+ if (joseHeader.zip === 'DEF') {
129
+ const maxDecompressedLength = options?.maxDecompressedLength ?? 250_000;
130
+ if (maxDecompressedLength === 0) {
131
+ throw new JOSENotSupported('JWE "zip" (Compression Algorithm) Header Parameter is not supported.');
132
+ }
133
+ if (maxDecompressedLength !== Infinity &&
134
+ (!Number.isSafeInteger(maxDecompressedLength) || maxDecompressedLength < 1)) {
135
+ throw new TypeError('maxDecompressedLength must be 0, a positive safe integer, or Infinity');
136
+ }
137
+ result.plaintext = await decompress(plaintext, maxDecompressedLength);
138
+ }
144
139
  if (jwe.protected !== undefined) {
145
140
  result.protectedHeader = parsedProt;
146
141
  }
147
142
  if (jwe.aad !== undefined) {
148
- try {
149
- result.additionalAuthenticatedData = b64u(jwe.aad);
150
- }
151
- catch {
152
- throw new JWEInvalid('Failed to base64url decode the aad');
153
- }
143
+ result.additionalAuthenticatedData = decodeBase64url(jwe.aad, 'aad', JWEInvalid);
154
144
  }
155
145
  if (jwe.unprotected !== undefined) {
156
146
  result.sharedUnprotectedHeader = jwe.unprotected;
@@ -1,13 +1,14 @@
1
1
  import { encode as b64u } from '../../util/base64url.js';
2
- import { unprotected } from '../../lib/private_symbols.js';
3
- import { encrypt } from '../../lib/encrypt.js';
4
- import { encryptKeyManagement } from '../../lib/encrypt_key_management.js';
2
+ import { unprotected, assertNotSet } from '../../lib/helpers.js';
3
+ import { encrypt } from '../../lib/content_encryption.js';
4
+ import { encryptKeyManagement } from '../../lib/key_management.js';
5
5
  import { JOSENotSupported, JWEInvalid } from '../../util/errors.js';
6
- import { isDisjoint } from '../../lib/is_disjoint.js';
6
+ import { isDisjoint } from '../../lib/type_checks.js';
7
7
  import { concat, encode } from '../../lib/buffer_utils.js';
8
8
  import { validateCrit } from '../../lib/validate_crit.js';
9
9
  import { normalizeKey } from '../../lib/normalize_key.js';
10
10
  import { checkKeyType } from '../../lib/check_key_type.js';
11
+ import { compress } from '../../lib/deflate.js';
11
12
  export class FlattenedEncrypt {
12
13
  #plaintext;
13
14
  #protectedHeader;
@@ -24,30 +25,22 @@ export class FlattenedEncrypt {
24
25
  this.#plaintext = plaintext;
25
26
  }
26
27
  setKeyManagementParameters(parameters) {
27
- if (this.#keyManagementParameters) {
28
- throw new TypeError('setKeyManagementParameters can only be called once');
29
- }
28
+ assertNotSet(this.#keyManagementParameters, 'setKeyManagementParameters');
30
29
  this.#keyManagementParameters = parameters;
31
30
  return this;
32
31
  }
33
32
  setProtectedHeader(protectedHeader) {
34
- if (this.#protectedHeader) {
35
- throw new TypeError('setProtectedHeader can only be called once');
36
- }
33
+ assertNotSet(this.#protectedHeader, 'setProtectedHeader');
37
34
  this.#protectedHeader = protectedHeader;
38
35
  return this;
39
36
  }
40
37
  setSharedUnprotectedHeader(sharedUnprotectedHeader) {
41
- if (this.#sharedUnprotectedHeader) {
42
- throw new TypeError('setSharedUnprotectedHeader can only be called once');
43
- }
38
+ assertNotSet(this.#sharedUnprotectedHeader, 'setSharedUnprotectedHeader');
44
39
  this.#sharedUnprotectedHeader = sharedUnprotectedHeader;
45
40
  return this;
46
41
  }
47
42
  setUnprotectedHeader(unprotectedHeader) {
48
- if (this.#unprotectedHeader) {
49
- throw new TypeError('setUnprotectedHeader can only be called once');
50
- }
43
+ assertNotSet(this.#unprotectedHeader, 'setUnprotectedHeader');
51
44
  this.#unprotectedHeader = unprotectedHeader;
52
45
  return this;
53
46
  }
@@ -56,16 +49,12 @@ export class FlattenedEncrypt {
56
49
  return this;
57
50
  }
58
51
  setContentEncryptionKey(cek) {
59
- if (this.#cek) {
60
- throw new TypeError('setContentEncryptionKey can only be called once');
61
- }
52
+ assertNotSet(this.#cek, 'setContentEncryptionKey');
62
53
  this.#cek = cek;
63
54
  return this;
64
55
  }
65
56
  setInitializationVector(iv) {
66
- if (this.#iv) {
67
- throw new TypeError('setInitializationVector can only be called once');
68
- }
57
+ assertNotSet(this.#iv, 'setInitializationVector');
69
58
  this.#iv = iv;
70
59
  return this;
71
60
  }
@@ -82,8 +71,11 @@ export class FlattenedEncrypt {
82
71
  ...this.#sharedUnprotectedHeader,
83
72
  };
84
73
  validateCrit(JWEInvalid, new Map(), options?.crit, this.#protectedHeader, joseHeader);
85
- if (joseHeader.zip !== undefined) {
86
- throw new JOSENotSupported('JWE "zip" (Compression Algorithm) Header Parameter is not supported.');
74
+ if (joseHeader.zip !== undefined && joseHeader.zip !== 'DEF') {
75
+ throw new JOSENotSupported('Unsupported JWE "zip" (Compression Algorithm) Header Parameter value.');
76
+ }
77
+ if (joseHeader.zip !== undefined && !this.#protectedHeader?.zip) {
78
+ throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header Parameter MUST be in a protected header.');
87
79
  }
88
80
  const { alg, enc } = joseHeader;
89
81
  if (typeof alg !== 'string' || !alg) {
@@ -139,7 +131,11 @@ export class FlattenedEncrypt {
139
131
  else {
140
132
  additionalData = protectedHeaderB;
141
133
  }
142
- const { ciphertext, tag, iv } = await encrypt(enc, this.#plaintext, cek, this.#iv, additionalData);
134
+ let plaintext = this.#plaintext;
135
+ if (joseHeader.zip === 'DEF') {
136
+ plaintext = await compress(plaintext);
137
+ }
138
+ const { ciphertext, tag, iv } = await encrypt(enc, plaintext, cek, this.#iv, additionalData);
143
139
  const jwe = {
144
140
  ciphertext: b64u(ciphertext),
145
141
  };
@@ -1,6 +1,6 @@
1
1
  import { flattenedDecrypt } from '../flattened/decrypt.js';
2
2
  import { JWEDecryptionFailed, JWEInvalid } from '../../util/errors.js';
3
- import { isObject } from '../../lib/is_object.js';
3
+ import { isObject } from '../../lib/type_checks.js';
4
4
  export async function generalDecrypt(jwe, key, options) {
5
5
  if (!isObject(jwe)) {
6
6
  throw new JWEInvalid('General JWE must be an object');
@@ -1,9 +1,9 @@
1
1
  import { FlattenedEncrypt } from '../flattened/encrypt.js';
2
- import { unprotected } from '../../lib/private_symbols.js';
2
+ import { unprotected, assertNotSet } from '../../lib/helpers.js';
3
3
  import { JOSENotSupported, JWEInvalid } from '../../util/errors.js';
4
- import { generateCek } from '../../lib/cek.js';
5
- import { isDisjoint } from '../../lib/is_disjoint.js';
6
- import { encryptKeyManagement } from '../../lib/encrypt_key_management.js';
4
+ import { generateCek } from '../../lib/content_encryption.js';
5
+ import { isDisjoint } from '../../lib/type_checks.js';
6
+ import { encryptKeyManagement } from '../../lib/key_management.js';
7
7
  import { encode as b64u } from '../../util/base64url.js';
8
8
  import { validateCrit } from '../../lib/validate_crit.js';
9
9
  import { normalizeKey } from '../../lib/normalize_key.js';
@@ -20,16 +20,12 @@ class IndividualRecipient {
20
20
  this.options = options;
21
21
  }
22
22
  setUnprotectedHeader(unprotectedHeader) {
23
- if (this.unprotectedHeader) {
24
- throw new TypeError('setUnprotectedHeader can only be called once');
25
- }
23
+ assertNotSet(this.unprotectedHeader, 'setUnprotectedHeader');
26
24
  this.unprotectedHeader = unprotectedHeader;
27
25
  return this;
28
26
  }
29
27
  setKeyManagementParameters(parameters) {
30
- if (this.keyManagementParameters) {
31
- throw new TypeError('setKeyManagementParameters can only be called once');
32
- }
28
+ assertNotSet(this.keyManagementParameters, 'setKeyManagementParameters');
33
29
  this.keyManagementParameters = parameters;
34
30
  return this;
35
31
  }
@@ -58,16 +54,12 @@ export class GeneralEncrypt {
58
54
  return recipient;
59
55
  }
60
56
  setProtectedHeader(protectedHeader) {
61
- if (this.#protectedHeader) {
62
- throw new TypeError('setProtectedHeader can only be called once');
63
- }
57
+ assertNotSet(this.#protectedHeader, 'setProtectedHeader');
64
58
  this.#protectedHeader = protectedHeader;
65
59
  return this;
66
60
  }
67
61
  setSharedUnprotectedHeader(sharedUnprotectedHeader) {
68
- if (this.#unprotectedHeader) {
69
- throw new TypeError('setSharedUnprotectedHeader can only be called once');
70
- }
62
+ assertNotSet(this.#unprotectedHeader, 'setSharedUnprotectedHeader');
71
63
  this.#unprotectedHeader = sharedUnprotectedHeader;
72
64
  return this;
73
65
  }
@@ -133,8 +125,11 @@ export class GeneralEncrypt {
133
125
  throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter must be the same for all recipients');
134
126
  }
135
127
  validateCrit(JWEInvalid, new Map(), recipient.options.crit, this.#protectedHeader, joseHeader);
136
- if (joseHeader.zip !== undefined) {
137
- throw new JOSENotSupported('JWE "zip" (Compression Algorithm) Header Parameter is not supported.');
128
+ if (joseHeader.zip !== undefined && joseHeader.zip !== 'DEF') {
129
+ throw new JOSENotSupported('Unsupported JWE "zip" (Compression Algorithm) Header Parameter value.');
130
+ }
131
+ if (joseHeader.zip !== undefined && !this.#protectedHeader?.zip) {
132
+ throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header Parameter MUST be in a protected header.');
138
133
  }
139
134
  }
140
135
  const cek = generateCek(enc);
@@ -1,5 +1,5 @@
1
1
  import { importJWK } from '../key/import.js';
2
- import { isObject } from '../lib/is_object.js';
2
+ import { isObject } from '../lib/type_checks.js';
3
3
  import { JWSInvalid } from '../util/errors.js';
4
4
  export async function EmbeddedJWK(protectedHeader, token) {
5
5
  const joseHeader = {
@@ -1,9 +1,9 @@
1
- import { digest } from '../lib/digest.js';
1
+ import { digest } from '../lib/helpers.js';
2
2
  import { encode as b64u } from '../util/base64url.js';
3
3
  import { JOSENotSupported, JWKInvalid } from '../util/errors.js';
4
4
  import { encode } from '../lib/buffer_utils.js';
5
5
  import { isKeyLike } from '../lib/is_key_like.js';
6
- import { isJWK } from '../lib/is_jwk.js';
6
+ import { isJWK } from '../lib/type_checks.js';
7
7
  import { exportJWK } from '../key/export.js';
8
8
  import { invalidKeyInput } from '../lib/invalid_key_input.js';
9
9
  const check = (value, description) => {
@@ -1,6 +1,6 @@
1
1
  import { importJWK } from '../key/import.js';
2
2
  import { JWKSInvalid, JOSENotSupported, JWKSNoMatchingKey, JWKSMultipleMatchingKeys, } from '../util/errors.js';
3
- import { isObject } from '../lib/is_object.js';
3
+ import { isObject } from '../lib/type_checks.js';
4
4
  function getKtyFromAlg(alg) {
5
5
  switch (typeof alg === 'string' && alg.slice(0, 2)) {
6
6
  case 'RS':
@@ -1,6 +1,6 @@
1
1
  import { JOSEError, JWKSNoMatchingKey, JWKSTimeout } from '../util/errors.js';
2
2
  import { createLocalJWKSet } from './local.js';
3
- import { isObject } from '../lib/is_object.js';
3
+ import { isObject } from '../lib/type_checks.js';
4
4
  function isCloudflareWorkers() {
5
5
  return (typeof WebSocketPair !== 'undefined' ||
6
6
  (typeof navigator !== 'undefined' && navigator.userAgent === 'Cloudflare-Workers') ||
@@ -9,7 +9,7 @@ function isCloudflareWorkers() {
9
9
  let USER_AGENT;
10
10
  if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
11
11
  const NAME = 'jose';
12
- const VERSION = 'v6.1.3';
12
+ const VERSION = 'v6.2.1';
13
13
  USER_AGENT = `${NAME}/${VERSION}`;
14
14
  }
15
15
  export const customFetch = Symbol();
@@ -1,11 +1,12 @@
1
1
  import { encode as b64u } from '../../util/base64url.js';
2
- import { sign } from '../../lib/sign.js';
3
- import { isDisjoint } from '../../lib/is_disjoint.js';
2
+ import { sign } from '../../lib/signing.js';
3
+ import { isDisjoint } from '../../lib/type_checks.js';
4
4
  import { JWSInvalid } from '../../util/errors.js';
5
5
  import { concat, encode } from '../../lib/buffer_utils.js';
6
6
  import { checkKeyType } from '../../lib/check_key_type.js';
7
7
  import { validateCrit } from '../../lib/validate_crit.js';
8
8
  import { normalizeKey } from '../../lib/normalize_key.js';
9
+ import { assertNotSet } from '../../lib/helpers.js';
9
10
  export class FlattenedSign {
10
11
  #payload;
11
12
  #protectedHeader;
@@ -17,16 +18,12 @@ export class FlattenedSign {
17
18
  this.#payload = payload;
18
19
  }
19
20
  setProtectedHeader(protectedHeader) {
20
- if (this.#protectedHeader) {
21
- throw new TypeError('setProtectedHeader can only be called once');
22
- }
21
+ assertNotSet(this.#protectedHeader, 'setProtectedHeader');
23
22
  this.#protectedHeader = protectedHeader;
24
23
  return this;
25
24
  }
26
25
  setUnprotectedHeader(unprotectedHeader) {
27
- if (this.#unprotectedHeader) {
28
- throw new TypeError('setUnprotectedHeader can only be called once');
29
- }
26
+ assertNotSet(this.#unprotectedHeader, 'setUnprotectedHeader');
30
27
  this.#unprotectedHeader = unprotectedHeader;
31
28
  return this;
32
29
  }
@@ -1,9 +1,10 @@
1
1
  import { decode as b64u } from '../../util/base64url.js';
2
- import { verify } from '../../lib/verify.js';
2
+ import { verify } from '../../lib/signing.js';
3
3
  import { JOSEAlgNotAllowed, JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js';
4
4
  import { concat, encoder, decoder, encode } from '../../lib/buffer_utils.js';
5
- import { isDisjoint } from '../../lib/is_disjoint.js';
6
- import { isObject } from '../../lib/is_object.js';
5
+ import { decodeBase64url } from '../../lib/helpers.js';
6
+ import { isDisjoint } from '../../lib/type_checks.js';
7
+ import { isObject } from '../../lib/type_checks.js';
7
8
  import { checkKeyType } from '../../lib/check_key_type.js';
8
9
  import { validateCrit } from '../../lib/validate_crit.js';
9
10
  import { validateAlgorithms } from '../../lib/validate_algorithms.js';
@@ -79,13 +80,7 @@ export async function flattenedVerify(jws, key, options) {
79
80
  ? encode(jws.payload)
80
81
  : encoder.encode(jws.payload)
81
82
  : jws.payload);
82
- let signature;
83
- try {
84
- signature = b64u(jws.signature);
85
- }
86
- catch {
87
- throw new JWSInvalid('Failed to base64url decode the signature');
88
- }
83
+ const signature = decodeBase64url(jws.signature, 'signature', JWSInvalid);
89
84
  const k = await normalizeKey(key, alg);
90
85
  const verified = await verify(alg, k, signature, data);
91
86
  if (!verified) {
@@ -93,12 +88,7 @@ export async function flattenedVerify(jws, key, options) {
93
88
  }
94
89
  let payload;
95
90
  if (b64) {
96
- try {
97
- payload = b64u(jws.payload);
98
- }
99
- catch {
100
- throw new JWSInvalid('Failed to base64url decode the payload');
101
- }
91
+ payload = decodeBase64url(jws.payload, 'payload', JWSInvalid);
102
92
  }
103
93
  else if (typeof jws.payload === 'string') {
104
94
  payload = encoder.encode(jws.payload);
@@ -1,5 +1,6 @@
1
1
  import { FlattenedSign } from '../flattened/sign.js';
2
2
  import { JWSInvalid } from '../../util/errors.js';
3
+ import { assertNotSet } from '../../lib/helpers.js';
3
4
  class IndividualSignature {
4
5
  #parent;
5
6
  protectedHeader;
@@ -12,16 +13,12 @@ class IndividualSignature {
12
13
  this.options = options;
13
14
  }
14
15
  setProtectedHeader(protectedHeader) {
15
- if (this.protectedHeader) {
16
- throw new TypeError('setProtectedHeader can only be called once');
17
- }
16
+ assertNotSet(this.protectedHeader, 'setProtectedHeader');
18
17
  this.protectedHeader = protectedHeader;
19
18
  return this;
20
19
  }
21
20
  setUnprotectedHeader(unprotectedHeader) {
22
- if (this.unprotectedHeader) {
23
- throw new TypeError('setUnprotectedHeader can only be called once');
24
- }
21
+ assertNotSet(this.unprotectedHeader, 'setUnprotectedHeader');
25
22
  this.unprotectedHeader = unprotectedHeader;
26
23
  return this;
27
24
  }
@@ -1,6 +1,6 @@
1
1
  import { flattenedVerify } from '../flattened/verify.js';
2
2
  import { JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js';
3
- import { isObject } from '../../lib/is_object.js';
3
+ import { isObject } from '../../lib/type_checks.js';
4
4
  export async function generalVerify(jws, key, options) {
5
5
  if (!isObject(jws)) {
6
6
  throw new JWSInvalid('General JWS must be an object');
@@ -1,5 +1,6 @@
1
1
  import { CompactEncrypt } from '../jwe/compact/encrypt.js';
2
2
  import { JWTClaimsBuilder } from '../lib/jwt_claims_set.js';
3
+ import { assertNotSet } from '../lib/helpers.js';
3
4
  export class EncryptJWT {
4
5
  #cek;
5
6
  #iv;
@@ -41,30 +42,22 @@ export class EncryptJWT {
41
42
  return this;
42
43
  }
43
44
  setProtectedHeader(protectedHeader) {
44
- if (this.#protectedHeader) {
45
- throw new TypeError('setProtectedHeader can only be called once');
46
- }
45
+ assertNotSet(this.#protectedHeader, 'setProtectedHeader');
47
46
  this.#protectedHeader = protectedHeader;
48
47
  return this;
49
48
  }
50
49
  setKeyManagementParameters(parameters) {
51
- if (this.#keyManagementParameters) {
52
- throw new TypeError('setKeyManagementParameters can only be called once');
53
- }
50
+ assertNotSet(this.#keyManagementParameters, 'setKeyManagementParameters');
54
51
  this.#keyManagementParameters = parameters;
55
52
  return this;
56
53
  }
57
54
  setContentEncryptionKey(cek) {
58
- if (this.#cek) {
59
- throw new TypeError('setContentEncryptionKey can only be called once');
60
- }
55
+ assertNotSet(this.#cek, 'setContentEncryptionKey');
61
56
  this.#cek = cek;
62
57
  return this;
63
58
  }
64
59
  setInitializationVector(iv) {
65
- if (this.#iv) {
66
- throw new TypeError('setInitializationVector can only be called once');
67
- }
60
+ assertNotSet(this.#iv, 'setInitializationVector');
68
61
  this.#iv = iv;
69
62
  return this;
70
63
  }
@@ -2,7 +2,7 @@ import { decode as decodeBase64URL } from '../util/base64url.js';
2
2
  import { fromSPKI, fromPKCS8, fromX509 } from '../lib/asn1.js';
3
3
  import { jwkToKey } from '../lib/jwk_to_key.js';
4
4
  import { JOSENotSupported } from '../util/errors.js';
5
- import { isObject } from '../lib/is_object.js';
5
+ import { isObject } from '../lib/type_checks.js';
6
6
  export async function importSPKI(spki, alg, options) {
7
7
  if (typeof spki !== 'string' || spki.indexOf('-----BEGIN PUBLIC KEY-----') !== 0) {
8
8
  throw new TypeError('"spki" must be SPKI formatted string');
@@ -1,5 +1,4 @@
1
- import { encrypt } from './encrypt.js';
2
- import { decrypt } from './decrypt.js';
1
+ import { encrypt, decrypt } from './content_encryption.js';
3
2
  import { encode as b64u } from '../util/base64url.js';
4
3
  export async function wrap(alg, key, cek, iv) {
5
4
  const jweAlgorithm = alg.slice(0, 7);
@@ -1,6 +1,6 @@
1
1
  import { withAlg as invalidKeyInput } from './invalid_key_input.js';
2
2
  import { isKeyLike } from './is_key_like.js';
3
- import * as jwk from './is_jwk.js';
3
+ import * as jwk from './type_checks.js';
4
4
  const tag = (key) => key?.[Symbol.toStringTag];
5
5
  const jwkMatchesOp = (alg, key, usage) => {
6
6
  if (key.use !== undefined) {