Aller au contenu

PD-264 — Spécification canonique contractuelle

1. Références

  • Story : PD-264
  • Epic : PD-187 — BLOCKCHAIN
  • Sous-epic : Horodatage qualifié RFC 3161 — conformité et interopérabilité
  • Projet : ProbatioVault-backend
  • Domaine : blockchain / crypto-proof
  • Besoin source : PD-264 — Expression de besoin
  • Dépendance amont : PD-55 (DONE) — worker ancrage blockchain, entités TSA, module NestJS, processeur Bull
  • Normes et exigences :
  • RFC 3161 §2.2 (nonce dans TimeStampReq)
  • RFC 3161 §2.4.2 (vérification du nonce dans TimeStampResp)
  • RFC 3161 §4.6 (protection anti-rejeu)
  • Outil d'interopérabilité cible : openssl ts -verify
  • Vérification formelle cible : Prolog RFC 3161 = 18/18

2. Objectif

  • Rendre le mécanisme nonce RFC 3161 obligatoire, vérifiable et traçable pour chaque jeton d'horodatage accepté.
  • Supprimer la non-conformité formelle actuelle (17/18) en atteignant 18/18.
  • Garantir le rejet systématique de toute réponse TSA :
  • sans nonce ;
  • avec nonce différent de la requête ;
  • avec nonce déjà utilisé.
  • Maintenir l'interopérabilité ASN.1/DER des jetons produits avec les outils standards.

3. Description fonctionnelle

  • Le système gère un cycle probatoire RFC 3161 incluant les états métier suivants :
  • REQUEST_EMITTED : requête TSA construite avec nonce.
  • RESPONSE_RECEIVED : réponse TSA reçue, en attente de validation.
  • RESPONSE_ACCEPTED : réponse valide et conforme, autorisée à entrer dans le flux probatoire.
  • RESPONSE_REJECTED : réponse invalide/non conforme, exclue du flux probatoire.
  • TOKEN_PERSISTED : jeton accepté persisté en base append-only.
  • Règles fonctionnelles :

  • Garde d'entrée d'automate : la validation fail-closed du nonce côté requête est un prérequis d'entrée dans le cycle d'états. Une requête sans nonce n'entre jamais dans l'automate ; TC-264-01 valide cette garde d'entrée (et non une transition interne).

  • Chaque requête RFC 3161 inclut un nonce binaire de 128 bits (obligation fail-closed, sans distinction production/non-production).

  • Chaque réponse TSA est validée strictement avant toute écriture probatoire.

  • La comparaison nonce requête/réponse DOIT utiliser une primitive de comparaison en temps constant (ex : crypto.timingSafeEqual).

  • Une réponse sans nonce est rejetée.
  • Une réponse avec nonce déjà existant est rejetée.
  • Une réponse rejetée n'est ni persistée ni propagée au journal append-only ni incluse dans l'agrégation Merkle.
  • Transitions d'états autorisées :
  • REQUEST_EMITTED -> RESPONSE_RECEIVED
  • RESPONSE_RECEIVED -> RESPONSE_ACCEPTED
  • RESPONSE_RECEIVED -> RESPONSE_REJECTED
  • RESPONSE_ACCEPTED -> TOKEN_PERSISTED
  • Transitions inverses (obligatoires) :
  • RESPONSE_ACCEPTED -> RESPONSE_RECEIVED : INTERDITE (validation définitive).
  • RESPONSE_REJECTED -> RESPONSE_RECEIVED : INTERDITE (réponse rejetée non rejouable).
  • TOKEN_PERSISTED -> RESPONSE_ACCEPTED : INTERDITE (immutabilité post-insertion).
  • RESPONSE_ACCEPTED -> RESPONSE_REJECTED : INTERDITE (pas de downgrade après acceptation).
  • RESPONSE_REJECTED -> RESPONSE_ACCEPTED : INTERDITE (nouvelle tentative requiert nouvelle requête et nouveau nonce).
  • Comportement au retour/downgrade :
  • Données existantes conservées sans altération.
  • Aucun déverrouillage fonctionnel rétroactif.
  • Aucun changement de quota applicable (non pertinent pour ce module).

3bis. Diagrammes Mermaid

Diagramme d'états — Cycle probatoire RFC 3161

