jose 3.17.0 → 3.20.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.
Files changed (103) hide show
  1. package/README.md +10 -3
  2. package/dist/browser/jwe/compact/decrypt.js +5 -1
  3. package/dist/browser/jwe/flattened/decrypt.js +5 -0
  4. package/dist/browser/jwk/embedded.js +3 -3
  5. package/dist/browser/jwk/from_key_like.js +2 -2
  6. package/dist/browser/jwk/parse.js +2 -31
  7. package/dist/browser/jwks/remote.js +7 -10
  8. package/dist/browser/jws/compact/verify.js +5 -1
  9. package/dist/browser/jws/flattened/verify.js +5 -0
  10. package/dist/browser/jwt/decrypt.js +5 -1
  11. package/dist/browser/jwt/encrypt.js +1 -1
  12. package/dist/browser/{lib/jwt_producer.js → jwt/produce.js} +4 -4
  13. package/dist/browser/jwt/sign.js +1 -1
  14. package/dist/browser/jwt/unsecured.js +1 -1
  15. package/dist/browser/jwt/verify.js +5 -1
  16. package/dist/browser/key/export.js +12 -0
  17. package/dist/browser/key/import.js +119 -0
  18. package/dist/browser/lib/check_key_type.js +33 -16
  19. package/dist/browser/lib/decrypt_key_management.js +37 -37
  20. package/dist/browser/lib/encrypt_key_management.js +2 -2
  21. package/dist/browser/lib/format_pem.js +4 -0
  22. package/dist/browser/runtime/asn1.js +119 -0
  23. package/dist/browser/runtime/base64url.js +12 -7
  24. package/dist/browser/runtime/fetch_jwks.js +18 -5
  25. package/dist/browser/runtime/is_key_like.js +5 -0
  26. package/dist/browser/util/errors.js +10 -3
  27. package/dist/node/cjs/jwe/compact/decrypt.js +5 -1
  28. package/dist/node/cjs/jwe/flattened/decrypt.js +5 -0
  29. package/dist/node/cjs/jwk/embedded.js +3 -3
  30. package/dist/node/cjs/jwk/from_key_like.js +2 -2
  31. package/dist/node/cjs/jwk/parse.js +2 -31
  32. package/dist/node/cjs/jwks/remote.js +7 -10
  33. package/dist/node/cjs/jws/compact/verify.js +5 -1
  34. package/dist/node/cjs/jws/flattened/verify.js +5 -0
  35. package/dist/node/cjs/jwt/decrypt.js +5 -1
  36. package/dist/node/cjs/jwt/encrypt.js +2 -2
  37. package/dist/node/cjs/{lib/jwt_producer.js → jwt/produce.js} +5 -4
  38. package/dist/node/cjs/jwt/sign.js +2 -2
  39. package/dist/node/cjs/jwt/unsecured.js +2 -2
  40. package/dist/node/cjs/jwt/verify.js +5 -1
  41. package/dist/node/cjs/key/export.js +18 -0
  42. package/dist/node/cjs/key/import.js +126 -0
  43. package/dist/node/cjs/lib/check_key_type.js +33 -16
  44. package/dist/node/cjs/lib/decrypt_key_management.js +37 -37
  45. package/dist/node/cjs/lib/encrypt_key_management.js +2 -2
  46. package/dist/node/cjs/lib/format_pem.js +6 -0
  47. package/dist/node/cjs/runtime/asn1.js +46 -0
  48. package/dist/node/cjs/runtime/base64url.js +5 -1
  49. package/dist/node/cjs/runtime/fetch_jwks.js +5 -1
  50. package/dist/node/cjs/runtime/is_key_like.js +11 -0
  51. package/dist/node/cjs/util/errors.js +12 -4
  52. package/dist/node/esm/jwe/compact/decrypt.js +5 -1
  53. package/dist/node/esm/jwe/flattened/decrypt.js +5 -0
  54. package/dist/node/esm/jwk/embedded.js +3 -3
  55. package/dist/node/esm/jwk/from_key_like.js +2 -2
  56. package/dist/node/esm/jwk/parse.js +2 -31
  57. package/dist/node/esm/jwks/remote.js +7 -10
  58. package/dist/node/esm/jws/compact/verify.js +5 -1
  59. package/dist/node/esm/jws/flattened/verify.js +5 -0
  60. package/dist/node/esm/jwt/decrypt.js +5 -1
  61. package/dist/node/esm/jwt/encrypt.js +1 -1
  62. package/dist/node/esm/{lib/jwt_producer.js → jwt/produce.js} +4 -4
  63. package/dist/node/esm/jwt/sign.js +1 -1
  64. package/dist/node/esm/jwt/unsecured.js +1 -1
  65. package/dist/node/esm/jwt/verify.js +5 -1
  66. package/dist/node/esm/key/export.js +12 -0
  67. package/dist/node/esm/key/import.js +119 -0
  68. package/dist/node/esm/lib/check_key_type.js +33 -16
  69. package/dist/node/esm/lib/decrypt_key_management.js +37 -37
  70. package/dist/node/esm/lib/encrypt_key_management.js +2 -2
  71. package/dist/node/esm/lib/format_pem.js +4 -0
  72. package/dist/node/esm/runtime/asn1.js +39 -0
  73. package/dist/node/esm/runtime/base64url.js +2 -0
  74. package/dist/node/esm/runtime/fetch_jwks.js +6 -2
  75. package/dist/node/esm/runtime/is_key_like.js +8 -0
  76. package/dist/node/esm/util/errors.js +10 -3
  77. package/dist/types/jwe/compact/decrypt.d.ts +3 -2
  78. package/dist/types/jwe/compact/encrypt.d.ts +1 -1
  79. package/dist/types/jwe/flattened/decrypt.d.ts +3 -2
  80. package/dist/types/jwe/flattened/encrypt.d.ts +1 -1
  81. package/dist/types/jwe/general/decrypt.d.ts +3 -2
  82. package/dist/types/jwk/embedded.d.ts +2 -3
  83. package/dist/types/jwk/from_key_like.d.ts +1 -1
  84. package/dist/types/jwk/parse.d.ts +1 -1
  85. package/dist/types/jws/compact/sign.d.ts +1 -1
  86. package/dist/types/jws/compact/verify.d.ts +3 -2
  87. package/dist/types/jws/flattened/sign.d.ts +1 -1
  88. package/dist/types/jws/flattened/verify.d.ts +3 -2
  89. package/dist/types/jws/general/sign.d.ts +1 -1
  90. package/dist/types/jws/general/verify.d.ts +3 -2
  91. package/dist/types/jwt/decrypt.d.ts +3 -2
  92. package/dist/types/jwt/encrypt.d.ts +2 -2
  93. package/dist/types/{lib/jwt_producer.d.ts → jwt/produce.d.ts} +1 -1
  94. package/dist/types/jwt/sign.d.ts +2 -2
  95. package/dist/types/jwt/unsecured.d.ts +1 -1
  96. package/dist/types/jwt/verify.d.ts +3 -2
  97. package/dist/types/key/export.d.ts +5 -0
  98. package/dist/types/key/import.d.ts +9 -0
  99. package/dist/types/types.d.ts +101 -5
  100. package/dist/types/util/errors.d.ts +5 -0
  101. package/dist/types/util/generate_key_pair.d.ts +2 -2
  102. package/dist/types/util/generate_secret.d.ts +1 -1
  103. package/package.json +20 -8
