jose 4.0.4 → 4.1.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.
Files changed (62) hide show
  1. package/dist/browser/{runtime → lib}/aesgcmkw.js +8 -8
  2. package/dist/browser/lib/check_key_type.js +1 -1
  3. package/dist/browser/lib/crypto_key.js +46 -56
  4. package/dist/browser/lib/decrypt_key_management.js +1 -1
  5. package/dist/browser/lib/encrypt_key_management.js +1 -1
  6. package/dist/browser/{runtime → lib}/invalid_key_input.js +0 -0
  7. package/dist/browser/runtime/aeskw.js +1 -1
  8. package/dist/browser/runtime/asn1.js +6 -7
  9. package/dist/browser/runtime/base64url.js +2 -4
  10. package/dist/browser/runtime/bogus.js +1 -1
  11. package/dist/browser/runtime/decrypt.js +2 -2
  12. package/dist/browser/runtime/ecdhes.js +1 -1
  13. package/dist/browser/runtime/encrypt.js +2 -2
  14. package/dist/browser/runtime/env.js +11 -0
  15. package/dist/browser/runtime/fetch_jwks.js +3 -5
  16. package/dist/browser/runtime/generate.js +5 -5
  17. package/dist/browser/runtime/get_sign_verify_key.js +2 -2
  18. package/dist/browser/runtime/jwk_to_key.js +5 -5
  19. package/dist/browser/runtime/key_to_jwk.js +1 -1
  20. package/dist/browser/runtime/pbes2kw.js +11 -34
  21. package/dist/browser/runtime/rsaes.js +1 -1
  22. package/dist/browser/runtime/subtle_dsa.js +8 -27
  23. package/dist/browser/runtime/webcrypto.js +8 -4
  24. package/dist/node/cjs/{runtime → lib}/aesgcmkw.js +8 -8
  25. package/dist/node/cjs/lib/check_key_type.js +1 -1
  26. package/dist/node/cjs/lib/crypto_key.js +48 -58
  27. package/dist/node/cjs/lib/decrypt_key_management.js +1 -1
  28. package/dist/node/cjs/lib/encrypt_key_management.js +1 -1
  29. package/dist/node/cjs/{runtime → lib}/invalid_key_input.js +0 -11
  30. package/dist/node/cjs/runtime/aeskw.js +1 -1
  31. package/dist/node/cjs/runtime/asn1.js +1 -1
  32. package/dist/node/cjs/runtime/decrypt.js +1 -1
  33. package/dist/node/cjs/runtime/ecdhes.js +1 -1
  34. package/dist/node/cjs/runtime/encrypt.js +1 -1
  35. package/dist/node/cjs/runtime/{global.js → env.js} +0 -0
  36. package/dist/node/cjs/runtime/get_named_curve.js +1 -1
  37. package/dist/node/cjs/runtime/get_sign_verify_key.js +1 -1
  38. package/dist/node/cjs/runtime/key_to_jwk.js +1 -1
  39. package/dist/node/cjs/runtime/node_key.js +6 -10
  40. package/dist/node/cjs/runtime/pbes2kw.js +1 -1
  41. package/dist/node/cjs/runtime/rsaes.js +1 -1
  42. package/dist/node/esm/{runtime → lib}/aesgcmkw.js +8 -8
  43. package/dist/node/esm/lib/check_key_type.js +1 -1
  44. package/dist/node/esm/lib/crypto_key.js +46 -56
  45. package/dist/node/esm/lib/decrypt_key_management.js +1 -1
  46. package/dist/node/esm/lib/encrypt_key_management.js +1 -1
  47. package/dist/node/esm/{runtime → lib}/invalid_key_input.js +0 -11
  48. package/dist/node/esm/runtime/aeskw.js +1 -1
  49. package/dist/node/esm/runtime/asn1.js +1 -1
  50. package/dist/node/esm/runtime/decrypt.js +1 -1
  51. package/dist/node/esm/runtime/ecdhes.js +1 -1
  52. package/dist/node/esm/runtime/encrypt.js +1 -1
  53. package/dist/node/esm/runtime/{global.js → env.js} +0 -0
  54. package/dist/node/esm/runtime/get_named_curve.js +1 -1
  55. package/dist/node/esm/runtime/get_sign_verify_key.js +1 -1
  56. package/dist/node/esm/runtime/key_to_jwk.js +1 -1
  57. package/dist/node/esm/runtime/node_key.js +6 -10
  58. package/dist/node/esm/runtime/pbes2kw.js +1 -1
  59. package/dist/node/esm/runtime/rsaes.js +1 -1
  60. package/dist/types/jwks/remote.d.ts +4 -0
  61. package/package.json +4 -1
  62. package/dist/browser/runtime/global.js +0 -27