Ce diagramme représente les 5 états métier et les transitions autorisées du cycle nonce. Les transitions inverses sont toutes INTERDITES (INV-264-12).

stateDiagram-v2
    [*] --> REQUEST_EMITTED : Requête TSA construite\n(nonce 128 bits obligatoire — INV-264-01)

    REQUEST_EMITTED --> RESPONSE_RECEIVED : Réponse TSA reçue

    RESPONSE_RECEIVED --> RESPONSE_ACCEPTED : Nonce présent (INV-264-02)\n+ égalité stricte (INV-264-03)\n+ temps constant (INV-264-04)\n+ unicité globale (INV-264-05)
    RESPONSE_RECEIVED --> RESPONSE_REJECTED : Nonce absent / mismatch / doublon\n(INV-264-07)

    RESPONSE_ACCEPTED --> TOKEN_PERSISTED : Persistance atomique DB\n(INV-264-06, INV-264-13)

    TOKEN_PERSISTED --> [*] : Jeton probatoire immutable\n(INV-264-08)

    note right of RESPONSE_REJECTED
        Aucune écriture DB,
        aucun append audit/Merkle
        (INV-264-06, INV-264-07)
    end note

    note right of RESPONSE_ACCEPTED
        Validation définitive —
        retour INTERDIT (INV-264-12)
    end note

Diagramme de séquence — Flux nominal requête-validation-persistance

Ce diagramme représente les interactions entre services lors du flux nominal, incluant la génération CSPRNG, l'appel TSA, la validation nonce et la persistance.

sequenceDiagram
    participant W as Worker Ancrage<br/>(PD-55)
    participant N as Module Nonce<br/>(PD-264)
    participant TSA as TSA RFC 3161<br/>(externe)
    participant DB as PostgreSQL<br/>(timestamp_tokens)
    participant M as Agrégation Merkle<br/>(post-commit)

    W->>N: buildRequest(hash)
    activate N
    N->>N: CSPRNG 128 bits (INV-264-01)
    N-->>W: TimeStampReq + nonce
    deactivate N

    W->>TSA: POST TimeStampReq
    activate TSA
    TSA-->>W: TimeStampResp
    deactivate TSA

    W->>N: validateResponse(req, resp)
    activate N
    N->>N: Vérifier présence nonce (INV-264-02)
    N->>N: timingSafeEqual(req.nonce, resp.nonce) (INV-264-04)
    N->>N: Vérifier conformité ASN.1/DER (INV-264-09)

    alt Nonce valide
        N->>DB: CHECK unicité nonce (INV-264-05)
        activate DB
        DB-->>N: OK (unique)
        deactivate DB
        N->>DB: BEGIN TX — INSERT token (INV-264-06, INV-264-13)
        activate DB
        DB-->>N: COMMIT
        deactivate DB
        N-->>W: RESPONSE_ACCEPTED → TOKEN_PERSISTED
        W->>M: Append post-commit (async, idempotent)
    else Nonce absent / mismatch / doublon
        N-->>W: RESPONSE_REJECTED (INV-264-07)
        Note over W,DB: Aucune écriture DB ni append Merkle
    end
    deactivate N

4. Périmètre (inclus / exclu)

  • Inclus :
  • Activation contractuelle du nonce dans le flux RFC 3161 du module tsa/.
  • Validation stricte présence/égalité/unicité du nonce avant toute persistance.
  • Contrat de stockage du nonce en binaire brut 16 octets.
  • Contrat d'unicité DB sur nonce (défense en profondeur anti-rejeu).
  • Contrat de conformité ASN.1/DER et d'interopérabilité de vérification.
  • Contrat de tests CI (mock TSA) + nightly (TSA qualifiée réelle).
  • Exclu (hors périmètre) :
  • Client QTSA complet (appel HTTP TSA externe) au-delà du besoin nonce.
  • Rotation/révocation certificats TSA.
  • Intégration d'une nouvelle TSA externe.
  • Changement de rétention des jetons (10 ans, défini PD-55).

