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.
- package/dist/types/jwe/general/decrypt.d.ts +7 -0
- package/dist/types/jws/general/verify.d.ts +8 -0
- package/dist/types/types.d.ts +15 -4
- package/dist/webapi/jwe/flattened/decrypt.js +28 -38
- package/dist/webapi/jwe/flattened/encrypt.js +21 -25
- package/dist/webapi/jwe/general/decrypt.js +1 -1
- package/dist/webapi/jwe/general/encrypt.js +13 -18
- package/dist/webapi/jwk/embedded.js +1 -1
- package/dist/webapi/jwk/thumbprint.js +2 -2
- package/dist/webapi/jwks/local.js +1 -1
- package/dist/webapi/jwks/remote.js +2 -2
- package/dist/webapi/jws/flattened/sign.js +5 -8
- package/dist/webapi/jws/flattened/verify.js +6 -16
- package/dist/webapi/jws/general/sign.js +3 -6
- package/dist/webapi/jws/general/verify.js +1 -1
- package/dist/webapi/jwt/encrypt.js +5 -12
- package/dist/webapi/key/import.js +1 -1
- package/dist/webapi/lib/aesgcmkw.js +1 -2
- package/dist/webapi/lib/check_key_type.js +1 -1
- package/dist/webapi/lib/content_encryption.js +217 -0
- package/dist/webapi/lib/crypto_key.js +9 -16
- package/dist/webapi/lib/deflate.js +44 -0
- package/dist/webapi/lib/ecdhes.js +1 -1
- package/dist/webapi/lib/helpers.js +19 -0
- package/dist/webapi/lib/jwk_to_key.js +9 -11
- package/dist/webapi/lib/jwt_claims_set.js +1 -1
- package/dist/webapi/lib/key_management.js +186 -0
- package/dist/webapi/lib/normalize_key.js +10 -20
- package/dist/webapi/lib/rsaes.js +1 -1
- package/dist/webapi/lib/signing.js +68 -0
- package/dist/webapi/lib/type_checks.js +40 -0
- package/dist/webapi/util/decode_jwt.js +1 -1
- package/dist/webapi/util/decode_protected_header.js +1 -1
- package/package.json +1 -1
- package/dist/webapi/lib/cek.js +0 -19
- package/dist/webapi/lib/check_cek_length.js +0 -7
- package/dist/webapi/lib/check_iv_length.js +0 -7
- package/dist/webapi/lib/check_key_length.js +0 -8
- package/dist/webapi/lib/decrypt.js +0 -106
- package/dist/webapi/lib/decrypt_key_management.js +0 -127
- package/dist/webapi/lib/digest.js +0 -4
- package/dist/webapi/lib/encrypt.js +0 -74
- package/dist/webapi/lib/encrypt_key_management.js +0 -92
- package/dist/webapi/lib/get_sign_verify_key.js +0 -12
- package/dist/webapi/lib/is_disjoint.js +0 -21
- package/dist/webapi/lib/is_jwk.js +0 -6
- package/dist/webapi/lib/is_object.js +0 -14
- package/dist/webapi/lib/iv.js +0 -19
- package/dist/webapi/lib/private_symbols.js +0 -1
- package/dist/webapi/lib/sign.js +0 -9
- package/dist/webapi/lib/subtle_dsa.js +0 -31
- 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}.
|
package/dist/types/types.d.ts
CHANGED
|
@@ -415,12 +415,12 @@ export interface JWEHeaderParameters extends JoseHeaderParameters {
|
|
|
415
415
|
crit?: string[]
|
|
416
416
|
|
|
417
417
|
/**
|
|
418
|
-
* JWE "zip" (Compression Algorithm) Header Parameter.
|
|
418
|
+
* JWE "zip" (Compression Algorithm) Header Parameter.
|
|
419
419
|
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
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/
|
|
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/
|
|
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/
|
|
5
|
-
import { isObject } from '../../lib/
|
|
6
|
-
import { decryptKeyManagement } from '../../lib/
|
|
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/
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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/
|
|
3
|
-
import { encrypt } from '../../lib/
|
|
4
|
-
import { encryptKeyManagement } from '../../lib/
|
|
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/
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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/
|
|
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/
|
|
2
|
+
import { unprotected, assertNotSet } from '../../lib/helpers.js';
|
|
3
3
|
import { JOSENotSupported, JWEInvalid } from '../../util/errors.js';
|
|
4
|
-
import { generateCek } from '../../lib/
|
|
5
|
-
import { isDisjoint } from '../../lib/
|
|
6
|
-
import { encryptKeyManagement } from '../../lib/
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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
|
|
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/
|
|
3
|
-
import { isDisjoint } from '../../lib/
|
|
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
|
-
|
|
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
|
-
|
|
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/
|
|
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 {
|
|
6
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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/
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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/
|
|
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 './
|
|
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 './
|
|
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) {
|