Skip to content

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

Open

Description

@drk-ram

Summary

Several validation gaps exist in src/cmcp_verify/azure_cvm.py:

  1. Non-canonical Base64urlUInt, private JWK members, and ambiguous HCLAkPub entries in _ak_from_runtime_data (src/cmcp_verify/azure_cvm.py lines 101-110):

    • json.loads(runtime_data) and json.loads(raw_evidence) do not reject duplicate JSON object keys via object_pairs_hook.
    • ak = next((k for k in keys if k.get("kid") == "HCLAkPub"), None) silently selects the first entry when multiple HCLAkPub keys are present, does not require k.get("kty") in (None, "RSA"), and accepts RFC 7517 / RFC 7518 private or symmetric JWK members (d, p, q, dp, dq, qi, oth, k).
    • _b64u(v) does not enforce canonical unpadded base64url (^[A-Za-z0-9_-]+$, len(v) % 4 != 1, round-trip match) or RFC 7518 Section 2 minimal Base64urlUInt encoding (raw[0] != 0, rejecting leading 0x00 bytes) and does not require e >= 3 and odd e.
  2. Unhandled struct.error / ValueError and silent truncation in _extract_extra_data, _verify_quote_signature, and Step f (src/cmcp_verify/azure_cvm.py lines 58-98, 178-197):

    • In _extract_extra_data(quote_msg), len(quote_msg) < 4 raises struct.error, and truncated TPM2B / qualifiedSigner / extraData slices (offset + ed_size > len(attest)) silently return short bytes instead of raising ValueError.
    • In _verify_quote_signature(quote_msg, quote_sig, ak), len(quote_sig) < 6 raises an unhandled struct.error (called outside try...except at line 179), and 6 + sig_size != len(quote_sig) does not reject truncated or trailing signature bytes.
    • At line 191, bytes.fromhex(report_data_hex) is called outside try...except, raising an unhandled ValueError on malformed report_data_hex.

Proposed Fix

  • Reject duplicate JSON keys in raw_evidence and runtime_data, require a single RSA HCLAkPub with no private/symmetric JWK parameters, and enforce canonical minimal Base64urlUInt encoding with odd e >= 3 and n >= 3.
  • Bound all struct.unpack_from and slice operations in _extract_extra_data and _verify_quote_signature, and guard report_data_hex decoding in Step f so malformed inputs fail closed as AzureCVMVerificationResult(verified=False, ...).

Activity

  1. github-actions commented on Oct 23, 2026

    @github-actions
    Contributor

    🟡 Contributor Check: MEDIUM

    Check Result
    Profile MEDIUM
    Credential LOW
    Overall MEDIUM

    Automated check by AgenTrust Contributor Check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions