Aller au contenu

Scellement & le ledger

Tant que le scellement a lieu dans la passerelle, la clé de signature et le journal cohabitent sur un même hôte : qui la compromet peut réécrire le journal et le re-sceller, et les points de contrôle certifient alors la version de l’histoire écrite par l’attaquant.

obsign-ledger s’exécute ailleurs (une autre machine, ou une tâche cron sous une autre identité), lit le WAL sans jamais y écrire, et scelle avec une clé que la passerelle ne détient jamais :

Fenêtre de terminal
openssl rand -hex 32 > /tmp/demo/seal-seed.hex
obsign-ledger seal \
--wal /tmp/demo/wal --chain-id demo \
--store /tmp/demo/ledger \
--key /tmp/demo/seal-seed.hex --key-id seal-prod
obsign-ledger export \
--wal /tmp/demo/wal --chain-id demo \
--store /tmp/demo/ledger --out /tmp/demo/evidence.json

Avant de sceller quoi que ce soit de nouveau, le ledger recalcule le hachage de l’enregistrement à la frontière scellée et le compare à la tête scellée. Un WAL réécrit, même un WAL dont la chaîne a été entièrement recalculée et est cohérente en interne, est refusé avec DivergedLog, et le mode run sort avec un code non nul dans ce cas : une divergence ne se répare jamais d’elle-même, et boucler dessus transformerait un incident en battement de cœur. Sortir n’est que la moitié de l’alerte. Qui est prévenu relève du superviseur : Alerter sur une divergence.

Le fichier de clé hexadécimale est de qualité développement par construction. La signature passe par le trait Sealer, qui constitue la frontière KMS/HSM. L’implémentation de production est Pkcs11Sealer : la clé vit dans un HSM derrière le module PKCS#11 du fournisseur, et n’entre pas davantage dans le processus du ledger.

Fenêtre de terminal
obsign-ledger seal \
--wal /tmp/demo/wal --chain-id demo \
--store /tmp/demo/ledger \
--hsm-module /usr/lib/pkcs11/vendor.so \
--hsm-key-label seal-prod \
--hsm-pin-file /etc/obsign/hsm-pin \
--key-id seal-prod

PKCS#11 est l’interface dont les déploiements visés disposent réellement : HSM sur site (Trustway, Luna, YubiHSM), middleware de carte à puce, SoftHSM en développement. C’est aussi un appel de bibliothèque local, si bien que le ledger lui-même ne fait toujours aucun appel réseau. Un KMS cloud serait une autre implémentation du même trait ; ce n’est délibérément pas celle-ci. Les liaisons sont écrites à la main au-dessus de dlopen, limitées aux sept appels dont le scellement a besoin, sans embarquer une crate de binding qui en traîne soixante et un autres.

Propriétés opérationnelles :

  • Le PIN vient d’un fichier ou de OBSIGN_HSM_PIN, jamais d’un argument (les arguments finissent dans ps et dans l’historique du shell).
  • Tout ce qui peut être mal configuré échoue au démarrage, avec le code d’erreur du fournisseur en clair : mauvais PIN, clé absente, clé P-256 sous un label qui devrait être Ed25519.
  • Le trait Sealer auto-vérifie chaque signature avant qu’elle ne soit persistée. Un emplacement de clé HSM mal configuré échoue au moment du scellement, pas vingt-quatre mois plus tard devant un auditeur.
  • En mode run, le PIN est présenté exactement une fois, au démarrage : une boucle de nouvelle tentative représentant un PIN erroné mènerait le token jusqu’à CKR_PIN_LOCKED.

Ce que le HSM apporte : un hôte de ledger compromis peut signer maintenant, mais ne peut pas exfiltrer la clé et re-sceller l’histoire plus tard, hors ligne, à loisir. Ce qu’il n’apporte pas : le HSM ne peut pas savoir si un point de contrôle résume honnêtement le WAL ; cela reste la détection de divergence du ledger, à un hôte de distance de la passerelle.

La signature d’un point de contrôle prouve qui a scellé ; elle ne dit rien de quand, et le détenteur de la clé pourrait antidater ts_ms. Ancrer le hachage du point de contrôle auprès d’une autorité d’horodatage rend la date opposable à un tiers. L’échange se fait par fichier (aucun client HTTP nulle part) ; les déploiements en air-gap passent d’abord :

Fenêtre de terminal
obsign-ledger anchor request \
--store /tmp/demo/ledger --chain-id demo --out /tmp/demo/checkpoint.tsq
# carry the .tsq to your TSA (openssl ts reads and produces these), then:
obsign-ledger anchor attach \
--store /tmp/demo/ledger --chain-id demo \
--response /tmp/demo/checkpoint.tsr --tsa "tsa.internal.acme.fr"

La réponse n’est attachée que si la TSA l’a accordée et si le jeton imprime exactement le hachage du point de contrôle : le jeton nomme son propre point de contrôle, il n’y a aucun drapeau à se tromper. Une ancre par chaîne suffit : le dernier point de contrôle couvre transitivement tous les précédents, par la chaîne des points de contrôle.