@@ -1,14 +1,14 @@
1
- import encrypt from './encrypt.js';
2
- import decrypt from './decrypt.js';
3
- import generateIv from '../lib/iv.js';
4
- import { encode as base64url } from './base64url.js';
5
- export const wrap = async (alg, key, cek, iv) => {
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 const unwrap = async (alg, key, encryptedKey, iv, tag) => {
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
+ }
@@ -1,4 +1,4 @@
1
- import invalidKeyInput from '../runtime/invalid_key_input.js';
1
+ import invalidKeyInput from './invalid_key_input.js';
2
2
  import isKeyLike, { types } from '../runtime/is_key_like.js';
3
3
  const symmetricTypeCheck = (key) => {
4
4
  if (key instanceof Uint8Array)
@@ -1,6 +1,12 @@
1
- import { isCloudflareWorkers, isNodeJs } from '../runtime/global.js';
1
+ import { isCloudflareWorkers, isNodeJs } from '../runtime/env.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
+ }
2
8
  function getHashLength(hash) {
3
- return parseInt(hash === null || hash === void 0 ? void 0 : hash.name.substr(4), 10);
9
+ return parseInt(hash.name.substr(4), 10);
4
10
  }
5
11
  function getNamedCurve(alg) {
6
12
  switch (alg) {
@@ -10,6 +16,8 @@ function getNamedCurve(alg) {
10
16
  return 'P-384';
11
17
  case 'ES512':
12
18
  return 'P-521';
19
+ default:
20
+ throw new Error('unreachable');
13
21
  }
14
22
  }
15
23
  function checkUsage(key, usages) {
@@ -33,65 +41,55 @@ export function checkSigCryptoKey(key, alg, ...usages) {
33
41
  case 'HS256':
34
42
  case 'HS384':
35
43
  case 'HS512': {
36
- if (key.algorithm.name !== 'HMAC') {
37
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be HMAC.`);
38
- }
44
+ if (!isAlgorithm(key.algorithm, 'HMAC'))
45
+ throw unusable('HMAC');
39
46
  const expected = parseInt(alg.substr(2), 10);
40
47
  const actual = getHashLength(key.algorithm.hash);
41
- if (actual !== expected) {
42
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
43
- }
48
+ if (actual !== expected)
49
+ throw unusable(`SHA-${expected}`, 'algorithm.hash');
44
50
  break;
45
51
  }
46
52
  case 'RS256':
47
53
  case 'RS384':
48
54
  case 'RS512': {
49
- if (key.algorithm.name !== 'RSASSA-PKCS1-v1_5') {
50
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be RSASSA-PKCS1-v1_5.`);
51
- }
55
+ if (!isAlgorithm(key.algorithm, 'RSASSA-PKCS1-v1_5'))
56
+ throw unusable('RSASSA-PKCS1-v1_5');
52
57
  const expected = parseInt(alg.substr(2), 10);
53
58
  const actual = getHashLength(key.algorithm.hash);
54
- if (actual !== expected) {
55
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
56
- }
59
+ if (actual !== expected)
60
+ throw unusable(`SHA-${expected}`, 'algorithm.hash');
57
61
  break;
58
62
  }
59
63
  case 'PS256':
60
64
  case 'PS384':
61
65
  case 'PS512': {
62
- if (key.algorithm.name !== 'RSA-PSS') {
63
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be RSA-PSS.`);
64
- }
66
+ if (!isAlgorithm(key.algorithm, 'RSA-PSS'))
67
+ throw unusable('RSA-PSS');
65
68
  const expected = parseInt(alg.substr(2), 10);
66
69
  const actual = getHashLength(key.algorithm.hash);
67
- if (actual !== expected) {
68
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
69
- }
70
+ if (actual !== expected)
71
+ throw unusable(`SHA-${expected}`, 'algorithm.hash');
70
72
  break;
71
73
  }
72
74
  case isNodeJs() && 'EdDSA': {
73
- if (key.algorithm.name !== 'NODE-ED25519' && key.algorithm.name !== 'NODE-ED448') {
74
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be NODE-ED25519 or NODE-ED448.`);
75
- }
75
+ if (key.algorithm.name !== 'NODE-ED25519' && key.algorithm.name !== 'NODE-ED448')
76
+ throw unusable('NODE-ED25519 or NODE-ED448');
76
77
  break;
77
78
  }
78
79
  case isCloudflareWorkers() && 'EdDSA': {
79
- if (key.algorithm.name !== 'NODE-ED25519') {
80
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be NODE-ED25519.`);
81
- }
80
+ if (!isAlgorithm(key.algorithm, 'NODE-ED25519'))
81
+ throw unusable('NODE-ED25519');
82
82
  break;
83
83
  }
84
84
  case 'ES256':
85
85
  case 'ES384':
86
86
  case 'ES512': {
87
- if (key.algorithm.name !== 'ECDSA') {
88
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be ECDSA.`);
89
- }
87
+ if (!isAlgorithm(key.algorithm, 'ECDSA'))
88
+ throw unusable('ECDSA');
90
89
  const expected = getNamedCurve(alg);
91
90
  const actual = key.algorithm.namedCurve;
92
- if (actual !== expected) {
93
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.namedCurve must be ${expected}.`);
94
- }
91
+ if (actual !== expected)
92
+ throw unusable(expected, 'algorithm.namedCurve');
95
93
  break;
96
94
  }
97
95
  default:
@@ -104,53 +102,45 @@ export function checkEncCryptoKey(key, alg, ...usages) {
104
102
  case 'A128GCM':
105
103
  case 'A192GCM':
106
104
  case 'A256GCM': {
107
- if (key.algorithm.name !== 'AES-GCM') {
108
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be AES-GCM.`);
109
- }
105
+ if (!isAlgorithm(key.algorithm, 'AES-GCM'))
106
+ throw unusable('AES-GCM');
110
107
  const expected = parseInt(alg.substr(1, 3), 10);
111
108
  const actual = key.algorithm.length;
112
- if (actual !== expected) {
113
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.length must be ${expected}.`);
114
- }
109
+ if (actual !== expected)
110
+ throw unusable(expected, 'algorithm.length');
115
111
  break;
116
112
  }
117
113
  case 'A128KW':
118
114
  case 'A192KW':
119
115
  case 'A256KW': {
120
- if (key.algorithm.name !== 'AES-KW') {
121
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be AES-KW.`);
122
- }
116
+ if (!isAlgorithm(key.algorithm, 'AES-KW'))
117
+ throw unusable('AES-KW');
123
118
  const expected = parseInt(alg.substr(1, 3), 10);
