aere-quantum/pq-kms/test/proba-hsm-incredere.mjs

42 lines
3.7 KiB
JavaScript

// test/proba-hsm-incredere.mjs (2026-09-29, revizuirea adversariala a feliei HSM, H1): fisierul sigilat NU alege biblioteca PKCS#11 si
// nici variabila de mediu trimisa drept PIN. Nu cere un HSM: unealta primita e o cale care NU exista, deci orice verificare care lasa
// cererea sa ajunga la unealta se vede ca HSM_TOOL_MISSING, iar un refuz dat INAINTE de unealta are codul lui. Controlul pozitiv al
// metodei: o sigilare corecta ajunge chiar la unealta (HSM_TOOL_MISSING), deci refuzurile de mai jos nu vin din altceva.
// node test/proba-hsm-incredere.mjs -> 0 toate cum trebuia, 1 altfel
// AERE_HSM_MODUL_SUB_PROBA=<cale> numai pentru controlul negativ (o copie plantata a modulului)
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
const AICI = path.dirname(fileURLToPath(import.meta.url));
const MOD = process.env.AERE_HSM_MODUL_SUB_PROBA || path.join(AICI, '..', 'hsm-radacina.mjs');
const { deschideRadacina, radacinaDinHsm, FORMAT_HSM } = await import(pathToFileURL(MOD).href);
let rele = 0, n = 0;
const cer = (nume, ok, extra = '') => { n++; console.log(` [${ok ? 'OK ' : 'RAU '}] ${nume}${extra ? ' (' + extra + ')' : ''}`); if (!ok) rele++; };
const codul = (fn) => { try { fn(); return 'FARA REFUZ'; } catch (e) { return e.code || String(e.message).slice(0, 60); } };
const LIB = path.resolve('/usr/lib/softhsm/libsofthsm2.so');
const RAU = path.resolve('/tmp/biblioteca-straina.so');
const UNEALTA = path.join(os.tmpdir(), 'nu-exista-' + process.pid, 'pkcs11-tool');
const sig = { format: FORMAT_HSM, mecanism: 'AES-CBC-PAD', modul: LIB, token: 'aere-kms', idCheie: '0a', pinEnv: 'AERE_HSM_PIN', iv: '00'.repeat(16), ct: '11'.repeat(64) };
const env = { AERE_HSM_PIN: '483920', AERE_HSM_MODULE: LIB, AERE_KMS_TOKEN: 'AERE-SINTETIC-jeton-api-care-nu-trebuie-trimis-ca-pin' };
const deschide = (s, e = env) => codul(() => deschideRadacina(s, { env: e, unealta: UNEALTA }));
cer('CONTROL POZITIV: o sigilare corecta ajunge la unealta (HSM_TOOL_MISSING aici), deci refuzurile de mai jos vin din verificari', deschide(sig) === 'HSM_TOOL_MISSING', deschide(sig));
cer('H1: o biblioteca din fisier, alta decat AERE_HSM_MODULE -> HSM_MODULE_NOT_ALLOWED, fara sa ruleze unealta', deschide({ ...sig, modul: RAU }) === 'HSM_MODULE_NOT_ALLOWED', deschide({ ...sig, modul: RAU }));
cer('H1: fara AERE_HSM_MODULE -> HSM_CONFIG_INVALID (fisierul singur nu alege biblioteca)', deschide(sig, { ...env, AERE_HSM_MODULE: '' }) === 'HSM_CONFIG_INVALID');
cer('H1: AERE_HSM_MODULE relativ -> HSM_CONFIG_INVALID', deschide(sig, { ...env, AERE_HSM_MODULE: 'libsofthsm2.so' }) === 'HSM_CONFIG_INVALID');
cer('H1: fisierul cere alta variabila drept PIN (jetonul API) -> HSM_SEAL_INVALID, fara sa ruleze unealta', deschide({ ...sig, pinEnv: 'AERE_KMS_TOKEN' }) === 'HSM_SEAL_INVALID', deschide({ ...sig, pinEnv: 'AERE_KMS_TOKEN' }));
const { pinEnv, ...faraPinEnv } = sig;
cer('o sigilare fara camp pinEnv (PIN-ul din AERE_HSM_PIN) ajunge la unealta', deschide(faraPinEnv) === 'HSM_TOOL_MISSING');
// drumul serverului: AERE_KMS_ROOT_HSM spre un fisier cu biblioteca straina
const T = fs.mkdtempSync(path.join(os.tmpdir(), 'hsm-incredere-'));
try {
const f = path.join(T, 'root-hsm.json'); fs.writeFileSync(f, JSON.stringify({ ...sig, modul: RAU }));
cer('H1 pe drumul serverului: AERE_KMS_ROOT_HSM cu biblioteca straina -> HSM_MODULE_NOT_ALLOWED', codul(() => radacinaDinHsm({ ...env, AERE_KMS_ROOT_HSM: f }, { unealta: UNEALTA })) === 'HSM_MODULE_NOT_ALLOWED');
} finally { fs.rmSync(T, { recursive: true, force: true }); }
console.log(`\nincrederea in fisierul sigilat (H1): ${n - rele}/${n} cum trebuia`);
process.exitCode = rele ? 1 : 0;