toolcraft 0.0.119 → 0.0.121

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 (153) hide show
  1. package/composition.json +17 -2
  2. package/dist/composition.json +17 -2
  3. package/dist/http.compile-check.d.ts +1 -0
  4. package/dist/http.compile-check.js +31 -0
  5. package/dist/http.d.ts +19 -0
  6. package/dist/http.js +62 -0
  7. package/dist/mcp.js +26 -11
  8. package/node_modules/jose/LICENSE.md +21 -0
  9. package/node_modules/jose/README.md +153 -0
  10. package/node_modules/jose/dist/types/index.d.ts +55 -0
  11. package/node_modules/jose/dist/types/jwe/compact/decrypt.d.ts +31 -0
  12. package/node_modules/jose/dist/types/jwe/compact/encrypt.d.ts +65 -0
  13. package/node_modules/jose/dist/types/jwe/flattened/decrypt.d.ts +31 -0
  14. package/node_modules/jose/dist/types/jwe/flattened/encrypt.d.ts +83 -0
  15. package/node_modules/jose/dist/types/jwe/general/decrypt.d.ts +38 -0
  16. package/node_modules/jose/dist/types/jwe/general/encrypt.d.ts +74 -0
  17. package/node_modules/jose/dist/types/jwk/embedded.d.ts +17 -0
  18. package/node_modules/jose/dist/types/jwk/thumbprint.d.ts +32 -0
  19. package/node_modules/jose/dist/types/jwks/local.d.ts +29 -0
  20. package/node_modules/jose/dist/types/jwks/remote.d.ts +237 -0
  21. package/node_modules/jose/dist/types/jws/compact/sign.d.ts +36 -0
  22. package/node_modules/jose/dist/types/jws/compact/verify.d.ts +33 -0
  23. package/node_modules/jose/dist/types/jws/flattened/sign.d.ts +42 -0
  24. package/node_modules/jose/dist/types/jws/flattened/verify.d.ts +33 -0
  25. package/node_modules/jose/dist/types/jws/general/sign.d.ts +53 -0
  26. package/node_modules/jose/dist/types/jws/general/verify.d.ts +41 -0
  27. package/node_modules/jose/dist/types/jwt/decrypt.d.ts +35 -0
  28. package/node_modules/jose/dist/types/jwt/encrypt.d.ts +91 -0
  29. package/node_modules/jose/dist/types/jwt/sign.d.ts +43 -0
  30. package/node_modules/jose/dist/types/jwt/unsecured.d.ts +43 -0
  31. package/node_modules/jose/dist/types/jwt/verify.d.ts +37 -0
  32. package/node_modules/jose/dist/types/key/export.d.ts +33 -0
  33. package/node_modules/jose/dist/types/key/generate_key_pair.d.ts +47 -0
  34. package/node_modules/jose/dist/types/key/generate_secret.d.ts +35 -0
  35. package/node_modules/jose/dist/types/key/import.d.ts +83 -0
  36. package/node_modules/jose/dist/types/types.d.ts +852 -0
  37. package/node_modules/jose/dist/types/util/base64url.d.ts +9 -0
  38. package/node_modules/jose/dist/types/util/decode_jwt.d.ts +18 -0
  39. package/node_modules/jose/dist/types/util/decode_protected_header.d.ts +17 -0
  40. package/node_modules/jose/dist/types/util/errors.d.ts +213 -0
  41. package/node_modules/jose/dist/webapi/index.js +32 -0
  42. package/node_modules/jose/dist/webapi/jwe/compact/decrypt.js +27 -0
  43. package/node_modules/jose/dist/webapi/jwe/compact/encrypt.js +27 -0
  44. package/node_modules/jose/dist/webapi/jwe/flattened/decrypt.js +159 -0
  45. package/node_modules/jose/dist/webapi/jwe/flattened/encrypt.js +167 -0
  46. package/node_modules/jose/dist/webapi/jwe/general/decrypt.js +31 -0
  47. package/node_modules/jose/dist/webapi/jwe/general/encrypt.js +182 -0
  48. package/node_modules/jose/dist/webapi/jwk/embedded.js +17 -0
  49. package/node_modules/jose/dist/webapi/jwk/thumbprint.js +68 -0
  50. package/node_modules/jose/dist/webapi/jwks/local.js +119 -0
  51. package/node_modules/jose/dist/webapi/jwks/remote.js +179 -0
  52. package/node_modules/jose/dist/webapi/jws/compact/sign.js +18 -0
  53. package/node_modules/jose/dist/webapi/jws/compact/verify.js +21 -0
  54. package/node_modules/jose/dist/webapi/jws/flattened/sign.js +89 -0
  55. package/node_modules/jose/dist/webapi/jws/flattened/verify.js +110 -0
  56. package/node_modules/jose/dist/webapi/jws/general/sign.js +70 -0
  57. package/node_modules/jose/dist/webapi/jws/general/verify.js +24 -0
  58. package/node_modules/jose/dist/webapi/jwt/decrypt.js +23 -0
  59. package/node_modules/jose/dist/webapi/jwt/encrypt.js +101 -0
  60. package/node_modules/jose/dist/webapi/jwt/sign.js +52 -0
  61. package/node_modules/jose/dist/webapi/jwt/unsecured.js +63 -0
  62. package/node_modules/jose/dist/webapi/jwt/verify.js +15 -0
  63. package/node_modules/jose/dist/webapi/key/export.js +11 -0
  64. package/node_modules/jose/dist/webapi/key/generate_key_pair.js +97 -0
  65. package/node_modules/jose/dist/webapi/key/generate_secret.js +40 -0
  66. package/node_modules/jose/dist/webapi/key/import.js +57 -0
  67. package/node_modules/jose/dist/webapi/lib/aesgcmkw.js +15 -0
  68. package/node_modules/jose/dist/webapi/lib/aeskw.js +25 -0
  69. package/node_modules/jose/dist/webapi/lib/asn1.js +243 -0
  70. package/node_modules/jose/dist/webapi/lib/base64.js +22 -0
  71. package/node_modules/jose/dist/webapi/lib/buffer_utils.js +43 -0
  72. package/node_modules/jose/dist/webapi/lib/check_key_type.js +122 -0
  73. package/node_modules/jose/dist/webapi/lib/content_encryption.js +217 -0
  74. package/node_modules/jose/dist/webapi/lib/crypto_key.js +136 -0
  75. package/node_modules/jose/dist/webapi/lib/deflate.js +44 -0
  76. package/node_modules/jose/dist/webapi/lib/ecdhes.js +52 -0
  77. package/node_modules/jose/dist/webapi/lib/helpers.js +19 -0
  78. package/node_modules/jose/dist/webapi/lib/invalid_key_input.js +27 -0
  79. package/node_modules/jose/dist/webapi/lib/is_key_like.js +17 -0
  80. package/node_modules/jose/dist/webapi/lib/jwk_to_key.js +107 -0
  81. package/node_modules/jose/dist/webapi/lib/jwt_claims_set.js +238 -0
  82. package/node_modules/jose/dist/webapi/lib/key_management.js +186 -0
  83. package/node_modules/jose/dist/webapi/lib/key_to_jwk.js +31 -0
  84. package/node_modules/jose/dist/webapi/lib/normalize_key.js +166 -0
  85. package/node_modules/jose/dist/webapi/lib/pbes2kw.js +42 -0
  86. package/node_modules/jose/dist/webapi/lib/rsaes.js +24 -0
  87. package/node_modules/jose/dist/webapi/lib/signing.js +68 -0
  88. package/node_modules/jose/dist/webapi/lib/type_checks.js +40 -0
  89. package/node_modules/jose/dist/webapi/lib/validate_algorithms.js +10 -0
  90. package/node_modules/jose/dist/webapi/lib/validate_crit.js +33 -0
  91. package/node_modules/jose/dist/webapi/util/base64url.js +30 -0
  92. package/node_modules/jose/dist/webapi/util/decode_jwt.js +32 -0
  93. package/node_modules/jose/dist/webapi/util/decode_protected_header.js +34 -0
  94. package/node_modules/jose/dist/webapi/util/errors.js +99 -0
  95. package/node_modules/jose/package.json +200 -0
  96. package/node_modules/tiny-http-mcp-server/LICENSE +21 -0
  97. package/node_modules/tiny-http-mcp-server/README.md +778 -0
  98. package/node_modules/tiny-http-mcp-server/dist/auth.d.ts +69 -0
  99. package/node_modules/tiny-http-mcp-server/dist/auth.js +261 -0
  100. package/node_modules/tiny-http-mcp-server/dist/cli.d.ts +20 -0
  101. package/node_modules/tiny-http-mcp-server/dist/cli.js +465 -0
  102. package/node_modules/tiny-http-mcp-server/dist/composition.json +30 -0
  103. package/node_modules/tiny-http-mcp-server/dist/express-middleware.d.ts +18 -0
  104. package/node_modules/tiny-http-mcp-server/dist/express-middleware.js +90 -0
  105. package/node_modules/tiny-http-mcp-server/dist/http-server.d.ts +49 -0
  106. package/node_modules/tiny-http-mcp-server/dist/http-server.js +264 -0
  107. package/node_modules/tiny-http-mcp-server/dist/http-transport.d.ts +164 -0
  108. package/node_modules/tiny-http-mcp-server/dist/http-transport.js +897 -0
  109. package/node_modules/tiny-http-mcp-server/dist/index.d.ts +13 -0
  110. package/node_modules/tiny-http-mcp-server/dist/index.js +6 -0
  111. package/node_modules/tiny-http-mcp-server/dist/load-oauth-verifier.d.ts +6 -0
  112. package/node_modules/tiny-http-mcp-server/dist/load-oauth-verifier.js +43 -0
  113. package/node_modules/tiny-http-mcp-server/dist/parse-body.d.ts +22 -0
  114. package/node_modules/tiny-http-mcp-server/dist/parse-body.js +150 -0
  115. package/node_modules/tiny-http-mcp-server/dist/server.d.ts +9 -0
  116. package/node_modules/tiny-http-mcp-server/dist/server.js +4 -0
  117. package/node_modules/tiny-http-mcp-server/dist/session.d.ts +18 -0
  118. package/node_modules/tiny-http-mcp-server/dist/session.js +37 -0
  119. package/node_modules/tiny-http-mcp-server/dist/sse.d.ts +11 -0
  120. package/node_modules/tiny-http-mcp-server/dist/sse.js +22 -0
  121. package/node_modules/tiny-http-mcp-server/dist/test-support.d.ts +10 -0
  122. package/node_modules/tiny-http-mcp-server/dist/test-support.js +398 -0
  123. package/node_modules/tiny-http-mcp-server/dist/testing.d.ts +59 -0
  124. package/node_modules/tiny-http-mcp-server/dist/testing.js +191 -0
  125. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/LICENSE +21 -0
  126. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/README.md +70 -0
  127. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/auth-store-session-store.d.ts +14 -0
  128. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/auth-store-session-store.js +169 -0
  129. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/authorization-state.d.ts +8 -0
  130. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/authorization-state.js +47 -0
  131. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/default-oauth-client-provider.d.ts +3 -0
  132. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/default-oauth-client-provider.js +627 -0
  133. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/loopback-authorization.d.ts +20 -0
  134. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/loopback-authorization.js +207 -0
  135. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/pkce.d.ts +2 -0
  136. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/pkce.js +7 -0
  137. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/token-endpoint.d.ts +40 -0
  138. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/token-endpoint.js +164 -0
  139. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/types.d.ts +113 -0
  140. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/client/types.js +1 -0
  141. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/index.d.ts +10 -0
  142. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/index.js +7 -0
  143. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/resource-indicator.d.ts +1 -0
  144. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/resource-indicator.js +11 -0
  145. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/server/jwks-token-verifier.d.ts +32 -0
  146. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/server/jwks-token-verifier.js +388 -0
  147. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/types.compile-check.d.ts +1 -0
  148. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/dist/types.compile-check.js +22 -0
  149. package/node_modules/tiny-http-mcp-server/node_modules/mcp-oauth/package.json +28 -0
  150. package/node_modules/tiny-http-mcp-server/package.json +59 -0
  151. package/node_modules/tiny-stdio-mcp-server/dist/composition.json +1 -1
  152. package/node_modules/toolcraft-schema/package.json +1 -1
  153. package/package.json +11 -4
