Skip to content

fix: strict X.509 certificate chains for Hermes Python 3.13 - #71

Merged
ak5 merged 2 commits into
devfrom
fix/strict-x509-hermes
Oct 4, 2026
Merged

ak5 merged 2 commits into
devfrom
fix/strict-x509-hermes

Conversation

@ak5

@ak5 ak5 commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

Summary

Fix intercepted HTTPS for Hermes Python 3.13.5 and HTTPX 0.28.1 under default OpenSSL strict verification. A real generated-CA CONNECT test first reproduces missing leaf Authority Key Identifier; an AKI-only repair exposes the next error, missing CA Key Usage. Repair both certificates rather than relaxing client verification.

Motivation and scope

Generated deployment CAs now include critical signing/CRL Key Usage and authority/subject identifiers alongside CA Basic Constraints. Interception leaves include issuer-linked AKI, SKI, critical non-CA Basic Constraints, digital-signature Key Usage and server-authentication EKU while retaining the exact DNS SAN. CA PEM serialization uses a secret-holding type. Existing policy, signed/workload listeners, mediation, ALPN, upstream verification and CA no-overwrite behavior are unchanged.

No Infra edits, deployment, cutover or issue creation. An installed CA lacking required extensions must be regenerated using the corrected binary and its new public trust distributed by Infra; updating the image cannot repair an installed certificate.

Security impact

  • Trust boundary changed: no.
  • Credential flow changed: no.
  • Threat model unchanged because the established identity, CA ownership, trust and credential boundaries remain intact. The owning contract, deployment/client guidance and security review document the corrected certificate profile and required acceptance.
  • No strict flags, certificate verification, hostname checks or upstream trust are disabled. Test environments contain no operator authentication or real credentials.
  • The raw Python hostname probe explicitly retains a TLS 1.2 floor, making the default secure protocol requirement visible to CodeQL as well as the runtime.

Documentation

Contract, CA rotation/client requirements, repository gate and implementation review updated together. Relative Markdown links and source/documentation parity pass.

Verification

  • mise run check: format, Clippy, Rust tests, dependency policy, deployment contract, Hermes package tests, and required strict-client gate.
  • Exact Python 3.13.5 / HTTPX 0.28.1 urllib and HTTPX test through a real intercepted CONNECT connection using ca::generate, verified local TLS origin and zero fake-provider lookups.
  • Strict certificate/hostname flags remain enabled; trusted calls, reuse/denied operation, untrusted CA and wrong hostname tested.
  • Actual served chain checked for role constraints, critical Key Usage, exact SAN, server EKU, noncritical identifiers and AKI/SKI agreement.
  • Before-fix failure: Missing Authority Key Identifier; AKI-only failure: CA cert does not include key usage extension; complete fix passes.
  • Required fresh Linux CI executes the same Hermes-version strict test; normal Rust invocation marks the dependency-specific test ignored and the dedicated gate runs it explicitly.

Risk and rollback

  • Risk: installed CAs are immutable; Infra must regenerate/distribute trust for any deficient CA and rerun its isolated acceptance before cutover. External CA chains remain operator-owned and must satisfy strict verification too.
  • Rollback: retain installed image/layout/config and matching CA/key/trust bundles; preserve egress isolation and the convergence guard. Restoring an incompatible certificate does not restore Python compatibility.

Comment thread tests/strict_tls_clients.py Fixed

@ak5 ak5 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Source review of a16e6d6da5ecad352252affc2e46a122a3a6f817: production changes only complete the generated CA/leaf certificate profile and use SecretString for serialized CA key material. Reviewed critical CA/non-CA Basic Constraints and Key Usage, issuer-linked/noncritical AKI/SKI, exact SAN, server-only EKU, unchanged key protection/no-overwrite behavior and unchanged policy/mediation/upstream TLS/ALPN.

Real Python 3.13.5/HTTPX 0.28.1 regression first failed with missing AKI, then with missing CA Key Usage under an AKI-only repair, and passes with the complete fix. Default strict flags, required certificate validation and hostname checks are asserted; the raw probe explicitly retains a TLS 1.2 floor. Actual served certificate extensions/role/identifier link are independently parsed in the Rust test. No real credentials or ambient client auth enter fixtures. Final mise run check, shell syntax, Markdown links and documentation parity pass.

The old immutable image also reproduces missing AKI in a Charon-owned isolated Linux Docker client with an OS-installed generated public CA and the reported public GET /zen. A final digest-pinned released image proof will follow publication. No unresolved source-review findings remain; this is the implementing agent's review, not an independent audit. Fresh Linux CI, CodeQL and image gates on this exact head must pass before merge.

No trust boundary/credential flow changed, so the threat model invariants remain applicable. Infra owns CA regeneration/trust distribution and isolated acceptance; no Infra edit/deploy, issue creation or live cutover occurred.

@ak5
ak5 merged commit c82eb63 into dev Oct 4, 2026
9 checks passed
@ak5
ak5 deleted the fix/strict-x509-hermes branch October 4, 2026 10:55
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.

2 participants