jose 4.0.2 → 4.1.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/browser/{runtime → lib}/aesgcmkw.js +8 -8
- package/dist/browser/lib/cek.js +18 -16
- package/dist/browser/lib/check_iv_length.js +2 -2
- package/dist/browser/lib/check_key_type.js +1 -1
- package/dist/browser/lib/crypto_key.js +150 -0
- package/dist/browser/lib/decrypt_key_management.js +3 -3
- package/dist/browser/lib/encrypt_key_management.js +3 -3
- package/dist/browser/{runtime → lib}/invalid_key_input.js +0 -0
- package/dist/browser/lib/iv.js +24 -19
- package/dist/browser/runtime/aeskw.js +6 -4
- package/dist/browser/runtime/asn1.js +4 -4
- package/dist/browser/runtime/bogus.js +1 -1
- package/dist/browser/runtime/check_cek_length.js +4 -34
- package/dist/browser/runtime/decrypt.js +20 -8
- package/dist/browser/runtime/ecdhes.js +4 -1
- package/dist/browser/runtime/encrypt.js +20 -8
- package/dist/browser/runtime/generate.js +4 -4
- package/dist/browser/runtime/get_sign_verify_key.js +4 -2
- package/dist/browser/runtime/jwk_to_key.js +4 -4
- package/dist/browser/runtime/key_to_jwk.js +1 -1
- package/dist/browser/runtime/pbes2kw.js +15 -36
- package/dist/browser/runtime/rsaes.js +4 -1
- package/dist/browser/runtime/subtle_dsa.js +7 -26
- package/dist/node/cjs/{runtime → lib}/aesgcmkw.js +8 -8
- package/dist/node/cjs/lib/cek.js +20 -17
- package/dist/node/cjs/lib/check_iv_length.js +1 -1
- package/dist/node/cjs/lib/check_key_type.js +1 -1
- package/dist/node/cjs/lib/crypto_key.js +155 -0
- package/dist/node/cjs/lib/decrypt_key_management.js +2 -2
- package/dist/node/cjs/lib/encrypt_key_management.js +2 -2
- package/dist/node/cjs/{runtime → lib}/invalid_key_input.js +0 -11
- package/dist/node/cjs/lib/iv.js +26 -20
- package/dist/node/cjs/runtime/aeskw.js +4 -2
- package/dist/node/cjs/runtime/asn1.js +2 -2
- package/dist/node/cjs/runtime/decrypt.js +4 -2
- package/dist/node/cjs/runtime/ecdhes.js +7 -4
- package/dist/node/cjs/runtime/encrypt.js +4 -2
- package/dist/node/cjs/runtime/get_named_curve.js +2 -2
- package/dist/node/cjs/runtime/get_sign_verify_key.js +6 -4
- package/dist/node/cjs/runtime/global.js +11 -0
- package/dist/node/cjs/runtime/key_to_jwk.js +2 -2
- package/dist/node/cjs/runtime/node_key.js +6 -10
- package/dist/node/cjs/runtime/pbes2kw.js +4 -2
- package/dist/node/cjs/runtime/rsaes.js +4 -2
- package/dist/node/cjs/runtime/webcrypto.js +1 -149
- package/dist/node/esm/{runtime → lib}/aesgcmkw.js +8 -8
- package/dist/node/esm/lib/cek.js +18 -16
- package/dist/node/esm/lib/check_iv_length.js +2 -2
- package/dist/node/esm/lib/check_key_type.js +1 -1
- package/dist/node/esm/lib/crypto_key.js +150 -0
- package/dist/node/esm/lib/decrypt_key_management.js +3 -3
- package/dist/node/esm/lib/encrypt_key_management.js +3 -3
- package/dist/node/esm/{runtime → lib}/invalid_key_input.js +0 -11
- package/dist/node/esm/lib/iv.js +24 -19
- package/dist/node/esm/runtime/aeskw.js +6 -4
- package/dist/node/esm/runtime/asn1.js +4 -4
- package/dist/node/esm/runtime/decrypt.js +6 -4
- package/dist/node/esm/runtime/ecdhes.js +9 -6
- package/dist/node/esm/runtime/encrypt.js +6 -4
- package/dist/node/esm/runtime/get_named_curve.js +4 -4
- package/dist/node/esm/runtime/get_sign_verify_key.js +7 -5
- package/dist/node/esm/runtime/global.js +6 -0
- package/dist/node/esm/runtime/key_to_jwk.js +4 -4
- package/dist/node/esm/runtime/node_key.js +6 -10
- package/dist/node/esm/runtime/pbes2kw.js +6 -4
- package/dist/node/esm/runtime/rsaes.js +6 -4
- package/dist/node/esm/runtime/webcrypto.js +0 -147
- package/dist/types/jwks/remote.d.ts +4 -0
- package/package.json +4 -1
|
@@ -8,13 +8,15 @@ const buffer_utils_js_1 = require("../lib/buffer_utils.js");
|
|
|
8
8
|
const digest_js_1 = require("./digest.js");
|
|
9
9
|
const errors_js_1 = require("../util/errors.js");
|
|
10
10
|
const webcrypto_js_1 = require("./webcrypto.js");
|
|
11
|
+
const crypto_key_js_1 = require("../lib/crypto_key.js");
|
|
11
12
|
const is_key_object_js_1 = require("./is_key_object.js");
|
|
12
|
-
const invalid_key_input_js_1 = require("
|
|
13
|
+
const invalid_key_input_js_1 = require("../lib/invalid_key_input.js");
|
|
13
14
|
const generateKeyPair = (0, util_1.promisify)(crypto_1.generateKeyPair);
|
|
14
15
|
const deriveKey = async (publicKee, privateKee, algorithm, keyLength, apu = new Uint8Array(0), apv = new Uint8Array(0)) => {
|
|
15
16
|
let publicKey;
|
|
16
17
|
if ((0, webcrypto_js_1.isCryptoKey)(publicKee)) {
|
|
17
|
-
|
|
18
|
+
(0, crypto_key_js_1.checkEncCryptoKey)(publicKee, 'ECDH-ES');
|
|
19
|
+
publicKey = crypto_1.KeyObject.from(publicKee);
|
|
18
20
|
}
|
|
19
21
|
else if ((0, is_key_object_js_1.default)(publicKee)) {
|
|
20
22
|
publicKey = publicKee;
|
|
@@ -24,7 +26,8 @@ const deriveKey = async (publicKee, privateKee, algorithm, keyLength, apu = new
|
|
|
24
26
|
}
|
|
25
27
|
let privateKey;
|
|
26
28
|
if ((0, webcrypto_js_1.isCryptoKey)(privateKee)) {
|
|
27
|
-
|
|
29
|
+
(0, crypto_key_js_1.checkEncCryptoKey)(privateKee, 'ECDH-ES', 'deriveBits', 'deriveKey');
|
|
30
|
+
privateKey = crypto_1.KeyObject.from(privateKee);
|
|
28
31
|
}
|
|
29
32
|
else if ((0, is_key_object_js_1.default)(privateKee)) {
|
|
30
33
|
privateKey = privateKee;
|
|
@@ -40,7 +43,7 @@ exports.deriveKey = deriveKey;
|
|
|
40
43
|
const generateEpk = async (kee) => {
|
|
41
44
|
let key;
|
|
42
45
|
if ((0, webcrypto_js_1.isCryptoKey)(kee)) {
|
|
43
|
-
key =
|
|
46
|
+
key = crypto_1.KeyObject.from(kee);
|
|
44
47
|
}
|
|
45
48
|
else if ((0, is_key_object_js_1.default)(kee)) {
|
|
46
49
|
key = kee;
|
|
@@ -6,8 +6,9 @@ const check_cek_length_js_1 = require("./check_cek_length.js");
|
|
|
6
6
|
const buffer_utils_js_1 = require("../lib/buffer_utils.js");
|
|
7
7
|
const cbc_tag_js_1 = require("./cbc_tag.js");
|
|
8
8
|
const webcrypto_js_1 = require("./webcrypto.js");
|
|
9
|
+
const crypto_key_js_1 = require("../lib/crypto_key.js");
|
|
9
10
|
const is_key_object_js_1 = require("./is_key_object.js");
|
|
10
|
-
const invalid_key_input_js_1 = require("
|
|
11
|
+
const invalid_key_input_js_1 = require("../lib/invalid_key_input.js");
|
|
11
12
|
const errors_js_1 = require("../util/errors.js");
|
|
12
13
|
const ciphers_js_1 = require("./ciphers.js");
|
|
13
14
|
async function cbcEncrypt(enc, plaintext, cek, iv, aad) {
|
|
@@ -44,7 +45,8 @@ async function gcmEncrypt(enc, plaintext, cek, iv, aad) {
|
|
|
44
45
|
const encrypt = async (enc, plaintext, cek, iv, aad) => {
|
|
45
46
|
let key;
|
|
46
47
|
if ((0, webcrypto_js_1.isCryptoKey)(cek)) {
|
|
47
|
-
|
|
48
|
+
(0, crypto_key_js_1.checkEncCryptoKey)(cek, enc, 'encrypt');
|
|
49
|
+
key = crypto_1.KeyObject.from(cek);
|
|
48
50
|
}
|
|
49
51
|
else if (cek instanceof Uint8Array || (0, is_key_object_js_1.default)(cek)) {
|
|
50
52
|
key = cek;
|
|
@@ -6,7 +6,7 @@ const crypto_1 = require("crypto");
|
|
|
6
6
|
const errors_js_1 = require("../util/errors.js");
|
|
7
7
|
const webcrypto_js_1 = require("./webcrypto.js");
|
|
8
8
|
const is_key_object_js_1 = require("./is_key_object.js");
|
|
9
|
-
const invalid_key_input_js_1 = require("
|
|
9
|
+
const invalid_key_input_js_1 = require("../lib/invalid_key_input.js");
|
|
10
10
|
const p256 = buffer_1.Buffer.from([42, 134, 72, 206, 61, 3, 1, 7]);
|
|
11
11
|
const p384 = buffer_1.Buffer.from([43, 129, 4, 0, 34]);
|
|
12
12
|
const p521 = buffer_1.Buffer.from([43, 129, 4, 0, 35]);
|
|
@@ -30,7 +30,7 @@ const getNamedCurve = (kee, raw) => {
|
|
|
30
30
|
var _a;
|
|
31
31
|
let key;
|
|
32
32
|
if ((0, webcrypto_js_1.isCryptoKey)(kee)) {
|
|
33
|
-
key =
|
|
33
|
+
key = crypto_1.KeyObject.from(kee);
|
|
34
34
|
}
|
|
35
35
|
else if ((0, is_key_object_js_1.default)(kee)) {
|
|
36
36
|
key = kee;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
3
|
+
const crypto_1 = require("crypto");
|
|
4
4
|
const webcrypto_js_1 = require("./webcrypto.js");
|
|
5
|
+
const crypto_key_js_1 = require("../lib/crypto_key.js");
|
|
5
6
|
const secret_key_js_1 = require("./secret_key.js");
|
|
6
|
-
const invalid_key_input_js_1 = require("
|
|
7
|
+
const invalid_key_input_js_1 = require("../lib/invalid_key_input.js");
|
|
7
8
|
function getSignVerifyKey(alg, key, usage) {
|
|
8
9
|
if (key instanceof Uint8Array) {
|
|
9
10
|
if (!alg.startsWith('HS')) {
|
|
@@ -11,11 +12,12 @@ function getSignVerifyKey(alg, key, usage) {
|
|
|
11
12
|
}
|
|
12
13
|
return (0, secret_key_js_1.default)(key);
|
|
13
14
|
}
|
|
14
|
-
if (key instanceof
|
|
15
|
+
if (key instanceof crypto_1.KeyObject) {
|
|
15
16
|
return key;
|
|
16
17
|
}
|
|
17
18
|
if ((0, webcrypto_js_1.isCryptoKey)(key)) {
|
|
18
|
-
|
|
19
|
+
(0, crypto_key_js_1.checkSigCryptoKey)(key, alg, usage);
|
|
20
|
+
return crypto_1.KeyObject.from(key);
|
|
19
21
|
}
|
|
20
22
|
throw new TypeError((0, invalid_key_input_js_1.default)(key, 'KeyObject', 'CryptoKey', 'Uint8Array'));
|
|
21
23
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isNodeJs = exports.isCloudflareWorkers = void 0;
|
|
4
|
+
function isCloudflareWorkers() {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
exports.isCloudflareWorkers = isCloudflareWorkers;
|
|
8
|
+
function isNodeJs() {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
exports.isNodeJs = isNodeJs;
|
|
@@ -7,7 +7,7 @@ const errors_js_1 = require("../util/errors.js");
|
|
|
7
7
|
const get_named_curve_js_1 = require("./get_named_curve.js");
|
|
8
8
|
const webcrypto_js_1 = require("./webcrypto.js");
|
|
9
9
|
const is_key_object_js_1 = require("./is_key_object.js");
|
|
10
|
-
const invalid_key_input_js_1 = require("
|
|
10
|
+
const invalid_key_input_js_1 = require("../lib/invalid_key_input.js");
|
|
11
11
|
const [major, minor] = process.version
|
|
12
12
|
.substr(1)
|
|
13
13
|
.split('.')
|
|
@@ -19,7 +19,7 @@ const keyToJWK = (key) => {
|
|
|
19
19
|
if (!key.extractable) {
|
|
20
20
|
throw new TypeError('CryptoKey is not extractable');
|
|
21
21
|
}
|
|
22
|
-
keyObject =
|
|
22
|
+
keyObject = crypto_1.KeyObject.from(key);
|
|
23
23
|
}
|
|
24
24
|
else if ((0, is_key_object_js_1.default)(key)) {
|
|
25
25
|
keyObject = key;
|
|
@@ -9,6 +9,10 @@ const [major, minor] = process.version
|
|
|
9
9
|
.split('.')
|
|
10
10
|
.map((str) => parseInt(str, 10));
|
|
11
11
|
const rsaPssParams = major >= 17 || (major === 16 && minor >= 9);
|
|
12
|
+
const PSS = {
|
|
13
|
+
padding: crypto_1.constants.RSA_PKCS1_PSS_PADDING,
|
|
14
|
+
saltLength: crypto_1.constants.RSA_PSS_SALTLEN_DIGEST,
|
|
15
|
+
};
|
|
12
16
|
const ecCurveAlgMap = new Map([
|
|
13
17
|
['ES256', 'P-256'],
|
|
14
18
|
['ES256K', 'secp256k1'],
|
|
@@ -48,11 +52,7 @@ function keyForCrypto(alg, key) {
|
|
|
48
52
|
throw new TypeError('Invalid key for this operation, its asymmetricKeyType must be rsa or rsa-pss');
|
|
49
53
|
}
|
|
50
54
|
(0, check_modulus_length_js_1.default)(key, alg);
|
|
51
|
-
return {
|
|
52
|
-
key,
|
|
53
|
-
padding: crypto_1.constants.RSA_PKCS1_PSS_PADDING,
|
|
54
|
-
saltLength: crypto_1.constants.RSA_PSS_SALTLEN_DIGEST,
|
|
55
|
-
};
|
|
55
|
+
return { key, ...PSS };
|
|
56
56
|
case !rsaPssParams && 'PS256':
|
|
57
57
|
case !rsaPssParams && 'PS384':
|
|
58
58
|
case !rsaPssParams && 'PS512':
|
|
@@ -60,11 +60,7 @@ function keyForCrypto(alg, key) {
|
|
|
60
60
|
throw new TypeError('Invalid key for this operation, its asymmetricKeyType must be rsa');
|
|
61
61
|
}
|
|
62
62
|
(0, check_modulus_length_js_1.default)(key, alg);
|
|
63
|
-
return {
|
|
64
|
-
key,
|
|
65
|
-
padding: crypto_1.constants.RSA_PKCS1_PSS_PADDING,
|
|
66
|
-
saltLength: crypto_1.constants.RSA_PSS_SALTLEN_DIGEST,
|
|
67
|
-
};
|
|
63
|
+
return { key, ...PSS };
|
|
68
64
|
case 'ES256':
|
|
69
65
|
case 'ES256K':
|
|
70
66
|
case 'ES384':
|
|
@@ -9,8 +9,9 @@ const base64url_js_1 = require("./base64url.js");
|
|
|
9
9
|
const aeskw_js_1 = require("./aeskw.js");
|
|
10
10
|
const check_p2s_js_1 = require("../lib/check_p2s.js");
|
|
11
11
|
const webcrypto_js_1 = require("./webcrypto.js");
|
|
12
|
+
const crypto_key_js_1 = require("../lib/crypto_key.js");
|
|
12
13
|
const is_key_object_js_1 = require("./is_key_object.js");
|
|
13
|
-
const invalid_key_input_js_1 = require("
|
|
14
|
+
const invalid_key_input_js_1 = require("../lib/invalid_key_input.js");
|
|
14
15
|
const pbkdf2 = (0, util_1.promisify)(crypto_1.pbkdf2);
|
|
15
16
|
function getPassword(key, alg) {
|
|
16
17
|
if ((0, is_key_object_js_1.default)(key)) {
|
|
@@ -20,7 +21,8 @@ function getPassword(key, alg) {
|
|
|
20
21
|
return key;
|
|
21
22
|
}
|
|
22
23
|
if ((0, webcrypto_js_1.isCryptoKey)(key)) {
|
|
23
|
-
|
|
24
|
+
(0, crypto_key_js_1.checkEncCryptoKey)(key, alg, 'deriveBits', 'deriveKey');
|
|
25
|
+
return crypto_1.KeyObject.from(key).export();
|
|
24
26
|
}
|
|
25
27
|
throw new TypeError((0, invalid_key_input_js_1.default)(key, 'KeyObject', 'CryptoKey', 'Uint8Array'));
|
|
26
28
|
}
|
|
@@ -4,8 +4,9 @@ exports.decrypt = exports.encrypt = void 0;
|
|
|
4
4
|
const crypto_1 = require("crypto");
|
|
5
5
|
const check_modulus_length_js_1 = require("./check_modulus_length.js");
|
|
6
6
|
const webcrypto_js_1 = require("./webcrypto.js");
|
|
7
|
+
const crypto_key_js_1 = require("../lib/crypto_key.js");
|
|
7
8
|
const is_key_object_js_1 = require("./is_key_object.js");
|
|
8
|
-
const invalid_key_input_js_1 = require("
|
|
9
|
+
const invalid_key_input_js_1 = require("../lib/invalid_key_input.js");
|
|
9
10
|
const checkKey = (key, alg) => {
|
|
10
11
|
if (key.asymmetricKeyType !== 'rsa') {
|
|
11
12
|
throw new TypeError('Invalid key for this operation, its asymmetricKeyType must be rsa');
|
|
@@ -44,7 +45,8 @@ function ensureKeyObject(key, alg, ...usages) {
|
|
|
44
45
|
return key;
|
|
45
46
|
}
|
|
46
47
|
if ((0, webcrypto_js_1.isCryptoKey)(key)) {
|
|
47
|
-
|
|
48
|
+
(0, crypto_key_js_1.checkEncCryptoKey)(key, alg, ...usages);
|
|
49
|
+
return crypto_1.KeyObject.from(key);
|
|
48
50
|
}
|
|
49
51
|
throw new TypeError((0, invalid_key_input_js_1.default)(key, 'KeyObject', 'CryptoKey'));
|
|
50
52
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.isCryptoKey = void 0;
|
|
4
4
|
const crypto = require("crypto");
|
|
5
5
|
const util = require("util");
|
|
6
6
|
const webcrypto = crypto.webcrypto;
|
|
@@ -9,151 +9,3 @@ exports.isCryptoKey = util.types.isCryptoKey
|
|
|
9
9
|
? (obj) => util.types.isCryptoKey(obj)
|
|
10
10
|
:
|
|
11
11
|
(obj) => false;
|
|
12
|
-
function getHashLength(hash) {
|
|
13
|
-
return parseInt(hash === null || hash === void 0 ? void 0 : hash.name.substr(4), 10);
|
|
14
|
-
}
|
|
15
|
-
function getNamedCurve(alg) {
|
|
16
|
-
switch (alg) {
|
|
17
|
-
case 'ES256':
|
|
18
|
-
return 'P-256';
|
|
19
|
-
case 'ES384':
|
|
20
|
-
return 'P-384';
|
|
21
|
-
case 'ES512':
|
|
22
|
-
return 'P-521';
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
function getKeyObject(key, alg, usage) {
|
|
26
|
-
switch (alg) {
|
|
27
|
-
case undefined:
|
|
28
|
-
break;
|
|
29
|
-
case 'HS256':
|
|
30
|
-
case 'HS384':
|
|
31
|
-
case 'HS512': {
|
|
32
|
-
if (key.algorithm.name !== 'HMAC') {
|
|
33
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be HMAC.`);
|
|
34
|
-
}
|
|
35
|
-
const expected = parseInt(alg.substr(2), 10);
|
|
36
|
-
const actual = getHashLength(key.algorithm.hash);
|
|
37
|
-
if (actual !== expected) {
|
|
38
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
|
|
39
|
-
}
|
|
40
|
-
break;
|
|
41
|
-
}
|
|
42
|
-
case 'RS256':
|
|
43
|
-
case 'RS384':
|
|
44
|
-
case 'RS512': {
|
|
45
|
-
if (key.algorithm.name !== 'RSASSA-PKCS1-v1_5') {
|
|
46
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be RSASSA-PKCS1-v1_5.`);
|
|
47
|
-
}
|
|
48
|
-
const expected = parseInt(alg.substr(2), 10);
|
|
49
|
-
const actual = getHashLength(key.algorithm.hash);
|
|
50
|
-
if (actual !== expected) {
|
|
51
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
|
|
52
|
-
}
|
|
53
|
-
break;
|
|
54
|
-
}
|
|
55
|
-
case 'PS256':
|
|
56
|
-
case 'PS384':
|
|
57
|
-
case 'PS512': {
|
|
58
|
-
if (key.algorithm.name !== 'RSA-PSS') {
|
|
59
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be RSA-PSS.`);
|
|
60
|
-
}
|
|
61
|
-
const expected = parseInt(alg.substr(2), 10);
|
|
62
|
-
const actual = getHashLength(key.algorithm.hash);
|
|
63
|
-
if (actual !== expected) {
|
|
64
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
|
|
65
|
-
}
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
case 'EdDSA': {
|
|
69
|
-
if (key.algorithm.name !== 'NODE-ED25519' && key.algorithm.name !== 'NODE-ED448') {
|
|
70
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be NODE-ED25519 or NODE-ED448.`);
|
|
71
|
-
}
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
case 'ES256':
|
|
75
|
-
case 'ES384':
|
|
76
|
-
case 'ES512': {
|
|
77
|
-
if (key.algorithm.name !== 'ECDSA') {
|
|
78
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be ECDSA.`);
|
|
79
|
-
}
|
|
80
|
-
const expected = getNamedCurve(alg);
|
|
81
|
-
const actual = key.algorithm.namedCurve;
|
|
82
|
-
if (actual !== expected) {
|
|
83
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.namedCurve must be ${expected}.`);
|
|
84
|
-
}
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
case 'A128GCM':
|
|
88
|
-
case 'A192GCM':
|
|
89
|
-
case 'A256GCM': {
|
|
90
|
-
if (key.algorithm.name !== 'AES-GCM') {
|
|
91
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be AES-GCM.`);
|
|
92
|
-
}
|
|
93
|
-
const expected = parseInt(alg.substr(1, 3), 10);
|
|
94
|
-
const actual = key.algorithm.length;
|
|
95
|
-
if (actual !== expected) {
|
|
96
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.length must be ${expected}.`);
|
|
97
|
-
}
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
case 'A128KW':
|
|
101
|
-
case 'A192KW':
|
|
102
|
-
case 'A256KW': {
|
|
103
|
-
if (key.algorithm.name !== 'AES-KW') {
|
|
104
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be AES-KW.`);
|
|
105
|
-
}
|
|
106
|
-
const expected = parseInt(alg.substr(1, 3), 10);
|
|
107
|
-
const actual = key.algorithm.length;
|
|
108
|
-
if (actual !== expected) {
|
|
109
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.length must be ${expected}.`);
|
|
110
|
-
}
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
case 'ECDH-ES':
|
|
114
|
-
if (key.algorithm.name !== 'ECDH') {
|
|
115
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be ECDH.`);
|
|
116
|
-
}
|
|
117
|
-
break;
|
|
118
|
-
case 'PBES2-HS256+A128KW':
|
|
119
|
-
case 'PBES2-HS384+A192KW':
|
|
120
|
-
case 'PBES2-HS512+A256KW':
|
|
121
|
-
if (key.algorithm.name !== 'PBKDF2') {
|
|
122
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be PBKDF2.`);
|
|
123
|
-
}
|
|
124
|
-
break;
|
|
125
|
-
case 'RSA-OAEP':
|
|
126
|
-
case 'RSA-OAEP-256':
|
|
127
|
-
case 'RSA-OAEP-384':
|
|
128
|
-
case 'RSA-OAEP-512': {
|
|
129
|
-
if (key.algorithm.name !== 'RSA-OAEP') {
|
|
130
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be RSA-OAEP.`);
|
|
131
|
-
}
|
|
132
|
-
const expected = parseInt(alg.substr(9), 10) || 1;
|
|
133
|
-
const actual = getHashLength(key.algorithm.hash);
|
|
134
|
-
if (actual !== expected) {
|
|
135
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
|
|
136
|
-
}
|
|
137
|
-
break;
|
|
138
|
-
}
|
|
139
|
-
default:
|
|
140
|
-
throw new TypeError('CryptoKey does not support this operation');
|
|
141
|
-
}
|
|
142
|
-
if (usage && !key.usages.find(Set.prototype.has.bind(usage))) {
|
|
143
|
-
const usages = [...usage];
|
|
144
|
-
let msg = 'CryptoKey does not support this operation, its usages must include ';
|
|
145
|
-
if (usages.length > 2) {
|
|
146
|
-
const last = usages.pop();
|
|
147
|
-
msg += `one of ${usages.join(', ')}, or ${last}.`;
|
|
148
|
-
}
|
|
149
|
-
else if (usages.length === 2) {
|
|
150
|
-
msg += `one of ${usages[0]} or ${usages[1]}.`;
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
msg += ` ${usages[0]}.`;
|
|
154
|
-
}
|
|
155
|
-
throw new TypeError(msg);
|
|
156
|
-
}
|
|
157
|
-
return crypto.KeyObject.from(key);
|
|
158
|
-
}
|
|
159
|
-
exports.getKeyObject = getKeyObject;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import encrypt from '
|
|
2
|
-
import decrypt from '
|
|
3
|
-
import generateIv from '
|
|
4
|
-
import { encode as base64url } from '
|
|
5
|
-
export
|
|
1
|
+
import encrypt from '../runtime/encrypt.js';
|
|
2
|
+
import decrypt from '../runtime/decrypt.js';
|
|
3
|
+
import generateIv from './iv.js';
|
|
4
|
+
import { encode as base64url } from '../runtime/base64url.js';
|
|
5
|
+
export async function wrap(alg, key, cek, iv) {
|
|
6
6
|
const jweAlgorithm = alg.substr(0, 7);
|
|
7
7
|
iv || (iv = generateIv(jweAlgorithm));
|
|
8
8
|
const { ciphertext: encryptedKey, tag } = await encrypt(jweAlgorithm, cek, key, iv, new Uint8Array(0));
|
|
9
9
|
return { encryptedKey, iv: base64url(iv), tag: base64url(tag) };
|
|
10
|
-
}
|
|
11
|
-
export
|
|
10
|
+
}
|
|
11
|
+
export async function unwrap(alg, key, encryptedKey, iv, tag) {
|
|
12
12
|
const jweAlgorithm = alg.substr(0, 7);
|
|
13
13
|
return decrypt(jweAlgorithm, key, encryptedKey, iv, tag, new Uint8Array(0));
|
|
14
|
-
}
|
|
14
|
+
}
|
package/dist/node/esm/lib/cek.js
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { JOSENotSupported } from '../util/errors.js';
|
|
2
2
|
import random from '../runtime/random.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
export function bitLength(alg) {
|
|
4
|
+
switch (alg) {
|
|
5
|
+
case 'A128CBC-HS256':
|
|
6
|
+
return 256;
|
|
7
|
+
case 'A192CBC-HS384':
|
|
8
|
+
return 384;
|
|
9
|
+
case 'A256CBC-HS512':
|
|
10
|
+
return 512;
|
|
11
|
+
case 'A128GCM':
|
|
12
|
+
return 128;
|
|
13
|
+
case 'A192GCM':
|
|
14
|
+
return 192;
|
|
15
|
+
case 'A256GCM':
|
|
16
|
+
return 256;
|
|
17
|
+
default:
|
|
18
|
+
throw new JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`);
|
|
15
19
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
export default generateCek;
|
|
19
|
-
export { bitLengths };
|
|
20
|
+
}
|
|
21
|
+
export default (alg) => random(new Uint8Array(bitLength(alg) >> 3));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { JWEInvalid } from '../util/errors.js';
|
|
2
|
-
import {
|
|
2
|
+
import { bitLength } from './iv.js';
|
|
3
3
|
const checkIvLength = (enc, iv) => {
|
|
4
|
-
if (iv.length << 3 !==
|
|
4
|
+
if (iv.length << 3 !== bitLength(enc)) {
|
|
5
5
|
throw new JWEInvalid('Invalid Initialization Vector length');
|
|
6
6
|
}
|
|
7
7
|
};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { isCloudflareWorkers, isNodeJs } from '../runtime/global.js';
|
|
2
|
+
function unusable(name, prop = 'algorithm.name') {
|
|
3
|
+
return new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
|
|
4
|
+
}
|
|
5
|
+
function isAlgorithm(algorithm, name) {
|
|
6
|
+
return algorithm.name === name;
|
|
7
|
+
}
|
|
8
|
+
function getHashLength(hash) {
|
|
9
|
+
return parseInt(hash.name.substr(4), 10);
|
|
10
|
+
}
|
|
11
|
+
function getNamedCurve(alg) {
|
|
12
|
+
switch (alg) {
|
|
13
|
+
case 'ES256':
|
|
14
|
+
return 'P-256';
|
|
15
|
+
case 'ES384':
|
|
16
|
+
return 'P-384';
|
|
17
|
+
case 'ES512':
|
|
18
|
+
return 'P-521';
|
|
19
|
+
default:
|
|
20
|
+
throw new Error('unreachable');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function checkUsage(key, usages) {
|
|
24
|
+
if (usages.length && !usages.some((expected) => key.usages.includes(expected))) {
|
|
25
|
+
let msg = 'CryptoKey does not support this operation, its usages must include ';
|
|
26
|
+
if (usages.length > 2) {
|
|
27
|
+
const last = usages.pop();
|
|
28
|
+
msg += `one of ${usages.join(', ')}, or ${last}.`;
|
|
29
|
+
}
|
|
30
|
+
else if (usages.length === 2) {
|
|
31
|
+
msg += `one of ${usages[0]} or ${usages[1]}.`;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
msg += `${usages[0]}.`;
|
|
35
|
+
}
|
|
36
|
+
throw new TypeError(msg);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function checkSigCryptoKey(key, alg, ...usages) {
|
|
40
|
+
switch (alg) {
|
|
41
|
+
case 'HS256':
|
|
42
|
+
case 'HS384':
|
|
43
|
+
case 'HS512': {
|
|
44
|
+
if (!isAlgorithm(key.algorithm, 'HMAC'))
|
|
45
|
+
throw unusable('HMAC');
|
|
46
|
+
const expected = parseInt(alg.substr(2), 10);
|
|
47
|
+
const actual = getHashLength(key.algorithm.hash);
|
|
48
|
+
if (actual !== expected)
|
|
49
|
+
throw unusable(`SHA-${expected}`, 'algorithm.hash');
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case 'RS256':
|
|
53
|
+
case 'RS384':
|
|
54
|
+
case 'RS512': {
|
|
55
|
+
if (!isAlgorithm(key.algorithm, 'RSASSA-PKCS1-v1_5'))
|
|
56
|
+
throw unusable('RSASSA-PKCS1-v1_5');
|
|
57
|
+
const expected = parseInt(alg.substr(2), 10);
|
|
58
|
+
const actual = getHashLength(key.algorithm.hash);
|
|
59
|
+
if (actual !== expected)
|
|
60
|
+
throw unusable(`SHA-${expected}`, 'algorithm.hash');
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
case 'PS256':
|
|
64
|
+
case 'PS384':
|
|
65
|
+
case 'PS512': {
|
|
66
|
+
if (!isAlgorithm(key.algorithm, 'RSA-PSS'))
|
|
67
|
+
throw unusable('RSA-PSS');
|
|
68
|
+
const expected = parseInt(alg.substr(2), 10);
|
|
69
|
+
const actual = getHashLength(key.algorithm.hash);
|
|
70
|
+
if (actual !== expected)
|
|
71
|
+
throw unusable(`SHA-${expected}`, 'algorithm.hash');
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
case isNodeJs() && 'EdDSA': {
|
|
75
|
+
if (key.algorithm.name !== 'NODE-ED25519' && key.algorithm.name !== 'NODE-ED448')
|
|
76
|
+
throw unusable('NODE-ED25519 or NODE-ED448');
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case isCloudflareWorkers() && 'EdDSA': {
|
|
80
|
+
if (!isAlgorithm(key.algorithm, 'NODE-ED25519'))
|
|
81
|
+
throw unusable('NODE-ED25519');
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
case 'ES256':
|
|
85
|
+
case 'ES384':
|
|
86
|
+
case 'ES512': {
|
|
87
|
+
if (!isAlgorithm(key.algorithm, 'ECDSA'))
|
|
88
|
+
throw unusable('ECDSA');
|
|
89
|
+
const expected = getNamedCurve(alg);
|
|
90
|
+
const actual = key.algorithm.namedCurve;
|
|
91
|
+
if (actual !== expected)
|
|
92
|
+
throw unusable(expected, 'algorithm.namedCurve');
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
default:
|
|
96
|
+
throw new TypeError('CryptoKey does not support this operation');
|
|
97
|
+
}
|
|
98
|
+
checkUsage(key, usages);
|
|
99
|
+
}
|
|
100
|
+
export function checkEncCryptoKey(key, alg, ...usages) {
|
|
101
|
+
switch (alg) {
|
|
102
|
+
case 'A128GCM':
|
|
103
|
+
case 'A192GCM':
|
|
104
|
+
case 'A256GCM': {
|
|
105
|
+
if (!isAlgorithm(key.algorithm, 'AES-GCM'))
|
|
106
|
+
throw unusable('AES-GCM');
|
|
107
|
+
const expected = parseInt(alg.substr(1, 3), 10);
|
|
108
|
+
const actual = key.algorithm.length;
|
|
109
|
+
if (actual !== expected)
|
|
110
|
+
throw unusable(expected, 'algorithm.length');
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
case 'A128KW':
|
|
114
|
+
case 'A192KW':
|
|
115
|
+
case 'A256KW': {
|
|
116
|
+
if (!isAlgorithm(key.algorithm, 'AES-KW'))
|
|
117
|
+
throw unusable('AES-KW');
|
|
118
|
+
const expected = parseInt(alg.substr(1, 3), 10);
|
|
119
|
+
const actual = key.algorithm.length;
|
|
120
|
+
if (actual !== expected)
|
|
121
|
+
throw unusable(expected, 'algorithm.length');
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
case 'ECDH-ES':
|
|
125
|
+
if (!isAlgorithm(key.algorithm, 'ECDH'))
|
|
126
|
+
throw unusable('ECDH');
|
|
127
|
+
break;
|
|
128
|
+
case 'PBES2-HS256+A128KW':
|
|
129
|
+
case 'PBES2-HS384+A192KW':
|
|
130
|
+
case 'PBES2-HS512+A256KW':
|
|
131
|
+
if (!isAlgorithm(key.algorithm, 'PBKDF2'))
|
|
132
|
+
throw unusable('PBKDF2');
|
|
133
|
+
break;
|
|
134
|
+
case 'RSA-OAEP':
|
|
135
|
+
case 'RSA-OAEP-256':
|
|
136
|
+
case 'RSA-OAEP-384':
|
|
137
|
+
case 'RSA-OAEP-512': {
|
|
138
|
+
if (!isAlgorithm(key.algorithm, 'RSA-OAEP'))
|
|
139
|
+
throw unusable('RSA-OAEP');
|
|
140
|
+
const expected = parseInt(alg.substr(9), 10) || 1;
|
|
141
|
+
const actual = getHashLength(key.algorithm.hash);
|
|
142
|
+
if (actual !== expected)
|
|
143
|
+
throw unusable(`SHA-${expected}`, 'algorithm.hash');
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
default:
|
|
147
|
+
throw new TypeError('CryptoKey does not support this operation');
|
|
148
|
+
}
|
|
149
|
+
checkUsage(key, usages);
|
|
150
|
+
}
|
|
@@ -2,13 +2,13 @@ import { unwrap as aesKw } from '../runtime/aeskw.js';
|
|
|
2
2
|
import * as ECDH from '../runtime/ecdhes.js';
|
|
3
3
|
import { decrypt as pbes2Kw } from '../runtime/pbes2kw.js';
|
|
4
4
|
import { decrypt as rsaEs } from '../runtime/rsaes.js';
|
|
5
|
-
import { unwrap as aesGcmKw } from '../runtime/aesgcmkw.js';
|
|
6
5
|
import { decode as base64url } from '../runtime/base64url.js';
|
|
7
6
|
import { JOSENotSupported, JWEInvalid } from '../util/errors.js';
|
|
8
|
-
import {
|
|
7
|
+
import { bitLength as cekLength } from '../lib/cek.js';
|
|
9
8
|
import { importJWK } from '../key/import.js';
|
|
10
9
|
import checkKeyType from './check_key_type.js';
|
|
11
10
|
import isObject from './is_object.js';
|
|
11
|
+
import { unwrap as aesGcmKw } from './aesgcmkw.js';
|
|
12
12
|
async function decryptKeyManagement(alg, key, encryptedKey, joseHeader) {
|
|
13
13
|
checkKeyType(alg, key, 'decrypt');
|
|
14
14
|
switch (alg) {
|
|
@@ -40,7 +40,7 @@ async function decryptKeyManagement(alg, key, encryptedKey, joseHeader) {
|
|
|
40
40
|
throw new JWEInvalid(`JOSE Header "apv" (Agreement PartyVInfo) invalid`);
|
|
41
41
|
partyVInfo = base64url(joseHeader.apv);
|
|
42
42
|
}
|
|
43
|
-
const sharedSecret = await ECDH.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, parseInt(alg.substr(-5, 3), 10) ||
|
|
43
|
+
const sharedSecret = await ECDH.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, parseInt(alg.substr(-5, 3), 10) || cekLength(joseHeader.enc), partyUInfo, partyVInfo);
|
|
44
44
|
if (alg === 'ECDH-ES')
|
|
45
45
|
return sharedSecret;
|
|
46
46
|
if (encryptedKey === undefined)
|
|
@@ -2,12 +2,12 @@ import { wrap as aesKw } from '../runtime/aeskw.js';
|
|
|
2
2
|
import * as ECDH from '../runtime/ecdhes.js';
|
|
3
3
|
import { encrypt as pbes2Kw } from '../runtime/pbes2kw.js';
|
|
4
4
|
import { encrypt as rsaEs } from '../runtime/rsaes.js';
|
|
5
|
-
import { wrap as aesGcmKw } from '../runtime/aesgcmkw.js';
|
|
6
5
|
import { encode as base64url } from '../runtime/base64url.js';
|
|
7
|
-
import generateCek, {
|
|
6
|
+
import generateCek, { bitLength as cekLength } from '../lib/cek.js';
|
|
8
7
|
import { JOSENotSupported } from '../util/errors.js';
|
|
9
8
|
import { exportJWK } from '../key/export.js';
|
|
10
9
|
import checkKeyType from './check_key_type.js';
|
|
10
|
+
import { wrap as aesGcmKw } from './aesgcmkw.js';
|
|
11
11
|
async function encryptKeyManagement(alg, enc, key, providedCek, providedParameters = {}) {
|
|
12
12
|
let encryptedKey;
|
|
13
13
|
let parameters;
|
|
@@ -29,7 +29,7 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
|
|
|
29
29
|
let { epk: ephemeralKey } = providedParameters;
|
|
30
30
|
ephemeralKey || (ephemeralKey = await ECDH.generateEpk(key));
|
|
31
31
|
const { x, y, crv, kty } = await exportJWK(ephemeralKey);
|
|
32
|
-
const sharedSecret = await ECDH.deriveKey(key, ephemeralKey, alg === 'ECDH-ES' ? enc : alg, parseInt(alg.substr(-5, 3), 10) ||
|
|
32
|
+
const sharedSecret = await ECDH.deriveKey(key, ephemeralKey, alg === 'ECDH-ES' ? enc : alg, parseInt(alg.substr(-5, 3), 10) || cekLength(enc), apu, apv);
|
|
33
33
|
parameters = { epk: { x, y, crv, kty } };
|
|
34
34
|
if (apu)
|
|
35
35
|
parameters.apu = base64url(apu);
|