jose 6.2.10 → 6.2.11

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 (87) hide show
  1. package/dist/types/jwe/compact/decrypt.d.ts +7 -16
  2. package/dist/types/jwe/compact/encrypt.d.ts +6 -17
  3. package/dist/types/jwe/flattened/decrypt.d.ts +7 -16
  4. package/dist/types/jwe/flattened/encrypt.d.ts +11 -34
  5. package/dist/types/jwe/general/decrypt.d.ts +7 -16
  6. package/dist/types/jwe/general/encrypt.d.ts +15 -35
  7. package/dist/types/jwk/embedded.d.ts +3 -8
  8. package/dist/types/jwk/thumbprint.d.ts +5 -5
  9. package/dist/types/jwks/local.d.ts +6 -10
  10. package/dist/types/jwks/remote.d.ts +13 -24
  11. package/dist/types/jws/compact/sign.d.ts +5 -10
  12. package/dist/types/jws/compact/verify.d.ts +9 -18
  13. package/dist/types/jws/flattened/sign.d.ts +7 -16
  14. package/dist/types/jws/flattened/verify.d.ts +9 -18
  15. package/dist/types/jws/general/sign.d.ts +11 -21
  16. package/dist/types/jws/general/verify.d.ts +9 -18
  17. package/dist/types/jwt/decrypt.d.ts +10 -20
  18. package/dist/types/jwt/encrypt.d.ts +6 -13
  19. package/dist/types/jwt/sign.d.ts +5 -6
  20. package/dist/types/jwt/unsecured.d.ts +9 -14
  21. package/dist/types/jwt/verify.d.ts +9 -19
  22. package/dist/types/key/export.d.ts +4 -4
  23. package/dist/types/key/generate_key_pair.d.ts +6 -8
  24. package/dist/types/key/generate_secret.d.ts +4 -11
  25. package/dist/types/key/import.d.ts +10 -17
  26. package/dist/types/types.d.ts +44 -84
  27. package/dist/types/util/base64url.d.ts +2 -2
  28. package/dist/types/util/decode_jwt.d.ts +3 -10
  29. package/dist/types/util/decode_protected_header.d.ts +4 -4
  30. package/dist/types/util/errors.d.ts +26 -53
  31. package/dist/webapi/index.js +70 -32
  32. package/dist/webapi/jwe/compact/decrypt.js +7 -8
  33. package/dist/webapi/jwe/compact/encrypt.js +42 -48
  34. package/dist/webapi/jwe/flattened/decrypt.js +14 -14
  35. package/dist/webapi/jwe/flattened/encrypt.js +53 -64
  36. package/dist/webapi/jwe/general/decrypt.js +38 -49
  37. package/dist/webapi/jwe/general/encrypt.js +121 -169
  38. package/dist/webapi/jwk/embedded.js +30 -32
  39. package/dist/webapi/jwk/thumbprint.js +54 -70
  40. package/dist/webapi/jwks/local.js +47 -64
  41. package/dist/webapi/jwks/remote.js +88 -136
  42. package/dist/webapi/jws/compact/sign.js +21 -21
  43. package/dist/webapi/jws/compact/verify.js +7 -8
  44. package/dist/webapi/jws/flattened/sign.js +29 -31
  45. package/dist/webapi/jws/flattened/verify.js +21 -24
  46. package/dist/webapi/jws/general/sign.js +61 -72
  47. package/dist/webapi/jws/general/verify.js +45 -69
  48. package/dist/webapi/jwt/decrypt.js +13 -20
  49. package/dist/webapi/jwt/encrypt.js +57 -70
  50. package/dist/webapi/jwt/sign.js +17 -16
  51. package/dist/webapi/jwt/unsecured.js +32 -40
  52. package/dist/webapi/jwt/verify.js +12 -14
  53. package/dist/webapi/key/export.js +32 -37
  54. package/dist/webapi/key/generate_key_pair.js +40 -48
  55. package/dist/webapi/key/generate_secret.js +35 -40
  56. package/dist/webapi/key/import.js +52 -56
  57. package/dist/webapi/lib/asn1.js +130 -169
  58. package/dist/webapi/lib/base64.js +18 -20
  59. package/dist/webapi/lib/buffer_utils.js +34 -38
  60. package/dist/webapi/lib/content_encryption.js +79 -115
  61. package/dist/webapi/lib/crypto_key.js +24 -25
  62. package/dist/webapi/lib/deflate.js +45 -47
  63. package/dist/webapi/lib/helpers.js +40 -37
  64. package/dist/webapi/lib/invalid_key_input.js +10 -24
  65. package/dist/webapi/lib/is_key_like.js +17 -15
  66. package/dist/webapi/lib/jwe_algorithms.js +106 -93
  67. package/dist/webapi/lib/jwe_decrypt.js +207 -230
  68. package/dist/webapi/lib/jwe_encrypt.js +104 -138
  69. package/dist/webapi/lib/jwk_metadata.js +17 -18
  70. package/dist/webapi/lib/jwk_to_key.js +9 -16
  71. package/dist/webapi/lib/jws_algorithms.js +62 -61
  72. package/dist/webapi/lib/jws_sign.js +50 -75
  73. package/dist/webapi/lib/jws_verify.js +80 -125
  74. package/dist/webapi/lib/jwt_claims_set.js +123 -209
  75. package/dist/webapi/lib/key.js +84 -136
  76. package/dist/webapi/lib/key_algorithm.js +13 -8
  77. package/dist/webapi/lib/key_descriptor.js +8 -6
  78. package/dist/webapi/lib/key_management.js +200 -231
  79. package/dist/webapi/lib/key_options.js +7 -5
  80. package/dist/webapi/lib/options.js +55 -68
  81. package/dist/webapi/lib/signing.js +18 -22
  82. package/dist/webapi/lib/type_checks.js +26 -29
  83. package/dist/webapi/util/base64url.js +26 -35
  84. package/dist/webapi/util/decode_jwt.js +32 -31
  85. package/dist/webapi/util/decode_protected_header.js +18 -23
  86. package/dist/webapi/util/errors.js +94 -84
  87. package/package.json +17 -81
