@fgv/ts-extras 5.1.0-40 → 5.1.0-41
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/dist/packlets/crypto-utils/hpkeProvider.js +34 -12
- package/dist/packlets/crypto-utils/hpkeProvider.js.map +1 -1
- package/dist/packlets/crypto-utils/index.browser.js +1 -1
- package/dist/packlets/crypto-utils/index.browser.js.map +1 -1
- package/dist/packlets/crypto-utils/index.js +1 -1
- package/dist/packlets/crypto-utils/index.js.map +1 -1
- package/dist/packlets/crypto-utils/keystore/converters.js +3 -4
- package/dist/packlets/crypto-utils/keystore/converters.js.map +1 -1
- package/dist/packlets/crypto-utils/keystore/keyStore.js +155 -16
- package/dist/packlets/crypto-utils/keystore/keyStore.js.map +1 -1
- package/dist/packlets/crypto-utils/keystore/model.js +8 -3
- package/dist/packlets/crypto-utils/keystore/model.js.map +1 -1
- package/dist/packlets/crypto-utils/model.js.map +1 -1
- package/dist/packlets/crypto-utils/nodeCryptoProvider.js +66 -0
- package/dist/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -1
- package/dist/packlets/crypto-utils/spkiHelpers.js +31 -0
- package/dist/packlets/crypto-utils/spkiHelpers.js.map +1 -1
- package/dist/ts-extras.d.ts +289 -7
- package/lib/packlets/crypto-utils/hpkeProvider.d.ts +11 -3
- package/lib/packlets/crypto-utils/hpkeProvider.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/hpkeProvider.js +34 -12
- package/lib/packlets/crypto-utils/hpkeProvider.js.map +1 -1
- package/lib/packlets/crypto-utils/index.browser.d.ts +1 -1
- package/lib/packlets/crypto-utils/index.browser.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/index.browser.js +2 -1
- package/lib/packlets/crypto-utils/index.browser.js.map +1 -1
- package/lib/packlets/crypto-utils/index.d.ts +1 -1
- package/lib/packlets/crypto-utils/index.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/index.js +2 -1
- package/lib/packlets/crypto-utils/index.js.map +1 -1
- package/lib/packlets/crypto-utils/keystore/converters.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/keystore/converters.js +2 -3
- package/lib/packlets/crypto-utils/keystore/converters.js.map +1 -1
- package/lib/packlets/crypto-utils/keystore/keyStore.d.ts +68 -3
- package/lib/packlets/crypto-utils/keystore/keyStore.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/keystore/keyStore.js +154 -15
- package/lib/packlets/crypto-utils/keystore/keyStore.js.map +1 -1
- package/lib/packlets/crypto-utils/keystore/model.d.ts +75 -2
- package/lib/packlets/crypto-utils/keystore/model.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/keystore/model.js +9 -4
- package/lib/packlets/crypto-utils/keystore/model.js.map +1 -1
- package/lib/packlets/crypto-utils/model.d.ts +89 -0
- package/lib/packlets/crypto-utils/model.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/model.js.map +1 -1
- package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts +25 -1
- package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/nodeCryptoProvider.js +66 -0
- package/lib/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -1
- package/lib/packlets/crypto-utils/spkiHelpers.d.ts +15 -0
- package/lib/packlets/crypto-utils/spkiHelpers.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/spkiHelpers.js +32 -0
- package/lib/packlets/crypto-utils/spkiHelpers.js.map +1 -1
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hpkeProvider.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/hpkeProvider.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { Result, captureAsyncResult, captureResult, fail, succeed } from '@fgv/ts-utils';\n\n// ---- Internal constants ----\n\n// \"HPKE-v1\" (7 bytes) — RFC 9180 domain separator prefix\nconst _HPKE_VERSION: Uint8Array<ArrayBuffer> = new Uint8Array([0x48, 0x50, 0x4b, 0x45, 0x2d, 0x76, 0x31]);\n\n// suite_id = \"HPKE\" || I2OSP(KEM_ID=0x0020, 2) || I2OSP(KDF_ID=0x0001, 2) || I2OSP(AEAD_ID=0x0002, 2)\n// Used in key schedule LabeledExtract/LabeledExpand calls.\nconst _SUITE_ID: Uint8Array<ArrayBuffer> = new Uint8Array([\n 0x48, 0x50, 0x4b, 0x45, 0x00, 0x20, 0x00, 0x01, 0x00, 0x02\n]);\n\n// kem_suite_id = \"KEM\" || I2OSP(KEM_ID=0x0020, 2)\n// Used in DHKEM-internal LabeledExtract/LabeledExpand calls.\nconst _KEM_SUITE_ID: Uint8Array<ArrayBuffer> = new Uint8Array([0x4b, 0x45, 0x4d, 0x00, 0x20]);\n\nconst _N_SECRET: number = 32; // Nsecret: KEM shared-secret output length\nconst _N_PK: number = 32; // Npk: X25519 public key (raw) length — also the enc length\nconst _N_K: number = 32; // Nk: AES-256-GCM key length\nconst _N_N: number = 12; // Nn: AES-256-GCM nonce length\nconst _N_T: number = 16; // Nt: AES-256-GCM authentication tag length\nconst _MODE_BASE: number = 0x00; // RFC 9180 mode_base\n\n// ---- Internal helpers ----\n// These are NOT exported. Per design D7, only the five public operations are public surface.\n\n// Copies any Uint8Array into a fresh Uint8Array<ArrayBuffer>.\n// Required to satisfy TypeScript's strict BufferSource typing for Web Crypto API calls —\n// subtle.* rejects Uint8Array<ArrayBufferLike> but accepts Uint8Array<ArrayBuffer>.\n// Pattern follows browserCryptoProvider.ts toBufferView.\nfunction _toBufferView(arr: Uint8Array): Uint8Array<ArrayBuffer> {\n const buffer = new ArrayBuffer(arr.byteLength);\n const view = new Uint8Array(buffer);\n view.set(arr);\n return view;\n}\n\nfunction _concat(...arrays: Uint8Array[]): Uint8Array<ArrayBuffer> {\n const total = arrays.reduce((n, a) => n + a.length, 0);\n const buffer = new ArrayBuffer(total);\n const out = new Uint8Array(buffer);\n let offset = 0;\n for (const a of arrays) {\n out.set(a, offset);\n offset += a.length;\n }\n return out;\n}\n\nfunction _i2osp(value: number, length: number): Uint8Array<ArrayBuffer> {\n const buffer = new ArrayBuffer(length);\n const out = new Uint8Array(buffer);\n for (let i = length - 1; i >= 0; i--) {\n out[i] = value % 256;\n value = Math.floor(value / 256);\n }\n return out;\n}\n\n// Decodes a base64url-encoded string to Uint8Array<ArrayBuffer>.\n// Uses `atob` (global in Node 18+ and all modern browsers; no import needed).\nfunction _base64UrlDecode(s: string): Uint8Array<ArrayBuffer> {\n const base64 = s.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64 + '='.repeat((4 - (base64.length % 4)) % 4);\n const binary = atob(padded);\n const buffer = new ArrayBuffer(binary.length);\n const out = new Uint8Array(buffer);\n for (let i = 0; i < binary.length; i++) {\n out[i] = binary.charCodeAt(i);\n }\n return out;\n}\n\n// HMAC-SHA256(key, data) — the underlying primitive for HKDF.\nasync function _hmacSha256(\n subtle: SubtleCrypto,\n key: Uint8Array,\n data: Uint8Array\n): Promise<Uint8Array<ArrayBuffer>> {\n const hmacKey = await subtle.importKey(\n 'raw',\n _toBufferView(key),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign']\n );\n return new Uint8Array(await subtle.sign('HMAC', hmacKey, _toBufferView(data)));\n}\n\n// RFC 5869 HKDF-Extract(salt, IKM) = HMAC-SHA256(key=salt, msg=IKM).\n// If salt is empty (length 0), uses 32 zero bytes per RFC 5869 §2.2.\nasync function _hkdfExtract(\n subtle: SubtleCrypto,\n salt: Uint8Array,\n ikm: Uint8Array\n): Promise<Uint8Array<ArrayBuffer>> {\n const effectiveSalt = salt.length === 0 ? new Uint8Array(32) : salt;\n return _hmacSha256(subtle, effectiveSalt, ikm);\n}\n\n// RFC 5869 HKDF-Expand(PRK, info, L) — iterative HMAC expansion.\nasync function _hkdfExpand(\n subtle: SubtleCrypto,\n prk: Uint8Array,\n info: Uint8Array,\n length: number\n): Promise<Uint8Array<ArrayBuffer>> {\n if (length > 255 * 32) {\n throw new Error(`HKDF-Expand: requested length ${length} exceeds maximum 8160 bytes (255 * HashLen)`);\n }\n const n = Math.ceil(length / 32);\n const buffer = new ArrayBuffer(length);\n const okm = new Uint8Array(buffer);\n let prev: Uint8Array<ArrayBuffer> = new Uint8Array(new ArrayBuffer(0));\n let offset = 0;\n for (let i = 1; i <= n; i++) {\n prev = await _hmacSha256(subtle, prk, _concat(prev, info, new Uint8Array([i])));\n const toCopy = Math.min(32, length - offset);\n okm.set(prev.subarray(0, toCopy), offset);\n offset += toCopy;\n }\n return okm;\n}\n\n// RFC 9180 §4 LabeledExtract — HKDF-Extract with HPKE-v1 domain label.\n// labeled_ikm = \"HPKE-v1\" || suite_id || label || ikm\n// Extract(salt, labeled_ikm)\nasync function _labeledExtract(\n subtle: SubtleCrypto,\n suiteId: Uint8Array,\n salt: Uint8Array,\n label: string,\n ikm: Uint8Array\n): Promise<Uint8Array<ArrayBuffer>> {\n const labeledIkm = _concat(_HPKE_VERSION, suiteId, new TextEncoder().encode(label), ikm);\n return _hkdfExtract(subtle, salt, labeledIkm);\n}\n\n// RFC 9180 §4 LabeledExpand — HKDF-Expand with HPKE-v1 domain label.\n// labeled_info = I2OSP(L, 2) || \"HPKE-v1\" || suite_id || label || info\n// Expand(prk, labeled_info, L)\nasync function _labeledExpand(\n subtle: SubtleCrypto,\n suiteId: Uint8Array,\n prk: Uint8Array,\n label: string,\n info: Uint8Array,\n length: number\n): Promise<Uint8Array<ArrayBuffer>> {\n const labeledInfo = _concat(\n _i2osp(length, 2),\n _HPKE_VERSION,\n suiteId,\n new TextEncoder().encode(label),\n info\n );\n return _hkdfExpand(subtle, prk, labeledInfo, length);\n}\n\n// RFC 9180 §4.1 DHKEM Encap — generates ephemeral keypair, DH with recipient pubkey,\n// derives shared_secret via ExtractAndExpand.\n// NOTE: uses label \"eae_prk\" (not \"dh\") per RFC 9180 §4.1 ExtractAndExpand.\nasync function _kemEncap(\n subtle: SubtleCrypto,\n recipientPublicKey: CryptoKey\n): Promise<{ sharedSecret: Uint8Array<ArrayBuffer>; enc: Uint8Array<ArrayBuffer> }> {\n const ephemeral = (await subtle.generateKey({ name: 'X25519' }, true, ['deriveBits'])) as CryptoKeyPair;\n const enc = new Uint8Array(await subtle.exportKey('raw', ephemeral.publicKey));\n const dh = new Uint8Array(\n await subtle.deriveBits({ name: 'X25519', public: recipientPublicKey }, ephemeral.privateKey, 256)\n );\n const pkRm = new Uint8Array(await subtle.exportKey('raw', recipientPublicKey));\n const kemContext = _concat(enc, pkRm);\n const eaePrk = await _labeledExtract(subtle, _KEM_SUITE_ID, new Uint8Array(0), 'eae_prk', dh);\n const sharedSecret = await _labeledExpand(\n subtle,\n _KEM_SUITE_ID,\n eaePrk,\n 'shared_secret',\n kemContext,\n _N_SECRET\n );\n return { sharedSecret, enc };\n}\n\n// RFC 9180 §4.1 DHKEM Decap — deserializes enc, DH with recipient privkey,\n// derives same shared_secret via ExtractAndExpand.\n// Requires recipientPrivateKey to be extractable (JWK export needed for pkRm).\nasync function _kemDecap(\n subtle: SubtleCrypto,\n enc: Uint8Array,\n recipientPrivateKey: CryptoKey\n): Promise<Uint8Array<ArrayBuffer>> {\n const pkE = await subtle.importKey('raw', _toBufferView(enc), { name: 'X25519' }, true, []);\n const dh = new Uint8Array(\n await subtle.deriveBits({ name: 'X25519', public: pkE }, recipientPrivateKey, 256)\n );\n // Recover recipient's own public key from JWK x field (base64url-encoded raw X25519 public key).\n const jwk = (await subtle.exportKey('jwk', recipientPrivateKey)) as JsonWebKey;\n /* c8 ignore next 3 - defensive: X25519 JWK always has an x field; unreachable via public API */\n if (!jwk.x) {\n throw new Error('HPKE Decap: failed to extract public key bytes from recipient private key JWK');\n }\n const pkRm = _base64UrlDecode(jwk.x);\n const kemContext = _concat(enc, pkRm);\n const eaePrk = await _labeledExtract(subtle, _KEM_SUITE_ID, new Uint8Array(0), 'eae_prk', dh);\n return _labeledExpand(subtle, _KEM_SUITE_ID, eaePrk, 'shared_secret', kemContext, _N_SECRET);\n}\n\n// RFC 9180 §5 KeySchedule (base mode, psk = b\"\", psk_id = b\"\").\nasync function _keyScheduleBase(\n subtle: SubtleCrypto,\n sharedSecret: Uint8Array,\n info: Uint8Array\n): Promise<{ key: Uint8Array<ArrayBuffer>; baseNonce: Uint8Array<ArrayBuffer> }> {\n const empty = new Uint8Array(0);\n const pskIdHash = await _labeledExtract(subtle, _SUITE_ID, empty, 'psk_id_hash', empty);\n const infoHash = await _labeledExtract(subtle, _SUITE_ID, empty, 'info_hash', info);\n const ksContext = _concat(new Uint8Array([_MODE_BASE]), pskIdHash, infoHash);\n const prk = await _labeledExtract(subtle, _SUITE_ID, sharedSecret, 'secret', empty);\n const key = await _labeledExpand(subtle, _SUITE_ID, prk, 'key', ksContext, _N_K);\n const baseNonce = await _labeledExpand(subtle, _SUITE_ID, prk, 'base_nonce', ksContext, _N_N);\n return { key, baseNonce };\n}\n\n// ---- Public types ----\n\n/**\n * Output of {@link HpkeProvider.sealBase}.\n *\n * The `ciphertext` field includes the 16-byte AES-256-GCM authentication tag\n * appended by Web Crypto's `encrypt()` operation: `length = plaintext.length + 16`.\n * @public\n */\nexport interface IHpkeSealResult {\n /**\n * Encapsulated key — 32-byte raw X25519 ephemeral public key (`enc` in RFC 9180).\n * Must be transmitted to the recipient alongside `ciphertext`.\n */\n readonly enc: Uint8Array;\n\n /**\n * AES-256-GCM ciphertext with the 16-byte authentication tag appended.\n * Length = `plaintext.length + 16`.\n */\n readonly ciphertext: Uint8Array;\n}\n\n// ---- Public class ----\n\n/**\n * HPKE base mode (RFC 9180) — `DHKEM(X25519, HKDF-SHA256) + HKDF-SHA256 + AES-256-GCM`.\n *\n * Class-based provider that captures a `SubtleCrypto` instance at construction,\n * matching the existing `NodeCryptoProvider` / `BrowserCryptoProvider` / `KeyStore`\n * factory pattern used throughout `@fgv/ts-extras/crypto-utils`.\n *\n * **Node.js usage:**\n * ```typescript\n * import * as crypto from 'crypto';\n * const hpke = HpkeProvider.create(crypto.webcrypto.subtle).orThrow();\n * ```\n *\n * **Browser usage:**\n * ```typescript\n * const hpke = HpkeProvider.create(globalThis.crypto.subtle).orThrow();\n * ```\n *\n * **Runtime requirements:** Node.js 20+ (X25519 in `crypto.webcrypto`);\n * Chrome 113+, Safari 16.4+, Firefox 118+ (X25519 added to Web Crypto in 2023).\n * @public\n */\nexport class HpkeProvider {\n private readonly _subtle: SubtleCrypto;\n\n private constructor(subtle: SubtleCrypto) {\n this._subtle = subtle;\n }\n\n /**\n * Creates an `HpkeProvider` bound to the given `SubtleCrypto` instance.\n *\n * @param subtle - Web Crypto SubtleCrypto instance.\n * Node.js: `(await import('crypto')).webcrypto.subtle`.\n * Browser: `globalThis.crypto.subtle`.\n * @returns `Success` with the provider, or `Failure` if construction fails.\n */\n public static create(subtle: SubtleCrypto): Result<HpkeProvider> {\n return captureResult(() => new HpkeProvider(subtle));\n }\n\n /**\n * HPKE base-mode seal (sender side). RFC 9180 §6.1.\n *\n * Generates a fresh ephemeral X25519 keypair, runs DHKEM Encap to produce a\n * shared secret and `enc` (32-byte raw ephemeral public key), derives the AEAD\n * key and nonce deterministically via the RFC 9180 key schedule, then encrypts\n * `plaintext` with AES-256-GCM.\n *\n * @param recipientPublicKey - Recipient's X25519 public `CryptoKey`\n * (`algorithm.name === 'X25519'`, `type === 'public'`, **`extractable: true`**).\n * Must be extractable — DHKEM Encap calls `exportKey('raw', ...)` on this key to\n * build the KEM shared-secret context. Keys imported with `extractable: false` will\n * cause this method to return a `Failure`.\n * @param info - Context-binding bytes. **Load-bearing — no default.**\n * Binds this ciphertext to a specific application context, preventing replay\n * across different contexts sharing the same recipient keypair.\n * Use `new TextEncoder().encode('myapp/v1/use-case\\x00' + contextId)` pattern.\n * Never pass an empty array in production: empty `info` provides no context binding.\n * @param aad - Additional authenticated data. Integrity-protected but not encrypted.\n * `new Uint8Array(0)` is valid when no AAD is needed.\n * @param plaintext - Bytes to encrypt. `new Uint8Array(0)` is valid.\n * @returns `Success` with `{ enc, ciphertext }`, or `Failure` with error context.\n */\n public async sealBase(\n recipientPublicKey: CryptoKey,\n info: Uint8Array,\n aad: Uint8Array,\n plaintext: Uint8Array\n ): Promise<Result<IHpkeSealResult>> {\n const result = await captureAsyncResult(async () => {\n const { sharedSecret, enc } = await _kemEncap(this._subtle, recipientPublicKey);\n const { key, baseNonce } = await _keyScheduleBase(this._subtle, sharedSecret, info);\n const aesKey = await this._subtle.importKey('raw', key, { name: 'AES-GCM' }, false, ['encrypt']);\n const ct = await this._subtle.encrypt(\n { name: 'AES-GCM', iv: baseNonce, additionalData: _toBufferView(aad) },\n aesKey,\n _toBufferView(plaintext)\n );\n return { enc, ciphertext: new Uint8Array(ct) };\n });\n return result.withErrorFormat((e: string) => `HPKE sealBase failed: ${e}`);\n }\n\n /**\n * HPKE base-mode open (recipient side). RFC 9180 §6.1.\n *\n * Decapsulates `enc` using the recipient's X25519 private key, derives the same\n * AEAD key and nonce from the shared secret and `info`, then authenticates and\n * decrypts `ciphertext` with AES-256-GCM.\n *\n * Returns `Failure` on any of:\n * - Wrong private key (different DH output → different key derivation)\n * - Wrong `info` (different key schedule context → different AEAD key)\n * - Wrong `aad` (AES-GCM authentication fails)\n * - Tampered `ciphertext` or `enc` (authentication fails or DH fails)\n * - `enc` not exactly 32 bytes\n * - `ciphertext` shorter than 16 bytes (no room for authentication tag)\n *\n * @param recipientPrivateKey - Recipient's X25519 private `CryptoKey`\n * (`algorithm.name === 'X25519'`, `type === 'private'`, `usages` includes `'deriveBits'`).\n * **Must be extractable** (`extractable: true`) — the recipient's public key bytes\n * are recovered from the JWK `x` field during Decap.\n * @param info - Context-binding bytes. Must exactly match `info` from `sealBase`.\n * @param aad - Must exactly match `aad` from `sealBase`.\n * @param enc - The encapsulated key from `sealBase` — exactly 32 bytes.\n * @param ciphertext - The ciphertext from `sealBase` — `plaintext.length + 16` bytes.\n * @returns `Success` with decrypted plaintext bytes, or `Failure` with error context.\n */\n public async openBase(\n recipientPrivateKey: CryptoKey,\n info: Uint8Array,\n aad: Uint8Array,\n enc: Uint8Array,\n ciphertext: Uint8Array\n ): Promise<Result<Uint8Array>> {\n if (enc.length !== _N_PK) {\n return fail(`HPKE openBase: enc must be ${_N_PK} bytes, got ${enc.length}`);\n }\n if (ciphertext.length < _N_T) {\n return fail(\n `HPKE openBase: ciphertext too short (minimum ${_N_T} bytes for auth tag, got ${ciphertext.length})`\n );\n }\n const result = await captureAsyncResult(async () => {\n const sharedSecret = await _kemDecap(this._subtle, enc, recipientPrivateKey);\n const { key, baseNonce } = await _keyScheduleBase(this._subtle, sharedSecret, info);\n const aesKey = await this._subtle.importKey('raw', key, { name: 'AES-GCM' }, false, ['decrypt']);\n const pt = await this._subtle.decrypt(\n { name: 'AES-GCM', iv: baseNonce, additionalData: _toBufferView(aad) },\n aesKey,\n _toBufferView(ciphertext)\n );\n return new Uint8Array(pt);\n });\n return result.withErrorFormat((e: string) => `HPKE openBase failed: ${e}`);\n }\n\n /**\n * HKDF-SHA256 key derivation (RFC 5869). Extract-then-Expand using SHA-256.\n *\n * This is raw RFC 5869 HKDF — it does **not** use RFC 9180's labeled variants.\n * The HPKE key schedule internally uses labeled HKDF; this method is the unlabeled\n * version for callers that need standalone key derivation.\n *\n * @param secret - Input keying material (IKM). Any length.\n * @param salt - Optional salt. Use `new Uint8Array(0)` if no salt is available\n * (RFC 5869: 32 zero bytes are used internally when salt is empty).\n * @param info - Context / application-binding bytes. Any length.\n * @param length - Number of output bytes to derive. Maximum 8160 bytes (255 × 32).\n * @returns `Success` with derived bytes, or `Failure` with error context.\n */\n public async hkdf(\n secret: Uint8Array,\n salt: Uint8Array,\n info: Uint8Array,\n length: number\n ): Promise<Result<Uint8Array>> {\n const result = await captureAsyncResult(async () => {\n const prk = await _hkdfExtract(this._subtle, salt, secret);\n return _hkdfExpand(this._subtle, prk, info, length);\n });\n return result.withErrorFormat((e: string) => `HKDF failed: ${e}`);\n }\n\n /**\n * Encodes an {@link IHpkeSealResult} as a single contiguous byte array for wire transport.\n *\n * Format: `enc` (32 bytes, fixed) || `ciphertext` (variable length).\n * The 32-byte `enc` length is fixed for X25519; the split point is unambiguous.\n *\n * @param result - The output of {@link HpkeProvider.sealBase}.\n * @returns Concatenated bytes: `enc || ciphertext`.\n */\n public static encodeEnvelope(result: IHpkeSealResult): Uint8Array {\n return _concat(result.enc, result.ciphertext);\n }\n\n /**\n * Decodes an envelope produced by {@link HpkeProvider.encodeEnvelope}.\n *\n * Validates that the buffer is at least 48 bytes (32-byte enc + 16-byte minimum\n * ciphertext containing the AES-GCM auth tag; zero-length plaintext is the minimum\n * meaningful case).\n *\n * @param envelope - Envelope bytes from `encodeEnvelope`.\n * @returns `Success` with `{ enc, ciphertext }`, or `Failure` if malformed.\n */\n public static decodeEnvelope(envelope: Uint8Array): Result<IHpkeSealResult> {\n const minLen = _N_PK + _N_T;\n if (envelope.length < minLen) {\n return fail(\n `HPKE decodeEnvelope: envelope too short (minimum ${minLen} bytes, got ${envelope.length})`\n );\n }\n return succeed({\n enc: envelope.slice(0, _N_PK),\n ciphertext: envelope.slice(_N_PK)\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"hpkeProvider.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/hpkeProvider.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { Result, captureAsyncResult, captureResult, fail, succeed } from '@fgv/ts-utils';\n\n// ---- Internal constants ----\n\n// \"HPKE-v1\" (7 bytes) — RFC 9180 domain separator prefix\nconst _HPKE_VERSION: Uint8Array<ArrayBuffer> = new Uint8Array([0x48, 0x50, 0x4b, 0x45, 0x2d, 0x76, 0x31]);\n\n// suite_id = \"HPKE\" || I2OSP(KEM_ID=0x0020, 2) || I2OSP(KDF_ID=0x0001, 2) || I2OSP(AEAD_ID=0x0002, 2)\n// Used in key schedule LabeledExtract/LabeledExpand calls.\nconst _SUITE_ID: Uint8Array<ArrayBuffer> = new Uint8Array([\n 0x48, 0x50, 0x4b, 0x45, 0x00, 0x20, 0x00, 0x01, 0x00, 0x02\n]);\n\n// kem_suite_id = \"KEM\" || I2OSP(KEM_ID=0x0020, 2)\n// Used in DHKEM-internal LabeledExtract/LabeledExpand calls.\nconst _KEM_SUITE_ID: Uint8Array<ArrayBuffer> = new Uint8Array([0x4b, 0x45, 0x4d, 0x00, 0x20]);\n\nconst _N_SECRET: number = 32; // Nsecret: KEM shared-secret output length\nconst _N_PK: number = 32; // Npk: X25519 public key (raw) length — also the enc length\nconst _N_K: number = 32; // Nk: AES-256-GCM key length\nconst _N_N: number = 12; // Nn: AES-256-GCM nonce length\nconst _N_T: number = 16; // Nt: AES-256-GCM authentication tag length\nconst _MODE_BASE: number = 0x00; // RFC 9180 mode_base\n\n// ---- Internal helpers ----\n// These are NOT exported. Per design D7, only the five public operations are public surface.\n\n// Copies any Uint8Array into a fresh Uint8Array<ArrayBuffer>.\n// Required to satisfy TypeScript's strict BufferSource typing for Web Crypto API calls —\n// subtle.* rejects Uint8Array<ArrayBufferLike> but accepts Uint8Array<ArrayBuffer>.\n// Pattern follows browserCryptoProvider.ts toBufferView.\nfunction _toBufferView(arr: Uint8Array): Uint8Array<ArrayBuffer> {\n const buffer = new ArrayBuffer(arr.byteLength);\n const view = new Uint8Array(buffer);\n view.set(arr);\n return view;\n}\n\nfunction _concat(...arrays: Uint8Array[]): Uint8Array<ArrayBuffer> {\n const total = arrays.reduce((n, a) => n + a.length, 0);\n const buffer = new ArrayBuffer(total);\n const out = new Uint8Array(buffer);\n let offset = 0;\n for (const a of arrays) {\n out.set(a, offset);\n offset += a.length;\n }\n return out;\n}\n\nfunction _i2osp(value: number, length: number): Uint8Array<ArrayBuffer> {\n const buffer = new ArrayBuffer(length);\n const out = new Uint8Array(buffer);\n for (let i = length - 1; i >= 0; i--) {\n out[i] = value % 256;\n value = Math.floor(value / 256);\n }\n return out;\n}\n\n// Decodes a base64url-encoded string to Uint8Array<ArrayBuffer>.\n// Uses `atob` (global in Node 18+ and all modern browsers; no import needed).\nfunction _base64UrlDecode(s: string): Uint8Array<ArrayBuffer> {\n const base64 = s.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64 + '='.repeat((4 - (base64.length % 4)) % 4);\n const binary = atob(padded);\n const buffer = new ArrayBuffer(binary.length);\n const out = new Uint8Array(buffer);\n for (let i = 0; i < binary.length; i++) {\n out[i] = binary.charCodeAt(i);\n }\n return out;\n}\n\n// HMAC-SHA256(key, data) — the underlying primitive for HKDF.\nasync function _hmacSha256(\n subtle: SubtleCrypto,\n key: Uint8Array,\n data: Uint8Array\n): Promise<Uint8Array<ArrayBuffer>> {\n const hmacKey = await subtle.importKey(\n 'raw',\n _toBufferView(key),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign']\n );\n return new Uint8Array(await subtle.sign('HMAC', hmacKey, _toBufferView(data)));\n}\n\n// RFC 5869 HKDF-Extract(salt, IKM) = HMAC-SHA256(key=salt, msg=IKM).\n// If salt is empty (length 0), uses 32 zero bytes per RFC 5869 §2.2.\nasync function _hkdfExtract(\n subtle: SubtleCrypto,\n salt: Uint8Array,\n ikm: Uint8Array\n): Promise<Uint8Array<ArrayBuffer>> {\n const effectiveSalt = salt.length === 0 ? new Uint8Array(32) : salt;\n return _hmacSha256(subtle, effectiveSalt, ikm);\n}\n\n// RFC 5869 HKDF-Expand(PRK, info, L) — iterative HMAC expansion.\nasync function _hkdfExpand(\n subtle: SubtleCrypto,\n prk: Uint8Array,\n info: Uint8Array,\n length: number\n): Promise<Uint8Array<ArrayBuffer>> {\n if (length > 255 * 32) {\n throw new Error(`HKDF-Expand: requested length ${length} exceeds maximum 8160 bytes (255 * HashLen)`);\n }\n const n = Math.ceil(length / 32);\n const buffer = new ArrayBuffer(length);\n const okm = new Uint8Array(buffer);\n let prev: Uint8Array<ArrayBuffer> = new Uint8Array(new ArrayBuffer(0));\n let offset = 0;\n for (let i = 1; i <= n; i++) {\n prev = await _hmacSha256(subtle, prk, _concat(prev, info, new Uint8Array([i])));\n const toCopy = Math.min(32, length - offset);\n okm.set(prev.subarray(0, toCopy), offset);\n offset += toCopy;\n }\n return okm;\n}\n\n// RFC 9180 §4 LabeledExtract — HKDF-Extract with HPKE-v1 domain label.\n// labeled_ikm = \"HPKE-v1\" || suite_id || label || ikm\n// Extract(salt, labeled_ikm)\nasync function _labeledExtract(\n subtle: SubtleCrypto,\n suiteId: Uint8Array,\n salt: Uint8Array,\n label: string,\n ikm: Uint8Array\n): Promise<Uint8Array<ArrayBuffer>> {\n const labeledIkm = _concat(_HPKE_VERSION, suiteId, new TextEncoder().encode(label), ikm);\n return _hkdfExtract(subtle, salt, labeledIkm);\n}\n\n// RFC 9180 §4 LabeledExpand — HKDF-Expand with HPKE-v1 domain label.\n// labeled_info = I2OSP(L, 2) || \"HPKE-v1\" || suite_id || label || info\n// Expand(prk, labeled_info, L)\nasync function _labeledExpand(\n subtle: SubtleCrypto,\n suiteId: Uint8Array,\n prk: Uint8Array,\n label: string,\n info: Uint8Array,\n length: number\n): Promise<Uint8Array<ArrayBuffer>> {\n const labeledInfo = _concat(\n _i2osp(length, 2),\n _HPKE_VERSION,\n suiteId,\n new TextEncoder().encode(label),\n info\n );\n return _hkdfExpand(subtle, prk, labeledInfo, length);\n}\n\n// RFC 9180 §4.1 DHKEM Encap — generates ephemeral keypair, DH with recipient pubkey,\n// derives shared_secret via ExtractAndExpand.\n// NOTE: uses label \"eae_prk\" (not \"dh\") per RFC 9180 §4.1 ExtractAndExpand.\nasync function _kemEncap(\n subtle: SubtleCrypto,\n recipientPublicKey: CryptoKey\n): Promise<{ sharedSecret: Uint8Array<ArrayBuffer>; enc: Uint8Array<ArrayBuffer> }> {\n const ephemeral = (await subtle.generateKey({ name: 'X25519' }, true, ['deriveBits'])) as CryptoKeyPair;\n const enc = new Uint8Array(await subtle.exportKey('raw', ephemeral.publicKey));\n const dh = new Uint8Array(\n await subtle.deriveBits({ name: 'X25519', public: recipientPublicKey }, ephemeral.privateKey, 256)\n );\n const pkRm = new Uint8Array(await subtle.exportKey('raw', recipientPublicKey));\n const kemContext = _concat(enc, pkRm);\n const eaePrk = await _labeledExtract(subtle, _KEM_SUITE_ID, new Uint8Array(0), 'eae_prk', dh);\n const sharedSecret = await _labeledExpand(\n subtle,\n _KEM_SUITE_ID,\n eaePrk,\n 'shared_secret',\n kemContext,\n _N_SECRET\n );\n return { sharedSecret, enc };\n}\n\n// RFC 9180 §4.1 DHKEM Decap — deserializes enc, DH with recipient privkey,\n// derives same shared_secret via ExtractAndExpand.\n// The DH step (deriveBits) works on a non-extractable recipientPrivateKey. Recovering the\n// recipient's own public key bytes (pkRm) for kem_context normally requires a JWK export, which\n// in turn requires recipientPrivateKey to be extractable — UNLESS the caller supplies pkRm\n// directly (raw 32-byte X25519 public key), in which case no JWK export happens and\n// recipientPrivateKey may be non-extractable.\nasync function _kemDecap(\n subtle: SubtleCrypto,\n enc: Uint8Array,\n recipientPrivateKey: CryptoKey,\n recipientPublicKey?: Uint8Array\n): Promise<Uint8Array<ArrayBuffer>> {\n const pkE = await subtle.importKey('raw', _toBufferView(enc), { name: 'X25519' }, true, []);\n const dh = new Uint8Array(\n await subtle.deriveBits({ name: 'X25519', public: pkE }, recipientPrivateKey, 256)\n );\n let pkRm: Uint8Array;\n if (recipientPublicKey !== undefined) {\n // Caller-supplied; length already validated in openBase.\n pkRm = recipientPublicKey;\n } else {\n // Recover recipient's own public key from JWK x field (base64url-encoded raw X25519 public key).\n const jwk = (await subtle.exportKey('jwk', recipientPrivateKey)) as JsonWebKey;\n /* c8 ignore next 3 - defensive: X25519 JWK always has an x field; unreachable via public API */\n if (!jwk.x) {\n throw new Error('HPKE Decap: failed to extract public key bytes from recipient private key JWK');\n }\n pkRm = _base64UrlDecode(jwk.x);\n }\n const kemContext = _concat(enc, pkRm);\n const eaePrk = await _labeledExtract(subtle, _KEM_SUITE_ID, new Uint8Array(0), 'eae_prk', dh);\n return _labeledExpand(subtle, _KEM_SUITE_ID, eaePrk, 'shared_secret', kemContext, _N_SECRET);\n}\n\n// RFC 9180 §5 KeySchedule (base mode, psk = b\"\", psk_id = b\"\").\nasync function _keyScheduleBase(\n subtle: SubtleCrypto,\n sharedSecret: Uint8Array,\n info: Uint8Array\n): Promise<{ key: Uint8Array<ArrayBuffer>; baseNonce: Uint8Array<ArrayBuffer> }> {\n const empty = new Uint8Array(0);\n const pskIdHash = await _labeledExtract(subtle, _SUITE_ID, empty, 'psk_id_hash', empty);\n const infoHash = await _labeledExtract(subtle, _SUITE_ID, empty, 'info_hash', info);\n const ksContext = _concat(new Uint8Array([_MODE_BASE]), pskIdHash, infoHash);\n const prk = await _labeledExtract(subtle, _SUITE_ID, sharedSecret, 'secret', empty);\n const key = await _labeledExpand(subtle, _SUITE_ID, prk, 'key', ksContext, _N_K);\n const baseNonce = await _labeledExpand(subtle, _SUITE_ID, prk, 'base_nonce', ksContext, _N_N);\n return { key, baseNonce };\n}\n\n// ---- Public types ----\n\n/**\n * Output of {@link HpkeProvider.sealBase}.\n *\n * The `ciphertext` field includes the 16-byte AES-256-GCM authentication tag\n * appended by Web Crypto's `encrypt()` operation: `length = plaintext.length + 16`.\n * @public\n */\nexport interface IHpkeSealResult {\n /**\n * Encapsulated key — 32-byte raw X25519 ephemeral public key (`enc` in RFC 9180).\n * Must be transmitted to the recipient alongside `ciphertext`.\n */\n readonly enc: Uint8Array;\n\n /**\n * AES-256-GCM ciphertext with the 16-byte authentication tag appended.\n * Length = `plaintext.length + 16`.\n */\n readonly ciphertext: Uint8Array;\n}\n\n// ---- Public class ----\n\n/**\n * HPKE base mode (RFC 9180) — `DHKEM(X25519, HKDF-SHA256) + HKDF-SHA256 + AES-256-GCM`.\n *\n * Class-based provider that captures a `SubtleCrypto` instance at construction,\n * matching the existing `NodeCryptoProvider` / `BrowserCryptoProvider` / `KeyStore`\n * factory pattern used throughout `@fgv/ts-extras/crypto-utils`.\n *\n * **Node.js usage:**\n * ```typescript\n * import * as crypto from 'crypto';\n * const hpke = HpkeProvider.create(crypto.webcrypto.subtle).orThrow();\n * ```\n *\n * **Browser usage:**\n * ```typescript\n * const hpke = HpkeProvider.create(globalThis.crypto.subtle).orThrow();\n * ```\n *\n * **Runtime requirements:** Node.js 20+ (X25519 in `crypto.webcrypto`);\n * Chrome 113+, Safari 16.4+, Firefox 118+ (X25519 added to Web Crypto in 2023).\n * @public\n */\nexport class HpkeProvider {\n private readonly _subtle: SubtleCrypto;\n\n private constructor(subtle: SubtleCrypto) {\n this._subtle = subtle;\n }\n\n /**\n * Creates an `HpkeProvider` bound to the given `SubtleCrypto` instance.\n *\n * @param subtle - Web Crypto SubtleCrypto instance.\n * Node.js: `(await import('crypto')).webcrypto.subtle`.\n * Browser: `globalThis.crypto.subtle`.\n * @returns `Success` with the provider, or `Failure` if construction fails.\n */\n public static create(subtle: SubtleCrypto): Result<HpkeProvider> {\n return captureResult(() => new HpkeProvider(subtle));\n }\n\n /**\n * HPKE base-mode seal (sender side). RFC 9180 §6.1.\n *\n * Generates a fresh ephemeral X25519 keypair, runs DHKEM Encap to produce a\n * shared secret and `enc` (32-byte raw ephemeral public key), derives the AEAD\n * key and nonce deterministically via the RFC 9180 key schedule, then encrypts\n * `plaintext` with AES-256-GCM.\n *\n * @param recipientPublicKey - Recipient's X25519 public `CryptoKey`\n * (`algorithm.name === 'X25519'`, `type === 'public'`, **`extractable: true`**).\n * Must be extractable — DHKEM Encap calls `exportKey('raw', ...)` on this key to\n * build the KEM shared-secret context. Keys imported with `extractable: false` will\n * cause this method to return a `Failure`.\n * @param info - Context-binding bytes. **Load-bearing — no default.**\n * Binds this ciphertext to a specific application context, preventing replay\n * across different contexts sharing the same recipient keypair.\n * Use `new TextEncoder().encode('myapp/v1/use-case\\x00' + contextId)` pattern.\n * Never pass an empty array in production: empty `info` provides no context binding.\n * @param aad - Additional authenticated data. Integrity-protected but not encrypted.\n * `new Uint8Array(0)` is valid when no AAD is needed.\n * @param plaintext - Bytes to encrypt. `new Uint8Array(0)` is valid.\n * @returns `Success` with `{ enc, ciphertext }`, or `Failure` with error context.\n */\n public async sealBase(\n recipientPublicKey: CryptoKey,\n info: Uint8Array,\n aad: Uint8Array,\n plaintext: Uint8Array\n ): Promise<Result<IHpkeSealResult>> {\n const result = await captureAsyncResult(async () => {\n const { sharedSecret, enc } = await _kemEncap(this._subtle, recipientPublicKey);\n const { key, baseNonce } = await _keyScheduleBase(this._subtle, sharedSecret, info);\n const aesKey = await this._subtle.importKey('raw', key, { name: 'AES-GCM' }, false, ['encrypt']);\n const ct = await this._subtle.encrypt(\n { name: 'AES-GCM', iv: baseNonce, additionalData: _toBufferView(aad) },\n aesKey,\n _toBufferView(plaintext)\n );\n return { enc, ciphertext: new Uint8Array(ct) };\n });\n return result.withErrorFormat((e: string) => `HPKE sealBase failed: ${e}`);\n }\n\n /**\n * HPKE base-mode open (recipient side). RFC 9180 §6.1.\n *\n * Decapsulates `enc` using the recipient's X25519 private key, derives the same\n * AEAD key and nonce from the shared secret and `info`, then authenticates and\n * decrypts `ciphertext` with AES-256-GCM.\n *\n * Returns `Failure` on any of:\n * - Wrong private key (different DH output → different key derivation)\n * - Wrong `info` (different key schedule context → different AEAD key)\n * - Wrong `aad` (AES-GCM authentication fails)\n * - Tampered `ciphertext` or `enc` (authentication fails or DH fails)\n * - `enc` not exactly 32 bytes\n * - `ciphertext` shorter than 16 bytes (no room for authentication tag)\n *\n * @param recipientPrivateKey - Recipient's X25519 private `CryptoKey`\n * (`algorithm.name === 'X25519'`, `type === 'private'`, `usages` includes `'deriveBits'`).\n * **Must be extractable** (`extractable: true`) only when `recipientPublicKey` is not\n * supplied — the recipient's public key bytes are then recovered from the JWK `x` field\n * during Decap. When `recipientPublicKey` is supplied, `recipientPrivateKey` may be\n * non-extractable.\n * @param info - Context-binding bytes. Must exactly match `info` from `sealBase`.\n * @param aad - Must exactly match `aad` from `sealBase`.\n * @param enc - The encapsulated key from `sealBase` — exactly 32 bytes.\n * @param ciphertext - The ciphertext from `sealBase` — `plaintext.length + 16` bytes.\n * @param recipientPublicKey - Optional raw 32-byte X25519 public key matching\n * `recipientPrivateKey` (`pkRm` in RFC 9180 §4.1). Public material — supplying it lets\n * Decap build `kem_context` without exporting `recipientPrivateKey` to JWK, so\n * `recipientPrivateKey` no longer needs to be extractable. A mismatched value only breaks\n * the caller's own decryption (AEAD authentication fails) — it cannot be used to attack\n * another party's ciphertext.\n * @returns `Success` with decrypted plaintext bytes, or `Failure` with error context.\n */\n public async openBase(\n recipientPrivateKey: CryptoKey,\n info: Uint8Array,\n aad: Uint8Array,\n enc: Uint8Array,\n ciphertext: Uint8Array,\n recipientPublicKey?: Uint8Array\n ): Promise<Result<Uint8Array>> {\n if (enc.length !== _N_PK) {\n return fail(`HPKE openBase: enc must be ${_N_PK} bytes, got ${enc.length}`);\n }\n if (ciphertext.length < _N_T) {\n return fail(\n `HPKE openBase: ciphertext too short (minimum ${_N_T} bytes for auth tag, got ${ciphertext.length})`\n );\n }\n if (recipientPublicKey !== undefined && recipientPublicKey.length !== _N_PK) {\n return fail(\n `HPKE openBase: recipientPublicKey must be ${_N_PK} bytes, got ${recipientPublicKey.length}`\n );\n }\n const result = await captureAsyncResult(async () => {\n const sharedSecret = await _kemDecap(this._subtle, enc, recipientPrivateKey, recipientPublicKey);\n const { key, baseNonce } = await _keyScheduleBase(this._subtle, sharedSecret, info);\n const aesKey = await this._subtle.importKey('raw', key, { name: 'AES-GCM' }, false, ['decrypt']);\n const pt = await this._subtle.decrypt(\n { name: 'AES-GCM', iv: baseNonce, additionalData: _toBufferView(aad) },\n aesKey,\n _toBufferView(ciphertext)\n );\n return new Uint8Array(pt);\n });\n return result.withErrorFormat((e: string) => `HPKE openBase failed: ${e}`);\n }\n\n /**\n * HKDF-SHA256 key derivation (RFC 5869). Extract-then-Expand using SHA-256.\n *\n * This is raw RFC 5869 HKDF — it does **not** use RFC 9180's labeled variants.\n * The HPKE key schedule internally uses labeled HKDF; this method is the unlabeled\n * version for callers that need standalone key derivation.\n *\n * @param secret - Input keying material (IKM). Any length.\n * @param salt - Optional salt. Use `new Uint8Array(0)` if no salt is available\n * (RFC 5869: 32 zero bytes are used internally when salt is empty).\n * @param info - Context / application-binding bytes. Any length.\n * @param length - Number of output bytes to derive. Maximum 8160 bytes (255 × 32).\n * @returns `Success` with derived bytes, or `Failure` with error context.\n */\n public async hkdf(\n secret: Uint8Array,\n salt: Uint8Array,\n info: Uint8Array,\n length: number\n ): Promise<Result<Uint8Array>> {\n const result = await captureAsyncResult(async () => {\n const prk = await _hkdfExtract(this._subtle, salt, secret);\n return _hkdfExpand(this._subtle, prk, info, length);\n });\n return result.withErrorFormat((e: string) => `HKDF failed: ${e}`);\n }\n\n /**\n * Encodes an {@link IHpkeSealResult} as a single contiguous byte array for wire transport.\n *\n * Format: `enc` (32 bytes, fixed) || `ciphertext` (variable length).\n * The 32-byte `enc` length is fixed for X25519; the split point is unambiguous.\n *\n * @param result - The output of {@link HpkeProvider.sealBase}.\n * @returns Concatenated bytes: `enc || ciphertext`.\n */\n public static encodeEnvelope(result: IHpkeSealResult): Uint8Array {\n return _concat(result.enc, result.ciphertext);\n }\n\n /**\n * Decodes an envelope produced by {@link HpkeProvider.encodeEnvelope}.\n *\n * Validates that the buffer is at least 48 bytes (32-byte enc + 16-byte minimum\n * ciphertext containing the AES-GCM auth tag; zero-length plaintext is the minimum\n * meaningful case).\n *\n * @param envelope - Envelope bytes from `encodeEnvelope`.\n * @returns `Success` with `{ enc, ciphertext }`, or `Failure` if malformed.\n */\n public static decodeEnvelope(envelope: Uint8Array): Result<IHpkeSealResult> {\n const minLen = _N_PK + _N_T;\n if (envelope.length < minLen) {\n return fail(\n `HPKE decodeEnvelope: envelope too short (minimum ${minLen} bytes, got ${envelope.length})`\n );\n }\n return succeed({\n enc: envelope.slice(0, _N_PK),\n ciphertext: envelope.slice(_N_PK)\n });\n }\n}\n"]}
|
|
@@ -12,6 +12,6 @@ export { Converters };
|
|
|
12
12
|
export { DirectEncryptionProvider, IDirectEncryptionProviderParams } from './directEncryptionProvider';
|
|
13
13
|
export { IKeyPairAlgorithmParams, keyPairAlgorithmParams } from './keyPairAlgorithmParams';
|
|
14
14
|
export { createEncryptedFile, decryptFile, fromBase64, ICreateEncryptedFileParams, toBase64, tryDecryptFile } from './encryptedFile';
|
|
15
|
-
export { base64UrlNoPadDecode, base64UrlNoPadEncode, exportPublicKeyAsMultibaseSpki, importPublicKeyFromMultibaseSpki, isValidMultibaseSpkiPublicKey, MultibaseSpkiPublicKeyRegExp, multibaseBase64UrlDecode, multibaseBase64UrlEncode } from './spkiHelpers';
|
|
15
|
+
export { base64UrlNoPadDecode, base64UrlNoPadEncode, exportPublicKeyAsMultibaseSpki, importPublicKeyFromMultibaseSpki, isValidMultibaseSpkiPublicKey, MultibaseSpkiPublicKeyRegExp, multibaseBase64UrlDecode, multibaseBase64UrlEncode, spkiToRawX25519 } from './spkiHelpers';
|
|
16
16
|
export { HpkeProvider, IHpkeSealResult } from './hpkeProvider';
|
|
17
17
|
//# sourceMappingURL=index.browser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.browser.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,WAAW,EACZ,MAAM,aAAa,CAAC;AAIrB,OAAO,KAAK,QAAQ,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,CAAC;AAGpB,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,CAAC;AAGtB,OAAO,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AAGvG,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAM3F,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,UAAU,EACV,0BAA0B,EAC1B,QAAQ,EACR,cAAc,EACf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,8BAA8B,EAC9B,gCAAgC,EAChC,6BAA6B,EAC7B,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,
|
|
1
|
+
{"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.browser.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,WAAW,EACZ,MAAM,aAAa,CAAC;AAIrB,OAAO,KAAK,QAAQ,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,CAAC;AAGpB,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,CAAC;AAGtB,OAAO,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AAGvG,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAM3F,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,UAAU,EACV,0BAA0B,EAC1B,QAAQ,EACR,cAAc,EACf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,8BAA8B,EAC9B,gCAAgC,EAChC,6BAA6B,EAC7B,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,EAChB,MAAM,eAAe,CAAC;AAIvB,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -55,7 +55,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
55
55
|
};
|
|
56
56
|
})();
|
|
57
57
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
58
|
-
exports.HpkeProvider = exports.multibaseBase64UrlEncode = exports.multibaseBase64UrlDecode = exports.MultibaseSpkiPublicKeyRegExp = exports.isValidMultibaseSpkiPublicKey = exports.importPublicKeyFromMultibaseSpki = exports.exportPublicKeyAsMultibaseSpki = exports.base64UrlNoPadEncode = exports.base64UrlNoPadDecode = exports.tryDecryptFile = exports.toBase64 = exports.fromBase64 = exports.decryptFile = exports.createEncryptedFile = exports.keyPairAlgorithmParams = exports.DirectEncryptionProvider = exports.Converters = exports.KeyStore = exports.GCM_IV_SIZE = exports.GCM_AUTH_TAG_SIZE = exports.ENCRYPTED_FILE_FORMAT = exports.DEFAULT_ALGORITHM = exports.AES_256_KEY_SIZE = void 0;
|
|
58
|
+
exports.HpkeProvider = exports.spkiToRawX25519 = exports.multibaseBase64UrlEncode = exports.multibaseBase64UrlDecode = exports.MultibaseSpkiPublicKeyRegExp = exports.isValidMultibaseSpkiPublicKey = exports.importPublicKeyFromMultibaseSpki = exports.exportPublicKeyAsMultibaseSpki = exports.base64UrlNoPadEncode = exports.base64UrlNoPadDecode = exports.tryDecryptFile = exports.toBase64 = exports.fromBase64 = exports.decryptFile = exports.createEncryptedFile = exports.keyPairAlgorithmParams = exports.DirectEncryptionProvider = exports.Converters = exports.KeyStore = exports.GCM_IV_SIZE = exports.GCM_AUTH_TAG_SIZE = exports.ENCRYPTED_FILE_FORMAT = exports.DEFAULT_ALGORITHM = exports.AES_256_KEY_SIZE = void 0;
|
|
59
59
|
/**
|
|
60
60
|
* Crypto utilities for encrypted file handling and key management (browser version).
|
|
61
61
|
* Note: For browser crypto provider, use \@fgv/ts-web-extras.
|
|
@@ -102,6 +102,7 @@ Object.defineProperty(exports, "isValidMultibaseSpkiPublicKey", { enumerable: tr
|
|
|
102
102
|
Object.defineProperty(exports, "MultibaseSpkiPublicKeyRegExp", { enumerable: true, get: function () { return spkiHelpers_1.MultibaseSpkiPublicKeyRegExp; } });
|
|
103
103
|
Object.defineProperty(exports, "multibaseBase64UrlDecode", { enumerable: true, get: function () { return spkiHelpers_1.multibaseBase64UrlDecode; } });
|
|
104
104
|
Object.defineProperty(exports, "multibaseBase64UrlEncode", { enumerable: true, get: function () { return spkiHelpers_1.multibaseBase64UrlEncode; } });
|
|
105
|
+
Object.defineProperty(exports, "spkiToRawX25519", { enumerable: true, get: function () { return spkiHelpers_1.spkiToRawX25519; } });
|
|
105
106
|
// HPKE base mode (RFC 9180) — DHKEM(X25519, HKDF-SHA256) + HKDF-SHA256 + AES-256-GCM
|
|
106
107
|
// hpkeProvider.ts has no Node-specific imports and is safe in the browser entry point.
|
|
107
108
|
var hpkeProvider_1 = require("./hpkeProvider");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.browser.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.browser.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEZ;;;;GAIG;AAEH,iCAAiC;AACjC,0CAAwB;AAExB,YAAY;AACZ,yCAMqB;AALnB,6GAAA,gBAAgB,OAAA;AAChB,8GAAA,iBAAiB,OAAA;AACjB,kHAAA,qBAAqB,OAAA;AACrB,8GAAA,iBAAiB,OAAA;AACjB,wGAAA,WAAW,OAAA;AAGb,gEAAgE;AAChE,iFAAiF;AACjF,mEAAqD;AAC5C,4BAAQ;AAEjB,uBAAuB;AACvB,yDAA2C;AAClC,gCAAU;AAEnB,6BAA6B;AAC7B,uEAAuG;AAA9F,oIAAA,wBAAwB,OAAA;AAEjC,8DAA8D;AAC9D,mEAA2F;AAAzD,gIAAA,sBAAsB,OAAA;AAExD,8DAA8D;AAC9D,4DAA4D;AAE5D,yBAAyB;AACzB,iDAOyB;AANvB,oHAAA,mBAAmB,OAAA;AACnB,4GAAA,WAAW,OAAA;AACX,2GAAA,UAAU,OAAA;AAEV,yGAAA,QAAQ,OAAA;AACR,+GAAA,cAAc,OAAA;AAGhB,qCAAqC;AACrC,
|
|
1
|
+
{"version":3,"file":"index.browser.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.browser.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEZ;;;;GAIG;AAEH,iCAAiC;AACjC,0CAAwB;AAExB,YAAY;AACZ,yCAMqB;AALnB,6GAAA,gBAAgB,OAAA;AAChB,8GAAA,iBAAiB,OAAA;AACjB,kHAAA,qBAAqB,OAAA;AACrB,8GAAA,iBAAiB,OAAA;AACjB,wGAAA,WAAW,OAAA;AAGb,gEAAgE;AAChE,iFAAiF;AACjF,mEAAqD;AAC5C,4BAAQ;AAEjB,uBAAuB;AACvB,yDAA2C;AAClC,gCAAU;AAEnB,6BAA6B;AAC7B,uEAAuG;AAA9F,oIAAA,wBAAwB,OAAA;AAEjC,8DAA8D;AAC9D,mEAA2F;AAAzD,gIAAA,sBAAsB,OAAA;AAExD,8DAA8D;AAC9D,4DAA4D;AAE5D,yBAAyB;AACzB,iDAOyB;AANvB,oHAAA,mBAAmB,OAAA;AACnB,4GAAA,WAAW,OAAA;AACX,2GAAA,UAAU,OAAA;AAEV,yGAAA,QAAQ,OAAA;AACR,+GAAA,cAAc,OAAA;AAGhB,qCAAqC;AACrC,6CAUuB;AATrB,mHAAA,oBAAoB,OAAA;AACpB,mHAAA,oBAAoB,OAAA;AACpB,6HAAA,8BAA8B,OAAA;AAC9B,+HAAA,gCAAgC,OAAA;AAChC,4HAAA,6BAA6B,OAAA;AAC7B,2HAAA,4BAA4B,OAAA;AAC5B,uHAAA,wBAAwB,OAAA;AACxB,uHAAA,wBAAwB,OAAA;AACxB,8GAAA,eAAe,OAAA;AAGjB,qFAAqF;AACrF,uFAAuF;AACvF,+CAA+D;AAAtD,4GAAA,YAAY,OAAA","sourcesContent":["// Copyright (c) 2024 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Crypto utilities for encrypted file handling and key management (browser version).\n * Note: For browser crypto provider, use \\@fgv/ts-web-extras.\n * @packageDocumentation\n */\n\n// Re-export all types from model\nexport * from './model';\n\n// Constants\nexport {\n AES_256_KEY_SIZE,\n DEFAULT_ALGORITHM,\n ENCRYPTED_FILE_FORMAT,\n GCM_AUTH_TAG_SIZE,\n GCM_IV_SIZE\n} from './constants';\n\n// KeyStore namespace (browser-safe barrel — omits the Node-only\n// EncryptedFilePrivateKeyStorage so the browser entry stays free of node:crypto)\nimport * as KeyStore from './keystore/index.browser';\nexport { KeyStore };\n\n// Converters namespace\nimport * as Converters from './converters';\nexport { Converters };\n\n// Direct encryption provider\nexport { DirectEncryptionProvider, IDirectEncryptionProviderParams } from './directEncryptionProvider';\n\n// WebCrypto parameter table for asymmetric keypair algorithms\nexport { IKeyPairAlgorithmParams, keyPairAlgorithmParams } from './keyPairAlgorithmParams';\n\n// Note: NodeCryptoProvider is NOT exported in browser version\n// Use BrowserCryptoProvider from @fgv/ts-web-extras instead\n\n// Encrypted file helpers\nexport {\n createEncryptedFile,\n decryptFile,\n fromBase64,\n ICreateEncryptedFileParams,\n toBase64,\n tryDecryptFile\n} from './encryptedFile';\n\n// Multibase/SPKI + base64url helpers\nexport {\n base64UrlNoPadDecode,\n base64UrlNoPadEncode,\n exportPublicKeyAsMultibaseSpki,\n importPublicKeyFromMultibaseSpki,\n isValidMultibaseSpkiPublicKey,\n MultibaseSpkiPublicKeyRegExp,\n multibaseBase64UrlDecode,\n multibaseBase64UrlEncode,\n spkiToRawX25519\n} from './spkiHelpers';\n\n// HPKE base mode (RFC 9180) — DHKEM(X25519, HKDF-SHA256) + HKDF-SHA256 + AES-256-GCM\n// hpkeProvider.ts has no Node-specific imports and is safe in the browser entry point.\nexport { HpkeProvider, IHpkeSealResult } from './hpkeProvider';\n"]}
|
|
@@ -13,6 +13,6 @@ export { DirectEncryptionProvider, IDirectEncryptionProviderParams } from './dir
|
|
|
13
13
|
export { IKeyPairAlgorithmParams, keyPairAlgorithmParams } from './keyPairAlgorithmParams';
|
|
14
14
|
export { NodeCryptoProvider, nodeCryptoProvider } from './nodeCryptoProvider';
|
|
15
15
|
export { createEncryptedFile, decryptFile, fromBase64, ICreateEncryptedFileParams, toBase64, tryDecryptFile } from './encryptedFile';
|
|
16
|
-
export { base64UrlNoPadDecode, base64UrlNoPadEncode, exportPublicKeyAsMultibaseSpki, importPublicKeyFromMultibaseSpki, isValidMultibaseSpkiPublicKey, MultibaseSpkiPublicKeyRegExp, multibaseBase64UrlDecode, multibaseBase64UrlEncode } from './spkiHelpers';
|
|
16
|
+
export { base64UrlNoPadDecode, base64UrlNoPadEncode, exportPublicKeyAsMultibaseSpki, importPublicKeyFromMultibaseSpki, isValidMultibaseSpkiPublicKey, MultibaseSpkiPublicKeyRegExp, multibaseBase64UrlDecode, multibaseBase64UrlEncode, spkiToRawX25519 } from './spkiHelpers';
|
|
17
17
|
export { HpkeProvider, IHpkeSealResult } from './hpkeProvider';
|
|
18
18
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.ts"],"names":[],"mappings":"AAoBA;;;GAGG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,CAAC;AAGrB,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,CAAC;AAGpB,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,CAAC;AAGtB,OAAO,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AAGvG,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAG3F,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,UAAU,EACV,0BAA0B,EAC1B,QAAQ,EACR,cAAc,EACf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,8BAA8B,EAC9B,gCAAgC,EAChC,6BAA6B,EAC7B,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.ts"],"names":[],"mappings":"AAoBA;;;GAGG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,CAAC;AAGrB,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,CAAC;AAGpB,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,CAAC;AAGtB,OAAO,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AAGvG,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAG3F,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,UAAU,EACV,0BAA0B,EAC1B,QAAQ,EACR,cAAc,EACf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,8BAA8B,EAC9B,gCAAgC,EAChC,6BAA6B,EAC7B,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,EAChB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -55,7 +55,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
55
55
|
};
|
|
56
56
|
})();
|
|
57
57
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
58
|
-
exports.HpkeProvider = exports.multibaseBase64UrlEncode = exports.multibaseBase64UrlDecode = exports.MultibaseSpkiPublicKeyRegExp = exports.isValidMultibaseSpkiPublicKey = exports.importPublicKeyFromMultibaseSpki = exports.exportPublicKeyAsMultibaseSpki = exports.base64UrlNoPadEncode = exports.base64UrlNoPadDecode = exports.tryDecryptFile = exports.toBase64 = exports.fromBase64 = exports.decryptFile = exports.createEncryptedFile = exports.nodeCryptoProvider = exports.NodeCryptoProvider = exports.keyPairAlgorithmParams = exports.DirectEncryptionProvider = exports.Converters = exports.KeyStore = exports.Constants = void 0;
|
|
58
|
+
exports.HpkeProvider = exports.spkiToRawX25519 = exports.multibaseBase64UrlEncode = exports.multibaseBase64UrlDecode = exports.MultibaseSpkiPublicKeyRegExp = exports.isValidMultibaseSpkiPublicKey = exports.importPublicKeyFromMultibaseSpki = exports.exportPublicKeyAsMultibaseSpki = exports.base64UrlNoPadEncode = exports.base64UrlNoPadDecode = exports.tryDecryptFile = exports.toBase64 = exports.fromBase64 = exports.decryptFile = exports.createEncryptedFile = exports.nodeCryptoProvider = exports.NodeCryptoProvider = exports.keyPairAlgorithmParams = exports.DirectEncryptionProvider = exports.Converters = exports.KeyStore = exports.Constants = void 0;
|
|
59
59
|
/**
|
|
60
60
|
* Crypto utilities for encrypted file handling and key management.
|
|
61
61
|
* @packageDocumentation
|
|
@@ -98,6 +98,7 @@ Object.defineProperty(exports, "isValidMultibaseSpkiPublicKey", { enumerable: tr
|
|
|
98
98
|
Object.defineProperty(exports, "MultibaseSpkiPublicKeyRegExp", { enumerable: true, get: function () { return spkiHelpers_1.MultibaseSpkiPublicKeyRegExp; } });
|
|
99
99
|
Object.defineProperty(exports, "multibaseBase64UrlDecode", { enumerable: true, get: function () { return spkiHelpers_1.multibaseBase64UrlDecode; } });
|
|
100
100
|
Object.defineProperty(exports, "multibaseBase64UrlEncode", { enumerable: true, get: function () { return spkiHelpers_1.multibaseBase64UrlEncode; } });
|
|
101
|
+
Object.defineProperty(exports, "spkiToRawX25519", { enumerable: true, get: function () { return spkiHelpers_1.spkiToRawX25519; } });
|
|
101
102
|
// HPKE base mode (RFC 9180) — DHKEM(X25519, HKDF-SHA256) + HKDF-SHA256 + AES-256-GCM
|
|
102
103
|
var hpkeProvider_1 = require("./hpkeProvider");
|
|
103
104
|
Object.defineProperty(exports, "HpkeProvider", { enumerable: true, get: function () { return hpkeProvider_1.HpkeProvider; } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEZ;;;GAGG;AAEH,iCAAiC;AACjC,0CAAwB;AAExB,YAAY;AACZ,uDAAyC;AAChC,8BAAS;AAElB,qBAAqB;AACrB,qDAAuC;AAC9B,4BAAQ;AAEjB,uBAAuB;AACvB,yDAA2C;AAClC,gCAAU;AAEnB,6BAA6B;AAC7B,uEAAuG;AAA9F,oIAAA,wBAAwB,OAAA;AAEjC,8DAA8D;AAC9D,mEAA2F;AAAzD,gIAAA,sBAAsB,OAAA;AAExD,qDAAqD;AACrD,2DAA8E;AAArE,wHAAA,kBAAkB,OAAA;AAAE,wHAAA,kBAAkB,OAAA;AAE/C,yBAAyB;AACzB,iDAOyB;AANvB,oHAAA,mBAAmB,OAAA;AACnB,4GAAA,WAAW,OAAA;AACX,2GAAA,UAAU,OAAA;AAEV,yGAAA,QAAQ,OAAA;AACR,+GAAA,cAAc,OAAA;AAGhB,qCAAqC;AACrC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEZ;;;GAGG;AAEH,iCAAiC;AACjC,0CAAwB;AAExB,YAAY;AACZ,uDAAyC;AAChC,8BAAS;AAElB,qBAAqB;AACrB,qDAAuC;AAC9B,4BAAQ;AAEjB,uBAAuB;AACvB,yDAA2C;AAClC,gCAAU;AAEnB,6BAA6B;AAC7B,uEAAuG;AAA9F,oIAAA,wBAAwB,OAAA;AAEjC,8DAA8D;AAC9D,mEAA2F;AAAzD,gIAAA,sBAAsB,OAAA;AAExD,qDAAqD;AACrD,2DAA8E;AAArE,wHAAA,kBAAkB,OAAA;AAAE,wHAAA,kBAAkB,OAAA;AAE/C,yBAAyB;AACzB,iDAOyB;AANvB,oHAAA,mBAAmB,OAAA;AACnB,4GAAA,WAAW,OAAA;AACX,2GAAA,UAAU,OAAA;AAEV,yGAAA,QAAQ,OAAA;AACR,+GAAA,cAAc,OAAA;AAGhB,qCAAqC;AACrC,6CAUuB;AATrB,mHAAA,oBAAoB,OAAA;AACpB,mHAAA,oBAAoB,OAAA;AACpB,6HAAA,8BAA8B,OAAA;AAC9B,+HAAA,gCAAgC,OAAA;AAChC,4HAAA,6BAA6B,OAAA;AAC7B,2HAAA,4BAA4B,OAAA;AAC5B,uHAAA,wBAAwB,OAAA;AACxB,uHAAA,wBAAwB,OAAA;AACxB,8GAAA,eAAe,OAAA;AAGjB,qFAAqF;AACrF,+CAA+D;AAAtD,4GAAA,YAAY,OAAA","sourcesContent":["// Copyright (c) 2024 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Crypto utilities for encrypted file handling and key management.\n * @packageDocumentation\n */\n\n// Re-export all types from model\nexport * from './model';\n\n// Constants\nimport * as Constants from './constants';\nexport { Constants };\n\n// KeyStore namespace\nimport * as KeyStore from './keystore';\nexport { KeyStore };\n\n// Converters namespace\nimport * as Converters from './converters';\nexport { Converters };\n\n// Direct encryption provider\nexport { DirectEncryptionProvider, IDirectEncryptionProviderParams } from './directEncryptionProvider';\n\n// WebCrypto parameter table for asymmetric keypair algorithms\nexport { IKeyPairAlgorithmParams, keyPairAlgorithmParams } from './keyPairAlgorithmParams';\n\n// Node.js crypto provider (Node.js environment only)\nexport { NodeCryptoProvider, nodeCryptoProvider } from './nodeCryptoProvider';\n\n// Encrypted file helpers\nexport {\n createEncryptedFile,\n decryptFile,\n fromBase64,\n ICreateEncryptedFileParams,\n toBase64,\n tryDecryptFile\n} from './encryptedFile';\n\n// Multibase/SPKI + base64url helpers\nexport {\n base64UrlNoPadDecode,\n base64UrlNoPadEncode,\n exportPublicKeyAsMultibaseSpki,\n importPublicKeyFromMultibaseSpki,\n isValidMultibaseSpkiPublicKey,\n MultibaseSpkiPublicKeyRegExp,\n multibaseBase64UrlDecode,\n multibaseBase64UrlEncode,\n spkiToRawX25519\n} from './spkiHelpers';\n\n// HPKE base mode (RFC 9180) — DHKEM(X25519, HKDF-SHA256) + HKDF-SHA256 + AES-256-GCM\nexport { HpkeProvider, IHpkeSealResult } from './hpkeProvider';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"converters.d.ts","sourceRoot":"","sources":["../../../../src/packlets/crypto-utils/keystore/converters.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,SAAS,EAAmC,SAAS,EAAc,MAAM,eAAe,CAAC;AAElG,OAAO,
|
|
1
|
+
{"version":3,"file":"converters.d.ts","sourceRoot":"","sources":["../../../../src/packlets/crypto-utils/keystore/converters.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,SAAS,EAAmC,SAAS,EAAc,MAAM,eAAe,CAAC;AAElG,OAAO,EAKL,4BAA4B,EAC5B,kBAAkB,EAClB,aAAa,EACb,2BAA2B,EAC3B,sBAAsB,EACtB,gBAAgB,EAChB,4BAA4B,EAC5B,cAAc,EACd,kBAAkB,EAClB,2BAA2B,EAE5B,MAAM,SAAS,CAAC;AAMjB;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,CAAC,cAAc,CACW,CAAC;AAMjE;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,CAAC,kBAAkB,CACW,CAAC;AAEzE;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,EAAE,SAAS,CAAC,2BAA2B,CACW,CAAC;AAE3F;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,EAAE,SAAS,CAAC,4BAA4B,CACW,CAAC;AAM7F;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,CAAC,gBAAgB,CACW,CAAC;AAMrE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,CAAC,UAAU,CAEE,CAAC;AAMrD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,0BAA0B,EAAE,SAAS,CAAC,2BAA2B,CAmB3E,CAAC;AAMJ;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,EAAE,SAAS,CAAC,4BAA4B,CAU5E,CAAC;AAML;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,CAAC,kBAAkB,CAGhE,CAAC;AAMH;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,CAAC,sBAAsB,CAIhE,CAAC;AAML;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,CAAC,aAAa,CAOhD,CAAC"}
|
|
@@ -30,9 +30,7 @@ const model_1 = require("./model");
|
|
|
30
30
|
* Converter for {@link CryptoUtils.KeyStore.KeyStoreFormat | key store format} version.
|
|
31
31
|
* @public
|
|
32
32
|
*/
|
|
33
|
-
exports.keystoreFormat = ts_utils_1.Converters.enumeratedValue(
|
|
34
|
-
model_1.KEYSTORE_FORMAT
|
|
35
|
-
]);
|
|
33
|
+
exports.keystoreFormat = ts_utils_1.Converters.enumeratedValue(model_1.allKeyStoreFormats);
|
|
36
34
|
// ============================================================================
|
|
37
35
|
// Secret Type Converters
|
|
38
36
|
// ============================================================================
|
|
@@ -132,6 +130,7 @@ exports.keystoreAsymmetricEntryJson = ts_utils_1.Converters.object({
|
|
|
132
130
|
id: ts_utils_1.Converters.string,
|
|
133
131
|
algorithm: exports.keyPairAlgorithm,
|
|
134
132
|
publicKeyJwk: exports.jsonWebKeyShape,
|
|
133
|
+
escrowedPrivateKeyJwk: exports.jsonWebKeyShape.optional(),
|
|
135
134
|
description: ts_utils_1.Converters.string.optional(),
|
|
136
135
|
createdAt: ts_utils_1.Converters.string
|
|
137
136
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"converters.js","sourceRoot":"","sources":["../../../../src/packlets/crypto-utils/keystore/converters.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { Converter, Converters, succeed, Validation, Validator, Validators } from '@fgv/ts-utils';\nimport { base64String, encryptionAlgorithm, pbkdf2KeyDerivationParams } from '../converters';\nimport {\n allKeyPairAlgorithms,\n allKeyStoreSecretTypes,\n allKeyStoreSymmetricSecretTypes,\n IKeyStoreAsymmetricEntryJson,\n IKeyStoreEntryJson,\n IKeyStoreFile,\n IKeyStoreSymmetricEntryJson,\n IKeyStoreVaultContents,\n KEYSTORE_FORMAT,\n KeyPairAlgorithm,\n KeyStoreAsymmetricSecretType,\n KeyStoreFormat,\n KeyStoreSecretType,\n KeyStoreSymmetricSecretType,\n allKeyStoreAsymmetricSecretTypes\n} from './model';\n\n// ============================================================================\n// Key Store Format Converter\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.KeyStoreFormat | key store format} version.\n * @public\n */\nexport const keystoreFormat: Converter<KeyStoreFormat> = Converters.enumeratedValue<KeyStoreFormat>([\n KEYSTORE_FORMAT\n]);\n\n// ============================================================================\n// Secret Type Converters\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.KeyStoreSecretType | any key store secret type} discriminator.\n * Accepts both symmetric and asymmetric type values.\n * @public\n */\nexport const keystoreSecretType: Converter<KeyStoreSecretType> =\n Converters.enumeratedValue<KeyStoreSecretType>(allKeyStoreSecretTypes);\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.KeyStoreSymmetricSecretType | symmetric secret type} discriminator.\n * Accepts only `'encryption-key'` and `'api-key'`.\n * @public\n */\nexport const keystoreSymmetricSecretType: Converter<KeyStoreSymmetricSecretType> =\n Converters.enumeratedValue<KeyStoreSymmetricSecretType>(allKeyStoreSymmetricSecretTypes);\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.KeyStoreAsymmetricSecretType | asymmetric secret type} discriminator.\n * Accepts only `'asymmetric-keypair'`.\n * @public\n */\nexport const keystoreAsymmetricSecretType: Converter<KeyStoreAsymmetricSecretType> =\n Converters.enumeratedValue<KeyStoreAsymmetricSecretType>(allKeyStoreAsymmetricSecretTypes);\n\n// ============================================================================\n// Key Pair Algorithm Converter\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.KeyPairAlgorithm | key pair algorithm}.\n * @public\n */\nexport const keyPairAlgorithm: Converter<KeyPairAlgorithm> =\n Converters.enumeratedValue<KeyPairAlgorithm>(allKeyPairAlgorithms);\n\n// ============================================================================\n// JWK Shape Validator\n// ============================================================================\n\n/**\n * In-place shape check for a JSON Web Key. Asserts only that the input is a\n * non-array object whose `kty` discriminator is a string; every other JWK\n * field passes through untouched. This is intentionally **not** a true JWK\n * validator — per-algorithm correctness (RSA `n`/`e`, EC `crv`/`x`/`y`,\n * key-size constraints, etc.) is delegated to `crypto.subtle.importKey` at\n * first use, which is the authoritative checker. The \"shape\" suffix in the\n * name is the warning sign for readers expecting full validation.\n * @remarks\n * Built with `Validators.object` (in-place, non-strict) so unknown JWK fields\n * survive the round-trip; the cast to `FieldValidators<JsonWebKey>` is required\n * only because TypeScript's mapped type demands an entry for every key in\n * `JsonWebKey`. At runtime the `ObjectValidator` only inspects keys present in\n * the field-validators map.\n * @public\n */\nexport const jsonWebKeyShape: Validator<JsonWebKey> = Validators.object<JsonWebKey>({\n kty: Validators.string\n} as Validation.Classes.FieldValidators<JsonWebKey>);\n\n// ============================================================================\n// Symmetric Secret Entry Converter\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntryJson | symmetric secret entry} in JSON form.\n *\n * @remarks\n * Backwards compatibility with vaults written before asymmetric-keypair\n * support: those entries may lack the `type` discriminator on the wire. To\n * keep the model type honest (`type` is required on\n * {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntryJson}, see its docs),\n * we declare `type` in `optionalFields` so the inner `Converters.object` will\n * accept input without it, then `.map()` injects the default\n * `'encryption-key'` when missing. The output therefore always carries the\n * discriminator and downstream code never sees the legacy missing-type form.\n *\n * @public\n */\nexport const keystoreSymmetricEntryJson: Converter<IKeyStoreSymmetricEntryJson> =\n Converters.object<IKeyStoreSymmetricEntryJson>(\n {\n name: Converters.string,\n type: keystoreSymmetricSecretType,\n key: base64String,\n description: Converters.string,\n createdAt: Converters.string\n },\n {\n // `type` is optional at the input layer for legacy-vault compatibility;\n // the .map() below normalizes by injecting the default.\n optionalFields: ['type', 'description']\n }\n ).map((entry) =>\n succeed<IKeyStoreSymmetricEntryJson>({\n ...entry,\n type: entry.type ?? 'encryption-key'\n })\n );\n\n// ============================================================================\n// Asymmetric Keypair Entry Converter\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.IKeyStoreAsymmetricEntryJson | asymmetric keypair entry} in JSON form.\n * The `publicKeyJwk` field passes through {@link CryptoUtils.KeyStore.Converters.jsonWebKeyShape | jsonWebKeyShape}\n * (shape check only — see its docs); cryptographic correctness is enforced by\n * `crypto.subtle.importKey` at use.\n * @public\n */\nexport const keystoreAsymmetricEntryJson: Converter<IKeyStoreAsymmetricEntryJson> =\n Converters.object<IKeyStoreAsymmetricEntryJson>({\n name: Converters.string,\n type: keystoreAsymmetricSecretType,\n id: Converters.string,\n algorithm: keyPairAlgorithm,\n publicKeyJwk: jsonWebKeyShape,\n description: Converters.string.optional(),\n createdAt: Converters.string\n });\n\n// ============================================================================\n// Discriminated-Union Entry Converter\n// ============================================================================\n\n/**\n * Discriminated-union converter for any {@link CryptoUtils.KeyStore.IKeyStoreEntryJson | key store entry} in JSON form.\n * Routes by the `type` field: `'asymmetric-keypair'` is parsed by\n * {@link CryptoUtils.KeyStore.Converters.keystoreAsymmetricEntryJson | keystoreAsymmetricEntryJson},\n * anything else (including a missing `type` field for backwards compatibility) by\n * {@link CryptoUtils.KeyStore.Converters.keystoreSymmetricEntryJson | keystoreSymmetricEntryJson}.\n * @public\n */\nexport const keystoreSecretEntryJson: Converter<IKeyStoreEntryJson> = Converters.oneOf<IKeyStoreEntryJson>([\n keystoreAsymmetricEntryJson,\n keystoreSymmetricEntryJson\n]);\n\n// ============================================================================\n// Vault Contents Converter\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.IKeyStoreVaultContents | key store vault contents} (decrypted state).\n * @public\n */\nexport const keystoreVaultContents: Converter<IKeyStoreVaultContents> =\n Converters.object<IKeyStoreVaultContents>({\n version: keystoreFormat,\n secrets: Converters.recordOf(keystoreSecretEntryJson)\n });\n\n// ============================================================================\n// Key Store File Converter\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.IKeyStoreFile | encrypted key store file}.\n * @public\n */\nexport const keystoreFile: Converter<IKeyStoreFile> = Converters.object<IKeyStoreFile>({\n format: keystoreFormat,\n algorithm: encryptionAlgorithm,\n iv: base64String,\n authTag: base64String,\n encryptedData: base64String,\n keyDerivation: pbkdf2KeyDerivationParams\n});\n"]}
|
|
1
|
+
{"version":3,"file":"converters.js","sourceRoot":"","sources":["../../../../src/packlets/crypto-utils/keystore/converters.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { Converter, Converters, succeed, Validation, Validator, Validators } from '@fgv/ts-utils';\nimport { base64String, encryptionAlgorithm, pbkdf2KeyDerivationParams } from '../converters';\nimport {\n allKeyPairAlgorithms,\n allKeyStoreFormats,\n allKeyStoreSecretTypes,\n allKeyStoreSymmetricSecretTypes,\n IKeyStoreAsymmetricEntryJson,\n IKeyStoreEntryJson,\n IKeyStoreFile,\n IKeyStoreSymmetricEntryJson,\n IKeyStoreVaultContents,\n KeyPairAlgorithm,\n KeyStoreAsymmetricSecretType,\n KeyStoreFormat,\n KeyStoreSecretType,\n KeyStoreSymmetricSecretType,\n allKeyStoreAsymmetricSecretTypes\n} from './model';\n\n// ============================================================================\n// Key Store Format Converter\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.KeyStoreFormat | key store format} version.\n * @public\n */\nexport const keystoreFormat: Converter<KeyStoreFormat> =\n Converters.enumeratedValue<KeyStoreFormat>(allKeyStoreFormats);\n\n// ============================================================================\n// Secret Type Converters\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.KeyStoreSecretType | any key store secret type} discriminator.\n * Accepts both symmetric and asymmetric type values.\n * @public\n */\nexport const keystoreSecretType: Converter<KeyStoreSecretType> =\n Converters.enumeratedValue<KeyStoreSecretType>(allKeyStoreSecretTypes);\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.KeyStoreSymmetricSecretType | symmetric secret type} discriminator.\n * Accepts only `'encryption-key'` and `'api-key'`.\n * @public\n */\nexport const keystoreSymmetricSecretType: Converter<KeyStoreSymmetricSecretType> =\n Converters.enumeratedValue<KeyStoreSymmetricSecretType>(allKeyStoreSymmetricSecretTypes);\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.KeyStoreAsymmetricSecretType | asymmetric secret type} discriminator.\n * Accepts only `'asymmetric-keypair'`.\n * @public\n */\nexport const keystoreAsymmetricSecretType: Converter<KeyStoreAsymmetricSecretType> =\n Converters.enumeratedValue<KeyStoreAsymmetricSecretType>(allKeyStoreAsymmetricSecretTypes);\n\n// ============================================================================\n// Key Pair Algorithm Converter\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.KeyPairAlgorithm | key pair algorithm}.\n * @public\n */\nexport const keyPairAlgorithm: Converter<KeyPairAlgorithm> =\n Converters.enumeratedValue<KeyPairAlgorithm>(allKeyPairAlgorithms);\n\n// ============================================================================\n// JWK Shape Validator\n// ============================================================================\n\n/**\n * In-place shape check for a JSON Web Key. Asserts only that the input is a\n * non-array object whose `kty` discriminator is a string; every other JWK\n * field passes through untouched. This is intentionally **not** a true JWK\n * validator — per-algorithm correctness (RSA `n`/`e`, EC `crv`/`x`/`y`,\n * key-size constraints, etc.) is delegated to `crypto.subtle.importKey` at\n * first use, which is the authoritative checker. The \"shape\" suffix in the\n * name is the warning sign for readers expecting full validation.\n * @remarks\n * Built with `Validators.object` (in-place, non-strict) so unknown JWK fields\n * survive the round-trip; the cast to `FieldValidators<JsonWebKey>` is required\n * only because TypeScript's mapped type demands an entry for every key in\n * `JsonWebKey`. At runtime the `ObjectValidator` only inspects keys present in\n * the field-validators map.\n * @public\n */\nexport const jsonWebKeyShape: Validator<JsonWebKey> = Validators.object<JsonWebKey>({\n kty: Validators.string\n} as Validation.Classes.FieldValidators<JsonWebKey>);\n\n// ============================================================================\n// Symmetric Secret Entry Converter\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntryJson | symmetric secret entry} in JSON form.\n *\n * @remarks\n * Backwards compatibility with vaults written before asymmetric-keypair\n * support: those entries may lack the `type` discriminator on the wire. To\n * keep the model type honest (`type` is required on\n * {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntryJson}, see its docs),\n * we declare `type` in `optionalFields` so the inner `Converters.object` will\n * accept input without it, then `.map()` injects the default\n * `'encryption-key'` when missing. The output therefore always carries the\n * discriminator and downstream code never sees the legacy missing-type form.\n *\n * @public\n */\nexport const keystoreSymmetricEntryJson: Converter<IKeyStoreSymmetricEntryJson> =\n Converters.object<IKeyStoreSymmetricEntryJson>(\n {\n name: Converters.string,\n type: keystoreSymmetricSecretType,\n key: base64String,\n description: Converters.string,\n createdAt: Converters.string\n },\n {\n // `type` is optional at the input layer for legacy-vault compatibility;\n // the .map() below normalizes by injecting the default.\n optionalFields: ['type', 'description']\n }\n ).map((entry) =>\n succeed<IKeyStoreSymmetricEntryJson>({\n ...entry,\n type: entry.type ?? 'encryption-key'\n })\n );\n\n// ============================================================================\n// Asymmetric Keypair Entry Converter\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.IKeyStoreAsymmetricEntryJson | asymmetric keypair entry} in JSON form.\n * The `publicKeyJwk` field passes through {@link CryptoUtils.KeyStore.Converters.jsonWebKeyShape | jsonWebKeyShape}\n * (shape check only — see its docs); cryptographic correctness is enforced by\n * `crypto.subtle.importKey` at use.\n * @public\n */\nexport const keystoreAsymmetricEntryJson: Converter<IKeyStoreAsymmetricEntryJson> =\n Converters.object<IKeyStoreAsymmetricEntryJson>({\n name: Converters.string,\n type: keystoreAsymmetricSecretType,\n id: Converters.string,\n algorithm: keyPairAlgorithm,\n publicKeyJwk: jsonWebKeyShape,\n escrowedPrivateKeyJwk: jsonWebKeyShape.optional(),\n description: Converters.string.optional(),\n createdAt: Converters.string\n });\n\n// ============================================================================\n// Discriminated-Union Entry Converter\n// ============================================================================\n\n/**\n * Discriminated-union converter for any {@link CryptoUtils.KeyStore.IKeyStoreEntryJson | key store entry} in JSON form.\n * Routes by the `type` field: `'asymmetric-keypair'` is parsed by\n * {@link CryptoUtils.KeyStore.Converters.keystoreAsymmetricEntryJson | keystoreAsymmetricEntryJson},\n * anything else (including a missing `type` field for backwards compatibility) by\n * {@link CryptoUtils.KeyStore.Converters.keystoreSymmetricEntryJson | keystoreSymmetricEntryJson}.\n * @public\n */\nexport const keystoreSecretEntryJson: Converter<IKeyStoreEntryJson> = Converters.oneOf<IKeyStoreEntryJson>([\n keystoreAsymmetricEntryJson,\n keystoreSymmetricEntryJson\n]);\n\n// ============================================================================\n// Vault Contents Converter\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.IKeyStoreVaultContents | key store vault contents} (decrypted state).\n * @public\n */\nexport const keystoreVaultContents: Converter<IKeyStoreVaultContents> =\n Converters.object<IKeyStoreVaultContents>({\n version: keystoreFormat,\n secrets: Converters.recordOf(keystoreSecretEntryJson)\n });\n\n// ============================================================================\n// Key Store File Converter\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.KeyStore.IKeyStoreFile | encrypted key store file}.\n * @public\n */\nexport const keystoreFile: Converter<IKeyStoreFile> = Converters.object<IKeyStoreFile>({\n format: keystoreFormat,\n algorithm: encryptionAlgorithm,\n iv: base64String,\n authTag: base64String,\n encryptedData: base64String,\n keyDerivation: pbkdf2KeyDerivationParams\n});\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { JsonValue } from '@fgv/ts-json-base';
|
|
2
2
|
import { Result } from '@fgv/ts-utils';
|
|
3
3
|
import { ICryptoProvider, IEncryptedFile, IEncryptionConfig, IEncryptionProvider, IArgon2idKeyDerivationParams, IArgon2idProvider, IKeyDerivationParams, SecretProvider } from '../model';
|
|
4
|
-
import { IAddKeyPairOptions, IAddKeyPairResult, IAddSecretFromPasswordArgon2idOptions, IAddSecretFromPasswordOptions, IAddSecretFromPasswordResult, IAddSecretOptions, IAddSecretResult, IImportKeyOptions, IImportSecretOptions, IKeyStoreCreateParams, IKeyStoreEntry, IKeyStoreFile, IKeyStoreOpenParams, IRemoveSecretResult, KeyStoreLockState, KeyStoreSecretType } from './model';
|
|
4
|
+
import { IAddKeyPairOptions, IAddKeyPairResult, IAddSecretFromPasswordArgon2idOptions, IAddSecretFromPasswordOptions, IAddSecretFromPasswordResult, IAddSecretOptions, IAddSecretResult, IGetKeyPairOptions, IImportKeyOptions, IImportSecretOptions, IKeyStoreCreateParams, IKeyStoreEntry, IKeyStoreFile, IKeyStoreOpenParams, IRemoveSecretResult, KeyStoreLockState, KeyStoreSecretType } from './model';
|
|
5
5
|
/**
|
|
6
6
|
* Password-protected key store for managing encryption secrets.
|
|
7
7
|
*
|
|
@@ -31,6 +31,20 @@ import { IAddKeyPairOptions, IAddKeyPairResult, IAddSecretFromPasswordArgon2idOp
|
|
|
31
31
|
* const encryptionConfig = keystore2.getEncryptionConfig().orThrow();
|
|
32
32
|
* ```
|
|
33
33
|
*
|
|
34
|
+
* @remarks
|
|
35
|
+
* SECURITY — private-key escrow. By default an asymmetric keypair's private
|
|
36
|
+
* key lives only in the per-device {@link CryptoUtils.KeyStore.IPrivateKeyStorage}
|
|
37
|
+
* backend; the vault carries only the public JWK, so a vault recovered on a new
|
|
38
|
+
* device reconstitutes with no private keys (a lost device is a lost identity).
|
|
39
|
+
* `addKeyPair(name, { escrow: true })` opts into carrying an encrypted private-key
|
|
40
|
+
* copy inside the vault ciphertext, so the vault file plus the master password can
|
|
41
|
+
* recover the identity on a fresh device via `getKeyPair(name, { rehydrate: true })`.
|
|
42
|
+
*
|
|
43
|
+
* When escrow is used, **the master password becomes the sole gate** protecting a
|
|
44
|
+
* private signing/decryption key that was previously unrecoverable from the vault.
|
|
45
|
+
* Configure escrow-bearing stores with a strong KDF — an Argon2id-derived master
|
|
46
|
+
* key or a high-iteration PBKDF2 count — and treat the vault file accordingly.
|
|
47
|
+
*
|
|
34
48
|
* @public
|
|
35
49
|
*/
|
|
36
50
|
export declare class KeyStore implements IEncryptionProvider {
|
|
@@ -137,6 +151,12 @@ export declare class KeyStore implements IEncryptionProvider {
|
|
|
137
151
|
* Gets a secret by name. Returns the {@link CryptoUtils.KeyStore.IKeyStoreEntry | discriminated union}
|
|
138
152
|
* — callers must check `entry.type` before accessing `key`/`id` since asymmetric
|
|
139
153
|
* entries carry no raw key material.
|
|
154
|
+
*
|
|
155
|
+
* SECURITY: for an escrow-enabled asymmetric-keypair entry the returned object
|
|
156
|
+
* carries `escrowedPrivateKeyJwk` in cleartext (same custody class as
|
|
157
|
+
* `publicKeyJwk`, gated by the same unlock) — do not log or serialize a
|
|
158
|
+
* `getSecret()` result casually.
|
|
159
|
+
*
|
|
140
160
|
* @param name - Name of the secret
|
|
141
161
|
* @returns Success with secret entry, Failure if not found or locked
|
|
142
162
|
* @public
|
|
@@ -323,12 +343,23 @@ export declare class KeyStore implements IEncryptionProvider {
|
|
|
323
343
|
* the keystore never caches private `CryptoKey` references between calls.
|
|
324
344
|
* The public key is re-imported from the vault's JWK so callers always
|
|
325
345
|
* receive a `CryptoKey` rather than the JWK form.
|
|
346
|
+
*
|
|
347
|
+
* With `options.rehydrate: true`, if the storage backend holds no blob for
|
|
348
|
+
* the entry's `id` and the entry carries an `escrowedPrivateKeyJwk` (see
|
|
349
|
+
* `addKeyPair(name, { escrow: true })`), the escrowed JWK is imported and
|
|
350
|
+
* stored under the entry's `id` before being returned — recovering the
|
|
351
|
+
* private key on a fresh device from the vault plus master password. This is
|
|
352
|
+
* fill-a-gap only: an existing storage blob is never overwritten.
|
|
353
|
+
*
|
|
326
354
|
* @param name - Name of the entry
|
|
355
|
+
* @param options - Optional {@link CryptoUtils.KeyStore.IGetKeyPairOptions}
|
|
356
|
+
* (currently the `rehydrate` escrow-recovery flag).
|
|
327
357
|
* @returns Success with `{ publicKey, privateKey }`, Failure if not found,
|
|
328
|
-
* locked, wrong type, no provider, or storage load
|
|
358
|
+
* locked, wrong type, no provider, or storage load (and any escrow
|
|
359
|
+
* rehydration) failed.
|
|
329
360
|
* @public
|
|
330
361
|
*/
|
|
331
|
-
getKeyPair(name: string): Promise<Result<{
|
|
362
|
+
getKeyPair(name: string, options?: IGetKeyPairOptions): Promise<Result<{
|
|
332
363
|
publicKey: CryptoKey;
|
|
333
364
|
privateKey: CryptoKey;
|
|
334
365
|
}>>;
|
|
@@ -414,6 +445,40 @@ export declare class KeyStore implements IEncryptionProvider {
|
|
|
414
445
|
* @returns A warning string if storage cleanup failed, otherwise undefined.
|
|
415
446
|
*/
|
|
416
447
|
private _releaseEntryResources;
|
|
448
|
+
/**
|
|
449
|
+
* Exports the transient extractable private `CryptoKey` to a JWK for escrow,
|
|
450
|
+
* via WebCrypto's `exportKey('jwk', ...)` (cross-runtime through
|
|
451
|
+
* `globalThis.crypto.subtle`). The result is carried in the vault entry — the
|
|
452
|
+
* same custody class as the public JWK — and is never returned from a public
|
|
453
|
+
* method nor logged.
|
|
454
|
+
*/
|
|
455
|
+
private _exportPrivateKeyJwk;
|
|
456
|
+
/**
|
|
457
|
+
* Re-imports an escrowed private-key JWK as a `CryptoKey` for `algorithm`
|
|
458
|
+
* with the requested extractability. The WebCrypto JWK-import descriptor is
|
|
459
|
+
* shared between the public and private halves for every supported algorithm,
|
|
460
|
+
* so `IKeyPairAlgorithmParams.importPublicKey` is reused; the private/public
|
|
461
|
+
* distinction is carried by the requested usages (see
|
|
462
|
+
* {@link KeyStore._privateKeyUsagesFor}). Cross-runtime through
|
|
463
|
+
* `globalThis.crypto.subtle`.
|
|
464
|
+
*/
|
|
465
|
+
private _importEscrowedPrivateKey;
|
|
466
|
+
/**
|
|
467
|
+
* Loads the private key for `entry` from storage, or — when
|
|
468
|
+
* `options.rehydrate` is set, storage holds no blob, and the entry carries an
|
|
469
|
+
* escrowed JWK — imports the escrowed key, persists it under the entry's `id`
|
|
470
|
+
* (fill-a-gap; never overwrites an existing blob), and returns it.
|
|
471
|
+
*/
|
|
472
|
+
private _loadOrRehydratePrivateKey;
|
|
473
|
+
/**
|
|
474
|
+
* Computes the key usages to request when importing an escrowed private JWK.
|
|
475
|
+
* Mirrors `EncryptedFilePrivateKeyStorage`: intersect the algorithm's private
|
|
476
|
+
* usages (its keypair usages minus the public-only ones) with the JWK's
|
|
477
|
+
* recorded `key_ops` so we request exactly the operations the stored key
|
|
478
|
+
* supports; fall back to the algorithm's private usages when `key_ops` is
|
|
479
|
+
* absent.
|
|
480
|
+
*/
|
|
481
|
+
private static _privateKeyUsagesFor;
|
|
417
482
|
/**
|
|
418
483
|
* Constant-time byte comparison. Returns false immediately for length
|
|
419
484
|
* mismatch (length is not secret); for equal-length inputs, walks the full
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyStore.d.ts","sourceRoot":"","sources":["../../../../src/packlets/crypto-utils/keystore/keyStore.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,
|
|
1
|
+
{"version":3,"file":"keyStore.d.ts","sourceRoot":"","sources":["../../../../src/packlets/crypto-utils/keystore/keyStore.ts"],"names":[],"mappings":"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"}
|