Skip to content

Track A · PR 6/7 — Add pq_chain validator #35

@bradh11

Description

@bradh11

Parent: #28 · Track A (cert-side) · Depends on PR 1 (Rust SPKI OIDs) · Independent of PRs 2/3

Scope

New opt-in validator that walks the certificate chain and emits per-cert PQ posture. Useful during the staged migration period when leaf, intermediate, and root rotate independently.

Returns

```python
{
"chain_length": 3,
"links": [
{"depth": 0, "subject": "...", "key_alg": "ml-dsa-65", "sig_alg": "ml-dsa-65", "is_pq": True},
{"depth": 1, "subject": "...", "key_alg": "rsaEncryption", "sig_alg": "sha256WithRSAEncryption", "is_pq": False},
{"depth": 2, "subject": "...", "key_alg": "rsaEncryption", "sig_alg": "sha256WithRSAEncryption", "is_pq": False},
],
"summary": {"leaf_pq": True, "intermediate_pq": False, "root_pq": False},
"is_valid": True, # or another threshold — see open question
}
```

Open question for the PR

What makes is_valid: True? Three options:

  1. Leaf PQ is enough (current proposal — matches the realistic 2026 migration order)
  2. Full chain PQ
  3. Configurable threshold via validator user-arg

Default to (1) and discuss in PR review.

Doc note (required)

Chains terminating at public trust anchors will report is_pq: False at the root for the foreseeable future. This is expected, not a bug — call it out in the docstring and the docs page.

Files to touch

  • certmonitor/validators/pq_chain.py (new) — model after chain.py
  • certmonitor/validators/init.py — register in VALIDATORS only
  • Docs page + mkdocs.yml entry
  • tests/test_validators/test_pq_chain.py (new)

Tests

  • All-classical chain (leaf, intermediate, root all RSA)
  • Hybrid migration: PQ leaf, classical intermediate + root
  • Fully PQ chain (synthetic — won't exist in the wild)
  • Single-cert chain (self-signed)
  • Empty chain → error dict

Definition of Done

  • make ci clean
  • Coverage ≥ 95%
  • CHANGELOG entry added
  • Docs page added to mkdocs.yml with the trust-anchor caveat explicitly called out
  • PR opened against develop from feat/pq-chain-validator
  • Validator is opt-in (not in DEFAULT_VALIDATORS)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions