Skip to content

fix(oe-ca-core,oe-conformance,oe-tsa-core): expiration de la clé TSU, contrôlée à chaque signature - #54

Closed
PhilippeVienne wants to merge 1 commit into
fix/tsa-gen-time-fractionfrom
fix/tsu-key-expiry
Closed

PhilippeVienne wants to merge 1 commit into
fix/tsa-gen-time-fractionfrom
fix/tsu-key-expiry

Conversation

@PhilippeVienne

Copy link
Copy Markdown
Contributor

Objet

Constat T-3 de l'audit de préparation eIDAS/WebTrust du 2026-09-25
(docs/AUDIT_2026_09_25.md, EN 319 421 TIS-7.6.7-01/-02/-04/-05/-06,
TIS-7.7.1-09) : la clé de signature d'une TSU n'avait aucune date
d'expiration propre — un processus de longue durée pouvait signer
indéfiniment avec la même clé, y compris au-delà de l'expiration du
certificat lui-même.

Décisions prises avec l'utilisateur avant d'écrire :

  • Certificat tsa_signer : 1 an → 2 ans. Clé : private_key_validity
    = 1 an (plus courte que le certificat, exigence shall).
  • Extension posée et vérifiée à chaque signature, pas seulement
    déclarative : Authority::timestamp refuse (systemFailure) une fois la
    clé expirée, à chaque appel, pas qu'au démarrage.

x509_cert::ext::pkix::PrivateKeyUsagePeriod existe déjà dans la
bibliothèque (pas de DER à la main comme pour #53/T-1) :
oe-ca-core::extensions::private_key_usage_period la pose (non critique,
recommandation RFC 5280), oe_conformance::check_tsu_certificate (le
Profile::check de tsa_signer, donc appelé par Issuer::issue avant tout
enregistrement) exige sa présence et que son notAfter précède celui du
certificat, et oe-tsa-core::Authority met en cache cette date à la
construction pour la revérifier à chaque signature.

Fixture tests/fixtures/tsa/tsu-cert.pem régénérée avec cette extension
(openssl req -addext ne la connaît pas par son nom — donnée en DER brut,
voir tests/fixtures/tsa/README.md pour la commande complète et comment
recalculer la valeur).

Empilée sur #53 (T-1) : mêmes fichiers oe-tsa-core/src/lib.rs.
Base : fix/tsa-gen-time-fraction (#53), pas dev.

Vérifications

  • cargo fmt --check : silencieux.
  • cargo clippy --workspace --all-targets -- -D warnings : silencieux, sur
    toolchain 1.97 (local) et 1.98.1 (CI).
  • cargo test --workspace (avec OE_CASTORE_TEST_DSN) : tout au vert.
  • cargo audit --ignore RUSTSEC-2023-0071 : aucune vulnérabilité.
  • oe-conformance/tests/tsu_certificate.rs (nouveaux tests, émission réelle
    via Issuer::issue, pas de DER construit à la main) : l'émission est
    refusée sans privateKeyUsagePeriod, et refusée quand la clé dépasse la
    validité du certificat.
  • oe-tsa-core/tests/end_to_end.rs (nouveau test) : passé l'expiration de
    la clé (mais avant celle du certificat), l'horodatage est refusé et
    aucune signature n'a lieu (compteur d'appels au signeur, pas
    seulement une erreur rendue après coup). Mutation : en retirant le
    contrôle, ce test échoue bien.

Revue humaine obligatoire

Voir PROVENANCE.md. Chaque case est cochée par le
contributeur humain qui valide la PR, après l'avoir fait lui-même.

  • Revue d'architecture validée par l'humain
  • Code relu et tests unitaires/intégration vérifiés localement
  • Absence de dépendances tierces incompatibles avec la double licence EUPL-1.2 / AGPL-3.0 (make licenses)
  • Validation de l'apport intellectuel et de la paternité humaine sur la modification

Assistance par IA

  • Cette PR a été produite avec l'assistance de Claude Code : les commits concernés portent la remorque Co-authored-by: Claude <noreply@anthropic.com>, auteur et committer restent humains, et scripts/provenance.py archive a été lancé
  • Cette PR a été écrite sans assistance par IA

… contrôlée à chaque signature

Constat T-3 de l'audit du 2026-09-25 (EN 319 421 TIS-7.6.7-01/-02/-04/-05/-06,
TIS-7.7.1-09) : la clé de signature d'une TSU n'avait pas de date d'expiration
propre, et rien n'empêchait un processus de longue durée de signer au-delà de
l'expiration du certificat lui-même. Norme : la clé doit expirer avant le
certificat, l'extension privateKeyUsagePeriod doit le porter, et le système
doit refuser toute signature une fois cette date atteinte.

oe-ca-core :
- profile::tsa_signer() porte maintenant private_key_validity (1 an), et
  validity passe à 2 ans (au lieu d'1 an) pour que la clé ait vraiment un
  cycle de vie plus court que le certificat qui la porte.
- extensions::private_key_usage_period pose l'extension (non critique,
  comme le recommande RFC 5280), via x509_cert::ext::pkix::PrivateKeyUsagePeriod
  (déjà fourni par la bibliothèque, pas d'encodage DER à la main ici).

oe-conformance : check_tsu_certificate (Profile::check de tsa_signer, donc
appelé par Issuer::issue avant tout enregistrement) exige désormais cette
extension et vérifie que son notAfter précède celui du certificat. Nouvelle
fonction publique tsu_private_key_not_after, réutilisée par oe-tsa-core.

oe-tsa-core : Authority met en cache la date d'expiration de la clé à la
construction, et Authority::timestamp la recontrôle à *chaque* appel, avant
la signature — un processus démarré avant l'expiration continue de la
refuser correctement une fois la date dépassée, pas seulement au démarrage.

Fixture tests/fixtures/tsa/tsu-cert.pem régénérée avec privateKeyUsagePeriod
(openssl req -addext ne connaît pas cette extension par son nom : donnée en
DER brut, voir tests/fixtures/tsa/README.md).

- oe-conformance : deux nouveaux tests bout-en-bout (émission réelle via
  Issuer::issue) prouvant le refus d'émission sans l'extension, et quand la
  clé dépasse la validité du certificat.
- oe-tsa-core : nouveau test bout-en-bout prouvant qu'aucune signature n'a
  lieu une fois la clé expirée (compteur d'appels au signeur, pas seulement
  une erreur rendue). Testé par mutation.

Co-authored-by: Claude <noreply@anthropic.com>
@PhilippeVienne
PhilippeVienne deleted the branch fix/tsa-gen-time-fraction September 30, 2026 13:53
@PhilippeVienne

Copy link
Copy Markdown
Contributor Author

Remplacée par #80 (base dev) : fermée par GitHub à la suppression de sa branche de base après la fusion de #76 (ex-#53).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant