jose 4.0.3 → 4.1.2
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 +4 -3
- package/dist/browser/runtime/asn1.js +4 -4
- package/dist/browser/runtime/bogus.js +1 -1
- package/dist/browser/runtime/check_cek_length.js +7 -0
- package/dist/browser/runtime/decrypt.js +10 -4
- package/dist/browser/runtime/ecdhes.js +5 -4
- package/dist/browser/runtime/encrypt.js +10 -4
- package/dist/browser/runtime/generate.js +4 -4
- package/dist/browser/runtime/get_sign_verify_key.js +5 -4
- 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 +14 -36
- package/dist/browser/runtime/rsaes.js +5 -4
- package/dist/browser/runtime/subtle_dsa.js +7 -26
- package/dist/browser/runtime/webcrypto.js +0 -145
- 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 -152
- 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 -149
- package/dist/types/jwks/remote.d.ts +4 -0
- package/package.json +4 -1
|
@@ -3,24 +3,25 @@ import { p2s as concatSalt } from '../lib/buffer_utils.js';
|
|
|
3
3
|
import { encode as base64url } from './base64url.js';
|
|
4
4
|
import { wrap, unwrap } from './aeskw.js';
|
|
5
5
|
import checkP2s from '../lib/check_p2s.js';
|
|
6
|
-
import crypto, {
|
|
7
|
-
import
|
|
6
|
+
import crypto, { isCryptoKey } from './webcrypto.js';
|
|
7
|
+
import { checkEncCryptoKey } from '../lib/crypto_key.js';
|
|
8
|
+
import invalidKeyInput from '../lib/invalid_key_input.js';
|
|
8
9
|
function getCryptoKey(key, alg) {
|
|
9
10
|
if (key instanceof Uint8Array) {
|
|
10
11
|
return crypto.subtle.importKey('raw', key, 'PBKDF2', false, ['deriveBits']);
|
|
11
12
|
}
|
|
12
13
|
if (isCryptoKey(key)) {
|
|
13
|
-
|
|
14
|
+
checkEncCryptoKey(key, alg, 'deriveBits', 'deriveKey');
|
|
14
15
|
return key;
|
|
15
16
|
}
|
|
16
17
|
throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'Uint8Array'));
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
+
async function deriveKey(p2s, alg, p2c, key) {
|
|
19
20
|
checkP2s(p2s);
|
|
20
21
|
const salt = concatSalt(alg, p2s);
|
|
21
22
|
const keylen = parseInt(alg.substr(13, 3), 10);
|
|
22
23
|
const subtleAlg = {
|
|
23
|
-
hash:
|
|
24
|
+
hash: `SHA-${alg.substr(8, 3)}`,
|
|
24
25
|
iterations: p2c,
|
|
25
26
|
name: 'PBKDF2',
|
|
26
27
|
salt,
|
|
@@ -30,43 +31,20 @@ export const encrypt = async (alg, key, cek, p2c = Math.floor(Math.random() * 20
|
|
|
30
31
|
name: 'AES-KW',
|
|
31
32
|
};
|
|
32
33
|
const cryptoKey = await getCryptoKey(key, alg);
|
|
33
|
-
let derived;
|
|
34
34
|
if (cryptoKey.usages.includes('deriveBits')) {
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
else if (cryptoKey.usages.includes('deriveKey')) {
|
|
38
|
-
derived = await crypto.subtle.deriveKey(subtleAlg, cryptoKey, wrapAlg, false, ['wrapKey']);
|
|
35
|
+
return new Uint8Array(await crypto.subtle.deriveBits(subtleAlg, cryptoKey, keylen));
|
|
39
36
|
}
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
if (cryptoKey.usages.includes('deriveKey')) {
|
|
38
|
+
return crypto.subtle.deriveKey(subtleAlg, cryptoKey, wrapAlg, false, ['wrapKey', 'unwrapKey']);
|
|
42
39
|
}
|
|
40
|
+
throw new TypeError('PBKDF2 key "usages" must include "deriveBits" or "deriveKey"');
|
|
41
|
+
}
|
|
42
|
+
export const encrypt = async (alg, key, cek, p2c = Math.floor(Math.random() * 2049) + 2048, p2s = random(new Uint8Array(16))) => {
|
|
43
|
+
const derived = await deriveKey(p2s, alg, p2c, key);
|
|
43
44
|
const encryptedKey = await wrap(alg.substr(-6), derived, cek);
|
|
44
45
|
return { encryptedKey, p2c, p2s: base64url(p2s) };
|
|
45
46
|
};
|
|
46
47
|
export const decrypt = async (alg, key, encryptedKey, p2c, p2s) => {
|
|
47
|
-
|
|
48
|
-
const salt = concatSalt(alg, p2s);
|
|
49
|
-
const keylen = parseInt(alg.substr(13, 3), 10);
|
|
50
|
-
const subtleAlg = {
|
|
51
|
-
hash: { name: `SHA-${alg.substr(8, 3)}` },
|
|
52
|
-
iterations: p2c,
|
|
53
|
-
name: 'PBKDF2',
|
|
54
|
-
salt,
|
|
55
|
-
};
|
|
56
|
-
const wrapAlg = {
|
|
57
|
-
length: keylen,
|
|
58
|
-
name: 'AES-KW',
|
|
59
|
-
};
|
|
60
|
-
const cryptoKey = await getCryptoKey(key, alg);
|
|
61
|
-
let derived;
|
|
62
|
-
if (cryptoKey.usages.includes('deriveBits')) {
|
|
63
|
-
derived = new Uint8Array(await crypto.subtle.deriveBits(subtleAlg, cryptoKey, keylen));
|
|
64
|
-
}
|
|
65
|
-
else if (cryptoKey.usages.includes('deriveKey')) {
|
|
66
|
-
derived = await crypto.subtle.deriveKey(subtleAlg, cryptoKey, wrapAlg, false, ['unwrapKey']);
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
throw new TypeError('PBKDF2 key "usages" must include "deriveBits" or "deriveKey"');
|
|
70
|
-
}
|
|
48
|
+
const derived = await deriveKey(p2s, alg, p2c, key);
|
|
71
49
|
return unwrap(alg.substr(-6), derived, encryptedKey);
|
|
72
50
|
};
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import subtleAlgorithm from './subtle_rsaes.js';
|
|
2
2
|
import bogusWebCrypto from './bogus.js';
|
|
3
|
-
import crypto, {
|
|
3
|
+
import crypto, { isCryptoKey } from './webcrypto.js';
|
|
4
|
+
import { checkEncCryptoKey } from '../lib/crypto_key.js';
|
|
4
5
|
import checkKeyLength from './check_key_length.js';
|
|
5
|
-
import invalidKeyInput from '
|
|
6
|
+
import invalidKeyInput from '../lib/invalid_key_input.js';
|
|
6
7
|
export const encrypt = async (alg, key, cek) => {
|
|
7
8
|
if (!isCryptoKey(key)) {
|
|
8
9
|
throw new TypeError(invalidKeyInput(key, 'CryptoKey'));
|
|
9
10
|
}
|
|
10
|
-
|
|
11
|
+
checkEncCryptoKey(key, alg, 'encrypt', 'wrapKey');
|
|
11
12
|
checkKeyLength(alg, key);
|
|
12
13
|
if (key.usages.includes('encrypt')) {
|
|
13
14
|
return new Uint8Array(await crypto.subtle.encrypt(subtleAlgorithm(alg), key, cek));
|
|
@@ -22,7 +23,7 @@ export const decrypt = async (alg, key, encryptedKey) => {
|
|
|
22
23
|
if (!isCryptoKey(key)) {
|
|
23
24
|
throw new TypeError(invalidKeyInput(key, 'CryptoKey'));
|
|
24
25
|
}
|
|
25
|
-
|
|
26
|
+
checkEncCryptoKey(key, alg, 'decrypt', 'unwrapKey');
|
|
26
27
|
checkKeyLength(alg, key);
|
|
27
28
|
if (key.usages.includes('decrypt')) {
|
|
28
29
|
return new Uint8Array(await crypto.subtle.decrypt(subtleAlgorithm(alg), key, encryptedKey));
|
|
@@ -1,45 +1,26 @@
|
|
|
1
1
|
import { isCloudflareWorkers, isNodeJs } from './global.js';
|
|
2
2
|
import { JOSENotSupported } from '../util/errors.js';
|
|
3
|
-
export default function subtleDsa(alg,
|
|
3
|
+
export default function subtleDsa(alg, namedCurve) {
|
|
4
|
+
const length = parseInt(alg.substr(-3), 10);
|
|
4
5
|
switch (alg) {
|
|
5
6
|
case 'HS256':
|
|
6
|
-
return { hash: { name: 'SHA-256' }, name: 'HMAC' };
|
|
7
7
|
case 'HS384':
|
|
8
|
-
return { hash: { name: 'SHA-384' }, name: 'HMAC' };
|
|
9
8
|
case 'HS512':
|
|
10
|
-
return { hash: {
|
|
9
|
+
return { hash: `SHA-${length}`, name: 'HMAC' };
|
|
11
10
|
case 'PS256':
|
|
12
|
-
return {
|
|
13
|
-
hash: { name: 'SHA-256' },
|
|
14
|
-
name: 'RSA-PSS',
|
|
15
|
-
saltLength: 256 >> 3,
|
|
16
|
-
};
|
|
17
11
|
case 'PS384':
|
|
18
|
-
return {
|
|
19
|
-
hash: { name: 'SHA-384' },
|
|
20
|
-
name: 'RSA-PSS',
|
|
21
|
-
saltLength: 384 >> 3,
|
|
22
|
-
};
|
|
23
12
|
case 'PS512':
|
|
24
|
-
return {
|
|
25
|
-
hash: { name: 'SHA-512' },
|
|
26
|
-
name: 'RSA-PSS',
|
|
27
|
-
saltLength: 512 >> 3,
|
|
28
|
-
};
|
|
13
|
+
return { hash: `SHA-${length}`, name: 'RSA-PSS', saltLength: length >> 3 };
|
|
29
14
|
case 'RS256':
|
|
30
|
-
return { hash: { name: 'SHA-256' }, name: 'RSASSA-PKCS1-v1_5' };
|
|
31
15
|
case 'RS384':
|
|
32
|
-
return { hash: { name: 'SHA-384' }, name: 'RSASSA-PKCS1-v1_5' };
|
|
33
16
|
case 'RS512':
|
|
34
|
-
return { hash: {
|
|
17
|
+
return { hash: `SHA-${length}`, name: 'RSASSA-PKCS1-v1_5' };
|
|
35
18
|
case 'ES256':
|
|
36
|
-
return { hash: { name: 'SHA-256' }, name: 'ECDSA', namedCurve: 'P-256' };
|
|
37
19
|
case 'ES384':
|
|
38
|
-
return { hash: { name: 'SHA-384' }, name: 'ECDSA', namedCurve: 'P-384' };
|
|
39
20
|
case 'ES512':
|
|
40
|
-
return { hash: {
|
|
21
|
+
return { hash: `SHA-${length}`, name: 'ECDSA', namedCurve };
|
|
41
22
|
case (isCloudflareWorkers() || isNodeJs()) && 'EdDSA':
|
|
42
|
-
return { name:
|
|
23
|
+
return { name: namedCurve, namedCurve };
|
|
43
24
|
default:
|
|
44
25
|
throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
|
|
45
26
|
}
|
|
@@ -6,148 +6,3 @@ export function isCryptoKey(key) {
|
|
|
6
6
|
}
|
|
7
7
|
return key != null && key instanceof globalThis.CryptoKey;
|
|
8
8
|
}
|
|
9
|
-
function getHashLength(hash) {
|
|
10
|
-
return parseInt(hash === null || hash === void 0 ? void 0 : hash.name.substr(4), 10);
|
|
11
|
-
}
|
|
12
|
-
function getNamedCurve(alg) {
|
|
13
|
-
switch (alg) {
|
|
14
|
-
case 'ES256':
|
|
15
|
-
return 'P-256';
|
|
16
|
-
case 'ES384':
|
|
17
|
-
return 'P-384';
|
|
18
|
-
case 'ES512':
|
|
19
|
-
return 'P-521';
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
export function checkCryptoKey(key, alg, ...usages) {
|
|
23
|
-
switch (alg) {
|
|
24
|
-
case undefined:
|
|
25
|
-
break;
|
|
26
|
-
case 'HS256':
|
|
27
|
-
case 'HS384':
|
|
28
|
-
case 'HS512': {
|
|
29
|
-
if (key.algorithm.name !== 'HMAC') {
|
|
30
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be HMAC.`);
|
|
31
|
-
}
|
|
32
|
-
const expected = parseInt(alg.substr(2), 10);
|
|
33
|
-
const actual = getHashLength(key.algorithm.hash);
|
|
34
|
-
if (actual !== expected) {
|
|
35
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
|
|
36
|
-
}
|
|
37
|
-
break;
|
|
38
|
-
}
|
|
39
|
-
case 'RS256':
|
|
40
|
-
case 'RS384':
|
|
41
|
-
case 'RS512': {
|
|
42
|
-
if (key.algorithm.name !== 'RSASSA-PKCS1-v1_5') {
|
|
43
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be RSASSA-PKCS1-v1_5.`);
|
|
44
|
-
}
|
|
45
|
-
const expected = parseInt(alg.substr(2), 10);
|
|
46
|
-
const actual = getHashLength(key.algorithm.hash);
|
|
47
|
-
if (actual !== expected) {
|
|
48
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
|
|
49
|
-
}
|
|
50
|
-
break;
|
|
51
|
-
}
|
|
52
|
-
case 'PS256':
|
|
53
|
-
case 'PS384':
|
|
54
|
-
case 'PS512': {
|
|
55
|
-
if (key.algorithm.name !== 'RSA-PSS') {
|
|
56
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be RSA-PSS.`);
|
|
57
|
-
}
|
|
58
|
-
const expected = parseInt(alg.substr(2), 10);
|
|
59
|
-
const actual = getHashLength(key.algorithm.hash);
|
|
60
|
-
if (actual !== expected) {
|
|
61
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
|
|
62
|
-
}
|
|
63
|
-
break;
|
|
64
|
-
}
|
|
65
|
-
case 'EdDSA': {
|
|
66
|
-
if (key.algorithm.name !== 'NODE-ED25519' && key.algorithm.name !== 'NODE-ED448') {
|
|
67
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be NODE-ED25519 or NODE-ED448.`);
|
|
68
|
-
}
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
71
|
-
case 'ES256':
|
|
72
|
-
case 'ES384':
|
|
73
|
-
case 'ES512': {
|
|
74
|
-
if (key.algorithm.name !== 'ECDSA') {
|
|
75
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be ECDSA.`);
|
|
76
|
-
}
|
|
77
|
-
const expected = getNamedCurve(alg);
|
|
78
|
-
const actual = key.algorithm.namedCurve;
|
|
79
|
-
if (actual !== expected) {
|
|
80
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.namedCurve must be ${expected}.`);
|
|
81
|
-
}
|
|
82
|
-
break;
|
|
83
|
-
}
|
|
84
|
-
case 'A128GCM':
|
|
85
|
-
case 'A192GCM':
|
|
86
|
-
case 'A256GCM': {
|
|
87
|
-
if (key.algorithm.name !== 'AES-GCM') {
|
|
88
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be AES-GCM.`);
|
|
89
|
-
}
|
|
90
|
-
const expected = parseInt(alg.substr(1, 3), 10);
|
|
91
|
-
const actual = key.algorithm.length;
|
|
92
|
-
if (actual !== expected) {
|
|
93
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.length must be ${expected}.`);
|
|
94
|
-
}
|
|
95
|
-
break;
|
|
96
|
-
}
|
|
97
|
-
case 'A128KW':
|
|
98
|
-
case 'A192KW':
|
|
99
|
-
case 'A256KW': {
|
|
100
|
-
if (key.algorithm.name !== 'AES-KW') {
|
|
101
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be AES-KW.`);
|
|
102
|
-
}
|
|
103
|
-
const expected = parseInt(alg.substr(1, 3), 10);
|
|
104
|
-
const actual = key.algorithm.length;
|
|
105
|
-
if (actual !== expected) {
|
|
106
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.length must be ${expected}.`);
|
|
107
|
-
}
|
|
108
|
-
break;
|
|
109
|
-
}
|
|
110
|
-
case 'ECDH-ES':
|
|
111
|
-
if (key.algorithm.name !== 'ECDH') {
|
|
112
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be ECDH.`);
|
|
113
|
-
}
|
|
114
|
-
break;
|
|
115
|
-
case 'PBES2-HS256+A128KW':
|
|
116
|
-
case 'PBES2-HS384+A192KW':
|
|
117
|
-
case 'PBES2-HS512+A256KW':
|
|
118
|
-
if (key.algorithm.name !== 'PBKDF2') {
|
|
119
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be PBKDF2.`);
|
|
120
|
-
}
|
|
121
|
-
break;
|
|
122
|
-
case 'RSA-OAEP':
|
|
123
|
-
case 'RSA-OAEP-256':
|
|
124
|
-
case 'RSA-OAEP-384':
|
|
125
|
-
case 'RSA-OAEP-512': {
|
|
126
|
-
if (key.algorithm.name !== 'RSA-OAEP') {
|
|
127
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be RSA-OAEP.`);
|
|
128
|
-
}
|
|
129
|
-
const expected = parseInt(alg.substr(9), 10) || 1;
|
|
130
|
-
const actual = getHashLength(key.algorithm.hash);
|
|
131
|
-
if (actual !== expected) {
|
|
132
|
-
throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
|
|
133
|
-
}
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
136
|
-
default:
|
|
137
|
-
throw new TypeError('CryptoKey does not support this operation');
|
|
138
|
-
}
|
|
139
|
-
if (usages.length && !usages.some((expected) => key.usages.includes(expected))) {
|
|
140
|
-
let msg = 'CryptoKey does not support this operation, its usages must include ';
|
|
141
|
-
if (usages.length > 2) {
|
|
142
|
-
const last = usages.pop();
|
|
143
|
-
msg += `one of ${usages.join(', ')}, or ${last}.`;
|
|
144
|
-
}
|
|
145
|
-
else if (usages.length === 2) {
|
|
146
|
-
msg += `one of ${usages[0]} or ${usages[1]}.`;
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
msg += `${usages[0]}.`;
|
|
150
|
-
}
|
|
151
|
-
throw new TypeError(msg);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.unwrap = exports.wrap = void 0;
|
|
4
|
-
const encrypt_js_1 = require("
|
|
5
|
-
const decrypt_js_1 = require("
|
|
6
|
-
const iv_js_1 = require("
|
|
7
|
-
const base64url_js_1 = require("
|
|
8
|
-
|
|
4
|
+
const encrypt_js_1 = require("../runtime/encrypt.js");
|
|
5
|
+
const decrypt_js_1 = require("../runtime/decrypt.js");
|
|
6
|
+
const iv_js_1 = require("./iv.js");
|
|
7
|
+
const base64url_js_1 = require("../runtime/base64url.js");
|
|
8
|
+
async function wrap(alg, key, cek, iv) {
|
|
9
9
|
const jweAlgorithm = alg.substr(0, 7);
|
|
10
10
|
iv || (iv = (0, iv_js_1.default)(jweAlgorithm));
|
|
11
11
|
const { ciphertext: encryptedKey, tag } = await (0, encrypt_js_1.default)(jweAlgorithm, cek, key, iv, new Uint8Array(0));
|
|
12
12
|
return { encryptedKey, iv: (0, base64url_js_1.encode)(iv), tag: (0, base64url_js_1.encode)(tag) };
|
|
13
|
-
}
|
|
13
|
+
}
|
|
14
14
|
exports.wrap = wrap;
|
|
15
|
-
|
|
15
|
+
async function unwrap(alg, key, encryptedKey, iv, tag) {
|
|
16
16
|
const jweAlgorithm = alg.substr(0, 7);
|
|
17
17
|
return (0, decrypt_js_1.default)(jweAlgorithm, key, encryptedKey, iv, tag, new Uint8Array(0));
|
|
18
|
-
}
|
|
18
|
+
}
|
|
19
19
|
exports.unwrap = unwrap;
|
package/dist/node/cjs/lib/cek.js
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.bitLength = void 0;
|
|
4
4
|
const errors_js_1 = require("../util/errors.js");
|
|
5
5
|
const random_js_1 = require("../runtime/random.js");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
6
|
+
function bitLength(alg) {
|
|
7
|
+
switch (alg) {
|
|
8
|
+
case 'A128CBC-HS256':
|
|
9
|
+
return 256;
|
|
10
|
+
case 'A192CBC-HS384':
|
|
11
|
+
return 384;
|
|
12
|
+
case 'A256CBC-HS512':
|
|
13
|
+
return 512;
|
|
14
|
+
case 'A128GCM':
|
|
15
|
+
return 128;
|
|
16
|
+
case 'A192GCM':
|
|
17
|
+
return 192;
|
|
18
|
+
case 'A256GCM':
|
|
19
|
+
return 256;
|
|
20
|
+
default:
|
|
21
|
+
throw new errors_js_1.JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`);
|
|
19
22
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
exports.default =
|
|
23
|
+
}
|
|
24
|
+
exports.bitLength = bitLength;
|
|
25
|
+
exports.default = (alg) => (0, random_js_1.default)(new Uint8Array(bitLength(alg) >> 3));
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const errors_js_1 = require("../util/errors.js");
|
|
4
4
|
const iv_js_1 = require("./iv.js");
|
|
5
5
|
const checkIvLength = (enc, iv) => {
|
|
6
|
-
if (iv.length << 3 !== iv_js_1.
|
|
6
|
+
if (iv.length << 3 !== (0, iv_js_1.bitLength)(enc)) {
|
|
7
7
|
throw new errors_js_1.JWEInvalid('Invalid Initialization Vector length');
|
|
8
8
|
}
|
|
9
9
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const invalid_key_input_js_1 = require("
|
|
3
|
+
const invalid_key_input_js_1 = require("./invalid_key_input.js");
|
|
4
4
|
const is_key_like_js_1 = require("../runtime/is_key_like.js");
|
|
5
5
|
const symmetricTypeCheck = (key) => {
|
|
6
6
|
if (key instanceof Uint8Array)
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkEncCryptoKey = exports.checkSigCryptoKey = void 0;
|
|
4
|
+
const global_js_1 = require("../runtime/global.js");
|
|
5
|
+
function unusable(name, prop = 'algorithm.name') {
|
|
6
|
+
return new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
|
|
7
|
+
}
|
|
8
|
+
function isAlgorithm(algorithm, name) {
|
|
9
|
+
return algorithm.name === name;
|
|
10
|
+
}
|
|
11
|
+
function getHashLength(hash) {
|
|
12
|
+
return parseInt(hash.name.substr(4), 10);
|
|
13
|
+
}
|
|
14
|
+
function getNamedCurve(alg) {
|
|
15
|
+
switch (alg) {
|
|
16
|
+
case 'ES256':
|
|
17
|
+
return 'P-256';
|
|
18
|
+
case 'ES384':
|
|
19
|
+
return 'P-384';
|
|
20
|
+
case 'ES512':
|
|
21
|
+
return 'P-521';
|
|
22
|
+
default:
|
|
23
|
+
throw new Error('unreachable');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function checkUsage(key, usages) {
|
|
27
|
+
if (usages.length && !usages.some((expected) => key.usages.includes(expected))) {
|
|
28
|
+
let msg = 'CryptoKey does not support this operation, its usages must include ';
|
|
29
|
+
if (usages.length > 2) {
|
|
30
|
+
const last = usages.pop();
|
|
31
|
+
msg += `one of ${usages.join(', ')}, or ${last}.`;
|
|
32
|
+
}
|
|
33
|
+
else if (usages.length === 2) {
|
|
34
|
+
msg += `one of ${usages[0]} or ${usages[1]}.`;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
msg += `${usages[0]}.`;
|
|
38
|
+
}
|
|
39
|
+
throw new TypeError(msg);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function checkSigCryptoKey(key, alg, ...usages) {
|
|
43
|
+
switch (alg) {
|
|
44
|
+
case 'HS256':
|
|
45
|
+
case 'HS384':
|
|
46
|
+
case 'HS512': {
|
|
47
|
+
if (!isAlgorithm(key.algorithm, 'HMAC'))
|
|
48
|
+
throw unusable('HMAC');
|
|
49
|
+
const expected = parseInt(alg.substr(2), 10);
|
|
50
|
+
const actual = getHashLength(key.algorithm.hash);
|
|
51
|
+
if (actual !== expected)
|
|
52
|
+
throw unusable(`SHA-${expected}`, 'algorithm.hash');
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
case 'RS256':
|
|
56
|
+
case 'RS384':
|
|
57
|
+
case 'RS512': {
|
|
58
|
+
if (!isAlgorithm(key.algorithm, 'RSASSA-PKCS1-v1_5'))
|
|
59
|
+
throw unusable('RSASSA-PKCS1-v1_5');
|
|
60
|
+
const expected = parseInt(alg.substr(2), 10);
|
|
61
|
+
const actual = getHashLength(key.algorithm.hash);
|
|
62
|
+
if (actual !== expected)
|
|
63
|
+
throw unusable(`SHA-${expected}`, 'algorithm.hash');
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case 'PS256':
|
|
67
|
+
case 'PS384':
|
|
68
|
+
case 'PS512': {
|
|
69
|
+
if (!isAlgorithm(key.algorithm, 'RSA-PSS'))
|
|
70
|
+
throw unusable('RSA-PSS');
|
|
71
|
+
const expected = parseInt(alg.substr(2), 10);
|
|
72
|
+
const actual = getHashLength(key.algorithm.hash);
|
|
73
|
+
if (actual !== expected)
|
|
74
|
+
throw unusable(`SHA-${expected}`, 'algorithm.hash');
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case (0, global_js_1.isNodeJs)() && 'EdDSA': {
|
|
78
|
+
if (key.algorithm.name !== 'NODE-ED25519' && key.algorithm.name !== 'NODE-ED448')
|
|
79
|
+
throw unusable('NODE-ED25519 or NODE-ED448');
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
case (0, global_js_1.isCloudflareWorkers)() && 'EdDSA': {
|
|
83
|
+
if (!isAlgorithm(key.algorithm, 'NODE-ED25519'))
|
|
84
|
+
throw unusable('NODE-ED25519');
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
case 'ES256':
|
|
88
|
+
case 'ES384':
|
|
89
|
+
case 'ES512': {
|
|
90
|
+
if (!isAlgorithm(key.algorithm, 'ECDSA'))
|
|
91
|
+
throw unusable('ECDSA');
|
|
92
|
+
const expected = getNamedCurve(alg);
|
|
93
|
+
const actual = key.algorithm.namedCurve;
|
|
94
|
+
if (actual !== expected)
|
|
95
|
+
throw unusable(expected, 'algorithm.namedCurve');
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
default:
|
|
99
|
+
throw new TypeError('CryptoKey does not support this operation');
|
|
100
|
+
}
|
|
101
|
+
checkUsage(key, usages);
|
|
102
|
+
}
|
|
103
|
+
exports.checkSigCryptoKey = checkSigCryptoKey;
|
|
104
|
+
function checkEncCryptoKey(key, alg, ...usages) {
|
|
105
|
+
switch (alg) {
|
|
106
|
+
case 'A128GCM':
|
|
107
|
+
case 'A192GCM':
|
|
108
|
+
case 'A256GCM': {
|
|
109
|
+
if (!isAlgorithm(key.algorithm, 'AES-GCM'))
|
|
110
|
+
throw unusable('AES-GCM');
|
|
111
|
+
const expected = parseInt(alg.substr(1, 3), 10);
|
|
112
|
+
const actual = key.algorithm.length;
|
|
113
|
+
if (actual !== expected)
|
|
114
|
+
throw unusable(expected, 'algorithm.length');
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
case 'A128KW':
|
|
118
|
+
case 'A192KW':
|
|
119
|
+
case 'A256KW': {
|
|
120
|
+
if (!isAlgorithm(key.algorithm, 'AES-KW'))
|
|
121
|
+
throw unusable('AES-KW');
|
|
122
|
+
const expected = parseInt(alg.substr(1, 3), 10);
|
|
123
|
+
const actual = key.algorithm.length;
|
|
124
|
+
if (actual !== expected)
|
|
125
|
+
throw unusable(expected, 'algorithm.length');
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
case 'ECDH-ES':
|
|
129
|
+
if (!isAlgorithm(key.algorithm, 'ECDH'))
|
|
130
|
+
throw unusable('ECDH');
|
|
131
|
+
break;
|
|
132
|
+
case 'PBES2-HS256+A128KW':
|
|
133
|
+
case 'PBES2-HS384+A192KW':
|
|
134
|
+
case 'PBES2-HS512+A256KW':
|
|
135
|
+
if (!isAlgorithm(key.algorithm, 'PBKDF2'))
|
|
136
|
+
throw unusable('PBKDF2');
|
|
137
|
+
break;
|
|
138
|
+
case 'RSA-OAEP':
|
|
139
|
+
case 'RSA-OAEP-256':
|
|
140
|
+
case 'RSA-OAEP-384':
|
|
141
|
+
case 'RSA-OAEP-512': {
|
|
142
|
+
if (!isAlgorithm(key.algorithm, 'RSA-OAEP'))
|
|
143
|
+
throw unusable('RSA-OAEP');
|
|
144
|
+
const expected = parseInt(alg.substr(9), 10) || 1;
|
|
145
|
+
const actual = getHashLength(key.algorithm.hash);
|
|
146
|
+
if (actual !== expected)
|
|
147
|
+
throw unusable(`SHA-${expected}`, 'algorithm.hash');
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
default:
|
|
151
|
+
throw new TypeError('CryptoKey does not support this operation');
|
|
152
|
+
}
|
|
153
|
+
checkUsage(key, usages);
|
|
154
|
+
}
|
|
155
|
+
exports.checkEncCryptoKey = checkEncCryptoKey;
|
|
@@ -4,13 +4,13 @@ const aeskw_js_1 = require("../runtime/aeskw.js");
|
|
|
4
4
|
const ECDH = require("../runtime/ecdhes.js");
|
|
5
5
|
const pbes2kw_js_1 = require("../runtime/pbes2kw.js");
|
|
6
6
|
const rsaes_js_1 = require("../runtime/rsaes.js");
|
|
7
|
-
const aesgcmkw_js_1 = require("../runtime/aesgcmkw.js");
|
|
8
7
|
const base64url_js_1 = require("../runtime/base64url.js");
|
|
9
8
|
const errors_js_1 = require("../util/errors.js");
|
|
10
9
|
const cek_js_1 = require("../lib/cek.js");
|
|
11
10
|
const import_js_1 = require("../key/import.js");
|
|
12
11
|
const check_key_type_js_1 = require("./check_key_type.js");
|
|
13
12
|
const is_object_js_1 = require("./is_object.js");
|
|
13
|
+
const aesgcmkw_js_1 = require("./aesgcmkw.js");
|
|
14
14
|
async function decryptKeyManagement(alg, key, encryptedKey, joseHeader) {
|
|
15
15
|
(0, check_key_type_js_1.default)(alg, key, 'decrypt');
|
|
16
16
|
switch (alg) {
|
|
@@ -42,7 +42,7 @@ async function decryptKeyManagement(alg, key, encryptedKey, joseHeader) {
|
|
|
42
42
|
throw new errors_js_1.JWEInvalid(`JOSE Header "apv" (Agreement PartyVInfo) invalid`);
|
|
43
43
|
partyVInfo = (0, base64url_js_1.decode)(joseHeader.apv);
|
|
44
44
|
}
|
|
45
|
-
const sharedSecret = await ECDH.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, parseInt(alg.substr(-5, 3), 10) || cek_js_1.
|
|
45
|
+
const sharedSecret = await ECDH.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, parseInt(alg.substr(-5, 3), 10) || (0, cek_js_1.bitLength)(joseHeader.enc), partyUInfo, partyVInfo);
|
|
46
46
|
if (alg === 'ECDH-ES')
|
|
47
47
|
return sharedSecret;
|
|
48
48
|
if (encryptedKey === undefined)
|
|
@@ -4,12 +4,12 @@ const aeskw_js_1 = require("../runtime/aeskw.js");
|
|
|
4
4
|
const ECDH = require("../runtime/ecdhes.js");
|
|
5
5
|
const pbes2kw_js_1 = require("../runtime/pbes2kw.js");
|
|
6
6
|
const rsaes_js_1 = require("../runtime/rsaes.js");
|
|
7
|
-
const aesgcmkw_js_1 = require("../runtime/aesgcmkw.js");
|
|
8
7
|
const base64url_js_1 = require("../runtime/base64url.js");
|
|
9
8
|
const cek_js_1 = require("../lib/cek.js");
|
|
10
9
|
const errors_js_1 = require("../util/errors.js");
|
|
11
10
|
const export_js_1 = require("../key/export.js");
|
|
12
11
|
const check_key_type_js_1 = require("./check_key_type.js");
|
|
12
|
+
const aesgcmkw_js_1 = require("./aesgcmkw.js");
|
|
13
13
|
async function encryptKeyManagement(alg, enc, key, providedCek, providedParameters = {}) {
|
|
14
14
|
let encryptedKey;
|
|
15
15
|
let parameters;
|
|
@@ -31,7 +31,7 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
|
|
|
31
31
|
let { epk: ephemeralKey } = providedParameters;
|
|
32
32
|
ephemeralKey || (ephemeralKey = await ECDH.generateEpk(key));
|
|
33
33
|
const { x, y, crv, kty } = await (0, export_js_1.exportJWK)(ephemeralKey);
|
|
34
|
-
const sharedSecret = await ECDH.deriveKey(key, ephemeralKey, alg === 'ECDH-ES' ? enc : alg, parseInt(alg.substr(-5, 3), 10) || cek_js_1.
|
|
34
|
+
const sharedSecret = await ECDH.deriveKey(key, ephemeralKey, alg === 'ECDH-ES' ? enc : alg, parseInt(alg.substr(-5, 3), 10) || (0, cek_js_1.bitLength)(enc), apu, apv);
|
|
35
35
|
parameters = { epk: { x, y, crv, kty } };
|
|
36
36
|
if (apu)
|
|
37
37
|
parameters.apu = (0, base64url_js_1.encode)(apu);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const util_1 = require("util");
|
|
4
3
|
exports.default = (actual, ...types) => {
|
|
5
4
|
let msg = 'Key must be ';
|
|
6
5
|
if (types.length > 2) {
|
|
@@ -23,16 +22,6 @@ exports.default = (actual, ...types) => {
|
|
|
23
22
|
if (actual.constructor && actual.constructor.name) {
|
|
24
23
|
msg += ` Received an instance of ${actual.constructor.name}`;
|
|
25
24
|
}
|
|
26
|
-
else {
|
|
27
|
-
const inspected = (0, util_1.inspect)(actual, { depth: -1 });
|
|
28
|
-
msg += ` Received ${inspected}`;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
let inspected = (0, util_1.inspect)(actual, { colors: false });
|
|
33
|
-
if (inspected.length > 25)
|
|
34
|
-
inspected = `${inspected.slice(0, 25)}...`;
|
|
35
|
-
msg += ` Received type ${typeof actual} (${inspected})`;
|
|
36
25
|
}
|
|
37
26
|
return msg;
|
|
38
27
|
};
|