jose 3.19.0 → 3.20.3
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/browser/jwe/flattened/decrypt.js +5 -9
- package/dist/browser/jwe/flattened/encrypt.js +2 -5
- package/dist/browser/jwk/embedded.js +2 -2
- package/dist/browser/jwks/remote.js +7 -10
- package/dist/browser/jws/flattened/sign.js +1 -2
- package/dist/browser/jws/flattened/verify.js +2 -4
- package/dist/browser/jwt/encrypt.js +1 -1
- package/dist/browser/{lib/jwt_producer.js → jwt/produce.js} +4 -4
- package/dist/browser/jwt/sign.js +1 -1
- package/dist/browser/jwt/unsecured.js +1 -1
- package/dist/browser/lib/cek.js +3 -2
- package/dist/browser/lib/check_key_type.js +33 -16
- package/dist/browser/lib/decrypt_key_management.js +35 -35
- package/dist/browser/lib/encrypt_key_management.js +3 -5
- package/dist/browser/lib/iv.js +3 -2
- package/dist/browser/runtime/aesgcmkw.js +1 -3
- package/dist/browser/runtime/fetch_jwks.js +16 -3
- package/dist/browser/runtime/is_key_like.js +5 -0
- package/dist/browser/runtime/random.js +1 -2
- package/dist/browser/util/errors.js +73 -34
- package/dist/node/cjs/jwe/flattened/decrypt.js +5 -9
- package/dist/node/cjs/jwe/flattened/encrypt.js +2 -5
- package/dist/node/cjs/jwk/embedded.js +2 -2
- package/dist/node/cjs/jwks/remote.js +7 -10
- package/dist/node/cjs/jws/flattened/sign.js +1 -2
- package/dist/node/cjs/jws/flattened/verify.js +2 -4
- package/dist/node/cjs/jwt/encrypt.js +2 -2
- package/dist/node/cjs/{lib/jwt_producer.js → jwt/produce.js} +5 -4
- package/dist/node/cjs/jwt/sign.js +2 -2
- package/dist/node/cjs/jwt/unsecured.js +2 -2
- package/dist/node/cjs/lib/cek.js +4 -3
- package/dist/node/cjs/lib/check_key_type.js +33 -16
- package/dist/node/cjs/lib/decrypt_key_management.js +35 -35
- package/dist/node/cjs/lib/encrypt_key_management.js +7 -9
- package/dist/node/cjs/lib/iv.js +4 -3
- package/dist/node/cjs/runtime/aesgcmkw.js +1 -3
- package/dist/node/cjs/runtime/fetch_jwks.js +5 -1
- package/dist/node/cjs/runtime/is_key_like.js +11 -0
- package/dist/node/cjs/runtime/random.js +3 -2
- package/dist/node/cjs/util/errors.js +77 -37
- package/dist/node/esm/jwe/flattened/decrypt.js +5 -9
- package/dist/node/esm/jwe/flattened/encrypt.js +2 -5
- package/dist/node/esm/jwk/embedded.js +2 -2
- package/dist/node/esm/jwks/remote.js +7 -10
- package/dist/node/esm/jws/flattened/sign.js +1 -2
- package/dist/node/esm/jws/flattened/verify.js +2 -4
- package/dist/node/esm/jwt/encrypt.js +1 -1
- package/dist/node/esm/{lib/jwt_producer.js → jwt/produce.js} +4 -4
- package/dist/node/esm/jwt/sign.js +1 -1
- package/dist/node/esm/jwt/unsecured.js +1 -1
- package/dist/node/esm/lib/cek.js +3 -2
- package/dist/node/esm/lib/check_key_type.js +33 -16
- package/dist/node/esm/lib/decrypt_key_management.js +35 -35
- package/dist/node/esm/lib/encrypt_key_management.js +3 -5
- package/dist/node/esm/lib/iv.js +3 -2
- package/dist/node/esm/runtime/aesgcmkw.js +1 -3
- package/dist/node/esm/runtime/fetch_jwks.js +6 -2
- package/dist/node/esm/runtime/is_key_like.js +8 -0
- package/dist/node/esm/runtime/random.js +1 -2
- package/dist/node/esm/util/errors.js +73 -34
- package/dist/types/jwe/compact/decrypt.d.ts +1 -1
- package/dist/types/jwe/compact/encrypt.d.ts +1 -1
- package/dist/types/jwe/flattened/decrypt.d.ts +1 -1
- package/dist/types/jwe/flattened/encrypt.d.ts +1 -1
- package/dist/types/jwe/general/decrypt.d.ts +1 -1
- package/dist/types/jwk/embedded.d.ts +2 -3
- package/dist/types/jwk/from_key_like.d.ts +1 -1
- package/dist/types/jwk/parse.d.ts +1 -1
- package/dist/types/jws/compact/sign.d.ts +1 -1
- package/dist/types/jws/compact/verify.d.ts +1 -1
- package/dist/types/jws/flattened/sign.d.ts +1 -1
- package/dist/types/jws/flattened/verify.d.ts +1 -1
- package/dist/types/jws/general/sign.d.ts +1 -1
- package/dist/types/jws/general/verify.d.ts +1 -1
- package/dist/types/jwt/decrypt.d.ts +1 -1
- package/dist/types/jwt/encrypt.d.ts +2 -2
- package/dist/types/{lib/jwt_producer.d.ts → jwt/produce.d.ts} +1 -1
- package/dist/types/jwt/sign.d.ts +2 -2
- package/dist/types/jwt/unsecured.d.ts +1 -1
- package/dist/types/jwt/verify.d.ts +1 -1
- package/dist/types/key/export.d.ts +3 -3
- package/dist/types/key/import.d.ts +4 -4
- package/dist/types/types.d.ts +99 -6
- package/dist/types/util/errors.d.ts +24 -16
- package/dist/types/util/generate_key_pair.d.ts +2 -2
- package/dist/types/util/generate_secret.d.ts +1 -1
- package/package.json +3 -4
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const random_js_1 = require("../runtime/random.js");
|
|
4
3
|
const aeskw_js_1 = require("../runtime/aeskw.js");
|
|
5
4
|
const ECDH = require("../runtime/ecdhes.js");
|
|
6
5
|
const pbes2kw_js_1 = require("../runtime/pbes2kw.js");
|
|
@@ -9,9 +8,8 @@ const aesgcmkw_js_1 = require("../runtime/aesgcmkw.js");
|
|
|
9
8
|
const base64url_js_1 = require("../runtime/base64url.js");
|
|
10
9
|
const cek_js_1 = require("../lib/cek.js");
|
|
11
10
|
const errors_js_1 = require("../util/errors.js");
|
|
12
|
-
const
|
|
11
|
+
const export_js_1 = require("../key/export.js");
|
|
13
12
|
const check_key_type_js_1 = require("./check_key_type.js");
|
|
14
|
-
const generateCek = (0, cek_js_1.default)(random_js_1.default);
|
|
15
13
|
async function encryptKeyManagement(alg, enc, key, providedCek, providedParameters = {}) {
|
|
16
14
|
let encryptedKey;
|
|
17
15
|
let parameters;
|
|
@@ -32,7 +30,7 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
|
|
|
32
30
|
const { apu, apv } = providedParameters;
|
|
33
31
|
let { epk: ephemeralKey } = providedParameters;
|
|
34
32
|
ephemeralKey || (ephemeralKey = await ECDH.generateEpk(key));
|
|
35
|
-
const { x, y, crv, kty } = await (0,
|
|
33
|
+
const { x, y, crv, kty } = await (0, export_js_1.exportJWK)(ephemeralKey);
|
|
36
34
|
const sharedSecret = await ECDH.deriveKey(key, ephemeralKey, alg === 'ECDH-ES' ? enc : alg, parseInt(alg.substr(-5, 3), 10) || cek_js_1.bitLengths.get(enc), apu, apv);
|
|
37
35
|
parameters = { epk: { x, y, crv, kty } };
|
|
38
36
|
if (apu)
|
|
@@ -43,7 +41,7 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
|
|
|
43
41
|
cek = sharedSecret;
|
|
44
42
|
break;
|
|
45
43
|
}
|
|
46
|
-
cek = providedCek ||
|
|
44
|
+
cek = providedCek || (0, cek_js_1.default)(enc);
|
|
47
45
|
const kwAlg = alg.substr(-6);
|
|
48
46
|
encryptedKey = await (0, aeskw_js_1.wrap)(kwAlg, sharedSecret, cek);
|
|
49
47
|
break;
|
|
@@ -53,14 +51,14 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
|
|
|
53
51
|
case 'RSA-OAEP-256':
|
|
54
52
|
case 'RSA-OAEP-384':
|
|
55
53
|
case 'RSA-OAEP-512': {
|
|
56
|
-
cek = providedCek ||
|
|
54
|
+
cek = providedCek || (0, cek_js_1.default)(enc);
|
|
57
55
|
encryptedKey = await (0, rsaes_js_1.encrypt)(alg, key, cek);
|
|
58
56
|
break;
|
|
59
57
|
}
|
|
60
58
|
case 'PBES2-HS256+A128KW':
|
|
61
59
|
case 'PBES2-HS384+A192KW':
|
|
62
60
|
case 'PBES2-HS512+A256KW': {
|
|
63
|
-
cek = providedCek ||
|
|
61
|
+
cek = providedCek || (0, cek_js_1.default)(enc);
|
|
64
62
|
const { p2c, p2s } = providedParameters;
|
|
65
63
|
({ encryptedKey, ...parameters } = await (0, pbes2kw_js_1.encrypt)(alg, key, cek, p2c, p2s));
|
|
66
64
|
break;
|
|
@@ -68,14 +66,14 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
|
|
|
68
66
|
case 'A128KW':
|
|
69
67
|
case 'A192KW':
|
|
70
68
|
case 'A256KW': {
|
|
71
|
-
cek = providedCek ||
|
|
69
|
+
cek = providedCek || (0, cek_js_1.default)(enc);
|
|
72
70
|
encryptedKey = await (0, aeskw_js_1.wrap)(alg, key, cek);
|
|
73
71
|
break;
|
|
74
72
|
}
|
|
75
73
|
case 'A128GCMKW':
|
|
76
74
|
case 'A192GCMKW':
|
|
77
75
|
case 'A256GCMKW': {
|
|
78
|
-
cek = providedCek ||
|
|
76
|
+
cek = providedCek || (0, cek_js_1.default)(enc);
|
|
79
77
|
const { iv } = providedParameters;
|
|
80
78
|
({ encryptedKey, ...parameters } = await (0, aesgcmkw_js_1.wrap)(alg, key, cek, iv));
|
|
81
79
|
break;
|
package/dist/node/cjs/lib/iv.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.bitLengths = void 0;
|
|
4
4
|
const errors_js_1 = require("../util/errors.js");
|
|
5
|
+
const random_js_1 = require("../runtime/random.js");
|
|
5
6
|
const bitLengths = new Map([
|
|
6
7
|
['A128CBC-HS256', 128],
|
|
7
8
|
['A128GCM', 96],
|
|
@@ -14,11 +15,11 @@ const bitLengths = new Map([
|
|
|
14
15
|
['A256GCMKW', 96],
|
|
15
16
|
]);
|
|
16
17
|
exports.bitLengths = bitLengths;
|
|
17
|
-
const
|
|
18
|
+
const generateIv = (alg) => {
|
|
18
19
|
const bitLength = bitLengths.get(alg);
|
|
19
20
|
if (!bitLength) {
|
|
20
21
|
throw new errors_js_1.JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`);
|
|
21
22
|
}
|
|
22
|
-
return
|
|
23
|
+
return (0, random_js_1.default)(new Uint8Array(bitLength >> 3));
|
|
23
24
|
};
|
|
24
|
-
exports.default =
|
|
25
|
+
exports.default = generateIv;
|
|
@@ -4,12 +4,10 @@ exports.unwrap = exports.wrap = void 0;
|
|
|
4
4
|
const encrypt_js_1 = require("./encrypt.js");
|
|
5
5
|
const decrypt_js_1 = require("./decrypt.js");
|
|
6
6
|
const iv_js_1 = require("../lib/iv.js");
|
|
7
|
-
const random_js_1 = require("./random.js");
|
|
8
7
|
const base64url_js_1 = require("./base64url.js");
|
|
9
|
-
const generateIv = (0, iv_js_1.default)(random_js_1.default);
|
|
10
8
|
const wrap = async (alg, key, cek, iv) => {
|
|
11
9
|
const jweAlgorithm = alg.substr(0, 7);
|
|
12
|
-
iv || (iv =
|
|
10
|
+
iv || (iv = (0, iv_js_1.default)(jweAlgorithm));
|
|
13
11
|
const { ciphertext: encryptedKey, tag } = await (0, encrypt_js_1.default)(jweAlgorithm, cek, key, iv, new Uint8Array(0));
|
|
14
12
|
return { encryptedKey, iv: (0, base64url_js_1.encode)(iv), tag: (0, base64url_js_1.encode)(tag) };
|
|
15
13
|
};
|
|
@@ -18,7 +18,11 @@ const fetchJwks = async (url, timeout, options) => {
|
|
|
18
18
|
agent,
|
|
19
19
|
timeout,
|
|
20
20
|
});
|
|
21
|
-
const [response] = await (0, events_1.once)(req, 'response');
|
|
21
|
+
const [response] = (await Promise.race([(0, events_1.once)(req, 'response'), (0, events_1.once)(req, 'timeout')]));
|
|
22
|
+
if (!response) {
|
|
23
|
+
req.destroy();
|
|
24
|
+
throw new errors_js_1.JWKSTimeout();
|
|
25
|
+
}
|
|
22
26
|
if (response.statusCode !== 200) {
|
|
23
27
|
throw new errors_js_1.JOSEError('Expected 200 OK from the JSON Web Key Set HTTP response');
|
|
24
28
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.types = void 0;
|
|
4
|
+
const webcrypto_js_1 = require("./webcrypto.js");
|
|
5
|
+
const is_key_object_js_1 = require("./is_key_object.js");
|
|
6
|
+
exports.default = (key) => (0, is_key_object_js_1.default)(key) || (0, webcrypto_js_1.isCryptoKey)(key);
|
|
7
|
+
const types = ['KeyObject'];
|
|
8
|
+
exports.types = types;
|
|
9
|
+
if (parseInt(process.versions.node) >= 16) {
|
|
10
|
+
types.push('CryptoKey');
|
|
11
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
exports.default = void 0;
|
|
4
|
+
var crypto_1 = require("crypto");
|
|
5
|
+
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return crypto_1.randomFillSync; } });
|
|
@@ -1,125 +1,165 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.JWSSignatureVerificationFailed = exports.JWKSTimeout = exports.JWKSMultipleMatchingKeys = exports.JWKSNoMatchingKey = exports.JWKSInvalid = exports.JWKInvalid = exports.JWTInvalid = exports.JWSInvalid = exports.JWEInvalid = exports.JWEDecryptionFailed = exports.JOSENotSupported = exports.JOSEAlgNotAllowed = exports.JWTExpired = exports.JWTClaimValidationFailed = exports.JOSEError = void 0;
|
|
4
4
|
class JOSEError extends Error {
|
|
5
5
|
constructor(message) {
|
|
6
|
+
var _a;
|
|
6
7
|
super(message);
|
|
7
|
-
this.code =
|
|
8
|
+
this.code = 'ERR_JOSE_GENERIC';
|
|
8
9
|
this.name = this.constructor.name;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
(_a = Error.captureStackTrace) === null || _a === void 0 ? void 0 : _a.call(Error, this, this.constructor);
|
|
11
|
+
}
|
|
12
|
+
static get code() {
|
|
13
|
+
return 'ERR_JOSE_GENERIC';
|
|
12
14
|
}
|
|
13
15
|
}
|
|
14
16
|
exports.JOSEError = JOSEError;
|
|
15
|
-
JOSEError.code = 'ERR_JOSE_GENERIC';
|
|
16
17
|
class JWTClaimValidationFailed extends JOSEError {
|
|
17
18
|
constructor(message, claim = 'unspecified', reason = 'unspecified') {
|
|
18
19
|
super(message);
|
|
19
|
-
this.code =
|
|
20
|
+
this.code = 'ERR_JWT_CLAIM_VALIDATION_FAILED';
|
|
20
21
|
this.claim = claim;
|
|
21
22
|
this.reason = reason;
|
|
22
23
|
}
|
|
24
|
+
static get code() {
|
|
25
|
+
return 'ERR_JWT_CLAIM_VALIDATION_FAILED';
|
|
26
|
+
}
|
|
23
27
|
}
|
|
24
28
|
exports.JWTClaimValidationFailed = JWTClaimValidationFailed;
|
|
25
|
-
|
|
29
|
+
class JWTExpired extends JOSEError {
|
|
30
|
+
constructor(message, claim = 'unspecified', reason = 'unspecified') {
|
|
31
|
+
super(message);
|
|
32
|
+
this.code = 'ERR_JWT_EXPIRED';
|
|
33
|
+
this.claim = claim;
|
|
34
|
+
this.reason = reason;
|
|
35
|
+
}
|
|
36
|
+
static get code() {
|
|
37
|
+
return 'ERR_JWT_EXPIRED';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.JWTExpired = JWTExpired;
|
|
26
41
|
class JOSEAlgNotAllowed extends JOSEError {
|
|
27
42
|
constructor() {
|
|
28
43
|
super(...arguments);
|
|
29
|
-
this.code =
|
|
44
|
+
this.code = 'ERR_JOSE_ALG_NOT_ALLOWED';
|
|
45
|
+
}
|
|
46
|
+
static get code() {
|
|
47
|
+
return 'ERR_JOSE_ALG_NOT_ALLOWED';
|
|
30
48
|
}
|
|
31
49
|
}
|
|
32
50
|
exports.JOSEAlgNotAllowed = JOSEAlgNotAllowed;
|
|
33
|
-
JOSEAlgNotAllowed.code = 'ERR_JOSE_ALG_NOT_ALLOWED';
|
|
34
51
|
class JOSENotSupported extends JOSEError {
|
|
35
52
|
constructor() {
|
|
36
53
|
super(...arguments);
|
|
37
|
-
this.code =
|
|
54
|
+
this.code = 'ERR_JOSE_NOT_SUPPORTED';
|
|
55
|
+
}
|
|
56
|
+
static get code() {
|
|
57
|
+
return 'ERR_JOSE_NOT_SUPPORTED';
|
|
38
58
|
}
|
|
39
59
|
}
|
|
40
60
|
exports.JOSENotSupported = JOSENotSupported;
|
|
41
|
-
JOSENotSupported.code = 'ERR_JOSE_NOT_SUPPORTED';
|
|
42
61
|
class JWEDecryptionFailed extends JOSEError {
|
|
43
62
|
constructor() {
|
|
44
63
|
super(...arguments);
|
|
45
|
-
this.code =
|
|
64
|
+
this.code = 'ERR_JWE_DECRYPTION_FAILED';
|
|
46
65
|
this.message = 'decryption operation failed';
|
|
47
66
|
}
|
|
67
|
+
static get code() {
|
|
68
|
+
return 'ERR_JWE_DECRYPTION_FAILED';
|
|
69
|
+
}
|
|
48
70
|
}
|
|
49
71
|
exports.JWEDecryptionFailed = JWEDecryptionFailed;
|
|
50
|
-
JWEDecryptionFailed.code = 'ERR_JWE_DECRYPTION_FAILED';
|
|
51
72
|
class JWEInvalid extends JOSEError {
|
|
52
73
|
constructor() {
|
|
53
74
|
super(...arguments);
|
|
54
|
-
this.code =
|
|
75
|
+
this.code = 'ERR_JWE_INVALID';
|
|
76
|
+
}
|
|
77
|
+
static get code() {
|
|
78
|
+
return 'ERR_JWE_INVALID';
|
|
55
79
|
}
|
|
56
80
|
}
|
|
57
81
|
exports.JWEInvalid = JWEInvalid;
|
|
58
|
-
JWEInvalid.code = 'ERR_JWE_INVALID';
|
|
59
82
|
class JWSInvalid extends JOSEError {
|
|
60
83
|
constructor() {
|
|
61
84
|
super(...arguments);
|
|
62
|
-
this.code =
|
|
85
|
+
this.code = 'ERR_JWS_INVALID';
|
|
86
|
+
}
|
|
87
|
+
static get code() {
|
|
88
|
+
return 'ERR_JWS_INVALID';
|
|
63
89
|
}
|
|
64
90
|
}
|
|
65
91
|
exports.JWSInvalid = JWSInvalid;
|
|
66
|
-
JWSInvalid.code = 'ERR_JWS_INVALID';
|
|
67
92
|
class JWTInvalid extends JOSEError {
|
|
68
93
|
constructor() {
|
|
69
94
|
super(...arguments);
|
|
70
|
-
this.code =
|
|
95
|
+
this.code = 'ERR_JWT_INVALID';
|
|
96
|
+
}
|
|
97
|
+
static get code() {
|
|
98
|
+
return 'ERR_JWT_INVALID';
|
|
71
99
|
}
|
|
72
100
|
}
|
|
73
101
|
exports.JWTInvalid = JWTInvalid;
|
|
74
|
-
JWTInvalid.code = 'ERR_JWT_INVALID';
|
|
75
102
|
class JWKInvalid extends JOSEError {
|
|
76
103
|
constructor() {
|
|
77
104
|
super(...arguments);
|
|
78
|
-
this.code =
|
|
105
|
+
this.code = 'ERR_JWK_INVALID';
|
|
106
|
+
}
|
|
107
|
+
static get code() {
|
|
108
|
+
return 'ERR_JWK_INVALID';
|
|
79
109
|
}
|
|
80
110
|
}
|
|
81
111
|
exports.JWKInvalid = JWKInvalid;
|
|
82
|
-
JWKInvalid.code = 'ERR_JWK_INVALID';
|
|
83
112
|
class JWKSInvalid extends JOSEError {
|
|
84
113
|
constructor() {
|
|
85
114
|
super(...arguments);
|
|
86
|
-
this.code =
|
|
115
|
+
this.code = 'ERR_JWKS_INVALID';
|
|
116
|
+
}
|
|
117
|
+
static get code() {
|
|
118
|
+
return 'ERR_JWKS_INVALID';
|
|
87
119
|
}
|
|
88
120
|
}
|
|
89
121
|
exports.JWKSInvalid = JWKSInvalid;
|
|
90
|
-
JWKSInvalid.code = 'ERR_JWKS_INVALID';
|
|
91
122
|
class JWKSNoMatchingKey extends JOSEError {
|
|
92
123
|
constructor() {
|
|
93
124
|
super(...arguments);
|
|
94
|
-
this.code =
|
|
125
|
+
this.code = 'ERR_JWKS_NO_MATCHING_KEY';
|
|
95
126
|
this.message = 'no applicable key found in the JSON Web Key Set';
|
|
96
127
|
}
|
|
128
|
+
static get code() {
|
|
129
|
+
return 'ERR_JWKS_NO_MATCHING_KEY';
|
|
130
|
+
}
|
|
97
131
|
}
|
|
98
132
|
exports.JWKSNoMatchingKey = JWKSNoMatchingKey;
|
|
99
|
-
JWKSNoMatchingKey.code = 'ERR_JWKS_NO_MATCHING_KEY';
|
|
100
133
|
class JWKSMultipleMatchingKeys extends JOSEError {
|
|
101
134
|
constructor() {
|
|
102
135
|
super(...arguments);
|
|
103
|
-
this.code =
|
|
136
|
+
this.code = 'ERR_JWKS_MULTIPLE_MATCHING_KEYS';
|
|
104
137
|
this.message = 'multiple matching keys found in the JSON Web Key Set';
|
|
105
138
|
}
|
|
139
|
+
static get code() {
|
|
140
|
+
return 'ERR_JWKS_MULTIPLE_MATCHING_KEYS';
|
|
141
|
+
}
|
|
106
142
|
}
|
|
107
143
|
exports.JWKSMultipleMatchingKeys = JWKSMultipleMatchingKeys;
|
|
108
|
-
|
|
109
|
-
class JWSSignatureVerificationFailed extends JOSEError {
|
|
144
|
+
class JWKSTimeout extends JOSEError {
|
|
110
145
|
constructor() {
|
|
111
146
|
super(...arguments);
|
|
112
|
-
this.code =
|
|
113
|
-
this.message = '
|
|
147
|
+
this.code = 'ERR_JWKS_TIMEOUT';
|
|
148
|
+
this.message = 'request timed out';
|
|
149
|
+
}
|
|
150
|
+
static get code() {
|
|
151
|
+
return 'ERR_JWKS_TIMEOUT';
|
|
114
152
|
}
|
|
115
153
|
}
|
|
116
|
-
exports.
|
|
117
|
-
JWSSignatureVerificationFailed
|
|
118
|
-
class JWTExpired extends JWTClaimValidationFailed {
|
|
154
|
+
exports.JWKSTimeout = JWKSTimeout;
|
|
155
|
+
class JWSSignatureVerificationFailed extends JOSEError {
|
|
119
156
|
constructor() {
|
|
120
157
|
super(...arguments);
|
|
121
|
-
this.code =
|
|
158
|
+
this.code = 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED';
|
|
159
|
+
this.message = 'signature verification failed';
|
|
160
|
+
}
|
|
161
|
+
static get code() {
|
|
162
|
+
return 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED';
|
|
122
163
|
}
|
|
123
164
|
}
|
|
124
|
-
exports.
|
|
125
|
-
JWTExpired.code = 'ERR_JWT_EXPIRED';
|
|
165
|
+
exports.JWSSignatureVerificationFailed = JWSSignatureVerificationFailed;
|
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
import { decode as base64url } from '../../runtime/base64url.js';
|
|
2
2
|
import decrypt from '../../runtime/decrypt.js';
|
|
3
3
|
import { inflate } from '../../runtime/zlib.js';
|
|
4
|
-
import random from '../../runtime/random.js';
|
|
5
4
|
import { JOSEAlgNotAllowed, JOSENotSupported, JWEInvalid } from '../../util/errors.js';
|
|
6
5
|
import isDisjoint from '../../lib/is_disjoint.js';
|
|
7
6
|
import isObject from '../../lib/is_object.js';
|
|
8
7
|
import decryptKeyManagement from '../../lib/decrypt_key_management.js';
|
|
9
8
|
import { encoder, decoder, concat } from '../../lib/buffer_utils.js';
|
|
10
|
-
import
|
|
9
|
+
import generateCek from '../../lib/cek.js';
|
|
11
10
|
import validateCrit from '../../lib/validate_crit.js';
|
|
12
11
|
import validateAlgorithms from '../../lib/validate_algorithms.js';
|
|
13
|
-
const generateCek = cekFactory(random);
|
|
14
|
-
const checkExtensions = validateCrit.bind(undefined, JWEInvalid, new Map());
|
|
15
|
-
const checkAlgOption = validateAlgorithms.bind(undefined, 'keyManagementAlgorithms');
|
|
16
|
-
const checkEncOption = validateAlgorithms.bind(undefined, 'contentEncryptionAlgorithms');
|
|
17
12
|
async function flattenedDecrypt(jwe, key, options) {
|
|
18
13
|
var _a;
|
|
19
14
|
if (!isObject(jwe)) {
|
|
@@ -64,7 +59,7 @@ async function flattenedDecrypt(jwe, key, options) {
|
|
|
64
59
|
...jwe.header,
|
|
65
60
|
...jwe.unprotected,
|
|
66
61
|
};
|
|
67
|
-
|
|
62
|
+
validateCrit(JWEInvalid, new Map(), options === null || options === void 0 ? void 0 : options.crit, parsedProt, joseHeader);
|
|
68
63
|
if (joseHeader.zip !== undefined) {
|
|
69
64
|
if (!parsedProt || !parsedProt.zip) {
|
|
70
65
|
throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');
|
|
@@ -80,8 +75,9 @@ async function flattenedDecrypt(jwe, key, options) {
|
|
|
80
75
|
if (typeof enc !== 'string' || !enc) {
|
|
81
76
|
throw new JWEInvalid('missing JWE Encryption Algorithm (enc) in JWE Header');
|
|
82
77
|
}
|
|
83
|
-
const keyManagementAlgorithms = options &&
|
|
84
|
-
const contentEncryptionAlgorithms = options &&
|
|
78
|
+
const keyManagementAlgorithms = options && validateAlgorithms('keyManagementAlgorithms', options.keyManagementAlgorithms);
|
|
79
|
+
const contentEncryptionAlgorithms = options &&
|
|
80
|
+
validateAlgorithms('contentEncryptionAlgorithms', options.contentEncryptionAlgorithms);
|
|
85
81
|
if (keyManagementAlgorithms && !keyManagementAlgorithms.has(alg)) {
|
|
86
82
|
throw new JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter not allowed');
|
|
87
83
|
}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { encode as base64url } from '../../runtime/base64url.js';
|
|
2
|
-
import random from '../../runtime/random.js';
|
|
3
2
|
import encrypt from '../../runtime/encrypt.js';
|
|
4
3
|
import { deflate } from '../../runtime/zlib.js';
|
|
5
|
-
import
|
|
4
|
+
import generateIv from '../../lib/iv.js';
|
|
6
5
|
import encryptKeyManagement from '../../lib/encrypt_key_management.js';
|
|
7
6
|
import { JOSENotSupported, JWEInvalid } from '../../util/errors.js';
|
|
8
7
|
import isDisjoint from '../../lib/is_disjoint.js';
|
|
9
8
|
import { encoder, decoder, concat } from '../../lib/buffer_utils.js';
|
|
10
9
|
import validateCrit from '../../lib/validate_crit.js';
|
|
11
|
-
const generateIv = ivFactory(random);
|
|
12
|
-
const checkExtensions = validateCrit.bind(undefined, JWEInvalid, new Map());
|
|
13
10
|
class FlattenedEncrypt {
|
|
14
11
|
constructor(plaintext) {
|
|
15
12
|
if (!(plaintext instanceof Uint8Array)) {
|
|
@@ -75,7 +72,7 @@ class FlattenedEncrypt {
|
|
|
75
72
|
...this._unprotectedHeader,
|
|
76
73
|
...this._sharedUnprotectedHeader,
|
|
77
74
|
};
|
|
78
|
-
|
|
75
|
+
validateCrit(JWEInvalid, new Map(), options === null || options === void 0 ? void 0 : options.crit, this._protectedHeader, joseHeader);
|
|
79
76
|
if (joseHeader.zip !== undefined) {
|
|
80
77
|
if (!this._protectedHeader || !this._protectedHeader.zip) {
|
|
81
78
|
throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');
|
|
@@ -9,8 +9,8 @@ async function EmbeddedJWK(protectedHeader, token) {
|
|
|
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 =
|
|
13
|
-
if (key.type !== 'public') {
|
|
12
|
+
const key = await importJWK({ ...joseHeader.jwk, ext: true }, joseHeader.alg, true);
|
|
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
|
}
|
|
16
16
|
return key;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import fetchJwks from '../runtime/fetch_jwks.js';
|
|
2
|
-
import
|
|
2
|
+
import { importJWK } from '../key/import.js';
|
|
3
3
|
import { JWKSInvalid, JOSENotSupported, JWKSNoMatchingKey, JWKSMultipleMatchingKeys, } from '../util/errors.js';
|
|
4
4
|
import isObject from '../lib/is_object.js';
|
|
5
5
|
function getKtyFromAlg(alg) {
|
|
6
|
-
switch (alg.substr(0, 2)) {
|
|
6
|
+
switch (typeof alg === 'string' && alg.substr(0, 2)) {
|
|
7
7
|
case 'RS':
|
|
8
8
|
case 'PS':
|
|
9
9
|
return 'RSA';
|
|
@@ -32,7 +32,7 @@ class RemoteJWKSet {
|
|
|
32
32
|
typeof (options === null || options === void 0 ? void 0 : options.cooldownDuration) === 'number' ? options === null || options === void 0 ? void 0 : options.cooldownDuration : 30000;
|
|
33
33
|
}
|
|
34
34
|
coolingDown() {
|
|
35
|
-
if (
|
|
35
|
+
if (!this._cooldownStarted) {
|
|
36
36
|
return false;
|
|
37
37
|
}
|
|
38
38
|
return Date.now() < this._cooldownStarted + this._cooldownDuration;
|
|
@@ -56,7 +56,7 @@ class RemoteJWKSet {
|
|
|
56
56
|
candidate = jwk.key_ops.includes('verify');
|
|
57
57
|
}
|
|
58
58
|
if (candidate && protectedHeader.alg === 'EdDSA') {
|
|
59
|
-
candidate =
|
|
59
|
+
candidate = jwk.crv === 'Ed25519' || jwk.crv === 'Ed448';
|
|
60
60
|
}
|
|
61
61
|
if (candidate) {
|
|
62
62
|
switch (protectedHeader.alg) {
|
|
@@ -88,13 +88,10 @@ class RemoteJWKSet {
|
|
|
88
88
|
else if (length !== 1) {
|
|
89
89
|
throw new JWKSMultipleMatchingKeys();
|
|
90
90
|
}
|
|
91
|
-
|
|
92
|
-
this._cached.set(jwk, {});
|
|
93
|
-
}
|
|
94
|
-
const cached = this._cached.get(jwk);
|
|
91
|
+
const cached = this._cached.get(jwk) || this._cached.set(jwk, {}).get(jwk);
|
|
95
92
|
if (cached[protectedHeader.alg] === undefined) {
|
|
96
|
-
const keyObject =
|
|
97
|
-
if (keyObject.type !== 'public') {
|
|
93
|
+
const keyObject = await importJWK({ ...jwk, ext: true }, protectedHeader.alg);
|
|
94
|
+
if (keyObject instanceof Uint8Array || keyObject.type !== 'public') {
|
|
98
95
|
throw new JWKSInvalid('JSON Web Key Set members must be public keys');
|
|
99
96
|
}
|
|
100
97
|
cached[protectedHeader.alg] = keyObject;
|
|
@@ -5,7 +5,6 @@ import { JWSInvalid } from '../../util/errors.js';
|
|
|
5
5
|
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
|
-
const checkExtensions = validateCrit.bind(undefined, JWSInvalid, new Map([['b64', true]]));
|
|
9
8
|
class FlattenedSign {
|
|
10
9
|
constructor(payload) {
|
|
11
10
|
if (!(payload instanceof Uint8Array)) {
|
|
@@ -38,7 +37,7 @@ class FlattenedSign {
|
|
|
38
37
|
...this._protectedHeader,
|
|
39
38
|
...this._unprotectedHeader,
|
|
40
39
|
};
|
|
41
|
-
const extensions =
|
|
40
|
+
const extensions = validateCrit(JWSInvalid, new Map([['b64', true]]), options === null || options === void 0 ? void 0 : options.crit, this._protectedHeader, joseHeader);
|
|
42
41
|
let b64 = true;
|
|
43
42
|
if (extensions.has('b64')) {
|
|
44
43
|
b64 = this._protectedHeader.b64;
|
|
@@ -7,8 +7,6 @@ import isObject from '../../lib/is_object.js';
|
|
|
7
7
|
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
|
-
const checkExtensions = validateCrit.bind(undefined, JWSInvalid, new Map([['b64', true]]));
|
|
11
|
-
const checkAlgOption = validateAlgorithms.bind(undefined, 'algorithms');
|
|
12
10
|
async function flattenedVerify(jws, key, options) {
|
|
13
11
|
var _a;
|
|
14
12
|
if (!isObject(jws)) {
|
|
@@ -46,7 +44,7 @@ async function flattenedVerify(jws, key, options) {
|
|
|
46
44
|
...parsedProt,
|
|
47
45
|
...jws.header,
|
|
48
46
|
};
|
|
49
|
-
const extensions =
|
|
47
|
+
const extensions = validateCrit(JWSInvalid, new Map([['b64', true]]), options === null || options === void 0 ? void 0 : options.crit, parsedProt, joseHeader);
|
|
50
48
|
let b64 = true;
|
|
51
49
|
if (extensions.has('b64')) {
|
|
52
50
|
b64 = parsedProt.b64;
|
|
@@ -58,7 +56,7 @@ async function flattenedVerify(jws, key, options) {
|
|
|
58
56
|
if (typeof alg !== 'string' || !alg) {
|
|
59
57
|
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
|
|
60
58
|
}
|
|
61
|
-
const algorithms = options &&
|
|
59
|
+
const algorithms = options && validateAlgorithms('algorithms', options.algorithms);
|
|
62
60
|
if (algorithms && !algorithms.has(alg)) {
|
|
63
61
|
throw new JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter not allowed');
|
|
64
62
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import CompactEncrypt from '../jwe/compact/encrypt.js';
|
|
2
2
|
import { encoder } from '../lib/buffer_utils.js';
|
|
3
|
-
import ProduceJWT from '
|
|
3
|
+
import { ProduceJWT } from './produce.js';
|
|
4
4
|
class EncryptJWT extends ProduceJWT {
|
|
5
5
|
setProtectedHeader(protectedHeader) {
|
|
6
6
|
if (this._protectedHeader) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import epoch from '
|
|
2
|
-
import isObject from '
|
|
3
|
-
import secs from '
|
|
4
|
-
export
|
|
1
|
+
import epoch from '../lib/epoch.js';
|
|
2
|
+
import isObject from '../lib/is_object.js';
|
|
3
|
+
import secs from '../lib/secs.js';
|
|
4
|
+
export class ProduceJWT {
|
|
5
5
|
constructor(payload) {
|
|
6
6
|
if (!isObject(payload)) {
|
|
7
7
|
throw new TypeError('JWT Claims Set MUST be an object');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import CompactSign from '../jws/compact/sign.js';
|
|
2
2
|
import { JWTInvalid } from '../util/errors.js';
|
|
3
3
|
import { encoder } from '../lib/buffer_utils.js';
|
|
4
|
-
import ProduceJWT from '
|
|
4
|
+
import { ProduceJWT } from './produce.js';
|
|
5
5
|
class SignJWT extends ProduceJWT {
|
|
6
6
|
setProtectedHeader(protectedHeader) {
|
|
7
7
|
this._protectedHeader = protectedHeader;
|
|
@@ -2,7 +2,7 @@ import * as base64url from '../runtime/base64url.js';
|
|
|
2
2
|
import { decoder } from '../lib/buffer_utils.js';
|
|
3
3
|
import { JWTInvalid } from '../util/errors.js';
|
|
4
4
|
import jwtPayload from '../lib/jwt_claims_set.js';
|
|
5
|
-
import ProduceJWT from '
|
|
5
|
+
import { ProduceJWT } from './produce.js';
|
|
6
6
|
class UnsecuredJWT extends ProduceJWT {
|
|
7
7
|
encode() {
|
|
8
8
|
const header = base64url.encode(JSON.stringify({ alg: 'none' }));
|
package/dist/node/esm/lib/cek.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { JOSENotSupported } from '../util/errors.js';
|
|
2
|
+
import random from '../runtime/random.js';
|
|
2
3
|
const bitLengths = new Map([
|
|
3
4
|
['A128CBC-HS256', 256],
|
|
4
5
|
['A128GCM', 128],
|
|
@@ -7,12 +8,12 @@ const bitLengths = new Map([
|
|
|
7
8
|
['A256CBC-HS512', 512],
|
|
8
9
|
['A256GCM', 256],
|
|
9
10
|
]);
|
|
10
|
-
const
|
|
11
|
+
const generateCek = (alg) => {
|
|
11
12
|
const bitLength = bitLengths.get(alg);
|
|
12
13
|
if (!bitLength) {
|
|
13
14
|
throw new JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`);
|
|
14
15
|
}
|
|
15
16
|
return random(new Uint8Array(bitLength >> 3));
|
|
16
17
|
};
|
|
17
|
-
export default
|
|
18
|
+
export default generateCek;
|
|
18
19
|
export { bitLengths };
|
|
@@ -1,28 +1,45 @@
|
|
|
1
1
|
import invalidKeyInput from '../runtime/invalid_key_input.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import isKeyLike, { types } from '../runtime/is_key_like.js';
|
|
3
|
+
const symmetricTypeCheck = (key) => {
|
|
4
|
+
if (key instanceof Uint8Array)
|
|
5
|
+
return;
|
|
6
|
+
if (!isKeyLike(key)) {
|
|
7
|
+
throw new TypeError(invalidKeyInput(key, ...types, 'Uint8Array'));
|
|
5
8
|
}
|
|
6
|
-
if (
|
|
7
|
-
|
|
8
|
-
alg.startsWith('PBES2') ||
|
|
9
|
-
alg.match(/^A\d{3}(?:GCM)?KW$/)) {
|
|
10
|
-
if (key instanceof Uint8Array || key.type === 'secret') {
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
throw new TypeError('CryptoKey or KeyObject instances for symmetric algorithms must be of type "secret"');
|
|
9
|
+
if (key.type !== 'secret') {
|
|
10
|
+
throw new TypeError(`${types.join(' or ')} instances for symmetric algorithms must be of type "secret"`);
|
|
14
11
|
}
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
};
|
|
13
|
+
const asymmetricTypeCheck = (key, usage) => {
|
|
14
|
+
if (!isKeyLike(key)) {
|
|
15
|
+
throw new TypeError(invalidKeyInput(key, ...types));
|
|
17
16
|
}
|
|
18
17
|
if (key.type === 'secret') {
|
|
19
|
-
throw new TypeError('
|
|
18
|
+
throw new TypeError(`${types.join(' or ')} instances for asymmetric algorithms must not be of type "secret"`);
|
|
20
19
|
}
|
|
21
20
|
if (usage === 'sign' && key.type === 'public') {
|
|
22
|
-
throw new TypeError('
|
|
21
|
+
throw new TypeError(`${types.join(' or ')} instances for asymmetric algorithm signing must be of type "private"`);
|
|
23
22
|
}
|
|
24
23
|
if (usage === 'decrypt' && key.type === 'public') {
|
|
25
|
-
throw new TypeError('
|
|
24
|
+
throw new TypeError(`${types.join(' or ')} instances for asymmetric algorithm decryption must be of type "private"`);
|
|
25
|
+
}
|
|
26
|
+
if (key.algorithm && usage === 'verify' && key.type === 'private') {
|
|
27
|
+
throw new TypeError(`${types.join(' or ')} instances for asymmetric algorithm verifying must be of type "public"`);
|
|
28
|
+
}
|
|
29
|
+
if (key.algorithm && usage === 'encrypt' && key.type === 'private') {
|
|
30
|
+
throw new TypeError(`${types.join(' or ')} instances for asymmetric algorithm encryption must be of type "public"`);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const checkKeyType = (alg, key, usage) => {
|
|
34
|
+
const symmetric = alg.startsWith('HS') ||
|
|
35
|
+
alg === 'dir' ||
|
|
36
|
+
alg.startsWith('PBES2') ||
|
|
37
|
+
/^A\d{3}(?:GCM)?KW$/.test(alg);
|
|
38
|
+
if (symmetric) {
|
|
39
|
+
symmetricTypeCheck(key);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
asymmetricTypeCheck(key, usage);
|
|
26
43
|
}
|
|
27
44
|
};
|
|
28
45
|
export default checkKeyType;
|