"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.KeyImporter = void 0;
const webcrypto_1 = require("@peculiar/webcrypto");
const utils_1 = require("../utils");
const elliptic_1 = require("elliptic");
const asn1_ecc_1 = require("@peculiar/asn1-ecc");
const asn1_schema_1 = require("@peculiar/asn1-schema");
const asn1_pkcs8_1 = require("@peculiar/asn1-pkcs8");
const asn1_x509_1 = require("@peculiar/asn1-x509");
const defaultKeyPrefs = {
    algorithm: "ECDSA",
    curve: "K-256"
};
class KeyImporter {
    constructor(keyPreferences = defaultKeyPrefs, ecKey) {
        this.keyPreferences = keyPreferences;
        this.ecKey = ecKey;
        this.crypto = new webcrypto_1.Crypto();
        // TODO: algorithm initialization
    }
    static fromPrivate(hex, keyPreferences = defaultKeyPrefs) {
        if (keyPreferences.algorithm === "ECDSA") {
            if (keyPreferences.curve === "K-256") {
                let ec = new elliptic_1.ec('secp256k1');
                // TODO: Support base64 & pem encoding
                return new KeyImporter(keyPreferences, ec.keyFromPrivate((0, utils_1.hexStringToUint8)(hex)));
            }
        }
        throw new Error("Key algorithm or curve is not supported!");
    }
    static fromPublic(hex, keyPreferences = defaultKeyPrefs) {
        if (keyPreferences.algorithm === "ECDSA") {
            if (keyPreferences.curve === "K-256") {
                let ec = new elliptic_1.ec('secp256k1');
                return new KeyImporter(keyPreferences, ec.keyFromPublic((0, utils_1.hexStringToUint8)(hex)));
            }
        }
        throw new Error("Key algorithm or curve is not supported!");
    }
    getPublicKey() {
        const pub = this.ecKey.getPublic().encode("array", false);
        return this.crypto.subtle.importKey("raw", new Uint8Array(pub), {
            name: this.keyPreferences.algorithm,
            namedCurve: this.keyPreferences.curve
        }, true, ["verify"]);
    }
    getRawPublicKey() {
        return new Uint8Array(this.ecKey.getPublic().encode("array", false));
    }
    getPrivateKey() {
        const priv = this.getPkcs8FromECKey(this.ecKey);
        return this.crypto.subtle.importKey("pkcs8", priv, {
            name: this.keyPreferences.algorithm,
            namedCurve: this.keyPreferences.curve
        }, true, ["sign"]);
    }
    getPkcs8FromECKey(keyPair) {
        let ecKeyInfo = new asn1_ecc_1.ECPrivateKey();
        ecKeyInfo.version = 1;
        ecKeyInfo.parameters = new asn1_ecc_1.ECParameters();
        ecKeyInfo.parameters.namedCurve = "1.3.132.0.10";
        ecKeyInfo.privateKey = new asn1_schema_1.OctetString((0, utils_1.hexStringToUint8)(keyPair.getPrivate().toString("hex")));
        ecKeyInfo.publicKey = (0, utils_1.hexStringToUint8)(keyPair.getPublic().encode("hex", false));
        let ecParams = new asn1_ecc_1.ECParameters();
        ecParams.namedCurve = "1.3.132.0.10";
        let convertedAsn = new asn1_pkcs8_1.PrivateKeyInfo();
        convertedAsn.version = 0;
        convertedAsn.privateKeyAlgorithm = new asn1_x509_1.AlgorithmIdentifier({
            algorithm: "1.2.840.10045.2.1",
            parameters: asn1_schema_1.AsnSerializer.serialize(ecParams)
        });
        convertedAsn.privateKey = new asn1_schema_1.OctetString(asn1_schema_1.AsnSerializer.serialize(ecKeyInfo));
        return new Uint8Array(asn1_schema_1.AsnSerializer.serialize(convertedAsn));
    }
}
exports.KeyImporter = KeyImporter;
