@happyvertical/encryption 0.111.5 → 0.111.7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"node-Bg7R5Icq.js","names":[],"sources":["../../src/adapters/node.ts"],"sourcesContent":["import * as crypto from 'node:crypto';\nimport { BaseEncryption } from '../shared/base.js';\nimport {\n DecryptError,\n EncryptError,\n InvalidKeyError,\n KeyError,\n SignatureError,\n} from '../shared/errors.js';\nimport type {\n DecryptOptions,\n EncryptionCapabilities,\n EncryptOptions,\n ExportKeyOptions,\n ImportKeyOptions,\n Key,\n KeyPair,\n KeyPairOptions,\n NodeCryptoOptions,\n SignOptions,\n VerifyOptions,\n} from '../shared/types.js';\n\n/**\n * Node.js crypto adapter\n *\n * Uses Node.js built-in crypto module for standard encryption algorithms\n * (AES, RSA, ECDH, ECDSA, etc.).\n *\n * @example\n * ```typescript\n * const crypto = new NodeCryptoEncryption({\n * type: 'node',\n * algorithm: 'aes-256-gcm',\n * key: encryptionKey\n * });\n *\n * const encrypted = await crypto.encryptText('Secret message');\n * const decrypted = await crypto.decryptText(encrypted);\n * ```\n */\nexport class NodeCryptoEncryption extends BaseEncryption {\n private options: NodeCryptoOptions;\n private key?: Buffer;\n private publicKey?: crypto.KeyObject;\n private privateKey?: crypto.KeyObject;\n\n constructor(options: NodeCryptoOptions) {\n super('node', options.debug);\n this.options = options;\n this.initializeKeys();\n }\n\n /**\n * Initialize keys from options\n */\n private initializeKeys(): void {\n // Derive key from password if specified\n if (this.options.keyDerivation) {\n this.key = this.deriveKey(this.options.keyDerivation);\n } else if (this.options.key) {\n this.key = this.parseBuffer(this.options.key);\n }\n\n // Initialize asymmetric keys\n if (this.options.publicKey) {\n this.publicKey = this.importPublicKeyObject(this.options.publicKey);\n }\n\n if (this.options.privateKey) {\n this.privateKey = this.importPrivateKeyObject(\n this.options.privateKey,\n this.options.passphrase,\n );\n }\n }\n\n /**\n * Derive key from password using PBKDF2\n */\n private deriveKey(\n derivation: NonNullable<NodeCryptoOptions['keyDerivation']>,\n ): Buffer {\n const salt = derivation.salt\n ? this.parseBuffer(derivation.salt)\n : crypto.randomBytes(16);\n const iterations = derivation.iterations || 100000;\n const keyLength = derivation.keyLength || this.getKeyLength();\n const digest = derivation.digest || 'sha256';\n\n return crypto.pbkdf2Sync(\n derivation.password,\n salt,\n iterations,\n keyLength,\n digest,\n );\n }\n\n /**\n * Get key length for current algorithm\n */\n private getKeyLength(): number {\n const algo = this.options.algorithm.toLowerCase();\n if (algo.includes('256')) return 32;\n if (algo.includes('192')) return 24;\n if (algo.includes('128')) return 16;\n return 32; // Default to 256 bits\n }\n\n /**\n * Parse buffer from string or Buffer\n */\n private parseBuffer(data: string | Buffer): Buffer {\n if (Buffer.isBuffer(data)) return data;\n\n const encoding = this.options.encoding || 'hex';\n if (encoding === 'hex') return Buffer.from(data, 'hex');\n if (encoding === 'base64') return Buffer.from(data, 'base64');\n if (encoding === 'utf8') return Buffer.from(data, 'utf8');\n\n return Buffer.from(data, 'hex');\n }\n\n /**\n * Import public key from PEM/DER\n */\n private importPublicKeyObject(key: string | Buffer): crypto.KeyObject {\n try {\n return crypto.createPublicKey(key);\n } catch (error) {\n throw new InvalidKeyError(\n `Failed to import public key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Import private key from PEM/DER\n */\n private importPrivateKeyObject(\n key: string | Buffer,\n passphrase?: string,\n ): crypto.KeyObject {\n try {\n if (passphrase) {\n return crypto.createPrivateKey({ key, passphrase });\n }\n return crypto.createPrivateKey(key);\n } catch (error) {\n throw new InvalidKeyError(\n `Failed to import private key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Check if algorithm is symmetric (AES)\n */\n private isSymmetric(): boolean {\n const algo = this.options.algorithm.toLowerCase();\n return algo.startsWith('aes-') || algo.includes('cipher');\n }\n\n /**\n * Check if algorithm is RSA\n */\n private isRSA(): boolean {\n const algo = this.options.algorithm.toLowerCase();\n return algo.startsWith('rsa');\n }\n\n async encryptText(text: string, options?: EncryptOptions): Promise<string> {\n try {\n this.log('Encrypting text', { length: text.length });\n\n if (this.isSymmetric()) {\n return this.encryptSymmetric(Buffer.from(text, 'utf8'));\n }\n\n if (this.isRSA()) {\n return this.encryptAsymmetric(Buffer.from(text, 'utf8'));\n }\n\n throw new EncryptError(\n `Unsupported encryption algorithm: ${this.options.algorithm}`,\n this.adapterType,\n );\n } catch (error) {\n if (error instanceof EncryptError) throw error;\n throw new EncryptError(\n `Failed to encrypt text: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async decryptText(\n encrypted: string,\n options?: DecryptOptions,\n ): Promise<string> {\n try {\n this.log('Decrypting text', { length: encrypted.length });\n\n if (this.isSymmetric()) {\n const decrypted = this.decryptSymmetric(encrypted);\n return decrypted.toString('utf8');\n }\n\n if (this.isRSA()) {\n const decrypted = this.decryptAsymmetric(encrypted);\n return decrypted.toString('utf8');\n }\n\n throw new DecryptError(\n `Unsupported decryption algorithm: ${this.options.algorithm}`,\n this.adapterType,\n );\n } catch (error) {\n if (error instanceof DecryptError) throw error;\n throw new DecryptError(\n `Failed to decrypt text: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async encryptBuffer(\n buffer: Buffer,\n options?: EncryptOptions,\n ): Promise<Buffer> {\n try {\n this.log('Encrypting buffer', { size: buffer.length });\n\n if (this.isSymmetric()) {\n const encrypted = this.encryptSymmetric(buffer);\n return Buffer.from(encrypted, 'base64');\n }\n\n if (this.isRSA()) {\n const encrypted = this.encryptAsymmetric(buffer);\n return Buffer.from(encrypted, 'base64');\n }\n\n throw new EncryptError(\n `Unsupported encryption algorithm: ${this.options.algorithm}`,\n this.adapterType,\n );\n } catch (error) {\n if (error instanceof EncryptError) throw error;\n throw new EncryptError(\n `Failed to encrypt buffer: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async decryptBuffer(\n buffer: Buffer,\n options?: DecryptOptions,\n ): Promise<Buffer> {\n try {\n this.log('Decrypting buffer', { size: buffer.length });\n\n const base64 = buffer.toString('base64');\n\n if (this.isSymmetric()) {\n return this.decryptSymmetric(base64);\n }\n\n if (this.isRSA()) {\n return this.decryptAsymmetric(base64);\n }\n\n throw new DecryptError(\n `Unsupported decryption algorithm: ${this.options.algorithm}`,\n this.adapterType,\n );\n } catch (error) {\n if (error instanceof DecryptError) throw error;\n throw new DecryptError(\n `Failed to decrypt buffer: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Symmetric encryption (AES)\n */\n private encryptSymmetric(data: Buffer): string {\n if (!this.key) {\n throw new KeyError(\n 'Encryption key required for symmetric encryption',\n this.adapterType,\n );\n }\n\n const algorithm = this.options.algorithm;\n const isGCM = algorithm.toLowerCase().includes('gcm');\n\n // Generate IV\n const ivLength = isGCM ? 12 : 16; // GCM uses 12 bytes, CBC uses 16\n const iv = this.options.iv\n ? this.parseBuffer(this.options.iv)\n : crypto.randomBytes(ivLength);\n\n // Create cipher\n const cipher = crypto.createCipheriv(algorithm, this.key, iv);\n\n // Encrypt\n const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);\n\n // For GCM, get auth tag\n let authTag: Buffer | undefined;\n if (isGCM) {\n authTag = (cipher as crypto.CipherGCM).getAuthTag();\n }\n\n // Combine: iv + (authTag if GCM) + encrypted\n let result: Buffer;\n if (authTag) {\n result = Buffer.concat([iv, authTag, encrypted]);\n } else {\n result = Buffer.concat([iv, encrypted]);\n }\n\n return result.toString('base64');\n }\n\n /**\n * Symmetric decryption (AES)\n */\n private decryptSymmetric(encrypted: string): Buffer {\n if (!this.key) {\n throw new KeyError(\n 'Decryption key required for symmetric decryption',\n this.adapterType,\n );\n }\n\n const algorithm = this.options.algorithm;\n const isGCM = algorithm.toLowerCase().includes('gcm');\n\n const encryptedBuffer = Buffer.from(encrypted, 'base64');\n\n // Extract IV\n const ivLength = isGCM ? 12 : 16;\n const iv = encryptedBuffer.subarray(0, ivLength);\n\n // Extract auth tag if GCM\n let authTag: Buffer | undefined;\n let ciphertext: Buffer;\n if (isGCM) {\n authTag = encryptedBuffer.subarray(ivLength, ivLength + 16);\n ciphertext = encryptedBuffer.subarray(ivLength + 16);\n } else {\n ciphertext = encryptedBuffer.subarray(ivLength);\n }\n\n // Create decipher\n const decipher = crypto.createDecipheriv(algorithm, this.key, iv);\n\n // Set auth tag for GCM\n if (authTag) {\n (decipher as crypto.DecipherGCM).setAuthTag(authTag);\n }\n\n // Decrypt\n const decrypted = Buffer.concat([\n decipher.update(ciphertext),\n decipher.final(),\n ]);\n\n return decrypted;\n }\n\n /**\n * Asymmetric encryption (RSA)\n */\n private encryptAsymmetric(data: Buffer): string {\n if (!this.publicKey) {\n throw new KeyError(\n 'Public key required for asymmetric encryption',\n this.adapterType,\n );\n }\n\n const encrypted = crypto.publicEncrypt(\n {\n key: this.publicKey,\n padding: this.getRSAPadding(),\n },\n data,\n );\n\n return encrypted.toString('base64');\n }\n\n /**\n * Asymmetric decryption (RSA)\n */\n private decryptAsymmetric(encrypted: string): Buffer {\n if (!this.privateKey) {\n throw new KeyError(\n 'Private key required for asymmetric decryption',\n this.adapterType,\n );\n }\n\n const encryptedBuffer = Buffer.from(encrypted, 'base64');\n\n const decrypted = crypto.privateDecrypt(\n {\n key: this.privateKey,\n padding: this.getRSAPadding(),\n },\n encryptedBuffer,\n );\n\n return decrypted;\n }\n\n /**\n * Get RSA padding mode\n */\n private getRSAPadding(): number {\n const algo = this.options.algorithm.toLowerCase();\n if (algo.includes('oaep')) {\n return crypto.constants.RSA_PKCS1_OAEP_PADDING;\n }\n if (algo.includes('pss')) {\n return crypto.constants.RSA_PKCS1_PSS_PADDING;\n }\n return crypto.constants.RSA_PKCS1_PADDING;\n }\n\n async generateKeyPair(options?: KeyPairOptions): Promise<KeyPair> {\n try {\n this.log('Generating key pair', options);\n\n const keyType = options?.type || 'rsa';\n\n if (keyType === 'rsa') {\n const modulusLength = options?.keySize || 2048;\n const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {\n modulusLength,\n publicKeyEncoding: {\n type: 'spki',\n format: 'pem',\n },\n privateKeyEncoding: {\n type: 'pkcs8',\n format: 'pem',\n ...(options?.passphrase && {\n cipher: 'aes-256-cbc',\n passphrase: options.passphrase,\n }),\n },\n });\n\n this.log('RSA key pair generated');\n\n return { publicKey, privateKey };\n }\n\n if (keyType === 'ecc' || keyType === 'ecdh') {\n const curve = options?.curve || 'prime256v1';\n const { publicKey, privateKey } = crypto.generateKeyPairSync('ec', {\n namedCurve: curve,\n publicKeyEncoding: {\n type: 'spki',\n format: 'pem',\n },\n privateKeyEncoding: {\n type: 'pkcs8',\n format: 'pem',\n ...(options?.passphrase && {\n cipher: 'aes-256-cbc',\n passphrase: options.passphrase,\n }),\n },\n });\n\n this.log('EC key pair generated');\n\n return { publicKey, privateKey };\n }\n\n if (keyType === 'ecdsa') {\n const curve = options?.curve || 'prime256v1';\n const { publicKey, privateKey } = crypto.generateKeyPairSync('ec', {\n namedCurve: curve,\n publicKeyEncoding: {\n type: 'spki',\n format: 'pem',\n },\n privateKeyEncoding: {\n type: 'pkcs8',\n format: 'pem',\n ...(options?.passphrase && {\n cipher: 'aes-256-cbc',\n passphrase: options.passphrase,\n }),\n },\n });\n\n this.log('ECDSA key pair generated');\n\n return { publicKey, privateKey };\n }\n\n throw new KeyError(\n `Unsupported key type for Node crypto: ${keyType}`,\n this.adapterType,\n );\n } catch (error) {\n throw new KeyError(\n `Failed to generate key pair: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async importKey(\n key: string | Buffer,\n options?: ImportKeyOptions,\n ): Promise<Key> {\n try {\n this.log('Importing key');\n\n const keyType = options?.type || 'public';\n\n if (keyType === 'public') {\n const keyObj = crypto.createPublicKey(key);\n const exported = keyObj.export({\n type: 'spki',\n format: 'pem',\n });\n\n return {\n type: 'public',\n format: 'pem',\n data: exported.toString(),\n algorithm: 'node',\n };\n }\n\n if (keyType === 'private') {\n const keyObj = options?.passphrase\n ? crypto.createPrivateKey({ key, passphrase: options.passphrase })\n : crypto.createPrivateKey(key);\n\n const exported = keyObj.export({\n type: 'pkcs8',\n format: 'pem',\n });\n\n return {\n type: 'private',\n format: 'pem',\n data: exported.toString(),\n algorithm: 'node',\n };\n }\n\n throw new InvalidKeyError(\n `Unsupported key type: ${keyType}`,\n this.adapterType,\n );\n } catch (error) {\n throw new InvalidKeyError(\n `Failed to import key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async exportKey(\n key: Key,\n options?: ExportKeyOptions,\n ): Promise<string | Buffer> {\n try {\n this.log('Exporting key');\n\n const format = options?.format || key.format || 'pem';\n\n if (format === 'pem' || format === 'armored') {\n return key.data as string;\n }\n\n if (format === 'binary' || format === 'der') {\n if (typeof key.data === 'string') {\n return Buffer.from(key.data);\n }\n return key.data as Buffer;\n }\n\n return key.data as string;\n } catch (error) {\n throw new KeyError(\n `Failed to export key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Sign data\n */\n async sign(\n data: string | Buffer,\n options?: SignOptions,\n ): Promise<string | Buffer> {\n try {\n this.log('Signing data');\n\n const privateKey = options?.privateKey\n ? this.importPrivateKeyObject(\n options.privateKey as string | Buffer,\n options.passphrase,\n )\n : this.privateKey;\n\n if (!privateKey) {\n throw new KeyError(\n 'No private key available for signing',\n this.adapterType,\n );\n }\n\n const message =\n typeof data === 'string' ? Buffer.from(data, 'utf8') : data;\n\n const signature = crypto.sign(null, message, privateKey);\n\n this.log('Data signed successfully');\n\n if (typeof data === 'string') {\n return signature.toString('base64');\n }\n\n return signature;\n } catch (error) {\n throw new SignatureError(\n `Failed to sign data: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Verify signature\n */\n async verify(\n data: string | Buffer,\n signature: string | Buffer,\n options?: VerifyOptions,\n ): Promise<boolean> {\n try {\n this.log('Verifying signature');\n\n if (!options?.publicKey) {\n return false;\n }\n\n const publicKey = this.importPublicKeyObject(\n options.publicKey as string | Buffer,\n );\n\n const message =\n typeof data === 'string' ? Buffer.from(data, 'utf8') : data;\n const sig =\n typeof signature === 'string'\n ? Buffer.from(signature, 'base64')\n : signature;\n\n const valid = crypto.verify(null, message, publicKey, sig);\n\n this.log(valid ? 'Signature verified' : 'Signature verification failed');\n\n return valid;\n } catch (error) {\n this.log('Signature verification failed', error);\n return false;\n }\n }\n\n async getCapabilities(): Promise<EncryptionCapabilities> {\n const algorithm = this.options.algorithm.toLowerCase();\n\n // Determine if algorithm is symmetric or asymmetric\n const symmetricAlgorithms = [\n 'aes-256-gcm',\n 'aes-256-cbc',\n 'aes-128-gcm',\n 'aes-128-cbc',\n ];\n const asymmetricAlgorithms = [\n 'rsa',\n 'rsa-oaep',\n 'rsa-pss',\n 'ecdh',\n 'ecdsa',\n ];\n\n const isSymmetric = symmetricAlgorithms.includes(algorithm);\n const isAsymmetric = asymmetricAlgorithms.some((algo) =>\n algorithm.includes(algo),\n );\n\n return {\n textEncryption: true,\n fileEncryption: true,\n bufferEncryption: true,\n streamEncryption: true,\n emailEncryption: false,\n signing: true,\n verification: true,\n keyGeneration: true,\n keyManagement: true,\n multipleRecipients: false,\n symmetricEncryption: isSymmetric,\n asymmetricEncryption: isAsymmetric,\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"node-9IJG40yb.js","names":[],"sources":["../../src/adapters/node.ts"],"sourcesContent":["import * as crypto from 'node:crypto';\nimport { BaseEncryption } from '../shared/base.js';\nimport {\n DecryptError,\n EncryptError,\n InvalidKeyError,\n KeyError,\n SignatureError,\n} from '../shared/errors.js';\nimport type {\n DecryptOptions,\n EncryptionCapabilities,\n EncryptOptions,\n ExportKeyOptions,\n ImportKeyOptions,\n Key,\n KeyPair,\n KeyPairOptions,\n NodeCryptoOptions,\n SignOptions,\n VerifyOptions,\n} from '../shared/types.js';\n\n/**\n * Node.js crypto adapter\n *\n * Uses Node.js built-in crypto module for standard encryption algorithms\n * (AES, RSA, ECDH, ECDSA, etc.).\n *\n * @example\n * ```typescript\n * const crypto = new NodeCryptoEncryption({\n * type: 'node',\n * algorithm: 'aes-256-gcm',\n * key: encryptionKey\n * });\n *\n * const encrypted = await crypto.encryptText('Secret message');\n * const decrypted = await crypto.decryptText(encrypted);\n * ```\n */\nexport class NodeCryptoEncryption extends BaseEncryption {\n private options: NodeCryptoOptions;\n private key?: Buffer;\n private publicKey?: crypto.KeyObject;\n private privateKey?: crypto.KeyObject;\n\n constructor(options: NodeCryptoOptions) {\n super('node', options.debug);\n this.options = options;\n this.initializeKeys();\n }\n\n /**\n * Initialize keys from options\n */\n private initializeKeys(): void {\n // Derive key from password if specified\n if (this.options.keyDerivation) {\n this.key = this.deriveKey(this.options.keyDerivation);\n } else if (this.options.key) {\n this.key = this.parseBuffer(this.options.key);\n }\n\n // Initialize asymmetric keys\n if (this.options.publicKey) {\n this.publicKey = this.importPublicKeyObject(this.options.publicKey);\n }\n\n if (this.options.privateKey) {\n this.privateKey = this.importPrivateKeyObject(\n this.options.privateKey,\n this.options.passphrase,\n );\n }\n }\n\n /**\n * Derive key from password using PBKDF2\n */\n private deriveKey(\n derivation: NonNullable<NodeCryptoOptions['keyDerivation']>,\n ): Buffer {\n const salt = derivation.salt\n ? this.parseBuffer(derivation.salt)\n : crypto.randomBytes(16);\n const iterations = derivation.iterations || 100000;\n const keyLength = derivation.keyLength || this.getKeyLength();\n const digest = derivation.digest || 'sha256';\n\n return crypto.pbkdf2Sync(\n derivation.password,\n salt,\n iterations,\n keyLength,\n digest,\n );\n }\n\n /**\n * Get key length for current algorithm\n */\n private getKeyLength(): number {\n const algo = this.options.algorithm.toLowerCase();\n if (algo.includes('256')) return 32;\n if (algo.includes('192')) return 24;\n if (algo.includes('128')) return 16;\n return 32; // Default to 256 bits\n }\n\n /**\n * Parse buffer from string or Buffer\n */\n private parseBuffer(data: string | Buffer): Buffer {\n if (Buffer.isBuffer(data)) return data;\n\n const encoding = this.options.encoding || 'hex';\n if (encoding === 'hex') return Buffer.from(data, 'hex');\n if (encoding === 'base64') return Buffer.from(data, 'base64');\n if (encoding === 'utf8') return Buffer.from(data, 'utf8');\n\n return Buffer.from(data, 'hex');\n }\n\n /**\n * Import public key from PEM/DER\n */\n private importPublicKeyObject(key: string | Buffer): crypto.KeyObject {\n try {\n return crypto.createPublicKey(key);\n } catch (error) {\n throw new InvalidKeyError(\n `Failed to import public key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Import private key from PEM/DER\n */\n private importPrivateKeyObject(\n key: string | Buffer,\n passphrase?: string,\n ): crypto.KeyObject {\n try {\n if (passphrase) {\n return crypto.createPrivateKey({ key, passphrase });\n }\n return crypto.createPrivateKey(key);\n } catch (error) {\n throw new InvalidKeyError(\n `Failed to import private key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Check if algorithm is symmetric (AES)\n */\n private isSymmetric(): boolean {\n const algo = this.options.algorithm.toLowerCase();\n return algo.startsWith('aes-') || algo.includes('cipher');\n }\n\n /**\n * Check if algorithm is RSA\n */\n private isRSA(): boolean {\n const algo = this.options.algorithm.toLowerCase();\n return algo.startsWith('rsa');\n }\n\n async encryptText(text: string, options?: EncryptOptions): Promise<string> {\n try {\n this.log('Encrypting text', { length: text.length });\n\n if (this.isSymmetric()) {\n return this.encryptSymmetric(Buffer.from(text, 'utf8'));\n }\n\n if (this.isRSA()) {\n return this.encryptAsymmetric(Buffer.from(text, 'utf8'));\n }\n\n throw new EncryptError(\n `Unsupported encryption algorithm: ${this.options.algorithm}`,\n this.adapterType,\n );\n } catch (error) {\n if (error instanceof EncryptError) throw error;\n throw new EncryptError(\n `Failed to encrypt text: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async decryptText(\n encrypted: string,\n options?: DecryptOptions,\n ): Promise<string> {\n try {\n this.log('Decrypting text', { length: encrypted.length });\n\n if (this.isSymmetric()) {\n const decrypted = this.decryptSymmetric(encrypted);\n return decrypted.toString('utf8');\n }\n\n if (this.isRSA()) {\n const decrypted = this.decryptAsymmetric(encrypted);\n return decrypted.toString('utf8');\n }\n\n throw new DecryptError(\n `Unsupported decryption algorithm: ${this.options.algorithm}`,\n this.adapterType,\n );\n } catch (error) {\n if (error instanceof DecryptError) throw error;\n throw new DecryptError(\n `Failed to decrypt text: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async encryptBuffer(\n buffer: Buffer,\n options?: EncryptOptions,\n ): Promise<Buffer> {\n try {\n this.log('Encrypting buffer', { size: buffer.length });\n\n if (this.isSymmetric()) {\n const encrypted = this.encryptSymmetric(buffer);\n return Buffer.from(encrypted, 'base64');\n }\n\n if (this.isRSA()) {\n const encrypted = this.encryptAsymmetric(buffer);\n return Buffer.from(encrypted, 'base64');\n }\n\n throw new EncryptError(\n `Unsupported encryption algorithm: ${this.options.algorithm}`,\n this.adapterType,\n );\n } catch (error) {\n if (error instanceof EncryptError) throw error;\n throw new EncryptError(\n `Failed to encrypt buffer: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async decryptBuffer(\n buffer: Buffer,\n options?: DecryptOptions,\n ): Promise<Buffer> {\n try {\n this.log('Decrypting buffer', { size: buffer.length });\n\n const base64 = buffer.toString('base64');\n\n if (this.isSymmetric()) {\n return this.decryptSymmetric(base64);\n }\n\n if (this.isRSA()) {\n return this.decryptAsymmetric(base64);\n }\n\n throw new DecryptError(\n `Unsupported decryption algorithm: ${this.options.algorithm}`,\n this.adapterType,\n );\n } catch (error) {\n if (error instanceof DecryptError) throw error;\n throw new DecryptError(\n `Failed to decrypt buffer: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Symmetric encryption (AES)\n */\n private encryptSymmetric(data: Buffer): string {\n if (!this.key) {\n throw new KeyError(\n 'Encryption key required for symmetric encryption',\n this.adapterType,\n );\n }\n\n const algorithm = this.options.algorithm;\n const isGCM = algorithm.toLowerCase().includes('gcm');\n\n // Generate IV\n const ivLength = isGCM ? 12 : 16; // GCM uses 12 bytes, CBC uses 16\n const iv = this.options.iv\n ? this.parseBuffer(this.options.iv)\n : crypto.randomBytes(ivLength);\n\n // Create cipher\n const cipher = crypto.createCipheriv(algorithm, this.key, iv);\n\n // Encrypt\n const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);\n\n // For GCM, get auth tag\n let authTag: Buffer | undefined;\n if (isGCM) {\n authTag = (cipher as crypto.CipherGCM).getAuthTag();\n }\n\n // Combine: iv + (authTag if GCM) + encrypted\n let result: Buffer;\n if (authTag) {\n result = Buffer.concat([iv, authTag, encrypted]);\n } else {\n result = Buffer.concat([iv, encrypted]);\n }\n\n return result.toString('base64');\n }\n\n /**\n * Symmetric decryption (AES)\n */\n private decryptSymmetric(encrypted: string): Buffer {\n if (!this.key) {\n throw new KeyError(\n 'Decryption key required for symmetric decryption',\n this.adapterType,\n );\n }\n\n const algorithm = this.options.algorithm;\n const isGCM = algorithm.toLowerCase().includes('gcm');\n\n const encryptedBuffer = Buffer.from(encrypted, 'base64');\n\n // Extract IV\n const ivLength = isGCM ? 12 : 16;\n const iv = encryptedBuffer.subarray(0, ivLength);\n\n // Extract auth tag if GCM\n let authTag: Buffer | undefined;\n let ciphertext: Buffer;\n if (isGCM) {\n authTag = encryptedBuffer.subarray(ivLength, ivLength + 16);\n ciphertext = encryptedBuffer.subarray(ivLength + 16);\n } else {\n ciphertext = encryptedBuffer.subarray(ivLength);\n }\n\n // Create decipher\n const decipher = crypto.createDecipheriv(algorithm, this.key, iv);\n\n // Set auth tag for GCM\n if (authTag) {\n (decipher as crypto.DecipherGCM).setAuthTag(authTag);\n }\n\n // Decrypt\n const decrypted = Buffer.concat([\n decipher.update(ciphertext),\n decipher.final(),\n ]);\n\n return decrypted;\n }\n\n /**\n * Asymmetric encryption (RSA)\n */\n private encryptAsymmetric(data: Buffer): string {\n if (!this.publicKey) {\n throw new KeyError(\n 'Public key required for asymmetric encryption',\n this.adapterType,\n );\n }\n\n const encrypted = crypto.publicEncrypt(\n {\n key: this.publicKey,\n padding: this.getRSAPadding(),\n },\n data,\n );\n\n return encrypted.toString('base64');\n }\n\n /**\n * Asymmetric decryption (RSA)\n */\n private decryptAsymmetric(encrypted: string): Buffer {\n if (!this.privateKey) {\n throw new KeyError(\n 'Private key required for asymmetric decryption',\n this.adapterType,\n );\n }\n\n const encryptedBuffer = Buffer.from(encrypted, 'base64');\n\n const decrypted = crypto.privateDecrypt(\n {\n key: this.privateKey,\n padding: this.getRSAPadding(),\n },\n encryptedBuffer,\n );\n\n return decrypted;\n }\n\n /**\n * Get RSA padding mode\n */\n private getRSAPadding(): number {\n const algo = this.options.algorithm.toLowerCase();\n if (algo.includes('oaep')) {\n return crypto.constants.RSA_PKCS1_OAEP_PADDING;\n }\n if (algo.includes('pss')) {\n return crypto.constants.RSA_PKCS1_PSS_PADDING;\n }\n return crypto.constants.RSA_PKCS1_PADDING;\n }\n\n async generateKeyPair(options?: KeyPairOptions): Promise<KeyPair> {\n try {\n this.log('Generating key pair', options);\n\n const keyType = options?.type || 'rsa';\n\n if (keyType === 'rsa') {\n const modulusLength = options?.keySize || 2048;\n const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {\n modulusLength,\n publicKeyEncoding: {\n type: 'spki',\n format: 'pem',\n },\n privateKeyEncoding: {\n type: 'pkcs8',\n format: 'pem',\n ...(options?.passphrase && {\n cipher: 'aes-256-cbc',\n passphrase: options.passphrase,\n }),\n },\n });\n\n this.log('RSA key pair generated');\n\n return { publicKey, privateKey };\n }\n\n if (keyType === 'ecc' || keyType === 'ecdh') {\n const curve = options?.curve || 'prime256v1';\n const { publicKey, privateKey } = crypto.generateKeyPairSync('ec', {\n namedCurve: curve,\n publicKeyEncoding: {\n type: 'spki',\n format: 'pem',\n },\n privateKeyEncoding: {\n type: 'pkcs8',\n format: 'pem',\n ...(options?.passphrase && {\n cipher: 'aes-256-cbc',\n passphrase: options.passphrase,\n }),\n },\n });\n\n this.log('EC key pair generated');\n\n return { publicKey, privateKey };\n }\n\n if (keyType === 'ecdsa') {\n const curve = options?.curve || 'prime256v1';\n const { publicKey, privateKey } = crypto.generateKeyPairSync('ec', {\n namedCurve: curve,\n publicKeyEncoding: {\n type: 'spki',\n format: 'pem',\n },\n privateKeyEncoding: {\n type: 'pkcs8',\n format: 'pem',\n ...(options?.passphrase && {\n cipher: 'aes-256-cbc',\n passphrase: options.passphrase,\n }),\n },\n });\n\n this.log('ECDSA key pair generated');\n\n return { publicKey, privateKey };\n }\n\n throw new KeyError(\n `Unsupported key type for Node crypto: ${keyType}`,\n this.adapterType,\n );\n } catch (error) {\n throw new KeyError(\n `Failed to generate key pair: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async importKey(\n key: string | Buffer,\n options?: ImportKeyOptions,\n ): Promise<Key> {\n try {\n this.log('Importing key');\n\n const keyType = options?.type || 'public';\n\n if (keyType === 'public') {\n const keyObj = crypto.createPublicKey(key);\n const exported = keyObj.export({\n type: 'spki',\n format: 'pem',\n });\n\n return {\n type: 'public',\n format: 'pem',\n data: exported.toString(),\n algorithm: 'node',\n };\n }\n\n if (keyType === 'private') {\n const keyObj = options?.passphrase\n ? crypto.createPrivateKey({ key, passphrase: options.passphrase })\n : crypto.createPrivateKey(key);\n\n const exported = keyObj.export({\n type: 'pkcs8',\n format: 'pem',\n });\n\n return {\n type: 'private',\n format: 'pem',\n data: exported.toString(),\n algorithm: 'node',\n };\n }\n\n throw new InvalidKeyError(\n `Unsupported key type: ${keyType}`,\n this.adapterType,\n );\n } catch (error) {\n throw new InvalidKeyError(\n `Failed to import key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async exportKey(\n key: Key,\n options?: ExportKeyOptions,\n ): Promise<string | Buffer> {\n try {\n this.log('Exporting key');\n\n const format = options?.format || key.format || 'pem';\n\n if (format === 'pem' || format === 'armored') {\n return key.data as string;\n }\n\n if (format === 'binary' || format === 'der') {\n if (typeof key.data === 'string') {\n return Buffer.from(key.data);\n }\n return key.data as Buffer;\n }\n\n return key.data as string;\n } catch (error) {\n throw new KeyError(\n `Failed to export key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Sign data\n */\n async sign(\n data: string | Buffer,\n options?: SignOptions,\n ): Promise<string | Buffer> {\n try {\n this.log('Signing data');\n\n const privateKey = options?.privateKey\n ? this.importPrivateKeyObject(\n options.privateKey as string | Buffer,\n options.passphrase,\n )\n : this.privateKey;\n\n if (!privateKey) {\n throw new KeyError(\n 'No private key available for signing',\n this.adapterType,\n );\n }\n\n const message =\n typeof data === 'string' ? Buffer.from(data, 'utf8') : data;\n\n const signature = crypto.sign(null, message, privateKey);\n\n this.log('Data signed successfully');\n\n if (typeof data === 'string') {\n return signature.toString('base64');\n }\n\n return signature;\n } catch (error) {\n throw new SignatureError(\n `Failed to sign data: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Verify signature\n */\n async verify(\n data: string | Buffer,\n signature: string | Buffer,\n options?: VerifyOptions,\n ): Promise<boolean> {\n try {\n this.log('Verifying signature');\n\n if (!options?.publicKey) {\n return false;\n }\n\n const publicKey = this.importPublicKeyObject(\n options.publicKey as string | Buffer,\n );\n\n const message =\n typeof data === 'string' ? Buffer.from(data, 'utf8') : data;\n const sig =\n typeof signature === 'string'\n ? Buffer.from(signature, 'base64')\n : signature;\n\n const valid = crypto.verify(null, message, publicKey, sig);\n\n this.log(valid ? 'Signature verified' : 'Signature verification failed');\n\n return valid;\n } catch (error) {\n this.log('Signature verification failed', error);\n return false;\n }\n }\n\n async getCapabilities(): Promise<EncryptionCapabilities> {\n const algorithm = this.options.algorithm.toLowerCase();\n\n // Determine if algorithm is symmetric or asymmetric\n const symmetricAlgorithms = [\n 'aes-256-gcm',\n 'aes-256-cbc',\n 'aes-128-gcm',\n 'aes-128-cbc',\n ];\n const asymmetricAlgorithms = [\n 'rsa',\n 'rsa-oaep',\n 'rsa-pss',\n 'ecdh',\n 'ecdsa',\n ];\n\n const isSymmetric = symmetricAlgorithms.includes(algorithm);\n const isAsymmetric = asymmetricAlgorithms.some((algo) =>\n algorithm.includes(algo),\n );\n\n return {\n textEncryption: true,\n fileEncryption: true,\n bufferEncryption: true,\n streamEncryption: true,\n emailEncryption: false,\n signing: true,\n verification: true,\n keyGeneration: true,\n keyManagement: true,\n multipleRecipients: false,\n symmetricEncryption: isSymmetric,\n asymmetricEncryption: isAsymmetric,\n };\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- import { c as KeyError, d as SignatureError, f as VerificationError, i as EncryptError, r as DecryptError, s as InvalidKeyError, t as BaseEncryption, u as PassphraseError } from "./base-qiu-WiZ0.js";
1
+ import { d as VerificationError, l as PassphraseError, n as DecryptError, o as InvalidKeyError, r as EncryptError, s as KeyError, u as SignatureError } from "./errors-Q_wX_NMz.js";
2
+ import { t as BaseEncryption } from "./base-COUQhj5x.js";
2
3
  import * as openpgp from "openpgp";
3
4
  //#region src/adapters/pgp.ts
4
5
  /**
@@ -645,4 +646,4 @@ var PGPEncryption = class extends BaseEncryption {
645
646
  //#endregion
646
647
  export { PGPEncryption };
647
648
 
648
- //# sourceMappingURL=pgp-rwlJTWLC.js.map
649
+ //# sourceMappingURL=pgp-Dss_W-gt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pgp-rwlJTWLC.js","names":[],"sources":["../../src/adapters/pgp.ts"],"sourcesContent":["import * as openpgp from 'openpgp';\nimport { BaseEncryption } from '../shared/base.js';\nimport {\n DecryptError,\n EncryptError,\n InvalidKeyError,\n KeyError,\n PassphraseError,\n SignatureError,\n VerificationError,\n} from '../shared/errors.js';\nimport type {\n DecryptOptions,\n EncryptionCapabilities,\n EncryptOptions,\n ExportKeyOptions,\n ImportKeyOptions,\n Key,\n KeyPair,\n KeyPairOptions,\n PGPOptions,\n SignOptions,\n VerifyOptions,\n} from '../shared/types.js';\n\n/**\n * PGP/OpenPGP encryption adapter\n *\n * Uses OpenPGP.js for encryption, decryption, signing, and key management.\n *\n * @example\n * ```typescript\n * const pgp = new PGPEncryption({\n * type: 'pgp',\n * publicKey: recipientPublicKey,\n * privateKey: myPrivateKey,\n * passphrase: 'my-passphrase'\n * });\n *\n * const encrypted = await pgp.encryptText('Secret message');\n * const decrypted = await pgp.decryptText(encrypted);\n * ```\n */\nexport class PGPEncryption extends BaseEncryption {\n private options: PGPOptions;\n private publicKeys?: openpgp.PublicKey[];\n private privateKeys?: openpgp.PrivateKey[];\n\n constructor(options: PGPOptions) {\n super('pgp', options.debug);\n this.options = options;\n }\n\n /**\n * Initialize keys from options\n */\n private async initializeKeys(): Promise<void> {\n if (this.publicKeys || this.privateKeys) {\n return; // Already initialized\n }\n\n try {\n // Load public keys\n if (this.options.publicKey) {\n const key = await openpgp.readKey({\n armoredKey: this.options.publicKey,\n });\n this.publicKeys = [key];\n } else if (this.options.publicKeys) {\n this.publicKeys = await Promise.all(\n this.options.publicKeys.map((k) =>\n openpgp.readKey({ armoredKey: k }),\n ),\n );\n }\n\n // Load private keys\n if (this.options.privateKey) {\n const key = await openpgp.readPrivateKey({\n armoredKey: this.options.privateKey,\n });\n\n // Decrypt private key if passphrase provided\n if (this.options.passphrase) {\n const decryptedKey = await openpgp.decryptKey({\n privateKey: key,\n passphrase: this.options.passphrase,\n });\n this.privateKeys = [decryptedKey];\n } else {\n this.privateKeys = [key];\n }\n } else if (this.options.privateKeys) {\n this.privateKeys = await Promise.all(\n this.options.privateKeys.map(async (k) => {\n const key = await openpgp.readPrivateKey({ armoredKey: k });\n if (this.options.passphrase) {\n return openpgp.decryptKey({\n privateKey: key,\n passphrase: this.options.passphrase,\n });\n }\n return key;\n }),\n );\n }\n } catch (error) {\n throw new KeyError(\n `Failed to initialize PGP keys: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Get public keys for encryption\n */\n private async getPublicKeys(\n options?: EncryptOptions,\n ): Promise<openpgp.PublicKey[]> {\n await this.initializeKeys();\n\n // Options override default keys\n if (options?.publicKeys) {\n return Promise.all(\n options.publicKeys.map((k) => openpgp.readKey({ armoredKey: k })),\n );\n }\n\n if (!this.publicKeys || this.publicKeys.length === 0) {\n throw new KeyError(\n 'No public keys available for encryption',\n this.adapterType,\n );\n }\n\n return this.publicKeys;\n }\n\n /**\n * Get private keys for decryption\n */\n private async getPrivateKeys(\n options?: DecryptOptions,\n ): Promise<openpgp.PrivateKey[]> {\n await this.initializeKeys();\n\n // Options override default keys\n if (options?.privateKey) {\n const key = await openpgp.readPrivateKey({\n armoredKey: options.privateKey as string,\n });\n\n if (options.passphrase) {\n const decryptedKey = await openpgp.decryptKey({\n privateKey: key,\n passphrase: options.passphrase,\n });\n return [decryptedKey];\n }\n\n return [key];\n }\n\n if (!this.privateKeys || this.privateKeys.length === 0) {\n throw new KeyError(\n 'No private keys available for decryption',\n this.adapterType,\n );\n }\n\n return this.privateKeys;\n }\n\n async encryptText(text: string, options?: EncryptOptions): Promise<string> {\n try {\n this.log('Encrypting text', { length: text.length });\n this.validateEncryptOptions(options);\n\n const publicKeys = await this.getPublicKeys(options);\n\n const format =\n options?.armor !== false ? ('armored' as const) : ('binary' as const);\n\n const encryptConfig: any = {\n message: await openpgp.createMessage({ text }),\n encryptionKeys: publicKeys,\n format,\n };\n\n // Add signing if requested\n if (options?.sign && options?.privateKey) {\n const signingKey = await openpgp.readPrivateKey({\n armoredKey: options.privateKey as string,\n });\n\n if (this.options.passphrase) {\n encryptConfig.signingKeys = await openpgp.decryptKey({\n privateKey: signingKey,\n passphrase: this.options.passphrase,\n });\n } else {\n encryptConfig.signingKeys = signingKey;\n }\n } else if (options?.sign && this.privateKeys) {\n encryptConfig.signingKeys = this.privateKeys;\n }\n\n const encrypted = await openpgp.encrypt(encryptConfig);\n\n this.log('Text encrypted successfully');\n\n // Convert binary output to base64 string for text encryption\n if (format === 'binary' && encrypted instanceof Uint8Array) {\n return Buffer.from(encrypted).toString('base64');\n }\n\n return encrypted as string;\n } catch (error) {\n throw new EncryptError(\n `Failed to encrypt text: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async decryptText(\n encrypted: string,\n options?: DecryptOptions,\n ): Promise<string> {\n try {\n this.log('Decrypting text', { length: encrypted.length });\n this.validateDecryptOptions(options);\n\n const privateKeys = await this.getPrivateKeys(options);\n\n // Try to read as armored message first, fallback to binary\n let message: openpgp.Message<any>;\n try {\n message = await openpgp.readMessage({\n armoredMessage: encrypted,\n });\n } catch {\n // If armored fails, try base64-encoded binary\n try {\n message = await openpgp.readMessage({\n binaryMessage: Buffer.from(encrypted, 'base64'),\n });\n } catch {\n // Last resort: try raw binary\n message = await openpgp.readMessage({\n binaryMessage: Buffer.from(encrypted, 'binary'),\n });\n }\n }\n\n const decryptConfig: openpgp.DecryptOptions = {\n message,\n decryptionKeys: privateKeys,\n format: 'utf8',\n };\n\n // Add verification if requested\n if (options?.verify && options?.publicKey) {\n if (typeof options.publicKey === 'string') {\n decryptConfig.verificationKeys = await openpgp.readKey({\n armoredKey: options.publicKey,\n });\n } else {\n throw new InvalidKeyError(\n 'PGP verification requires armored public key string',\n this.adapterType,\n );\n }\n }\n\n const result = await openpgp.decrypt(decryptConfig);\n\n // Verify signature if requested\n if (options?.verify && result.signatures) {\n try {\n await result.signatures[0].verified;\n this.log('Signature verified successfully');\n } catch (error) {\n throw new VerificationError(\n 'Signature verification failed',\n this.adapterType,\n error,\n );\n }\n }\n\n this.log('Text decrypted successfully');\n return result.data as string;\n } catch (error) {\n if (error instanceof VerificationError) {\n throw error;\n }\n throw new DecryptError(\n `Failed to decrypt text: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async encryptBuffer(\n buffer: Buffer,\n options?: EncryptOptions,\n ): Promise<Buffer> {\n try {\n this.log('Encrypting buffer', { size: buffer.length });\n this.validateEncryptOptions(options);\n\n const publicKeys = await this.getPublicKeys(options);\n\n const format =\n options?.armor === true ? ('armored' as const) : ('binary' as const);\n\n const encryptConfig: any = {\n message: await openpgp.createMessage({ binary: buffer }),\n encryptionKeys: publicKeys,\n format,\n };\n\n // Add signing if requested\n if (options?.sign && options?.privateKey) {\n const signingKey = await openpgp.readPrivateKey({\n armoredKey: options.privateKey as string,\n });\n\n if (this.options.passphrase) {\n encryptConfig.signingKeys = await openpgp.decryptKey({\n privateKey: signingKey,\n passphrase: this.options.passphrase,\n });\n } else {\n encryptConfig.signingKeys = signingKey;\n }\n } else if (options?.sign && this.privateKeys) {\n encryptConfig.signingKeys = this.privateKeys;\n }\n\n const encrypted = await openpgp.encrypt(encryptConfig);\n\n this.log('Buffer encrypted successfully');\n\n if (typeof encrypted === 'string') {\n return Buffer.from(encrypted);\n }\n\n // Handle Uint8Array, WebStream, or NodeWebStream\n if (encrypted instanceof Uint8Array) {\n return Buffer.from(encrypted);\n }\n\n // Fallback for stream types (shouldn't happen with current config)\n return Buffer.from(encrypted as any);\n } catch (error) {\n throw new EncryptError(\n `Failed to encrypt buffer: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async decryptBuffer(\n buffer: Buffer,\n options?: DecryptOptions,\n ): Promise<Buffer> {\n try {\n this.log('Decrypting buffer', { size: buffer.length });\n this.validateDecryptOptions(options);\n\n const privateKeys = await this.getPrivateKeys(options);\n\n // Try to read as armored message first, fallback to binary\n let message: any;\n try {\n message = await openpgp.readMessage({\n armoredMessage: buffer.toString('utf8'),\n });\n } catch {\n message = await openpgp.readMessage({\n binaryMessage: buffer,\n });\n }\n\n const decryptConfig: openpgp.DecryptOptions = {\n message,\n decryptionKeys: privateKeys,\n format: 'binary',\n };\n\n // Add verification if requested\n if (options?.verify && options?.publicKey) {\n if (typeof options.publicKey === 'string') {\n decryptConfig.verificationKeys = await openpgp.readKey({\n armoredKey: options.publicKey,\n });\n } else {\n throw new InvalidKeyError(\n 'PGP verification requires armored public key string',\n this.adapterType,\n );\n }\n }\n\n const result = await openpgp.decrypt(decryptConfig);\n\n // Verify signature if requested\n if (options?.verify && result.signatures) {\n try {\n await result.signatures[0].verified;\n this.log('Signature verified successfully');\n } catch (error) {\n throw new VerificationError(\n 'Signature verification failed',\n this.adapterType,\n error,\n );\n }\n }\n\n this.log('Buffer decrypted successfully');\n return Buffer.from(result.data as Uint8Array);\n } catch (error) {\n if (error instanceof VerificationError) {\n throw error;\n }\n throw new DecryptError(\n `Failed to decrypt buffer: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async generateKeyPair(options?: KeyPairOptions): Promise<KeyPair> {\n try {\n this.log('Generating PGP key pair', options);\n\n const keyType = options?.type || 'rsa';\n const keySize = options?.keySize || 4096;\n\n let generateOptions: Parameters<typeof openpgp.generateKey>[0];\n\n if (keyType === 'rsa') {\n generateOptions = {\n type: 'rsa',\n rsaBits: keySize,\n userIDs: [\n {\n name: options?.name || '',\n email: options?.email || '',\n },\n ],\n passphrase: options?.passphrase,\n format: 'object',\n };\n } else if (keyType === 'ecc' || keyType === 'ecdh') {\n generateOptions = {\n type: 'ecc',\n curve: (options?.curve as any) || 'curve25519',\n userIDs: [\n {\n name: options?.name || '',\n email: options?.email || '',\n },\n ],\n passphrase: options?.passphrase,\n format: 'object',\n };\n } else {\n throw new KeyError(\n `Unsupported key type for PGP: ${keyType}`,\n this.adapterType,\n );\n }\n\n const { privateKey: privKeyObj, publicKey: pubKeyObj } =\n await openpgp.generateKey(generateOptions);\n\n // Armor the keys for return\n const publicKey = pubKeyObj.armor();\n const privateKey = privKeyObj.armor();\n\n const fingerprint = pubKeyObj.getFingerprint();\n const keyId = pubKeyObj.getKeyID().toHex();\n\n this.log('Key pair generated successfully', { keyId, fingerprint });\n\n return {\n publicKey,\n privateKey,\n fingerprint,\n keyId,\n };\n } catch (error) {\n throw new KeyError(\n `Failed to generate PGP key pair: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async importKey(\n key: string | Buffer,\n options?: ImportKeyOptions,\n ): Promise<Key> {\n try {\n this.log('Importing PGP key');\n\n const armoredKey = typeof key === 'string' ? key : key.toString('utf8');\n\n const keyType = options?.type || 'public';\n\n if (keyType === 'public') {\n const pubKey = await openpgp.readKey({ armoredKey });\n\n const expirationTime = await pubKey.getExpirationTime();\n\n return {\n type: 'public',\n format: 'armored',\n data: armoredKey,\n fingerprint: pubKey.getFingerprint(),\n keyId: pubKey.getKeyID().toHex(),\n algorithm: pubKey.getAlgorithmInfo().algorithm,\n created: pubKey.getCreationTime(),\n expires: expirationTime instanceof Date ? expirationTime : undefined,\n userIds: pubKey.getUserIDs().map((uid: string) => {\n const match = uid.match(/^(.*?)\\s*<(.+?)>$/);\n if (match) {\n return { name: match[1], email: match[2] };\n }\n return { email: uid };\n }),\n };\n }\n\n // Private key\n const privKey = await openpgp.readPrivateKey({ armoredKey });\n\n // Decrypt if passphrase provided\n let decryptedKey = privKey;\n if (options?.passphrase) {\n try {\n decryptedKey = await openpgp.decryptKey({\n privateKey: privKey,\n passphrase: options.passphrase,\n });\n } catch (error) {\n throw new PassphraseError(\n 'Invalid passphrase for private key',\n this.adapterType,\n error,\n );\n }\n }\n\n this.log('Key imported successfully');\n\n const expirationTime = await decryptedKey.getExpirationTime();\n\n return {\n type: 'private',\n format: 'armored',\n data: armoredKey,\n fingerprint: decryptedKey.getFingerprint(),\n keyId: decryptedKey.getKeyID().toHex(),\n algorithm: decryptedKey.getAlgorithmInfo().algorithm,\n created: decryptedKey.getCreationTime(),\n expires: expirationTime instanceof Date ? expirationTime : undefined,\n userIds: decryptedKey.getUserIDs().map((uid: string) => {\n const match = uid.match(/^(.*?)\\s*<(.+?)>$/);\n if (match) {\n return { name: match[1], email: match[2] };\n }\n return { email: uid };\n }),\n };\n } catch (error) {\n if (error instanceof PassphraseError) {\n throw error;\n }\n throw new InvalidKeyError(\n `Failed to import PGP key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async exportKey(\n key: Key,\n options?: ExportKeyOptions,\n ): Promise<string | Buffer> {\n try {\n this.log('Exporting PGP key');\n\n // PGP keys are already in armored format\n if (typeof key.data === 'string') {\n if (options?.format === 'binary') {\n return Buffer.from(key.data);\n }\n return key.data;\n }\n\n if (Buffer.isBuffer(key.data)) {\n if (options?.format === 'armored' || options?.armor) {\n return key.data.toString('utf8');\n }\n return key.data;\n }\n\n throw new InvalidKeyError(\n 'Invalid key data format for export',\n this.adapterType,\n );\n } catch (error) {\n throw new KeyError(\n `Failed to export PGP key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Sign data with private key\n */\n async sign(\n data: string | Buffer,\n options?: SignOptions,\n ): Promise<string | Buffer> {\n try {\n this.log('Signing data');\n\n await this.initializeKeys();\n\n let signingKey: openpgp.PrivateKey;\n\n if (options?.privateKey) {\n signingKey = await openpgp.readPrivateKey({\n armoredKey: options.privateKey as string,\n });\n\n if (options.passphrase) {\n signingKey = await openpgp.decryptKey({\n privateKey: signingKey,\n passphrase: options.passphrase,\n });\n }\n } else if (this.privateKeys && this.privateKeys.length > 0) {\n signingKey = this.privateKeys[0];\n } else {\n throw new KeyError(\n 'No private key available for signing',\n this.adapterType,\n );\n }\n\n const message =\n typeof data === 'string'\n ? await openpgp.createMessage({ text: data })\n : await openpgp.createMessage({ binary: data });\n\n const format =\n options?.armor !== false ? ('armored' as const) : ('binary' as const);\n\n // Sign with format\n const signed = await openpgp.sign({\n message,\n signingKeys: signingKey,\n detached: options?.detached,\n format,\n } as any);\n\n this.log('Data signed successfully');\n\n if (format === 'armored') {\n return signed as string;\n } else {\n // When format is 'binary', convert result to Buffer\n if (signed instanceof Uint8Array) {\n return Buffer.from(signed);\n }\n return Buffer.from(signed as any);\n }\n } catch (error) {\n throw new SignatureError(\n `Failed to sign data: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Verify signature\n */\n async verify(\n data: string | Buffer,\n signature: string | Buffer,\n options?: VerifyOptions,\n ): Promise<boolean> {\n try {\n this.log('Verifying signature');\n\n if (!options?.publicKey) {\n throw new KeyError(\n 'Public key required for signature verification',\n this.adapterType,\n );\n }\n\n const verificationKey = await openpgp.readKey({\n armoredKey: options.publicKey as string,\n });\n\n // Check if this is a detached signature\n const signatureStr =\n typeof signature === 'string' ? signature : signature.toString('utf8');\n const isDetached = signatureStr.includes('-----BEGIN PGP SIGNATURE-----');\n\n if (isDetached) {\n // Detached signature verification\n const message =\n typeof data === 'string'\n ? await openpgp.createMessage({ text: data })\n : await openpgp.createMessage({ binary: data });\n\n const sig = await openpgp.readSignature({\n armoredSignature: signatureStr,\n });\n\n const result = await openpgp.verify({\n message: message as any,\n signature: sig,\n verificationKeys: verificationKey,\n } as any);\n\n await result.signatures[0].verified;\n } else {\n // Inline signature verification (signature embedded in message)\n let message: any;\n\n if (signatureStr.includes('-----BEGIN PGP SIGNED MESSAGE-----')) {\n // Cleartext signature\n message = await openpgp.readCleartextMessage({\n cleartextMessage: signatureStr,\n });\n } else {\n // Binary or armored signed message\n try {\n message = await openpgp.readMessage({\n armoredMessage: signatureStr,\n });\n } catch {\n message = await openpgp.readMessage({\n binaryMessage:\n typeof signature === 'string'\n ? Buffer.from(signature, 'binary')\n : signature,\n });\n }\n }\n\n const result = await openpgp.verify({\n message,\n verificationKeys: verificationKey,\n } as any);\n\n await result.signatures[0].verified;\n }\n\n this.log('Signature verified successfully');\n return true;\n } catch (error) {\n if (error instanceof KeyError) {\n throw error;\n }\n this.log('Signature verification failed', error);\n return false;\n }\n }\n\n /**\n * Encrypt email message in PGP/MIME format\n */\n async encryptEmail(\n message: import('../shared/types.js').EmailMessage,\n options?: import('../shared/types.js').EncryptEmailOptions,\n ): Promise<import('../shared/types.js').EmailMessage> {\n try {\n this.log('Encrypting email message');\n\n // Serialize email content (subject, text, html, attachments)\n const emailContent = this.serializeEmailContent(message, options);\n\n // Get public keys for encryption\n const publicKeys = await this.getPublicKeys({\n publicKeys: options?.publicKeys,\n });\n\n // Get private key for signing if requested\n let signingKey: openpgp.PrivateKey | undefined;\n if (options?.sign) {\n await this.initializeKeys();\n if (options.privateKey) {\n const key = await openpgp.readPrivateKey({\n armoredKey: options.privateKey,\n });\n if (options.passphrase) {\n signingKey = await openpgp.decryptKey({\n privateKey: key,\n passphrase: options.passphrase,\n });\n } else {\n signingKey = key;\n }\n } else if (this.privateKeys && this.privateKeys.length > 0) {\n signingKey = this.privateKeys[0];\n }\n }\n\n // Encrypt the email content\n const encryptConfig: any = {\n message: await openpgp.createMessage({ text: emailContent }),\n encryptionKeys: publicKeys,\n format:\n options?.armor !== false ? ('armored' as const) : ('binary' as const),\n };\n\n if (signingKey) {\n encryptConfig.signingKeys = signingKey;\n }\n\n const encrypted = await openpgp.encrypt(encryptConfig);\n\n this.log('Email encrypted successfully');\n\n // Return encrypted message in PGP/MIME format\n return {\n ...message,\n text: encrypted as string,\n html: undefined, // Clear HTML when encrypted\n contentType:\n 'multipart/encrypted; protocol=\"application/pgp-encrypted\"',\n headers: {\n ...(message.headers || {}),\n 'Content-Type':\n 'multipart/encrypted; protocol=\"application/pgp-encrypted\"',\n },\n };\n } catch (error) {\n throw new EncryptError(\n `Failed to encrypt email: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Decrypt PGP/MIME email message\n */\n async decryptEmail(\n message: import('../shared/types.js').EmailMessage,\n options?: import('../shared/types.js').DecryptEmailOptions,\n ): Promise<import('../shared/types.js').DecryptedEmail> {\n try {\n this.log('Decrypting email message');\n\n if (!message.text) {\n throw new DecryptError(\n 'Email message has no text content to decrypt',\n this.adapterType,\n );\n }\n\n // Get private keys for decryption\n const privateKeys = await this.getPrivateKeys({\n privateKey: options?.privateKey,\n passphrase: options?.passphrase,\n });\n\n // Read encrypted message\n let encryptedMessage: openpgp.Message<any>;\n try {\n encryptedMessage = await openpgp.readMessage({\n armoredMessage: message.text,\n });\n } catch {\n encryptedMessage = await openpgp.readMessage({\n binaryMessage: Buffer.from(message.text, 'base64'),\n });\n }\n\n // Decrypt the message\n const decryptConfig: openpgp.DecryptOptions = {\n message: encryptedMessage,\n decryptionKeys: privateKeys,\n format: 'utf8',\n };\n\n // Add verification if requested\n if (options?.verify) {\n const verificationKey = options.publicKey || this.options.publicKey;\n if (verificationKey) {\n decryptConfig.verificationKeys = await openpgp.readKey({\n armoredKey: verificationKey,\n });\n }\n }\n\n const result = await openpgp.decrypt(decryptConfig);\n const decryptedContent = result.data as string;\n\n // Verify signature if requested\n let verified = false;\n let verificationError: string | undefined;\n let signerKeyId: string | undefined;\n let signerFingerprint: string | undefined;\n\n if (options?.verify) {\n const verificationKey = options.publicKey || this.options.publicKey;\n\n if (!verificationKey) {\n verificationError = 'Public key required for signature verification';\n this.log('Email signature verification skipped: no public key');\n } else if (!result.signatures || result.signatures.length === 0) {\n verificationError = 'No signature found in message';\n this.log('Email signature verification skipped: no signatures');\n } else {\n try {\n // Verify the signature\n await result.signatures[0].verified;\n verified = true;\n signerKeyId = result.signatures[0].keyID.toHex();\n // Get fingerprint from verification key\n const pubKey = await openpgp.readKey({\n armoredKey: verificationKey,\n });\n signerFingerprint = pubKey.getFingerprint();\n this.log('Email signature verified successfully');\n } catch (error) {\n verificationError =\n error instanceof Error ? error.message : String(error);\n this.log('Email signature verification failed', error);\n }\n }\n }\n\n // Deserialize email content\n const deserializedMessage = this.deserializeEmailContent(\n decryptedContent,\n message,\n );\n\n this.log('Email decrypted successfully');\n\n return {\n ...deserializedMessage,\n encrypted: true,\n signed: result.signatures && result.signatures.length > 0,\n verified: options?.verify ? verified : undefined,\n verificationError,\n signerKeyId,\n signerFingerprint,\n encryptionAlgorithm: 'pgp',\n };\n } catch (error) {\n if (error instanceof DecryptError) {\n throw error;\n }\n throw new DecryptError(\n `Failed to decrypt email: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Sign email message\n */\n async signEmail(\n message: import('../shared/types.js').EmailMessage,\n options?: import('../shared/types.js').SignEmailOptions,\n ): Promise<import('../shared/types.js').EmailMessage> {\n try {\n this.log('Signing email message');\n\n // Serialize email content\n const emailContent = this.serializeEmailContent(message);\n\n // Get signing key\n await this.initializeKeys();\n let signingKey: openpgp.PrivateKey;\n\n if (options?.privateKey) {\n const key = await openpgp.readPrivateKey({\n armoredKey: options.privateKey as string,\n });\n if (options.passphrase) {\n signingKey = await openpgp.decryptKey({\n privateKey: key,\n passphrase: options.passphrase,\n });\n } else {\n signingKey = key;\n }\n } else if (this.privateKeys && this.privateKeys.length > 0) {\n signingKey = this.privateKeys[0];\n } else {\n throw new KeyError(\n 'No private key available for signing email',\n this.adapterType,\n );\n }\n\n // Sign the message (cleartext signature)\n const signedMessageObj = await openpgp.sign({\n message: await openpgp.createCleartextMessage({ text: emailContent }),\n signingKeys: signingKey,\n format: 'object' as const,\n });\n\n // Convert to armored string\n const signedMessage = signedMessageObj.armor();\n\n this.log('Email signed successfully');\n\n return {\n ...message,\n text: signedMessage,\n contentType: 'text/plain; charset=utf-8',\n headers: {\n ...(message.headers || {}),\n 'Content-Type': 'text/plain; charset=utf-8',\n },\n };\n } catch (error) {\n throw new SignatureError(\n `Failed to sign email: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Verify email signature\n */\n async verifyEmail(\n message: import('../shared/types.js').EmailMessage,\n options?: import('../shared/types.js').VerifyEmailOptions,\n ): Promise<import('../shared/types.js').VerificationResult> {\n try {\n this.log('Verifying email signature');\n\n if (!message.text) {\n return {\n valid: false,\n message: 'Email message has no text content to verify',\n };\n }\n\n if (!options?.publicKey) {\n return {\n valid: false,\n message: 'Public key required for email signature verification',\n };\n }\n\n const verificationKey = await openpgp.readKey({\n armoredKey: options.publicKey as string,\n });\n\n // Read signed message\n const signedMessage = await openpgp.readCleartextMessage({\n cleartextMessage: message.text,\n });\n\n // Verify the signature\n const result = await openpgp.verify({\n message: signedMessage,\n verificationKeys: verificationKey,\n });\n\n await result.signatures[0].verified;\n\n const keyId = result.signatures[0].keyID.toHex();\n const fingerprint = verificationKey.getFingerprint();\n\n this.log('Email signature verified successfully');\n\n return {\n valid: true,\n keyId,\n keyFingerprint: fingerprint,\n timestamp: new Date(),\n algorithm: 'pgp',\n };\n } catch (error) {\n this.log('Email signature verification failed', error);\n return {\n valid: false,\n message: (error as Error).message,\n };\n }\n }\n\n /**\n * Serialize email content for encryption/signing\n */\n private serializeEmailContent(\n message: import('../shared/types.js').EmailMessage,\n options?: import('../shared/types.js').EncryptEmailOptions,\n ): string {\n const parts: string[] = [];\n\n // Add subject (optionally encrypt it)\n if (options?.encryptSubject) {\n parts.push(`Subject: ${message.subject}`);\n }\n\n // Add text content\n if (message.text) {\n parts.push(`\\n${message.text}`);\n }\n\n // Add HTML content\n if (message.html) {\n parts.push(`\\n--- HTML Content ---\\n${message.html}`);\n }\n\n // Add attachment metadata (not the actual content)\n if (message.attachments && message.attachments.length > 0) {\n parts.push('\\n--- Attachments ---');\n for (const attachment of message.attachments) {\n parts.push(\n `- ${attachment.filename || 'unnamed'} (${attachment.contentType}, ${attachment.size} bytes)`,\n );\n }\n }\n\n return parts.join('\\n');\n }\n\n /**\n * Deserialize email content after decryption\n */\n private deserializeEmailContent(\n content: string,\n originalMessage: import('../shared/types.js').EmailMessage,\n ): import('../shared/types.js').EmailMessage {\n const lines = content.split('\\n');\n let subject = originalMessage.subject;\n let text = '';\n let html: string | undefined;\n\n // Parse decrypted content\n let currentSection = 'text';\n for (const line of lines) {\n if (line.startsWith('Subject: ')) {\n subject = line.substring(9);\n } else if (line === '--- HTML Content ---') {\n currentSection = 'html';\n } else if (line === '--- Attachments ---') {\n break; // Stop at attachments\n } else if (currentSection === 'text' && line.trim()) {\n text += `${line}\\n`;\n } else if (currentSection === 'html') {\n if (!html) html = '';\n html += `${line}\\n`;\n }\n }\n\n return {\n ...originalMessage,\n subject,\n text: text.trim(),\n html: html?.trim(),\n };\n }\n\n async getCapabilities(): Promise<EncryptionCapabilities> {\n return {\n textEncryption: true,\n fileEncryption: true,\n bufferEncryption: true,\n streamEncryption: true,\n emailEncryption: true,\n signing: true,\n verification: true,\n keyGeneration: true,\n keyManagement: true,\n multipleRecipients: true,\n symmetricEncryption: false,\n asymmetricEncryption: true,\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pgp-Dss_W-gt.js","names":[],"sources":["../../src/adapters/pgp.ts"],"sourcesContent":["import * as openpgp from 'openpgp';\nimport { BaseEncryption } from '../shared/base.js';\nimport {\n DecryptError,\n EncryptError,\n InvalidKeyError,\n KeyError,\n PassphraseError,\n SignatureError,\n VerificationError,\n} from '../shared/errors.js';\nimport type {\n DecryptOptions,\n EncryptionCapabilities,\n EncryptOptions,\n ExportKeyOptions,\n ImportKeyOptions,\n Key,\n KeyPair,\n KeyPairOptions,\n PGPOptions,\n SignOptions,\n VerifyOptions,\n} from '../shared/types.js';\n\n/**\n * PGP/OpenPGP encryption adapter\n *\n * Uses OpenPGP.js for encryption, decryption, signing, and key management.\n *\n * @example\n * ```typescript\n * const pgp = new PGPEncryption({\n * type: 'pgp',\n * publicKey: recipientPublicKey,\n * privateKey: myPrivateKey,\n * passphrase: 'my-passphrase'\n * });\n *\n * const encrypted = await pgp.encryptText('Secret message');\n * const decrypted = await pgp.decryptText(encrypted);\n * ```\n */\nexport class PGPEncryption extends BaseEncryption {\n private options: PGPOptions;\n private publicKeys?: openpgp.PublicKey[];\n private privateKeys?: openpgp.PrivateKey[];\n\n constructor(options: PGPOptions) {\n super('pgp', options.debug);\n this.options = options;\n }\n\n /**\n * Initialize keys from options\n */\n private async initializeKeys(): Promise<void> {\n if (this.publicKeys || this.privateKeys) {\n return; // Already initialized\n }\n\n try {\n // Load public keys\n if (this.options.publicKey) {\n const key = await openpgp.readKey({\n armoredKey: this.options.publicKey,\n });\n this.publicKeys = [key];\n } else if (this.options.publicKeys) {\n this.publicKeys = await Promise.all(\n this.options.publicKeys.map((k) =>\n openpgp.readKey({ armoredKey: k }),\n ),\n );\n }\n\n // Load private keys\n if (this.options.privateKey) {\n const key = await openpgp.readPrivateKey({\n armoredKey: this.options.privateKey,\n });\n\n // Decrypt private key if passphrase provided\n if (this.options.passphrase) {\n const decryptedKey = await openpgp.decryptKey({\n privateKey: key,\n passphrase: this.options.passphrase,\n });\n this.privateKeys = [decryptedKey];\n } else {\n this.privateKeys = [key];\n }\n } else if (this.options.privateKeys) {\n this.privateKeys = await Promise.all(\n this.options.privateKeys.map(async (k) => {\n const key = await openpgp.readPrivateKey({ armoredKey: k });\n if (this.options.passphrase) {\n return openpgp.decryptKey({\n privateKey: key,\n passphrase: this.options.passphrase,\n });\n }\n return key;\n }),\n );\n }\n } catch (error) {\n throw new KeyError(\n `Failed to initialize PGP keys: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Get public keys for encryption\n */\n private async getPublicKeys(\n options?: EncryptOptions,\n ): Promise<openpgp.PublicKey[]> {\n await this.initializeKeys();\n\n // Options override default keys\n if (options?.publicKeys) {\n return Promise.all(\n options.publicKeys.map((k) => openpgp.readKey({ armoredKey: k })),\n );\n }\n\n if (!this.publicKeys || this.publicKeys.length === 0) {\n throw new KeyError(\n 'No public keys available for encryption',\n this.adapterType,\n );\n }\n\n return this.publicKeys;\n }\n\n /**\n * Get private keys for decryption\n */\n private async getPrivateKeys(\n options?: DecryptOptions,\n ): Promise<openpgp.PrivateKey[]> {\n await this.initializeKeys();\n\n // Options override default keys\n if (options?.privateKey) {\n const key = await openpgp.readPrivateKey({\n armoredKey: options.privateKey as string,\n });\n\n if (options.passphrase) {\n const decryptedKey = await openpgp.decryptKey({\n privateKey: key,\n passphrase: options.passphrase,\n });\n return [decryptedKey];\n }\n\n return [key];\n }\n\n if (!this.privateKeys || this.privateKeys.length === 0) {\n throw new KeyError(\n 'No private keys available for decryption',\n this.adapterType,\n );\n }\n\n return this.privateKeys;\n }\n\n async encryptText(text: string, options?: EncryptOptions): Promise<string> {\n try {\n this.log('Encrypting text', { length: text.length });\n this.validateEncryptOptions(options);\n\n const publicKeys = await this.getPublicKeys(options);\n\n const format =\n options?.armor !== false ? ('armored' as const) : ('binary' as const);\n\n const encryptConfig: any = {\n message: await openpgp.createMessage({ text }),\n encryptionKeys: publicKeys,\n format,\n };\n\n // Add signing if requested\n if (options?.sign && options?.privateKey) {\n const signingKey = await openpgp.readPrivateKey({\n armoredKey: options.privateKey as string,\n });\n\n if (this.options.passphrase) {\n encryptConfig.signingKeys = await openpgp.decryptKey({\n privateKey: signingKey,\n passphrase: this.options.passphrase,\n });\n } else {\n encryptConfig.signingKeys = signingKey;\n }\n } else if (options?.sign && this.privateKeys) {\n encryptConfig.signingKeys = this.privateKeys;\n }\n\n const encrypted = await openpgp.encrypt(encryptConfig);\n\n this.log('Text encrypted successfully');\n\n // Convert binary output to base64 string for text encryption\n if (format === 'binary' && encrypted instanceof Uint8Array) {\n return Buffer.from(encrypted).toString('base64');\n }\n\n return encrypted as string;\n } catch (error) {\n throw new EncryptError(\n `Failed to encrypt text: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async decryptText(\n encrypted: string,\n options?: DecryptOptions,\n ): Promise<string> {\n try {\n this.log('Decrypting text', { length: encrypted.length });\n this.validateDecryptOptions(options);\n\n const privateKeys = await this.getPrivateKeys(options);\n\n // Try to read as armored message first, fallback to binary\n let message: openpgp.Message<any>;\n try {\n message = await openpgp.readMessage({\n armoredMessage: encrypted,\n });\n } catch {\n // If armored fails, try base64-encoded binary\n try {\n message = await openpgp.readMessage({\n binaryMessage: Buffer.from(encrypted, 'base64'),\n });\n } catch {\n // Last resort: try raw binary\n message = await openpgp.readMessage({\n binaryMessage: Buffer.from(encrypted, 'binary'),\n });\n }\n }\n\n const decryptConfig: openpgp.DecryptOptions = {\n message,\n decryptionKeys: privateKeys,\n format: 'utf8',\n };\n\n // Add verification if requested\n if (options?.verify && options?.publicKey) {\n if (typeof options.publicKey === 'string') {\n decryptConfig.verificationKeys = await openpgp.readKey({\n armoredKey: options.publicKey,\n });\n } else {\n throw new InvalidKeyError(\n 'PGP verification requires armored public key string',\n this.adapterType,\n );\n }\n }\n\n const result = await openpgp.decrypt(decryptConfig);\n\n // Verify signature if requested\n if (options?.verify && result.signatures) {\n try {\n await result.signatures[0].verified;\n this.log('Signature verified successfully');\n } catch (error) {\n throw new VerificationError(\n 'Signature verification failed',\n this.adapterType,\n error,\n );\n }\n }\n\n this.log('Text decrypted successfully');\n return result.data as string;\n } catch (error) {\n if (error instanceof VerificationError) {\n throw error;\n }\n throw new DecryptError(\n `Failed to decrypt text: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async encryptBuffer(\n buffer: Buffer,\n options?: EncryptOptions,\n ): Promise<Buffer> {\n try {\n this.log('Encrypting buffer', { size: buffer.length });\n this.validateEncryptOptions(options);\n\n const publicKeys = await this.getPublicKeys(options);\n\n const format =\n options?.armor === true ? ('armored' as const) : ('binary' as const);\n\n const encryptConfig: any = {\n message: await openpgp.createMessage({ binary: buffer }),\n encryptionKeys: publicKeys,\n format,\n };\n\n // Add signing if requested\n if (options?.sign && options?.privateKey) {\n const signingKey = await openpgp.readPrivateKey({\n armoredKey: options.privateKey as string,\n });\n\n if (this.options.passphrase) {\n encryptConfig.signingKeys = await openpgp.decryptKey({\n privateKey: signingKey,\n passphrase: this.options.passphrase,\n });\n } else {\n encryptConfig.signingKeys = signingKey;\n }\n } else if (options?.sign && this.privateKeys) {\n encryptConfig.signingKeys = this.privateKeys;\n }\n\n const encrypted = await openpgp.encrypt(encryptConfig);\n\n this.log('Buffer encrypted successfully');\n\n if (typeof encrypted === 'string') {\n return Buffer.from(encrypted);\n }\n\n // Handle Uint8Array, WebStream, or NodeWebStream\n if (encrypted instanceof Uint8Array) {\n return Buffer.from(encrypted);\n }\n\n // Fallback for stream types (shouldn't happen with current config)\n return Buffer.from(encrypted as any);\n } catch (error) {\n throw new EncryptError(\n `Failed to encrypt buffer: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async decryptBuffer(\n buffer: Buffer,\n options?: DecryptOptions,\n ): Promise<Buffer> {\n try {\n this.log('Decrypting buffer', { size: buffer.length });\n this.validateDecryptOptions(options);\n\n const privateKeys = await this.getPrivateKeys(options);\n\n // Try to read as armored message first, fallback to binary\n let message: any;\n try {\n message = await openpgp.readMessage({\n armoredMessage: buffer.toString('utf8'),\n });\n } catch {\n message = await openpgp.readMessage({\n binaryMessage: buffer,\n });\n }\n\n const decryptConfig: openpgp.DecryptOptions = {\n message,\n decryptionKeys: privateKeys,\n format: 'binary',\n };\n\n // Add verification if requested\n if (options?.verify && options?.publicKey) {\n if (typeof options.publicKey === 'string') {\n decryptConfig.verificationKeys = await openpgp.readKey({\n armoredKey: options.publicKey,\n });\n } else {\n throw new InvalidKeyError(\n 'PGP verification requires armored public key string',\n this.adapterType,\n );\n }\n }\n\n const result = await openpgp.decrypt(decryptConfig);\n\n // Verify signature if requested\n if (options?.verify && result.signatures) {\n try {\n await result.signatures[0].verified;\n this.log('Signature verified successfully');\n } catch (error) {\n throw new VerificationError(\n 'Signature verification failed',\n this.adapterType,\n error,\n );\n }\n }\n\n this.log('Buffer decrypted successfully');\n return Buffer.from(result.data as Uint8Array);\n } catch (error) {\n if (error instanceof VerificationError) {\n throw error;\n }\n throw new DecryptError(\n `Failed to decrypt buffer: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async generateKeyPair(options?: KeyPairOptions): Promise<KeyPair> {\n try {\n this.log('Generating PGP key pair', options);\n\n const keyType = options?.type || 'rsa';\n const keySize = options?.keySize || 4096;\n\n let generateOptions: Parameters<typeof openpgp.generateKey>[0];\n\n if (keyType === 'rsa') {\n generateOptions = {\n type: 'rsa',\n rsaBits: keySize,\n userIDs: [\n {\n name: options?.name || '',\n email: options?.email || '',\n },\n ],\n passphrase: options?.passphrase,\n format: 'object',\n };\n } else if (keyType === 'ecc' || keyType === 'ecdh') {\n generateOptions = {\n type: 'ecc',\n curve: (options?.curve as any) || 'curve25519',\n userIDs: [\n {\n name: options?.name || '',\n email: options?.email || '',\n },\n ],\n passphrase: options?.passphrase,\n format: 'object',\n };\n } else {\n throw new KeyError(\n `Unsupported key type for PGP: ${keyType}`,\n this.adapterType,\n );\n }\n\n const { privateKey: privKeyObj, publicKey: pubKeyObj } =\n await openpgp.generateKey(generateOptions);\n\n // Armor the keys for return\n const publicKey = pubKeyObj.armor();\n const privateKey = privKeyObj.armor();\n\n const fingerprint = pubKeyObj.getFingerprint();\n const keyId = pubKeyObj.getKeyID().toHex();\n\n this.log('Key pair generated successfully', { keyId, fingerprint });\n\n return {\n publicKey,\n privateKey,\n fingerprint,\n keyId,\n };\n } catch (error) {\n throw new KeyError(\n `Failed to generate PGP key pair: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async importKey(\n key: string | Buffer,\n options?: ImportKeyOptions,\n ): Promise<Key> {\n try {\n this.log('Importing PGP key');\n\n const armoredKey = typeof key === 'string' ? key : key.toString('utf8');\n\n const keyType = options?.type || 'public';\n\n if (keyType === 'public') {\n const pubKey = await openpgp.readKey({ armoredKey });\n\n const expirationTime = await pubKey.getExpirationTime();\n\n return {\n type: 'public',\n format: 'armored',\n data: armoredKey,\n fingerprint: pubKey.getFingerprint(),\n keyId: pubKey.getKeyID().toHex(),\n algorithm: pubKey.getAlgorithmInfo().algorithm,\n created: pubKey.getCreationTime(),\n expires: expirationTime instanceof Date ? expirationTime : undefined,\n userIds: pubKey.getUserIDs().map((uid: string) => {\n const match = uid.match(/^(.*?)\\s*<(.+?)>$/);\n if (match) {\n return { name: match[1], email: match[2] };\n }\n return { email: uid };\n }),\n };\n }\n\n // Private key\n const privKey = await openpgp.readPrivateKey({ armoredKey });\n\n // Decrypt if passphrase provided\n let decryptedKey = privKey;\n if (options?.passphrase) {\n try {\n decryptedKey = await openpgp.decryptKey({\n privateKey: privKey,\n passphrase: options.passphrase,\n });\n } catch (error) {\n throw new PassphraseError(\n 'Invalid passphrase for private key',\n this.adapterType,\n error,\n );\n }\n }\n\n this.log('Key imported successfully');\n\n const expirationTime = await decryptedKey.getExpirationTime();\n\n return {\n type: 'private',\n format: 'armored',\n data: armoredKey,\n fingerprint: decryptedKey.getFingerprint(),\n keyId: decryptedKey.getKeyID().toHex(),\n algorithm: decryptedKey.getAlgorithmInfo().algorithm,\n created: decryptedKey.getCreationTime(),\n expires: expirationTime instanceof Date ? expirationTime : undefined,\n userIds: decryptedKey.getUserIDs().map((uid: string) => {\n const match = uid.match(/^(.*?)\\s*<(.+?)>$/);\n if (match) {\n return { name: match[1], email: match[2] };\n }\n return { email: uid };\n }),\n };\n } catch (error) {\n if (error instanceof PassphraseError) {\n throw error;\n }\n throw new InvalidKeyError(\n `Failed to import PGP key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async exportKey(\n key: Key,\n options?: ExportKeyOptions,\n ): Promise<string | Buffer> {\n try {\n this.log('Exporting PGP key');\n\n // PGP keys are already in armored format\n if (typeof key.data === 'string') {\n if (options?.format === 'binary') {\n return Buffer.from(key.data);\n }\n return key.data;\n }\n\n if (Buffer.isBuffer(key.data)) {\n if (options?.format === 'armored' || options?.armor) {\n return key.data.toString('utf8');\n }\n return key.data;\n }\n\n throw new InvalidKeyError(\n 'Invalid key data format for export',\n this.adapterType,\n );\n } catch (error) {\n throw new KeyError(\n `Failed to export PGP key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Sign data with private key\n */\n async sign(\n data: string | Buffer,\n options?: SignOptions,\n ): Promise<string | Buffer> {\n try {\n this.log('Signing data');\n\n await this.initializeKeys();\n\n let signingKey: openpgp.PrivateKey;\n\n if (options?.privateKey) {\n signingKey = await openpgp.readPrivateKey({\n armoredKey: options.privateKey as string,\n });\n\n if (options.passphrase) {\n signingKey = await openpgp.decryptKey({\n privateKey: signingKey,\n passphrase: options.passphrase,\n });\n }\n } else if (this.privateKeys && this.privateKeys.length > 0) {\n signingKey = this.privateKeys[0];\n } else {\n throw new KeyError(\n 'No private key available for signing',\n this.adapterType,\n );\n }\n\n const message =\n typeof data === 'string'\n ? await openpgp.createMessage({ text: data })\n : await openpgp.createMessage({ binary: data });\n\n const format =\n options?.armor !== false ? ('armored' as const) : ('binary' as const);\n\n // Sign with format\n const signed = await openpgp.sign({\n message,\n signingKeys: signingKey,\n detached: options?.detached,\n format,\n } as any);\n\n this.log('Data signed successfully');\n\n if (format === 'armored') {\n return signed as string;\n } else {\n // When format is 'binary', convert result to Buffer\n if (signed instanceof Uint8Array) {\n return Buffer.from(signed);\n }\n return Buffer.from(signed as any);\n }\n } catch (error) {\n throw new SignatureError(\n `Failed to sign data: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Verify signature\n */\n async verify(\n data: string | Buffer,\n signature: string | Buffer,\n options?: VerifyOptions,\n ): Promise<boolean> {\n try {\n this.log('Verifying signature');\n\n if (!options?.publicKey) {\n throw new KeyError(\n 'Public key required for signature verification',\n this.adapterType,\n );\n }\n\n const verificationKey = await openpgp.readKey({\n armoredKey: options.publicKey as string,\n });\n\n // Check if this is a detached signature\n const signatureStr =\n typeof signature === 'string' ? signature : signature.toString('utf8');\n const isDetached = signatureStr.includes('-----BEGIN PGP SIGNATURE-----');\n\n if (isDetached) {\n // Detached signature verification\n const message =\n typeof data === 'string'\n ? await openpgp.createMessage({ text: data })\n : await openpgp.createMessage({ binary: data });\n\n const sig = await openpgp.readSignature({\n armoredSignature: signatureStr,\n });\n\n const result = await openpgp.verify({\n message: message as any,\n signature: sig,\n verificationKeys: verificationKey,\n } as any);\n\n await result.signatures[0].verified;\n } else {\n // Inline signature verification (signature embedded in message)\n let message: any;\n\n if (signatureStr.includes('-----BEGIN PGP SIGNED MESSAGE-----')) {\n // Cleartext signature\n message = await openpgp.readCleartextMessage({\n cleartextMessage: signatureStr,\n });\n } else {\n // Binary or armored signed message\n try {\n message = await openpgp.readMessage({\n armoredMessage: signatureStr,\n });\n } catch {\n message = await openpgp.readMessage({\n binaryMessage:\n typeof signature === 'string'\n ? Buffer.from(signature, 'binary')\n : signature,\n });\n }\n }\n\n const result = await openpgp.verify({\n message,\n verificationKeys: verificationKey,\n } as any);\n\n await result.signatures[0].verified;\n }\n\n this.log('Signature verified successfully');\n return true;\n } catch (error) {\n if (error instanceof KeyError) {\n throw error;\n }\n this.log('Signature verification failed', error);\n return false;\n }\n }\n\n /**\n * Encrypt email message in PGP/MIME format\n */\n async encryptEmail(\n message: import('../shared/types.js').EmailMessage,\n options?: import('../shared/types.js').EncryptEmailOptions,\n ): Promise<import('../shared/types.js').EmailMessage> {\n try {\n this.log('Encrypting email message');\n\n // Serialize email content (subject, text, html, attachments)\n const emailContent = this.serializeEmailContent(message, options);\n\n // Get public keys for encryption\n const publicKeys = await this.getPublicKeys({\n publicKeys: options?.publicKeys,\n });\n\n // Get private key for signing if requested\n let signingKey: openpgp.PrivateKey | undefined;\n if (options?.sign) {\n await this.initializeKeys();\n if (options.privateKey) {\n const key = await openpgp.readPrivateKey({\n armoredKey: options.privateKey,\n });\n if (options.passphrase) {\n signingKey = await openpgp.decryptKey({\n privateKey: key,\n passphrase: options.passphrase,\n });\n } else {\n signingKey = key;\n }\n } else if (this.privateKeys && this.privateKeys.length > 0) {\n signingKey = this.privateKeys[0];\n }\n }\n\n // Encrypt the email content\n const encryptConfig: any = {\n message: await openpgp.createMessage({ text: emailContent }),\n encryptionKeys: publicKeys,\n format:\n options?.armor !== false ? ('armored' as const) : ('binary' as const),\n };\n\n if (signingKey) {\n encryptConfig.signingKeys = signingKey;\n }\n\n const encrypted = await openpgp.encrypt(encryptConfig);\n\n this.log('Email encrypted successfully');\n\n // Return encrypted message in PGP/MIME format\n return {\n ...message,\n text: encrypted as string,\n html: undefined, // Clear HTML when encrypted\n contentType:\n 'multipart/encrypted; protocol=\"application/pgp-encrypted\"',\n headers: {\n ...(message.headers || {}),\n 'Content-Type':\n 'multipart/encrypted; protocol=\"application/pgp-encrypted\"',\n },\n };\n } catch (error) {\n throw new EncryptError(\n `Failed to encrypt email: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Decrypt PGP/MIME email message\n */\n async decryptEmail(\n message: import('../shared/types.js').EmailMessage,\n options?: import('../shared/types.js').DecryptEmailOptions,\n ): Promise<import('../shared/types.js').DecryptedEmail> {\n try {\n this.log('Decrypting email message');\n\n if (!message.text) {\n throw new DecryptError(\n 'Email message has no text content to decrypt',\n this.adapterType,\n );\n }\n\n // Get private keys for decryption\n const privateKeys = await this.getPrivateKeys({\n privateKey: options?.privateKey,\n passphrase: options?.passphrase,\n });\n\n // Read encrypted message\n let encryptedMessage: openpgp.Message<any>;\n try {\n encryptedMessage = await openpgp.readMessage({\n armoredMessage: message.text,\n });\n } catch {\n encryptedMessage = await openpgp.readMessage({\n binaryMessage: Buffer.from(message.text, 'base64'),\n });\n }\n\n // Decrypt the message\n const decryptConfig: openpgp.DecryptOptions = {\n message: encryptedMessage,\n decryptionKeys: privateKeys,\n format: 'utf8',\n };\n\n // Add verification if requested\n if (options?.verify) {\n const verificationKey = options.publicKey || this.options.publicKey;\n if (verificationKey) {\n decryptConfig.verificationKeys = await openpgp.readKey({\n armoredKey: verificationKey,\n });\n }\n }\n\n const result = await openpgp.decrypt(decryptConfig);\n const decryptedContent = result.data as string;\n\n // Verify signature if requested\n let verified = false;\n let verificationError: string | undefined;\n let signerKeyId: string | undefined;\n let signerFingerprint: string | undefined;\n\n if (options?.verify) {\n const verificationKey = options.publicKey || this.options.publicKey;\n\n if (!verificationKey) {\n verificationError = 'Public key required for signature verification';\n this.log('Email signature verification skipped: no public key');\n } else if (!result.signatures || result.signatures.length === 0) {\n verificationError = 'No signature found in message';\n this.log('Email signature verification skipped: no signatures');\n } else {\n try {\n // Verify the signature\n await result.signatures[0].verified;\n verified = true;\n signerKeyId = result.signatures[0].keyID.toHex();\n // Get fingerprint from verification key\n const pubKey = await openpgp.readKey({\n armoredKey: verificationKey,\n });\n signerFingerprint = pubKey.getFingerprint();\n this.log('Email signature verified successfully');\n } catch (error) {\n verificationError =\n error instanceof Error ? error.message : String(error);\n this.log('Email signature verification failed', error);\n }\n }\n }\n\n // Deserialize email content\n const deserializedMessage = this.deserializeEmailContent(\n decryptedContent,\n message,\n );\n\n this.log('Email decrypted successfully');\n\n return {\n ...deserializedMessage,\n encrypted: true,\n signed: result.signatures && result.signatures.length > 0,\n verified: options?.verify ? verified : undefined,\n verificationError,\n signerKeyId,\n signerFingerprint,\n encryptionAlgorithm: 'pgp',\n };\n } catch (error) {\n if (error instanceof DecryptError) {\n throw error;\n }\n throw new DecryptError(\n `Failed to decrypt email: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Sign email message\n */\n async signEmail(\n message: import('../shared/types.js').EmailMessage,\n options?: import('../shared/types.js').SignEmailOptions,\n ): Promise<import('../shared/types.js').EmailMessage> {\n try {\n this.log('Signing email message');\n\n // Serialize email content\n const emailContent = this.serializeEmailContent(message);\n\n // Get signing key\n await this.initializeKeys();\n let signingKey: openpgp.PrivateKey;\n\n if (options?.privateKey) {\n const key = await openpgp.readPrivateKey({\n armoredKey: options.privateKey as string,\n });\n if (options.passphrase) {\n signingKey = await openpgp.decryptKey({\n privateKey: key,\n passphrase: options.passphrase,\n });\n } else {\n signingKey = key;\n }\n } else if (this.privateKeys && this.privateKeys.length > 0) {\n signingKey = this.privateKeys[0];\n } else {\n throw new KeyError(\n 'No private key available for signing email',\n this.adapterType,\n );\n }\n\n // Sign the message (cleartext signature)\n const signedMessageObj = await openpgp.sign({\n message: await openpgp.createCleartextMessage({ text: emailContent }),\n signingKeys: signingKey,\n format: 'object' as const,\n });\n\n // Convert to armored string\n const signedMessage = signedMessageObj.armor();\n\n this.log('Email signed successfully');\n\n return {\n ...message,\n text: signedMessage,\n contentType: 'text/plain; charset=utf-8',\n headers: {\n ...(message.headers || {}),\n 'Content-Type': 'text/plain; charset=utf-8',\n },\n };\n } catch (error) {\n throw new SignatureError(\n `Failed to sign email: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Verify email signature\n */\n async verifyEmail(\n message: import('../shared/types.js').EmailMessage,\n options?: import('../shared/types.js').VerifyEmailOptions,\n ): Promise<import('../shared/types.js').VerificationResult> {\n try {\n this.log('Verifying email signature');\n\n if (!message.text) {\n return {\n valid: false,\n message: 'Email message has no text content to verify',\n };\n }\n\n if (!options?.publicKey) {\n return {\n valid: false,\n message: 'Public key required for email signature verification',\n };\n }\n\n const verificationKey = await openpgp.readKey({\n armoredKey: options.publicKey as string,\n });\n\n // Read signed message\n const signedMessage = await openpgp.readCleartextMessage({\n cleartextMessage: message.text,\n });\n\n // Verify the signature\n const result = await openpgp.verify({\n message: signedMessage,\n verificationKeys: verificationKey,\n });\n\n await result.signatures[0].verified;\n\n const keyId = result.signatures[0].keyID.toHex();\n const fingerprint = verificationKey.getFingerprint();\n\n this.log('Email signature verified successfully');\n\n return {\n valid: true,\n keyId,\n keyFingerprint: fingerprint,\n timestamp: new Date(),\n algorithm: 'pgp',\n };\n } catch (error) {\n this.log('Email signature verification failed', error);\n return {\n valid: false,\n message: (error as Error).message,\n };\n }\n }\n\n /**\n * Serialize email content for encryption/signing\n */\n private serializeEmailContent(\n message: import('../shared/types.js').EmailMessage,\n options?: import('../shared/types.js').EncryptEmailOptions,\n ): string {\n const parts: string[] = [];\n\n // Add subject (optionally encrypt it)\n if (options?.encryptSubject) {\n parts.push(`Subject: ${message.subject}`);\n }\n\n // Add text content\n if (message.text) {\n parts.push(`\\n${message.text}`);\n }\n\n // Add HTML content\n if (message.html) {\n parts.push(`\\n--- HTML Content ---\\n${message.html}`);\n }\n\n // Add attachment metadata (not the actual content)\n if (message.attachments && message.attachments.length > 0) {\n parts.push('\\n--- Attachments ---');\n for (const attachment of message.attachments) {\n parts.push(\n `- ${attachment.filename || 'unnamed'} (${attachment.contentType}, ${attachment.size} bytes)`,\n );\n }\n }\n\n return parts.join('\\n');\n }\n\n /**\n * Deserialize email content after decryption\n */\n private deserializeEmailContent(\n content: string,\n originalMessage: import('../shared/types.js').EmailMessage,\n ): import('../shared/types.js').EmailMessage {\n const lines = content.split('\\n');\n let subject = originalMessage.subject;\n let text = '';\n let html: string | undefined;\n\n // Parse decrypted content\n let currentSection = 'text';\n for (const line of lines) {\n if (line.startsWith('Subject: ')) {\n subject = line.substring(9);\n } else if (line === '--- HTML Content ---') {\n currentSection = 'html';\n } else if (line === '--- Attachments ---') {\n break; // Stop at attachments\n } else if (currentSection === 'text' && line.trim()) {\n text += `${line}\\n`;\n } else if (currentSection === 'html') {\n if (!html) html = '';\n html += `${line}\\n`;\n }\n }\n\n return {\n ...originalMessage,\n subject,\n text: text.trim(),\n html: html?.trim(),\n };\n }\n\n async getCapabilities(): Promise<EncryptionCapabilities> {\n return {\n textEncryption: true,\n fileEncryption: true,\n bufferEncryption: true,\n streamEncryption: true,\n emailEncryption: true,\n signing: true,\n verification: true,\n keyGeneration: true,\n keyManagement: true,\n multipleRecipients: true,\n symmetricEncryption: false,\n asymmetricEncryption: true,\n };\n }\n}\n"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- import { a as EncryptionError, c as KeyError, d as SignatureError, f as VerificationError, i as EncryptError, l as KeyNotFoundError, n as AlgorithmError, o as FormatError, r as DecryptError, s as InvalidKeyError, t as BaseEncryption, u as PassphraseError } from "./chunks/base-qiu-WiZ0.js";
1
+ import { a as FormatError, c as KeyNotFoundError, d as VerificationError, i as EncryptionError, l as PassphraseError, n as DecryptError, o as InvalidKeyError, r as EncryptError, s as KeyError, t as AlgorithmError, u as SignatureError } from "./chunks/errors-Q_wX_NMz.js";
2
+ import { t as BaseEncryption } from "./chunks/base-COUQhj5x.js";
2
3
  //#region src/shared/factory.ts
3
4
  /**
4
5
  * Type guard to check if options are PGP options
@@ -116,17 +117,17 @@ async function getEncryption(options) {
116
117
  validateCommonOptions(options);
117
118
  if (isPGPOptions(options)) {
118
119
  validatePGPOptions(options);
119
- const { PGPEncryption } = await import("./chunks/pgp-rwlJTWLC.js");
120
+ const { PGPEncryption } = await import("./chunks/pgp-Dss_W-gt.js");
120
121
  return new PGPEncryption(options);
121
122
  }
122
123
  if (isNaClOptions(options)) {
123
124
  validateNaClOptions(options);
124
- const { NaClEncryption } = await import("./chunks/nacl-BElkPprm.js");
125
+ const { NaClEncryption } = await import("./chunks/nacl-Ct71p1KK.js");
125
126
  return new NaClEncryption(options);
126
127
  }
127
128
  if (isNodeCryptoOptions(options)) {
128
129
  validateNodeCryptoOptions(options);
129
- const { NodeCryptoEncryption } = await import("./chunks/node-Bg7R5Icq.js");
130
+ const { NodeCryptoEncryption } = await import("./chunks/node-9IJG40yb.js");
130
131
  return new NodeCryptoEncryption(options);
131
132
  }
132
133
  throw new Error(`Unsupported encryption adapter type: ${options.type}`);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/shared/factory.ts"],"sourcesContent":["import type {\n Encryption,\n GetEncryptionOptions,\n NaClOptions,\n NodeCryptoOptions,\n PGPOptions,\n} from './types.js';\n\n/**\n * Type guard to check if options are PGP options\n */\nexport function isPGPOptions(opts: GetEncryptionOptions): opts is PGPOptions {\n return opts.type === 'pgp';\n}\n\n/**\n * Type guard to check if options are NaCl options\n */\nexport function isNaClOptions(opts: GetEncryptionOptions): opts is NaClOptions {\n return opts.type === 'nacl';\n}\n\n/**\n * Type guard to check if options are Node crypto options\n */\nexport function isNodeCryptoOptions(\n opts: GetEncryptionOptions,\n): opts is NodeCryptoOptions {\n return opts.type === 'node';\n}\n\n/**\n * Validate common options\n */\nfunction validateCommonOptions(options: GetEncryptionOptions): void {\n if (!options.type) {\n throw new Error('Encryption adapter type is required');\n }\n\n const validTypes = ['pgp', 'nacl', 'node'];\n if (!validTypes.includes(options.type)) {\n throw new Error(\n `Invalid encryption adapter type: ${options.type}. Must be one of: ${validTypes.join(', ')}`,\n );\n }\n}\n\n/**\n * Validate PGP-specific options\n */\nfunction validatePGPOptions(options: PGPOptions): void {\n // Validate armor option if provided\n if (options.armor !== undefined && typeof options.armor !== 'boolean') {\n throw new Error('PGP armor option must be a boolean');\n }\n\n // Validate compression option if provided\n if (\n options.compression !== undefined &&\n typeof options.compression !== 'boolean'\n ) {\n throw new Error('PGP compression option must be a boolean');\n }\n\n // PGP requires at least one public key or private key for initialization\n // (keys can also be provided per-operation)\n // Keys are optional - adapter can be created without them (e.g., for key generation)\n}\n\n/**\n * Validate NaCl-specific options\n */\nfunction validateNaClOptions(options: NaClOptions): void {\n // Validate encoding option if provided\n if (options.encoding) {\n const validEncodings = ['base64', 'hex', 'utf8'];\n if (!validEncodings.includes(options.encoding)) {\n throw new Error(\n `Invalid NaCl encoding: ${options.encoding}. Must be one of: ${validEncodings.join(', ')}`,\n );\n }\n }\n\n // Validate key formats if provided as strings\n if (typeof options.secretKey === 'string' && options.secretKey.length === 0) {\n throw new Error('NaCl secret key cannot be empty string');\n }\n\n if (typeof options.publicKey === 'string' && options.publicKey.length === 0) {\n throw new Error('NaCl public key cannot be empty string');\n }\n\n // NaCl requires at least a secret key or public key\n // Keys are optional - adapter can be created without them (e.g., for key generation)\n}\n\n/**\n * Validate Node crypto-specific options\n */\nfunction validateNodeCryptoOptions(options: NodeCryptoOptions): void {\n // Algorithm is required\n if (!options.algorithm) {\n throw new Error('Node crypto algorithm is required');\n }\n\n // Validate encoding option if provided\n if (options.encoding) {\n const validEncodings = ['hex', 'base64', 'utf8'];\n if (!validEncodings.includes(options.encoding)) {\n throw new Error(\n `Invalid Node crypto encoding: ${options.encoding}. Must be one of: ${validEncodings.join(', ')}`,\n );\n }\n }\n\n // Validate key derivation options if provided\n if (options.keyDerivation) {\n if (\n !options.keyDerivation.password ||\n options.keyDerivation.password.trim().length === 0\n ) {\n throw new Error('Key derivation password is required');\n }\n\n if (\n options.keyDerivation.iterations !== undefined &&\n options.keyDerivation.iterations < 1000\n ) {\n throw new Error(\n 'Key derivation iterations must be at least 1000 for security',\n );\n }\n\n if (\n options.keyDerivation.keyLength !== undefined &&\n options.keyDerivation.keyLength < 16\n ) {\n throw new Error('Key derivation key length must be at least 16 bytes');\n }\n }\n\n // Validate symmetric vs asymmetric algorithm requirements\n const symmetricAlgorithms = [\n 'aes-256-gcm',\n 'aes-256-cbc',\n 'aes-128-gcm',\n 'aes-128-cbc',\n ];\n const asymmetricAlgorithms = ['rsa', 'rsa-oaep', 'rsa-pss', 'ecdh', 'ecdsa'];\n\n if (symmetricAlgorithms.includes(options.algorithm)) {\n // Symmetric algorithms need a key or key derivation for encryption/decryption\n // Keys are optional - adapter can be created without them (e.g., for key generation)\n } else if (asymmetricAlgorithms.includes(options.algorithm)) {\n // Asymmetric algorithms need public/private keys for encryption/decryption\n // Keys are optional - adapter can be created without them (e.g., for key generation)\n }\n}\n\n/**\n * Factory function to create encryption adapter instances\n *\n * @example\n * ```typescript\n * // PGP\n * const pgp = await getEncryption({\n * type: 'pgp',\n * publicKey: recipientPublicKey,\n * privateKey: myPrivateKey,\n * passphrase: 'my-passphrase'\n * });\n *\n * // NaCl\n * const nacl = await getEncryption({\n * type: 'nacl',\n * secretKey: mySecretKey\n * });\n *\n * // Node crypto\n * const crypto = await getEncryption({\n * type: 'node',\n * algorithm: 'aes-256-gcm',\n * key: encryptionKey\n * });\n * ```\n */\nexport async function getEncryption(\n options: GetEncryptionOptions,\n): Promise<Encryption> {\n // Validate common options\n validateCommonOptions(options);\n\n // Validate and create adapter based on type\n if (isPGPOptions(options)) {\n validatePGPOptions(options);\n\n // Lazy load PGP adapter (reduces initial bundle size)\n const { PGPEncryption } = await import('../adapters/pgp.js');\n return new PGPEncryption(options);\n }\n\n if (isNaClOptions(options)) {\n validateNaClOptions(options);\n\n // Lazy load NaCl adapter\n const { NaClEncryption } = await import('../adapters/nacl.js');\n return new NaClEncryption(options);\n }\n\n if (isNodeCryptoOptions(options)) {\n validateNodeCryptoOptions(options);\n\n // Lazy load Node crypto adapter\n const { NodeCryptoEncryption } = await import('../adapters/node.js');\n return new NodeCryptoEncryption(options);\n }\n\n // This should never happen due to validateCommonOptions, but TypeScript needs it\n throw new Error(\n `Unsupported encryption adapter type: ${(options as GetEncryptionOptions).type}`,\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/shared/factory.ts"],"sourcesContent":["import type {\n Encryption,\n GetEncryptionOptions,\n NaClOptions,\n NodeCryptoOptions,\n PGPOptions,\n} from './types.js';\n\n/**\n * Type guard to check if options are PGP options\n */\nexport function isPGPOptions(opts: GetEncryptionOptions): opts is PGPOptions {\n return opts.type === 'pgp';\n}\n\n/**\n * Type guard to check if options are NaCl options\n */\nexport function isNaClOptions(opts: GetEncryptionOptions): opts is NaClOptions {\n return opts.type === 'nacl';\n}\n\n/**\n * Type guard to check if options are Node crypto options\n */\nexport function isNodeCryptoOptions(\n opts: GetEncryptionOptions,\n): opts is NodeCryptoOptions {\n return opts.type === 'node';\n}\n\n/**\n * Validate common options\n */\nfunction validateCommonOptions(options: GetEncryptionOptions): void {\n if (!options.type) {\n throw new Error('Encryption adapter type is required');\n }\n\n const validTypes = ['pgp', 'nacl', 'node'];\n if (!validTypes.includes(options.type)) {\n throw new Error(\n `Invalid encryption adapter type: ${options.type}. Must be one of: ${validTypes.join(', ')}`,\n );\n }\n}\n\n/**\n * Validate PGP-specific options\n */\nfunction validatePGPOptions(options: PGPOptions): void {\n // Validate armor option if provided\n if (options.armor !== undefined && typeof options.armor !== 'boolean') {\n throw new Error('PGP armor option must be a boolean');\n }\n\n // Validate compression option if provided\n if (\n options.compression !== undefined &&\n typeof options.compression !== 'boolean'\n ) {\n throw new Error('PGP compression option must be a boolean');\n }\n\n // PGP requires at least one public key or private key for initialization\n // (keys can also be provided per-operation)\n // Keys are optional - adapter can be created without them (e.g., for key generation)\n}\n\n/**\n * Validate NaCl-specific options\n */\nfunction validateNaClOptions(options: NaClOptions): void {\n // Validate encoding option if provided\n if (options.encoding) {\n const validEncodings = ['base64', 'hex', 'utf8'];\n if (!validEncodings.includes(options.encoding)) {\n throw new Error(\n `Invalid NaCl encoding: ${options.encoding}. Must be one of: ${validEncodings.join(', ')}`,\n );\n }\n }\n\n // Validate key formats if provided as strings\n if (typeof options.secretKey === 'string' && options.secretKey.length === 0) {\n throw new Error('NaCl secret key cannot be empty string');\n }\n\n if (typeof options.publicKey === 'string' && options.publicKey.length === 0) {\n throw new Error('NaCl public key cannot be empty string');\n }\n\n // NaCl requires at least a secret key or public key\n // Keys are optional - adapter can be created without them (e.g., for key generation)\n}\n\n/**\n * Validate Node crypto-specific options\n */\nfunction validateNodeCryptoOptions(options: NodeCryptoOptions): void {\n // Algorithm is required\n if (!options.algorithm) {\n throw new Error('Node crypto algorithm is required');\n }\n\n // Validate encoding option if provided\n if (options.encoding) {\n const validEncodings = ['hex', 'base64', 'utf8'];\n if (!validEncodings.includes(options.encoding)) {\n throw new Error(\n `Invalid Node crypto encoding: ${options.encoding}. Must be one of: ${validEncodings.join(', ')}`,\n );\n }\n }\n\n // Validate key derivation options if provided\n if (options.keyDerivation) {\n if (\n !options.keyDerivation.password ||\n options.keyDerivation.password.trim().length === 0\n ) {\n throw new Error('Key derivation password is required');\n }\n\n if (\n options.keyDerivation.iterations !== undefined &&\n options.keyDerivation.iterations < 1000\n ) {\n throw new Error(\n 'Key derivation iterations must be at least 1000 for security',\n );\n }\n\n if (\n options.keyDerivation.keyLength !== undefined &&\n options.keyDerivation.keyLength < 16\n ) {\n throw new Error('Key derivation key length must be at least 16 bytes');\n }\n }\n\n // Validate symmetric vs asymmetric algorithm requirements\n const symmetricAlgorithms = [\n 'aes-256-gcm',\n 'aes-256-cbc',\n 'aes-128-gcm',\n 'aes-128-cbc',\n ];\n const asymmetricAlgorithms = ['rsa', 'rsa-oaep', 'rsa-pss', 'ecdh', 'ecdsa'];\n\n if (symmetricAlgorithms.includes(options.algorithm)) {\n // Symmetric algorithms need a key or key derivation for encryption/decryption\n // Keys are optional - adapter can be created without them (e.g., for key generation)\n } else if (asymmetricAlgorithms.includes(options.algorithm)) {\n // Asymmetric algorithms need public/private keys for encryption/decryption\n // Keys are optional - adapter can be created without them (e.g., for key generation)\n }\n}\n\n/**\n * Factory function to create encryption adapter instances\n *\n * @example\n * ```typescript\n * // PGP\n * const pgp = await getEncryption({\n * type: 'pgp',\n * publicKey: recipientPublicKey,\n * privateKey: myPrivateKey,\n * passphrase: 'my-passphrase'\n * });\n *\n * // NaCl\n * const nacl = await getEncryption({\n * type: 'nacl',\n * secretKey: mySecretKey\n * });\n *\n * // Node crypto\n * const crypto = await getEncryption({\n * type: 'node',\n * algorithm: 'aes-256-gcm',\n * key: encryptionKey\n * });\n * ```\n */\nexport async function getEncryption(\n options: GetEncryptionOptions,\n): Promise<Encryption> {\n // Validate common options\n validateCommonOptions(options);\n\n // Validate and create adapter based on type\n if (isPGPOptions(options)) {\n validatePGPOptions(options);\n\n // Lazy load PGP adapter (reduces initial bundle size)\n const { PGPEncryption } = await import('../adapters/pgp.js');\n return new PGPEncryption(options);\n }\n\n if (isNaClOptions(options)) {\n validateNaClOptions(options);\n\n // Lazy load NaCl adapter\n const { NaClEncryption } = await import('../adapters/nacl.js');\n return new NaClEncryption(options);\n }\n\n if (isNodeCryptoOptions(options)) {\n validateNodeCryptoOptions(options);\n\n // Lazy load Node crypto adapter\n const { NodeCryptoEncryption } = await import('../adapters/node.js');\n return new NodeCryptoEncryption(options);\n }\n\n // This should never happen due to validateCommonOptions, but TypeScript needs it\n throw new Error(\n `Unsupported encryption adapter type: ${(options as GetEncryptionOptions).type}`,\n );\n}\n"],"mappings":";;;;;;AAWA,SAAgB,aAAa,MAAgD;CAC3E,OAAO,KAAK,SAAS;AACvB;;;;AAKA,SAAgB,cAAc,MAAiD;CAC7E,OAAO,KAAK,SAAS;AACvB;;;;AAKA,SAAgB,oBACd,MAC2B;CAC3B,OAAO,KAAK,SAAS;AACvB;;;;AAKA,SAAS,sBAAsB,SAAqC;CAClE,IAAI,CAAC,QAAQ,MACX,MAAM,IAAI,MAAM,qCAAqC;CAGvD,MAAM,aAAa;EAAC;EAAO;EAAQ;CAAM;CACzC,IAAI,CAAC,WAAW,SAAS,QAAQ,IAAI,GACnC,MAAM,IAAI,MACR,oCAAoC,QAAQ,KAAK,oBAAoB,WAAW,KAAK,IAAI,GAC3F;AAEJ;;;;AAKA,SAAS,mBAAmB,SAA2B;CAErD,IAAI,QAAQ,UAAU,KAAA,KAAa,OAAO,QAAQ,UAAU,WAC1D,MAAM,IAAI,MAAM,oCAAoC;CAItD,IACE,QAAQ,gBAAgB,KAAA,KACxB,OAAO,QAAQ,gBAAgB,WAE/B,MAAM,IAAI,MAAM,0CAA0C;AAM9D;;;;AAKA,SAAS,oBAAoB,SAA4B;CAEvD,IAAI,QAAQ,UAAU;EACpB,MAAM,iBAAiB;GAAC;GAAU;GAAO;EAAM;EAC/C,IAAI,CAAC,eAAe,SAAS,QAAQ,QAAQ,GAC3C,MAAM,IAAI,MACR,0BAA0B,QAAQ,SAAS,oBAAoB,eAAe,KAAK,IAAI,GACzF;CAEJ;CAGA,IAAI,OAAO,QAAQ,cAAc,YAAY,QAAQ,UAAU,WAAW,GACxE,MAAM,IAAI,MAAM,wCAAwC;CAG1D,IAAI,OAAO,QAAQ,cAAc,YAAY,QAAQ,UAAU,WAAW,GACxE,MAAM,IAAI,MAAM,wCAAwC;AAK5D;;;;AAKA,SAAS,0BAA0B,SAAkC;CAEnE,IAAI,CAAC,QAAQ,WACX,MAAM,IAAI,MAAM,mCAAmC;CAIrD,IAAI,QAAQ,UAAU;EACpB,MAAM,iBAAiB;GAAC;GAAO;GAAU;EAAM;EAC/C,IAAI,CAAC,eAAe,SAAS,QAAQ,QAAQ,GAC3C,MAAM,IAAI,MACR,iCAAiC,QAAQ,SAAS,oBAAoB,eAAe,KAAK,IAAI,GAChG;CAEJ;CAGA,IAAI,QAAQ,eAAe;EACzB,IACE,CAAC,QAAQ,cAAc,YACvB,QAAQ,cAAc,SAAS,KAAK,CAAC,CAAC,WAAW,GAEjD,MAAM,IAAI,MAAM,qCAAqC;EAGvD,IACE,QAAQ,cAAc,eAAe,KAAA,KACrC,QAAQ,cAAc,aAAa,KAEnC,MAAM,IAAI,MACR,8DACF;EAGF,IACE,QAAQ,cAAc,cAAc,KAAA,KACpC,QAAQ,cAAc,YAAY,IAElC,MAAM,IAAI,MAAM,qDAAqD;CAEzE;CAGA,MAAM,sBAAsB;EAC1B;EACA;EACA;EACA;CACF;CACA,MAAM,uBAAuB;EAAC;EAAO;EAAY;EAAW;EAAQ;CAAO;CAE3E,IAAI,oBAAoB,SAAS,QAAQ,SAAS,GAAG,CAGrD,OAAO,IAAI,qBAAqB,SAAS,QAAQ,SAAS,GAAG,CAG7D;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,eAAsB,cACpB,SACqB;CAErB,sBAAsB,OAAO;CAG7B,IAAI,aAAa,OAAO,GAAG;EACzB,mBAAmB,OAAO;EAG1B,MAAM,EAAE,kBAAkB,MAAM,OAAO;EACvC,OAAO,IAAI,cAAc,OAAO;CAClC;CAEA,IAAI,cAAc,OAAO,GAAG;EAC1B,oBAAoB,OAAO;EAG3B,MAAM,EAAE,mBAAmB,MAAM,OAAO;EACxC,OAAO,IAAI,eAAe,OAAO;CACnC;CAEA,IAAI,oBAAoB,OAAO,GAAG;EAChC,0BAA0B,OAAO;EAGjC,MAAM,EAAE,yBAAyB,MAAM,OAAO;EAC9C,OAAO,IAAI,qBAAqB,OAAO;CACzC;CAGA,MAAM,IAAI,MACR,wCAAyC,QAAiC,MAC5E;AACF"}
@@ -0,0 +1,23 @@
1
+ export interface VaultSnapshotContext {
2
+ accountId: string;
3
+ deviceId: string;
4
+ sequence: bigint;
5
+ }
6
+ export interface SealVaultSnapshotOptions {
7
+ key: Uint8Array;
8
+ /** Opaque 16-byte identifier represented by 32 lowercase hex digits. */
9
+ keyId: string;
10
+ context: VaultSnapshotContext;
11
+ compression?: 'none' | 'zlib';
12
+ }
13
+ export interface OpenVaultSnapshotOptions {
14
+ /** Trusted restore context, supplied independently of the envelope. */
15
+ context: VaultSnapshotContext;
16
+ /** Called once with the untrusted key ID, scoped by the caller to this account. */
17
+ resolveKey: (keyId: string) => Uint8Array | undefined;
18
+ }
19
+ /** Seal a bounded snapshot with a fresh cryptographically random nonce. */
20
+ export declare function sealVaultSnapshot(snapshot: Uint8Array, options: SealVaultSnapshotOptions): Uint8Array;
21
+ /** Authenticate the header and context before decoding any snapshot bytes. */
22
+ export declare function openVaultSnapshot(envelope: Uint8Array, { context, resolveKey }: OpenVaultSnapshotOptions): Uint8Array;
23
+ //# sourceMappingURL=vault-snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault-snapshot.d.ts","sourceRoot":"","sources":["../src/vault-snapshot.ts"],"names":[],"mappings":"AA4BA,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,UAAU,CAAC;IAChB,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,oBAAoB,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,wBAAwB;IACvC,uEAAuE;IACvE,OAAO,EAAE,oBAAoB,CAAC;IAC9B,mFAAmF;IACnF,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;CACvD;AAyCD,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,UAAU,EACpB,OAAO,EAAE,wBAAwB,GAChC,UAAU,CAmCZ;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,UAAU,EACpB,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,wBAAwB,GAChD,UAAU,CAmEZ"}
@@ -0,0 +1,97 @@
1
+ import { a as FormatError, c as KeyNotFoundError, n as DecryptError, o as InvalidKeyError } from "./chunks/errors-Q_wX_NMz.js";
2
+ import { randomBytes, timingSafeEqual } from "node:crypto";
3
+ import { deflateSync, inflateSync } from "node:zlib";
4
+ import nacl from "tweetnacl";
5
+ //#region src/vault-snapshot.ts
6
+ var MAGIC = Buffer.from("HVSE");
7
+ var VERSION = 1;
8
+ var ALGORITHM = 1;
9
+ var KEY_ID_OFFSET = 7;
10
+ var NONCE_OFFSET = 23;
11
+ var HEADER_BYTES = NONCE_OFFSET + nacl.secretbox.nonceLength;
12
+ var MAX_ID_BYTES = 255;
13
+ var MIN_CONTEXT_BYTES = 12;
14
+ var MAX_CONTEXT_BYTES = 520;
15
+ var MAX_SNAPSHOT_BYTES = 8 * 1024 * 1024;
16
+ var MAX_ENCODED_BYTES = 8454144;
17
+ var MAX_ENVELOPE_BYTES = 2 * HEADER_BYTES + nacl.secretbox.overheadLength + MAX_CONTEXT_BYTES + MAX_ENCODED_BYTES;
18
+ var MAX_SEQUENCE = (1n << 64n) - 1n;
19
+ function encodeId(id) {
20
+ if (typeof id !== "string" || id.length === 0 || id.length > MAX_ID_BYTES) throw new FormatError("Invalid vault snapshot context ID");
21
+ const bytes = Buffer.from(id, "utf8");
22
+ if (bytes.length > MAX_ID_BYTES || bytes.toString("utf8") !== id) throw new FormatError("Invalid vault snapshot context ID");
23
+ return bytes;
24
+ }
25
+ function encodeContext(context) {
26
+ const { accountId, deviceId, sequence } = context;
27
+ const account = encodeId(accountId);
28
+ const device = encodeId(deviceId);
29
+ if (typeof sequence !== "bigint" || sequence < 0n || sequence > MAX_SEQUENCE) throw new FormatError("Invalid vault snapshot sequence");
30
+ const counter = Buffer.alloc(8);
31
+ counter.writeBigUInt64BE(sequence);
32
+ return Buffer.concat([
33
+ Buffer.of(account.length),
34
+ account,
35
+ Buffer.of(device.length),
36
+ device,
37
+ counter
38
+ ]);
39
+ }
40
+ function checkKey(key) {
41
+ if (!(key instanceof Uint8Array) || key.length !== nacl.secretbox.keyLength) throw new InvalidKeyError("Vault snapshot key must be 32 bytes");
42
+ }
43
+ /** Seal a bounded snapshot with a fresh cryptographically random nonce. */
44
+ function sealVaultSnapshot(snapshot, options) {
45
+ const { key, keyId, context, compression = "none" } = options;
46
+ checkKey(key);
47
+ if (!(snapshot instanceof Uint8Array) || snapshot.length > MAX_SNAPSHOT_BYTES) throw new FormatError("Invalid vault snapshot size");
48
+ if (typeof keyId !== "string" || keyId.length !== 32 || /[^0-9a-f]/.test(keyId)) throw new FormatError("Invalid vault snapshot key ID");
49
+ if (compression !== "none" && compression !== "zlib") throw new FormatError("Unsupported vault snapshot compression");
50
+ const contextBytes = encodeContext(context);
51
+ const nonce = randomBytes(nacl.secretbox.nonceLength);
52
+ const header = Buffer.concat([
53
+ MAGIC,
54
+ Buffer.of(VERSION, ALGORITHM, compression === "zlib" ? 1 : 0),
55
+ Buffer.from(keyId, "hex"),
56
+ nonce
57
+ ]);
58
+ const payload = compression === "zlib" ? deflateSync(snapshot, { maxOutputLength: MAX_ENCODED_BYTES }) : snapshot;
59
+ const message = Buffer.concat([
60
+ header,
61
+ contextBytes,
62
+ payload
63
+ ]);
64
+ return Buffer.concat([header, nacl.secretbox(message, nonce, key)]);
65
+ }
66
+ /** Authenticate the header and context before decoding any snapshot bytes. */
67
+ function openVaultSnapshot(envelope, { context, resolveKey }) {
68
+ const minBytes = 2 * HEADER_BYTES + MIN_CONTEXT_BYTES + nacl.secretbox.overheadLength;
69
+ if (!(envelope instanceof Uint8Array) || envelope.length < minBytes || envelope.length > MAX_ENVELOPE_BYTES) throw new FormatError("Invalid vault snapshot envelope size");
70
+ const bytes = Buffer.from(envelope);
71
+ if (!bytes.subarray(0, MAGIC.length).equals(MAGIC) || bytes[4] !== VERSION || bytes[5] !== ALGORITHM || bytes[6] !== 0 && bytes[6] !== 1) throw new FormatError("Unsupported vault snapshot header");
72
+ const prefix = Buffer.concat([bytes.subarray(0, HEADER_BYTES), encodeContext(context)]);
73
+ const payloadLength = bytes.length - HEADER_BYTES - nacl.secretbox.overheadLength - prefix.length;
74
+ const compressed = bytes[6] === 1;
75
+ if (payloadLength < 0 || payloadLength > (compressed ? MAX_ENCODED_BYTES : MAX_SNAPSHOT_BYTES)) throw new FormatError("Invalid vault snapshot payload size");
76
+ const keyId = bytes.toString("hex", KEY_ID_OFFSET, NONCE_OFFSET);
77
+ const key = resolveKey(keyId);
78
+ if (key === void 0) throw new KeyNotFoundError("Vault snapshot key not found", keyId);
79
+ checkKey(key);
80
+ const nonce = bytes.subarray(NONCE_OFFSET, HEADER_BYTES);
81
+ const message = nacl.secretbox.open(bytes.subarray(HEADER_BYTES), nonce, key);
82
+ if (!message || !timingSafeEqual(prefix, message.subarray(0, prefix.length))) throw new DecryptError("Vault snapshot authentication failed");
83
+ const payload = message.subarray(prefix.length);
84
+ if (!compressed) return payload.slice();
85
+ try {
86
+ const result = inflateSync(payload, {
87
+ info: true,
88
+ maxOutputLength: MAX_SNAPSHOT_BYTES
89
+ });
90
+ if (result.engine.bytesWritten === payload.length) return result.buffer;
91
+ } catch {}
92
+ throw new DecryptError("Invalid vault snapshot compression payload");
93
+ }
94
+ //#endregion
95
+ export { openVaultSnapshot, sealVaultSnapshot };
96
+
97
+ //# sourceMappingURL=vault-snapshot.js.map