@@ -1,177 +1,129 @@
1
- import { assertNotSet } from '../../lib/helpers.js';
2
- import { JWEInvalid } from '../../util/errors.js';
3
- import { generateCek } from '../../lib/content_encryption.js';
4
- import { encryptKeyManagement } from '../../lib/key_management.js';
5
- import { encode as b64u } from '../../util/base64url.js';
6
- import { checkDisjoint, checkEncryptHeaders, createJWE, encryptJWE } from '../../lib/jwe_encrypt.js';
7
- import { prepareKey } from '../../lib/key.js';
8
- import { jweAlgorithm } from '../../lib/jwe_algorithms.js';
9
- import { assertUint8Array } from '../../lib/type_checks.js';
1
+ import { assertNotSet } from "../../lib/helpers.js";
2
+ import { JWEInvalid } from "../../util/errors.js";
3
+ import { generateCek } from "../../lib/content_encryption.js";
4
+ import { encode as b64u } from "../../util/base64url.js";
5
+ import { checkDisjoint, checkEncryptHeaders, createJWE, encryptJWE, transportCek } from "../../lib/jwe_encrypt.js";
6
+ import { JWE, isJWECEKTransport, jweAlgorithm } from "../../lib/jwe_algorithms.js";
7
+ import { assertUint8Array } from "../../lib/type_checks.js";
10
8
  class IndividualRecipient {
11
- #parent;
12
- state;
13
- constructor(enc, key, crit) {
14
- this.#parent = enc;
15
- this.state = [undefined, undefined, key, crit];
16
- }
17
- setUnprotectedHeader(unprotectedHeader) {
18
- assertNotSet(this.state[0], 'setUnprotectedHeader');
19
- this.state[0] = unprotectedHeader;
20
- return this;
21
- }
22
- setKeyManagementParameters(parameters) {
23
- assertNotSet(this.state[1], 'setKeyManagementParameters');
24
- this.state[1] = parameters;
25
- return this;
26
- }
27
- addRecipient(...args) {
28
- return this.#parent.addRecipient(...args);
29
- }
30
- encrypt(...args) {
31
- return this.#parent.encrypt(...args);
32
- }
33
- done() {
34
- return this.#parent;
35
- }
9
+ #parent;
10
+ state;
11
+ constructor(enc, key, crit) {
12
+ this.#parent = enc, this.state = [void 0, void 0, key, crit];
13
+ }
14
+ setUnprotectedHeader(unprotectedHeader) {
15
+ return assertNotSet(this.state[0], "setUnprotectedHeader"), this.state[0] = unprotectedHeader, this;
16
+ }
17
+ setKeyManagementParameters(parameters) {
18
+ return assertNotSet(this.state[1], "setKeyManagementParameters"), this.state[1] = parameters, this;
19
+ }
20
+ addRecipient(...args) {
21
+ return this.#parent.addRecipient(...args);
22
+ }
23
+ encrypt(...args) {
24
+ return this.#parent.encrypt(...args);
25
+ }
26
+ done() {
27
+ return this.#parent;
28
+ }
36
29
  }
