Skip to content

fix(oe-tsa-core): encodage DER du failInfo des refus RFC 3161 - #62

Open
PhilippeVienne wants to merge 1 commit into
devfrom
fix/tsa-failinfo-encoding
Open

PhilippeVienne wants to merge 1 commit into
devfrom
fix/tsa-failinfo-encoding

Conversation

@PhilippeVienne

Copy link
Copy Markdown
Contributor

Objet

Défaut de production trouvé en écrivant le test de câblage du binaire tsa-server (constat D-2, tranche c) : tous les refus RFC 3161 portaient un failInfo mal encodé. Base dev, indépendante.

error_response construisait à la main l'octet « bits inutilisés » du PKIFailureInfo, puis le passait à BitString::from_bytes, qui en ajoute un second. Pour timeNotAvailable (bit 14), la réponse portait 03 04 00 01 00 02 (bits 7 et 22) au lieu de 03 03 01 00 02 : openssl ts -reply -text affichait Failure info: unspecified. Un client ne pouvait pas savoir pourquoi sa demande était refusée (RFC 3161 §2.4.2) — y compris la suspension de la TSU sur heure non traçable (EN 319 421 TIS-7.7.1-07), qui ne se distinguait pas d'une panne quelconque.

Pourquoi personne ne l'a vu : le corpus historique (tests/fixtures/rfc3161/rejects-*) ne contient que les requêtes, et les tests vérifiaient le type d'erreur Rust (FailureInfo::TimeNotAvailable), jamais le DER rendu.

  • BitString::new(unused, bytes), DER minimal (bits nuls de fin retirés).
  • error_response_encodes_the_rfc3161_failure_bit : DER exact de chacun des 7 FailureInfo.
  • openssl_reads_the_failure_reason : openssl ts -reply -text nomme la raison (« the TSA's time source is not available », etc.).

Vérifications

  • Mutation : en réinjectant l'ancien encodage, les deux nouveaux tests échouent.
  • cargo fmt --check, cargo clippy --workspace --all-targets -- -D warnings (1.97 et 1.98.1), cargo test --workspace avec PostgreSQL, cargo audit --ignore RUSTSEC-2023-0071 : verts.

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

error_response construisait à la main l'octet « bits inutilisés » du
PKIFailureInfo, puis le passait à BitString::from_bytes, qui en ajoute un
second. Le bit lu n'était donc pas le bon : timeNotAvailable (bit 14)
arrivait comme les bits 7 et 22, et openssl affichait « Failure info:
unspecified ». Tous les refus étaient concernés (badAlg,
unacceptedPolicy, timeNotAvailable…) : un client ne pouvait pas savoir
pourquoi sa demande était refusée (RFC 3161 §2.4.2).

Trouvé par un test de câblage du binaire tsa-server (constat D-2). Le
corpus historique ne contient que les requêtes, et les tests existants
vérifiaient le type d'erreur Rust, jamais le DER rendu.

- BitString::new(unused, bytes), en DER minimal.
- error_response_encodes_the_rfc3161_failure_bit : DER exact de chaque
  FailureInfo ; openssl_reads_the_failure_reason : openssl nomme la
  raison. Les deux échouent avec l'ancien encodage.

Co-authored-by: Claude <noreply@anthropic.com>
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