refactor(tpm): delegate NV certify parsing to Agent Manifest - #601
Conversation
Signed-off-by: Noah Ingwers <98993329+noah-ing@users.noreply.github.com>
|
🟡 Contributor Check: MEDIUM
Automated check by AgenTrust Contributor Check. |
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
imran-siddique
left a comment
There was a problem hiding this comment.
Approved. The migration to the Agent Manifest parser is a clean delegation, the swtpm reference corpus and the expanded unit coverage are welcome additions, and all functional checks are green. Thanks Noah.
|
Thank you for the detailed review and for carrying this through #602 and the 0.4.1 release. I especially appreciated the careful scope correction and the authorship credit. Working through the verifier boundary and reproducing the issue concretely taught me a great deal. |
What
TPMS_ATTEST/TPMS_NV_CERTIFY_INFOwire parser and delegate parsing toagent_manifest.parse_tpm_nv_certify.parse_nv_certify()return shape andValueErrorcontract while using the canonical parser's exact-buffer and union-type checks.TPMS_ATTESTbytes when evidence arrives inTPM2B_ATTESTtransport framing.swtpmreference pair that exercises the released parser, certificate-chain check, TPM signature envelopes, phase bindings, index identity, and extend relation end to end.Why
Agent Manifest PR agentrust-io/agent-manifest#304 added the canonical NV-certify parser in release 0.11.2 and explicitly enabled cMCP to retire its remaining local wire parser. cMCP already requires
agent-manifest>=0.11.2, so keeping both implementations only preserves a trust-boundary split.The implementations had also developed observable framing differences: the local parser rejected valid size-prefixed
TPM2B_ATTESTinput and did not requirenvContentsto consume the complete signed structure. This completes the downstream migration without introducing a new dependency or public API.Security impact
TPM wire parsing now has one authority across Agent Manifest and cMCP. For size-prefixed transport, signature verification covers
parsed.attest.raw—the inner structure signed by the AK—not the unsigned two-byte transport length. Quote/NV type confusion, truncation, and undeclared trailing data remain fail-closed.cMCP still owns the gateway-specific two-certify phase binding, same-index check, expected gateway digest, and extend relation. The configured AK trust-root and signature requirements are unchanged.
The reference corpus is software-TPM evidence under a synthetic test CA. It does not establish physical TPM or TEE provenance, vendor enrollment, EK-to-AK activation, hardware key residency, requester/TPM co-location, boot state, or runtime integrity.
Test plan
pytestpasses — 1,474 passed, 6 pre-existing environment-gated hardware skips; 86.95% coverage in anautocrlf=trueclean checkout.ruff checkpasses.mypypasses across 65 source files.Additional verification:
pip-audit --skip-editablereports no known dependency vulnerabilities.twine check, install independently, import outside the checkout, and pass the installed CLI smoke.Manual producer path:
swtpm0.7.3 instance and created a restricted RSA-2048 RSASSA/SHA-256 AK withtpm2-tools5.6.TPM_NT_EXTENDindex, certified its pre-value, extended the gateway digest, and certified its post-value.post == SHA256(pre || gateway_digest), replay rejection under a new nonce, signature-tamper rejection, and every committed artifact checksum.DCO sign-off