Skip to content

fix(tdx): bind verification to signed quote header - #374

Merged
imran-siddique merged 1 commit into
agentrust-io:mainfrom
altrudev:fix/tdx-signed-header-binding-364
Sep 2, 2026
Merged

fix(tdx): bind verification to signed quote header#374
imran-siddique merged 1 commit into
agentrust-io:mainfrom
altrudev:fix/tdx-signed-header-binding-364

Conversation

@altrudev

@altrudev altrudev commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Closes #364.

What

verify_tdx_quote() now establishes the signed production TDX profile before accepting any signature or certification semantics:

  • version == 4;
  • att_key_type == 2 (ECDSA_P256);
  • tee_type == 0x81 (TDX).

The full verifier calls parse_tdx_quote(..., strict=True) as its profile prerequisite. The strict parser now checks the previously omitted attestation-key type as well as version and TEE type.

strict=False remains available for diagnostic field extraction only; its documentation now states that it does not authorize cryptographic interpretation of a declared profile.

Regression evidence

The existing synthetic full-chain builder is parameterized at the signed header. Each unsupported-header control is therefore self-consistent and re-signed by the same generated attestation key rather than byte-flipped after signing:

  • production header (4, 2, 0x81) keeps the existing successful path;
  • version 5 is refused by the full verifier;
  • attestation-key type 3 is refused by the full verifier;
  • TEE type 0x00 is refused by the full verifier;
  • the strict parser directly refuses key type 3;
  • strict=False remains a diagnostic parse control.

Existing body-tamper, pinned-root, certificate-validity, QE-binding, signature-section, and chain behavior is left unchanged.

Scope

No algorithm, wire format, certificate-chain rule, trust root, report-data binding, or signature preimage is changed. This patch only binds the implemented TDX-v4/P-256 verifier to the signed header that declares that profile.

AI-assistance disclosure: ChatGPT assisted with source triage, mutation-oriented regression design, implementation drafting, and exact-diff review. altrudev reviewed the bounded claim and remains responsible for the contribution.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

🟡 Contributor Check: MEDIUM

Check Result
Profile MEDIUM
Credential LOW
Overall MEDIUM

Automated check by AgenTrust Contributor Check.

@github-actions github-actions Bot added the needs-review:MEDIUM Contributor check flagged MEDIUM risk label Sep 1, 2026
Signed-off-by: Altru.dev <altrudevelop@gmail.com>
@altrudev
altrudev force-pushed the fix/tdx-signed-header-binding-364 branch from cd87040 to 1f703a7 Compare September 1, 2026 18:18

altrudev commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@carloshvp Implemented the accepted #364 boundary at exact head 1f703a760527f247dae143e33054b03388582d30.

The full verifier now establishes parse_tdx_quote(..., strict=True) before any signature/certification semantics, and the strict parser now requires version 4, ECDSA-P256 attestation key type 2, and TDX tee_type 0x81. strict=False is documented as diagnostic extraction only.

The existing synthetic full-chain builder is parameterized at the signed header, so the wrong-version, wrong-key-type, and wrong-TEE controls are re-signed self-consistent quotes rather than post-signature byte flips. The valid production-header path and the existing tamper/root/certificate/QE/PCK behavior remain unchanged.

Exact-head gates: CI SUCCESS; CodeQL SUCCESS. PR is mergeable and the diff is one commit / two files. The PR is still Draft only because the GitHub integration's Ready-for-review mutation currently errors on an upstream GraphQL fullDatabaseId field; no code/test gate is outstanding.

@altrudev
altrudev marked this pull request as ready for review September 1, 2026 18:25
@altrudev
altrudev requested a review from a team as a code owner September 1, 2026 18:25

@imran-siddique imran-siddique left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Merging. The ordering is the whole point of this change and it is right.

Establishing version == 4, att_key_type == ECDSA_P256 and tee_type == 0x81 before accepting any signature or certification semantics is the correct sequence, because interpreting a signature under an unverified profile means the profile is deciding how to read the evidence while being part of the evidence. Adding the previously omitted attestation-key type to the strict parser closes the gap that mattered most: an accepted key type is what tells you which algorithm the signature is even in.

The strict=False documentation change carries more weight than its size. "Does not authorize cryptographic interpretation of a declared profile" is the same distinction I have just written on #373, where a platform label was standing in for a completed verification. A declared profile says which procedure applies. It is never evidence that the procedure ran, and a diagnostic parser whose output is used as authorization is how that confusion enters a codebase.

The regression evidence is built correctly, and this is the second time this week I have said that about your tests: parameterising the synthetic full-chain builder at the signed header, so each unsupported-header control is self-consistent and re-signed by the same generated key rather than byte-patched, means a rejection is attributable to the header rule. A byte-patched control fails for two reasons at once and proves neither.

Thirteen checks, only the maintainer hold red. Closes #364.

@imran-siddique
imran-siddique merged commit 69d4ea1 into agentrust-io:main Sep 2, 2026
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-review:MEDIUM Contributor check flagged MEDIUM risk

Projects

None yet

Development

Successfully merging this pull request may close these issues.

verify_tdx_quote does not bind verification to the quote's declared TDX header

2 participants