@@ -0,0 +1,217 @@
1
+ import { concat, uint64be } from './buffer_utils.js';
2
+ import { checkEncCryptoKey } from './crypto_key.js';
3
+ import { invalidKeyInput } from './invalid_key_input.js';
4
+ import { JOSENotSupported, JWEDecryptionFailed, JWEInvalid } from '../util/errors.js';
5
+ import { isCryptoKey } from './is_key_like.js';
6
+ export function cekLength(alg) {
7
+ switch (alg) {
8
+ case 'A128GCM':
9
+ return 128;
10
+ case 'A192GCM':
11
+ return 192;
12
+ case 'A256GCM':
13
+ case 'A128CBC-HS256':
14
+ return 256;
15
+ case 'A192CBC-HS384':
16
+ return 384;
17
+ case 'A256CBC-HS512':
18
+ return 512;
19
+ default:
20
+ throw new JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`);
21
+ }
22
+ }
23
+ export const generateCek = (alg) => crypto.getRandomValues(new Uint8Array(cekLength(alg) >> 3));
24
+ function checkCekLength(cek, expected) {
25
+ const actual = cek.byteLength << 3;
26
+ if (actual !== expected) {
27
+ throw new JWEInvalid(`Invalid Content Encryption Key length. Expected ${expected} bits, got ${actual} bits`);
28
+ }
29
+ }
30
+ function ivBitLength(alg) {
31
+ switch (alg) {
32
+ case 'A128GCM':
33
+ case 'A128GCMKW':
34
+ case 'A192GCM':
35
+ case 'A192GCMKW':
36
+ case 'A256GCM':
37
+ case 'A256GCMKW':
38
+ return 96;
39
+ case 'A128CBC-HS256':
40
+ case 'A192CBC-HS384':
41
+ case 'A256CBC-HS512':
42
+ return 128;
43
+ default:
44
+ throw new JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`);
45
+ }
46
+ }
47
+ export const generateIv = (alg) => crypto.getRandomValues(new Uint8Array(ivBitLength(alg) >> 3));
48
+ export function checkIvLength(enc, iv) {
49
+ if (iv.length << 3 !== ivBitLength(enc)) {
50
+ throw new JWEInvalid('Invalid Initialization Vector length');
51
+ }
52
+ }
53
+ async function cbcKeySetup(enc, cek, usage) {
54
+ if (!(cek instanceof Uint8Array)) {
55
+ throw new TypeError(invalidKeyInput(cek, 'Uint8Array'));
56
+ }
57
+ const keySize = parseInt(enc.slice(1, 4), 10);
58
+ const encKey = await crypto.subtle.importKey('raw', cek.subarray(keySize >> 3), 'AES-CBC', false, [usage]);
59
+ const macKey = await crypto.subtle.importKey('raw', cek.subarray(0, keySize >> 3), {
60
+ hash: `SHA-${keySize << 1}`,
61
+ name: 'HMAC',
62
+ }, false, ['sign']);
63
+ return { encKey, macKey, keySize };
64
+ }
65
+ async function cbcHmacTag(macKey, macData, keySize) {
66
+ return new Uint8Array((await crypto.subtle.sign('HMAC', macKey, macData)).slice(0, keySize >> 3));
67
+ }
68
+ async function cbcEncrypt(enc, plaintext, cek, iv, aad) {
69
+ const { encKey, macKey, keySize } = await cbcKeySetup(enc, cek, 'encrypt');
70
+ const ciphertext = new Uint8Array(await crypto.subtle.encrypt({
71
+ iv: iv,
72
+ name: 'AES-CBC',
73
+ }, encKey, plaintext));
74
+ const macData = concat(aad, iv, ciphertext, uint64be(aad.length << 3));
75
+ const tag = await cbcHmacTag(macKey, macData, keySize);
76
+ return { ciphertext, tag, iv };
77
+ }
78
+ async function timingSafeEqual(a, b) {
79
+ if (!(a instanceof Uint8Array)) {
80
+ throw new TypeError('First argument must be a buffer');
81
+ }
82
+ if (!(b instanceof Uint8Array)) {
83
+ throw new TypeError('Second argument must be a buffer');
84
+ }
85
+ const algorithm = { name: 'HMAC', hash: 'SHA-256' };
86
+ const key = (await crypto.subtle.generateKey(algorithm, false, ['sign']));
87
+ const aHmac = new Uint8Array(await crypto.subtle.sign(algorithm, key, a));
88
+ const bHmac = new Uint8Array(await crypto.subtle.sign(algorithm, key, b));
89
+ let out = 0;
90
+ let i = -1;
91
+ while (++i < 32) {
92
+ out |= aHmac[i] ^ bHmac[i];
93
+ }
94
+ return out === 0;
95
+ }
96
+ async function cbcDecrypt(enc, cek, ciphertext, iv, tag, aad) {
97
+ const { encKey, macKey, keySize } = await cbcKeySetup(enc, cek, 'decrypt');
98
+ const macData = concat(aad, iv, ciphertext, uint64be(aad.length << 3));
99
+ const expectedTag = await cbcHmacTag(macKey, macData, keySize);
100
+ let macCheckPassed;
101
+ try {
102
+ macCheckPassed = await timingSafeEqual(tag, expectedTag);
103
+ }
104
+ catch {
105
+ }
106
+ if (!macCheckPassed) {
107
+ throw new JWEDecryptionFailed();
108
+ }
109
+ let plaintext;
110
+ try {
111
+ plaintext = new Uint8Array(await crypto.subtle.decrypt({ iv: iv, name: 'AES-CBC' }, encKey, ciphertext));
112
+ }
113
+ catch {
114
+ }
115
+ if (!plaintext) {
116
+ throw new JWEDecryptionFailed();
117
+ }
118
+ return plaintext;
119
+ }
120
+ async function gcmEncrypt(enc, plaintext, cek, iv, aad) {
121
+ let encKey;
122
+ if (cek instanceof Uint8Array) {
123
+ encKey = await crypto.subtle.importKey('raw', cek, 'AES-GCM', false, ['encrypt']);
124
+ }
125
+ else {
126
+ checkEncCryptoKey(cek, enc, 'encrypt');
127
+ encKey = cek;
128
+ }
129
+ const encrypted = new Uint8Array(await crypto.subtle.encrypt({
130
+ additionalData: aad,
131
+ iv: iv,
132
+ name: 'AES-GCM',
133
+ tagLength: 128,
134
+ }, encKey, plaintext));
135
+ const tag = encrypted.slice(-16);
136
+ const ciphertext = encrypted.slice(0, -16);
137
+ return { ciphertext, tag, iv };
138
+ }
139
+ async function gcmDecrypt(enc, cek, ciphertext, iv, tag, aad) {
140
+ let encKey;
141
+ if (cek instanceof Uint8Array) {
142
+ encKey = await crypto.subtle.importKey('raw', cek, 'AES-GCM', false, ['decrypt']);
143
+ }
144
+ else {
145
+ checkEncCryptoKey(cek, enc, 'decrypt');
146
+ encKey = cek;
147
+ }
148
+ try {
149
+ return new Uint8Array(await crypto.subtle.decrypt({
150
+ additionalData: aad,
151
+ iv: iv,
152
+ name: 'AES-GCM',
153
+ tagLength: 128,
154
+ }, encKey, concat(ciphertext, tag)));
155
+ }
156
+ catch {
157
+ throw new JWEDecryptionFailed();
158
+ }
159
+ }
160
+ const unsupportedEnc = 'Unsupported JWE Content Encryption Algorithm';
161
+ export async function encrypt(enc, plaintext, cek, iv, aad) {
162
+ if (!isCryptoKey(cek) && !(cek instanceof Uint8Array)) {
163
+ throw new TypeError(invalidKeyInput(cek, 'CryptoKey', 'KeyObject', 'Uint8Array', 'JSON Web Key'));
164
+ }
165
+ if (iv) {
166
+ checkIvLength(enc, iv);
167
+ }
168
+ else {
169
+ iv = generateIv(enc);
170
+ }
171
+ switch (enc) {
172
+ case 'A128CBC-HS256':
173
+ case 'A192CBC-HS384':
174
+ case 'A256CBC-HS512':
175
+ if (cek instanceof Uint8Array) {
176
+ checkCekLength(cek, parseInt(enc.slice(-3), 10));
177
+ }
178
+ return cbcEncrypt(enc, plaintext, cek, iv, aad);
179
+ case 'A128GCM':
180
+ case 'A192GCM':
181
+ case 'A256GCM':
182
+ if (cek instanceof Uint8Array) {
183
+ checkCekLength(cek, parseInt(enc.slice(1, 4), 10));
184
+ }
185
+ return gcmEncrypt(enc, plaintext, cek, iv, aad);
186
+ default:
187
+ throw new JOSENotSupported(unsupportedEnc);
188
+ }
189
+ }
190
+ export async function decrypt(enc, cek, ciphertext, iv, tag, aad) {
191
+ if (!isCryptoKey(cek) && !(cek instanceof Uint8Array)) {
192
+ throw new TypeError(invalidKeyInput(cek, 'CryptoKey', 'KeyObject', 'Uint8Array', 'JSON Web Key'));
193
+ }
194
+ if (!iv) {
195
+ throw new JWEInvalid('JWE Initialization Vector missing');
196
+ }
197
+ if (!tag) {
198
+ throw new JWEInvalid('JWE Authentication Tag missing');
199
+ }
200
+ checkIvLength(enc, iv);
201
+ switch (enc) {
202
+ case 'A128CBC-HS256':
203
+ case 'A192CBC-HS384':
204
+ case 'A256CBC-HS512':
205
+ if (cek instanceof Uint8Array)
206
+ checkCekLength(cek, parseInt(enc.slice(-3), 10));
207
+ return cbcDecrypt(enc, cek, ciphertext, iv, tag, aad);
208
+ case 'A128GCM':
209
+ case 'A192GCM':
210
+ case 'A256GCM':
211
+ if (cek instanceof Uint8Array)
212
+ checkCekLength(cek, parseInt(enc.slice(1, 4), 10));
213
+ return gcmDecrypt(enc, cek, ciphertext, iv, tag, aad);
214
+ default:
215
+ throw new JOSENotSupported(unsupportedEnc);
216
+ }
217
+ }
@@ -0,0 +1,136 @@
1
+ const unusable = (name, prop = 'algorithm.name') => new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
2
+ const isAlgorithm = (algorithm, name) => algorithm.name === name;
3
+ function getHashLength(hash) {
4
+ return parseInt(hash.name.slice(4), 10);
5
+ }
6
+ function checkHashLength(algorithm, expected) {
7
+ const actual = getHashLength(algorithm.hash);
8
+ if (actual !== expected)
9
+ throw unusable(`SHA-${expected}`, 'algorithm.hash');
10
+ }
11
+ function getNamedCurve(alg) {
12
+ switch (alg) {
13
+ case 'ES256':
14
+ return 'P-256';
15
+ case 'ES384':
16
+ return 'P-384';
17
+ case 'ES512':
18
+ return 'P-521';
19
+ default:
20
+ throw new Error('unreachable');
21
+ }
22
+ }
23
+ function checkUsage(key, usage) {
24
+ if (usage && !key.usages.includes(usage)) {
25
+ throw new TypeError(`CryptoKey does not support this operation, its usages must include ${usage}.`);
26
+ }
27
+ }
28
+ export function checkSigCryptoKey(key, alg, usage) {
29
+ switch (alg) {
30
+ case 'HS256':
31
+ case 'HS384':
32
+ case 'HS512': {
33
+ if (!isAlgorithm(key.algorithm, 'HMAC'))
34
+ throw unusable('HMAC');
35
+ checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
36
+ break;
37
+ }
38
+ case 'RS256':
39
+ case 'RS384':
40
+ case 'RS512': {
41
+ if (!isAlgorithm(key.algorithm, 'RSASSA-PKCS1-v1_5'))
42
+ throw unusable('RSASSA-PKCS1-v1_5');
43
+ checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
44
+ break;
45
+ }
46
+ case 'PS256':
47
+ case 'PS384':
48
+ case 'PS512': {
49
+ if (!isAlgorithm(key.algorithm, 'RSA-PSS'))
50
+ throw unusable('RSA-PSS');
51
+ checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
52
+ break;
53
+ }
54
+ case 'Ed25519':
55
+ case 'EdDSA': {
56
+ if (!isAlgorithm(key.algorithm, 'Ed25519'))
57
+ throw unusable('Ed25519');
58
+ break;
59
+ }
60
+ case 'ML-DSA-44':
61
+ case 'ML-DSA-65':
62
+ case 'ML-DSA-87': {
63
+ if (!isAlgorithm(key.algorithm, alg))
64
+ throw unusable(alg);
65
+ break;
66
+ }
67
+ case 'ES256':
68
+ case 'ES384':
69
+ case 'ES512': {
70
+ if (!isAlgorithm(key.algorithm, 'ECDSA'))
71
+ throw unusable('ECDSA');
72
+ const expected = getNamedCurve(alg);
73
+ const actual = key.algorithm.namedCurve;
74
+ if (actual !== expected)
75
+ throw unusable(expected, 'algorithm.namedCurve');
76
+ break;
77
+ }
78
+ default:
79
+ throw new TypeError('CryptoKey does not support this operation');
80
+ }
81
+ checkUsage(key, usage);
82
+ }
83
+ export function checkEncCryptoKey(key, alg, usage) {
84
+ switch (alg) {
85
+ case 'A128GCM':
86
+ case 'A192GCM':
87
+ case 'A256GCM': {
88
+ if (!isAlgorithm(key.algorithm, 'AES-GCM'))
89
+ throw unusable('AES-GCM');
90
+ const expected = parseInt(alg.slice(1, 4), 10);
91
+ const actual = key.algorithm.length;
92
+ if (actual !== expected)
93
+ throw unusable(expected, 'algorithm.length');
94
+ break;
95
+ }
96
+ case 'A128KW':
97
+ case 'A192KW':
98
+ case 'A256KW': {
99
+ if (!isAlgorithm(key.algorithm, 'AES-KW'))
100
+ throw unusable('AES-KW');
101
+ const expected = parseInt(alg.slice(1, 4), 10);
102
+ const actual = key.algorithm.length;
103
+ if (actual !== expected)
104
+ throw unusable(expected, 'algorithm.length');
105
+ break;
106
+ }
107
+ case 'ECDH': {
108
+ switch (key.algorithm.name) {
109
+ case 'ECDH':
110
+ case 'X25519':
111
+ break;
112
+ default:
113
+ throw unusable('ECDH or X25519');
114
+ }
115
+ break;
116
+ }
117
+ case 'PBES2-HS256+A128KW':
118
+ case 'PBES2-HS384+A192KW':
119
+ case 'PBES2-HS512+A256KW':
120
+ if (!isAlgorithm(key.algorithm, 'PBKDF2'))
121
+ throw unusable('PBKDF2');
122
+ break;
123
+ case 'RSA-OAEP':
124
+ case 'RSA-OAEP-256':
125
+ case 'RSA-OAEP-384':
126
+ case 'RSA-OAEP-512': {
127
+ if (!isAlgorithm(key.algorithm, 'RSA-OAEP'))
128
+ throw unusable('RSA-OAEP');
129
+ checkHashLength(key.algorithm, parseInt(alg.slice(9), 10) || 1);
130
+ break;
131
+ }
132
+ default:
133
+ throw new TypeError('CryptoKey does not support this operation');
134
+ }
135
+ checkUsage(key, usage);
136
+ }
@@ -0,0 +1,44 @@
1
+ import { JOSENotSupported, JWEInvalid } from '../util/errors.js';
2
+ import { concat } from './buffer_utils.js';
3
+ function supported(name) {
4
+ if (typeof globalThis[name] === 'undefined') {
5
+ throw new JOSENotSupported(`JWE "zip" (Compression Algorithm) Header Parameter requires the ${name} API.`);
6
+ }
7
+ }
8
+ export async function compress(input) {
9
+ supported('CompressionStream');
10
+ const cs = new CompressionStream('deflate-raw');
11
+ const writer = cs.writable.getWriter();
12
+ writer.write(input).catch(() => { });
13
+ writer.close().catch(() => { });
14
+ const chunks = [];
15
+ const reader = cs.readable.getReader();
16
+ for (;;) {
17
+ const { value, done } = await reader.read();
18
+ if (done)
19
+ break;
20
+ chunks.push(value);
21
+ }
22
+ return concat(...chunks);
23
+ }
24
+ export async function decompress(input, maxLength) {
25
+ supported('DecompressionStream');
26
+ const ds = new DecompressionStream('deflate-raw');
27
+ const writer = ds.writable.getWriter();
28
+ writer.write(input).catch(() => { });
29
+ writer.close().catch(() => { });
30
+ const chunks = [];
31
+ let length = 0;
32
+ const reader = ds.readable.getReader();
33
+ for (;;) {
34
+ const { value, done } = await reader.read();
35
+ if (done)
36
+ break;
37
+ chunks.push(value);
38
+ length += value.byteLength;
39
+ if (maxLength !== Infinity && length > maxLength) {
40
+ throw new JWEInvalid('Decompressed plaintext exceeded the configured limit');
41
+ }
42
+ }
43
+ return concat(...chunks);
44
+ }
@@ -0,0 +1,52 @@
1
+ import { encode, concat, uint32be } from './buffer_utils.js';
2
+ import { checkEncCryptoKey } from './crypto_key.js';
3
+ import { digest } from './helpers.js';
4
+ function lengthAndInput(input) {
5
+ return concat(uint32be(input.length), input);
6
+ }
7
+ async function concatKdf(Z, L, OtherInfo) {
8
+ const dkLen = L >> 3;
9
+ const hashLen = 32;
10
+ const reps = Math.ceil(dkLen / hashLen);
11
+ const dk = new Uint8Array(reps * hashLen);
12
+ for (let i = 1; i <= reps; i++) {
13
+ const hashInput = new Uint8Array(4 + Z.length + OtherInfo.length);
14
+ hashInput.set(uint32be(i), 0);
15
+ hashInput.set(Z, 4);
16
+ hashInput.set(OtherInfo, 4 + Z.length);
17
+ const hashResult = await digest('sha256', hashInput);
18
+ dk.set(hashResult, (i - 1) * hashLen);
19
+ }
20
+ return dk.slice(0, dkLen);
21
+ }
22
+ export async function deriveKey(publicKey, privateKey, algorithm, keyLength, apu = new Uint8Array(), apv = new Uint8Array()) {
23
+ checkEncCryptoKey(publicKey, 'ECDH');
24
+ checkEncCryptoKey(privateKey, 'ECDH', 'deriveBits');
25
+ const algorithmID = lengthAndInput(encode(algorithm));
26
+ const partyUInfo = lengthAndInput(apu);
27
+ const partyVInfo = lengthAndInput(apv);
28
+ const suppPubInfo = uint32be(keyLength);
29
+ const suppPrivInfo = new Uint8Array();
30
+ const otherInfo = concat(algorithmID, partyUInfo, partyVInfo, suppPubInfo, suppPrivInfo);
31
+ const Z = new Uint8Array(await crypto.subtle.deriveBits({
32
+ name: publicKey.algorithm.name,
33
+ public: publicKey,
34
+ }, privateKey, getEcdhBitLength(publicKey)));
35
+ return concatKdf(Z, keyLength, otherInfo);
36
+ }
37
+ function getEcdhBitLength(publicKey) {
38
+ if (publicKey.algorithm.name === 'X25519') {
39
+ return 256;
40
+ }
41
+ return (Math.ceil(parseInt(publicKey.algorithm.namedCurve.slice(-3), 10) / 8) << 3);
42
+ }
43
+ export function allowed(key) {
44
+ switch (key.algorithm.namedCurve) {
45
+ case 'P-256':
46
+ case 'P-384':
47
+ case 'P-521':
48
+ return true;
49
+ default:
50
+ return key.algorithm.name === 'X25519';
51
+ }
52
+ }
@@ -0,0 +1,19 @@
1
+ import { decode } from '../util/base64url.js';
2
+ export const unprotected = Symbol();
3
+ export function assertNotSet(value, name) {
4
+ if (value) {
5
+ throw new TypeError(`${name} can only be called once`);
6
+ }
7
+ }
8
+ export function decodeBase64url(value, label, ErrorClass) {
9
+ try {
10
+ return decode(value);
11
+ }
12
+ catch {
13
+ throw new ErrorClass(`Failed to base64url decode the ${label}`);
14
+ }
15
+ }
16
+ export async function digest(algorithm, data) {
17
+ const subtleDigest = `SHA-${algorithm.slice(-3)}`;
18
+ return new Uint8Array(await crypto.subtle.digest(subtleDigest, data));
19
+ }
@@ -0,0 +1,27 @@
1
+ function message(msg, actual, ...types) {
2
+ types = types.filter(Boolean);
3
+ if (types.length > 2) {
4
+ const last = types.pop();
5
+ msg += `one of type ${types.join(', ')}, or ${last}.`;
6
+ }
7
+ else if (types.length === 2) {
8
+ msg += `one of type ${types[0]} or ${types[1]}.`;
9
+ }
10
+ else {
11
+ msg += `of type ${types[0]}.`;
12
+ }
13
+ if (actual == null) {
14
+ msg += ` Received ${actual}`;
15
+ }
16
+ else if (typeof actual === 'function' && actual.name) {
17
+ msg += ` Received function ${actual.name}`;
18
+ }
19
+ else if (typeof actual === 'object' && actual != null) {
20
+ if (actual.constructor?.name) {
21
+ msg += ` Received an instance of ${actual.constructor.name}`;
22
+ }
23
+ }
24
+ return msg;
25
+ }
26
+ export const invalidKeyInput = (actual, ...types) => message('Key must be ', actual, ...types);
27
+ export const withAlg = (alg, actual, ...types) => message(`Key for the ${alg} algorithm must be `, actual, ...types);
@@ -0,0 +1,17 @@
1
+ export function assertCryptoKey(key) {
2
+ if (!isCryptoKey(key)) {
3
+ throw new Error('CryptoKey instance expected');
4
+ }
5
+ }
6
+ export const isCryptoKey = (key) => {
7
+ if (key?.[Symbol.toStringTag] === 'CryptoKey')
8
+ return true;
9
+ try {
10
+ return key instanceof CryptoKey;
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ };
16
+ export const isKeyObject = (key) => key?.[Symbol.toStringTag] === 'KeyObject';
17
+ export const isKeyLike = (key) => isCryptoKey(key) || isKeyObject(key);
@@ -0,0 +1,107 @@
1
+ import { JOSENotSupported } from '../util/errors.js';
2
+ const unsupportedAlg = 'Invalid or unsupported JWK "alg" (Algorithm) Parameter value';
3
+ function subtleMapping(jwk) {
4
+ let algorithm;
5
+ let keyUsages;
6
+ switch (jwk.kty) {
7
+ case 'AKP': {
8
+ switch (jwk.alg) {
9
+ case 'ML-DSA-44':
10
+ case 'ML-DSA-65':
11
+ case 'ML-DSA-87':
12
+ algorithm = { name: jwk.alg };
13
+ keyUsages = jwk.priv ? ['sign'] : ['verify'];
14
+ break;
15
+ default:
16
+ throw new JOSENotSupported(unsupportedAlg);
17
+ }
18
+ break;
19
+ }
20
+ case 'RSA': {
21
+ switch (jwk.alg) {
22
+ case 'PS256':
23
+ case 'PS384':
24
+ case 'PS512':
25
+ algorithm = { name: 'RSA-PSS', hash: `SHA-${jwk.alg.slice(-3)}` };
26
+ keyUsages = jwk.d ? ['sign'] : ['verify'];
27
+ break;
28
+ case 'RS256':
29
+ case 'RS384':
30
+ case 'RS512':
31
+ algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${jwk.alg.slice(-3)}` };
32
+ keyUsages = jwk.d ? ['sign'] : ['verify'];
33
+ break;
34
+ case 'RSA-OAEP':
35
+ case 'RSA-OAEP-256':
36
+ case 'RSA-OAEP-384':
37
+ case 'RSA-OAEP-512':
38
+ algorithm = {
39
+ name: 'RSA-OAEP',
40
+ hash: `SHA-${parseInt(jwk.alg.slice(-3), 10) || 1}`,
41
+ };
42
+ keyUsages = jwk.d ? ['decrypt', 'unwrapKey'] : ['encrypt', 'wrapKey'];
43
+ break;
44
+ default:
45
+ throw new JOSENotSupported(unsupportedAlg);
46
+ }
47
+ break;
48
+ }
49
+ case 'EC': {
50
+ switch (jwk.alg) {
51
+ case 'ES256':
52
+ case 'ES384':
53
+ case 'ES512':
54
+ algorithm = {
55
+ name: 'ECDSA',
56
+ namedCurve: { ES256: 'P-256', ES384: 'P-384', ES512: 'P-521' }[jwk.alg],
57
+ };
58
+ keyUsages = jwk.d ? ['sign'] : ['verify'];
59
+ break;
60
+ case 'ECDH-ES':
61
+ case 'ECDH-ES+A128KW':
62
+ case 'ECDH-ES+A192KW':
63
+ case 'ECDH-ES+A256KW':
64
+ algorithm = { name: 'ECDH', namedCurve: jwk.crv };
65
+ keyUsages = jwk.d ? ['deriveBits'] : [];
66
+ break;
67
+ default:
68
+ throw new JOSENotSupported(unsupportedAlg);
69
+ }
70
+ break;
71
+ }
72
+ case 'OKP': {
73
+ switch (jwk.alg) {
74
+ case 'Ed25519':
75
+ case 'EdDSA':
76
+ algorithm = { name: 'Ed25519' };
77
+ keyUsages = jwk.d ? ['sign'] : ['verify'];
78
+ break;
79
+ case 'ECDH-ES':
80
+ case 'ECDH-ES+A128KW':
81
+ case 'ECDH-ES+A192KW':
82
+ case 'ECDH-ES+A256KW':
83
+ algorithm = { name: jwk.crv };
84
+ keyUsages = jwk.d ? ['deriveBits'] : [];
85
+ break;
86
+ default:
87
+ throw new JOSENotSupported(unsupportedAlg);
88
+ }
89
+ break;
90
+ }
91
+ default:
92
+ throw new JOSENotSupported('Invalid or unsupported JWK "kty" (Key Type) Parameter value');
93
+ }
94
+ return { algorithm, keyUsages };
95
+ }
96
+ export async function jwkToKey(jwk) {
97
+ if (!jwk.alg) {
98
+ throw new TypeError('"alg" argument is required when "jwk.alg" is not present');
99
+ }
100
+ const { algorithm, keyUsages } = subtleMapping(jwk);
101
+ const keyData = { ...jwk };
102
+ if (keyData.kty !== 'AKP') {
103
+ delete keyData.alg;
104
+ }
105
+ delete keyData.use;
106
+ return crypto.subtle.importKey('jwk', keyData, algorithm, jwk.ext ?? (jwk.d || jwk.priv ? false : true), jwk.key_ops ?? keyUsages);
107
+ }