@@ -1,30 +1,47 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const invalid_key_input_js_1 = require("../runtime/invalid_key_input.js");
4
- const checkKeyType = (alg, key, usage) => {
5
- if (!(key instanceof Uint8Array) && !(key === null || key === void 0 ? void 0 : key.type)) {
6
- throw new TypeError((0, invalid_key_input_js_1.default)(key, 'KeyObject', 'CryptoKey', 'Uint8Array'));
4
+ const is_key_like_js_1 = require("../runtime/is_key_like.js");
5
+ const symmetricTypeCheck = (key) => {
6
+ if (key instanceof Uint8Array)
7
+ return;
8
+ if (!(0, is_key_like_js_1.default)(key)) {
9
+ throw new TypeError((0, invalid_key_input_js_1.default)(key, ...is_key_like_js_1.types, 'Uint8Array'));
7
10
  }
8
- if (alg.startsWith('HS') ||
9
- alg === 'dir' ||
10
- alg.startsWith('PBES2') ||
11
- alg.match(/^A\d{3}(?:GCM)?KW$/)) {
12
- if (key instanceof Uint8Array || key.type === 'secret') {
13
- return;
14
- }
15
- throw new TypeError('CryptoKey or KeyObject instances for symmetric algorithms must be of type "secret"');
11
+ if (key.type !== 'secret') {
12
+ throw new TypeError(`${is_key_like_js_1.types.join(' or ')} instances for symmetric algorithms must be of type "secret"`);
16
13
  }
17
- if (key instanceof Uint8Array) {
18
- throw new TypeError((0, invalid_key_input_js_1.default)(key, 'KeyObject', 'CryptoKey'));
14
+ };
15
+ const asymmetricTypeCheck = (key, usage) => {
16
+ if (!(0, is_key_like_js_1.default)(key)) {
17
+ throw new TypeError((0, invalid_key_input_js_1.default)(key, ...is_key_like_js_1.types));
19
18
  }
20
19
  if (key.type === 'secret') {
21
- throw new TypeError('CryptoKey or KeyObject instances for asymmetric algorithms must not be of type "secret"');
20
+ throw new TypeError(`${is_key_like_js_1.types.join(' or ')} instances for asymmetric algorithms must not be of type "secret"`);
22
21
  }
23
22
  if (usage === 'sign' && key.type === 'public') {
24
- throw new TypeError('CryptoKey or KeyObject instances for asymmetric algorithm signing must be of type "private"');
23
+ throw new TypeError(`${is_key_like_js_1.types.join(' or ')} instances for asymmetric algorithm signing must be of type "private"`);
25
24
  }
26
25
  if (usage === 'decrypt' && key.type === 'public') {
27
- throw new TypeError('CryptoKey or KeyObject instances for asymmetric algorithm decryption must be of type "private"');
26
+ throw new TypeError(`${is_key_like_js_1.types.join(' or ')} instances for asymmetric algorithm decryption must be of type "private"`);
27
+ }
28
+ if (key.algorithm && usage === 'verify' && key.type === 'private') {
29
+ throw new TypeError(`${is_key_like_js_1.types.join(' or ')} instances for asymmetric algorithm verifying must be of type "public"`);
30
+ }
31
+ if (key.algorithm && usage === 'encrypt' && key.type === 'private') {
32
+ throw new TypeError(`${is_key_like_js_1.types.join(' or ')} instances for asymmetric algorithm encryption must be of type "public"`);
33
+ }
34
+ };
35
+ const checkKeyType = (alg, key, usage) => {
36
+ const symmetric = alg.startsWith('HS') ||
37
+ alg === 'dir' ||
38
+ alg.startsWith('PBES2') ||
39
+ /^A\d{3}(?:GCM)?KW$/.test(alg);
40
+ if (symmetric) {
41
+ symmetricTypeCheck(key);
42
+ }
43
+ else {
44
+ asymmetricTypeCheck(key, usage);
28
45
  }
29
46
  };
30
47
  exports.default = checkKeyType;
@@ -8,83 +8,83 @@ const aesgcmkw_js_1 = require("../runtime/aesgcmkw.js");
8
8
  const base64url_js_1 = require("../runtime/base64url.js");
9
9
  const errors_js_1 = require("../util/errors.js");
10
10
  const cek_js_1 = require("../lib/cek.js");
11
- const parse_js_1 = require("../jwk/parse.js");
11
+ const import_js_1 = require("../key/import.js");
12
12
  const check_key_type_js_1 = require("./check_key_type.js");
13
- function assertEnryptedKey(encryptedKey) {
14
- if (!encryptedKey) {
15
- throw new errors_js_1.JWEInvalid('JWE Encrypted Key missing');
16
- }
17
- }
18
- function assertHeaderParameter(joseHeader, parameter, name) {
19
- if (joseHeader[parameter] === undefined) {
20
- throw new errors_js_1.JWEInvalid(`JOSE Header ${name} (${parameter}) missing`);
21
- }
22
- }
13
+ const is_object_js_1 = require("./is_object.js");
23
14
  async function decryptKeyManagement(alg, key, encryptedKey, joseHeader) {
24
15
  (0, check_key_type_js_1.default)(alg, key, 'decrypt');
25
16
  switch (alg) {
26
17
  case 'dir': {
27
- if (encryptedKey !== undefined) {
18
+ if (encryptedKey !== undefined)
28
19
  throw new errors_js_1.JWEInvalid('Encountered unexpected JWE Encrypted Key');
29
- }
30
20
  return key;
31
21
  }
32
22
  case 'ECDH-ES':
33
- if (encryptedKey !== undefined) {
23
+ if (encryptedKey !== undefined)
34
24
  throw new errors_js_1.JWEInvalid('Encountered unexpected JWE Encrypted Key');
35
- }
36
25
  case 'ECDH-ES+A128KW':
37
26
  case 'ECDH-ES+A192KW':
38
27
  case 'ECDH-ES+A256KW': {
39
- assertHeaderParameter(joseHeader, 'epk', 'Ephemeral Public Key');
40
- if (!ECDH.ecdhAllowed(key)) {
28
+ if (!(0, is_object_js_1.default)(joseHeader.epk))
29
+ throw new errors_js_1.JWEInvalid(`JOSE Header "epk" (Ephemeral Public Key) missing or invalid`);
30
+ if (!ECDH.ecdhAllowed(key))
41
31
  throw new errors_js_1.JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
42
- }
43
- const epk = await (0, parse_js_1.parseJwk)(joseHeader.epk, alg);
32
+ const epk = await (0, import_js_1.importJWK)(joseHeader.epk, alg);
44
33
  let partyUInfo;
45
34
  let partyVInfo;
46
- if (joseHeader.apu !== undefined)
35
+ if (joseHeader.apu !== undefined) {
36
+ if (typeof joseHeader.apu !== 'string')
37
+ throw new errors_js_1.JWEInvalid(`JOSE Header "apu" (Agreement PartyUInfo) invalid`);
47
38
  partyUInfo = (0, base64url_js_1.decode)(joseHeader.apu);
48
- if (joseHeader.apv !== undefined)
39
+ }
40
+ if (joseHeader.apv !== undefined) {
41
+ if (typeof joseHeader.apv !== 'string')
42
+ throw new errors_js_1.JWEInvalid(`JOSE Header "apv" (Agreement PartyVInfo) invalid`);
49
43
  partyVInfo = (0, base64url_js_1.decode)(joseHeader.apv);
44
+ }
50
45
  const sharedSecret = await ECDH.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, parseInt(alg.substr(-5, 3), 10) || cek_js_1.bitLengths.get(joseHeader.enc), partyUInfo, partyVInfo);
51
- if (alg === 'ECDH-ES') {
46
+ if (alg === 'ECDH-ES')
52
47
  return sharedSecret;
53
- }
54
- assertEnryptedKey(encryptedKey);
55
- const kwAlg = alg.substr(-6);
56
- return (0, aeskw_js_1.unwrap)(kwAlg, sharedSecret, encryptedKey);
48
+ if (encryptedKey === undefined)
49
+ throw new errors_js_1.JWEInvalid('JWE Encrypted Key missing');
50
+ return (0, aeskw_js_1.unwrap)(alg.substr(-6), sharedSecret, encryptedKey);
57
51
  }
58
52
  case 'RSA1_5':
59
53
  case 'RSA-OAEP':
60
54
  case 'RSA-OAEP-256':
61
55
  case 'RSA-OAEP-384':
62
56
  case 'RSA-OAEP-512': {
63
- assertEnryptedKey(encryptedKey);
57
+ if (encryptedKey === undefined)
58
+ throw new errors_js_1.JWEInvalid('JWE Encrypted Key missing');
64
59
  return (0, rsaes_js_1.decrypt)(alg, key, encryptedKey);
65
60
  }
66
61
  case 'PBES2-HS256+A128KW':
67
62
  case 'PBES2-HS384+A192KW':
68
63
  case 'PBES2-HS512+A256KW': {
69
- assertEnryptedKey(encryptedKey);
70
- assertHeaderParameter(joseHeader, 'p2c', 'PBES2 Count');
71
- assertHeaderParameter(joseHeader, 'p2s', 'PBES2 Salt');
72
- const { p2c } = joseHeader;
73
- const p2s = (0, base64url_js_1.decode)(joseHeader.p2s);
74
- return (0, pbes2kw_js_1.decrypt)(alg, key, encryptedKey, p2c, p2s);
64
+ if (encryptedKey === undefined)
65
+ throw new errors_js_1.JWEInvalid('JWE Encrypted Key missing');
66
+ if (typeof joseHeader.p2c !== 'number')
67
+ throw new errors_js_1.JWEInvalid(`JOSE Header "p2c" (PBES2 Count) missing or invalid`);
68
+ if (typeof joseHeader.p2s !== 'string')
69
+ throw new errors_js_1.JWEInvalid(`JOSE Header "p2s" (PBES2 Salt) missing or invalid`);
70
+ return (0, pbes2kw_js_1.decrypt)(alg, key, encryptedKey, joseHeader.p2c, (0, base64url_js_1.decode)(joseHeader.p2s));
75
71
  }
76
72
  case 'A128KW':
77
73
  case 'A192KW':
78
74
  case 'A256KW': {
79
- assertEnryptedKey(encryptedKey);
75
+ if (encryptedKey === undefined)
76
+ throw new errors_js_1.JWEInvalid('JWE Encrypted Key missing');
80
77
  return (0, aeskw_js_1.unwrap)(alg, key, encryptedKey);
81
78
  }
82
79
  case 'A128GCMKW':
83
80
  case 'A192GCMKW':
84
81
  case 'A256GCMKW': {
85
- assertEnryptedKey(encryptedKey);
86
- assertHeaderParameter(joseHeader, 'iv', 'Initialization Vector');
87
- assertHeaderParameter(joseHeader, 'tag', 'Authentication Tag');
82
+ if (encryptedKey === undefined)
83
+ throw new errors_js_1.JWEInvalid('JWE Encrypted Key missing');
84
+ if (typeof joseHeader.iv !== 'string')
85
+ throw new errors_js_1.JWEInvalid(`JOSE Header "iv" (Initialization Vector) missing or invalid`);
86
+ if (typeof joseHeader.tag !== 'string')
87
+ throw new errors_js_1.JWEInvalid(`JOSE Header "tag" (Authentication Tag) missing or invalid`);
88
88
  const iv = (0, base64url_js_1.decode)(joseHeader.iv);
89
89
  const tag = (0, base64url_js_1.decode)(joseHeader.tag);
90
90
  return (0, aesgcmkw_js_1.unwrap)(alg, key, encryptedKey, iv, tag);
@@ -9,7 +9,7 @@ const aesgcmkw_js_1 = require("../runtime/aesgcmkw.js");
9
9
  const base64url_js_1 = require("../runtime/base64url.js");
10
10
  const cek_js_1 = require("../lib/cek.js");
11
11
  const errors_js_1 = require("../util/errors.js");
12
- const from_key_like_js_1 = require("../jwk/from_key_like.js");
12
+ const export_js_1 = require("../key/export.js");
13
13
  const check_key_type_js_1 = require("./check_key_type.js");
14
14
  const generateCek = (0, cek_js_1.default)(random_js_1.default);
15
15
  async function encryptKeyManagement(alg, enc, key, providedCek, providedParameters = {}) {
@@ -32,7 +32,7 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
32
32
  const { apu, apv } = providedParameters;
33
33
  let { epk: ephemeralKey } = providedParameters;
34
34
  ephemeralKey || (ephemeralKey = await ECDH.generateEpk(key));
35
- const { x, y, crv, kty } = await (0, from_key_like_js_1.fromKeyLike)(ephemeralKey);
35
+ const { x, y, crv, kty } = await (0, export_js_1.exportJWK)(ephemeralKey);
36
36
  const sharedSecret = await ECDH.deriveKey(key, ephemeralKey, alg === 'ECDH-ES' ? enc : alg, parseInt(alg.substr(-5, 3), 10) || cek_js_1.bitLengths.get(enc), apu, apv);
37
37
  parameters = { epk: { x, y, crv, kty } };
38
38
  if (apu)
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = (b64, descriptor) => {
4
+ const newlined = (b64.match(/.{1,64}/g) || []).join('\n');
5
+ return `-----BEGIN ${descriptor}-----\n${newlined}\n-----END ${descriptor}-----`;
6
+ };
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fromSPKI = exports.fromPKCS8 = exports.toPKCS8 = exports.toSPKI = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const webcrypto_js_1 = require("./webcrypto.js");
6
+ const is_key_object_js_1 = require("./is_key_object.js");
7
+ const invalid_key_input_js_1 = require("./invalid_key_input.js");
8
+ const genericExport = (keyType, keyFormat, key) => {
9
+ let keyObject;
10
+ if ((0, webcrypto_js_1.isCryptoKey)(key)) {
11
+ if (!key.extractable) {
12
+ throw new TypeError('CryptoKey is not extractable');
13
+ }
14
+ keyObject = (0, webcrypto_js_1.getKeyObject)(key);
15
+ }
16
+ else if ((0, is_key_object_js_1.default)(key)) {
17
+ keyObject = key;
18
+ }
19
+ else {
20
+ throw new TypeError((0, invalid_key_input_js_1.default)(key, 'KeyObject', 'CryptoKey'));
21
+ }
22
+ if (keyObject.type !== keyType) {
23
+ throw new TypeError(`key is not a ${keyType} key`);
24
+ }
25
+ return keyObject.export({ format: 'pem', type: keyFormat });
26
+ };
27
+ const toSPKI = (key) => {
28
+ return genericExport('public', 'spki', key);
29
+ };
30
+ exports.toSPKI = toSPKI;
31
+ const toPKCS8 = (key) => {
32
+ return genericExport('private', 'pkcs8', key);
33
+ };
34
+ exports.toPKCS8 = toPKCS8;
35
+ const fromPKCS8 = (pem) => (0, crypto_1.createPrivateKey)({
36
+ key: Buffer.from(pem.replace(/(?:-----(?:BEGIN|END) PRIVATE KEY-----|\s)/g, ''), 'base64'),
37
+ type: 'pkcs8',
38
+ format: 'der',
39
+ });
40
+ exports.fromPKCS8 = fromPKCS8;
41
+ const fromSPKI = (pem) => (0, crypto_1.createPublicKey)({
42
+ key: Buffer.from(pem.replace(/(?:-----(?:BEGIN|END) PUBLIC KEY-----|\s)/g, ''), 'base64'),
43
+ type: 'spki',
44
+ format: 'der',
45
+ });
46
+ exports.fromSPKI = fromSPKI;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.decode = exports.encode = void 0;
3
+ exports.decode = exports.encode = exports.encodeBase64 = exports.decodeBase64 = void 0;
4
4
  const buffer_utils_js_1 = require("../lib/buffer_utils.js");
5
5
  let encodeImpl;
6
6
  function normalize(input) {
@@ -16,6 +16,10 @@ if (Buffer.isEncoding('base64url')) {
16
16
  else {
17
17
  encodeImpl = (input) => Buffer.from(input).toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
18
18
  }
19
+ const decodeBase64 = (input) => Buffer.from(input, 'base64');
20
+ exports.decodeBase64 = decodeBase64;
21
+ const encodeBase64 = (input) => Buffer.from(input).toString('base64');
22
+ exports.encodeBase64 = encodeBase64;
19
23
  exports.encode = encodeImpl;
20
24
  const decode = (input) => Buffer.from(normalize(input), 'base64');
21
25
  exports.decode = decode;
@@ -18,7 +18,11 @@ const fetchJwks = async (url, timeout, options) => {
18
18
  agent,
19
19
  timeout,
20
20
  });
21
- const [response] = await (0, events_1.once)(req, 'response');
21
+ const [response] = (await Promise.race([(0, events_1.once)(req, 'response'), (0, events_1.once)(req, 'timeout')]));
22
+ if (!response) {
23
+ req.destroy();
24
+ throw new errors_js_1.JWKSTimeout();
25
+ }
22
26
  if (response.statusCode !== 200) {
23
27
  throw new errors_js_1.JOSEError('Expected 200 OK from the JSON Web Key Set HTTP response');
24
28
  }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.types = void 0;
4
+ const webcrypto_js_1 = require("./webcrypto.js");
5
+ const is_key_object_js_1 = require("./is_key_object.js");
6
+ exports.default = (key) => (0, is_key_object_js_1.default)(key) || (0, webcrypto_js_1.isCryptoKey)(key);
7
+ const types = ['KeyObject'];
8
+ exports.types = types;
9
+ if (parseInt(process.versions.node) >= 16) {
10
+ types.push('CryptoKey');
11
+ }
@@ -1,14 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.JWTExpired = exports.JWSSignatureVerificationFailed = exports.JWKSMultipleMatchingKeys = exports.JWKSNoMatchingKey = exports.JWKSInvalid = exports.JWKInvalid = exports.JWTInvalid = exports.JWSInvalid = exports.JWEInvalid = exports.JWEDecryptionFailed = exports.JOSENotSupported = exports.JOSEAlgNotAllowed = exports.JWTClaimValidationFailed = exports.JOSEError = void 0;
3
+ exports.JWTExpired = exports.JWSSignatureVerificationFailed = exports.JWKSTimeout = exports.JWKSMultipleMatchingKeys = exports.JWKSNoMatchingKey = exports.JWKSInvalid = exports.JWKInvalid = exports.JWTInvalid = exports.JWSInvalid = exports.JWEInvalid = exports.JWEDecryptionFailed = exports.JOSENotSupported = exports.JOSEAlgNotAllowed = exports.JWTClaimValidationFailed = exports.JOSEError = void 0;
4
4
  class JOSEError extends Error {
5
5
  constructor(message) {
6
+ var _a;
6
7
  super(message);
7
8
  this.code = JOSEError.code;
8
9
  this.name = this.constructor.name;
9
- if (Error.captureStackTrace) {
10
- Error.captureStackTrace(this, this.constructor);
11
- }
10
+ (_a = Error.captureStackTrace) === null || _a === void 0 ? void 0 : _a.call(Error, this, this.constructor);
12
11
  }
13
12
  }
14
13
  exports.JOSEError = JOSEError;
@@ -106,6 +105,15 @@ class JWKSMultipleMatchingKeys extends JOSEError {
106
105
  }
107
106
  exports.JWKSMultipleMatchingKeys = JWKSMultipleMatchingKeys;
108
107
  JWKSMultipleMatchingKeys.code = 'ERR_JWKS_MULTIPLE_MATCHING_KEYS';
108
+ class JWKSTimeout extends JOSEError {
109
+ constructor() {
110
+ super(...arguments);
111
+ this.code = JWKSTimeout.code;
112
+ this.message = 'request timed out';
113
+ }
114
+ }
115
+ exports.JWKSTimeout = JWKSTimeout;
116
+ JWKSTimeout.code = 'ERR_JWKS_TIMEOUT';
109
117
  class JWSSignatureVerificationFailed extends JOSEError {
110
118
  constructor() {
111
119
  super(...arguments);
@@ -19,7 +19,11 @@ async function compactDecrypt(jwe, key, options) {
19
19
  tag: (tag || undefined),
20
20
  encrypted_key: encryptedKey || undefined,
21
21
  }, key, options);
22
- return { plaintext: decrypted.plaintext, protectedHeader: decrypted.protectedHeader };
22
+ const result = { plaintext: decrypted.plaintext, protectedHeader: decrypted.protectedHeader };
23
+ if (typeof key === 'function') {
24
+ return { ...result, key: decrypted.key };
25
+ }
26
+ return result;
23
27
  }
24
28
  export { compactDecrypt };
25
29
  export default compactDecrypt;
@@ -92,8 +92,10 @@ async function flattenedDecrypt(jwe, key, options) {
92
92
  if (jwe.encrypted_key !== undefined) {
93
93
  encryptedKey = base64url(jwe.encrypted_key);
94
94
  }
95
+ let resolvedKey = false;
95
96
  if (typeof key === 'function') {
96
97
  key = await key(parsedProt, jwe);
98
+ resolvedKey = true;
97
99
  }
98
100
  let cek;
99
101
  try {
@@ -132,6 +134,9 @@ async function flattenedDecrypt(jwe, key, options) {
132
134
  if (jwe.header !== undefined) {
133
135
  result.unprotectedHeader = jwe.header;
134
136
  }
137
+ if (resolvedKey) {
138
+ return { ...result, key };
139
+ }
135
140
  return result;
136
141
  }
137
142
  export { flattenedDecrypt };
@@ -1,4 +1,4 @@
1
- import parseJwk from './parse.js';
1
+ import { importJWK } from '../key/import.js';
2
2
  import isObject from '../lib/is_object.js';
3
3
  import { JWSInvalid } from '../util/errors.js';
4
4
  async function EmbeddedJWK(protectedHeader, token) {
@@ -9,8 +9,8 @@ async function EmbeddedJWK(protectedHeader, token) {
9
9
  if (!isObject(joseHeader.jwk)) {
10
10
  throw new JWSInvalid('"jwk" (JSON Web Key) Header Parameter must be a JSON object');
11
11
  }
12
- const key = await parseJwk(joseHeader.jwk, joseHeader.alg, true);
13
- if (key.type !== 'public') {
12
+ const key = await importJWK({ ...joseHeader.jwk, ext: true }, joseHeader.alg, true);
13
+ if (key instanceof Uint8Array || key.type !== 'public') {
14
14
  throw new JWSInvalid('"jwk" (JSON Web Key) Header Parameter must be a public key');
15
15
  }
16
16
  return key;
@@ -1,6 +1,6 @@
1
- import asJWK from '../runtime/key_to_jwk.js';
1
+ import { exportJWK } from '../key/export.js';
2
2
  async function fromKeyLike(key) {
3
- return asJWK(key);
3
+ return exportJWK(key);
4
4
  }
5
5
  export { fromKeyLike };
6
6
  export default fromKeyLike;
@@ -1,35 +1,6 @@
1
- import { decode as base64url } from '../runtime/base64url.js';
2
- import asKeyObject from '../runtime/jwk_to_key.js';
3
- import { JOSENotSupported } from '../util/errors.js';
4
- import isObject from '../lib/is_object.js';
1
+ import { importJWK } from '../key/import.js';
5
2
  async function parseJwk(jwk, alg, octAsKeyObject) {
6
- if (!isObject(jwk)) {
7
- throw new TypeError('JWK must be an object');
8
- }
9
- alg || (alg = jwk.alg);
10
- if (typeof alg !== 'string' || !alg) {
11
- throw new TypeError('"alg" argument is required when "jwk.alg" is not present');
12
- }
13
- switch (jwk.kty) {
14
- case 'oct':
15
- if (typeof jwk.k !== 'string' || !jwk.k) {
16
- throw new TypeError('missing "k" (Key Value) Parameter value');
17
- }
18
- octAsKeyObject !== null && octAsKeyObject !== void 0 ? octAsKeyObject : (octAsKeyObject = jwk.ext !== true);
19
- if (octAsKeyObject) {
20
- return asKeyObject({ ...jwk, alg, ext: false });
21
- }
22
- return base64url(jwk.k);
23
- case 'RSA':
24
- if (jwk.oth !== undefined) {
25
- throw new JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is not supported');
26
- }
27
- case 'EC':
28
- case 'OKP':
29
- return asKeyObject({ ...jwk, alg });
30
- default:
31
- throw new JOSENotSupported('Unsupported "kty" (Key Type) Parameter value');
32
- }
3
+ return importJWK(jwk, alg, octAsKeyObject);
33
4
  }
34
5
  export { parseJwk };
35
6
  export default parseJwk;
@@ -1,9 +1,9 @@
1
1
  import fetchJwks from '../runtime/fetch_jwks.js';
2
- import parseJWK from '../jwk/parse.js';
2
+ import { importJWK } from '../key/import.js';
3
3
  import { JWKSInvalid, JOSENotSupported, JWKSNoMatchingKey, JWKSMultipleMatchingKeys, } from '../util/errors.js';
4
4
  import isObject from '../lib/is_object.js';
5
5
  function getKtyFromAlg(alg) {
6
- switch (alg.substr(0, 2)) {
6
+ switch (typeof alg === 'string' && alg.substr(0, 2)) {
7
7
  case 'RS':
8
8
  case 'PS':
9
9
  return 'RSA';
@@ -32,7 +32,7 @@ class RemoteJWKSet {
32
32
  typeof (options === null || options === void 0 ? void 0 : options.cooldownDuration) === 'number' ? options === null || options === void 0 ? void 0 : options.cooldownDuration : 30000;
33
33
  }
34
34
  coolingDown() {
35
- if (typeof this._cooldownStarted === 'undefined') {
35
+ if (!this._cooldownStarted) {
36
36
  return false;
37
37
  }
38
38
  return Date.now() < this._cooldownStarted + this._cooldownDuration;
@@ -56,7 +56,7 @@ class RemoteJWKSet {
56
56
  candidate = jwk.key_ops.includes('verify');
57
57
  }
58
58
  if (candidate && protectedHeader.alg === 'EdDSA') {
59
- candidate = ['Ed25519', 'Ed448'].includes(jwk.crv);
59
+ candidate = jwk.crv === 'Ed25519' || jwk.crv === 'Ed448';
60
60
  }
61
61
  if (candidate) {
62
62
  switch (protectedHeader.alg) {
@@ -88,13 +88,10 @@ class RemoteJWKSet {
88
88
  else if (length !== 1) {
89
89
  throw new JWKSMultipleMatchingKeys();
90
90
  }
91
- if (!this._cached.has(jwk)) {
92
- this._cached.set(jwk, {});
93
- }
94
- const cached = this._cached.get(jwk);
91
+ const cached = this._cached.get(jwk) || this._cached.set(jwk, {}).get(jwk);
95
92
  if (cached[protectedHeader.alg] === undefined) {
96
- const keyObject = await parseJWK({ ...jwk, alg: protectedHeader.alg });
97
- if (keyObject.type !== 'public') {
93
+ const keyObject = await importJWK({ ...jwk, ext: true }, protectedHeader.alg);
94
+ if (keyObject instanceof Uint8Array || keyObject.type !== 'public') {
98
95
  throw new JWKSInvalid('JSON Web Key Set members must be public keys');
99
96
  }
100
97
  cached[protectedHeader.alg] = keyObject;
@@ -17,7 +17,11 @@ async function compactVerify(jws, key, options) {
17
17
  protected: protectedHeader || undefined,
18
18
  signature: (signature || undefined),
19
19
  }, key, options);
20
- return { payload: verified.payload, protectedHeader: verified.protectedHeader };
20
+ const result = { payload: verified.payload, protectedHeader: verified.protectedHeader };
21
+ if (typeof key === 'function') {
22
+ return { ...result, key: verified.key };
23
+ }
24
+ return result;
21
25
  }
22
26
  export { compactVerify };
23
27
  export default compactVerify;
@@ -70,8 +70,10 @@ async function flattenedVerify(jws, key, options) {
70
70
  else if (typeof jws.payload !== 'string' && !(jws.payload instanceof Uint8Array)) {
71
71
  throw new JWSInvalid('JWS Payload must be a string or an Uint8Array instance');
72
72
  }
73
+ let resolvedKey = false;
73
74
  if (typeof key === 'function') {
74
75
  key = await key(parsedProt, jws);
76
+ resolvedKey = true;
75
77
  }
76
78
  checkKeyType(alg, key, 'verify');
77
79
  const data = concat(encoder.encode((_a = jws.protected) !== null && _a !== void 0 ? _a : ''), encoder.encode('.'), typeof jws.payload === 'string' ? encoder.encode(jws.payload) : jws.payload);
@@ -97,6 +99,9 @@ async function flattenedVerify(jws, key, options) {
97
99
  if (jws.header !== undefined) {
98
100
  result.unprotectedHeader = jws.header;
99
101
  }
102
+ if (resolvedKey) {
103
+ return { ...result, key };
104
+ }
100
105
  return result;
101
106
  }
102
107
  export { flattenedVerify };
@@ -15,7 +15,11 @@ async function jwtDecrypt(jwt, key, options) {
15
15
  JSON.stringify(protectedHeader.aud) !== JSON.stringify(payload.aud)) {
16
16
  throw new JWTClaimValidationFailed('replicated "aud" claim header parameter mismatch', 'aud', 'mismatch');
17
17
  }
18
- return { payload, protectedHeader };
18
+ const result = { payload, protectedHeader };
19
+ if (typeof key === 'function') {
20
+ return { ...result, key: decrypted.key };
21
+ }
22
+ return result;
19
23
  }
20
24
  export { jwtDecrypt };
21
25
  export default jwtDecrypt;
@@ -1,6 +1,6 @@
1
1
  import CompactEncrypt from '../jwe/compact/encrypt.js';
2
2
  import { encoder } from '../lib/buffer_utils.js';
3
- import ProduceJWT from '../lib/jwt_producer.js';
3
+ import { ProduceJWT } from './produce.js';
4
4
  class EncryptJWT extends ProduceJWT {
5
5
  setProtectedHeader(protectedHeader) {
6
6
  if (this._protectedHeader) {
@@ -1,7 +1,7 @@
1
- import epoch from './epoch.js';
2
- import isObject from './is_object.js';
3
- import secs from './secs.js';
4
- export default class ProduceJWT {
1
+ import epoch from '../lib/epoch.js';
2
+ import isObject from '../lib/is_object.js';
3
+ import secs from '../lib/secs.js';
4
+ export class ProduceJWT {
5
5
  constructor(payload) {
6
6
  if (!isObject(payload)) {
7
7
  throw new TypeError('JWT Claims Set MUST be an object');
@@ -1,7 +1,7 @@
1
1
  import CompactSign from '../jws/compact/sign.js';
2
2
  import { JWTInvalid } from '../util/errors.js';
3
3
  import { encoder } from '../lib/buffer_utils.js';
4
- import ProduceJWT from '../lib/jwt_producer.js';
4
+ import { ProduceJWT } from './produce.js';
5
5
  class SignJWT extends ProduceJWT {
6
6
  setProtectedHeader(protectedHeader) {
7
7
  this._protectedHeader = protectedHeader;
@@ -2,7 +2,7 @@ import * as base64url from '../runtime/base64url.js';
2
2
  import { decoder } from '../lib/buffer_utils.js';
3
3
  import { JWTInvalid } from '../util/errors.js';
4
4
  import jwtPayload from '../lib/jwt_claims_set.js';
5
- import ProduceJWT from '../lib/jwt_producer.js';
5
+ import { ProduceJWT } from './produce.js';
6
6
  class UnsecuredJWT extends ProduceJWT {
7
7
  encode() {
8
8
  const header = base64url.encode(JSON.stringify({ alg: 'none' }));
@@ -8,7 +8,11 @@ async function jwtVerify(jwt, key, options) {
8
8
  throw new JWTInvalid('JWTs MUST NOT use unencoded payload');
9
9
  }
10
10
  const payload = jwtPayload(verified.protectedHeader, verified.payload, options);
11
- return { payload, protectedHeader: verified.protectedHeader };
11
+ const result = { payload, protectedHeader: verified.protectedHeader };
12
+ if (typeof key === 'function') {
13
+ return { ...result, key: verified.key };
14
+ }
15
+ return result;
12
16
  }
13
17
  export { jwtVerify };
14
18
  export default jwtVerify;
@@ -0,0 +1,12 @@
1
+ import { toSPKI as exportPublic } from '../runtime/asn1.js';
2
+ import { toPKCS8 as exportPrivate } from '../runtime/asn1.js';
3
+ import keyToJWK from '../runtime/key_to_jwk.js';
4
+ export async function exportSPKI(key) {
5
+ return exportPublic(key);
6
+ }
7
+ export async function exportPKCS8(key) {
8
+ return exportPrivate(key);
9
+ }
10
+ export async function exportJWK(key) {
11
+ return keyToJWK(key);
12
+ }