Skip to content

vaportpm-verify: harden cert-chain validation + guard trust anchor#8

Open
HarryR wants to merge 1 commit into
mainfrom
harden-cert-chain-validation
Open

vaportpm-verify: harden cert-chain validation + guard trust anchor#8
HarryR wants to merge 1 commit into
mainfrom
harden-cert-chain-validation

Conversation

@HarryR

@HarryR HarryR commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Follow-ups from an adversarial review of the attestation verification path (the single point of trust for the zkVM attestation flow). All changes are in vaportpm-verify.

Changes

Enforce signatureAlgorithm consistency (RFC 5280 §4.1.1.2)
Each certificate's outer signatureAlgorithm must equal its inner tbsCertificate.signature. The chain validator selects the verification algorithm from the outer field but verifies over the TBS bytes (which carry the inner field), so requiring equality closes an algorithm-substitution gap between the two. New ChainValidationReason::SignatureAlgorithmMismatch.

Require Key Usage on CA certificates (not just leaves)
Previously a non-leaf cert with no Key Usage extension skipped the keyCertSign check entirely (RFC 5280 §6.1.4(n) only mandates the check when the extension is present). We now require the extension on every cert, removing the leaf/CA asymmetry. BasicConstraints.cA remains the authoritative CA gate; Key Usage is defence in depth. New ChainValidationReason::CaMissingKeyUsage.

Guard the trust anchor against drift
AWS_NITRO_ROOT_HASH / GCP_EKAK_ROOT_HASH are kept hardcoded (deriving them in-guest costs significant zkVM circuit cycles), which means nothing at runtime checks they match the certs they represent. Added tests that re-derive each hash from the embedded root PEM and assert equality, turning silent drift into a CI failure. Both pass today — the constants are in sync.

Docs / comments brought in line with enforcement

  • validate_tpm_cert_chain doc corrected: EKU is intentionally not checked (GCP AK leaves carry only Key Usage; BasicConstraints.cA is authoritative).
  • Documented why extract_basic_constraints hand-parses a minimal ASN.1 subset (circuit size + smaller, auditable trust surface; fail-closed by construction).
  • Documented the SHA-256 pcrDigest invariant in verify_pcr_digest_matches (holds even for SHA-384 PCR banks, because the digest follows the AK signing-scheme hash, not the bank algorithm) — with a "do not change" warning.

Tests

Negative tests added for both new checks (test_reject_signature_algorithm_mismatch, test_reject_ca_without_key_usage) plus the two anchor-consistency tests. Full suite green: 103 lib + 16 GCP + 13 Nitro.

🤖 Generated with Claude Code

Adversarial review follow-ups on the attestation verification path:

- Enforce signatureAlgorithm consistency (RFC 5280 4.1.1.2): each cert's
  outer signatureAlgorithm must equal its inner tbsCertificate.signature,
  closing an algorithm-substitution gap since the verify alg is chosen from
  the outer field. New ChainValidationReason::SignatureAlgorithmMismatch.

- Require the Key Usage extension on CA certs (not just leaves), removing
  the leaf/CA asymmetry. BasicConstraints.cA remains the authoritative CA
  gate; KU is defence in depth. New ChainValidationReason::CaMissingKeyUsage.

- Add root-anchor consistency tests: re-derive AWS_NITRO_ROOT_HASH and
  GCP_EKAK_ROOT_HASH from the embedded root PEMs and assert equality, so the
  precomputed constants (kept hardcoded to save zkVM circuit cycles) can
  never silently drift from the certs they represent.

- Docs/comments: correct validate_tpm_cert_chain to match enforcement (EKU
  is intentionally unchecked); document why extract_basic_constraints hand-
  parses a minimal ASN.1 subset; document the SHA-256 pcrDigest invariant in
  verify_pcr_digest_matches (holds even for SHA-384 PCR banks).

Adds negative tests for both new checks. Full suite green.

Co-Authored-By: Claude Opus 4.8 (1M context) <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