37
30
  function copyOptionalMembers(flattened, jwe, recipient) {
38
- const { aad, protected: protectedHeader, unprotected, header } = flattened;
39
- if (aad)
40
- jwe.aad = aad;
41
- if (protectedHeader)
42
- jwe.protected = protectedHeader;
43
- if (unprotected)
44
- jwe.unprotected = unprotected;
45
- if (header)
46
- recipient.header = header;
31
+ const { aad, protected: protectedHeader, unprotected, header } = flattened;
32
+ aad && (jwe.aad = aad), protectedHeader && (jwe.protected = protectedHeader), unprotected && (jwe.unprotected = unprotected), header && (recipient.header = header);
47
33
  }
48
- export class GeneralEncrypt {
49
- #plaintext;
50
- #recipients = [];
51
- #protectedHeader;
52
- #unprotectedHeader;
53
- #aad;
54
- constructor(plaintext) {
55
- this.#plaintext = plaintext;
56
- }
57
- addRecipient(key, options) {
58
- const recipient = new IndividualRecipient(this, key, options?.crit);
59
- this.#recipients.push(recipient);
60
- return recipient;
61
- }
62
- setProtectedHeader(protectedHeader) {
63
- assertNotSet(this.#protectedHeader, 'setProtectedHeader');
64
- this.#protectedHeader = protectedHeader;
65
- return this;
66
- }
67
- setSharedUnprotectedHeader(sharedUnprotectedHeader) {
68
- assertNotSet(this.#unprotectedHeader, 'setSharedUnprotectedHeader');
69
- this.#unprotectedHeader = sharedUnprotectedHeader;
70
- return this;
34
+ class GeneralEncrypt {
35
+ #plaintext;
36
+ #recipients = [];
37
+ #protectedHeader;
38
+ #unprotectedHeader;
39
+ #aad;
40
+ constructor(plaintext) {
41
+ this.#plaintext = plaintext;
42
+ }
43
+ addRecipient(key, options) {
44
+ const recipient = new IndividualRecipient(this, key, options?.crit);
45
+ return this.#recipients.push(recipient), recipient;
46
+ }
47
+ setProtectedHeader(protectedHeader) {
48
+ return assertNotSet(this.#protectedHeader, "setProtectedHeader"), this.#protectedHeader = protectedHeader, this;
49
+ }
50
+ setSharedUnprotectedHeader(sharedUnprotectedHeader) {
51
+ return assertNotSet(this.#unprotectedHeader, "setSharedUnprotectedHeader"), this.#unprotectedHeader = sharedUnprotectedHeader, this;
52
+ }
53
+ setAdditionalAuthenticatedData(aad) {
54
+ return this.#aad = aad, this;
55
+ }
56
+ async encrypt() {
57
+ if (!this.#recipients.length)
58
+ throw new JWEInvalid("at least one recipient must be added");
59
+ if (assertUint8Array(this.#plaintext, "plaintext"), this.#recipients.length === 1) {
60
+ const [unprotectedHeader, keyManagementParameters, key, crit] = this.#recipients[0].state, flattened = await createJWE([
61
+ this.#plaintext,
62
+ this.#protectedHeader,
63
+ unprotectedHeader,
64
+ this.#unprotectedHeader,
65
+ this.#aad,
66
+ void 0,
67
+ void 0,
68
+ keyManagementParameters,
69
+ crit,
70
+ !1
71
+ ], key), jwe2 = {
72
+ ciphertext: flattened.ciphertext,
73
+ recipients: [{}]
74
+ };
75
+ return flattened.iv && (jwe2.iv = flattened.iv), flattened.tag && (jwe2.tag = flattened.tag), flattened.encrypted_key && (jwe2.recipients[0].encrypted_key = flattened.encrypted_key), copyOptionalMembers(flattened, jwe2, jwe2.recipients[0]), jwe2;
71
76
  }
72
- setAdditionalAuthenticatedData(aad) {
73
- this.#aad = aad;
74
- return this;
77
+ let enc, protectedHeader = this.#protectedHeader, sharedUnprotectedHeader = this.#unprotectedHeader;
78
+ const inputs = [], checked = [];
79
+ for (let i = 0; i < this.#recipients.length; i++) {
80
+ const recipient = this.#recipients[i], [unprotectedHeader, keyManagementParameters, , crit] = recipient.state, input = [
81
+ this.#plaintext,
82
+ protectedHeader,
83
+ unprotectedHeader,
84
+ sharedUnprotectedHeader,
85
+ this.#aad,
86
+ void 0,
87
+ void 0,
88
+ keyManagementParameters,
89
+ crit,
90
+ !0
91
+ ], headers = checkEncryptHeaders(input);
92
+ inputs.push(input), checked.push(headers), i === 0 && (protectedHeader = input[1], sharedUnprotectedHeader = input[3]);
93
+ const algEntry = JWE[headers[1]];
94
+ if (algEntry && !isJWECEKTransport(algEntry))
95
+ throw new JWEInvalid(`"${headers[1]}" alg may only have a single recipient`);
96
+ if (!enc)
97
+ enc = headers[2];
98
+ else if (enc !== headers[2])
99
+ throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter must be the same for all recipients');
75
100
  }
76
- async encrypt() {
77
- if (!this.#recipients.length) {
78
- throw new JWEInvalid('at least one recipient must be added');
79
- }
80
- assertUint8Array(this.#plaintext, 'plaintext');
81
- if (this.#recipients.length === 1) {
82
- const [unprotectedHeader, keyManagementParameters, key, crit] = this.#recipients[0].state;
83
- const flattened = await createJWE([
84
- this.#plaintext,
85
- this.#protectedHeader,
86
- unprotectedHeader,
87
- this.#unprotectedHeader,
88
- this.#aad,
89
- undefined,
90
- undefined,
91
- keyManagementParameters,
92
- crit,
93
- false,
94
- ], key);
95
- const jwe = {
96
- ciphertext: flattened.ciphertext,
97
- iv: flattened.iv,
98
- recipients: [{}],
99
- tag: flattened.tag,
100
- };
101
- if (flattened.encrypted_key)
102
- jwe.recipients[0].encrypted_key = flattened.encrypted_key;
103
- copyOptionalMembers(flattened, jwe, jwe.recipients[0]);
104
- return jwe;
105
- }
106
- let enc;
107
- let protectedHeader = this.#protectedHeader;
108
- let sharedUnprotectedHeader = this.#unprotectedHeader;
109
- const inputs = [];
110
- const checked = [];
111
- for (let i = 0; i < this.#recipients.length; i++) {
112
- const recipient = this.#recipients[i];
113
- const [unprotectedHeader, keyManagementParameters, , crit] = recipient.state;
114
- const input = [
115
- this.#plaintext,
116
- protectedHeader,
117
- unprotectedHeader,
118
- sharedUnprotectedHeader,
119
- this.#aad,
120
- undefined,
121
- undefined,
122
- keyManagementParameters,
123
- crit,
124
- true,
125
- ];
126
- const headers = checkEncryptHeaders(input);
127
- inputs.push(input);
128
- checked.push(headers);
129
- if (i === 0) {
130
- protectedHeader = input[1];
131
- sharedUnprotectedHeader = input[3];
132
- }
133
- if (headers[1] === 'dir' || headers[1] === 'ECDH-ES') {
134
- throw new JWEInvalid(`"${headers[1]}" alg may only have a single recipient`);
135
- }
136
- if (!enc) {
137
- enc = headers[2];
138
- }
139
- else if (enc !== headers[2]) {
140
- throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter must be the same for all recipients');
141
- }
142
- }
143
- const cek = generateCek(checked[0][3]);
144
- const jwe = {
145
- ciphertext: '',
146
- recipients: [],
147
- };
148
- for (let i = 0; i < this.#recipients.length; i++) {
149
- const recipient = this.#recipients[i];
150
- const [, keyManagementParameters, key] = recipient.state;
151
- const target = {};
152
- jwe.recipients.push(target);
153
- if (i === 0) {
154
- inputs[0][5] = cek;
155
- const flattened = await encryptJWE(inputs[0], checked[0], key);
156
- jwe.ciphertext = flattened.ciphertext;
157
- jwe.iv = flattened.iv;
158
- jwe.tag = flattened.tag;
159
- target.encrypted_key = flattened.encrypted_key;
160
- copyOptionalMembers(flattened, jwe, target);
161
- continue;
162
- }
163
- const [, alg, , encEntry] = checked[i];
164
- const unprotectedHeader = inputs[i][2];
165
- const k = await prepareKey(jweAlgorithm(alg), key, 'encrypt');
166
- const [, encryptedKey, parameters] = await encryptKeyManagement(alg, encEntry, k, cek, keyManagementParameters);
167
- target.encrypted_key = b64u(encryptedKey);
168
- if (unprotectedHeader || parameters) {
169
- const header = { ...unprotectedHeader, ...parameters };
170
- if (parameters)
171
- checkDisjoint(inputs[i][1], header, inputs[i][3]);
172
- target.header = header;
173
- }
174
- }
175
- return jwe;
101
+ const algEntries = checked.map(([, alg]) => {
102
+ const algEntry = jweAlgorithm(alg);
103
+ if (!isJWECEKTransport(algEntry))
104
+ throw new JWEInvalid(`"${alg}" alg may only have a single recipient`);
105
+ return algEntry;
106
+ }), cek = generateCek(checked[0][3]), jwe = {
107
+ ciphertext: "",
108
+ recipients: []
109
+ };
110
+ for (let i = 0; i < this.#recipients.length; i++) {
111
+ const recipient = this.#recipients[i], [, keyManagementParameters, key] = recipient.state, target = {};
112
+ if (jwe.recipients.push(target), i === 0) {
113
+ inputs[0][5] = cek;
114
+ const flattened = await encryptJWE(inputs[0], checked[0], key, algEntries[0]);
115
+ jwe.ciphertext = flattened.ciphertext, flattened.iv && (jwe.iv = flattened.iv), flattened.tag && (jwe.tag = flattened.tag), flattened.encrypted_key && (target.encrypted_key = flattened.encrypted_key), copyOptionalMembers(flattened, jwe, target);
116
+ continue;
117
+ }
118
+ const [joseHeader, , , encEntry] = checked[i], unprotectedHeader = inputs[i][2], [, encryptedKey, parameters] = await transportCek(algEntries[i], encEntry, key, cek, joseHeader, keyManagementParameters);
119
+ if (target.encrypted_key = b64u(encryptedKey), unprotectedHeader || parameters) {
120
+ const header = { ...unprotectedHeader, ...parameters };
121
+ parameters && checkDisjoint(inputs[i][1], header, inputs[i][3]), target.header = header;
122
+ }
176
123
  }
124
+ return jwe;
125
+ }
177
126
  }
127
+ export {
128
+ GeneralEncrypt
129
+ };
@@ -1,33 +1,31 @@
1
- import { jwkToKey } from '../lib/jwk_to_key.js';
2
- import { jwsAlgorithm } from '../lib/jws_algorithms.js';
3
- import { isObject } from '../lib/type_checks.js';
4
- import { JWSInvalid } from '../util/errors.js';
5
- import { normalizeJwk } from '../lib/jwk_metadata.js';
6
- export async function EmbeddedJWK(protectedHeader, token) {
7
- const joseHeader = {
8
- ...protectedHeader,
9
- ...token?.header,
10
- };
11
- if (!isObject(joseHeader.jwk)) {
12
- throw new JWSInvalid('"jwk" (JSON Web Key) Header Parameter must be a JSON object');
13
- }
14
- let jwk;
15
- try {
16
- jwk = normalizeJwk(joseHeader.jwk);
17
- }
18
- catch (cause) {
19
- throw new JWSInvalid('Invalid Embedded JWK', { cause });
20
- }
21
- const entry = jwsAlgorithm(joseHeader.alg);
22
- if (jwk.use !== undefined && jwk.use !== 'sig') {
23
- throw new JWSInvalid('Invalid Embedded JWK, its "use" must be "sig" when present');
24
- }
25
- if (jwk.alg !== undefined && jwk.alg !== entry.alg) {
26
- throw new JWSInvalid(`Invalid Embedded JWK, its "alg" must be "${entry.alg}" when present`);
27
- }
28
- const key = await jwkToKey(entry, { ...jwk, ext: true });
29
- if (key.type !== 'public') {
30
- throw new JWSInvalid('"jwk" (JSON Web Key) Header Parameter must be a public key');
31
- }
32
- return key;
1
+ import { jwkToKey } from "../lib/jwk_to_key.js";
2
+ import { jwsAlgorithm } from "../lib/jws_algorithms.js";
3
+ import { isObject } from "../lib/type_checks.js";
4
+ import { JWSInvalid } from "../util/errors.js";
5
+ import { normalizeJwk } from "../lib/jwk_metadata.js";
6
+ async function EmbeddedJWK(protectedHeader, token) {
7
+ const joseHeader = {
8
+ ...protectedHeader,
9
+ ...token?.header
10
+ };
11
+ if (!isObject(joseHeader.jwk))
12
+ throw new JWSInvalid('"jwk" (JSON Web Key) Header Parameter must be a JSON object');
13
+ let jwk;
14
+ try {
15
+ jwk = normalizeJwk(joseHeader.jwk);
16
+ } catch (cause) {
17
+ throw new JWSInvalid("Invalid Embedded JWK", { cause });
18
+ }
19
+ const entry = jwsAlgorithm(joseHeader.alg);
20
+ if (jwk.use !== void 0 && jwk.use !== "sig")
21
+ throw new JWSInvalid('Invalid Embedded JWK, its "use" must be "sig" when present');
22
+ if (jwk.alg !== void 0 && jwk.alg !== entry.alg)
23
+ throw new JWSInvalid(`Invalid Embedded JWK, its "alg" must be "${entry.alg}" when present`);
24
+ const key = await jwkToKey(entry, { ...jwk, ext: !0 });
25
+ if (key.type !== "public")
26
+ throw new JWSInvalid('"jwk" (JSON Web Key) Header Parameter must be a public key');
27
+ return key;
33
28
  }
29
+ export {
30
+ EmbeddedJWK
31
+ };
@@ -1,74 +1,58 @@
1
- import { digest } from '../lib/helpers.js';
2
- import { encode as b64u } from '../util/base64url.js';
3
- import { JOSENotSupported, JWKInvalid } from '../util/errors.js';
4
- import { encode } from '../lib/buffer_utils.js';
5
- import { isKeyLike } from '../lib/is_key_like.js';
6
- import { isObject } from '../lib/type_checks.js';
7
- import { exportJWK } from '../key/export.js';
8
- import { invalidKeyInput } from '../lib/invalid_key_input.js';
9
- import { snapshotJwk } from '../lib/jwk_metadata.js';
1
+ import { digest } from "../lib/helpers.js";
2
+ import { encode as b64u } from "../util/base64url.js";
3
+ import { JOSENotSupported, JWKInvalid } from "../util/errors.js";
4
+ import { encode } from "../lib/buffer_utils.js";
5
+ import { isKeyLike } from "../lib/is_key_like.js";
6
+ import { isObject } from "../lib/type_checks.js";
7
+ import { exportJWK } from "../key/export.js";
8
+ import { invalidKeyInput } from "../lib/invalid_key_input.js";
9
+ import { snapshotJwk } from "../lib/jwk_metadata.js";
10
10
  const check = (value, description) => {
11
- if (typeof value !== 'string' || !value) {
12
- throw new JWKInvalid(`${description} missing or invalid`);
13
- }
11
+ if (typeof value != "string" || !value)
12
+ throw new JWKInvalid(`${description} missing or invalid`);
14
13
  };
15
- export async function calculateJwkThumbprint(key, digestAlgorithm) {
16
- let jwk;
17
- if (isObject(key)) {
18
- jwk = snapshotJwk(key);
19
- if (typeof jwk.kty !== 'string') {
20
- throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'KeyObject', 'JSON Web Key'));
21
- }
22
- }
23
- else if (isKeyLike(key)) {
24
- jwk = snapshotJwk(await exportJWK(key));
25
- }
26
- else {
27
- throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'KeyObject', 'JSON Web Key'));
28
- }
29
- digestAlgorithm ??= 'sha256';
30
- if (digestAlgorithm !== 'sha256' &&
31
- digestAlgorithm !== 'sha384' &&
32
- digestAlgorithm !== 'sha512') {
33
- throw new TypeError('digestAlgorithm must one of "sha256", "sha384", or "sha512"');
34
- }
35
- let components;
36
- switch (jwk.kty) {
37
- case 'AKP':
38
- check(jwk.alg, '"alg" (Algorithm) Parameter');
39
- check(jwk.pub, '"pub" (Public key) Parameter');
40
- components = { alg: jwk.alg, kty: jwk.kty, pub: jwk.pub };
41
- break;
42
- case 'EC':
43
- check(jwk.crv, '"crv" (Curve) Parameter');
44
- check(jwk.x, '"x" (X Coordinate) Parameter');
45
- check(jwk.y, '"y" (Y Coordinate) Parameter');
46
- components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y };
47
- break;
48
- case 'OKP':
49
- check(jwk.crv, '"crv" (Subtype of Key Pair) Parameter');
50
- check(jwk.x, '"x" (Public Key) Parameter');
51
- components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x };
52
- break;
53
- case 'RSA':
54
- check(jwk.e, '"e" (Exponent) Parameter');
55
- check(jwk.n, '"n" (Modulus) Parameter');
56
- components = { e: jwk.e, kty: jwk.kty, n: jwk.n };
57
- break;
58
- case 'oct':
59
- if (typeof jwk.k !== 'string') {
60
- throw new JWKInvalid('"k" (Key Value) Parameter missing or invalid');
61
- }
62
- components = { k: jwk.k, kty: jwk.kty };
63
- break;
64
- default:
65
- throw new JOSENotSupported('"kty" (Key Type) Parameter missing or unsupported');
66
- }
67
- const data = encode(JSON.stringify(components));
68
- return b64u(await digest(digestAlgorithm, data));
14
+ async function calculateJwkThumbprint(key, digestAlgorithm) {
15
+ let jwk;
16
+ if (isObject(key)) {
17
+ if (jwk = snapshotJwk(key), typeof jwk.kty != "string")
18
+ throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "JSON Web Key"));
19
+ } else if (isKeyLike(key))
20
+ jwk = snapshotJwk(await exportJWK(key));
21
+ else
22
+ throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "JSON Web Key"));
23
+ if (digestAlgorithm ??= "sha256", digestAlgorithm !== "sha256" && digestAlgorithm !== "sha384" && digestAlgorithm !== "sha512")
24
+ throw new TypeError('digestAlgorithm must one of "sha256", "sha384", or "sha512"');
25
+ let components;
26
+ switch (jwk.kty) {
27
+ case "AKP":
28
+ check(jwk.alg, '"alg" (Algorithm) Parameter'), check(jwk.pub, '"pub" (Public key) Parameter'), components = { alg: jwk.alg, kty: jwk.kty, pub: jwk.pub };
29
+ break;
30
+ case "EC":
31
+ check(jwk.crv, '"crv" (Curve) Parameter'), check(jwk.x, '"x" (X Coordinate) Parameter'), check(jwk.y, '"y" (Y Coordinate) Parameter'), components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y };
32
+ break;
33
+ case "OKP":
34
+ check(jwk.crv, '"crv" (Subtype of Key Pair) Parameter'), check(jwk.x, '"x" (Public Key) Parameter'), components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x };
35
+ break;
36
+ case "RSA":
37
+ check(jwk.e, '"e" (Exponent) Parameter'), check(jwk.n, '"n" (Modulus) Parameter'), components = { e: jwk.e, kty: jwk.kty, n: jwk.n };
38
+ break;
39
+ case "oct":
40
+ if (typeof jwk.k != "string")
41
+ throw new JWKInvalid('"k" (Key Value) Parameter missing or invalid');
42
+ components = { k: jwk.k, kty: jwk.kty };
43
+ break;
44
+ default:
45
+ throw new JOSENotSupported('"kty" (Key Type) Parameter missing or unsupported');
46
+ }
47
+ const data = encode(JSON.stringify(components));
48
+ return b64u(await digest(digestAlgorithm, data));
69
49
  }
