Skip to content

fix(verify/azure_cvm): enforce minimal Base64urlUInt, reject private/duplicate HCLAkPub JWKs, and bound TPM quote parsing (#801) - #805

Open
drk-ram wants to merge 1 commit into
agentrust-io:mainfrom
drk-ram:drk-ram-fix-azure-cvm-801
Open

drk-ram wants to merge 1 commit into
agentrust-io:mainfrom
drk-ram:drk-ram-fix-azure-cvm-801

Conversation

@drk-ram

@drk-ram drk-ram commented Oct 23, 2026

Copy link
Copy Markdown

What

Enforce canonical minimal Base64urlUInt encoding and reject private/duplicate HCLAkPub JWKs, duplicate JSON keys, and truncated TPM quote structures in cmcp_verify.azure_cvm.

Why

Closes #801.

Security impact

Prevents leading-0x00 non-minimal Base64urlUInt RSA parameters, private JWK members, ambiguous HCLAkPub entries, and duplicate JSON keys in Azure CVM runtime data, and ensures truncated TPMS_ATTEST / TPMT_SIGNATURE blobs or malformed report_data_hex fail closed without raising unhandled struct.error or ValueError.

Test plan

  • pytest passes (pytest tests/unit/test_azure_cvm_verify.py -q)
  • ruff check passes (ruff check src/cmcp_verify/azure_cvm.py tests/unit/test_azure_cvm_verify.py)
  • mypy passes (mypy src/cmcp_verify/azure_cvm.py)
  • Manual test performed

DCO sign-off

@github-actions

github-actions Bot commented Oct 23, 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 Oct 23, 2026
carloshvp
carloshvp previously approved these changes Oct 24, 2026

@carloshvp carloshvp 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.

Reviewed exact head ce1648d977ce89687b9a6c6d3df87af451f68c63 in an isolated checkout.

Reviewed minimal canonical RSA Base64urlUInt parsing, public-only key material, unique HCLAkPub selection, report-data validation and bounded TPM quote parsing. The focused malformed/private/non-minimal-key and short-structure regression passes at this head and fails when the actual merge-base Azure verifier is restored in process. The full suite retains its signed positive controls.

Local hash-locked Python 3.12.10 validation: 2,526 unit tests passed, 20 skipped; pip check, Ruff, mypy, Bandit and diff whitespace checks passed. All PR commits carry sign-offs. No blocking source finding within this scope; required hosted checks and maintainer approvals remain separate.

Reviewed with OpenAI Codex.

noah-ing
noah-ing previously approved these changes Oct 24, 2026

@noah-ing noah-ing left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed exact head ce1648d977ce89687b9a6c6d3df87af451f68c63 in an isolated locked environment. I exercised signed synthetic Azure SNP/TPM evidence with 36 positive and negative controls covering canonical HCL AK parsing, duplicate and private JWK rejection, bounded quote parsing, and malformed nonce handling. The focused cases and full local unit suite passed (2,526 passed, 20 skipped), as did Ruff, mypy, Bandit, and dependency consistency checks. I found no blocker in this diff and approve the changed code. Hosted CI is still blocked by the existing locked-dependency audit, and required maintainer gates must complete before merge.

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 75.80645% with 15 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/cmcp_verify/azure_cvm.py 75.80% 15 Missing ⚠️

📢 Thoughts on this report? Let us know!

@rajnisht7 rajnisht7 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.

The overall changes looks good, two things still needs to be hardened:

  • _extract_extra_data never checks the TPMS_ATTEST type-it skips past the type field and only looks at magic + extraData. A CERTIFY (or any other attestation type) that is signed by the AK and has the right extraData is accepted as a quote, the shared agent_manifest.verify_tpm_quote already rejects non-TPM_ST_ATTEST_QUOTE (0x8018). This path should do the same, kindly validate type == 0x8018 and add tests for both bare and TPM2B-wrapped CERTIFY (must reject) plus QUOTE (must still accept).
  • kty is not required-current check is if "kty" in ak and ak["kty"] != "RSA", so a HCLAkPub with no kty at all is accepted, whereas commit message and issue both say “require a single RSA HCLAkPub”. Should be if ak.get("kty") != "RSA". Add a regression test for missing kty.

@dinakarjs dinakarjs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Current-head review follow-up at d61268c: I independently reproduced Rajnish's two outstanding checks with freshly signed synthetic valid/refusal twins, and prepared a signed adoption companion: dinakarjs#9, commit c26a55f. It requires the quote attestation type in both bare/TPM2B forms and an explicit RSA key type in HCLAkPub. Each new guard is independently caught by its paired test when restored to the earlier helper behavior.

Final local candidate tree 1581318780eb68af1423a9b0212656e712f5e117: full unit suite 2607 passed / 8 skipped; 11 focused Azure cases passed / one optional hardware skip; the three new cases also pass under -O. Ruff, strict mypy (77 files), configured Bandit and whitespace checks pass in this head's hash-locked Python 3.12.14 environment. No live TPM/Azure request or hardware acceptance is claimed. @drk-ram please adopt the single signed commit into this existing PR, then request independent exact-head review. This is a contribution/adoption COMMENT, not an independent approval of my own repair.

…duplicate HCLAkPub JWKs, and bound TPM quote parsing (agentrust-io#801)

- Reject duplicate JSON keys and non-finite constants in raw_evidence and runtime_data, require a single RSA HCLAkPub key (kty == "RSA") with no private/symmetric JWK parameters, and enforce canonical minimal Base64urlUInt encoding with odd e >= 3 and n >= 3.
- Require TPMS_ATTEST type == 0x8018 (TPM_ST_ATTEST_QUOTE) for both bare and TPM2B-wrapped attestations, bound struct.unpack_from and slice operations in _extract_extra_data and _verify_quote_signature, and validate report_data_hex before bytes.fromhex.

Closes agentrust-io#801

Signed-off-by: Raghuvar Karthik Durga <177662415+drk-ram@users.noreply.github.com>
@drk-ram
drk-ram dismissed stale reviews from carloshvp and noah-ing via 5d057eb October 30, 2026 14:36
@drk-ram
drk-ram force-pushed the drk-ram-fix-azure-cvm-801 branch from d61268c to 5d057eb Compare October 30, 2026 14:36
@drk-ram

drk-ram commented Oct 30, 2026

Copy link
Copy Markdown
Author

@rajnisht7 Addressed both points in \5d057eb:

  • _extract_extra_data\ now validates \TPMS_ATTEST\ \ ype == 0x8018\ (\TPM_ST_ATTEST_QUOTE) for both bare and \TPM2B_ATTEST-wrapped payloads, with regression tests rejecting bare and \TPM2B_ATTEST-wrapped \TPM_ST_ATTEST_CERTIFY\ (\

@noah-ing noah-ing left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed current head 5d057eb610547a86d8f0942867c7636d1f048171 after the rebase dismissed my earlier approval. Relative to the previously reviewed verifier source, this head adds two fail-closed checks: HCLAkPub must explicitly declare RSA, and TPMS_ATTEST must carry the QUOTE type before its extra data is used. The bare and TPM2B-wrapped CERTIFY negatives, matching QUOTE positives, and signed synthetic evidence controls pass. The TPM type values agree with the published TCG constants.

In a fresh hash-locked Python 3.12 environment, the focused Azure CVM tests passed (10 passed, 1 skipped), as did the full unit suite (2,593 passed, 21 skipped). Touched-file Ruff, module mypy, configured Bandit, dependency consistency, and diff whitespace checks passed. I have no further changes requested on this scope and approve the current head. The substantive hosted workflows are not shown on this PR head; the maintainer gate remains a separate merge requirement.

@carloshvp carloshvp 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.

Reviewed commit 5d057eb610547a86d8f0942867c7636d1f048171.

The verifier rejects private or non-minimal HCLAkPub JWKs and duplicate members, checks RSA parameters, bounds TPM quote fields and checks the quote signature length. Valid synthetic Azure evidence still verifies.

Focused tests: 10 passed, 1 skipped; repository Ruff, mypy and configured Bandit pass. This is software verifier/parser evidence. Required hosted checks and the independent security review requirement remain in force.

This branch has not been deployed

No deployments
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.

fix(verify/azure_cvm): enforce minimal Base64urlUInt, reject private/duplicate HCLAkPub JWKs, and bound TPM quote parsing

6 participants