5. Modèle de données (entités, champs, index, contraintes)

  • Entité concernée : timestamp_tokens
  • Champs contractuels minimaux :

  • nonce : BYTEA, taille exacte 16 octets, contrainte DDL NOT NULL en base pour tout token accepté ; migration requise de la colonne héritée PD-55 (VARCHAR(64) nullable) vers BYTEA NOT NULL (16 octets).

  • tsa_token : artefact RFC 3161 binaire (structure DER valide requise pour acceptation).
  • created_at et identifiants probatoires : inchangés par PD-264 (hérités).
  • Contraintes :
  • Contrainte d'immutabilité post-insertion maintenue (héritage PD-55).
  • Contrainte d'unicité sur nonce (index unique).

  • Contrainte DDL complémentaire recommandée : vérification taille octet_length(nonce) = 16 côté base.

  • Rejet métier si nonce absent, taille invalide, mismatch, doublon.
  • États de validation (métier) :
  • RESPONSE_ACCEPTED et RESPONSE_REJECTED sont mutuellement exclusifs.
  • Données manquantes explicitement identifiées :
  • Le nom exact de la contrainte/index existant et la convention de nommage SQL ne sont pas fournis.
  • Le schéma SQL complet de timestamp_tokens n'est pas fourni dans le besoin.
  • Ces éléments sont requis pour une traçabilité DDL exhaustive, mais n'affectent pas les obligations contractuelles ci-dessus.

6. Invariants (INV-264-XX)

  • INV-264-01 — Nonce obligatoire (fail-closed) Toute requête RFC 3161 contient un nonce de 128 bits. Aucune exception de mode d'exécution n'est autorisée.
  • INV-264-02 — Présence nonce en réponse Toute réponse TSA acceptée contient un nonce non nul.
  • INV-264-03 — Égalité stricte Toute réponse TSA acceptée vérifie nonce_response == nonce_request en binaire.
  • INV-264-04 — Comparaison à primitive temps constant La vérification d'égalité nonce requête/réponse DOIT utiliser une primitive de comparaison en temps constant (ex : crypto.timingSafeEqual).
  • INV-264-05 — Unicité globale Un nonce accepté n'existe qu'une seule fois dans timestamp_tokens.
  • INV-264-06 — Validation avant écriture Aucune écriture DB, journal append-only ou inclusion Merkle ne se produit avant validation complète du nonce.
  • INV-264-07 — Rejet strict des réponses non conformes Toute réponse sans nonce, avec mismatch ou nonce déjà utilisé est rejetée.
  • INV-264-08 — Immutabilité post-insertion Le nonce persisté ne peut pas être modifié après insertion.
  • INV-264-09 — Conformité ASN.1/DER Tout token accepté est structurellement conforme RFC 3161 §2.4.2.
  • INV-264-10 — Interopérabilité Tout token accepté est vérifiable avec openssl ts -verify.
  • INV-264-11 — Invariant de sécurité formel Pour toute réponse acceptée : présence nonce, égalité binaire, unicité en store.
  • INV-264-envelope-encryption — NON APPLICABLE dans le contexte PD-264 Le nonce RFC 3161 de PD-264 n'est pas un secret cryptographique ; aucun artefact secret temporaire (clé, fragment, DEK, ReKey) n'est produit par ce périmètre. Le nonce est uniquement manipulé en mémoire transitoire pendant la validation puis persisté comme donnée probatoire.
  • INV-264-12 — Interdiction des transitions inverses Les transitions RESPONSE_ACCEPTED -> RESPONSE_RECEIVED, RESPONSE_REJECTED -> RESPONSE_RECEIVED, TOKEN_PERSISTED -> RESPONSE_ACCEPTED, RESPONSE_ACCEPTED -> RESPONSE_REJECTED et RESPONSE_REJECTED -> RESPONSE_ACCEPTED sont strictement interdites.
  • INV-264-13 — Atomicité ACCEPTED -> PERSISTED (scope borné) La transition RESPONSE_ACCEPTED -> TOKEN_PERSISTED DOIT être atomique uniquement sur la persistance DB (INSERT timestamp_tokens) via transaction englobante. Les opérations append-only journal et agrégation Merkle sont post-commit, asynchrones et idempotentes (retry-safe). En cas de crash avant commit : aucun token persisté. En cas de crash après commit mais avant append/Merkle : le token persisté reste valide et le rattrapage est assuré par le worker de réconciliation PD-55.

