@ricsam/quickjs-crypto 0.2.15 → 0.2.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -6
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/subtle-crypto.cjs +60 -47
- package/dist/cjs/subtle-crypto.cjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/subtle-crypto.mjs +60 -47
- package/dist/mjs/subtle-crypto.mjs.map +3 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
# @ricsam/quickjs-crypto
|
|
2
2
|
|
|
3
|
-
Web Crypto API implementation
|
|
3
|
+
Web Crypto API implementation for QuickJS runtime.
|
|
4
|
+
|
|
5
|
+
> **Note**: This is a low-level package. For most use cases, use [`@ricsam/quickjs-runtime`](../runtime) with `createRuntime()` instead.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bun add @ricsam/quickjs-crypto
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Setup
|
|
4
14
|
|
|
5
15
|
```typescript
|
|
6
16
|
import { setupCrypto } from "@ricsam/quickjs-crypto";
|
|
@@ -8,12 +18,13 @@ import { setupCrypto } from "@ricsam/quickjs-crypto";
|
|
|
8
18
|
const handle = setupCrypto(context);
|
|
9
19
|
```
|
|
10
20
|
|
|
11
|
-
|
|
21
|
+
## Injected Globals
|
|
22
|
+
|
|
12
23
|
- `crypto.getRandomValues(array)` - Fill a TypedArray with random bytes
|
|
13
24
|
- `crypto.randomUUID()` - Generate a random UUID v4
|
|
14
25
|
- `crypto.subtle` - SubtleCrypto interface for cryptographic operations
|
|
15
26
|
|
|
16
|
-
|
|
27
|
+
## Usage in QuickJS
|
|
17
28
|
|
|
18
29
|
```javascript
|
|
19
30
|
// Generate random bytes
|
|
@@ -51,7 +62,7 @@ const decrypted = await crypto.subtle.decrypt(
|
|
|
51
62
|
);
|
|
52
63
|
```
|
|
53
64
|
|
|
54
|
-
|
|
65
|
+
## SubtleCrypto Methods
|
|
55
66
|
|
|
56
67
|
| Method | Description |
|
|
57
68
|
|--------|-------------|
|
|
@@ -63,7 +74,8 @@ const decrypted = await crypto.subtle.decrypt(
|
|
|
63
74
|
| `deriveBits` / `deriveKey` | Derive keys (PBKDF2, ECDH) |
|
|
64
75
|
| `wrapKey` / `unwrapKey` | Wrap/unwrap keys for secure transport |
|
|
65
76
|
|
|
66
|
-
|
|
77
|
+
## Supported Algorithms
|
|
78
|
+
|
|
67
79
|
- **Encryption**: AES-GCM, AES-CBC
|
|
68
80
|
- **Signing**: HMAC, ECDSA
|
|
69
81
|
- **Hashing**: SHA-256, SHA-384, SHA-512
|
|
@@ -72,4 +84,4 @@ const decrypted = await crypto.subtle.decrypt(
|
|
|
72
84
|
|
|
73
85
|
> **Note**: Cryptographic operations are delegated to the host's native `crypto.subtle` implementation, ensuring secure and performant cryptography.
|
|
74
86
|
|
|
75
|
-
**See also:** [MDN Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API)
|
|
87
|
+
**See also:** [MDN Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API)
|
package/dist/cjs/package.json
CHANGED
|
@@ -95,7 +95,7 @@ function getArg(args, index) {
|
|
|
95
95
|
}
|
|
96
96
|
return arg;
|
|
97
97
|
}
|
|
98
|
-
function createSubtleMethod(context, methodName, unmarshalArgs, implementation) {
|
|
98
|
+
function createSubtleMethod(context, methodName, unmarshalArgs, implementation, marshalResult) {
|
|
99
99
|
return context.newFunction(methodName, (...args) => {
|
|
100
100
|
const deferred = context.newPromise();
|
|
101
101
|
let unmarshaledArgs;
|
|
@@ -112,11 +112,21 @@ function createSubtleMethod(context, methodName, unmarshalArgs, implementation)
|
|
|
112
112
|
return deferred.handle;
|
|
113
113
|
}
|
|
114
114
|
Promise.resolve().then(async () => {
|
|
115
|
+
if (!context.alive) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
115
118
|
try {
|
|
116
|
-
const
|
|
119
|
+
const rawResult = await implementation(unmarshaledArgs);
|
|
120
|
+
if (!context.alive) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const resultHandle = marshalResult(context, rawResult);
|
|
117
124
|
deferred.resolve(resultHandle);
|
|
118
125
|
resultHandle.dispose();
|
|
119
126
|
} catch (error) {
|
|
127
|
+
if (!context.alive) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
120
130
|
const errorHandle = import_quickjs_core.marshal(context, {
|
|
121
131
|
name: error instanceof Error ? error.name : "Error",
|
|
122
132
|
message: error instanceof Error ? error.message : String(error)
|
|
@@ -124,7 +134,9 @@ function createSubtleMethod(context, methodName, unmarshalArgs, implementation)
|
|
|
124
134
|
deferred.reject(errorHandle);
|
|
125
135
|
errorHandle.dispose();
|
|
126
136
|
}
|
|
127
|
-
context.
|
|
137
|
+
if (context.alive) {
|
|
138
|
+
context.runtime.executePendingJobs();
|
|
139
|
+
}
|
|
128
140
|
});
|
|
129
141
|
return deferred.handle;
|
|
130
142
|
});
|
|
@@ -134,22 +146,28 @@ function createSubtleCryptoObject(context) {
|
|
|
134
146
|
const digestFn = createSubtleMethod(context, "digest", (ctx, args) => ({
|
|
135
147
|
algorithm: import_quickjs_core.unmarshal(ctx, getArg(args, 0)),
|
|
136
148
|
data: import_quickjs_core.unmarshal(ctx, getArg(args, 1))
|
|
137
|
-
}), async (
|
|
149
|
+
}), async ({ algorithm, data }) => {
|
|
138
150
|
const result = await crypto.subtle.digest(algorithm, data);
|
|
139
|
-
return
|
|
140
|
-
});
|
|
151
|
+
return new Uint8Array(result);
|
|
152
|
+
}, (ctx, result) => import_quickjs_core.marshal(ctx, result));
|
|
141
153
|
context.setProp(subtle, "digest", digestFn);
|
|
142
154
|
digestFn.dispose();
|
|
143
155
|
const generateKeyFn = createSubtleMethod(context, "generateKey", (ctx, args) => ({
|
|
144
156
|
algorithm: import_quickjs_core.unmarshal(ctx, getArg(args, 0)),
|
|
145
157
|
extractable: import_quickjs_core.unmarshal(ctx, getArg(args, 1)),
|
|
146
158
|
keyUsages: import_quickjs_core.unmarshal(ctx, getArg(args, 2))
|
|
147
|
-
}), async (
|
|
159
|
+
}), async ({ algorithm, extractable, keyUsages }) => {
|
|
148
160
|
const result = await crypto.subtle.generateKey(algorithm, extractable, keyUsages);
|
|
149
161
|
if ("publicKey" in result && "privateKey" in result) {
|
|
150
|
-
return
|
|
162
|
+
return { type: "pair", publicKey: result.publicKey, privateKey: result.privateKey };
|
|
163
|
+
} else {
|
|
164
|
+
return { type: "key", hostKey: result };
|
|
165
|
+
}
|
|
166
|
+
}, (ctx, result) => {
|
|
167
|
+
if (result.type === "pair") {
|
|
168
|
+
return createCryptoKeyPairInstance(ctx, { publicKey: result.publicKey, privateKey: result.privateKey });
|
|
151
169
|
} else {
|
|
152
|
-
return createCryptoKeyInstance(ctx, result);
|
|
170
|
+
return createCryptoKeyInstance(ctx, result.hostKey);
|
|
153
171
|
}
|
|
154
172
|
});
|
|
155
173
|
context.setProp(subtle, "generateKey", generateKeyFn);
|
|
@@ -158,10 +176,10 @@ function createSubtleCryptoObject(context) {
|
|
|
158
176
|
algorithm: import_quickjs_core.unmarshal(ctx, getArg(args, 0)),
|
|
159
177
|
key: getHostKey(ctx, getArg(args, 1)),
|
|
160
178
|
data: import_quickjs_core.unmarshal(ctx, getArg(args, 2))
|
|
161
|
-
}), async (
|
|
179
|
+
}), async ({ algorithm, key, data }) => {
|
|
162
180
|
const result = await crypto.subtle.sign(algorithm, key, data);
|
|
163
|
-
return
|
|
164
|
-
});
|
|
181
|
+
return new Uint8Array(result);
|
|
182
|
+
}, (ctx, result) => import_quickjs_core.marshal(ctx, result));
|
|
165
183
|
context.setProp(subtle, "sign", signFn);
|
|
166
184
|
signFn.dispose();
|
|
167
185
|
const verifyFn = createSubtleMethod(context, "verify", (ctx, args) => ({
|
|
@@ -169,30 +187,29 @@ function createSubtleCryptoObject(context) {
|
|
|
169
187
|
key: getHostKey(ctx, getArg(args, 1)),
|
|
170
188
|
signature: import_quickjs_core.unmarshal(ctx, getArg(args, 2)),
|
|
171
189
|
data: import_quickjs_core.unmarshal(ctx, getArg(args, 3))
|
|
172
|
-
}), async (
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
});
|
|
190
|
+
}), async ({ algorithm, key, signature, data }) => {
|
|
191
|
+
return await crypto.subtle.verify(algorithm, key, signature, data);
|
|
192
|
+
}, (ctx, result) => import_quickjs_core.marshal(ctx, result));
|
|
176
193
|
context.setProp(subtle, "verify", verifyFn);
|
|
177
194
|
verifyFn.dispose();
|
|
178
195
|
const encryptFn = createSubtleMethod(context, "encrypt", (ctx, args) => ({
|
|
179
196
|
algorithm: import_quickjs_core.unmarshal(ctx, getArg(args, 0)),
|
|
180
197
|
key: getHostKey(ctx, getArg(args, 1)),
|
|
181
198
|
data: import_quickjs_core.unmarshal(ctx, getArg(args, 2))
|
|
182
|
-
}), async (
|
|
199
|
+
}), async ({ algorithm, key, data }) => {
|
|
183
200
|
const result = await crypto.subtle.encrypt(algorithm, key, data);
|
|
184
|
-
return
|
|
185
|
-
});
|
|
201
|
+
return new Uint8Array(result);
|
|
202
|
+
}, (ctx, result) => import_quickjs_core.marshal(ctx, result));
|
|
186
203
|
context.setProp(subtle, "encrypt", encryptFn);
|
|
187
204
|
encryptFn.dispose();
|
|
188
205
|
const decryptFn = createSubtleMethod(context, "decrypt", (ctx, args) => ({
|
|
189
206
|
algorithm: import_quickjs_core.unmarshal(ctx, getArg(args, 0)),
|
|
190
207
|
key: getHostKey(ctx, getArg(args, 1)),
|
|
191
208
|
data: import_quickjs_core.unmarshal(ctx, getArg(args, 2))
|
|
192
|
-
}), async (
|
|
209
|
+
}), async ({ algorithm, key, data }) => {
|
|
193
210
|
const result = await crypto.subtle.decrypt(algorithm, key, data);
|
|
194
|
-
return
|
|
195
|
-
});
|
|
211
|
+
return new Uint8Array(result);
|
|
212
|
+
}, (ctx, result) => import_quickjs_core.marshal(ctx, result));
|
|
196
213
|
context.setProp(subtle, "decrypt", decryptFn);
|
|
197
214
|
decryptFn.dispose();
|
|
198
215
|
const importKeyFn = createSubtleMethod(context, "importKey", (ctx, args) => ({
|
|
@@ -201,10 +218,9 @@ function createSubtleCryptoObject(context) {
|
|
|
201
218
|
algorithm: import_quickjs_core.unmarshal(ctx, getArg(args, 2)),
|
|
202
219
|
extractable: import_quickjs_core.unmarshal(ctx, getArg(args, 3)),
|
|
203
220
|
keyUsages: import_quickjs_core.unmarshal(ctx, getArg(args, 4))
|
|
204
|
-
}), async (
|
|
205
|
-
let result;
|
|
221
|
+
}), async ({ format, keyData, algorithm, extractable, keyUsages }) => {
|
|
206
222
|
if (format === "jwk") {
|
|
207
|
-
|
|
223
|
+
return await crypto.subtle.importKey(format, keyData, algorithm, extractable, keyUsages);
|
|
208
224
|
} else {
|
|
209
225
|
let data;
|
|
210
226
|
if (keyData instanceof Uint8Array) {
|
|
@@ -212,23 +228,22 @@ function createSubtleCryptoObject(context) {
|
|
|
212
228
|
} else {
|
|
213
229
|
data = keyData;
|
|
214
230
|
}
|
|
215
|
-
|
|
231
|
+
return await crypto.subtle.importKey(format, data, algorithm, extractable, keyUsages);
|
|
216
232
|
}
|
|
217
|
-
|
|
218
|
-
});
|
|
233
|
+
}, (ctx, result) => createCryptoKeyInstance(ctx, result));
|
|
219
234
|
context.setProp(subtle, "importKey", importKeyFn);
|
|
220
235
|
importKeyFn.dispose();
|
|
221
236
|
const exportKeyFn = createSubtleMethod(context, "exportKey", (ctx, args) => ({
|
|
222
237
|
format: import_quickjs_core.unmarshal(ctx, getArg(args, 0)),
|
|
223
238
|
key: getHostKey(ctx, getArg(args, 1))
|
|
224
|
-
}), async (
|
|
239
|
+
}), async ({ format, key }) => {
|
|
225
240
|
const result = await crypto.subtle.exportKey(format, key);
|
|
226
241
|
if (result instanceof ArrayBuffer) {
|
|
227
|
-
return
|
|
242
|
+
return new Uint8Array(result);
|
|
228
243
|
} else {
|
|
229
|
-
return
|
|
244
|
+
return result;
|
|
230
245
|
}
|
|
231
|
-
});
|
|
246
|
+
}, (ctx, result) => import_quickjs_core.marshal(ctx, result));
|
|
232
247
|
context.setProp(subtle, "exportKey", exportKeyFn);
|
|
233
248
|
exportKeyFn.dispose();
|
|
234
249
|
const deriveBitsFn = createSubtleMethod(context, "deriveBits", (ctx, args) => {
|
|
@@ -246,10 +261,10 @@ function createSubtleCryptoObject(context) {
|
|
|
246
261
|
}
|
|
247
262
|
}
|
|
248
263
|
return { algorithm, baseKey, length };
|
|
249
|
-
}, async (
|
|
264
|
+
}, async ({ algorithm, baseKey, length }) => {
|
|
250
265
|
const result = await crypto.subtle.deriveBits(algorithm, baseKey, length);
|
|
251
|
-
return
|
|
252
|
-
});
|
|
266
|
+
return new Uint8Array(result);
|
|
267
|
+
}, (ctx, result) => import_quickjs_core.marshal(ctx, result));
|
|
253
268
|
context.setProp(subtle, "deriveBits", deriveBitsFn);
|
|
254
269
|
deriveBitsFn.dispose();
|
|
255
270
|
const deriveKeyFn = createSubtleMethod(context, "deriveKey", (ctx, args) => {
|
|
@@ -269,10 +284,9 @@ function createSubtleCryptoObject(context) {
|
|
|
269
284
|
}
|
|
270
285
|
}
|
|
271
286
|
return { algorithm, baseKey, derivedKeyType, extractable, keyUsages };
|
|
272
|
-
}, async (
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
});
|
|
287
|
+
}, async ({ algorithm, baseKey, derivedKeyType, extractable, keyUsages }) => {
|
|
288
|
+
return await crypto.subtle.deriveKey(algorithm, baseKey, derivedKeyType, extractable, keyUsages);
|
|
289
|
+
}, (ctx, result) => createCryptoKeyInstance(ctx, result));
|
|
276
290
|
context.setProp(subtle, "deriveKey", deriveKeyFn);
|
|
277
291
|
deriveKeyFn.dispose();
|
|
278
292
|
const wrapKeyFn = createSubtleMethod(context, "wrapKey", (ctx, args) => ({
|
|
@@ -280,10 +294,10 @@ function createSubtleCryptoObject(context) {
|
|
|
280
294
|
key: getHostKey(ctx, getArg(args, 1)),
|
|
281
295
|
wrappingKey: getHostKey(ctx, getArg(args, 2)),
|
|
282
296
|
wrapAlgorithm: import_quickjs_core.unmarshal(ctx, getArg(args, 3))
|
|
283
|
-
}), async (
|
|
297
|
+
}), async ({ format, key, wrappingKey, wrapAlgorithm }) => {
|
|
284
298
|
const result = await crypto.subtle.wrapKey(format, key, wrappingKey, wrapAlgorithm);
|
|
285
|
-
return
|
|
286
|
-
});
|
|
299
|
+
return new Uint8Array(result);
|
|
300
|
+
}, (ctx, result) => import_quickjs_core.marshal(ctx, result));
|
|
287
301
|
context.setProp(subtle, "wrapKey", wrapKeyFn);
|
|
288
302
|
wrapKeyFn.dispose();
|
|
289
303
|
const unwrapKeyFn = createSubtleMethod(context, "unwrapKey", (ctx, args) => ({
|
|
@@ -294,14 +308,13 @@ function createSubtleCryptoObject(context) {
|
|
|
294
308
|
unwrappedKeyAlgorithm: import_quickjs_core.unmarshal(ctx, getArg(args, 4)),
|
|
295
309
|
extractable: import_quickjs_core.unmarshal(ctx, getArg(args, 5)),
|
|
296
310
|
keyUsages: import_quickjs_core.unmarshal(ctx, getArg(args, 6))
|
|
297
|
-
}), async (
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
});
|
|
311
|
+
}), async ({ format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages }) => {
|
|
312
|
+
return await crypto.subtle.unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages);
|
|
313
|
+
}, (ctx, result) => createCryptoKeyInstance(ctx, result));
|
|
301
314
|
context.setProp(subtle, "unwrapKey", unwrapKeyFn);
|
|
302
315
|
unwrapKeyFn.dispose();
|
|
303
316
|
return subtle;
|
|
304
317
|
}
|
|
305
318
|
})
|
|
306
319
|
|
|
307
|
-
//# debugId=
|
|
320
|
+
//# debugId=44813671DCFC8D8164756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/subtle-crypto.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { CryptoKeyState, KeyUsage } from \"./types.cjs\";\nimport {\n nextInstanceId,\n registerInstance,\n getInstanceStateById,\n marshal,\n unmarshal,\n} from \"@ricsam/quickjs-core\";\n\n/**\n * Helper to create a CryptoKey instance in QuickJS from a host CryptoKey\n *\n * This registers the host key in our state management and creates\n * a QuickJS CryptoKey object that references it via __instanceId__\n */\nexport function createCryptoKeyInstance(\n context: QuickJSContext,\n hostKey: globalThis.CryptoKey\n): QuickJSHandle {\n const instanceId = nextInstanceId();\n\n const state: CryptoKeyState = {\n hostKey,\n type: hostKey.type,\n extractable: hostKey.extractable,\n algorithm: hostKey.algorithm as KeyAlgorithm,\n usages: Array.from(hostKey.usages) as KeyUsage[],\n };\n\n registerInstance(instanceId, \"CryptoKey\", state);\n\n // Create instance via evalCode to properly instantiate with prototype chain\n const result = context.evalCode(`\n (function() {\n const key = Object.create(CryptoKey.prototype);\n Object.defineProperty(key, '__instanceId__', {\n value: ${instanceId},\n enumerable: false,\n writable: false,\n configurable: false\n });\n return key;\n })()\n `);\n\n if (result.error) {\n const err = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to create CryptoKey instance: ${JSON.stringify(err)}`);\n }\n\n return result.value;\n}\n\n/**\n * Helper to create a CryptoKeyPair object in QuickJS\n */\nfunction createCryptoKeyPairInstance(\n context: QuickJSContext,\n keyPair: globalThis.CryptoKeyPair\n): QuickJSHandle {\n const publicKeyHandle = createCryptoKeyInstance(context, keyPair.publicKey);\n const privateKeyHandle = createCryptoKeyInstance(context, keyPair.privateKey);\n\n const obj = context.newObject();\n context.setProp(obj, \"publicKey\", publicKeyHandle);\n context.setProp(obj, \"privateKey\", privateKeyHandle);\n\n publicKeyHandle.dispose();\n privateKeyHandle.dispose();\n\n return obj;\n}\n\n/**\n * Helper to get the host CryptoKey from a QuickJS CryptoKey handle\n */\nfunction getHostKey(context: QuickJSContext, keyHandle: QuickJSHandle): globalThis.CryptoKey {\n const instanceIdHandle = context.getProp(keyHandle, \"__instanceId__\");\n if (context.typeof(instanceIdHandle) !== \"number\") {\n instanceIdHandle.dispose();\n throw new Error(\"Invalid CryptoKey: missing __instanceId__\");\n }\n\n const instanceId = context.getNumber(instanceIdHandle);\n instanceIdHandle.dispose();\n\n const state = getInstanceStateById<CryptoKeyState>(instanceId);\n if (!state) {\n throw new Error(\"Invalid CryptoKey: state not found\");\n }\n\n return state.hostKey;\n}\n\n/**\n * Helper to safely get an argument from the args array\n */\nfunction getArg(args: QuickJSHandle[], index: number): QuickJSHandle {\n const arg = args[index];\n if (!arg) {\n throw new Error(`Missing argument at index ${index}`);\n }\n return arg;\n}\n\n/**\n * Create an async SubtleCrypto method that handles CryptoKey marshalling\n *\n * @param unmarshalArgs - Function to unmarshal arguments synchronously before async work\n * @param implementation - Async implementation that receives unmarshaled args\n */\nfunction createSubtleMethod<T>(\n context: QuickJSContext,\n methodName: string,\n unmarshalArgs: (context: QuickJSContext, args: QuickJSHandle[]) => T,\n implementation: (context: QuickJSContext, unmarshaledArgs: T) => Promise<QuickJSHandle>\n): QuickJSHandle {\n return context.newFunction(methodName, (...args) => {\n const deferred = context.newPromise();\n\n // Unmarshal arguments synchronously BEFORE scheduling async work\n // This is critical because the QuickJS handles may be disposed before the microtask runs\n let unmarshaledArgs: T;\n try {\n unmarshaledArgs = unmarshalArgs(context, args);\n } catch (error) {\n // If unmarshalling fails, reject immediately\n const errorHandle = marshal(context, {\n name: error instanceof Error ? error.name : \"Error\",\n message: error instanceof Error ? error.message : String(error),\n });\n deferred.reject(errorHandle);\n errorHandle.dispose();\n context.runtime.executePendingJobs();\n return deferred.handle;\n }\n\n // Run the async implementation in a microtask\n Promise.resolve().then(async () => {\n try {\n const resultHandle = await implementation(context, unmarshaledArgs);\n deferred.resolve(resultHandle);\n resultHandle.dispose();\n } catch (error) {\n // Use marshal instead of newError to avoid issues with disposed context\n const errorHandle = marshal(context, {\n name: error instanceof Error ? error.name : \"Error\",\n message: error instanceof Error ? error.message : String(error),\n });\n deferred.reject(errorHandle);\n errorHandle.dispose();\n }\n context.runtime.executePendingJobs();\n });\n\n return deferred.handle;\n });\n}\n\n// Type definitions for unmarshaled args\ninterface DigestArgs {\n algorithm: AlgorithmIdentifier;\n data: Uint8Array;\n}\n\ninterface GenerateKeyArgs {\n algorithm: RsaHashedKeyGenParams | EcKeyGenParams | AesKeyGenParams | HmacKeyGenParams;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\ninterface SignArgs {\n algorithm: AlgorithmIdentifier;\n key: globalThis.CryptoKey;\n data: Uint8Array;\n}\n\ninterface VerifyArgs {\n algorithm: AlgorithmIdentifier;\n key: globalThis.CryptoKey;\n signature: Uint8Array;\n data: Uint8Array;\n}\n\ninterface EncryptDecryptArgs {\n algorithm: AlgorithmIdentifier;\n key: globalThis.CryptoKey;\n data: Uint8Array;\n}\n\ninterface ImportKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n keyData: Uint8Array | JsonWebKey;\n algorithm: AlgorithmIdentifier;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\ninterface ExportKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n key: globalThis.CryptoKey;\n}\n\ninterface DeriveBitsArgs {\n algorithm: Record<string, unknown>;\n baseKey: globalThis.CryptoKey;\n length: number;\n}\n\ninterface DeriveKeyArgs {\n algorithm: Record<string, unknown>;\n baseKey: globalThis.CryptoKey;\n derivedKeyType: AlgorithmIdentifier;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\ninterface WrapKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n key: globalThis.CryptoKey;\n wrappingKey: globalThis.CryptoKey;\n wrapAlgorithm: AlgorithmIdentifier;\n}\n\ninterface UnwrapKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n wrappedKey: Uint8Array;\n unwrappingKey: globalThis.CryptoKey;\n unwrapAlgorithm: AlgorithmIdentifier;\n unwrappedKeyAlgorithm: AlgorithmIdentifier;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\n/**\n * Create the SubtleCrypto object with all methods\n */\nexport function createSubtleCryptoObject(context: QuickJSContext): QuickJSHandle {\n const subtle = context.newObject();\n\n // digest(algorithm, data) -> ArrayBuffer\n const digestFn = createSubtleMethod<DigestArgs>(\n context,\n \"digest\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n data: unmarshal(ctx, getArg(args, 1)) as Uint8Array,\n }),\n async (ctx, { algorithm, data }) => {\n const result = await crypto.subtle.digest(algorithm, data as unknown as BufferSource);\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"digest\", digestFn);\n digestFn.dispose();\n\n // generateKey(algorithm, extractable, keyUsages) -> CryptoKey | CryptoKeyPair\n const generateKeyFn = createSubtleMethod<GenerateKeyArgs>(\n context,\n \"generateKey\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as GenerateKeyArgs[\"algorithm\"],\n extractable: unmarshal(ctx, getArg(args, 1)) as boolean,\n keyUsages: unmarshal(ctx, getArg(args, 2)) as globalThis.KeyUsage[],\n }),\n async (ctx, { algorithm, extractable, keyUsages }) => {\n const result = await crypto.subtle.generateKey(algorithm, extractable, keyUsages);\n\n // Check if it's a key pair or single key\n if (\"publicKey\" in result && \"privateKey\" in result) {\n return createCryptoKeyPairInstance(ctx, result);\n } else {\n return createCryptoKeyInstance(ctx, result as globalThis.CryptoKey);\n }\n }\n );\n context.setProp(subtle, \"generateKey\", generateKeyFn);\n generateKeyFn.dispose();\n\n // sign(algorithm, key, data) -> ArrayBuffer\n const signFn = createSubtleMethod<SignArgs>(\n context,\n \"sign\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n data: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n }),\n async (ctx, { algorithm, key, data }) => {\n const result = await crypto.subtle.sign(algorithm, key, data as unknown as BufferSource);\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"sign\", signFn);\n signFn.dispose();\n\n // verify(algorithm, key, signature, data) -> boolean\n const verifyFn = createSubtleMethod<VerifyArgs>(\n context,\n \"verify\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n signature: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n data: unmarshal(ctx, getArg(args, 3)) as Uint8Array,\n }),\n async (ctx, { algorithm, key, signature, data }) => {\n const result = await crypto.subtle.verify(\n algorithm,\n key,\n signature as unknown as BufferSource,\n data as unknown as BufferSource\n );\n return marshal(ctx, result);\n }\n );\n context.setProp(subtle, \"verify\", verifyFn);\n verifyFn.dispose();\n\n // encrypt(algorithm, key, data) -> ArrayBuffer\n const encryptFn = createSubtleMethod<EncryptDecryptArgs>(\n context,\n \"encrypt\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n data: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n }),\n async (ctx, { algorithm, key, data }) => {\n const result = await crypto.subtle.encrypt(\n algorithm,\n key,\n data as unknown as BufferSource\n );\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"encrypt\", encryptFn);\n encryptFn.dispose();\n\n // decrypt(algorithm, key, data) -> ArrayBuffer\n const decryptFn = createSubtleMethod<EncryptDecryptArgs>(\n context,\n \"decrypt\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n data: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n }),\n async (ctx, { algorithm, key, data }) => {\n const result = await crypto.subtle.decrypt(\n algorithm,\n key,\n data as unknown as BufferSource\n );\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"decrypt\", decryptFn);\n decryptFn.dispose();\n\n // importKey(format, keyData, algorithm, extractable, keyUsages) -> CryptoKey\n const importKeyFn = createSubtleMethod<ImportKeyArgs>(\n context,\n \"importKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as ImportKeyArgs[\"format\"],\n keyData: unmarshal(ctx, getArg(args, 1)) as Uint8Array | JsonWebKey,\n algorithm: unmarshal(ctx, getArg(args, 2)) as AlgorithmIdentifier,\n extractable: unmarshal(ctx, getArg(args, 3)) as boolean,\n keyUsages: unmarshal(ctx, getArg(args, 4)) as globalThis.KeyUsage[],\n }),\n async (ctx, { format, keyData, algorithm, extractable, keyUsages }) => {\n let result: globalThis.CryptoKey;\n\n if (format === \"jwk\") {\n // JWK format expects JsonWebKey\n result = await crypto.subtle.importKey(\n format,\n keyData as JsonWebKey,\n algorithm,\n extractable,\n keyUsages\n );\n } else {\n // Non-jwk formats expect BufferSource\n // Convert Uint8Array to ArrayBuffer\n let data: BufferSource;\n if (keyData instanceof Uint8Array) {\n data = keyData.buffer.slice(keyData.byteOffset, keyData.byteOffset + keyData.byteLength) as ArrayBuffer;\n } else {\n data = keyData as BufferSource;\n }\n\n result = await crypto.subtle.importKey(\n format,\n data,\n algorithm,\n extractable,\n keyUsages\n ) as globalThis.CryptoKey;\n }\n\n return createCryptoKeyInstance(ctx, result);\n }\n );\n context.setProp(subtle, \"importKey\", importKeyFn);\n importKeyFn.dispose();\n\n // exportKey(format, key) -> ArrayBuffer | JsonWebKey\n const exportKeyFn = createSubtleMethod<ExportKeyArgs>(\n context,\n \"exportKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as ExportKeyArgs[\"format\"],\n key: getHostKey(ctx, getArg(args, 1)),\n }),\n async (ctx, { format, key }) => {\n const result = await crypto.subtle.exportKey(format, key);\n\n if (result instanceof ArrayBuffer) {\n return marshal(ctx, new Uint8Array(result));\n } else {\n // JsonWebKey - marshal as plain object\n return marshal(ctx, result);\n }\n }\n );\n context.setProp(subtle, \"exportKey\", exportKeyFn);\n exportKeyFn.dispose();\n\n // deriveBits(algorithm, baseKey, length) -> ArrayBuffer\n const deriveBitsFn = createSubtleMethod<DeriveBitsArgs>(\n context,\n \"deriveBits\",\n (ctx, args) => {\n const algorithmRaw = unmarshal(ctx, getArg(args, 0)) as Record<string, unknown>;\n const baseKey = getHostKey(ctx, getArg(args, 1));\n const length = unmarshal(ctx, getArg(args, 2)) as number;\n\n // If the algorithm has a 'public' property, it needs to be a CryptoKey\n let algorithm = algorithmRaw;\n if (algorithmRaw.public && typeof algorithmRaw.public === \"object\") {\n const publicKeyData = algorithmRaw.public as { __instanceId__?: number };\n if (publicKeyData.__instanceId__ !== undefined) {\n const publicKeyState = getInstanceStateById<CryptoKeyState>(publicKeyData.__instanceId__);\n if (publicKeyState) {\n algorithm = { ...algorithmRaw, public: publicKeyState.hostKey };\n }\n }\n }\n\n return { algorithm, baseKey, length };\n },\n async (ctx, { algorithm, baseKey, length }) => {\n const result = await crypto.subtle.deriveBits(\n algorithm as unknown as AlgorithmIdentifier,\n baseKey,\n length\n );\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"deriveBits\", deriveBitsFn);\n deriveBitsFn.dispose();\n\n // deriveKey(algorithm, baseKey, derivedKeyType, extractable, keyUsages) -> CryptoKey\n const deriveKeyFn = createSubtleMethod<DeriveKeyArgs>(\n context,\n \"deriveKey\",\n (ctx, args) => {\n const algorithmRaw = unmarshal(ctx, getArg(args, 0)) as Record<string, unknown>;\n const baseKey = getHostKey(ctx, getArg(args, 1));\n const derivedKeyType = unmarshal(ctx, getArg(args, 2)) as AlgorithmIdentifier;\n const extractable = unmarshal(ctx, getArg(args, 3)) as boolean;\n const keyUsages = unmarshal(ctx, getArg(args, 4)) as globalThis.KeyUsage[];\n\n // If the algorithm has a 'public' property, it needs to be a CryptoKey\n let algorithm = algorithmRaw;\n if (algorithmRaw.public && typeof algorithmRaw.public === \"object\") {\n const publicKeyData = algorithmRaw.public as { __instanceId__?: number };\n if (publicKeyData.__instanceId__ !== undefined) {\n const publicKeyState = getInstanceStateById<CryptoKeyState>(publicKeyData.__instanceId__);\n if (publicKeyState) {\n algorithm = { ...algorithmRaw, public: publicKeyState.hostKey };\n }\n }\n }\n\n return { algorithm, baseKey, derivedKeyType, extractable, keyUsages };\n },\n async (ctx, { algorithm, baseKey, derivedKeyType, extractable, keyUsages }) => {\n const result = await crypto.subtle.deriveKey(\n algorithm as unknown as AlgorithmIdentifier,\n baseKey,\n derivedKeyType,\n extractable,\n keyUsages\n );\n\n return createCryptoKeyInstance(ctx, result as globalThis.CryptoKey);\n }\n );\n context.setProp(subtle, \"deriveKey\", deriveKeyFn);\n deriveKeyFn.dispose();\n\n // wrapKey(format, key, wrappingKey, wrapAlgorithm) -> ArrayBuffer\n const wrapKeyFn = createSubtleMethod<WrapKeyArgs>(\n context,\n \"wrapKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as WrapKeyArgs[\"format\"],\n key: getHostKey(ctx, getArg(args, 1)),\n wrappingKey: getHostKey(ctx, getArg(args, 2)),\n wrapAlgorithm: unmarshal(ctx, getArg(args, 3)) as AlgorithmIdentifier,\n }),\n async (ctx, { format, key, wrappingKey, wrapAlgorithm }) => {\n const result = await crypto.subtle.wrapKey(format, key, wrappingKey, wrapAlgorithm);\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"wrapKey\", wrapKeyFn);\n wrapKeyFn.dispose();\n\n // unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages) -> CryptoKey\n const unwrapKeyFn = createSubtleMethod<UnwrapKeyArgs>(\n context,\n \"unwrapKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as UnwrapKeyArgs[\"format\"],\n wrappedKey: unmarshal(ctx, getArg(args, 1)) as Uint8Array,\n unwrappingKey: getHostKey(ctx, getArg(args, 2)),\n unwrapAlgorithm: unmarshal(ctx, getArg(args, 3)) as AlgorithmIdentifier,\n unwrappedKeyAlgorithm: unmarshal(ctx, getArg(args, 4)) as AlgorithmIdentifier,\n extractable: unmarshal(ctx, getArg(args, 5)) as boolean,\n keyUsages: unmarshal(ctx, getArg(args, 6)) as globalThis.KeyUsage[],\n }),\n async (ctx, { format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages }) => {\n const result = await crypto.subtle.unwrapKey(\n format,\n wrappedKey as unknown as BufferSource,\n unwrappingKey,\n unwrapAlgorithm,\n unwrappedKeyAlgorithm,\n extractable,\n keyUsages\n );\n\n return createCryptoKeyInstance(ctx, result as globalThis.CryptoKey);\n }\n );\n context.setProp(subtle, \"unwrapKey\", unwrapKeyFn);\n unwrapKeyFn.dispose();\n\n return subtle;\n}\n"
|
|
5
|
+
"import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { CryptoKeyState, KeyUsage } from \"./types.cjs\";\nimport {\n nextInstanceId,\n registerInstance,\n getInstanceStateById,\n marshal,\n unmarshal,\n} from \"@ricsam/quickjs-core\";\n\n/**\n * Helper to create a CryptoKey instance in QuickJS from a host CryptoKey\n *\n * This registers the host key in our state management and creates\n * a QuickJS CryptoKey object that references it via __instanceId__\n */\nexport function createCryptoKeyInstance(\n context: QuickJSContext,\n hostKey: globalThis.CryptoKey\n): QuickJSHandle {\n const instanceId = nextInstanceId();\n\n const state: CryptoKeyState = {\n hostKey,\n type: hostKey.type,\n extractable: hostKey.extractable,\n algorithm: hostKey.algorithm as KeyAlgorithm,\n usages: Array.from(hostKey.usages) as KeyUsage[],\n };\n\n registerInstance(instanceId, \"CryptoKey\", state);\n\n // Create instance via evalCode to properly instantiate with prototype chain\n const result = context.evalCode(`\n (function() {\n const key = Object.create(CryptoKey.prototype);\n Object.defineProperty(key, '__instanceId__', {\n value: ${instanceId},\n enumerable: false,\n writable: false,\n configurable: false\n });\n return key;\n })()\n `);\n\n if (result.error) {\n const err = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to create CryptoKey instance: ${JSON.stringify(err)}`);\n }\n\n return result.value;\n}\n\n/**\n * Helper to create a CryptoKeyPair object in QuickJS\n */\nfunction createCryptoKeyPairInstance(\n context: QuickJSContext,\n keyPair: globalThis.CryptoKeyPair\n): QuickJSHandle {\n const publicKeyHandle = createCryptoKeyInstance(context, keyPair.publicKey);\n const privateKeyHandle = createCryptoKeyInstance(context, keyPair.privateKey);\n\n const obj = context.newObject();\n context.setProp(obj, \"publicKey\", publicKeyHandle);\n context.setProp(obj, \"privateKey\", privateKeyHandle);\n\n publicKeyHandle.dispose();\n privateKeyHandle.dispose();\n\n return obj;\n}\n\n/**\n * Helper to get the host CryptoKey from a QuickJS CryptoKey handle\n */\nfunction getHostKey(context: QuickJSContext, keyHandle: QuickJSHandle): globalThis.CryptoKey {\n const instanceIdHandle = context.getProp(keyHandle, \"__instanceId__\");\n if (context.typeof(instanceIdHandle) !== \"number\") {\n instanceIdHandle.dispose();\n throw new Error(\"Invalid CryptoKey: missing __instanceId__\");\n }\n\n const instanceId = context.getNumber(instanceIdHandle);\n instanceIdHandle.dispose();\n\n const state = getInstanceStateById<CryptoKeyState>(instanceId);\n if (!state) {\n throw new Error(\"Invalid CryptoKey: state not found\");\n }\n\n return state.hostKey;\n}\n\n/**\n * Helper to safely get an argument from the args array\n */\nfunction getArg(args: QuickJSHandle[], index: number): QuickJSHandle {\n const arg = args[index];\n if (!arg) {\n throw new Error(`Missing argument at index ${index}`);\n }\n return arg;\n}\n\n/**\n * Create an async SubtleCrypto method that handles CryptoKey marshalling\n *\n * The key insight is that implementations must NOT use the context after their\n * async operations, because the context could be disposed during the await.\n * Instead, implementations return raw JavaScript values, and marshalling happens\n * in this function AFTER checking that the context is still alive.\n *\n * @param unmarshalArgs - Function to unmarshal arguments synchronously before async work\n * @param implementation - Async implementation that returns raw values (no context access)\n * @param marshalResult - Function to marshal the raw result to a QuickJS handle\n */\nfunction createSubtleMethod<T, R>(\n context: QuickJSContext,\n methodName: string,\n unmarshalArgs: (context: QuickJSContext, args: QuickJSHandle[]) => T,\n implementation: (unmarshaledArgs: T) => Promise<R>,\n marshalResult: (context: QuickJSContext, result: R) => QuickJSHandle\n): QuickJSHandle {\n return context.newFunction(methodName, (...args) => {\n const deferred = context.newPromise();\n\n // Unmarshal arguments synchronously BEFORE scheduling async work\n // This is critical because the QuickJS handles may be disposed before the microtask runs\n let unmarshaledArgs: T;\n try {\n unmarshaledArgs = unmarshalArgs(context, args);\n } catch (error) {\n // If unmarshalling fails, reject immediately\n const errorHandle = marshal(context, {\n name: error instanceof Error ? error.name : \"Error\",\n message: error instanceof Error ? error.message : String(error),\n });\n deferred.reject(errorHandle);\n errorHandle.dispose();\n context.runtime.executePendingJobs();\n return deferred.handle;\n }\n\n // Run the async implementation in a microtask\n Promise.resolve().then(async () => {\n // Guard: Check if context is still alive before starting\n if (!context.alive) {\n return;\n }\n\n try {\n // Implementation returns raw values - no context access after await\n const rawResult = await implementation(unmarshaledArgs);\n\n // Guard: Check if context is still alive BEFORE marshalling\n if (!context.alive) {\n return;\n }\n\n // Now safe to marshal the result\n const resultHandle = marshalResult(context, rawResult);\n deferred.resolve(resultHandle);\n resultHandle.dispose();\n } catch (error) {\n // Guard: Check if context is still alive before error handling\n if (!context.alive) {\n return;\n }\n\n const errorHandle = marshal(context, {\n name: error instanceof Error ? error.name : \"Error\",\n message: error instanceof Error ? error.message : String(error),\n });\n deferred.reject(errorHandle);\n errorHandle.dispose();\n }\n\n if (context.alive) {\n context.runtime.executePendingJobs();\n }\n });\n\n return deferred.handle;\n });\n}\n\n// Type definitions for unmarshaled args\ninterface DigestArgs {\n algorithm: AlgorithmIdentifier;\n data: Uint8Array;\n}\n\ninterface GenerateKeyArgs {\n algorithm: RsaHashedKeyGenParams | EcKeyGenParams | AesKeyGenParams | HmacKeyGenParams;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\ninterface SignArgs {\n algorithm: AlgorithmIdentifier;\n key: globalThis.CryptoKey;\n data: Uint8Array;\n}\n\ninterface VerifyArgs {\n algorithm: AlgorithmIdentifier;\n key: globalThis.CryptoKey;\n signature: Uint8Array;\n data: Uint8Array;\n}\n\ninterface EncryptDecryptArgs {\n algorithm: AlgorithmIdentifier;\n key: globalThis.CryptoKey;\n data: Uint8Array;\n}\n\ninterface ImportKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n keyData: Uint8Array | JsonWebKey;\n algorithm: AlgorithmIdentifier;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\ninterface ExportKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n key: globalThis.CryptoKey;\n}\n\ninterface DeriveBitsArgs {\n algorithm: Record<string, unknown>;\n baseKey: globalThis.CryptoKey;\n length: number;\n}\n\ninterface DeriveKeyArgs {\n algorithm: Record<string, unknown>;\n baseKey: globalThis.CryptoKey;\n derivedKeyType: AlgorithmIdentifier;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\ninterface WrapKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n key: globalThis.CryptoKey;\n wrappingKey: globalThis.CryptoKey;\n wrapAlgorithm: AlgorithmIdentifier;\n}\n\ninterface UnwrapKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n wrappedKey: Uint8Array;\n unwrappingKey: globalThis.CryptoKey;\n unwrapAlgorithm: AlgorithmIdentifier;\n unwrappedKeyAlgorithm: AlgorithmIdentifier;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\n// Result types for marshalling\ntype GenerateKeyResult =\n | { type: \"key\"; hostKey: globalThis.CryptoKey }\n | { type: \"pair\"; publicKey: globalThis.CryptoKey; privateKey: globalThis.CryptoKey };\ntype ExportKeyResult = Uint8Array | JsonWebKey;\n\n/**\n * Create the SubtleCrypto object with all methods\n */\nexport function createSubtleCryptoObject(context: QuickJSContext): QuickJSHandle {\n const subtle = context.newObject();\n\n // digest(algorithm, data) -> ArrayBuffer\n const digestFn = createSubtleMethod<DigestArgs, Uint8Array>(\n context,\n \"digest\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n data: unmarshal(ctx, getArg(args, 1)) as Uint8Array,\n }),\n async ({ algorithm, data }) => {\n const result = await crypto.subtle.digest(algorithm, data as unknown as BufferSource);\n return new Uint8Array(result);\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"digest\", digestFn);\n digestFn.dispose();\n\n // generateKey(algorithm, extractable, keyUsages) -> CryptoKey | CryptoKeyPair\n const generateKeyFn = createSubtleMethod<GenerateKeyArgs, GenerateKeyResult>(\n context,\n \"generateKey\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as GenerateKeyArgs[\"algorithm\"],\n extractable: unmarshal(ctx, getArg(args, 1)) as boolean,\n keyUsages: unmarshal(ctx, getArg(args, 2)) as globalThis.KeyUsage[],\n }),\n async ({ algorithm, extractable, keyUsages }) => {\n const result = await crypto.subtle.generateKey(algorithm, extractable, keyUsages);\n\n // Check if it's a key pair or single key\n if (\"publicKey\" in result && \"privateKey\" in result) {\n return { type: \"pair\", publicKey: result.publicKey, privateKey: result.privateKey };\n } else {\n return { type: \"key\", hostKey: result as globalThis.CryptoKey };\n }\n },\n (ctx, result) => {\n if (result.type === \"pair\") {\n return createCryptoKeyPairInstance(ctx, { publicKey: result.publicKey, privateKey: result.privateKey });\n } else {\n return createCryptoKeyInstance(ctx, result.hostKey);\n }\n }\n );\n context.setProp(subtle, \"generateKey\", generateKeyFn);\n generateKeyFn.dispose();\n\n // sign(algorithm, key, data) -> ArrayBuffer\n const signFn = createSubtleMethod<SignArgs, Uint8Array>(\n context,\n \"sign\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n data: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n }),\n async ({ algorithm, key, data }) => {\n const result = await crypto.subtle.sign(algorithm, key, data as unknown as BufferSource);\n return new Uint8Array(result);\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"sign\", signFn);\n signFn.dispose();\n\n // verify(algorithm, key, signature, data) -> boolean\n const verifyFn = createSubtleMethod<VerifyArgs, boolean>(\n context,\n \"verify\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n signature: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n data: unmarshal(ctx, getArg(args, 3)) as Uint8Array,\n }),\n async ({ algorithm, key, signature, data }) => {\n return await crypto.subtle.verify(\n algorithm,\n key,\n signature as unknown as BufferSource,\n data as unknown as BufferSource\n );\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"verify\", verifyFn);\n verifyFn.dispose();\n\n // encrypt(algorithm, key, data) -> ArrayBuffer\n const encryptFn = createSubtleMethod<EncryptDecryptArgs, Uint8Array>(\n context,\n \"encrypt\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n data: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n }),\n async ({ algorithm, key, data }) => {\n const result = await crypto.subtle.encrypt(\n algorithm,\n key,\n data as unknown as BufferSource\n );\n return new Uint8Array(result);\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"encrypt\", encryptFn);\n encryptFn.dispose();\n\n // decrypt(algorithm, key, data) -> ArrayBuffer\n const decryptFn = createSubtleMethod<EncryptDecryptArgs, Uint8Array>(\n context,\n \"decrypt\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n data: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n }),\n async ({ algorithm, key, data }) => {\n const result = await crypto.subtle.decrypt(\n algorithm,\n key,\n data as unknown as BufferSource\n );\n return new Uint8Array(result);\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"decrypt\", decryptFn);\n decryptFn.dispose();\n\n // importKey(format, keyData, algorithm, extractable, keyUsages) -> CryptoKey\n const importKeyFn = createSubtleMethod<ImportKeyArgs, globalThis.CryptoKey>(\n context,\n \"importKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as ImportKeyArgs[\"format\"],\n keyData: unmarshal(ctx, getArg(args, 1)) as Uint8Array | JsonWebKey,\n algorithm: unmarshal(ctx, getArg(args, 2)) as AlgorithmIdentifier,\n extractable: unmarshal(ctx, getArg(args, 3)) as boolean,\n keyUsages: unmarshal(ctx, getArg(args, 4)) as globalThis.KeyUsage[],\n }),\n async ({ format, keyData, algorithm, extractable, keyUsages }) => {\n if (format === \"jwk\") {\n // JWK format expects JsonWebKey\n return await crypto.subtle.importKey(\n format,\n keyData as JsonWebKey,\n algorithm,\n extractable,\n keyUsages\n );\n } else {\n // Non-jwk formats expect BufferSource\n // Convert Uint8Array to ArrayBuffer\n let data: BufferSource;\n if (keyData instanceof Uint8Array) {\n data = keyData.buffer.slice(keyData.byteOffset, keyData.byteOffset + keyData.byteLength) as ArrayBuffer;\n } else {\n data = keyData as BufferSource;\n }\n\n return await crypto.subtle.importKey(\n format,\n data,\n algorithm,\n extractable,\n keyUsages\n ) as globalThis.CryptoKey;\n }\n },\n (ctx, result) => createCryptoKeyInstance(ctx, result)\n );\n context.setProp(subtle, \"importKey\", importKeyFn);\n importKeyFn.dispose();\n\n // exportKey(format, key) -> ArrayBuffer | JsonWebKey\n const exportKeyFn = createSubtleMethod<ExportKeyArgs, ExportKeyResult>(\n context,\n \"exportKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as ExportKeyArgs[\"format\"],\n key: getHostKey(ctx, getArg(args, 1)),\n }),\n async ({ format, key }) => {\n const result = await crypto.subtle.exportKey(format, key);\n\n if (result instanceof ArrayBuffer) {\n return new Uint8Array(result);\n } else {\n // JsonWebKey - return as-is\n return result;\n }\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"exportKey\", exportKeyFn);\n exportKeyFn.dispose();\n\n // deriveBits(algorithm, baseKey, length) -> ArrayBuffer\n const deriveBitsFn = createSubtleMethod<DeriveBitsArgs, Uint8Array>(\n context,\n \"deriveBits\",\n (ctx, args) => {\n const algorithmRaw = unmarshal(ctx, getArg(args, 0)) as Record<string, unknown>;\n const baseKey = getHostKey(ctx, getArg(args, 1));\n const length = unmarshal(ctx, getArg(args, 2)) as number;\n\n // If the algorithm has a 'public' property, it needs to be a CryptoKey\n let algorithm = algorithmRaw;\n if (algorithmRaw.public && typeof algorithmRaw.public === \"object\") {\n const publicKeyData = algorithmRaw.public as { __instanceId__?: number };\n if (publicKeyData.__instanceId__ !== undefined) {\n const publicKeyState = getInstanceStateById<CryptoKeyState>(publicKeyData.__instanceId__);\n if (publicKeyState) {\n algorithm = { ...algorithmRaw, public: publicKeyState.hostKey };\n }\n }\n }\n\n return { algorithm, baseKey, length };\n },\n async ({ algorithm, baseKey, length }) => {\n const result = await crypto.subtle.deriveBits(\n algorithm as unknown as AlgorithmIdentifier,\n baseKey,\n length\n );\n return new Uint8Array(result);\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"deriveBits\", deriveBitsFn);\n deriveBitsFn.dispose();\n\n // deriveKey(algorithm, baseKey, derivedKeyType, extractable, keyUsages) -> CryptoKey\n const deriveKeyFn = createSubtleMethod<DeriveKeyArgs, globalThis.CryptoKey>(\n context,\n \"deriveKey\",\n (ctx, args) => {\n const algorithmRaw = unmarshal(ctx, getArg(args, 0)) as Record<string, unknown>;\n const baseKey = getHostKey(ctx, getArg(args, 1));\n const derivedKeyType = unmarshal(ctx, getArg(args, 2)) as AlgorithmIdentifier;\n const extractable = unmarshal(ctx, getArg(args, 3)) as boolean;\n const keyUsages = unmarshal(ctx, getArg(args, 4)) as globalThis.KeyUsage[];\n\n // If the algorithm has a 'public' property, it needs to be a CryptoKey\n let algorithm = algorithmRaw;\n if (algorithmRaw.public && typeof algorithmRaw.public === \"object\") {\n const publicKeyData = algorithmRaw.public as { __instanceId__?: number };\n if (publicKeyData.__instanceId__ !== undefined) {\n const publicKeyState = getInstanceStateById<CryptoKeyState>(publicKeyData.__instanceId__);\n if (publicKeyState) {\n algorithm = { ...algorithmRaw, public: publicKeyState.hostKey };\n }\n }\n }\n\n return { algorithm, baseKey, derivedKeyType, extractable, keyUsages };\n },\n async ({ algorithm, baseKey, derivedKeyType, extractable, keyUsages }) => {\n return await crypto.subtle.deriveKey(\n algorithm as unknown as AlgorithmIdentifier,\n baseKey,\n derivedKeyType,\n extractable,\n keyUsages\n ) as globalThis.CryptoKey;\n },\n (ctx, result) => createCryptoKeyInstance(ctx, result)\n );\n context.setProp(subtle, \"deriveKey\", deriveKeyFn);\n deriveKeyFn.dispose();\n\n // wrapKey(format, key, wrappingKey, wrapAlgorithm) -> ArrayBuffer\n const wrapKeyFn = createSubtleMethod<WrapKeyArgs, Uint8Array>(\n context,\n \"wrapKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as WrapKeyArgs[\"format\"],\n key: getHostKey(ctx, getArg(args, 1)),\n wrappingKey: getHostKey(ctx, getArg(args, 2)),\n wrapAlgorithm: unmarshal(ctx, getArg(args, 3)) as AlgorithmIdentifier,\n }),\n async ({ format, key, wrappingKey, wrapAlgorithm }) => {\n const result = await crypto.subtle.wrapKey(format, key, wrappingKey, wrapAlgorithm);\n return new Uint8Array(result);\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"wrapKey\", wrapKeyFn);\n wrapKeyFn.dispose();\n\n // unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages) -> CryptoKey\n const unwrapKeyFn = createSubtleMethod<UnwrapKeyArgs, globalThis.CryptoKey>(\n context,\n \"unwrapKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as UnwrapKeyArgs[\"format\"],\n wrappedKey: unmarshal(ctx, getArg(args, 1)) as Uint8Array,\n unwrappingKey: getHostKey(ctx, getArg(args, 2)),\n unwrapAlgorithm: unmarshal(ctx, getArg(args, 3)) as AlgorithmIdentifier,\n unwrappedKeyAlgorithm: unmarshal(ctx, getArg(args, 4)) as AlgorithmIdentifier,\n extractable: unmarshal(ctx, getArg(args, 5)) as boolean,\n keyUsages: unmarshal(ctx, getArg(args, 6)) as globalThis.KeyUsage[],\n }),\n async ({ format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages }) => {\n return await crypto.subtle.unwrapKey(\n format,\n wrappedKey as unknown as BufferSource,\n unwrappingKey,\n unwrapAlgorithm,\n unwrappedKeyAlgorithm,\n extractable,\n keyUsages\n ) as globalThis.CryptoKey;\n },\n (ctx, result) => createCryptoKeyInstance(ctx, result)\n );\n context.setProp(subtle, \"unwrapKey\", unwrapKeyFn);\n unwrapKeyFn.dispose();\n\n return subtle;\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQO,IANP;AAcO,SAAS,uBAAuB,CACrC,SACA,SACe;AAAA,EACf,MAAM,aAAa,mCAAe;AAAA,EAElC,MAAM,QAAwB;AAAA,IAC5B;AAAA,IACA,MAAM,QAAQ;AAAA,IACd,aAAa,QAAQ;AAAA,IACrB,WAAW,QAAQ;AAAA,IACnB,QAAQ,MAAM,KAAK,QAAQ,MAAM;AAAA,EACnC;AAAA,EAEA,qCAAiB,YAAY,aAAa,KAAK;AAAA,EAG/C,MAAM,SAAS,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,iBAIjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAOd;AAAA,EAED,IAAI,OAAO,OAAO;AAAA,IAChB,MAAM,MAAM,QAAQ,KAAK,OAAO,KAAK;AAAA,IACrC,OAAO,MAAM,QAAQ;AAAA,IACrB,MAAM,IAAI,MAAM,wCAAwC,KAAK,UAAU,GAAG,GAAG;AAAA,EAC/E;AAAA,EAEA,OAAO,OAAO;AAAA;AAMhB,SAAS,2BAA2B,CAClC,SACA,SACe;AAAA,EACf,MAAM,kBAAkB,wBAAwB,SAAS,QAAQ,SAAS;AAAA,EAC1E,MAAM,mBAAmB,wBAAwB,SAAS,QAAQ,UAAU;AAAA,EAE5E,MAAM,MAAM,QAAQ,UAAU;AAAA,EAC9B,QAAQ,QAAQ,KAAK,aAAa,eAAe;AAAA,EACjD,QAAQ,QAAQ,KAAK,cAAc,gBAAgB;AAAA,EAEnD,gBAAgB,QAAQ;AAAA,EACxB,iBAAiB,QAAQ;AAAA,EAEzB,OAAO;AAAA;AAMT,SAAS,UAAU,CAAC,SAAyB,WAAgD;AAAA,EAC3F,MAAM,mBAAmB,QAAQ,QAAQ,WAAW,gBAAgB;AAAA,EACpE,IAAI,QAAQ,OAAO,gBAAgB,MAAM,UAAU;AAAA,IACjD,iBAAiB,QAAQ;AAAA,IACzB,MAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AAAA,EAEA,MAAM,aAAa,QAAQ,UAAU,gBAAgB;AAAA,EACrD,iBAAiB,QAAQ;AAAA,EAEzB,MAAM,QAAQ,yCAAqC,UAAU;AAAA,EAC7D,IAAI,CAAC,OAAO;AAAA,IACV,MAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AAAA,EAEA,OAAO,MAAM;AAAA;AAMf,SAAS,MAAM,CAAC,MAAuB,OAA8B;AAAA,EACnE,MAAM,MAAM,KAAK;AAAA,EACjB,IAAI,CAAC,KAAK;AAAA,IACR,MAAM,IAAI,MAAM,6BAA6B,OAAO;AAAA,EACtD;AAAA,EACA,OAAO;AAAA;
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "44813671DCFC8D8164756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/mjs/package.json
CHANGED
|
@@ -67,7 +67,7 @@ function getArg(args, index) {
|
|
|
67
67
|
}
|
|
68
68
|
return arg;
|
|
69
69
|
}
|
|
70
|
-
function createSubtleMethod(context, methodName, unmarshalArgs, implementation) {
|
|
70
|
+
function createSubtleMethod(context, methodName, unmarshalArgs, implementation, marshalResult) {
|
|
71
71
|
return context.newFunction(methodName, (...args) => {
|
|
72
72
|
const deferred = context.newPromise();
|
|
73
73
|
let unmarshaledArgs;
|
|
@@ -84,11 +84,21 @@ function createSubtleMethod(context, methodName, unmarshalArgs, implementation)
|
|
|
84
84
|
return deferred.handle;
|
|
85
85
|
}
|
|
86
86
|
Promise.resolve().then(async () => {
|
|
87
|
+
if (!context.alive) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
87
90
|
try {
|
|
88
|
-
const
|
|
91
|
+
const rawResult = await implementation(unmarshaledArgs);
|
|
92
|
+
if (!context.alive) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const resultHandle = marshalResult(context, rawResult);
|
|
89
96
|
deferred.resolve(resultHandle);
|
|
90
97
|
resultHandle.dispose();
|
|
91
98
|
} catch (error) {
|
|
99
|
+
if (!context.alive) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
92
102
|
const errorHandle = marshal(context, {
|
|
93
103
|
name: error instanceof Error ? error.name : "Error",
|
|
94
104
|
message: error instanceof Error ? error.message : String(error)
|
|
@@ -96,7 +106,9 @@ function createSubtleMethod(context, methodName, unmarshalArgs, implementation)
|
|
|
96
106
|
deferred.reject(errorHandle);
|
|
97
107
|
errorHandle.dispose();
|
|
98
108
|
}
|
|
99
|
-
context.
|
|
109
|
+
if (context.alive) {
|
|
110
|
+
context.runtime.executePendingJobs();
|
|
111
|
+
}
|
|
100
112
|
});
|
|
101
113
|
return deferred.handle;
|
|
102
114
|
});
|
|
@@ -106,22 +118,28 @@ function createSubtleCryptoObject(context) {
|
|
|
106
118
|
const digestFn = createSubtleMethod(context, "digest", (ctx, args) => ({
|
|
107
119
|
algorithm: unmarshal(ctx, getArg(args, 0)),
|
|
108
120
|
data: unmarshal(ctx, getArg(args, 1))
|
|
109
|
-
}), async (
|
|
121
|
+
}), async ({ algorithm, data }) => {
|
|
110
122
|
const result = await crypto.subtle.digest(algorithm, data);
|
|
111
|
-
return
|
|
112
|
-
});
|
|
123
|
+
return new Uint8Array(result);
|
|
124
|
+
}, (ctx, result) => marshal(ctx, result));
|
|
113
125
|
context.setProp(subtle, "digest", digestFn);
|
|
114
126
|
digestFn.dispose();
|
|
115
127
|
const generateKeyFn = createSubtleMethod(context, "generateKey", (ctx, args) => ({
|
|
116
128
|
algorithm: unmarshal(ctx, getArg(args, 0)),
|
|
117
129
|
extractable: unmarshal(ctx, getArg(args, 1)),
|
|
118
130
|
keyUsages: unmarshal(ctx, getArg(args, 2))
|
|
119
|
-
}), async (
|
|
131
|
+
}), async ({ algorithm, extractable, keyUsages }) => {
|
|
120
132
|
const result = await crypto.subtle.generateKey(algorithm, extractable, keyUsages);
|
|
121
133
|
if ("publicKey" in result && "privateKey" in result) {
|
|
122
|
-
return
|
|
134
|
+
return { type: "pair", publicKey: result.publicKey, privateKey: result.privateKey };
|
|
135
|
+
} else {
|
|
136
|
+
return { type: "key", hostKey: result };
|
|
137
|
+
}
|
|
138
|
+
}, (ctx, result) => {
|
|
139
|
+
if (result.type === "pair") {
|
|
140
|
+
return createCryptoKeyPairInstance(ctx, { publicKey: result.publicKey, privateKey: result.privateKey });
|
|
123
141
|
} else {
|
|
124
|
-
return createCryptoKeyInstance(ctx, result);
|
|
142
|
+
return createCryptoKeyInstance(ctx, result.hostKey);
|
|
125
143
|
}
|
|
126
144
|
});
|
|
127
145
|
context.setProp(subtle, "generateKey", generateKeyFn);
|
|
@@ -130,10 +148,10 @@ function createSubtleCryptoObject(context) {
|
|
|
130
148
|
algorithm: unmarshal(ctx, getArg(args, 0)),
|
|
131
149
|
key: getHostKey(ctx, getArg(args, 1)),
|
|
132
150
|
data: unmarshal(ctx, getArg(args, 2))
|
|
133
|
-
}), async (
|
|
151
|
+
}), async ({ algorithm, key, data }) => {
|
|
134
152
|
const result = await crypto.subtle.sign(algorithm, key, data);
|
|
135
|
-
return
|
|
136
|
-
});
|
|
153
|
+
return new Uint8Array(result);
|
|
154
|
+
}, (ctx, result) => marshal(ctx, result));
|
|
137
155
|
context.setProp(subtle, "sign", signFn);
|
|
138
156
|
signFn.dispose();
|
|
139
157
|
const verifyFn = createSubtleMethod(context, "verify", (ctx, args) => ({
|
|
@@ -141,30 +159,29 @@ function createSubtleCryptoObject(context) {
|
|
|
141
159
|
key: getHostKey(ctx, getArg(args, 1)),
|
|
142
160
|
signature: unmarshal(ctx, getArg(args, 2)),
|
|
143
161
|
data: unmarshal(ctx, getArg(args, 3))
|
|
144
|
-
}), async (
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
});
|
|
162
|
+
}), async ({ algorithm, key, signature, data }) => {
|
|
163
|
+
return await crypto.subtle.verify(algorithm, key, signature, data);
|
|
164
|
+
}, (ctx, result) => marshal(ctx, result));
|
|
148
165
|
context.setProp(subtle, "verify", verifyFn);
|
|
149
166
|
verifyFn.dispose();
|
|
150
167
|
const encryptFn = createSubtleMethod(context, "encrypt", (ctx, args) => ({
|
|
151
168
|
algorithm: unmarshal(ctx, getArg(args, 0)),
|
|
152
169
|
key: getHostKey(ctx, getArg(args, 1)),
|
|
153
170
|
data: unmarshal(ctx, getArg(args, 2))
|
|
154
|
-
}), async (
|
|
171
|
+
}), async ({ algorithm, key, data }) => {
|
|
155
172
|
const result = await crypto.subtle.encrypt(algorithm, key, data);
|
|
156
|
-
return
|
|
157
|
-
});
|
|
173
|
+
return new Uint8Array(result);
|
|
174
|
+
}, (ctx, result) => marshal(ctx, result));
|
|
158
175
|
context.setProp(subtle, "encrypt", encryptFn);
|
|
159
176
|
encryptFn.dispose();
|
|
160
177
|
const decryptFn = createSubtleMethod(context, "decrypt", (ctx, args) => ({
|
|
161
178
|
algorithm: unmarshal(ctx, getArg(args, 0)),
|
|
162
179
|
key: getHostKey(ctx, getArg(args, 1)),
|
|
163
180
|
data: unmarshal(ctx, getArg(args, 2))
|
|
164
|
-
}), async (
|
|
181
|
+
}), async ({ algorithm, key, data }) => {
|
|
165
182
|
const result = await crypto.subtle.decrypt(algorithm, key, data);
|
|
166
|
-
return
|
|
167
|
-
});
|
|
183
|
+
return new Uint8Array(result);
|
|
184
|
+
}, (ctx, result) => marshal(ctx, result));
|
|
168
185
|
context.setProp(subtle, "decrypt", decryptFn);
|
|
169
186
|
decryptFn.dispose();
|
|
170
187
|
const importKeyFn = createSubtleMethod(context, "importKey", (ctx, args) => ({
|
|
@@ -173,10 +190,9 @@ function createSubtleCryptoObject(context) {
|
|
|
173
190
|
algorithm: unmarshal(ctx, getArg(args, 2)),
|
|
174
191
|
extractable: unmarshal(ctx, getArg(args, 3)),
|
|
175
192
|
keyUsages: unmarshal(ctx, getArg(args, 4))
|
|
176
|
-
}), async (
|
|
177
|
-
let result;
|
|
193
|
+
}), async ({ format, keyData, algorithm, extractable, keyUsages }) => {
|
|
178
194
|
if (format === "jwk") {
|
|
179
|
-
|
|
195
|
+
return await crypto.subtle.importKey(format, keyData, algorithm, extractable, keyUsages);
|
|
180
196
|
} else {
|
|
181
197
|
let data;
|
|
182
198
|
if (keyData instanceof Uint8Array) {
|
|
@@ -184,23 +200,22 @@ function createSubtleCryptoObject(context) {
|
|
|
184
200
|
} else {
|
|
185
201
|
data = keyData;
|
|
186
202
|
}
|
|
187
|
-
|
|
203
|
+
return await crypto.subtle.importKey(format, data, algorithm, extractable, keyUsages);
|
|
188
204
|
}
|
|
189
|
-
|
|
190
|
-
});
|
|
205
|
+
}, (ctx, result) => createCryptoKeyInstance(ctx, result));
|
|
191
206
|
context.setProp(subtle, "importKey", importKeyFn);
|
|
192
207
|
importKeyFn.dispose();
|
|
193
208
|
const exportKeyFn = createSubtleMethod(context, "exportKey", (ctx, args) => ({
|
|
194
209
|
format: unmarshal(ctx, getArg(args, 0)),
|
|
195
210
|
key: getHostKey(ctx, getArg(args, 1))
|
|
196
|
-
}), async (
|
|
211
|
+
}), async ({ format, key }) => {
|
|
197
212
|
const result = await crypto.subtle.exportKey(format, key);
|
|
198
213
|
if (result instanceof ArrayBuffer) {
|
|
199
|
-
return
|
|
214
|
+
return new Uint8Array(result);
|
|
200
215
|
} else {
|
|
201
|
-
return
|
|
216
|
+
return result;
|
|
202
217
|
}
|
|
203
|
-
});
|
|
218
|
+
}, (ctx, result) => marshal(ctx, result));
|
|
204
219
|
context.setProp(subtle, "exportKey", exportKeyFn);
|
|
205
220
|
exportKeyFn.dispose();
|
|
206
221
|
const deriveBitsFn = createSubtleMethod(context, "deriveBits", (ctx, args) => {
|
|
@@ -218,10 +233,10 @@ function createSubtleCryptoObject(context) {
|
|
|
218
233
|
}
|
|
219
234
|
}
|
|
220
235
|
return { algorithm, baseKey, length };
|
|
221
|
-
}, async (
|
|
236
|
+
}, async ({ algorithm, baseKey, length }) => {
|
|
222
237
|
const result = await crypto.subtle.deriveBits(algorithm, baseKey, length);
|
|
223
|
-
return
|
|
224
|
-
});
|
|
238
|
+
return new Uint8Array(result);
|
|
239
|
+
}, (ctx, result) => marshal(ctx, result));
|
|
225
240
|
context.setProp(subtle, "deriveBits", deriveBitsFn);
|
|
226
241
|
deriveBitsFn.dispose();
|
|
227
242
|
const deriveKeyFn = createSubtleMethod(context, "deriveKey", (ctx, args) => {
|
|
@@ -241,10 +256,9 @@ function createSubtleCryptoObject(context) {
|
|
|
241
256
|
}
|
|
242
257
|
}
|
|
243
258
|
return { algorithm, baseKey, derivedKeyType, extractable, keyUsages };
|
|
244
|
-
}, async (
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
});
|
|
259
|
+
}, async ({ algorithm, baseKey, derivedKeyType, extractable, keyUsages }) => {
|
|
260
|
+
return await crypto.subtle.deriveKey(algorithm, baseKey, derivedKeyType, extractable, keyUsages);
|
|
261
|
+
}, (ctx, result) => createCryptoKeyInstance(ctx, result));
|
|
248
262
|
context.setProp(subtle, "deriveKey", deriveKeyFn);
|
|
249
263
|
deriveKeyFn.dispose();
|
|
250
264
|
const wrapKeyFn = createSubtleMethod(context, "wrapKey", (ctx, args) => ({
|
|
@@ -252,10 +266,10 @@ function createSubtleCryptoObject(context) {
|
|
|
252
266
|
key: getHostKey(ctx, getArg(args, 1)),
|
|
253
267
|
wrappingKey: getHostKey(ctx, getArg(args, 2)),
|
|
254
268
|
wrapAlgorithm: unmarshal(ctx, getArg(args, 3))
|
|
255
|
-
}), async (
|
|
269
|
+
}), async ({ format, key, wrappingKey, wrapAlgorithm }) => {
|
|
256
270
|
const result = await crypto.subtle.wrapKey(format, key, wrappingKey, wrapAlgorithm);
|
|
257
|
-
return
|
|
258
|
-
});
|
|
271
|
+
return new Uint8Array(result);
|
|
272
|
+
}, (ctx, result) => marshal(ctx, result));
|
|
259
273
|
context.setProp(subtle, "wrapKey", wrapKeyFn);
|
|
260
274
|
wrapKeyFn.dispose();
|
|
261
275
|
const unwrapKeyFn = createSubtleMethod(context, "unwrapKey", (ctx, args) => ({
|
|
@@ -266,10 +280,9 @@ function createSubtleCryptoObject(context) {
|
|
|
266
280
|
unwrappedKeyAlgorithm: unmarshal(ctx, getArg(args, 4)),
|
|
267
281
|
extractable: unmarshal(ctx, getArg(args, 5)),
|
|
268
282
|
keyUsages: unmarshal(ctx, getArg(args, 6))
|
|
269
|
-
}), async (
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
});
|
|
283
|
+
}), async ({ format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages }) => {
|
|
284
|
+
return await crypto.subtle.unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages);
|
|
285
|
+
}, (ctx, result) => createCryptoKeyInstance(ctx, result));
|
|
273
286
|
context.setProp(subtle, "unwrapKey", unwrapKeyFn);
|
|
274
287
|
unwrapKeyFn.dispose();
|
|
275
288
|
return subtle;
|
|
@@ -279,4 +292,4 @@ export {
|
|
|
279
292
|
createCryptoKeyInstance
|
|
280
293
|
};
|
|
281
294
|
|
|
282
|
-
//# debugId=
|
|
295
|
+
//# debugId=BDAAC1BB5C73211A64756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/subtle-crypto.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { CryptoKeyState, KeyUsage } from \"./types.mjs\";\nimport {\n nextInstanceId,\n registerInstance,\n getInstanceStateById,\n marshal,\n unmarshal,\n} from \"@ricsam/quickjs-core\";\n\n/**\n * Helper to create a CryptoKey instance in QuickJS from a host CryptoKey\n *\n * This registers the host key in our state management and creates\n * a QuickJS CryptoKey object that references it via __instanceId__\n */\nexport function createCryptoKeyInstance(\n context: QuickJSContext,\n hostKey: globalThis.CryptoKey\n): QuickJSHandle {\n const instanceId = nextInstanceId();\n\n const state: CryptoKeyState = {\n hostKey,\n type: hostKey.type,\n extractable: hostKey.extractable,\n algorithm: hostKey.algorithm as KeyAlgorithm,\n usages: Array.from(hostKey.usages) as KeyUsage[],\n };\n\n registerInstance(instanceId, \"CryptoKey\", state);\n\n // Create instance via evalCode to properly instantiate with prototype chain\n const result = context.evalCode(`\n (function() {\n const key = Object.create(CryptoKey.prototype);\n Object.defineProperty(key, '__instanceId__', {\n value: ${instanceId},\n enumerable: false,\n writable: false,\n configurable: false\n });\n return key;\n })()\n `);\n\n if (result.error) {\n const err = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to create CryptoKey instance: ${JSON.stringify(err)}`);\n }\n\n return result.value;\n}\n\n/**\n * Helper to create a CryptoKeyPair object in QuickJS\n */\nfunction createCryptoKeyPairInstance(\n context: QuickJSContext,\n keyPair: globalThis.CryptoKeyPair\n): QuickJSHandle {\n const publicKeyHandle = createCryptoKeyInstance(context, keyPair.publicKey);\n const privateKeyHandle = createCryptoKeyInstance(context, keyPair.privateKey);\n\n const obj = context.newObject();\n context.setProp(obj, \"publicKey\", publicKeyHandle);\n context.setProp(obj, \"privateKey\", privateKeyHandle);\n\n publicKeyHandle.dispose();\n privateKeyHandle.dispose();\n\n return obj;\n}\n\n/**\n * Helper to get the host CryptoKey from a QuickJS CryptoKey handle\n */\nfunction getHostKey(context: QuickJSContext, keyHandle: QuickJSHandle): globalThis.CryptoKey {\n const instanceIdHandle = context.getProp(keyHandle, \"__instanceId__\");\n if (context.typeof(instanceIdHandle) !== \"number\") {\n instanceIdHandle.dispose();\n throw new Error(\"Invalid CryptoKey: missing __instanceId__\");\n }\n\n const instanceId = context.getNumber(instanceIdHandle);\n instanceIdHandle.dispose();\n\n const state = getInstanceStateById<CryptoKeyState>(instanceId);\n if (!state) {\n throw new Error(\"Invalid CryptoKey: state not found\");\n }\n\n return state.hostKey;\n}\n\n/**\n * Helper to safely get an argument from the args array\n */\nfunction getArg(args: QuickJSHandle[], index: number): QuickJSHandle {\n const arg = args[index];\n if (!arg) {\n throw new Error(`Missing argument at index ${index}`);\n }\n return arg;\n}\n\n/**\n * Create an async SubtleCrypto method that handles CryptoKey marshalling\n *\n * @param unmarshalArgs - Function to unmarshal arguments synchronously before async work\n * @param implementation - Async implementation that receives unmarshaled args\n */\nfunction createSubtleMethod<T>(\n context: QuickJSContext,\n methodName: string,\n unmarshalArgs: (context: QuickJSContext, args: QuickJSHandle[]) => T,\n implementation: (context: QuickJSContext, unmarshaledArgs: T) => Promise<QuickJSHandle>\n): QuickJSHandle {\n return context.newFunction(methodName, (...args) => {\n const deferred = context.newPromise();\n\n // Unmarshal arguments synchronously BEFORE scheduling async work\n // This is critical because the QuickJS handles may be disposed before the microtask runs\n let unmarshaledArgs: T;\n try {\n unmarshaledArgs = unmarshalArgs(context, args);\n } catch (error) {\n // If unmarshalling fails, reject immediately\n const errorHandle = marshal(context, {\n name: error instanceof Error ? error.name : \"Error\",\n message: error instanceof Error ? error.message : String(error),\n });\n deferred.reject(errorHandle);\n errorHandle.dispose();\n context.runtime.executePendingJobs();\n return deferred.handle;\n }\n\n // Run the async implementation in a microtask\n Promise.resolve().then(async () => {\n try {\n const resultHandle = await implementation(context, unmarshaledArgs);\n deferred.resolve(resultHandle);\n resultHandle.dispose();\n } catch (error) {\n // Use marshal instead of newError to avoid issues with disposed context\n const errorHandle = marshal(context, {\n name: error instanceof Error ? error.name : \"Error\",\n message: error instanceof Error ? error.message : String(error),\n });\n deferred.reject(errorHandle);\n errorHandle.dispose();\n }\n context.runtime.executePendingJobs();\n });\n\n return deferred.handle;\n });\n}\n\n// Type definitions for unmarshaled args\ninterface DigestArgs {\n algorithm: AlgorithmIdentifier;\n data: Uint8Array;\n}\n\ninterface GenerateKeyArgs {\n algorithm: RsaHashedKeyGenParams | EcKeyGenParams | AesKeyGenParams | HmacKeyGenParams;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\ninterface SignArgs {\n algorithm: AlgorithmIdentifier;\n key: globalThis.CryptoKey;\n data: Uint8Array;\n}\n\ninterface VerifyArgs {\n algorithm: AlgorithmIdentifier;\n key: globalThis.CryptoKey;\n signature: Uint8Array;\n data: Uint8Array;\n}\n\ninterface EncryptDecryptArgs {\n algorithm: AlgorithmIdentifier;\n key: globalThis.CryptoKey;\n data: Uint8Array;\n}\n\ninterface ImportKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n keyData: Uint8Array | JsonWebKey;\n algorithm: AlgorithmIdentifier;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\ninterface ExportKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n key: globalThis.CryptoKey;\n}\n\ninterface DeriveBitsArgs {\n algorithm: Record<string, unknown>;\n baseKey: globalThis.CryptoKey;\n length: number;\n}\n\ninterface DeriveKeyArgs {\n algorithm: Record<string, unknown>;\n baseKey: globalThis.CryptoKey;\n derivedKeyType: AlgorithmIdentifier;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\ninterface WrapKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n key: globalThis.CryptoKey;\n wrappingKey: globalThis.CryptoKey;\n wrapAlgorithm: AlgorithmIdentifier;\n}\n\ninterface UnwrapKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n wrappedKey: Uint8Array;\n unwrappingKey: globalThis.CryptoKey;\n unwrapAlgorithm: AlgorithmIdentifier;\n unwrappedKeyAlgorithm: AlgorithmIdentifier;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\n/**\n * Create the SubtleCrypto object with all methods\n */\nexport function createSubtleCryptoObject(context: QuickJSContext): QuickJSHandle {\n const subtle = context.newObject();\n\n // digest(algorithm, data) -> ArrayBuffer\n const digestFn = createSubtleMethod<DigestArgs>(\n context,\n \"digest\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n data: unmarshal(ctx, getArg(args, 1)) as Uint8Array,\n }),\n async (ctx, { algorithm, data }) => {\n const result = await crypto.subtle.digest(algorithm, data as unknown as BufferSource);\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"digest\", digestFn);\n digestFn.dispose();\n\n // generateKey(algorithm, extractable, keyUsages) -> CryptoKey | CryptoKeyPair\n const generateKeyFn = createSubtleMethod<GenerateKeyArgs>(\n context,\n \"generateKey\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as GenerateKeyArgs[\"algorithm\"],\n extractable: unmarshal(ctx, getArg(args, 1)) as boolean,\n keyUsages: unmarshal(ctx, getArg(args, 2)) as globalThis.KeyUsage[],\n }),\n async (ctx, { algorithm, extractable, keyUsages }) => {\n const result = await crypto.subtle.generateKey(algorithm, extractable, keyUsages);\n\n // Check if it's a key pair or single key\n if (\"publicKey\" in result && \"privateKey\" in result) {\n return createCryptoKeyPairInstance(ctx, result);\n } else {\n return createCryptoKeyInstance(ctx, result as globalThis.CryptoKey);\n }\n }\n );\n context.setProp(subtle, \"generateKey\", generateKeyFn);\n generateKeyFn.dispose();\n\n // sign(algorithm, key, data) -> ArrayBuffer\n const signFn = createSubtleMethod<SignArgs>(\n context,\n \"sign\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n data: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n }),\n async (ctx, { algorithm, key, data }) => {\n const result = await crypto.subtle.sign(algorithm, key, data as unknown as BufferSource);\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"sign\", signFn);\n signFn.dispose();\n\n // verify(algorithm, key, signature, data) -> boolean\n const verifyFn = createSubtleMethod<VerifyArgs>(\n context,\n \"verify\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n signature: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n data: unmarshal(ctx, getArg(args, 3)) as Uint8Array,\n }),\n async (ctx, { algorithm, key, signature, data }) => {\n const result = await crypto.subtle.verify(\n algorithm,\n key,\n signature as unknown as BufferSource,\n data as unknown as BufferSource\n );\n return marshal(ctx, result);\n }\n );\n context.setProp(subtle, \"verify\", verifyFn);\n verifyFn.dispose();\n\n // encrypt(algorithm, key, data) -> ArrayBuffer\n const encryptFn = createSubtleMethod<EncryptDecryptArgs>(\n context,\n \"encrypt\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n data: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n }),\n async (ctx, { algorithm, key, data }) => {\n const result = await crypto.subtle.encrypt(\n algorithm,\n key,\n data as unknown as BufferSource\n );\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"encrypt\", encryptFn);\n encryptFn.dispose();\n\n // decrypt(algorithm, key, data) -> ArrayBuffer\n const decryptFn = createSubtleMethod<EncryptDecryptArgs>(\n context,\n \"decrypt\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n data: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n }),\n async (ctx, { algorithm, key, data }) => {\n const result = await crypto.subtle.decrypt(\n algorithm,\n key,\n data as unknown as BufferSource\n );\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"decrypt\", decryptFn);\n decryptFn.dispose();\n\n // importKey(format, keyData, algorithm, extractable, keyUsages) -> CryptoKey\n const importKeyFn = createSubtleMethod<ImportKeyArgs>(\n context,\n \"importKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as ImportKeyArgs[\"format\"],\n keyData: unmarshal(ctx, getArg(args, 1)) as Uint8Array | JsonWebKey,\n algorithm: unmarshal(ctx, getArg(args, 2)) as AlgorithmIdentifier,\n extractable: unmarshal(ctx, getArg(args, 3)) as boolean,\n keyUsages: unmarshal(ctx, getArg(args, 4)) as globalThis.KeyUsage[],\n }),\n async (ctx, { format, keyData, algorithm, extractable, keyUsages }) => {\n let result: globalThis.CryptoKey;\n\n if (format === \"jwk\") {\n // JWK format expects JsonWebKey\n result = await crypto.subtle.importKey(\n format,\n keyData as JsonWebKey,\n algorithm,\n extractable,\n keyUsages\n );\n } else {\n // Non-jwk formats expect BufferSource\n // Convert Uint8Array to ArrayBuffer\n let data: BufferSource;\n if (keyData instanceof Uint8Array) {\n data = keyData.buffer.slice(keyData.byteOffset, keyData.byteOffset + keyData.byteLength) as ArrayBuffer;\n } else {\n data = keyData as BufferSource;\n }\n\n result = await crypto.subtle.importKey(\n format,\n data,\n algorithm,\n extractable,\n keyUsages\n ) as globalThis.CryptoKey;\n }\n\n return createCryptoKeyInstance(ctx, result);\n }\n );\n context.setProp(subtle, \"importKey\", importKeyFn);\n importKeyFn.dispose();\n\n // exportKey(format, key) -> ArrayBuffer | JsonWebKey\n const exportKeyFn = createSubtleMethod<ExportKeyArgs>(\n context,\n \"exportKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as ExportKeyArgs[\"format\"],\n key: getHostKey(ctx, getArg(args, 1)),\n }),\n async (ctx, { format, key }) => {\n const result = await crypto.subtle.exportKey(format, key);\n\n if (result instanceof ArrayBuffer) {\n return marshal(ctx, new Uint8Array(result));\n } else {\n // JsonWebKey - marshal as plain object\n return marshal(ctx, result);\n }\n }\n );\n context.setProp(subtle, \"exportKey\", exportKeyFn);\n exportKeyFn.dispose();\n\n // deriveBits(algorithm, baseKey, length) -> ArrayBuffer\n const deriveBitsFn = createSubtleMethod<DeriveBitsArgs>(\n context,\n \"deriveBits\",\n (ctx, args) => {\n const algorithmRaw = unmarshal(ctx, getArg(args, 0)) as Record<string, unknown>;\n const baseKey = getHostKey(ctx, getArg(args, 1));\n const length = unmarshal(ctx, getArg(args, 2)) as number;\n\n // If the algorithm has a 'public' property, it needs to be a CryptoKey\n let algorithm = algorithmRaw;\n if (algorithmRaw.public && typeof algorithmRaw.public === \"object\") {\n const publicKeyData = algorithmRaw.public as { __instanceId__?: number };\n if (publicKeyData.__instanceId__ !== undefined) {\n const publicKeyState = getInstanceStateById<CryptoKeyState>(publicKeyData.__instanceId__);\n if (publicKeyState) {\n algorithm = { ...algorithmRaw, public: publicKeyState.hostKey };\n }\n }\n }\n\n return { algorithm, baseKey, length };\n },\n async (ctx, { algorithm, baseKey, length }) => {\n const result = await crypto.subtle.deriveBits(\n algorithm as unknown as AlgorithmIdentifier,\n baseKey,\n length\n );\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"deriveBits\", deriveBitsFn);\n deriveBitsFn.dispose();\n\n // deriveKey(algorithm, baseKey, derivedKeyType, extractable, keyUsages) -> CryptoKey\n const deriveKeyFn = createSubtleMethod<DeriveKeyArgs>(\n context,\n \"deriveKey\",\n (ctx, args) => {\n const algorithmRaw = unmarshal(ctx, getArg(args, 0)) as Record<string, unknown>;\n const baseKey = getHostKey(ctx, getArg(args, 1));\n const derivedKeyType = unmarshal(ctx, getArg(args, 2)) as AlgorithmIdentifier;\n const extractable = unmarshal(ctx, getArg(args, 3)) as boolean;\n const keyUsages = unmarshal(ctx, getArg(args, 4)) as globalThis.KeyUsage[];\n\n // If the algorithm has a 'public' property, it needs to be a CryptoKey\n let algorithm = algorithmRaw;\n if (algorithmRaw.public && typeof algorithmRaw.public === \"object\") {\n const publicKeyData = algorithmRaw.public as { __instanceId__?: number };\n if (publicKeyData.__instanceId__ !== undefined) {\n const publicKeyState = getInstanceStateById<CryptoKeyState>(publicKeyData.__instanceId__);\n if (publicKeyState) {\n algorithm = { ...algorithmRaw, public: publicKeyState.hostKey };\n }\n }\n }\n\n return { algorithm, baseKey, derivedKeyType, extractable, keyUsages };\n },\n async (ctx, { algorithm, baseKey, derivedKeyType, extractable, keyUsages }) => {\n const result = await crypto.subtle.deriveKey(\n algorithm as unknown as AlgorithmIdentifier,\n baseKey,\n derivedKeyType,\n extractable,\n keyUsages\n );\n\n return createCryptoKeyInstance(ctx, result as globalThis.CryptoKey);\n }\n );\n context.setProp(subtle, \"deriveKey\", deriveKeyFn);\n deriveKeyFn.dispose();\n\n // wrapKey(format, key, wrappingKey, wrapAlgorithm) -> ArrayBuffer\n const wrapKeyFn = createSubtleMethod<WrapKeyArgs>(\n context,\n \"wrapKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as WrapKeyArgs[\"format\"],\n key: getHostKey(ctx, getArg(args, 1)),\n wrappingKey: getHostKey(ctx, getArg(args, 2)),\n wrapAlgorithm: unmarshal(ctx, getArg(args, 3)) as AlgorithmIdentifier,\n }),\n async (ctx, { format, key, wrappingKey, wrapAlgorithm }) => {\n const result = await crypto.subtle.wrapKey(format, key, wrappingKey, wrapAlgorithm);\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"wrapKey\", wrapKeyFn);\n wrapKeyFn.dispose();\n\n // unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages) -> CryptoKey\n const unwrapKeyFn = createSubtleMethod<UnwrapKeyArgs>(\n context,\n \"unwrapKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as UnwrapKeyArgs[\"format\"],\n wrappedKey: unmarshal(ctx, getArg(args, 1)) as Uint8Array,\n unwrappingKey: getHostKey(ctx, getArg(args, 2)),\n unwrapAlgorithm: unmarshal(ctx, getArg(args, 3)) as AlgorithmIdentifier,\n unwrappedKeyAlgorithm: unmarshal(ctx, getArg(args, 4)) as AlgorithmIdentifier,\n extractable: unmarshal(ctx, getArg(args, 5)) as boolean,\n keyUsages: unmarshal(ctx, getArg(args, 6)) as globalThis.KeyUsage[],\n }),\n async (ctx, { format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages }) => {\n const result = await crypto.subtle.unwrapKey(\n format,\n wrappedKey as unknown as BufferSource,\n unwrappingKey,\n unwrapAlgorithm,\n unwrappedKeyAlgorithm,\n extractable,\n keyUsages\n );\n\n return createCryptoKeyInstance(ctx, result as globalThis.CryptoKey);\n }\n );\n context.setProp(subtle, \"unwrapKey\", unwrapKeyFn);\n unwrapKeyFn.dispose();\n\n return subtle;\n}\n"
|
|
5
|
+
"import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { CryptoKeyState, KeyUsage } from \"./types.mjs\";\nimport {\n nextInstanceId,\n registerInstance,\n getInstanceStateById,\n marshal,\n unmarshal,\n} from \"@ricsam/quickjs-core\";\n\n/**\n * Helper to create a CryptoKey instance in QuickJS from a host CryptoKey\n *\n * This registers the host key in our state management and creates\n * a QuickJS CryptoKey object that references it via __instanceId__\n */\nexport function createCryptoKeyInstance(\n context: QuickJSContext,\n hostKey: globalThis.CryptoKey\n): QuickJSHandle {\n const instanceId = nextInstanceId();\n\n const state: CryptoKeyState = {\n hostKey,\n type: hostKey.type,\n extractable: hostKey.extractable,\n algorithm: hostKey.algorithm as KeyAlgorithm,\n usages: Array.from(hostKey.usages) as KeyUsage[],\n };\n\n registerInstance(instanceId, \"CryptoKey\", state);\n\n // Create instance via evalCode to properly instantiate with prototype chain\n const result = context.evalCode(`\n (function() {\n const key = Object.create(CryptoKey.prototype);\n Object.defineProperty(key, '__instanceId__', {\n value: ${instanceId},\n enumerable: false,\n writable: false,\n configurable: false\n });\n return key;\n })()\n `);\n\n if (result.error) {\n const err = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to create CryptoKey instance: ${JSON.stringify(err)}`);\n }\n\n return result.value;\n}\n\n/**\n * Helper to create a CryptoKeyPair object in QuickJS\n */\nfunction createCryptoKeyPairInstance(\n context: QuickJSContext,\n keyPair: globalThis.CryptoKeyPair\n): QuickJSHandle {\n const publicKeyHandle = createCryptoKeyInstance(context, keyPair.publicKey);\n const privateKeyHandle = createCryptoKeyInstance(context, keyPair.privateKey);\n\n const obj = context.newObject();\n context.setProp(obj, \"publicKey\", publicKeyHandle);\n context.setProp(obj, \"privateKey\", privateKeyHandle);\n\n publicKeyHandle.dispose();\n privateKeyHandle.dispose();\n\n return obj;\n}\n\n/**\n * Helper to get the host CryptoKey from a QuickJS CryptoKey handle\n */\nfunction getHostKey(context: QuickJSContext, keyHandle: QuickJSHandle): globalThis.CryptoKey {\n const instanceIdHandle = context.getProp(keyHandle, \"__instanceId__\");\n if (context.typeof(instanceIdHandle) !== \"number\") {\n instanceIdHandle.dispose();\n throw new Error(\"Invalid CryptoKey: missing __instanceId__\");\n }\n\n const instanceId = context.getNumber(instanceIdHandle);\n instanceIdHandle.dispose();\n\n const state = getInstanceStateById<CryptoKeyState>(instanceId);\n if (!state) {\n throw new Error(\"Invalid CryptoKey: state not found\");\n }\n\n return state.hostKey;\n}\n\n/**\n * Helper to safely get an argument from the args array\n */\nfunction getArg(args: QuickJSHandle[], index: number): QuickJSHandle {\n const arg = args[index];\n if (!arg) {\n throw new Error(`Missing argument at index ${index}`);\n }\n return arg;\n}\n\n/**\n * Create an async SubtleCrypto method that handles CryptoKey marshalling\n *\n * The key insight is that implementations must NOT use the context after their\n * async operations, because the context could be disposed during the await.\n * Instead, implementations return raw JavaScript values, and marshalling happens\n * in this function AFTER checking that the context is still alive.\n *\n * @param unmarshalArgs - Function to unmarshal arguments synchronously before async work\n * @param implementation - Async implementation that returns raw values (no context access)\n * @param marshalResult - Function to marshal the raw result to a QuickJS handle\n */\nfunction createSubtleMethod<T, R>(\n context: QuickJSContext,\n methodName: string,\n unmarshalArgs: (context: QuickJSContext, args: QuickJSHandle[]) => T,\n implementation: (unmarshaledArgs: T) => Promise<R>,\n marshalResult: (context: QuickJSContext, result: R) => QuickJSHandle\n): QuickJSHandle {\n return context.newFunction(methodName, (...args) => {\n const deferred = context.newPromise();\n\n // Unmarshal arguments synchronously BEFORE scheduling async work\n // This is critical because the QuickJS handles may be disposed before the microtask runs\n let unmarshaledArgs: T;\n try {\n unmarshaledArgs = unmarshalArgs(context, args);\n } catch (error) {\n // If unmarshalling fails, reject immediately\n const errorHandle = marshal(context, {\n name: error instanceof Error ? error.name : \"Error\",\n message: error instanceof Error ? error.message : String(error),\n });\n deferred.reject(errorHandle);\n errorHandle.dispose();\n context.runtime.executePendingJobs();\n return deferred.handle;\n }\n\n // Run the async implementation in a microtask\n Promise.resolve().then(async () => {\n // Guard: Check if context is still alive before starting\n if (!context.alive) {\n return;\n }\n\n try {\n // Implementation returns raw values - no context access after await\n const rawResult = await implementation(unmarshaledArgs);\n\n // Guard: Check if context is still alive BEFORE marshalling\n if (!context.alive) {\n return;\n }\n\n // Now safe to marshal the result\n const resultHandle = marshalResult(context, rawResult);\n deferred.resolve(resultHandle);\n resultHandle.dispose();\n } catch (error) {\n // Guard: Check if context is still alive before error handling\n if (!context.alive) {\n return;\n }\n\n const errorHandle = marshal(context, {\n name: error instanceof Error ? error.name : \"Error\",\n message: error instanceof Error ? error.message : String(error),\n });\n deferred.reject(errorHandle);\n errorHandle.dispose();\n }\n\n if (context.alive) {\n context.runtime.executePendingJobs();\n }\n });\n\n return deferred.handle;\n });\n}\n\n// Type definitions for unmarshaled args\ninterface DigestArgs {\n algorithm: AlgorithmIdentifier;\n data: Uint8Array;\n}\n\ninterface GenerateKeyArgs {\n algorithm: RsaHashedKeyGenParams | EcKeyGenParams | AesKeyGenParams | HmacKeyGenParams;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\ninterface SignArgs {\n algorithm: AlgorithmIdentifier;\n key: globalThis.CryptoKey;\n data: Uint8Array;\n}\n\ninterface VerifyArgs {\n algorithm: AlgorithmIdentifier;\n key: globalThis.CryptoKey;\n signature: Uint8Array;\n data: Uint8Array;\n}\n\ninterface EncryptDecryptArgs {\n algorithm: AlgorithmIdentifier;\n key: globalThis.CryptoKey;\n data: Uint8Array;\n}\n\ninterface ImportKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n keyData: Uint8Array | JsonWebKey;\n algorithm: AlgorithmIdentifier;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\ninterface ExportKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n key: globalThis.CryptoKey;\n}\n\ninterface DeriveBitsArgs {\n algorithm: Record<string, unknown>;\n baseKey: globalThis.CryptoKey;\n length: number;\n}\n\ninterface DeriveKeyArgs {\n algorithm: Record<string, unknown>;\n baseKey: globalThis.CryptoKey;\n derivedKeyType: AlgorithmIdentifier;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\ninterface WrapKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n key: globalThis.CryptoKey;\n wrappingKey: globalThis.CryptoKey;\n wrapAlgorithm: AlgorithmIdentifier;\n}\n\ninterface UnwrapKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n wrappedKey: Uint8Array;\n unwrappingKey: globalThis.CryptoKey;\n unwrapAlgorithm: AlgorithmIdentifier;\n unwrappedKeyAlgorithm: AlgorithmIdentifier;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\n// Result types for marshalling\ntype GenerateKeyResult =\n | { type: \"key\"; hostKey: globalThis.CryptoKey }\n | { type: \"pair\"; publicKey: globalThis.CryptoKey; privateKey: globalThis.CryptoKey };\ntype ExportKeyResult = Uint8Array | JsonWebKey;\n\n/**\n * Create the SubtleCrypto object with all methods\n */\nexport function createSubtleCryptoObject(context: QuickJSContext): QuickJSHandle {\n const subtle = context.newObject();\n\n // digest(algorithm, data) -> ArrayBuffer\n const digestFn = createSubtleMethod<DigestArgs, Uint8Array>(\n context,\n \"digest\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n data: unmarshal(ctx, getArg(args, 1)) as Uint8Array,\n }),\n async ({ algorithm, data }) => {\n const result = await crypto.subtle.digest(algorithm, data as unknown as BufferSource);\n return new Uint8Array(result);\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"digest\", digestFn);\n digestFn.dispose();\n\n // generateKey(algorithm, extractable, keyUsages) -> CryptoKey | CryptoKeyPair\n const generateKeyFn = createSubtleMethod<GenerateKeyArgs, GenerateKeyResult>(\n context,\n \"generateKey\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as GenerateKeyArgs[\"algorithm\"],\n extractable: unmarshal(ctx, getArg(args, 1)) as boolean,\n keyUsages: unmarshal(ctx, getArg(args, 2)) as globalThis.KeyUsage[],\n }),\n async ({ algorithm, extractable, keyUsages }) => {\n const result = await crypto.subtle.generateKey(algorithm, extractable, keyUsages);\n\n // Check if it's a key pair or single key\n if (\"publicKey\" in result && \"privateKey\" in result) {\n return { type: \"pair\", publicKey: result.publicKey, privateKey: result.privateKey };\n } else {\n return { type: \"key\", hostKey: result as globalThis.CryptoKey };\n }\n },\n (ctx, result) => {\n if (result.type === \"pair\") {\n return createCryptoKeyPairInstance(ctx, { publicKey: result.publicKey, privateKey: result.privateKey });\n } else {\n return createCryptoKeyInstance(ctx, result.hostKey);\n }\n }\n );\n context.setProp(subtle, \"generateKey\", generateKeyFn);\n generateKeyFn.dispose();\n\n // sign(algorithm, key, data) -> ArrayBuffer\n const signFn = createSubtleMethod<SignArgs, Uint8Array>(\n context,\n \"sign\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n data: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n }),\n async ({ algorithm, key, data }) => {\n const result = await crypto.subtle.sign(algorithm, key, data as unknown as BufferSource);\n return new Uint8Array(result);\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"sign\", signFn);\n signFn.dispose();\n\n // verify(algorithm, key, signature, data) -> boolean\n const verifyFn = createSubtleMethod<VerifyArgs, boolean>(\n context,\n \"verify\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n signature: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n data: unmarshal(ctx, getArg(args, 3)) as Uint8Array,\n }),\n async ({ algorithm, key, signature, data }) => {\n return await crypto.subtle.verify(\n algorithm,\n key,\n signature as unknown as BufferSource,\n data as unknown as BufferSource\n );\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"verify\", verifyFn);\n verifyFn.dispose();\n\n // encrypt(algorithm, key, data) -> ArrayBuffer\n const encryptFn = createSubtleMethod<EncryptDecryptArgs, Uint8Array>(\n context,\n \"encrypt\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n data: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n }),\n async ({ algorithm, key, data }) => {\n const result = await crypto.subtle.encrypt(\n algorithm,\n key,\n data as unknown as BufferSource\n );\n return new Uint8Array(result);\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"encrypt\", encryptFn);\n encryptFn.dispose();\n\n // decrypt(algorithm, key, data) -> ArrayBuffer\n const decryptFn = createSubtleMethod<EncryptDecryptArgs, Uint8Array>(\n context,\n \"decrypt\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n data: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n }),\n async ({ algorithm, key, data }) => {\n const result = await crypto.subtle.decrypt(\n algorithm,\n key,\n data as unknown as BufferSource\n );\n return new Uint8Array(result);\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"decrypt\", decryptFn);\n decryptFn.dispose();\n\n // importKey(format, keyData, algorithm, extractable, keyUsages) -> CryptoKey\n const importKeyFn = createSubtleMethod<ImportKeyArgs, globalThis.CryptoKey>(\n context,\n \"importKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as ImportKeyArgs[\"format\"],\n keyData: unmarshal(ctx, getArg(args, 1)) as Uint8Array | JsonWebKey,\n algorithm: unmarshal(ctx, getArg(args, 2)) as AlgorithmIdentifier,\n extractable: unmarshal(ctx, getArg(args, 3)) as boolean,\n keyUsages: unmarshal(ctx, getArg(args, 4)) as globalThis.KeyUsage[],\n }),\n async ({ format, keyData, algorithm, extractable, keyUsages }) => {\n if (format === \"jwk\") {\n // JWK format expects JsonWebKey\n return await crypto.subtle.importKey(\n format,\n keyData as JsonWebKey,\n algorithm,\n extractable,\n keyUsages\n );\n } else {\n // Non-jwk formats expect BufferSource\n // Convert Uint8Array to ArrayBuffer\n let data: BufferSource;\n if (keyData instanceof Uint8Array) {\n data = keyData.buffer.slice(keyData.byteOffset, keyData.byteOffset + keyData.byteLength) as ArrayBuffer;\n } else {\n data = keyData as BufferSource;\n }\n\n return await crypto.subtle.importKey(\n format,\n data,\n algorithm,\n extractable,\n keyUsages\n ) as globalThis.CryptoKey;\n }\n },\n (ctx, result) => createCryptoKeyInstance(ctx, result)\n );\n context.setProp(subtle, \"importKey\", importKeyFn);\n importKeyFn.dispose();\n\n // exportKey(format, key) -> ArrayBuffer | JsonWebKey\n const exportKeyFn = createSubtleMethod<ExportKeyArgs, ExportKeyResult>(\n context,\n \"exportKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as ExportKeyArgs[\"format\"],\n key: getHostKey(ctx, getArg(args, 1)),\n }),\n async ({ format, key }) => {\n const result = await crypto.subtle.exportKey(format, key);\n\n if (result instanceof ArrayBuffer) {\n return new Uint8Array(result);\n } else {\n // JsonWebKey - return as-is\n return result;\n }\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"exportKey\", exportKeyFn);\n exportKeyFn.dispose();\n\n // deriveBits(algorithm, baseKey, length) -> ArrayBuffer\n const deriveBitsFn = createSubtleMethod<DeriveBitsArgs, Uint8Array>(\n context,\n \"deriveBits\",\n (ctx, args) => {\n const algorithmRaw = unmarshal(ctx, getArg(args, 0)) as Record<string, unknown>;\n const baseKey = getHostKey(ctx, getArg(args, 1));\n const length = unmarshal(ctx, getArg(args, 2)) as number;\n\n // If the algorithm has a 'public' property, it needs to be a CryptoKey\n let algorithm = algorithmRaw;\n if (algorithmRaw.public && typeof algorithmRaw.public === \"object\") {\n const publicKeyData = algorithmRaw.public as { __instanceId__?: number };\n if (publicKeyData.__instanceId__ !== undefined) {\n const publicKeyState = getInstanceStateById<CryptoKeyState>(publicKeyData.__instanceId__);\n if (publicKeyState) {\n algorithm = { ...algorithmRaw, public: publicKeyState.hostKey };\n }\n }\n }\n\n return { algorithm, baseKey, length };\n },\n async ({ algorithm, baseKey, length }) => {\n const result = await crypto.subtle.deriveBits(\n algorithm as unknown as AlgorithmIdentifier,\n baseKey,\n length\n );\n return new Uint8Array(result);\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"deriveBits\", deriveBitsFn);\n deriveBitsFn.dispose();\n\n // deriveKey(algorithm, baseKey, derivedKeyType, extractable, keyUsages) -> CryptoKey\n const deriveKeyFn = createSubtleMethod<DeriveKeyArgs, globalThis.CryptoKey>(\n context,\n \"deriveKey\",\n (ctx, args) => {\n const algorithmRaw = unmarshal(ctx, getArg(args, 0)) as Record<string, unknown>;\n const baseKey = getHostKey(ctx, getArg(args, 1));\n const derivedKeyType = unmarshal(ctx, getArg(args, 2)) as AlgorithmIdentifier;\n const extractable = unmarshal(ctx, getArg(args, 3)) as boolean;\n const keyUsages = unmarshal(ctx, getArg(args, 4)) as globalThis.KeyUsage[];\n\n // If the algorithm has a 'public' property, it needs to be a CryptoKey\n let algorithm = algorithmRaw;\n if (algorithmRaw.public && typeof algorithmRaw.public === \"object\") {\n const publicKeyData = algorithmRaw.public as { __instanceId__?: number };\n if (publicKeyData.__instanceId__ !== undefined) {\n const publicKeyState = getInstanceStateById<CryptoKeyState>(publicKeyData.__instanceId__);\n if (publicKeyState) {\n algorithm = { ...algorithmRaw, public: publicKeyState.hostKey };\n }\n }\n }\n\n return { algorithm, baseKey, derivedKeyType, extractable, keyUsages };\n },\n async ({ algorithm, baseKey, derivedKeyType, extractable, keyUsages }) => {\n return await crypto.subtle.deriveKey(\n algorithm as unknown as AlgorithmIdentifier,\n baseKey,\n derivedKeyType,\n extractable,\n keyUsages\n ) as globalThis.CryptoKey;\n },\n (ctx, result) => createCryptoKeyInstance(ctx, result)\n );\n context.setProp(subtle, \"deriveKey\", deriveKeyFn);\n deriveKeyFn.dispose();\n\n // wrapKey(format, key, wrappingKey, wrapAlgorithm) -> ArrayBuffer\n const wrapKeyFn = createSubtleMethod<WrapKeyArgs, Uint8Array>(\n context,\n \"wrapKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as WrapKeyArgs[\"format\"],\n key: getHostKey(ctx, getArg(args, 1)),\n wrappingKey: getHostKey(ctx, getArg(args, 2)),\n wrapAlgorithm: unmarshal(ctx, getArg(args, 3)) as AlgorithmIdentifier,\n }),\n async ({ format, key, wrappingKey, wrapAlgorithm }) => {\n const result = await crypto.subtle.wrapKey(format, key, wrappingKey, wrapAlgorithm);\n return new Uint8Array(result);\n },\n (ctx, result) => marshal(ctx, result)\n );\n context.setProp(subtle, \"wrapKey\", wrapKeyFn);\n wrapKeyFn.dispose();\n\n // unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages) -> CryptoKey\n const unwrapKeyFn = createSubtleMethod<UnwrapKeyArgs, globalThis.CryptoKey>(\n context,\n \"unwrapKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as UnwrapKeyArgs[\"format\"],\n wrappedKey: unmarshal(ctx, getArg(args, 1)) as Uint8Array,\n unwrappingKey: getHostKey(ctx, getArg(args, 2)),\n unwrapAlgorithm: unmarshal(ctx, getArg(args, 3)) as AlgorithmIdentifier,\n unwrappedKeyAlgorithm: unmarshal(ctx, getArg(args, 4)) as AlgorithmIdentifier,\n extractable: unmarshal(ctx, getArg(args, 5)) as boolean,\n keyUsages: unmarshal(ctx, getArg(args, 6)) as globalThis.KeyUsage[],\n }),\n async ({ format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages }) => {\n return await crypto.subtle.unwrapKey(\n format,\n wrappedKey as unknown as BufferSource,\n unwrappingKey,\n unwrapAlgorithm,\n unwrappedKeyAlgorithm,\n extractable,\n keyUsages\n ) as globalThis.CryptoKey;\n },\n (ctx, result) => createCryptoKeyInstance(ctx, result)\n );\n context.setProp(subtle, \"unwrapKey\", unwrapKeyFn);\n unwrapKeyFn.dispose();\n\n return subtle;\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcO,SAAS,uBAAuB,CACrC,SACA,SACe;AAAA,EACf,MAAM,aAAa,eAAe;AAAA,EAElC,MAAM,QAAwB;AAAA,IAC5B;AAAA,IACA,MAAM,QAAQ;AAAA,IACd,aAAa,QAAQ;AAAA,IACrB,WAAW,QAAQ;AAAA,IACnB,QAAQ,MAAM,KAAK,QAAQ,MAAM;AAAA,EACnC;AAAA,EAEA,iBAAiB,YAAY,aAAa,KAAK;AAAA,EAG/C,MAAM,SAAS,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,iBAIjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAOd;AAAA,EAED,IAAI,OAAO,OAAO;AAAA,IAChB,MAAM,MAAM,QAAQ,KAAK,OAAO,KAAK;AAAA,IACrC,OAAO,MAAM,QAAQ;AAAA,IACrB,MAAM,IAAI,MAAM,wCAAwC,KAAK,UAAU,GAAG,GAAG;AAAA,EAC/E;AAAA,EAEA,OAAO,OAAO;AAAA;AAMhB,SAAS,2BAA2B,CAClC,SACA,SACe;AAAA,EACf,MAAM,kBAAkB,wBAAwB,SAAS,QAAQ,SAAS;AAAA,EAC1E,MAAM,mBAAmB,wBAAwB,SAAS,QAAQ,UAAU;AAAA,EAE5E,MAAM,MAAM,QAAQ,UAAU;AAAA,EAC9B,QAAQ,QAAQ,KAAK,aAAa,eAAe;AAAA,EACjD,QAAQ,QAAQ,KAAK,cAAc,gBAAgB;AAAA,EAEnD,gBAAgB,QAAQ;AAAA,EACxB,iBAAiB,QAAQ;AAAA,EAEzB,OAAO;AAAA;AAMT,SAAS,UAAU,CAAC,SAAyB,WAAgD;AAAA,EAC3F,MAAM,mBAAmB,QAAQ,QAAQ,WAAW,gBAAgB;AAAA,EACpE,IAAI,QAAQ,OAAO,gBAAgB,MAAM,UAAU;AAAA,IACjD,iBAAiB,QAAQ;AAAA,IACzB,MAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AAAA,EAEA,MAAM,aAAa,QAAQ,UAAU,gBAAgB;AAAA,EACrD,iBAAiB,QAAQ;AAAA,EAEzB,MAAM,QAAQ,qBAAqC,UAAU;AAAA,EAC7D,IAAI,CAAC,OAAO;AAAA,IACV,MAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AAAA,EAEA,OAAO,MAAM;AAAA;AAMf,SAAS,MAAM,CAAC,MAAuB,OAA8B;AAAA,EACnE,MAAM,MAAM,KAAK;AAAA,EACjB,IAAI,CAAC,KAAK;AAAA,IACR,MAAM,IAAI,MAAM,6BAA6B,OAAO;AAAA,EACtD;AAAA,EACA,OAAO;AAAA;
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcO,SAAS,uBAAuB,CACrC,SACA,SACe;AAAA,EACf,MAAM,aAAa,eAAe;AAAA,EAElC,MAAM,QAAwB;AAAA,IAC5B;AAAA,IACA,MAAM,QAAQ;AAAA,IACd,aAAa,QAAQ;AAAA,IACrB,WAAW,QAAQ;AAAA,IACnB,QAAQ,MAAM,KAAK,QAAQ,MAAM;AAAA,EACnC;AAAA,EAEA,iBAAiB,YAAY,aAAa,KAAK;AAAA,EAG/C,MAAM,SAAS,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,iBAIjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAOd;AAAA,EAED,IAAI,OAAO,OAAO;AAAA,IAChB,MAAM,MAAM,QAAQ,KAAK,OAAO,KAAK;AAAA,IACrC,OAAO,MAAM,QAAQ;AAAA,IACrB,MAAM,IAAI,MAAM,wCAAwC,KAAK,UAAU,GAAG,GAAG;AAAA,EAC/E;AAAA,EAEA,OAAO,OAAO;AAAA;AAMhB,SAAS,2BAA2B,CAClC,SACA,SACe;AAAA,EACf,MAAM,kBAAkB,wBAAwB,SAAS,QAAQ,SAAS;AAAA,EAC1E,MAAM,mBAAmB,wBAAwB,SAAS,QAAQ,UAAU;AAAA,EAE5E,MAAM,MAAM,QAAQ,UAAU;AAAA,EAC9B,QAAQ,QAAQ,KAAK,aAAa,eAAe;AAAA,EACjD,QAAQ,QAAQ,KAAK,cAAc,gBAAgB;AAAA,EAEnD,gBAAgB,QAAQ;AAAA,EACxB,iBAAiB,QAAQ;AAAA,EAEzB,OAAO;AAAA;AAMT,SAAS,UAAU,CAAC,SAAyB,WAAgD;AAAA,EAC3F,MAAM,mBAAmB,QAAQ,QAAQ,WAAW,gBAAgB;AAAA,EACpE,IAAI,QAAQ,OAAO,gBAAgB,MAAM,UAAU;AAAA,IACjD,iBAAiB,QAAQ;AAAA,IACzB,MAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AAAA,EAEA,MAAM,aAAa,QAAQ,UAAU,gBAAgB;AAAA,EACrD,iBAAiB,QAAQ;AAAA,EAEzB,MAAM,QAAQ,qBAAqC,UAAU;AAAA,EAC7D,IAAI,CAAC,OAAO;AAAA,IACV,MAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AAAA,EAEA,OAAO,MAAM;AAAA;AAMf,SAAS,MAAM,CAAC,MAAuB,OAA8B;AAAA,EACnE,MAAM,MAAM,KAAK;AAAA,EACjB,IAAI,CAAC,KAAK;AAAA,IACR,MAAM,IAAI,MAAM,6BAA6B,OAAO;AAAA,EACtD;AAAA,EACA,OAAO;AAAA;AAeT,SAAS,kBAAwB,CAC/B,SACA,YACA,eACA,gBACA,eACe;AAAA,EACf,OAAO,QAAQ,YAAY,YAAY,IAAI,SAAS;AAAA,IAClD,MAAM,WAAW,QAAQ,WAAW;AAAA,IAIpC,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,kBAAkB,cAAc,SAAS,IAAI;AAAA,MAC7C,OAAO,OAAO;AAAA,MAEd,MAAM,cAAc,QAAQ,SAAS;AAAA,QACnC,MAAM,iBAAiB,QAAQ,MAAM,OAAO;AAAA,QAC5C,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAChE,CAAC;AAAA,MACD,SAAS,OAAO,WAAW;AAAA,MAC3B,YAAY,QAAQ;AAAA,MACpB,QAAQ,QAAQ,mBAAmB;AAAA,MACnC,OAAO,SAAS;AAAA;AAAA,IAIlB,QAAQ,QAAQ,EAAE,KAAK,YAAY;AAAA,MAEjC,IAAI,CAAC,QAAQ,OAAO;AAAA,QAClB;AAAA,MACF;AAAA,MAEA,IAAI;AAAA,QAEF,MAAM,YAAY,MAAM,eAAe,eAAe;AAAA,QAGtD,IAAI,CAAC,QAAQ,OAAO;AAAA,UAClB;AAAA,QACF;AAAA,QAGA,MAAM,eAAe,cAAc,SAAS,SAAS;AAAA,QACrD,SAAS,QAAQ,YAAY;AAAA,QAC7B,aAAa,QAAQ;AAAA,QACrB,OAAO,OAAO;AAAA,QAEd,IAAI,CAAC,QAAQ,OAAO;AAAA,UAClB;AAAA,QACF;AAAA,QAEA,MAAM,cAAc,QAAQ,SAAS;AAAA,UACnC,MAAM,iBAAiB,QAAQ,MAAM,OAAO;AAAA,UAC5C,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAChE,CAAC;AAAA,QACD,SAAS,OAAO,WAAW;AAAA,QAC3B,YAAY,QAAQ;AAAA;AAAA,MAGtB,IAAI,QAAQ,OAAO;AAAA,QACjB,QAAQ,QAAQ,mBAAmB;AAAA,MACrC;AAAA,KACD;AAAA,IAED,OAAO,SAAS;AAAA,GACjB;AAAA;AAuFI,SAAS,wBAAwB,CAAC,SAAwC;AAAA,EAC/E,MAAM,SAAS,QAAQ,UAAU;AAAA,EAGjC,MAAM,WAAW,mBACf,SACA,UACA,CAAC,KAAK,UAAU;AAAA,IACd,WAAW,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACzC,MAAM,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,EACtC,IACA,SAAS,WAAW,WAAW;AAAA,IAC7B,MAAM,SAAS,MAAM,OAAO,OAAO,OAAO,WAAW,IAA+B;AAAA,IACpF,OAAO,IAAI,WAAW,MAAM;AAAA,KAE9B,CAAC,KAAK,WAAW,QAAQ,KAAK,MAAM,CACtC;AAAA,EACA,QAAQ,QAAQ,QAAQ,UAAU,QAAQ;AAAA,EAC1C,SAAS,QAAQ;AAAA,EAGjB,MAAM,gBAAgB,mBACpB,SACA,eACA,CAAC,KAAK,UAAU;AAAA,IACd,WAAW,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACzC,aAAa,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IAC3C,WAAW,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,EAC3C,IACA,SAAS,WAAW,aAAa,gBAAgB;AAAA,IAC/C,MAAM,SAAS,MAAM,OAAO,OAAO,YAAY,WAAW,aAAa,SAAS;AAAA,IAGhF,IAAI,eAAe,UAAU,gBAAgB,QAAQ;AAAA,MACnD,OAAO,EAAE,MAAM,QAAQ,WAAW,OAAO,WAAW,YAAY,OAAO,WAAW;AAAA,IACpF,EAAO;AAAA,MACL,OAAO,EAAE,MAAM,OAAO,SAAS,OAA+B;AAAA;AAAA,KAGlE,CAAC,KAAK,WAAW;AAAA,IACf,IAAI,OAAO,SAAS,QAAQ;AAAA,MAC1B,OAAO,4BAA4B,KAAK,EAAE,WAAW,OAAO,WAAW,YAAY,OAAO,WAAW,CAAC;AAAA,IACxG,EAAO;AAAA,MACL,OAAO,wBAAwB,KAAK,OAAO,OAAO;AAAA;AAAA,GAGxD;AAAA,EACA,QAAQ,QAAQ,QAAQ,eAAe,aAAa;AAAA,EACpD,cAAc,QAAQ;AAAA,EAGtB,MAAM,SAAS,mBACb,SACA,QACA,CAAC,KAAK,UAAU;AAAA,IACd,WAAW,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACzC,KAAK,WAAW,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACpC,MAAM,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,EACtC,IACA,SAAS,WAAW,KAAK,WAAW;AAAA,IAClC,MAAM,SAAS,MAAM,OAAO,OAAO,KAAK,WAAW,KAAK,IAA+B;AAAA,IACvF,OAAO,IAAI,WAAW,MAAM;AAAA,KAE9B,CAAC,KAAK,WAAW,QAAQ,KAAK,MAAM,CACtC;AAAA,EACA,QAAQ,QAAQ,QAAQ,QAAQ,MAAM;AAAA,EACtC,OAAO,QAAQ;AAAA,EAGf,MAAM,WAAW,mBACf,SACA,UACA,CAAC,KAAK,UAAU;AAAA,IACd,WAAW,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACzC,KAAK,WAAW,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACpC,WAAW,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACzC,MAAM,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,EACtC,IACA,SAAS,WAAW,KAAK,WAAW,WAAW;AAAA,IAC7C,OAAO,MAAM,OAAO,OAAO,OACzB,WACA,KACA,WACA,IACF;AAAA,KAEF,CAAC,KAAK,WAAW,QAAQ,KAAK,MAAM,CACtC;AAAA,EACA,QAAQ,QAAQ,QAAQ,UAAU,QAAQ;AAAA,EAC1C,SAAS,QAAQ;AAAA,EAGjB,MAAM,YAAY,mBAChB,SACA,WACA,CAAC,KAAK,UAAU;AAAA,IACd,WAAW,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACzC,KAAK,WAAW,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACpC,MAAM,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,EACtC,IACA,SAAS,WAAW,KAAK,WAAW;AAAA,IAClC,MAAM,SAAS,MAAM,OAAO,OAAO,QACjC,WACA,KACA,IACF;AAAA,IACA,OAAO,IAAI,WAAW,MAAM;AAAA,KAE9B,CAAC,KAAK,WAAW,QAAQ,KAAK,MAAM,CACtC;AAAA,EACA,QAAQ,QAAQ,QAAQ,WAAW,SAAS;AAAA,EAC5C,UAAU,QAAQ;AAAA,EAGlB,MAAM,YAAY,mBAChB,SACA,WACA,CAAC,KAAK,UAAU;AAAA,IACd,WAAW,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACzC,KAAK,WAAW,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACpC,MAAM,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,EACtC,IACA,SAAS,WAAW,KAAK,WAAW;AAAA,IAClC,MAAM,SAAS,MAAM,OAAO,OAAO,QACjC,WACA,KACA,IACF;AAAA,IACA,OAAO,IAAI,WAAW,MAAM;AAAA,KAE9B,CAAC,KAAK,WAAW,QAAQ,KAAK,MAAM,CACtC;AAAA,EACA,QAAQ,QAAQ,QAAQ,WAAW,SAAS;AAAA,EAC5C,UAAU,QAAQ;AAAA,EAGlB,MAAM,cAAc,mBAClB,SACA,aACA,CAAC,KAAK,UAAU;AAAA,IACd,QAAQ,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACtC,SAAS,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACvC,WAAW,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACzC,aAAa,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IAC3C,WAAW,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,EAC3C,IACA,SAAS,QAAQ,SAAS,WAAW,aAAa,gBAAgB;AAAA,IAChE,IAAI,WAAW,OAAO;AAAA,MAEpB,OAAO,MAAM,OAAO,OAAO,UACzB,QACA,SACA,WACA,aACA,SACF;AAAA,IACF,EAAO;AAAA,MAGL,IAAI;AAAA,MACJ,IAAI,mBAAmB,YAAY;AAAA,QACjC,OAAO,QAAQ,OAAO,MAAM,QAAQ,YAAY,QAAQ,aAAa,QAAQ,UAAU;AAAA,MACzF,EAAO;AAAA,QACL,OAAO;AAAA;AAAA,MAGT,OAAO,MAAM,OAAO,OAAO,UACzB,QACA,MACA,WACA,aACA,SACF;AAAA;AAAA,KAGJ,CAAC,KAAK,WAAW,wBAAwB,KAAK,MAAM,CACtD;AAAA,EACA,QAAQ,QAAQ,QAAQ,aAAa,WAAW;AAAA,EAChD,YAAY,QAAQ;AAAA,EAGpB,MAAM,cAAc,mBAClB,SACA,aACA,CAAC,KAAK,UAAU;AAAA,IACd,QAAQ,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACtC,KAAK,WAAW,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,EACtC,IACA,SAAS,QAAQ,UAAU;AAAA,IACzB,MAAM,SAAS,MAAM,OAAO,OAAO,UAAU,QAAQ,GAAG;AAAA,IAExD,IAAI,kBAAkB,aAAa;AAAA,MACjC,OAAO,IAAI,WAAW,MAAM;AAAA,IAC9B,EAAO;AAAA,MAEL,OAAO;AAAA;AAAA,KAGX,CAAC,KAAK,WAAW,QAAQ,KAAK,MAAM,CACtC;AAAA,EACA,QAAQ,QAAQ,QAAQ,aAAa,WAAW;AAAA,EAChD,YAAY,QAAQ;AAAA,EAGpB,MAAM,eAAe,mBACnB,SACA,cACA,CAAC,KAAK,SAAS;AAAA,IACb,MAAM,eAAe,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACnD,MAAM,UAAU,WAAW,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IAC/C,MAAM,SAAS,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IAG7C,IAAI,YAAY;AAAA,IAChB,IAAI,aAAa,UAAU,OAAO,aAAa,WAAW,UAAU;AAAA,MAClE,MAAM,gBAAgB,aAAa;AAAA,MACnC,IAAI,cAAc,mBAAmB,WAAW;AAAA,QAC9C,MAAM,iBAAiB,qBAAqC,cAAc,cAAc;AAAA,QACxF,IAAI,gBAAgB;AAAA,UAClB,YAAY,KAAK,cAAc,QAAQ,eAAe,QAAQ;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAAA,IAEA,OAAO,EAAE,WAAW,SAAS,OAAO;AAAA,KAEtC,SAAS,WAAW,SAAS,aAAa;AAAA,IACxC,MAAM,SAAS,MAAM,OAAO,OAAO,WACjC,WACA,SACA,MACF;AAAA,IACA,OAAO,IAAI,WAAW,MAAM;AAAA,KAE9B,CAAC,KAAK,WAAW,QAAQ,KAAK,MAAM,CACtC;AAAA,EACA,QAAQ,QAAQ,QAAQ,cAAc,YAAY;AAAA,EAClD,aAAa,QAAQ;AAAA,EAGrB,MAAM,cAAc,mBAClB,SACA,aACA,CAAC,KAAK,SAAS;AAAA,IACb,MAAM,eAAe,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACnD,MAAM,UAAU,WAAW,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IAC/C,MAAM,iBAAiB,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACrD,MAAM,cAAc,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IAClD,MAAM,YAAY,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IAGhD,IAAI,YAAY;AAAA,IAChB,IAAI,aAAa,UAAU,OAAO,aAAa,WAAW,UAAU;AAAA,MAClE,MAAM,gBAAgB,aAAa;AAAA,MACnC,IAAI,cAAc,mBAAmB,WAAW;AAAA,QAC9C,MAAM,iBAAiB,qBAAqC,cAAc,cAAc;AAAA,QACxF,IAAI,gBAAgB;AAAA,UAClB,YAAY,KAAK,cAAc,QAAQ,eAAe,QAAQ;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAAA,IAEA,OAAO,EAAE,WAAW,SAAS,gBAAgB,aAAa,UAAU;AAAA,KAEtE,SAAS,WAAW,SAAS,gBAAgB,aAAa,gBAAgB;AAAA,IACxE,OAAO,MAAM,OAAO,OAAO,UACzB,WACA,SACA,gBACA,aACA,SACF;AAAA,KAEF,CAAC,KAAK,WAAW,wBAAwB,KAAK,MAAM,CACtD;AAAA,EACA,QAAQ,QAAQ,QAAQ,aAAa,WAAW;AAAA,EAChD,YAAY,QAAQ;AAAA,EAGpB,MAAM,YAAY,mBAChB,SACA,WACA,CAAC,KAAK,UAAU;AAAA,IACd,QAAQ,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACtC,KAAK,WAAW,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACpC,aAAa,WAAW,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IAC5C,eAAe,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,EAC/C,IACA,SAAS,QAAQ,KAAK,aAAa,oBAAoB;AAAA,IACrD,MAAM,SAAS,MAAM,OAAO,OAAO,QAAQ,QAAQ,KAAK,aAAa,aAAa;AAAA,IAClF,OAAO,IAAI,WAAW,MAAM;AAAA,KAE9B,CAAC,KAAK,WAAW,QAAQ,KAAK,MAAM,CACtC;AAAA,EACA,QAAQ,QAAQ,QAAQ,WAAW,SAAS;AAAA,EAC5C,UAAU,QAAQ;AAAA,EAGlB,MAAM,cAAc,mBAClB,SACA,aACA,CAAC,KAAK,UAAU;AAAA,IACd,QAAQ,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACtC,YAAY,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IAC1C,eAAe,WAAW,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IAC9C,iBAAiB,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IAC/C,uBAAuB,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACrD,aAAa,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IAC3C,WAAW,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,EAC3C,IACA,SAAS,QAAQ,YAAY,eAAe,iBAAiB,uBAAuB,aAAa,gBAAgB;AAAA,IAC/G,OAAO,MAAM,OAAO,OAAO,UACzB,QACA,YACA,eACA,iBACA,uBACA,aACA,SACF;AAAA,KAEF,CAAC,KAAK,WAAW,wBAAwB,KAAK,MAAM,CACtD;AAAA,EACA,QAAQ,QAAQ,QAAQ,aAAa,WAAW;AAAA,EAChD,YAAY,QAAQ;AAAA,EAEpB,OAAO;AAAA;",
|
|
8
|
+
"debugId": "BDAAC1BB5C73211A64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ricsam/quickjs-crypto",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.17",
|
|
4
4
|
"main": "./dist/cjs/index.cjs",
|
|
5
5
|
"types": "./dist/types/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"typecheck": "tsc --noEmit"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@ricsam/quickjs-core": "^0.2.
|
|
22
|
+
"@ricsam/quickjs-core": "^0.2.17",
|
|
23
23
|
"quickjs-emscripten": "^0.31.0"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|