124
119
  const actual = key.algorithm.length;
125
- if (actual !== expected) {
126
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.length must be ${expected}.`);
127
- }
120
+ if (actual !== expected)
121
+ throw unusable(expected, 'algorithm.length');
128
122
  break;
129
123
  }
130
124
  case 'ECDH-ES':
131
- if (key.algorithm.name !== 'ECDH') {
132
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be ECDH.`);
133
- }
125
+ if (!isAlgorithm(key.algorithm, 'ECDH'))
126
+ throw unusable('ECDH');
134
127
  break;
135
128
  case 'PBES2-HS256+A128KW':
136
129
  case 'PBES2-HS384+A192KW':
137
130
  case 'PBES2-HS512+A256KW':
138
- if (key.algorithm.name !== 'PBKDF2') {
139
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be PBKDF2.`);
140
- }
131
+ if (!isAlgorithm(key.algorithm, 'PBKDF2'))
132
+ throw unusable('PBKDF2');
141
133
  break;
142
134
  case 'RSA-OAEP':
143
135
  case 'RSA-OAEP-256':
144
136
  case 'RSA-OAEP-384':
145
137
  case 'RSA-OAEP-512': {
146
- if (key.algorithm.name !== 'RSA-OAEP') {
147
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be RSA-OAEP.`);
148
- }
138
+ if (!isAlgorithm(key.algorithm, 'RSA-OAEP'))
139
+ throw unusable('RSA-OAEP');
149
140
  const expected = parseInt(alg.substr(9), 10) || 1;
