// ══════════════════════════════════════════════════════════════════
// Key Storage Backend — B-10 Security Hardening
// ══════════════════════════════════════════════════════════════════
// Pluggable key storage interface. Reference implementation stores
// keys in memory (same as before). Production deployments should
// implement encrypted file, HSM, or KMS backends.
//
// WARNING: The default InMemoryKeyStorage stores keys as raw hex
// in process memory. This is NOT safe for production. Use
// EncryptedFileKeyStorage or implement your own backend.
// ══════════════════════════════════════════════════════════════════
import { createCipheriv, createDecipheriv, randomBytes, scryptSync } from 'crypto';
/**
 * Default in-memory key storage. Keys stored as raw hex in a Map.
 * WARNING: Not safe for production — keys lost on process restart,
 * no encryption at rest.
 */
export class InMemoryKeyStorage {
    keys = new Map();
    async store(agentId, privateKey, publicKey) {
        this.keys.set(agentId, { privateKey, publicKey });
    }
    async retrieve(agentId) {
        return this.keys.get(agentId) ?? null;
    }
    async delete(agentId) {
        return this.keys.delete(agentId);
    }
    async list() {
        return Array.from(this.keys.keys());
    }
}
/**
 * Encrypted file key storage. Keys encrypted with AES-256-GCM
 * using a password-derived key (scrypt). Stores as JSON file.
 * Better than raw hex — suitable for development and testing.
 * For production, implement HSM/KMS backend.
 */
export class EncryptedFileKeyStorage {
    password;
    filePath;
    cache = new Map();
    loaded = false;
    constructor(filePath, password) {
        this.filePath = filePath;
        this.password = password;
    }
    encrypt(plaintext) {
        const salt = randomBytes(16);
        const key = scryptSync(this.password, salt, 32);
        const iv = randomBytes(12);
        const cipher = createCipheriv('aes-256-gcm', key, iv);
        const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
        const tag = cipher.getAuthTag();
        return [salt, iv, tag, encrypted].map(b => b.toString('hex')).join(':');
    }
    decrypt(ciphertext) {
        const [saltHex, ivHex, tagHex, encHex] = ciphertext.split(':');
        const salt = Buffer.from(saltHex, 'hex');
        const iv = Buffer.from(ivHex, 'hex');
        const tag = Buffer.from(tagHex, 'hex');
        const encrypted = Buffer.from(encHex, 'hex');
        const key = scryptSync(this.password, salt, 32);
        const decipher = createDecipheriv('aes-256-gcm', key, iv);
        decipher.setAuthTag(tag);
        return decipher.update(encrypted) + decipher.final('utf8');
    }
    async load() {
        if (this.loaded)
            return;
        try {
            const { readFile } = await import('fs/promises');
            const data = JSON.parse(await readFile(this.filePath, 'utf8'));
            for (const [id, enc] of Object.entries(data)) {
                const decrypted = JSON.parse(this.decrypt(enc));
                this.cache.set(id, decrypted);
            }
        }
        catch { /* file doesn't exist yet */ }
        this.loaded = true;
    }
    async save() {
        const { writeFile } = await import('fs/promises');
        const data = {};
        for (const [id, keys] of this.cache) {
            data[id] = this.encrypt(JSON.stringify(keys));
        }
        await writeFile(this.filePath, JSON.stringify(data, null, 2));
    }
    async store(agentId, privateKey, publicKey) {
        await this.load();
        this.cache.set(agentId, { privateKey, publicKey });
        await this.save();
    }
    async retrieve(agentId) {
        await this.load();
        return this.cache.get(agentId) ?? null;
    }
    async delete(agentId) {
        await this.load();
        const deleted = this.cache.delete(agentId);
        if (deleted)
            await this.save();
        return deleted;
    }
    async list() {
        await this.load();
        return Array.from(this.cache.keys());
    }
}
//# sourceMappingURL=key-storage.js.map