jose 4.15.4 → 5.0.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/README.md +2 -1
- package/dist/browser/index.js +2 -4
- package/dist/browser/jwe/flattened/decrypt.js +13 -22
- package/dist/browser/jwe/flattened/encrypt.js +3 -18
- package/dist/browser/jwe/general/decrypt.js +1 -1
- package/dist/browser/jwe/general/encrypt.js +8 -13
- package/dist/browser/jwk/embedded.js +2 -2
- package/dist/browser/jwk/thumbprint.js +2 -2
- package/dist/browser/jwks/local.js +2 -2
- package/dist/browser/jwks/remote.js +4 -4
- package/dist/browser/jws/flattened/sign.js +1 -1
- package/dist/browser/jws/flattened/verify.js +6 -7
- package/dist/browser/jws/general/verify.js +1 -1
- package/dist/browser/jwt/produce.js +19 -4
- package/dist/browser/jwt/sign.js +1 -2
- package/dist/browser/jwt/unsecured.js +1 -1
- package/dist/browser/jwt/verify.js +1 -2
- package/dist/browser/key/import.js +1 -6
- package/dist/browser/lib/decrypt_key_management.js +6 -6
- package/dist/browser/lib/jwt_claims_set.js +1 -1
- package/dist/browser/runtime/asn1.js +1 -2
- package/dist/browser/runtime/base64url.js +1 -1
- package/dist/browser/runtime/decrypt.js +3 -3
- package/dist/browser/runtime/fetch_jwks.js +1 -1
- package/dist/browser/runtime/generate.js +5 -8
- package/dist/browser/runtime/jwk_to_key.js +2 -45
- package/dist/browser/runtime/verify.js +1 -1
- package/dist/browser/util/decode_jwt.js +2 -2
- package/dist/browser/util/decode_protected_header.js +1 -1
- package/dist/browser/util/errors.js +1 -2
- package/dist/node/cjs/jwe/compact/encrypt.js +1 -0
- package/dist/node/cjs/jwe/flattened/decrypt.js +7 -16
- package/dist/node/cjs/jwe/flattened/encrypt.js +12 -19
- package/dist/node/cjs/jwe/general/encrypt.js +16 -13
- package/dist/node/cjs/jwk/embedded.js +2 -2
- package/dist/node/cjs/jwk/thumbprint.js +2 -2
- package/dist/node/cjs/jwks/local.js +3 -2
- package/dist/node/cjs/jwks/remote.js +13 -6
- package/dist/node/cjs/jws/compact/sign.js +1 -0
- package/dist/node/cjs/jws/flattened/sign.js +4 -1
- package/dist/node/cjs/jws/flattened/verify.js +3 -4
- package/dist/node/cjs/jws/general/sign.js +7 -1
- package/dist/node/cjs/jwt/encrypt.js +7 -0
- package/dist/node/cjs/jwt/produce.js +20 -4
- package/dist/node/cjs/jwt/sign.js +2 -2
- package/dist/node/cjs/jwt/verify.js +1 -2
- package/dist/node/cjs/key/import.js +2 -7
- package/dist/node/cjs/lib/aesgcmkw.js +1 -1
- package/dist/node/cjs/lib/decrypt_key_management.js +1 -1
- package/dist/node/cjs/lib/encrypt_key_management.js +1 -1
- package/dist/node/cjs/runtime/aeskw.js +6 -6
- package/dist/node/cjs/runtime/asn1.js +8 -8
- package/dist/node/cjs/runtime/base64url.js +6 -11
- package/dist/node/cjs/runtime/cbc_tag.js +2 -2
- package/dist/node/cjs/runtime/check_key_length.js +8 -0
- package/dist/node/cjs/runtime/ciphers.js +2 -2
- package/dist/node/cjs/runtime/decrypt.js +4 -4
- package/dist/node/cjs/runtime/digest.js +2 -2
- package/dist/node/cjs/runtime/ecdhes.js +7 -7
- package/dist/node/cjs/runtime/encrypt.js +4 -4
- package/dist/node/cjs/runtime/fetch_jwks.js +4 -4
- package/dist/node/cjs/runtime/generate.js +7 -11
- package/dist/node/cjs/runtime/get_named_curve.js +7 -45
- package/dist/node/cjs/runtime/get_sign_verify_key.js +4 -4
- package/dist/node/cjs/runtime/is_key_like.js +1 -1
- package/dist/node/cjs/runtime/is_key_object.js +2 -5
- package/dist/node/cjs/runtime/jwk_to_key.js +2 -113
- package/dist/node/cjs/runtime/key_to_jwk.js +6 -130
- package/dist/node/cjs/runtime/node_key.js +9 -18
- package/dist/node/cjs/runtime/pbes2kw.js +4 -4
- package/dist/node/cjs/runtime/random.js +2 -2
- package/dist/node/cjs/runtime/rsaes.js +8 -8
- package/dist/node/cjs/runtime/sign.js +3 -9
- package/dist/node/cjs/runtime/timing_safe_equal.js +2 -2
- package/dist/node/cjs/runtime/verify.js +3 -10
- package/dist/node/cjs/runtime/webcrypto.js +4 -6
- package/dist/node/cjs/util/errors.js +26 -59
- package/dist/node/esm/jwe/compact/encrypt.js +1 -0
- package/dist/node/esm/jwe/flattened/decrypt.js +7 -16
- package/dist/node/esm/jwe/flattened/encrypt.js +12 -19
- package/dist/node/esm/jwe/general/encrypt.js +17 -14
- package/dist/node/esm/jwk/embedded.js +2 -2
- package/dist/node/esm/jwk/thumbprint.js +2 -2
- package/dist/node/esm/jwks/local.js +3 -2
- package/dist/node/esm/jwks/remote.js +13 -6
- package/dist/node/esm/jws/compact/sign.js +1 -0
- package/dist/node/esm/jws/flattened/sign.js +4 -1
- package/dist/node/esm/jws/flattened/verify.js +3 -4
- package/dist/node/esm/jws/general/sign.js +7 -1
- package/dist/node/esm/jwt/encrypt.js +7 -0
- package/dist/node/esm/jwt/produce.js +20 -4
- package/dist/node/esm/jwt/sign.js +2 -2
- package/dist/node/esm/jwt/verify.js +1 -2
- package/dist/node/esm/key/import.js +2 -7
- package/dist/node/esm/lib/aesgcmkw.js +1 -1
- package/dist/node/esm/lib/decrypt_key_management.js +1 -1
- package/dist/node/esm/lib/encrypt_key_management.js +1 -1
- package/dist/node/esm/runtime/aeskw.js +2 -2
- package/dist/node/esm/runtime/asn1.js +2 -2
- package/dist/node/esm/runtime/base64url.js +4 -10
- package/dist/node/esm/runtime/cbc_tag.js +1 -1
- package/dist/node/esm/runtime/check_key_length.js +6 -0
- package/dist/node/esm/runtime/ciphers.js +2 -2
- package/dist/node/esm/runtime/decrypt.js +1 -1
- package/dist/node/esm/runtime/digest.js +1 -1
- package/dist/node/esm/runtime/ecdhes.js +2 -2
- package/dist/node/esm/runtime/encrypt.js +1 -1
- package/dist/node/esm/runtime/fetch_jwks.js +3 -3
- package/dist/node/esm/runtime/generate.js +5 -9
- package/dist/node/esm/runtime/get_named_curve.js +5 -42
- package/dist/node/esm/runtime/get_sign_verify_key.js +1 -1
- package/dist/node/esm/runtime/is_key_like.js +1 -1
- package/dist/node/esm/runtime/is_key_object.js +2 -5
- package/dist/node/esm/runtime/jwk_to_key.js +2 -113
- package/dist/node/esm/runtime/key_to_jwk.js +5 -129
- package/dist/node/esm/runtime/node_key.js +7 -16
- package/dist/node/esm/runtime/pbes2kw.js +2 -2
- package/dist/node/esm/runtime/random.js +1 -1
- package/dist/node/esm/runtime/rsaes.js +3 -3
- package/dist/node/esm/runtime/sign.js +3 -9
- package/dist/node/esm/runtime/timing_safe_equal.js +1 -1
- package/dist/node/esm/runtime/verify.js +3 -10
- package/dist/node/esm/runtime/webcrypto.js +3 -6
- package/dist/node/esm/util/errors.js +26 -59
- package/dist/types/index.d.ts +1 -1
- package/dist/types/jwe/compact/decrypt.d.ts +1 -1
- package/dist/types/jwe/flattened/decrypt.d.ts +1 -1
- package/dist/types/jwe/general/decrypt.d.ts +1 -1
- package/dist/types/jwe/general/encrypt.d.ts +3 -7
- package/dist/types/jwk/embedded.d.ts +1 -1
- package/dist/types/jwks/local.d.ts +3 -3
- package/dist/types/jwks/remote.d.ts +1 -1
- package/dist/types/jws/compact/verify.d.ts +1 -1
- package/dist/types/jws/flattened/verify.d.ts +1 -1
- package/dist/types/jws/general/verify.d.ts +1 -1
- package/dist/types/jwt/decrypt.d.ts +3 -3
- package/dist/types/jwt/produce.d.ts +12 -12
- package/dist/types/jwt/unsecured.d.ts +3 -3
- package/dist/types/jwt/verify.d.ts +3 -3
- package/dist/types/key/generate_key_pair.d.ts +7 -5
- package/dist/types/key/generate_secret.d.ts +1 -1
- package/dist/types/key/import.d.ts +4 -6
- package/dist/types/types.d.ts +13 -50
- package/package.json +1 -1
- package/dist/browser/runtime/zlib.js +0 -7
- package/dist/node/cjs/runtime/asn1_sequence_decoder.js +0 -47
- package/dist/node/cjs/runtime/asn1_sequence_encoder.js +0 -91
- package/dist/node/cjs/runtime/check_modulus_length.js +0 -52
- package/dist/node/cjs/runtime/flags.js +0 -8
- package/dist/node/cjs/runtime/zlib.js +0 -11
- package/dist/node/esm/runtime/asn1_sequence_decoder.js +0 -44
- package/dist/node/esm/runtime/asn1_sequence_encoder.js +0 -88
- package/dist/node/esm/runtime/check_modulus_length.js +0 -48
- package/dist/node/esm/runtime/flags.js +0 -5
- package/dist/node/esm/runtime/zlib.js +0 -6
|
@@ -5,12 +5,11 @@ class JOSEError extends Error {
|
|
|
5
5
|
static get code() {
|
|
6
6
|
return 'ERR_JOSE_GENERIC';
|
|
7
7
|
}
|
|
8
|
+
code = 'ERR_JOSE_GENERIC';
|
|
8
9
|
constructor(message) {
|
|
9
|
-
var _a;
|
|
10
10
|
super(message);
|
|
11
|
-
this.code = 'ERR_JOSE_GENERIC';
|
|
12
11
|
this.name = this.constructor.name;
|
|
13
|
-
|
|
12
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
14
13
|
}
|
|
15
14
|
}
|
|
16
15
|
exports.JOSEError = JOSEError;
|
|
@@ -18,9 +17,11 @@ class JWTClaimValidationFailed extends JOSEError {
|
|
|
18
17
|
static get code() {
|
|
19
18
|
return 'ERR_JWT_CLAIM_VALIDATION_FAILED';
|
|
20
19
|
}
|
|
20
|
+
code = 'ERR_JWT_CLAIM_VALIDATION_FAILED';
|
|
21
|
+
claim;
|
|
22
|
+
reason;
|
|
21
23
|
constructor(message, claim = 'unspecified', reason = 'unspecified') {
|
|
22
24
|
super(message);
|
|
23
|
-
this.code = 'ERR_JWT_CLAIM_VALIDATION_FAILED';
|
|
24
25
|
this.claim = claim;
|
|
25
26
|
this.reason = reason;
|
|
26
27
|
}
|
|
@@ -30,137 +31,103 @@ class JWTExpired extends JOSEError {
|
|
|
30
31
|
static get code() {
|
|
31
32
|
return 'ERR_JWT_EXPIRED';
|
|
32
33
|
}
|
|
34
|
+
code = 'ERR_JWT_EXPIRED';
|
|
35
|
+
claim;
|
|
36
|
+
reason;
|
|
33
37
|
constructor(message, claim = 'unspecified', reason = 'unspecified') {
|
|
34
38
|
super(message);
|
|
35
|
-
this.code = 'ERR_JWT_EXPIRED';
|
|
36
39
|
this.claim = claim;
|
|
37
40
|
this.reason = reason;
|
|
38
41
|
}
|
|
39
42
|
}
|
|
40
43
|
exports.JWTExpired = JWTExpired;
|
|
41
44
|
class JOSEAlgNotAllowed extends JOSEError {
|
|
42
|
-
constructor() {
|
|
43
|
-
super(...arguments);
|
|
44
|
-
this.code = 'ERR_JOSE_ALG_NOT_ALLOWED';
|
|
45
|
-
}
|
|
46
45
|
static get code() {
|
|
47
46
|
return 'ERR_JOSE_ALG_NOT_ALLOWED';
|
|
48
47
|
}
|
|
48
|
+
code = 'ERR_JOSE_ALG_NOT_ALLOWED';
|
|
49
49
|
}
|
|
50
50
|
exports.JOSEAlgNotAllowed = JOSEAlgNotAllowed;
|
|
51
51
|
class JOSENotSupported extends JOSEError {
|
|
52
|
-
constructor() {
|
|
53
|
-
super(...arguments);
|
|
54
|
-
this.code = 'ERR_JOSE_NOT_SUPPORTED';
|
|
55
|
-
}
|
|
56
52
|
static get code() {
|
|
57
53
|
return 'ERR_JOSE_NOT_SUPPORTED';
|
|
58
54
|
}
|
|
55
|
+
code = 'ERR_JOSE_NOT_SUPPORTED';
|
|
59
56
|
}
|
|
60
57
|
exports.JOSENotSupported = JOSENotSupported;
|
|
61
58
|
class JWEDecryptionFailed extends JOSEError {
|
|
62
|
-
constructor() {
|
|
63
|
-
super(...arguments);
|
|
64
|
-
this.code = 'ERR_JWE_DECRYPTION_FAILED';
|
|
65
|
-
this.message = 'decryption operation failed';
|
|
66
|
-
}
|
|
67
59
|
static get code() {
|
|
68
60
|
return 'ERR_JWE_DECRYPTION_FAILED';
|
|
69
61
|
}
|
|
62
|
+
code = 'ERR_JWE_DECRYPTION_FAILED';
|
|
63
|
+
message = 'decryption operation failed';
|
|
70
64
|
}
|
|
71
65
|
exports.JWEDecryptionFailed = JWEDecryptionFailed;
|
|
72
66
|
class JWEInvalid extends JOSEError {
|
|
73
|
-
constructor() {
|
|
74
|
-
super(...arguments);
|
|
75
|
-
this.code = 'ERR_JWE_INVALID';
|
|
76
|
-
}
|
|
77
67
|
static get code() {
|
|
78
68
|
return 'ERR_JWE_INVALID';
|
|
79
69
|
}
|
|
70
|
+
code = 'ERR_JWE_INVALID';
|
|
80
71
|
}
|
|
81
72
|
exports.JWEInvalid = JWEInvalid;
|
|
82
73
|
class JWSInvalid extends JOSEError {
|
|
83
|
-
constructor() {
|
|
84
|
-
super(...arguments);
|
|
85
|
-
this.code = 'ERR_JWS_INVALID';
|
|
86
|
-
}
|
|
87
74
|
static get code() {
|
|
88
75
|
return 'ERR_JWS_INVALID';
|
|
89
76
|
}
|
|
77
|
+
code = 'ERR_JWS_INVALID';
|
|
90
78
|
}
|
|
91
79
|
exports.JWSInvalid = JWSInvalid;
|
|
92
80
|
class JWTInvalid extends JOSEError {
|
|
93
|
-
constructor() {
|
|
94
|
-
super(...arguments);
|
|
95
|
-
this.code = 'ERR_JWT_INVALID';
|
|
96
|
-
}
|
|
97
81
|
static get code() {
|
|
98
82
|
return 'ERR_JWT_INVALID';
|
|
99
83
|
}
|
|
84
|
+
code = 'ERR_JWT_INVALID';
|
|
100
85
|
}
|
|
101
86
|
exports.JWTInvalid = JWTInvalid;
|
|
102
87
|
class JWKInvalid extends JOSEError {
|
|
103
|
-
constructor() {
|
|
104
|
-
super(...arguments);
|
|
105
|
-
this.code = 'ERR_JWK_INVALID';
|
|
106
|
-
}
|
|
107
88
|
static get code() {
|
|
108
89
|
return 'ERR_JWK_INVALID';
|
|
109
90
|
}
|
|
91
|
+
code = 'ERR_JWK_INVALID';
|
|
110
92
|
}
|
|
111
93
|
exports.JWKInvalid = JWKInvalid;
|
|
112
94
|
class JWKSInvalid extends JOSEError {
|
|
113
|
-
constructor() {
|
|
114
|
-
super(...arguments);
|
|
115
|
-
this.code = 'ERR_JWKS_INVALID';
|
|
116
|
-
}
|
|
117
95
|
static get code() {
|
|
118
96
|
return 'ERR_JWKS_INVALID';
|
|
119
97
|
}
|
|
98
|
+
code = 'ERR_JWKS_INVALID';
|
|
120
99
|
}
|
|
121
100
|
exports.JWKSInvalid = JWKSInvalid;
|
|
122
101
|
class JWKSNoMatchingKey extends JOSEError {
|
|
123
|
-
constructor() {
|
|
124
|
-
super(...arguments);
|
|
125
|
-
this.code = 'ERR_JWKS_NO_MATCHING_KEY';
|
|
126
|
-
this.message = 'no applicable key found in the JSON Web Key Set';
|
|
127
|
-
}
|
|
128
102
|
static get code() {
|
|
129
103
|
return 'ERR_JWKS_NO_MATCHING_KEY';
|
|
130
104
|
}
|
|
105
|
+
code = 'ERR_JWKS_NO_MATCHING_KEY';
|
|
106
|
+
message = 'no applicable key found in the JSON Web Key Set';
|
|
131
107
|
}
|
|
132
108
|
exports.JWKSNoMatchingKey = JWKSNoMatchingKey;
|
|
133
109
|
class JWKSMultipleMatchingKeys extends JOSEError {
|
|
134
|
-
|
|
135
|
-
super(...arguments);
|
|
136
|
-
this.code = 'ERR_JWKS_MULTIPLE_MATCHING_KEYS';
|
|
137
|
-
this.message = 'multiple matching keys found in the JSON Web Key Set';
|
|
138
|
-
}
|
|
110
|
+
[Symbol.asyncIterator];
|
|
139
111
|
static get code() {
|
|
140
112
|
return 'ERR_JWKS_MULTIPLE_MATCHING_KEYS';
|
|
141
113
|
}
|
|
114
|
+
code = 'ERR_JWKS_MULTIPLE_MATCHING_KEYS';
|
|
115
|
+
message = 'multiple matching keys found in the JSON Web Key Set';
|
|
142
116
|
}
|
|
143
117
|
exports.JWKSMultipleMatchingKeys = JWKSMultipleMatchingKeys;
|
|
144
|
-
Symbol.asyncIterator;
|
|
145
118
|
class JWKSTimeout extends JOSEError {
|
|
146
|
-
constructor() {
|
|
147
|
-
super(...arguments);
|
|
148
|
-
this.code = 'ERR_JWKS_TIMEOUT';
|
|
149
|
-
this.message = 'request timed out';
|
|
150
|
-
}
|
|
151
119
|
static get code() {
|
|
152
120
|
return 'ERR_JWKS_TIMEOUT';
|
|
153
121
|
}
|
|
122
|
+
code = 'ERR_JWKS_TIMEOUT';
|
|
123
|
+
message = 'request timed out';
|
|
154
124
|
}
|
|
155
125
|
exports.JWKSTimeout = JWKSTimeout;
|
|
156
126
|
class JWSSignatureVerificationFailed extends JOSEError {
|
|
157
|
-
constructor() {
|
|
158
|
-
super(...arguments);
|
|
159
|
-
this.code = 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED';
|
|
160
|
-
this.message = 'signature verification failed';
|
|
161
|
-
}
|
|
162
127
|
static get code() {
|
|
163
128
|
return 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED';
|
|
164
129
|
}
|
|
130
|
+
code = 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED';
|
|
131
|
+
message = 'signature verification failed';
|
|
165
132
|
}
|
|
166
133
|
exports.JWSSignatureVerificationFailed = JWSSignatureVerificationFailed;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { decode as base64url } from '../../runtime/base64url.js';
|
|
2
2
|
import decrypt from '../../runtime/decrypt.js';
|
|
3
|
-
import { inflate } from '../../runtime/zlib.js';
|
|
4
3
|
import { JOSEAlgNotAllowed, JOSENotSupported, JWEInvalid } from '../../util/errors.js';
|
|
5
4
|
import isDisjoint from '../../lib/is_disjoint.js';
|
|
6
5
|
import isObject from '../../lib/is_object.js';
|
|
@@ -10,7 +9,6 @@ import generateCek from '../../lib/cek.js';
|
|
|
10
9
|
import validateCrit from '../../lib/validate_crit.js';
|
|
11
10
|
import validateAlgorithms from '../../lib/validate_algorithms.js';
|
|
12
11
|
export async function flattenedDecrypt(jwe, key, options) {
|
|
13
|
-
var _a;
|
|
14
12
|
if (!isObject(jwe)) {
|
|
15
13
|
throw new JWEInvalid('Flattened JWE must be an object');
|
|
16
14
|
}
|
|
@@ -59,14 +57,9 @@ export async function flattenedDecrypt(jwe, key, options) {
|
|
|
59
57
|
...jwe.header,
|
|
60
58
|
...jwe.unprotected,
|
|
61
59
|
};
|
|
62
|
-
validateCrit(JWEInvalid, new Map(), options
|
|
60
|
+
validateCrit(JWEInvalid, new Map(), options?.crit, parsedProt, joseHeader);
|
|
63
61
|
if (joseHeader.zip !== undefined) {
|
|
64
|
-
|
|
65
|
-
throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');
|
|
66
|
-
}
|
|
67
|
-
if (joseHeader.zip !== 'DEF') {
|
|
68
|
-
throw new JOSENotSupported('Unsupported JWE "zip" (Compression Algorithm) Header Parameter value');
|
|
69
|
-
}
|
|
62
|
+
throw new JOSENotSupported('JWE "zip" (Compression Algorithm) Header Parameter is not supported.');
|
|
70
63
|
}
|
|
71
64
|
const { alg, enc } = joseHeader;
|
|
72
65
|
if (typeof alg !== 'string' || !alg) {
|
|
@@ -78,11 +71,12 @@ export async function flattenedDecrypt(jwe, key, options) {
|
|
|
78
71
|
const keyManagementAlgorithms = options && validateAlgorithms('keyManagementAlgorithms', options.keyManagementAlgorithms);
|
|
79
72
|
const contentEncryptionAlgorithms = options &&
|
|
80
73
|
validateAlgorithms('contentEncryptionAlgorithms', options.contentEncryptionAlgorithms);
|
|
81
|
-
if (keyManagementAlgorithms && !keyManagementAlgorithms.has(alg))
|
|
82
|
-
|
|
74
|
+
if ((keyManagementAlgorithms && !keyManagementAlgorithms.has(alg)) ||
|
|
75
|
+
(!keyManagementAlgorithms && alg.startsWith('PBES2'))) {
|
|
76
|
+
throw new JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter value not allowed');
|
|
83
77
|
}
|
|
84
78
|
if (contentEncryptionAlgorithms && !contentEncryptionAlgorithms.has(enc)) {
|
|
85
|
-
throw new JOSEAlgNotAllowed('"enc" (Encryption Algorithm) Header Parameter not allowed');
|
|
79
|
+
throw new JOSEAlgNotAllowed('"enc" (Encryption Algorithm) Header Parameter value not allowed');
|
|
86
80
|
}
|
|
87
81
|
let encryptedKey;
|
|
88
82
|
if (jwe.encrypted_key !== undefined) {
|
|
@@ -122,7 +116,7 @@ export async function flattenedDecrypt(jwe, key, options) {
|
|
|
122
116
|
catch {
|
|
123
117
|
throw new JWEInvalid('Failed to base64url decode the tag');
|
|
124
118
|
}
|
|
125
|
-
const protectedHeader = encoder.encode(
|
|
119
|
+
const protectedHeader = encoder.encode(jwe.protected ?? '');
|
|
126
120
|
let additionalData;
|
|
127
121
|
if (jwe.aad !== undefined) {
|
|
128
122
|
additionalData = concat(protectedHeader, encoder.encode('.'), encoder.encode(jwe.aad));
|
|
@@ -138,9 +132,6 @@ export async function flattenedDecrypt(jwe, key, options) {
|
|
|
138
132
|
throw new JWEInvalid('Failed to base64url decode the ciphertext');
|
|
139
133
|
}
|
|
140
134
|
let plaintext = await decrypt(enc, cek, ciphertext, iv, tag, additionalData);
|
|
141
|
-
if (joseHeader.zip === 'DEF') {
|
|
142
|
-
plaintext = await ((options === null || options === void 0 ? void 0 : options.inflateRaw) || inflate)(plaintext);
|
|
143
|
-
}
|
|
144
135
|
const result = { plaintext };
|
|
145
136
|
if (jwe.protected !== undefined) {
|
|
146
137
|
result.protectedHeader = parsedProt;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { encode as base64url } from '../../runtime/base64url.js';
|
|
2
2
|
import encrypt from '../../runtime/encrypt.js';
|
|
3
|
-
import { deflate } from '../../runtime/zlib.js';
|
|
4
3
|
import generateIv from '../../lib/iv.js';
|
|
5
4
|
import encryptKeyManagement from '../../lib/encrypt_key_management.js';
|
|
6
5
|
import { JOSENotSupported, JWEInvalid } from '../../util/errors.js';
|
|
@@ -9,6 +8,14 @@ import { encoder, decoder, concat } from '../../lib/buffer_utils.js';
|
|
|
9
8
|
import validateCrit from '../../lib/validate_crit.js';
|
|
10
9
|
export const unprotected = Symbol();
|
|
11
10
|
export class FlattenedEncrypt {
|
|
11
|
+
_plaintext;
|
|
12
|
+
_protectedHeader;
|
|
13
|
+
_sharedUnprotectedHeader;
|
|
14
|
+
_unprotectedHeader;
|
|
15
|
+
_aad;
|
|
16
|
+
_cek;
|
|
17
|
+
_iv;
|
|
18
|
+
_keyManagementParameters;
|
|
12
19
|
constructor(plaintext) {
|
|
13
20
|
if (!(plaintext instanceof Uint8Array)) {
|
|
14
21
|
throw new TypeError('plaintext must be an instance of Uint8Array');
|
|
@@ -73,14 +80,9 @@ export class FlattenedEncrypt {
|
|
|
73
80
|
...this._unprotectedHeader,
|
|
74
81
|
...this._sharedUnprotectedHeader,
|
|
75
82
|
};
|
|
76
|
-
validateCrit(JWEInvalid, new Map(), options
|
|
83
|
+
validateCrit(JWEInvalid, new Map(), options?.crit, this._protectedHeader, joseHeader);
|
|
77
84
|
if (joseHeader.zip !== undefined) {
|
|
78
|
-
|
|
79
|
-
throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');
|
|
80
|
-
}
|
|
81
|
-
if (joseHeader.zip !== 'DEF') {
|
|
82
|
-
throw new JOSENotSupported('Unsupported JWE "zip" (Compression Algorithm) Header Parameter value');
|
|
83
|
-
}
|
|
85
|
+
throw new JOSENotSupported('JWE "zip" (Compression Algorithm) Header Parameter is not supported.');
|
|
84
86
|
}
|
|
85
87
|
const { alg, enc } = joseHeader;
|
|
86
88
|
if (typeof alg !== 'string' || !alg) {
|
|
@@ -123,7 +125,7 @@ export class FlattenedEncrypt {
|
|
|
123
125
|
}
|
|
124
126
|
}
|
|
125
127
|
}
|
|
126
|
-
this._iv
|
|
128
|
+
this._iv ||= generateIv(enc);
|
|
127
129
|
let additionalData;
|
|
128
130
|
let protectedHeader;
|
|
129
131
|
let aadMember;
|
|
@@ -140,16 +142,7 @@ export class FlattenedEncrypt {
|
|
|
140
142
|
else {
|
|
141
143
|
additionalData = protectedHeader;
|
|
142
144
|
}
|
|
143
|
-
|
|
144
|
-
let tag;
|
|
145
|
-
if (joseHeader.zip === 'DEF') {
|
|
146
|
-
const deflated = await ((options === null || options === void 0 ? void 0 : options.deflateRaw) || deflate)(this._plaintext);
|
|
147
|
-
({ ciphertext, tag } = await encrypt(enc, deflated, cek, this._iv, additionalData));
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
;
|
|
151
|
-
({ ciphertext, tag } = await encrypt(enc, this._plaintext, cek, this._iv, additionalData));
|
|
152
|
-
}
|
|
145
|
+
const { ciphertext, tag } = await encrypt(enc, this._plaintext, cek, this._iv, additionalData);
|
|
153
146
|
const jwe = {
|
|
154
147
|
ciphertext: base64url(ciphertext),
|
|
155
148
|
iv: base64url(this._iv),
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { FlattenedEncrypt, unprotected } from '../flattened/encrypt.js';
|
|
2
|
-
import { JWEInvalid } from '../../util/errors.js';
|
|
2
|
+
import { JOSENotSupported, JWEInvalid } from '../../util/errors.js';
|
|
3
3
|
import generateCek from '../../lib/cek.js';
|
|
4
4
|
import isDisjoint from '../../lib/is_disjoint.js';
|
|
5
5
|
import encryptKeyManagement from '../../lib/encrypt_key_management.js';
|
|
6
6
|
import { encode as base64url } from '../../runtime/base64url.js';
|
|
7
7
|
import validateCrit from '../../lib/validate_crit.js';
|
|
8
8
|
class IndividualRecipient {
|
|
9
|
+
parent;
|
|
10
|
+
unprotectedHeader;
|
|
11
|
+
key;
|
|
12
|
+
options;
|
|
9
13
|
constructor(enc, key, options) {
|
|
10
14
|
this.parent = enc;
|
|
11
15
|
this.key = key;
|
|
@@ -29,12 +33,16 @@ class IndividualRecipient {
|
|
|
29
33
|
}
|
|
30
34
|
}
|
|
31
35
|
export class GeneralEncrypt {
|
|
36
|
+
_plaintext;
|
|
37
|
+
_recipients = [];
|
|
38
|
+
_protectedHeader;
|
|
39
|
+
_unprotectedHeader;
|
|
40
|
+
_aad;
|
|
32
41
|
constructor(plaintext) {
|
|
33
|
-
this._recipients = [];
|
|
34
42
|
this._plaintext = plaintext;
|
|
35
43
|
}
|
|
36
44
|
addRecipient(key, options) {
|
|
37
|
-
const recipient = new IndividualRecipient(this, key, { crit: options
|
|
45
|
+
const recipient = new IndividualRecipient(this, key, { crit: options?.crit });
|
|
38
46
|
this._recipients.push(recipient);
|
|
39
47
|
return recipient;
|
|
40
48
|
}
|
|
@@ -56,12 +64,10 @@ export class GeneralEncrypt {
|
|
|
56
64
|
this._aad = aad;
|
|
57
65
|
return this;
|
|
58
66
|
}
|
|
59
|
-
async encrypt(
|
|
60
|
-
var _a, _b, _c;
|
|
67
|
+
async encrypt() {
|
|
61
68
|
if (!this._recipients.length) {
|
|
62
69
|
throw new JWEInvalid('at least one recipient must be added');
|
|
63
70
|
}
|
|
64
|
-
options = { deflateRaw: options === null || options === void 0 ? void 0 : options.deflateRaw };
|
|
65
71
|
if (this._recipients.length === 1) {
|
|
66
72
|
const [recipient] = this._recipients;
|
|
67
73
|
const flattened = await new FlattenedEncrypt(this._plaintext)
|
|
@@ -69,7 +75,7 @@ export class GeneralEncrypt {
|
|
|
69
75
|
.setProtectedHeader(this._protectedHeader)
|
|
70
76
|
.setSharedUnprotectedHeader(this._unprotectedHeader)
|
|
71
77
|
.setUnprotectedHeader(recipient.unprotectedHeader)
|
|
72
|
-
.encrypt(recipient.key, { ...recipient.options
|
|
78
|
+
.encrypt(recipient.key, { ...recipient.options });
|
|
73
79
|
let jwe = {
|
|
74
80
|
ciphertext: flattened.ciphertext,
|
|
75
81
|
iv: flattened.iv,
|
|
@@ -117,9 +123,7 @@ export class GeneralEncrypt {
|
|
|
117
123
|
}
|
|
118
124
|
validateCrit(JWEInvalid, new Map(), recipient.options.crit, this._protectedHeader, joseHeader);
|
|
119
125
|
if (joseHeader.zip !== undefined) {
|
|
120
|
-
|
|
121
|
-
throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');
|
|
122
|
-
}
|
|
126
|
+
throw new JOSENotSupported('JWE "zip" (Compression Algorithm) Header Parameter is not supported.');
|
|
123
127
|
}
|
|
124
128
|
}
|
|
125
129
|
const cek = generateCek(enc);
|
|
@@ -149,7 +153,6 @@ export class GeneralEncrypt {
|
|
|
149
153
|
.setKeyManagementParameters({ p2c })
|
|
150
154
|
.encrypt(recipient.key, {
|
|
151
155
|
...recipient.options,
|
|
152
|
-
...options,
|
|
153
156
|
[unprotected]: true,
|
|
154
157
|
});
|
|
155
158
|
jwe.ciphertext = flattened.ciphertext;
|
|
@@ -166,9 +169,9 @@ export class GeneralEncrypt {
|
|
|
166
169
|
target.header = flattened.header;
|
|
167
170
|
continue;
|
|
168
171
|
}
|
|
169
|
-
const { encryptedKey, parameters } = await encryptKeyManagement(
|
|
170
|
-
|
|
171
|
-
|
|
172
|
+
const { encryptedKey, parameters } = await encryptKeyManagement(recipient.unprotectedHeader?.alg ||
|
|
173
|
+
this._protectedHeader?.alg ||
|
|
174
|
+
this._unprotectedHeader?.alg, enc, recipient.key, cek, { p2c });
|
|
172
175
|
target.encrypted_key = base64url(encryptedKey);
|
|
173
176
|
if (recipient.unprotectedHeader || parameters)
|
|
174
177
|
target.header = { ...recipient.unprotectedHeader, ...parameters };
|
|
@@ -4,12 +4,12 @@ import { JWSInvalid } from '../util/errors.js';
|
|
|
4
4
|
export async function EmbeddedJWK(protectedHeader, token) {
|
|
5
5
|
const joseHeader = {
|
|
6
6
|
...protectedHeader,
|
|
7
|
-
...token
|
|
7
|
+
...token?.header,
|
|
8
8
|
};
|
|
9
9
|
if (!isObject(joseHeader.jwk)) {
|
|
10
10
|
throw new JWSInvalid('"jwk" (JSON Web Key) Header Parameter must be a JSON object');
|
|
11
11
|
}
|
|
12
|
-
const key = await importJWK({ ...joseHeader.jwk, ext: true }, joseHeader.alg
|
|
12
|
+
const key = await importJWK({ ...joseHeader.jwk, ext: true }, joseHeader.alg);
|
|
13
13
|
if (key instanceof Uint8Array || key.type !== 'public') {
|
|
14
14
|
throw new JWSInvalid('"jwk" (JSON Web Key) Header Parameter must be a public key');
|
|
15
15
|
}
|
|
@@ -12,7 +12,7 @@ export async function calculateJwkThumbprint(jwk, digestAlgorithm) {
|
|
|
12
12
|
if (!isObject(jwk)) {
|
|
13
13
|
throw new TypeError('JWK must be an object');
|
|
14
14
|
}
|
|
15
|
-
digestAlgorithm
|
|
15
|
+
digestAlgorithm ??= 'sha256';
|
|
16
16
|
if (digestAlgorithm !== 'sha256' &&
|
|
17
17
|
digestAlgorithm !== 'sha384' &&
|
|
18
18
|
digestAlgorithm !== 'sha512') {
|
|
@@ -47,7 +47,7 @@ export async function calculateJwkThumbprint(jwk, digestAlgorithm) {
|
|
|
47
47
|
return base64url(await digest(digestAlgorithm, data));
|
|
48
48
|
}
|
|
49
49
|
export async function calculateJwkThumbprintUri(jwk, digestAlgorithm) {
|
|
50
|
-
digestAlgorithm
|
|
50
|
+
digestAlgorithm ??= 'sha256';
|
|
51
51
|
const thumbprint = await calculateJwkThumbprint(jwk, digestAlgorithm);
|
|
52
52
|
return `urn:ietf:params:oauth:jwk-thumbprint:sha-${digestAlgorithm.slice(-3)}:${thumbprint}`;
|
|
53
53
|
}
|
|
@@ -30,15 +30,16 @@ function clone(obj) {
|
|
|
30
30
|
return JSON.parse(JSON.stringify(obj));
|
|
31
31
|
}
|
|
32
32
|
export class LocalJWKSet {
|
|
33
|
+
_jwks;
|
|
34
|
+
_cached = new WeakMap();
|
|
33
35
|
constructor(jwks) {
|
|
34
|
-
this._cached = new WeakMap();
|
|
35
36
|
if (!isJWKSLike(jwks)) {
|
|
36
37
|
throw new JWKSInvalid('JSON Web Key Set malformed');
|
|
37
38
|
}
|
|
38
39
|
this._jwks = clone(jwks);
|
|
39
40
|
}
|
|
40
41
|
async getKey(protectedHeader, token) {
|
|
41
|
-
const { alg, kid } = { ...protectedHeader, ...token
|
|
42
|
+
const { alg, kid } = { ...protectedHeader, ...token?.header };
|
|
42
43
|
const kty = getKtyFromAlg(alg);
|
|
43
44
|
const candidates = this._jwks.keys.filter((jwk) => {
|
|
44
45
|
let candidate = kty === jwk.kty;
|
|
@@ -7,6 +7,13 @@ function isCloudflareWorkers() {
|
|
|
7
7
|
(typeof EdgeRuntime !== 'undefined' && EdgeRuntime === 'vercel'));
|
|
8
8
|
}
|
|
9
9
|
class RemoteJWKSet extends LocalJWKSet {
|
|
10
|
+
_url;
|
|
11
|
+
_timeoutDuration;
|
|
12
|
+
_cooldownDuration;
|
|
13
|
+
_cacheMaxAge;
|
|
14
|
+
_jwksTimestamp;
|
|
15
|
+
_pendingFetch;
|
|
16
|
+
_options;
|
|
10
17
|
constructor(url, options) {
|
|
11
18
|
super({ keys: [] });
|
|
12
19
|
this._jwks = undefined;
|
|
@@ -14,12 +21,12 @@ class RemoteJWKSet extends LocalJWKSet {
|
|
|
14
21
|
throw new TypeError('url must be an instance of URL');
|
|
15
22
|
}
|
|
16
23
|
this._url = new URL(url.href);
|
|
17
|
-
this._options = { agent: options
|
|
24
|
+
this._options = { agent: options?.agent, headers: options?.headers };
|
|
18
25
|
this._timeoutDuration =
|
|
19
|
-
typeof
|
|
26
|
+
typeof options?.timeoutDuration === 'number' ? options?.timeoutDuration : 5000;
|
|
20
27
|
this._cooldownDuration =
|
|
21
|
-
typeof
|
|
22
|
-
this._cacheMaxAge = typeof
|
|
28
|
+
typeof options?.cooldownDuration === 'number' ? options?.cooldownDuration : 30000;
|
|
29
|
+
this._cacheMaxAge = typeof options?.cacheMaxAge === 'number' ? options?.cacheMaxAge : 600000;
|
|
23
30
|
}
|
|
24
31
|
coolingDown() {
|
|
25
32
|
return typeof this._jwksTimestamp === 'number'
|
|
@@ -52,7 +59,7 @@ class RemoteJWKSet extends LocalJWKSet {
|
|
|
52
59
|
if (this._pendingFetch && isCloudflareWorkers()) {
|
|
53
60
|
this._pendingFetch = undefined;
|
|
54
61
|
}
|
|
55
|
-
this._pendingFetch
|
|
62
|
+
this._pendingFetch ||= fetchJwks(this._url, this._timeoutDuration, this._options)
|
|
56
63
|
.then((json) => {
|
|
57
64
|
if (!isJWKSLike(json)) {
|
|
58
65
|
throw new JWKSInvalid('JSON Web Key Set malformed');
|
|
@@ -64,7 +71,7 @@ class RemoteJWKSet extends LocalJWKSet {
|
|
|
64
71
|
.catch((err) => {
|
|
65
72
|
this._pendingFetch = undefined;
|
|
66
73
|
throw err;
|
|
67
|
-
})
|
|
74
|
+
});
|
|
68
75
|
await this._pendingFetch;
|
|
69
76
|
}
|
|
70
77
|
}
|
|
@@ -6,6 +6,9 @@ import { encoder, decoder, concat } 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
|
export class FlattenedSign {
|
|
9
|
+
_payload;
|
|
10
|
+
_protectedHeader;
|
|
11
|
+
_unprotectedHeader;
|
|
9
12
|
constructor(payload) {
|
|
10
13
|
if (!(payload instanceof Uint8Array)) {
|
|
11
14
|
throw new TypeError('payload must be an instance of Uint8Array');
|
|
@@ -37,7 +40,7 @@ export class FlattenedSign {
|
|
|
37
40
|
...this._protectedHeader,
|
|
38
41
|
...this._unprotectedHeader,
|
|
39
42
|
};
|
|
40
|
-
const extensions = validateCrit(JWSInvalid, new Map([['b64', true]]), options
|
|
43
|
+
const extensions = validateCrit(JWSInvalid, new Map([['b64', true]]), options?.crit, this._protectedHeader, joseHeader);
|
|
41
44
|
let b64 = true;
|
|
42
45
|
if (extensions.has('b64')) {
|
|
43
46
|
b64 = this._protectedHeader.b64;
|
|
@@ -8,7 +8,6 @@ import checkKeyType from '../../lib/check_key_type.js';
|
|
|
8
8
|
import validateCrit from '../../lib/validate_crit.js';
|
|
9
9
|
import validateAlgorithms from '../../lib/validate_algorithms.js';
|
|
10
10
|
export async function flattenedVerify(jws, key, options) {
|
|
11
|
-
var _a;
|
|
12
11
|
if (!isObject(jws)) {
|
|
13
12
|
throw new JWSInvalid('Flattened JWS must be an object');
|
|
14
13
|
}
|
|
@@ -44,7 +43,7 @@ export async function flattenedVerify(jws, key, options) {
|
|
|
44
43
|
...parsedProt,
|
|
45
44
|
...jws.header,
|
|
46
45
|
};
|
|
47
|
-
const extensions = validateCrit(JWSInvalid, new Map([['b64', true]]), options
|
|
46
|
+
const extensions = validateCrit(JWSInvalid, new Map([['b64', true]]), options?.crit, parsedProt, joseHeader);
|
|
48
47
|
let b64 = true;
|
|
49
48
|
if (extensions.has('b64')) {
|
|
50
49
|
b64 = parsedProt.b64;
|
|
@@ -58,7 +57,7 @@ export async function flattenedVerify(jws, key, options) {
|
|
|
58
57
|
}
|
|
59
58
|
const algorithms = options && validateAlgorithms('algorithms', options.algorithms);
|
|
60
59
|
if (algorithms && !algorithms.has(alg)) {
|
|
61
|
-
throw new JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter not allowed');
|
|
60
|
+
throw new JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter value not allowed');
|
|
62
61
|
}
|
|
63
62
|
if (b64) {
|
|
64
63
|
if (typeof jws.payload !== 'string') {
|
|
@@ -74,7 +73,7 @@ export async function flattenedVerify(jws, key, options) {
|
|
|
74
73
|
resolvedKey = true;
|
|
75
74
|
}
|
|
76
75
|
checkKeyType(alg, key, 'verify');
|
|
77
|
-
const data = concat(encoder.encode(
|
|
76
|
+
const data = concat(encoder.encode(jws.protected ?? ''), encoder.encode('.'), typeof jws.payload === 'string' ? encoder.encode(jws.payload) : jws.payload);
|
|
78
77
|
let signature;
|
|
79
78
|
try {
|
|
80
79
|
signature = base64url(jws.signature);
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { FlattenedSign } from '../flattened/sign.js';
|
|
2
2
|
import { JWSInvalid } from '../../util/errors.js';
|
|
3
3
|
class IndividualSignature {
|
|
4
|
+
parent;
|
|
5
|
+
protectedHeader;
|
|
6
|
+
unprotectedHeader;
|
|
7
|
+
options;
|
|
8
|
+
key;
|
|
4
9
|
constructor(sig, key, options) {
|
|
5
10
|
this.parent = sig;
|
|
6
11
|
this.key = key;
|
|
@@ -31,8 +36,9 @@ class IndividualSignature {
|
|
|
31
36
|
}
|
|
32
37
|
}
|
|
33
38
|
export class GeneralSign {
|
|
39
|
+
_payload;
|
|
40
|
+
_signatures = [];
|
|
34
41
|
constructor(payload) {
|
|
35
|
-
this._signatures = [];
|
|
36
42
|
this._payload = payload;
|
|
37
43
|
}
|
|
38
44
|
addSignature(key, options) {
|
|
@@ -2,6 +2,13 @@ import { CompactEncrypt } from '../jwe/compact/encrypt.js';
|
|
|
2
2
|
import { encoder } from '../lib/buffer_utils.js';
|
|
3
3
|
import { ProduceJWT } from './produce.js';
|
|
4
4
|
export class EncryptJWT extends ProduceJWT {
|
|
5
|
+
_cek;
|
|
6
|
+
_iv;
|
|
7
|
+
_keyManagementParameters;
|
|
8
|
+
_protectedHeader;
|
|
9
|
+
_replicateIssuerAsHeader;
|
|
10
|
+
_replicateSubjectAsHeader;
|
|
11
|
+
_replicateAudienceAsHeader;
|
|
5
12
|
setProtectedHeader(protectedHeader) {
|
|
6
13
|
if (this._protectedHeader) {
|
|
7
14
|
throw new TypeError('setProtectedHeader can only be called once');
|