70
- export async function calculateJwkThumbprintUri(key, digestAlgorithm) {
71
- digestAlgorithm ??= 'sha256';
72
- const thumbprint = await calculateJwkThumbprint(key, digestAlgorithm);
73
- return `urn:ietf:params:oauth:jwk-thumbprint:sha-${digestAlgorithm.slice(-3)}:${thumbprint}`;
50
+ async function calculateJwkThumbprintUri(key, digestAlgorithm) {
51
+ digestAlgorithm ??= "sha256";
52
+ const thumbprint = await calculateJwkThumbprint(key, digestAlgorithm);
53
+ return `urn:ietf:params:oauth:jwk-thumbprint:sha-${digestAlgorithm.slice(-3)}:${thumbprint}`;
74
54
  }
55
+ export {
56
+ calculateJwkThumbprint,
57
+ calculateJwkThumbprintUri
58
+ };
@@ -1,70 +1,53 @@
1
- import { jwkToKey } from '../lib/jwk_to_key.js';
2
- import { JWS } from '../lib/jws_algorithms.js';
3
- import { JWKSInvalid, JOSENotSupported, JWKSNoMatchingKey, JWKSMultipleMatchingKeys, } from '../util/errors.js';
4
- import { isJwkSet } from '../lib/type_checks.js';
5
- import { snapshotJwk } from '../lib/jwk_metadata.js';
1
+ import { jwkToKey } from "../lib/jwk_to_key.js";
2
+ import { JWS } from "../lib/jws_algorithms.js";
3
+ import { JWKSInvalid, JOSENotSupported, JWKSNoMatchingKey, JWKSMultipleMatchingKeys } from "../util/errors.js";
4
+ import { isJwkSet } from "../lib/type_checks.js";
5
+ import { snapshotJwk } from "../lib/jwk_metadata.js";
6
6
  function isUsableJWK(jwk, entry, alg, kid) {
7
- const { kty, key_ops, ext, kid: jwkKid, alg: jwkAlg, use, crv } = snapshotJwk(jwk);
8
- const keyOps = Array.isArray(key_ops) ? [...key_ops] : key_ops;
9
- return ((ext === undefined || typeof ext === 'boolean') &&
10
- (keyOps === undefined ||
11
- (Array.isArray(keyOps) &&
12
- keyOps.every((operation, index) => typeof operation === 'string' && keyOps.indexOf(operation) === index) &&
13
- keyOps.includes('verify'))) &&
14
- entry.kty.includes(kty) &&
15
- (kid === undefined || (typeof kid === 'string' && kid === jwkKid)) &&
16
- (jwkAlg === undefined ? kty !== 'AKP' : alg === jwkAlg) &&
17
- (use === undefined || use === 'sig') &&
18
- (!entry.crv || crv === entry.crv));
7
+ const { kty, key_ops, ext, kid: jwkKid, alg: jwkAlg, use, crv } = snapshotJwk(jwk), keyOps = Array.isArray(key_ops) ? [...key_ops] : key_ops;
8
+ return (ext === void 0 || typeof ext == "boolean") && (keyOps === void 0 || Array.isArray(keyOps) && keyOps.every((operation, index) => typeof operation == "string" && keyOps.indexOf(operation) === index) && keyOps.includes("verify")) && entry.kty.includes(kty) && (kid === void 0 || typeof kid == "string" && kid === jwkKid) && (jwkAlg === void 0 ? kty !== "AKP" : alg === jwkAlg) && (use === void 0 || use === "sig") && (!entry.crv || crv === entry.crv);
19
9
  }
20
10
  async function importWithAlgCache(cache, jwk, entry) {
21
- const cached = cache.get(jwk) || cache.set(jwk, {}).get(jwk);
22
- const { alg } = entry;
23
- if (cached[alg] === undefined) {
24
- const key = await jwkToKey(entry, { ...jwk, alg, ext: true });
25
- if (key.type !== 'public') {
26
- throw new JWKSInvalid('JSON Web Key Set members must be public keys');
27
- }
28
- cached[alg] = key;
29
- }
30
- return cached[alg];
11
+ const cached = cache.get(jwk) || cache.set(jwk, {}).get(jwk), { alg } = entry;
12
+ if (cached[alg] === void 0) {
13
+ const key = await jwkToKey(entry, { ...jwk, alg, ext: !0 });
14
+ if (key.type !== "public")
15
+ throw new JWKSInvalid("JSON Web Key Set members must be public keys");
16
+ cached[alg] = key;
17
+ }
18
+ return cached[alg];
31
19
  }
32
- export function createLocalJWKSet(jwks) {
33
- let snapshot;
34
- try {
35
- snapshot = structuredClone(jwks);
36
- }
37
- catch { }
38
- if (!isJwkSet(snapshot)) {
39
- throw new JWKSInvalid('JSON Web Key Set malformed');
20
+ function createLocalJWKSet(jwks) {
21
+ let snapshot;
22
+ try {
23
+ snapshot = structuredClone(jwks);
24
+ } catch {
25
+ }
26
+ if (!isJwkSet(snapshot))
27
+ throw new JWKSInvalid("JSON Web Key Set malformed");
28
+ const cached = /* @__PURE__ */ new WeakMap();
29
+ return Object.defineProperty(async (protectedHeader, token) => {
30
+ const { alg, kid } = { ...protectedHeader, ...token?.header }, entry = typeof alg == "string" ? JWS[alg] : void 0;
31
+ if (!entry || entry.secret)
32
+ throw new JOSENotSupported('Unsupported "alg" value for a JSON Web Key Set');
33
+ const candidates = snapshot.keys.filter((jwk2) => isUsableJWK(jwk2, entry, alg, kid)), { 0: jwk, length } = candidates;
34
+ if (!length)
35
+ throw new JWKSNoMatchingKey();
36
+ if (length !== 1) {
37
+ const error = new JWKSMultipleMatchingKeys();
38
+ throw error[Symbol.asyncIterator] = async function* () {
39
+ for (const jwk2 of candidates)
40
+ try {
41
+ yield await importWithAlgCache(cached, jwk2, entry);
42
+ } catch {
43
+ }
44
+ }, error;
40
45
  }
41
- const cached = new WeakMap();
42
- const localJWKSet = async (protectedHeader, token) => {
43
- const { alg, kid } = { ...protectedHeader, ...token?.header };
44
- const entry = typeof alg === 'string' ? JWS[alg] : undefined;
45
- if (!entry || entry.secret) {
46
- throw new JOSENotSupported('Unsupported "alg" value for a JSON Web Key Set');
47
- }
48
- const candidates = snapshot.keys.filter((jwk) => isUsableJWK(jwk, entry, alg, kid));
49
- const { 0: jwk, length } = candidates;
50
- if (!length) {
51
- throw new JWKSNoMatchingKey();
52
- }
53
- if (length !== 1) {
54
- const error = new JWKSMultipleMatchingKeys();
55
- error[Symbol.asyncIterator] = async function* () {
56
- for (const jwk of candidates) {
57
- try {
58
- yield await importWithAlgCache(cached, jwk, entry);
59
- }
60
- catch { }
61
- }
62
- };
63
- throw error;
64
- }
65
- return importWithAlgCache(cached, jwk, entry);
66
- };
67
- return Object.defineProperty(localJWKSet, 'jwks', {
68
- value: () => structuredClone(snapshot),
69
- });
46
+ return importWithAlgCache(cached, jwk, entry);
47
+ }, "jwks", {
48
+ value: () => structuredClone(snapshot)
49
+ });
70
50
  }
51
+ export {
52
+ createLocalJWKSet
53
+ };