150
141
  const actual = getHashLength(key.algorithm.hash);
151
- if (actual !== expected) {
152
- throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
153
- }
142
+ if (actual !== expected)
143
+ throw unusable(`SHA-${expected}`, 'algorithm.hash');
154
144
  break;
155
145
  }
156
146
  default:
@@ -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
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) {
@@ -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
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;
@@ -1,7 +1,7 @@
1
1
  import bogusWebCrypto from './bogus.js';
2
2
  import crypto, { isCryptoKey } from './webcrypto.js';
3
3
  import { checkEncCryptoKey } from '../lib/crypto_key.js';
4
- import invalidKeyInput from './invalid_key_input.js';
4
+ import invalidKeyInput from '../lib/invalid_key_input.js';
5
5
  function checkKeySize(key, alg) {
6
6
  if (key.algorithm.length !== parseInt(alg.substr(1, 3), 10)) {
7
7
  throw new TypeError(`Invalid key size for alg: ${alg}`);
@@ -1,6 +1,6 @@
1
- import globalThis, { isCloudflareWorkers, isNodeJs } from './global.js';
1
+ import { isCloudflareWorkers, isNodeJs } from './env.js';
2
2
  import crypto, { isCryptoKey } from './webcrypto.js';
3
- import invalidKeyInput from './invalid_key_input.js';
3
+ import invalidKeyInput from '../lib/invalid_key_input.js';
4
4
  import { encodeBase64 } from './base64url.js';
5
5
  import formatPEM from '../lib/format_pem.js';
6
6
  import { JOSENotSupported } from '../util/errors.js';
@@ -54,8 +54,7 @@ const genericImport = async (replace, keyFormat, pem, alg, options) => {
54
54
  var _a;
55
55
  let algorithm;
56
56
  let keyUsages;
57
- const keyData = new Uint8Array(globalThis
58
- .atob(pem.replace(replace, ''))
57
+ const keyData = new Uint8Array(atob(pem.replace(replace, ''))
59
58
  .split('')
60
59
  .map((c) => c.charCodeAt(0)));
61
60
  const isPublic = keyFormat === 'spki';
@@ -63,13 +62,13 @@ const genericImport = async (replace, keyFormat, pem, alg, options) => {
63
62
  case 'PS256':
64
63
  case 'PS384':
65
64
  case 'PS512':
66
- algorithm = { name: 'RSA-PSS', hash: { name: `SHA-${alg.substr(-3)}` } };
65
+ algorithm = { name: 'RSA-PSS', hash: `SHA-${alg.substr(-3)}` };
67
66
  keyUsages = isPublic ? ['verify'] : ['sign'];
68
67
  break;
69
68
  case 'RS256':
70
69
  case 'RS384':
71
70
  case 'RS512':
72
- algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: { name: `SHA-${alg.substr(-3)}` } };
71
+ algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.substr(-3)}` };
73
72
  keyUsages = isPublic ? ['verify'] : ['sign'];
74
73
  break;
75
74
  case 'RSA-OAEP':
@@ -78,7 +77,7 @@ const genericImport = async (replace, keyFormat, pem, alg, options) => {
78
77
  case 'RSA-OAEP-512':
79
78
  algorithm = {
80
79
  name: 'RSA-OAEP',
81
- hash: { name: `SHA-${parseInt(alg.substr(-3), 10) || 1}` },
80
+ hash: `SHA-${parseInt(alg.substr(-3), 10) || 1}`,
82
81
  };
83
82
  keyUsages = isPublic ? ['encrypt', 'wrapKey'] : ['decrypt', 'unwrapKey'];
84
83
  break;
@@ -1,5 +1,4 @@
1
1
  import { encoder, decoder } from '../lib/buffer_utils.js';
2
- import globalThis from './global.js';
3
2
  export const encodeBase64 = (input) => {
4
3
  let unencoded = input;
5
4
  if (typeof unencoded === 'string') {
@@ -10,14 +9,13 @@ export const encodeBase64 = (input) => {
10
9
  for (let i = 0; i < unencoded.length; i += CHUNK_SIZE) {
11
10
  arr.push(String.fromCharCode.apply(null, unencoded.subarray(i, i + CHUNK_SIZE)));
12
11
  }
13
- return globalThis.btoa(arr.join(''));
12
+ return btoa(arr.join(''));
14
13
  };
15
14
  export const encode = (input) => {
16
15
  return encodeBase64(input).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
17
16
  };
18
17
  export const decodeBase64 = (encoded) => {
19
- return new Uint8Array(globalThis
20
- .atob(encoded)
18
+ return new Uint8Array(atob(encoded)
21
19
  .split('')
22
20
  .map((c) => c.charCodeAt(0)));
23
21
  };
@@ -1,5 +1,5 @@
1
1
  const bogusWebCrypto = [
2
- { hash: { name: 'SHA-256' }, name: 'HMAC' },
2
+ { hash: 'SHA-256', name: 'HMAC' },
3
3
  true,
4
4
  ['sign'],
5
5
  ];
@@ -5,7 +5,7 @@ import timingSafeEqual from './timing_safe_equal.js';
5
5
  import { JOSENotSupported, JWEDecryptionFailed } from '../util/errors.js';
6
6
  import crypto, { isCryptoKey } from './webcrypto.js';
7
7
  import { checkEncCryptoKey } from '../lib/crypto_key.js';
8
- import invalidKeyInput from './invalid_key_input.js';
8
+ import invalidKeyInput from '../lib/invalid_key_input.js';
9
9
  async function cbcDecrypt(enc, cek, ciphertext, iv, tag, aad) {
10
10
  if (!(cek instanceof Uint8Array)) {
11
11
  throw new TypeError(invalidKeyInput(cek, 'Uint8Array'));
@@ -13,7 +13,7 @@ async function cbcDecrypt(enc, cek, ciphertext, iv, tag, aad) {
13
13
  const keySize = parseInt(enc.substr(1, 3), 10);
14
14
  const encKey = await crypto.subtle.importKey('raw', cek.subarray(keySize >> 3), 'AES-CBC', false, ['decrypt']);
15
15
  const macKey = await crypto.subtle.importKey('raw', cek.subarray(0, keySize >> 3), {
16
- hash: { name: `SHA-${keySize << 1}` },
16
+ hash: `SHA-${keySize << 1}`,
17
17
  name: 'HMAC',
18
18
  }, false, ['sign']);
19
19
  const macData = concat(aad, iv, ciphertext, uint64be(aad.length << 3));
@@ -2,7 +2,7 @@ import { encoder, concat, uint32be, lengthAndInput, concatKdf } from '../lib/buf
2
2
  import crypto, { isCryptoKey } from './webcrypto.js';
3
3
  import { checkEncCryptoKey } from '../lib/crypto_key.js';
4
4
  import digest from './digest.js';
5
- import invalidKeyInput from './invalid_key_input.js';
5
+ import invalidKeyInput from '../lib/invalid_key_input.js';
6
6
  export const deriveKey = async (publicKey, privateKey, algorithm, keyLength, apu = new Uint8Array(0), apv = new Uint8Array(0)) => {
7
7
  if (!isCryptoKey(publicKey)) {
8
8
  throw new TypeError(invalidKeyInput(publicKey, 'CryptoKey'));
@@ -3,7 +3,7 @@ import checkIvLength from '../lib/check_iv_length.js';
3
3
  import checkCekLength from './check_cek_length.js';
4
4
  import crypto, { isCryptoKey } from './webcrypto.js';
5
5
  import { checkEncCryptoKey } from '../lib/crypto_key.js';
6
- import invalidKeyInput from './invalid_key_input.js';
6
+ import invalidKeyInput from '../lib/invalid_key_input.js';
7
7
  import { JOSENotSupported } from '../util/errors.js';
8
8
  async function cbcEncrypt(enc, plaintext, cek, iv, aad) {
9
9
  if (!(cek instanceof Uint8Array)) {
@@ -12,7 +12,7 @@ async function cbcEncrypt(enc, plaintext, cek, iv, aad) {
12
12
  const keySize = parseInt(enc.substr(1, 3), 10);
13
13
  const encKey = await crypto.subtle.importKey('raw', cek.subarray(keySize >> 3), 'AES-CBC', false, ['encrypt']);
14
14
  const macKey = await crypto.subtle.importKey('raw', cek.subarray(0, keySize >> 3), {
15
- hash: { name: `SHA-${keySize << 1}` },
15
+ hash: `SHA-${keySize << 1}`,
16
16
  name: 'HMAC',
17
17
  }, false, ['sign']);
18
18
  const ciphertext = new Uint8Array(await crypto.subtle.encrypt({
@@ -0,0 +1,11 @@
1
+ export function isCloudflareWorkers() {
2
+ return typeof WebSocketPair === 'function';
3
+ }
4
+ export function isNodeJs() {
5
+ try {
6
+ return process.versions.node !== undefined;
7
+ }
8
+ catch (_a) {
9
+ return false;
10
+ }
11
+ }
@@ -1,5 +1,5 @@
1
1
  import { JOSEError, JWKSTimeout } from '../util/errors.js';
2
- import globalThis, { isCloudflareWorkers } from './global.js';
2
+ import { isCloudflareWorkers } from './env.js';
3
3
  const fetchJwks = async (url, timeout) => {
4
4
  let controller;
5
5
  let id;
@@ -11,8 +11,7 @@ const fetchJwks = async (url, timeout) => {
11
11
  controller.abort();
12
12
  }, timeout);
13
13
  }
14
- const response = await globalThis
15
- .fetch(url.href, {
14
+ const response = await fetch(url.href, {
16
15
  signal: controller ? controller.signal : undefined,
17
16
  redirect: 'manual',
18
17
  method: 'GET',
@@ -23,8 +22,7 @@ const fetchJwks = async (url, timeout) => {
23
22
  mode: 'cors',
24
23
  }
25
24
  : undefined),
26
- })
27
- .catch((err) => {
25
+ }).catch((err) => {
28
26
  if (timedOut)
29
27
  throw new JWKSTimeout();
30
28
  throw err;
@@ -1,4 +1,4 @@
1
- import { isCloudflareWorkers, isNodeJs } from './global.js';
1
+ import { isCloudflareWorkers, isNodeJs } from './env.js';
2
2
  import crypto from './webcrypto.js';
3
3
  import { JOSENotSupported } from '../util/errors.js';
4
4
  import random from './random.js';
@@ -12,7 +12,7 @@ export async function generateSecret(alg, options) {
12
12
  case 'HS384':
13
13
  case 'HS512':
14
14
  length = parseInt(alg.substr(-3), 10);
15
- algorithm = { name: 'HMAC', hash: { name: `SHA-${length}` }, length };
15
+ algorithm = { name: 'HMAC', hash: `SHA-${length}`, length };
16
16
  keyUsages = ['sign', 'verify'];
17
17
  break;
18
18
  case 'A128CBC-HS256':
@@ -60,7 +60,7 @@ export async function generateKeyPair(alg, options) {
60
60
  case 'PS512':
61
61
  algorithm = {
62
62
  name: 'RSA-PSS',
63
- hash: { name: `SHA-${alg.substr(-3)}` },
63
+ hash: `SHA-${alg.substr(-3)}`,
64
64
  publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
65
65
  modulusLength: getModulusLengthOption(options),
66
66
  };
@@ -71,7 +71,7 @@ export async function generateKeyPair(alg, options) {
71
71
  case 'RS512':
72
72
  algorithm = {
73
73
  name: 'RSASSA-PKCS1-v1_5',
74
- hash: { name: `SHA-${alg.substr(-3)}` },
74
+ hash: `SHA-${alg.substr(-3)}`,
75
75
  publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
76
76
  modulusLength: getModulusLengthOption(options),
77
77
  };
@@ -83,7 +83,7 @@ export async function generateKeyPair(alg, options) {
83
83
  case 'RSA-OAEP-512':
84
84
  algorithm = {
85
85
  name: 'RSA-OAEP',
86
- hash: { name: `SHA-${parseInt(alg.substr(-3), 10) || 1}` },
86
+ hash: `SHA-${parseInt(alg.substr(-3), 10) || 1}`,
87
87
  publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
88
88
  modulusLength: getModulusLengthOption(options),
89
89
  };
@@ -1,6 +1,6 @@
1
1
  import crypto, { isCryptoKey } from './webcrypto.js';
2
2
  import { checkSigCryptoKey } from '../lib/crypto_key.js';
3
- import invalidKeyInput from './invalid_key_input.js';
3
+ import invalidKeyInput from '../lib/invalid_key_input.js';
4
4
  export default function getCryptoKey(alg, key, usage) {
5
5
  if (isCryptoKey(key)) {
6
6
  checkSigCryptoKey(key, alg, usage);
@@ -10,7 +10,7 @@ export default function getCryptoKey(alg, key, usage) {
10
10
  if (!alg.startsWith('HS')) {
11
11
  throw new TypeError(invalidKeyInput(key, 'CryptoKey'));
12
12
  }
13
- return crypto.subtle.importKey('raw', key, { hash: { name: `SHA-${alg.substr(-3)}` }, name: 'HMAC' }, false, [usage]);
13
+ return crypto.subtle.importKey('raw', key, { hash: `SHA-${alg.substr(-3)}`, name: 'HMAC' }, false, [usage]);
14
14
  }
15
15
  throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'Uint8Array'));
16
16
  }
@@ -1,4 +1,4 @@
1
- import { isCloudflareWorkers, isNodeJs } from './global.js';
1
+ import { isCloudflareWorkers, isNodeJs } from './env.js';
2
2
  import crypto from './webcrypto.js';
3
3
  import { JOSENotSupported } from '../util/errors.js';
4
4
  import { decode as base64url } from './base64url.js';
@@ -11,7 +11,7 @@ function subtleMapping(jwk) {
11
11
  case 'HS256':
12
12
  case 'HS384':
13
13
  case 'HS512':
14
- algorithm = { name: 'HMAC', hash: { name: `SHA-${jwk.alg.substr(-3)}` } };
14
+ algorithm = { name: 'HMAC', hash: `SHA-${jwk.alg.substr(-3)}` };
15
15
  keyUsages = ['sign', 'verify'];
16
16
  break;
17
17
  case 'A128CBC-HS256':
@@ -49,13 +49,13 @@ function subtleMapping(jwk) {
49
49
  case 'PS256':
50
50
  case 'PS384':
51
51
  case 'PS512':
52
- algorithm = { name: 'RSA-PSS', hash: { name: `SHA-${jwk.alg.substr(-3)}` } };
52
+ algorithm = { name: 'RSA-PSS', hash: `SHA-${jwk.alg.substr(-3)}` };
53
53
  keyUsages = jwk.d ? ['sign'] : ['verify'];
54
54
  break;
55
55
  case 'RS256':
56
56
  case 'RS384':
57
57
  case 'RS512':
58
- algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: { name: `SHA-${jwk.alg.substr(-3)}` } };
58
+ algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${jwk.alg.substr(-3)}` };
59
59
  keyUsages = jwk.d ? ['sign'] : ['verify'];
60
60
  break;
61
61
  case 'RSA-OAEP':
@@ -64,7 +64,7 @@ function subtleMapping(jwk) {
64
64
  case 'RSA-OAEP-512':
65
65
  algorithm = {
66
66
  name: 'RSA-OAEP',
67
- hash: { name: `SHA-${parseInt(jwk.alg.substr(-3), 10) || 1}` },
67
+ hash: `SHA-${parseInt(jwk.alg.substr(-3), 10) || 1}`,
68
68
  };
69
69
  keyUsages = jwk.d ? ['decrypt', 'unwrapKey'] : ['encrypt', 'wrapKey'];
70
70
  break;
@@ -1,5 +1,5 @@
1
1
  import crypto, { isCryptoKey } from './webcrypto.js';
2
- import invalidKeyInput from './invalid_key_input.js';
2
+ import invalidKeyInput from '../lib/invalid_key_input.js';
3
3
  import { encode as base64url } from './base64url.js';
4
4
  const keyToJWK = async (key) => {
5
5
  if (key instanceof Uint8Array) {
@@ -5,7 +5,7 @@ import { wrap, unwrap } from './aeskw.js';
5
5
  import checkP2s from '../lib/check_p2s.js';
6
6
  import crypto, { isCryptoKey } from './webcrypto.js';
7
7
  import { checkEncCryptoKey } from '../lib/crypto_key.js';
8
- import invalidKeyInput from './invalid_key_input.js';
8
+ import invalidKeyInput from '../lib/invalid_key_input.js';
9
9
  function getCryptoKey(key, alg) {
10
10
  if (key instanceof Uint8Array) {
11
11
  return crypto.subtle.importKey('raw', key, 'PBKDF2', false, ['deriveBits']);
@@ -16,12 +16,12 @@ function getCryptoKey(key, alg) {
16
16
  }
17
17
  throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'Uint8Array'));
18
18
  }
19
- export const encrypt = async (alg, key, cek, p2c = Math.floor(Math.random() * 2049) + 2048, p2s = random(new Uint8Array(16))) => {
19
+ async function deriveKey(p2s, alg, p2c, key) {
20
20
  checkP2s(p2s);
21
21
  const salt = concatSalt(alg, p2s);
22
22
  const keylen = parseInt(alg.substr(13, 3), 10);
23
23
  const subtleAlg = {
24
- hash: { name: `SHA-${alg.substr(8, 3)}` },
24
+ hash: `SHA-${alg.substr(8, 3)}`,
25
25
  iterations: p2c,
26
26
  name: 'PBKDF2',
27
27
  salt,
@@ -31,43 +31,20 @@ export const encrypt = async (alg, key, cek, p2c = Math.floor(Math.random() * 20
31
31
  name: 'AES-KW',
32
32
  };
33
33
  const cryptoKey = await getCryptoKey(key, alg);
34
- let derived;
35
34
  if (cryptoKey.usages.includes('deriveBits')) {
36
- derived = new Uint8Array(await crypto.subtle.deriveBits(subtleAlg, cryptoKey, keylen));
37
- }
38
- else if (cryptoKey.usages.includes('deriveKey')) {
39
- derived = await crypto.subtle.deriveKey(subtleAlg, cryptoKey, wrapAlg, false, ['wrapKey']);
35
+ return new Uint8Array(await crypto.subtle.deriveBits(subtleAlg, cryptoKey, keylen));
40
36
  }
41
- else {
42
- throw new TypeError('PBKDF2 key "usages" must include "deriveBits" or "deriveKey"');
37
+ if (cryptoKey.usages.includes('deriveKey')) {
38
+ return crypto.subtle.deriveKey(subtleAlg, cryptoKey, wrapAlg, false, ['wrapKey', 'unwrapKey']);
43
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);
44
44
  const encryptedKey = await wrap(alg.substr(-6), derived, cek);
45
45
  return { encryptedKey, p2c, p2s: base64url(p2s) };
46
46
  };
47
47
  export const decrypt = async (alg, key, encryptedKey, p2c, p2s) => {
48
- checkP2s(p2s);
49
- const salt = concatSalt(alg, p2s);
50
- const keylen = parseInt(alg.substr(13, 3), 10);
51
- const subtleAlg = {
52
- hash: { name: `SHA-${alg.substr(8, 3)}` },
53
- iterations: p2c,
54
- name: 'PBKDF2',
55
- salt,
56
- };
57
- const wrapAlg = {
58
- length: keylen,
59
- name: 'AES-KW',
60
- };
61
- const cryptoKey = await getCryptoKey(key, alg);
62
- let derived;
63
- if (cryptoKey.usages.includes('deriveBits')) {
64
- derived = new Uint8Array(await crypto.subtle.deriveBits(subtleAlg, cryptoKey, keylen));
65
- }
66
- else if (cryptoKey.usages.includes('deriveKey')) {
67
- derived = await crypto.subtle.deriveKey(subtleAlg, cryptoKey, wrapAlg, false, ['unwrapKey']);
68
- }
69
- else {
70
- throw new TypeError('PBKDF2 key "usages" must include "deriveBits" or "deriveKey"');
71
- }
48
+ const derived = await deriveKey(p2s, alg, p2c, key);
72
49
  return unwrap(alg.substr(-6), derived, encryptedKey);
73
50
  };
@@ -3,7 +3,7 @@ import bogusWebCrypto from './bogus.js';
3
3
  import crypto, { isCryptoKey } from './webcrypto.js';
4
4
  import { checkEncCryptoKey } from '../lib/crypto_key.js';
5
5
  import checkKeyLength from './check_key_length.js';
6
- import invalidKeyInput from './invalid_key_input.js';
6
+ import invalidKeyInput from '../lib/invalid_key_input.js';
7
7
  export const encrypt = async (alg, key, cek) => {
8
8
  if (!isCryptoKey(key)) {
9
9
  throw new TypeError(invalidKeyInput(key, 'CryptoKey'));