import { CryptoSystem, KeyUse } from "keystore-idb/types.js";
import config from "keystore-idb/config.js";
import aes from "keystore-idb/aes/index.js";
import rsa from "keystore-idb/rsa/index.js";
import utils from "keystore-idb/utils.js";
export default class InMemoryRSAKeyStore {
    constructor(cfg, exchangeKeyPair, writeKeyPair) {
        this.cfg = cfg;
        this.inMemoryStore = {};
        this.exchangeKeyPair = exchangeKeyPair;
        this.writeKeyPair = writeKeyPair;
    }
    static async init(maybeCfg) {
        const cfg = config.normalize({
            ...(maybeCfg || {}),
            type: CryptoSystem.RSA
        });
        const { rsaSize, hashAlg } = cfg;
        const exchangeKeyPair = await rsa.makeKeypair(rsaSize, hashAlg, KeyUse.Exchange);
        const writeKeyPair = await rsa.makeKeypair(rsaSize, hashAlg, KeyUse.Write);
        return new InMemoryRSAKeyStore(cfg, exchangeKeyPair, writeKeyPair);
    }
    async exchangeKey() {
        return this.exchangeKeyPair;
    }
    async writeKey() {
        return this.writeKeyPair;
    }
    async getSymmKey(keyName, cfg) {
        const mergedCfg = config.merge(this.cfg, cfg);
        const maybeKey = this.inMemoryStore[keyName];
        if (maybeKey !== null) {
            return maybeKey;
        }
        const key = await aes.makeKey(config.symmKeyOpts(mergedCfg));
        this.inMemoryStore[keyName] = key;
        return key;
    }
    async keyExists(keyName) {
        const key = this.inMemoryStore[keyName];
        return key !== null;
    }
    async deleteKey(keyName) {
        delete this.inMemoryStore[keyName];
    }
    async destroy() {
        this.inMemoryStore = {};
    }
    async importSymmKey(keyStr, keyName, cfg) {
        const mergedCfg = config.merge(this.cfg, cfg);
        const key = await aes.importKey(keyStr, config.symmKeyOpts(mergedCfg));
        this.inMemoryStore[keyName] = key;
    }
    async exportSymmKey(keyName, cfg) {
        const key = await this.getSymmKey(keyName, cfg);
        return await aes.exportKey(key);
    }
    async encryptWithSymmKey(msg, keyName, cfg) {
        const mergedCfg = config.merge(this.cfg, cfg);
        const key = await this.getSymmKey(keyName, cfg);
        const cipherText = await aes.encryptBytes(utils.strToArrBuf(msg, mergedCfg.charSize), key, config.symmKeyOpts(mergedCfg));
        return utils.arrBufToBase64(cipherText);
    }
    async decryptWithSymmKey(cipherText, keyName, cfg) {
        const mergedCfg = config.merge(this.cfg, cfg);
        const key = await this.getSymmKey(keyName, cfg);
        const msgBytes = await aes.decryptBytes(utils.base64ToArrBuf(cipherText), key, config.symmKeyOpts(mergedCfg));
        return utils.arrBufToStr(msgBytes, mergedCfg.charSize);
    }
    async sign(msg, cfg) {
        const mergedCfg = config.merge(this.cfg, cfg);
        const writeKey = await this.writeKey();
        if (!writeKey.privateKey)
            throw new Error("Missing private key in write key-pair");
        return utils.arrBufToBase64(await rsa.sign(msg, writeKey.privateKey, mergedCfg.charSize));
    }
    async verify(msg, sig, publicKey, cfg) {
        const mergedCfg = config.merge(this.cfg, cfg);
        return await rsa.verify(msg, sig, publicKey, mergedCfg.charSize, mergedCfg.hashAlg);
    }
    async encrypt(msg, publicKey, cfg) {
        const mergedCfg = config.merge(this.cfg, cfg);
        return utils.arrBufToBase64(await rsa.encrypt(msg, publicKey, mergedCfg.charSize, mergedCfg.hashAlg));
    }
    async decrypt(cipherText, publicKey, // unused param so that keystore interfaces match
    cfg) {
        const exchangeKey = await this.exchangeKey();
        const mergedCfg = config.merge(this.cfg, cfg);
        if (!exchangeKey.privateKey)
            throw new Error("Missing private key in exchange key-pair");
        return utils.arrBufToStr(await rsa.decrypt(cipherText, exchangeKey.privateKey), mergedCfg.charSize);
    }
    async publicExchangeKey() {
        const exchangeKey = await this.exchangeKey();
        return rsa.getPublicKey(exchangeKey);
    }
    async publicWriteKey() {
        const writeKey = await this.writeKey();
        return rsa.getPublicKey(writeKey);
    }
}
//# sourceMappingURL=memory.js.map