7. Critères d'acceptation (CA-264-XX)

  • CA-264-01 : Une requête RFC 3161 sans nonce est refusée (fail-closed, tous modes).
  • CA-264-02 : Une réponse TSA sans nonce est rejetée.
  • CA-264-03 : Une réponse TSA avec nonce différent de la requête est rejetée.
  • CA-264-04 : Une réponse TSA avec nonce identique et inédit est acceptable (sous réserve des autres validations RFC).
  • CA-264-05 : Une tentative d'acceptation d'un nonce déjà persisté est rejetée (unicité effective).
  • CA-264-06 : Aucun enregistrement DB n'est créé quand la validation nonce échoue.
  • CA-264-07 : Aucun append audit/Merkle n'est produit quand la validation nonce échoue.
  • CA-264-08 : Le nonce persisté est en binaire brut de 16 octets.
  • CA-264-09 : Le token accepté est vérifiable via openssl ts -verify.
  • CA-264-10 : La suite de vérification formelle Prolog passe de 17/18 à 18/18.
  • CA-264-11 : CI rapide exécute des tests déterministes avec mock TSA conforme RFC.
  • CA-264-12 : Nightly exécute une vérification sur TSA qualifiée réelle et archive le token probatoire.

8. Contraintes non fonctionnelles (performance, sécurité, conformité)

  • Sécurité :
  • Génération nonce via CSPRNG uniquement.
  • Interdiction de générateurs pseudo-aléatoires non cryptographiques.
  • Comparaison nonce via primitive de comparaison en temps constant.
  • Défense en profondeur : validation applicative + contrainte d'unicité DB.

  • Protocole statistique TC-264-07 (obligation de moyen) :

    • Méthode : comparaison des distributions égal/mismatch avec Welch t-test bilatéral + Mann-Whitney U.
    • Seuil : alpha = 0.01 (par test, décision conjointe).
    • Taille d'échantillon : N = 100000 mesures par classe (égal et mismatch), après warm-up de 5000 itérations.
    • Critère d'acceptation : p_ttest >= 0.01 ET p_mwu >= 0.01 ET |Cliff's delta| < 0.147 (effet négligeable).
  • Procédure d'escalade TC-264-07 :

    • En cas d'échec statistique (p < 0.01 ou |Cliff's delta| >= 0.147), le test est relancé une seule fois sur infrastructure stable (CPU isolé/pinning).
    • En cas de second échec : ESCALADE obligatoire ; l'implémentation DOIT être auditée pour identifier une fuite temporelle potentielle.
    • Ce contrôle est bloquant pour Gate 8 (non bloquant pour Gate ⅗).
  • Conformité :
  • Alignement strict RFC 3161 (§2.2, §2.4.2, §4.6).
  • Conformité formelle Prolog attendue : 18/18.
  • Interopérabilité obligatoire avec openssl ts -verify.
  • Qualité :
  • Aucune régression CI (Sonar QG non dégradé, exigences de couverture projet respectées).
  • Temporalité / SLA :
  • Aucune transition temporelle identifiée (pas de TTL, expiration, deadline ou window dans le périmètre nonce).
  • Robustesse :
  • Le rejet nonce est déterministe, traçable et sans effet de bord persistant.

9. Hypothèses

  • PD-55 reste disponible et valide comme fondation technique (module TSA, worker, entités, trigger d'immutabilité).
  • Le flux probatoire conserve l'ordre logique : requête -> validation -> persistance -> agrégation Merkle -> ancrage blockchain.
  • Les environnements CI et nightly disposent des prérequis cryptographiques/outils nécessaires pour les vérifications contractuelles.
  • Les conventions de nommage DB/index seront définies selon standards projet.
  • L'implémentation fournit une transaction englobante pour garantir l'atomicité de RESPONSE_ACCEPTED -> TOKEN_PERSISTED sur la seule persistance DB ; append-only et Merkle sont traités post-commit via mécanismes idempotents et réconciliation PD-55.
  • Aucune question ouverte bloquante n'existe côté PO à date.

10. Liens documentaires / Dépendances

  • Dépendance story : PD-55 (DONE).
  • Document source : PD-264 — Expression de besoin.
  • Références normatives : RFC 3161 (§2.2, §2.4.2, §4.6).
  • Vérification externe : openssl ts -verify.
  • Contraintes organisationnelles : Sprint PD Sprint 9 (2026-02-20 au 2026-03-16).
  • Exigences de test :
  • CI standard : mock TSA conforme RFC.
  • Nightly probatoire : TSA qualifiée réelle + archivage artefact.