/**
 * HSM Provider Interface and Base Implementations
 * Provides abstraction layer for Hardware Security Module operations
 */
import { EventEmitter } from 'events';
import * as crypto from 'crypto';
/**
 * Supported key types
 */
export var KeyType;
(function (KeyType) {
    KeyType["AES"] = "AES";
    KeyType["RSA"] = "RSA";
    KeyType["EC"] = "EC";
    KeyType["HMAC"] = "HMAC";
    KeyType["DES3"] = "3DES";
    KeyType["CHACHA20"] = "CHACHA20";
})(KeyType || (KeyType = {}));
/**
 * Supported elliptic curves
 */
export var ECCurve;
(function (ECCurve) {
    ECCurve["P256"] = "P-256";
    ECCurve["P384"] = "P-384";
    ECCurve["P521"] = "P-521";
    ECCurve["SECP256K1"] = "secp256k1";
    ECCurve["ED25519"] = "Ed25519";
})(ECCurve || (ECCurve = {}));
/**
 * Key usage permissions
 */
export var KeyUsage;
(function (KeyUsage) {
    KeyUsage["ENCRYPT"] = "encrypt";
    KeyUsage["DECRYPT"] = "decrypt";
    KeyUsage["SIGN"] = "sign";
    KeyUsage["VERIFY"] = "verify";
    KeyUsage["WRAP"] = "wrap";
    KeyUsage["UNWRAP"] = "unwrap";
    KeyUsage["DERIVE"] = "derive";
})(KeyUsage || (KeyUsage = {}));
/**
 * Supported signing algorithms
 */
export var SigningAlgorithm;
(function (SigningAlgorithm) {
    SigningAlgorithm["RSASSA_PKCS1_V1_5_SHA256"] = "RSASSA-PKCS1-v1_5-SHA256";
    SigningAlgorithm["RSASSA_PKCS1_V1_5_SHA384"] = "RSASSA-PKCS1-v1_5-SHA384";
    SigningAlgorithm["RSASSA_PKCS1_V1_5_SHA512"] = "RSASSA-PKCS1-v1_5-SHA512";
    SigningAlgorithm["RSASSA_PSS_SHA256"] = "RSASSA-PSS-SHA256";
    SigningAlgorithm["RSASSA_PSS_SHA384"] = "RSASSA-PSS-SHA384";
    SigningAlgorithm["RSASSA_PSS_SHA512"] = "RSASSA-PSS-SHA512";
    SigningAlgorithm["ECDSA_SHA256"] = "ECDSA-SHA256";
    SigningAlgorithm["ECDSA_SHA384"] = "ECDSA-SHA384";
    SigningAlgorithm["ECDSA_SHA512"] = "ECDSA-SHA512";
    SigningAlgorithm["ED25519"] = "Ed25519";
    SigningAlgorithm["HMAC_SHA256"] = "HMAC-SHA256";
    SigningAlgorithm["HMAC_SHA384"] = "HMAC-SHA384";
    SigningAlgorithm["HMAC_SHA512"] = "HMAC-SHA512";
})(SigningAlgorithm || (SigningAlgorithm = {}));
/**
 * Supported encryption algorithms
 */
export var EncryptionAlgorithm;
(function (EncryptionAlgorithm) {
    EncryptionAlgorithm["AES_GCM"] = "AES-GCM";
    EncryptionAlgorithm["AES_CBC"] = "AES-CBC";
    EncryptionAlgorithm["AES_CTR"] = "AES-CTR";
    EncryptionAlgorithm["RSA_OAEP_SHA256"] = "RSA-OAEP-SHA256";
    EncryptionAlgorithm["RSA_OAEP_SHA384"] = "RSA-OAEP-SHA384";
    EncryptionAlgorithm["RSA_OAEP_SHA512"] = "RSA-OAEP-SHA512";
    EncryptionAlgorithm["CHACHA20_POLY1305"] = "CHACHA20-POLY1305";
})(EncryptionAlgorithm || (EncryptionAlgorithm = {}));
// ============================================================================
// Base HSM Provider Implementation
// ============================================================================
/**
 * Abstract base class for HSM providers
 * Provides common functionality and enforces interface compliance
 */
