@ricsam/quickjs-crypto 0.0.1 → 0.2.13

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.
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/subtle-crypto.ts"],
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"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "447E4B44811F04E864756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,3 @@
1
+ // @bun
2
+
3
+ //# debugId=6BB96AFC5414BDD964756E2164756E21
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [
5
+ ],
6
+ "mappings": "",
7
+ "debugId": "6BB96AFC5414BDD964756E2164756E21",
8
+ "names": []
9
+ }
@@ -0,0 +1,10 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+ import type { StateMap } from "./types.ts";
3
+ /**
4
+ * Create the CryptoKey class for the QuickJS context
5
+ *
6
+ * CryptoKey is an opaque type - the actual key material stays on the host.
7
+ * The QuickJS instance only holds metadata and an instanceId that maps
8
+ * to the host-side CryptoKey.
9
+ */
10
+ export declare function createCryptoKeyClass(context: QuickJSContext, stateMap: StateMap): QuickJSHandle;
@@ -0,0 +1,3 @@
1
+ export { setupCrypto } from "./setup.ts";
2
+ export type { SetupCryptoOptions, CryptoHandle, CryptoKeyState, KeyUsage, KeyType, } from "./types.ts";
3
+ export { createCryptoKeyInstance } from "./subtle-crypto.ts";
@@ -0,0 +1,287 @@
1
+ /**
2
+ * QuickJS Global Type Definitions for @ricsam/quickjs-crypto
3
+ *
4
+ * These types define the globals injected by setupCrypto() into a QuickJS context.
5
+ * Use these types to typecheck user code that will run inside QuickJS.
6
+ *
7
+ * @example
8
+ * // Generate random bytes
9
+ * const arr = new Uint8Array(16);
10
+ * crypto.getRandomValues(arr);
11
+ *
12
+ * // Generate UUID
13
+ * const uuid = crypto.randomUUID();
14
+ *
15
+ * // Use SubtleCrypto
16
+ * const key = await crypto.subtle.generateKey(
17
+ * { name: "AES-GCM", length: 256 },
18
+ * true,
19
+ * ["encrypt", "decrypt"]
20
+ * );
21
+ */
22
+
23
+ export {};
24
+
25
+ declare global {
26
+ /**
27
+ * CryptoKey represents a cryptographic key.
28
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey
29
+ */
30
+ interface CryptoKey {
31
+ /**
32
+ * The type of key: "public", "private", or "secret".
33
+ */
34
+ readonly type: "public" | "private" | "secret";
35
+
36
+ /**
37
+ * Whether the key can be exported.
38
+ */
39
+ readonly extractable: boolean;
40
+
41
+ /**
42
+ * The algorithm used by this key.
43
+ */
44
+ readonly algorithm: KeyAlgorithm;
45
+
46
+ /**
47
+ * The usages allowed for this key.
48
+ */
49
+ readonly usages: ReadonlyArray<KeyUsage>;
50
+ }
51
+
52
+ /**
53
+ * CryptoKey constructor (keys cannot be constructed directly).
54
+ */
55
+ const CryptoKey: {
56
+ prototype: CryptoKey;
57
+ };
58
+
59
+ /**
60
+ * SubtleCrypto interface for cryptographic operations.
61
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
62
+ */
63
+ interface SubtleCrypto {
64
+ /**
65
+ * Generate a digest (hash) of the given data.
66
+ *
67
+ * @param algorithm - Hash algorithm (e.g., "SHA-256", "SHA-384", "SHA-512")
68
+ * @param data - Data to hash
69
+ * @returns Promise resolving to the hash as ArrayBuffer
70
+ */
71
+ digest(
72
+ algorithm: AlgorithmIdentifier,
73
+ data: BufferSource
74
+ ): Promise<ArrayBuffer>;
75
+
76
+ /**
77
+ * Generate a new cryptographic key or key pair.
78
+ *
79
+ * @param algorithm - Key generation algorithm
80
+ * @param extractable - Whether the key can be exported
81
+ * @param keyUsages - Allowed key usages
82
+ * @returns Promise resolving to a CryptoKey or CryptoKeyPair
83
+ */
84
+ generateKey(
85
+ algorithm: RsaHashedKeyGenParams | EcKeyGenParams | AesKeyGenParams | HmacKeyGenParams,
86
+ extractable: boolean,
87
+ keyUsages: KeyUsage[]
88
+ ): Promise<CryptoKey | CryptoKeyPair>;
89
+
90
+ /**
91
+ * Sign data using a private key.
92
+ *
93
+ * @param algorithm - Signing algorithm
94
+ * @param key - Private key to sign with
95
+ * @param data - Data to sign
96
+ * @returns Promise resolving to the signature as ArrayBuffer
97
+ */
98
+ sign(
99
+ algorithm: AlgorithmIdentifier,
100
+ key: CryptoKey,
101
+ data: BufferSource
102
+ ): Promise<ArrayBuffer>;
103
+
104
+ /**
105
+ * Verify a signature.
106
+ *
107
+ * @param algorithm - Signing algorithm
108
+ * @param key - Public key to verify with
109
+ * @param signature - Signature to verify
110
+ * @param data - Data that was signed
111
+ * @returns Promise resolving to true if valid, false otherwise
112
+ */
113
+ verify(
114
+ algorithm: AlgorithmIdentifier,
115
+ key: CryptoKey,
116
+ signature: BufferSource,
117
+ data: BufferSource
118
+ ): Promise<boolean>;
119
+
120
+ /**
121
+ * Encrypt data.
122
+ *
123
+ * @param algorithm - Encryption algorithm
124
+ * @param key - Encryption key
125
+ * @param data - Data to encrypt
126
+ * @returns Promise resolving to encrypted data as ArrayBuffer
127
+ */
128
+ encrypt(
129
+ algorithm: AlgorithmIdentifier,
130
+ key: CryptoKey,
131
+ data: BufferSource
132
+ ): Promise<ArrayBuffer>;
133
+
134
+ /**
135
+ * Decrypt data.
136
+ *
137
+ * @param algorithm - Decryption algorithm
138
+ * @param key - Decryption key
139
+ * @param data - Data to decrypt
140
+ * @returns Promise resolving to decrypted data as ArrayBuffer
141
+ */
142
+ decrypt(
143
+ algorithm: AlgorithmIdentifier,
144
+ key: CryptoKey,
145
+ data: BufferSource
146
+ ): Promise<ArrayBuffer>;
147
+
148
+ /**
149
+ * Import a key from external data.
150
+ *
151
+ * @param format - Key format ("raw", "pkcs8", "spki", "jwk")
152
+ * @param keyData - Key data
153
+ * @param algorithm - Key algorithm
154
+ * @param extractable - Whether the key can be exported
155
+ * @param keyUsages - Allowed key usages
156
+ * @returns Promise resolving to a CryptoKey
157
+ */
158
+ importKey(
159
+ format: "raw" | "pkcs8" | "spki" | "jwk",
160
+ keyData: BufferSource | JsonWebKey,
161
+ algorithm: AlgorithmIdentifier,
162
+ extractable: boolean,
163
+ keyUsages: KeyUsage[]
164
+ ): Promise<CryptoKey>;
165
+
166
+ /**
167
+ * Export a key.
168
+ *
169
+ * @param format - Export format ("raw", "pkcs8", "spki", "jwk")
170
+ * @param key - Key to export
171
+ * @returns Promise resolving to ArrayBuffer or JsonWebKey
172
+ */
173
+ exportKey(
174
+ format: "raw" | "pkcs8" | "spki" | "jwk",
175
+ key: CryptoKey
176
+ ): Promise<ArrayBuffer | JsonWebKey>;
177
+
178
+ /**
179
+ * Derive bits from a key.
180
+ *
181
+ * @param algorithm - Derivation algorithm
182
+ * @param baseKey - Base key for derivation
183
+ * @param length - Number of bits to derive
184
+ * @returns Promise resolving to derived bits as ArrayBuffer
185
+ */
186
+ deriveBits(
187
+ algorithm: AlgorithmIdentifier,
188
+ baseKey: CryptoKey,
189
+ length: number
190
+ ): Promise<ArrayBuffer>;
191
+
192
+ /**
193
+ * Derive a new key from a base key.
194
+ *
195
+ * @param algorithm - Derivation algorithm
196
+ * @param baseKey - Base key for derivation
197
+ * @param derivedKeyType - Type of key to derive
198
+ * @param extractable - Whether the derived key can be exported
199
+ * @param keyUsages - Allowed usages for derived key
200
+ * @returns Promise resolving to a CryptoKey
201
+ */
202
+ deriveKey(
203
+ algorithm: AlgorithmIdentifier,
204
+ baseKey: CryptoKey,
205
+ derivedKeyType: AlgorithmIdentifier,
206
+ extractable: boolean,
207
+ keyUsages: KeyUsage[]
208
+ ): Promise<CryptoKey>;
209
+
210
+ /**
211
+ * Wrap a key for secure export.
212
+ *
213
+ * @param format - Key format
214
+ * @param key - Key to wrap
215
+ * @param wrappingKey - Key to wrap with
216
+ * @param wrapAlgorithm - Wrapping algorithm
217
+ * @returns Promise resolving to wrapped key as ArrayBuffer
218
+ */
219
+ wrapKey(
220
+ format: "raw" | "pkcs8" | "spki" | "jwk",
221
+ key: CryptoKey,
222
+ wrappingKey: CryptoKey,
223
+ wrapAlgorithm: AlgorithmIdentifier
224
+ ): Promise<ArrayBuffer>;
225
+
226
+ /**
227
+ * Unwrap a wrapped key.
228
+ *
229
+ * @param format - Key format
230
+ * @param wrappedKey - Wrapped key data
231
+ * @param unwrappingKey - Key to unwrap with
232
+ * @param unwrapAlgorithm - Unwrapping algorithm
233
+ * @param unwrappedKeyAlgorithm - Algorithm for the unwrapped key
234
+ * @param extractable - Whether the unwrapped key can be exported
235
+ * @param keyUsages - Allowed usages for unwrapped key
236
+ * @returns Promise resolving to a CryptoKey
237
+ */
238
+ unwrapKey(
239
+ format: "raw" | "pkcs8" | "spki" | "jwk",
240
+ wrappedKey: BufferSource,
241
+ unwrappingKey: CryptoKey,
242
+ unwrapAlgorithm: AlgorithmIdentifier,
243
+ unwrappedKeyAlgorithm: AlgorithmIdentifier,
244
+ extractable: boolean,
245
+ keyUsages: KeyUsage[]
246
+ ): Promise<CryptoKey>;
247
+ }
248
+
249
+ /**
250
+ * Crypto interface providing cryptographic functionality.
251
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Crypto
252
+ */
253
+ interface Crypto {
254
+ /**
255
+ * SubtleCrypto interface for cryptographic operations.
256
+ */
257
+ readonly subtle: SubtleCrypto;
258
+
259
+ /**
260
+ * Fill a TypedArray with cryptographically random values.
261
+ *
262
+ * @param array - TypedArray to fill (max 65536 bytes)
263
+ * @returns The same array, filled with random values
264
+ *
265
+ * @example
266
+ * const arr = new Uint8Array(16);
267
+ * crypto.getRandomValues(arr);
268
+ */
269
+ getRandomValues<T extends ArrayBufferView | null>(array: T): T;
270
+
271
+ /**
272
+ * Generate a random UUID v4.
273
+ *
274
+ * @returns A random UUID string
275
+ *
276
+ * @example
277
+ * const uuid = crypto.randomUUID();
278
+ * // "550e8400-e29b-41d4-a716-446655440000"
279
+ */
280
+ randomUUID(): string;
281
+ }
282
+
283
+ /**
284
+ * Crypto object providing cryptographic functionality.
285
+ */
286
+ const crypto: Crypto;
287
+ }
@@ -0,0 +1,14 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+ /**
3
+ * Create the getRandomValues function for the crypto global
4
+ *
5
+ * getRandomValues fills a TypedArray with cryptographically random values
6
+ * and returns the same array (modified in-place)
7
+ */
8
+ export declare function createGetRandomValuesFunction(context: QuickJSContext): QuickJSHandle;
9
+ /**
10
+ * Create the randomUUID function for the crypto global
11
+ *
12
+ * randomUUID returns a string containing a randomly generated UUID v4
13
+ */
14
+ export declare function createRandomUUIDFunction(context: QuickJSContext): QuickJSHandle;
@@ -0,0 +1,43 @@
1
+ import type { QuickJSContext } from "quickjs-emscripten";
2
+ import type { SetupCryptoOptions, CryptoHandle } from "./types.ts";
3
+ /**
4
+ * Setup crypto globals in a QuickJS context
5
+ *
6
+ * Provides: crypto.subtle (SubtleCrypto), crypto.getRandomValues, crypto.randomUUID, CryptoKey
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const handle = setupCrypto(context);
11
+ *
12
+ * context.evalCode(`
13
+ * // Generate a random UUID
14
+ * const uuid = crypto.randomUUID();
15
+ *
16
+ * // Generate random bytes
17
+ * const arr = new Uint8Array(16);
18
+ * crypto.getRandomValues(arr);
19
+ *
20
+ * // Use SubtleCrypto for encryption
21
+ * const key = await crypto.subtle.generateKey(
22
+ * { name: "AES-GCM", length: 256 },
23
+ * true,
24
+ * ["encrypt", "decrypt"]
25
+ * );
26
+ *
27
+ * const iv = crypto.getRandomValues(new Uint8Array(12));
28
+ * const data = new TextEncoder().encode("secret message");
29
+ * const encrypted = await crypto.subtle.encrypt(
30
+ * { name: "AES-GCM", iv },
31
+ * key,
32
+ * data
33
+ * );
34
+ * `);
35
+ *
36
+ * handle.dispose();
37
+ * ```
38
+ *
39
+ * @param context - QuickJS context
40
+ * @param options - Setup options
41
+ * @returns CryptoHandle for cleanup
42
+ */
43
+ export declare function setupCrypto(context: QuickJSContext, options?: SetupCryptoOptions): CryptoHandle;
@@ -0,0 +1,12 @@
1
+ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
+ /**
3
+ * Helper to create a CryptoKey instance in QuickJS from a host CryptoKey
4
+ *
5
+ * This registers the host key in our state management and creates
6
+ * a QuickJS CryptoKey object that references it via __instanceId__
7
+ */
8
+ export declare function createCryptoKeyInstance(context: QuickJSContext, hostKey: globalThis.CryptoKey): QuickJSHandle;
9
+ /**
10
+ * Create the SubtleCrypto object with all methods
11
+ */
12
+ export declare function createSubtleCryptoObject(context: QuickJSContext): QuickJSHandle;
@@ -0,0 +1,44 @@
1
+ import type { StateMap, CoreHandle } from "@ricsam/quickjs-core";
2
+ export type { StateMap, CoreHandle };
3
+ /**
4
+ * Key usage types as defined by Web Crypto API
5
+ */
6
+ export type KeyUsage = "encrypt" | "decrypt" | "sign" | "verify" | "deriveKey" | "deriveBits" | "wrapKey" | "unwrapKey";
7
+ /**
8
+ * Key type
9
+ */
10
+ export type KeyType = "public" | "private" | "secret";
11
+ /**
12
+ * Internal state for CryptoKey instances
13
+ * The actual CryptoKey stays on the host side
14
+ */
15
+ export interface CryptoKeyState {
16
+ /** Reference to host crypto key (actual CryptoKey from host) */
17
+ hostKey: globalThis.CryptoKey;
18
+ /** Key type: public, private, or secret */
19
+ type: KeyType;
20
+ /** Whether the key can be exported */
21
+ extractable: boolean;
22
+ /** Algorithm information */
23
+ algorithm: KeyAlgorithm;
24
+ /** Allowed usages for this key */
25
+ usages: KeyUsage[];
26
+ }
27
+ /**
28
+ * Options for setupCrypto
29
+ */
30
+ export interface SetupCryptoOptions {
31
+ /** Shared state map for instance tracking */
32
+ stateMap?: StateMap;
33
+ /** Core handle from setupCore */
34
+ coreHandle?: CoreHandle;
35
+ }
36
+ /**
37
+ * Handle returned from setupCrypto
38
+ */
39
+ export interface CryptoHandle {
40
+ /** Shared state map */
41
+ readonly stateMap: StateMap;
42
+ /** Dispose and cleanup */
43
+ dispose(): void;
44
+ }
package/package.json CHANGED
@@ -1,10 +1,58 @@
1
1
  {
2
2
  "name": "@ricsam/quickjs-crypto",
3
- "version": "0.0.1",
4
- "description": "OIDC trusted publishing setup package for @ricsam/quickjs-crypto",
3
+ "version": "0.2.13",
4
+ "main": "./dist/cjs/index.cjs",
5
+ "types": "./dist/types/index.d.ts",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/types/index.d.ts",
9
+ "require": "./dist/cjs/index.cjs",
10
+ "import": "./dist/mjs/index.mjs"
11
+ },
12
+ "./quickjs": {
13
+ "types": "./dist/types/quickjs.d.ts"
14
+ }
15
+ },
16
+ "scripts": {
17
+ "build": "bun build ./src/index.ts --outdir ./dist --target bun",
18
+ "test": "bun test",
19
+ "typecheck": "tsc --noEmit"
20
+ },
21
+ "dependencies": {
22
+ "@ricsam/quickjs-core": "^0.2.13",
23
+ "quickjs-emscripten": "^0.31.0"
24
+ },
25
+ "peerDependencies": {
26
+ "quickjs-emscripten": "^0.31.0"
27
+ },
28
+ "author": "Richard Samuelsson",
29
+ "license": "MIT",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/ricsam/richie-qjs.git"
33
+ },
34
+ "bugs": {
35
+ "url": "https://github.com/ricsam/richie-qjs/issues"
36
+ },
37
+ "homepage": "https://github.com/ricsam/richie-qjs#readme",
5
38
  "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
39
+ "quickjs",
40
+ "sandbox",
41
+ "javascript",
42
+ "runtime",
43
+ "fetch",
44
+ "filesystem",
45
+ "streams",
46
+ "wasm",
47
+ "emscripten"
48
+ ],
49
+ "description": "Web Crypto API implementation for QuickJS runtime",
50
+ "module": "./dist/mjs/index.mjs",
51
+ "publishConfig": {
52
+ "access": "public"
53
+ },
54
+ "files": [
55
+ "dist",
56
+ "README.md"
9
57
  ]
10
- }
58
+ }
package/README.md DELETED
@@ -1,45 +0,0 @@
1
- # @ricsam/quickjs-crypto
2
-
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
4
-
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
6
-
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
8
-
9
- ## Purpose
10
-
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@ricsam/quickjs-crypto`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
15
-
16
- ## What is OIDC Trusted Publishing?
17
-
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
19
-
20
- ## Setup Instructions
21
-
22
- To properly configure OIDC trusted publishing for this package:
23
-
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
28
-
29
- ## DO NOT USE THIS PACKAGE
30
-
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
36
-
37
- ## More Information
38
-
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
42
-
43
- ---
44
-
45
- **Maintained for OIDC setup purposes only**