export class BaseHSMProvider extends EventEmitter {
    config;
    connected = false;
    auditLogs = [];
    keys = new Map();
    constructor(config) {
        super();
        this.config = {
            connectionTimeout: 30000,
            operationTimeout: 60000,
            auditLogging: true,
            retry: {
                maxAttempts: 3,
                initialDelay: 100,
                maxDelay: 5000,
                backoffMultiplier: 2,
            },
            ...config,
        };
    }
    /**
     * Log an audit entry
     */
    logAudit(entry) {
        if (!this.config.auditLogging)
            return;
        const fullEntry = {
            ...entry,
            timestamp: new Date(),
        };
        this.auditLogs.push(fullEntry);
        this.emit('audit', fullEntry);
        // Keep only last 10000 entries in memory
        if (this.auditLogs.length > 10000) {
            this.auditLogs = this.auditLogs.slice(-10000);
        }
    }
    /**
     * Execute operation with retry
     */
    async withRetry(operation, operationName) {
        const { maxAttempts, initialDelay, maxDelay, backoffMultiplier } = this.config.retry;
        let lastError;
        let delay = initialDelay;
        for (let attempt = 1; attempt <= maxAttempts; attempt++) {
            try {
                return await operation();
            }
            catch (error) {
                lastError = error instanceof Error ? error : new Error(String(error));
                if (attempt < maxAttempts) {
                    this.emit('retry', { operation: operationName, attempt, error: lastError });
                    await this.sleep(delay);
                    delay = Math.min(delay * backoffMultiplier, maxDelay);
                }
            }
        }
        throw lastError;
    }
    /**
     * Sleep utility
     */
    sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
    /**
     * Generate a unique key ID
     */
    generateKeyId() {
        return `key-${Date.now()}-${crypto.randomBytes(8).toString('hex')}`;
    }
    /**
     * Validate key spec
     */
    validateKeySpec(spec) {
        if (!spec.label) {
            throw new Error('Key label is required');
        }
        if (!spec.type) {
            throw new Error('Key type is required');
        }
        if (!spec.usage || spec.usage.length === 0) {
            throw new Error('At least one key usage must be specified');
        }
        // Type-specific validation
        switch (spec.type) {
            case KeyType.AES:
                if (spec.size && ![128, 192, 256].includes(spec.size)) {
                    throw new Error('AES key size must be 128, 192, or 256 bits');
                }
                break;
            case KeyType.RSA:
                if (spec.size && spec.size < 2048) {
                    throw new Error('RSA key size must be at least 2048 bits');
                }
                break;
            case KeyType.EC:
                if (!spec.curve) {
                    throw new Error('EC curve must be specified');
                }
                break;
        }
    }
    /**
     * Get key or throw
     */
    getKeyOrThrow(keyHandle) {
        const key = this.keys.get(keyHandle);
        if (!key) {
            throw new Error(`Key not found: ${keyHandle}`);
        }
        return key;
    }
    /**
     * Validate key usage
     */
    validateKeyUsage(key, requiredUsage) {
        if (!key.usage.includes(requiredUsage)) {
            throw new Error(`Key ${key.id} does not permit ${requiredUsage} operation`);
        }
    }
    /**
     * Ensure connected
     */
    ensureConnected() {
        if (!this.connected) {
            throw new Error('HSM is not connected');
        }
    }
    /**
     * Get audit logs
     */
    async getAuditLogs(startTime, endTime) {
        let logs = [...this.auditLogs];
        if (startTime) {
            logs = logs.filter(log => log.timestamp >= startTime);
        }
        if (endTime) {
            logs = logs.filter(log => log.timestamp <= endTime);
        }
        return logs;
    }
}
// ============================================================================
// HSM Error Types
// ============================================================================
export class HSMError extends Error {
    code;
    provider;
    cause;
    constructor(message, code, provider, cause) {
        super(message);
        this.code = code;
        this.provider = provider;
        this.cause = cause;
        this.name = 'HSMError';
    }
}
export class HSMConnectionError extends HSMError {
    constructor(message, provider, cause) {
        super(message, 'CONNECTION_ERROR', provider, cause);
        this.name = 'HSMConnectionError';
    }
}
export class HSMKeyNotFoundError extends HSMError {
    constructor(keyId, provider) {
        super(`Key not found: ${keyId}`, 'KEY_NOT_FOUND', provider);
        this.name = 'HSMKeyNotFoundError';
    }
}
export class HSMOperationError extends HSMError {
    constructor(operation, message, provider, cause) {
        super(`${operation} failed: ${message}`, 'OPERATION_ERROR', provider, cause);
        this.name = 'HSMOperationError';
    }
}
export class HSMPermissionError extends HSMError {
    constructor(message, provider) {
        super(message, 'PERMISSION_DENIED', provider);
        this.name = 'HSMPermissionError';
    }
}
//# sourceMappingURL=provider.js.map