Feat/v3 verifier - #122
Feat/v3 verifier#122lsd-cat wants to merge 11 commits into
Conversation
PORTING.md pins the module map, snake_case interface contract, adapter wiring, acceptance harness, and Python-specific pitfalls for the v3 port (per tinfoil-conformance docs/PORTING_PLAYBOOK.md, referencing tinfoil-go feat/v3 Turin-era as primary source). embedded_roots.py carries the production trust anchors byte-identical to Go's go:embed copies (Genoa + Turin + Intel SGX + Sigstore trusted root). Implementation phases follow on this branch.
1:1 Python port of the v3 envelope (strict parse + check: nonce, endorsed section hashes, report_data ladder, collateral accessors), the fail-closed platform-endorsements artifact parser (Turin-era fields), Go-semantics strict JSON (hand parser: decoded-name duplicate rejection with U+FFFD surrogate coercion, raw-literal exact ints, canonical encodings), measurement types, embedded production roots byte-identical to Go's, and the conformance adapter skeleton (tinfoil-conformance script; envelope stage live, others exit 20). Conformance: envelope 21/21 via the shared runner; 121 unit tests; existing suite unaffected (599 passed).
authenticate_code / authenticate_platform_endorsements / authenticate_freshness on the official sigstore-python (Verifier + verify_dsse works fully offline against a supplied trusted root, matching sigstore-go's chain/SCT/tlog/ integrated-time semantics), with every tinfoil check it lacks implemented here: media-type + legacy-layout + one-signature gates, duplicate-SCT-log rejection, SAN-regex + issuer + runner_environment policy, protojson-strict statement parse, subject digest enforcement, source ref/digest extraction (tag + 40-hex commit), platform repo pin, freshness witness (earliest tlog time, 5min skew, 7d age; timedelta arithmetic, no floats). Adapter stages authenticate-provenance + assemble-policy wired. Conformance: provenance 33/33, policy 29/29, envelope 21/21; 201 unit tests green.
sev_authenticate: strict report ABI (all mbz ranges), CPUID-FMS product line (Genoa+Turin), per-product pinned roots with injectable override, KDS chain + extension validation (Turin TCB layouts, hwid variants, per-version spl rules), RSA-PSS-SHA384 chain, fail-closed CRL (window + ASK/VCEK revocation), report ECDSA-P384 LE signature over [0,0x2A0), VLEK/masked-CHIP_ID rejects. sev_assemble/sev_validate: the forked go-sev-guest configured subset incl. per-product iommu_write_safe/fmc_spl rules, Turin-aware TCB relations, and the strict-equality companions. Deliberate fail-closed extensions beyond the fork (VCEK-serial revocation, ARK self-signature) match the JS port. Conformance: quote-sev 13/13, frozen-time 2/2, embedded-root SEV reject; 67 unit tests.
sev_authenticate: strict 1184-byte report ABI (all mbz/reserved rules), per-product trusted roots (Genoa + Turin embedded chains, override seam), product from CPUID FMS, VLEK/masked-CHIP_ID rejects, VCEK KDS extension validation (TCB struct v0/v1, HWID 64/8, exclusivity rules), RSA-PSS-SHA384 chain with ARK self-signature, fail-closed CRL (window + ASK/VCEK serials), ECDSA-P384 LE signature over [0,0x2A0). sev_assemble/sev_validate: the full configured go-sev-guest subset incl. per-product iommu_write_safe/fmc_spl rules, layout-tagged TCB floors and relations, mitigation-vector supersets, Turin 8-byte PSN chip-id binding; report_id/_ma stay unenforced. Conformance: quote-sev 13/13, embedded-root SEV reject, frozen-time 2/2; 67 unit tests on real synthetic chains.
authenticate_code / authenticate_platform_endorsements / authenticate_freshness on official sigstore-python 4.4 (offline verify_dsse against a caller-supplied trusted root: chain, SCT, Merkle inclusion, checkpoint, SET, observer timestamps, DSSE), with every tinfoil check it lacks ported locally: media-type/legacy/one-signature gates, duplicate-SCT-log rejection, SAN-regex + issuer + runner_environment policy, protojson-strict statement parsing, artifact-digest semantics + DoS limits, source ref/tag/commit extraction, freshness witness (earliest tlog time, 5min skew, 7d age). Adapter stages authenticate-provenance + assemble-policy wired. provenance 33/33, policy 29/29, envelope 21/21.
Full DCAP quote-v4 verification: ABI parse, PCK SGX-extension tree, TCB Info v3 + QE Identity with encoding/json semantics (exact ints, no floats), chain to the pinned Intel root at the verification time incl. the header-root byte-equality pin, root/PCK CRL windows + revocation, QE/AK signature chain and report-data binding, versioned-module TCB status, PCS replay getter with URL canonicalization and canonical-MIME headers, tcbEvaluationDataNumber recorder, and tdx_assemble/tdx_validate policy comparison (fixed-bit xfam/ td_attributes rules, zero pins, component-wise TEE_TCB_SVN). Conformance: quote-tdx 12/12 and byte-identical to the Go adapter on that directory; real-crypto synthetic test material, no mocks; 390 v3 unit tests green.
… surface quote_authenticate/assemble_and_validate (1:1 quote.go), verify_document_v3 (one appraisal time pins freshness and the quote clock; VerifiedDocumentV3 incl. code_tag; channel-key accessors with id/format pins), fetch_attestation/ random_nonce, the remaining adapter stages (both endorsed keys required on full verify; layer attribution from VerificationError), live-verify through the PUBLIC surface with TLS-SPKI channel binding, and the Tier-1 exports from the package root per SDK_SURFACE_SPEC (adapter full-verify + live consume them; block stages deep-import per the spec allowance). Verified independently: 185/185; byte-identical wire outputs vs Go AND vs JS (0 divergent both ways); live facts identical across all three adapters against production (freshness witness re-signed upstream); 395 unit tests; capabilities schema-valid.
…dening Three-audit fix batch (fidelity/spec/duplication): - Public verify_document_v3 is now the clean 3-arg surface-spec form; the root/clock injection seams move to a private _verify_document_v3 consumed only by the conformance adapter (spec §3 adapter-only seam). - Real parity bug fixed: the SEV PEM decoder rejected CRLF chains Go accepts — found by diffing the sev/tdx duplicated x509 helpers, which are now one shared x509common.py (Go encoding/pem semantics; the two strict TLV readers stay separate with their deltas documented). - Hardening: TDX option-length guards restored, report_data length checked at tdx_assemble, asserts on the trust path replaced with typed POLICY_REJECTED raises (survives python -O), dict-lookup KeyErrors replaced with typed errors, bare-IPv6 live-verify host parsing fixed. - ~700 LOC of parallel-session scaffolding removed (superseded stage scripts, duplicate TDX/envelope test files + builders); PORTING.md moved out of the shipped wheel to repo root; four inaccurate comments corrected; README gains the conformance claim (adapter spec v1.1, surface spec v1.0 Tier-1). Verified: 358 v3 tests + 836 total; 185/185 fixtures; byte-identical vs Go and JS (185 each); live facts identical vs production; wheel free of PORTING.
Replace the v2 engine (GitHub release + Sigstore bundle fetch + hardware- measurement repo fetch) with the v3 flow, mirroring Go SecureClient.verifyV3 and the JS Tier-2: random_nonce -> fetch_attestation -> the public verify_document_v3 -> both endorsed channel keys hard-required at binding. Transports unchanged and fed from the verified document: ehbp binds to the endorsed HPKE key, tls pins the endorsed SPKI fingerprint per connection (no eager dial, Go #118 parity). GroundTruth/VerificationDocument keep their schema, populated from v3 facts incl. the TDX hardware-measurement fingerprint rule; rejection layers map to the existing step states. Release notes: v3-only, no v2 fallback (Go/JS parity); verify_from_bundle removed (it was the v2 engine); the pinned-measurement constructor mode now raises rather than silently skipping code provenance; v3 rejections surface as AttestationError with the layered VerificationError as __cause__. Verified: 848 unit tests (15 new v3-flow); live integration green against inference.tinfoil.sh on the v3 engine (v0.0.142, document carries all v3 facts; remaining 401s reproduced on the unmodified tree = stale API key, not code); conformance suite untouched at 185/185.
Security review finding: the freshness anchor read log_entry.integrated_time unconditionally, but that time is only cryptographically bound when the inclusion promise (SET) is present and verified — the same gate sigstore-python uses to run _verify_set. The embedded trusted root carries a TSA, so a bundle supplying its verified time via a timestamp authority (no inclusion promise) could feed an unverified integrated_time into the 7-day freshness window, weakening anti-replay. Now require the inclusion promise before trusting the tlog time, matching Go's Type=="Tlog" VerifiedTimestamps filter. Real freshness bundles carry inclusion promises, so fixtures are unaffected (freshness 14/14, provenance 33/33).
There was a problem hiding this comment.
40 issues found across 69 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/tinfoil/v3/tdx/expectations.py">
<violation number="1" location="src/tinfoil/v3/tdx/expectations.py:24">
P1: TDX debug quotes are accepted because `_TD_ATTRIBUTES_FIXED0` includes bit 0 and `_validate_bits` has no separate DEBUG check. Reject bit 0 unconditionally, since debug TD memory is visible to the host and breaks confidentiality.</violation>
<violation number="2" location="src/tinfoil/v3/tdx/expectations.py:106">
P3: Custom agent: **Nuke belt-and-suspenders**
`_options(p)` already rejects `minimum_tcb_evaluation_data_number is None` through `validate_tdx_policy(p)`, so this guard is unreachable after a successful call. Remove the duplicate check and keep policy validation centralized in `_options`.</violation>
</file>
<file name="src/tinfoil/v3/tdx/verify.py">
<violation number="1" location="src/tinfoil/v3/tdx/verify.py:502">
P1: When a quote's PCK leaf is issued by Intel SGX PCK Processor CA, this unconditional Platform CA check rejects the chain before verification. Select the expected intermediate phrase from `pck_cert.issuer_cn` so processor PCK quotes can authenticate.</violation>
<violation number="2" location="src/tinfoil/v3/tdx/verify.py:777">
P1: For a versioned TDX quote, this validates the top-level `TdxModule` instead of the selected `TdxModuleIdentity`, leaving the version-specific signer and SEAM attributes unbound. Compare `mr_signer_seam` and masked `seam_attributes` with the identity selected from `TEE_TCB_SVN[1]` before accepting its TCB status.</violation>
</file>
<file name="src/tinfoil/v3/sev/abi.py">
<violation number="1" location="src/tinfoil/v3/sev/abi.py:283">
P1: For report versions below 5, `0x1F8:0x208` is reserved and must be zero, but this check skips that range. Reject those bytes for versions below 5, while retaining `0x208` as the start for v5 reports where the mitigation vectors are defined.</violation>
</file>
<file name="src/tinfoil/v3/tdx/der.py">
<violation number="1" location="src/tinfoil/v3/tdx/der.py:161">
P2: Despite the P-256 contract, these helpers accept any elliptic-curve public key and verify it with SHA-256. Require `pub.curve` to be `SECP256R1` before verifying.</violation>
<violation number="2" location="src/tinfoil/v3/tdx/der.py:263">
P2: When a nested TLV extends beyond its parent, `tlv_children` accepts it if the bytes still fit the outer buffer and may parse sibling bytes as child content. Reject children whose `end` exceeds `t.end`.</violation>
<violation number="3" location="src/tinfoil/v3/tdx/der.py:272">
P2: When a future SGX OID uses first arc 2 with a second arc above 39, `decode_oid` computes the wrong arcs and fails to recognize it. Parse the first subidentifier as base-128 and reject unterminated or non-minimal components.</violation>
</file>
<file name="src/tinfoil/v3/tdx/quote.py">
<violation number="1" location="src/tinfoil/v3/tdx/quote.py:142">
P2: Quotes carrying a non-Intel QE vendor ID are accepted as long as their other signatures and collateral verify. Validate `qe_vendor_id` against Intel's vendor ID during header checking, matching the existing ABI parser, so authenticated quotes cannot claim an unsupported QE vendor.</violation>
</file>
<file name="src/tinfoil/v3/fetch.py">
<violation number="1" location="src/tinfoil/v3/fetch.py:24">
P2: When the attestation endpoint returns an oversized body, this fetch buffers it completely before verification and has no maximum response size. Stream the response and reject it after a bounded number of bytes to prevent a malicious or misbehaving router from exhausting client memory.</violation>
<violation number="2" location="src/tinfoil/v3/fetch.py:24">
P2: The 10-second `httpx` timeout does not cap total fetch duration. A slow peer can keep this call alive by sending data before each read timeout; enforce an overall deadline while streaming the bounded response.</violation>
</file>
<file name="src/tinfoil/v3/provenance/provenance.py">
<violation number="1" location="src/tinfoil/v3/provenance/provenance.py:241">
P2: Signed payloads with a missing or non-in-toto `_type` are accepted by the code and platform verifiers. Require `Statement.type` to equal `https://in-toto.io/Statement/v1`, matching the freshness verifier's check.</violation>
<violation number="2" location="src/tinfoil/v3/provenance/provenance.py:251">
P2: Malformed signed subjects can pass despite the documented protojson-style strict parsing because several recognized subject fields are never type-checked. Validate each allowed field's scalar/map type, or reject fields the verifier does not consume.</violation>
</file>
<file name="src/tinfoil/v3/strictjson.py">
<violation number="1" location="src/tinfoil/v3/strictjson.py:93">
P2: A deeply nested raw bundle or statement raises `RecursionError` instead of `ValueError`, escaping the caller's rejection path and potentially aborting verification. Catch this in `unmarshal()` or replace recursive walking with an iterative or depth-limited parser.</violation>
</file>
<file name="src/tinfoil/v3/client.py">
<violation number="1" location="src/tinfoil/v3/client.py:130">
P2: When `verification_time` is omitted, the freshness proofs and quote validity checks use different appraisal times. Pass the already sampled `appraisal` to `quote_authenticate` so boundary-sensitive verification remains consistent.</violation>
</file>
<file name="src/tinfoil/v3/__init__.py">
<violation number="1" location="src/tinfoil/v3/__init__.py:38">
P2: Custom agent: **Flag Security Vulnerabilities**
When an HTTPS attestation endpoint redirects to HTTP, `fetch_attestation` follows the redirect and sends the next request without TLS. Restrict redirects to HTTPS or disable redirect following before exposing this fetch API.</violation>
</file>
<file name="src/tinfoil/client.py">
<violation number="1" location="src/tinfoil/client.py:40">
P2: Custom agent: **Slop Comments**
Remove this import-narration comment: it repeats the v3 public-surface and single-network-request claims already documented in `verify()`, and the latter is inaccurate when `verify()` first performs router discovery via `get_router_address()`.</violation>
<violation number="2" location="src/tinfoil/client.py:885">
P2: Custom agent: **Detect Outdated or Unused State/Enum Definitions**
The `skipped` state is now obsolete: the v3 flow and remaining code never assign it after the pinned and bundle paths were removed. Remove `skipped` from `VerificationStepState.status` so the declared states match the application logic.</violation>
<violation number="3" location="src/tinfoil/client.py:897">
P2: When the existing ATC/bundle path is used for a deployment where the enclave is reachable only through a proxy, this call now dials the discovered enclave directly and ignores the configured proxy/ATC service. Preserve the bundle/proxy path or route the v3 attestation fetch through the configured proxy before replacing the old flow.</violation>
<violation number="4" location="src/tinfoil/client.py:1087">
P2: When callers use `get_router_address(atc_base_url=...)` directly, this accepts plaintext ATC URLs even though the client path requires HTTPS. Validate `atc_base_url` as an absolute HTTPS URL before constructing the routers endpoint.</violation>
</file>
<file name="src/tinfoil/v3/sev/authenticate.py">
<violation number="1" location="src/tinfoil/v3/sev/authenticate.py:155">
P2: Turin reports using an extended model 1 FMS are rejected before reaching the pinned Turin root, although `kds.product_line_from_fms` classifies them as Turin. Use the KDS product-line mapper here, or centralize the mapping, so supported Turin revisions follow the same product policy throughout verification.</violation>
</file>
<file name="src/tinfoil/v3/provenance/freshness.py">
<violation number="1" location="src/tinfoil/v3/provenance/freshness.py:108">
P2: Custom agent: **Check System Design and Architectural Patterns**
`verify_bundle_with_identity` already parses and verifies this bundle, including a parsed `VerifiedBundle.statement`, but `_parse_freshness_statement(bundle_json)` reparses and decodes the raw bundle. Apply the freshness-specific checks to the verified payload/statement or expose a shared parsed representation instead of parsing the bundle twice.</violation>
<violation number="2" location="src/tinfoil/v3/provenance/freshness.py:138">
P2: When a caller supplies an uppercase digest to `authenticate_code`, passing its returned `Code` to `authenticate_freshness` rejects the valid artifact as malformed. Preserve the existing case-insensitive digest contract by normalizing the expected digest for bundle, statement, and witness comparisons instead of imposing a lowercase-only invariant here.</violation>
</file>
<file name="src/tinfoil/v3/tdx/authenticate.py">
<violation number="1" location="src/tinfoil/v3/tdx/authenticate.py:61">
P2: When `tdx_authenticate(..., now=naive_datetime)` is used, `PCSReplayGetter.get` compares that naive value with timezone-aware CRL timestamps and raises `TypeError`. Normalize naive `now` to UTC before constructing the replay getter so this verification path returns `VerificationError` instead of escaping.</violation>
</file>
<file name="src/tinfoil/v3/provenance/bundle_format.py">
<violation number="1" location="src/tinfoil/v3/provenance/bundle_format.py:25">
P2: The dot-form media type is defined only for v0.3, but this regex also accepts unsupported `bundle.v0.1+json` and `bundle.v0.2+json` values. Restrict the dot-form check to v0.3 so unsupported bundle formats cannot pass `parse_bundle`.</violation>
</file>
<file name="src/tinfoil/v3/policy.py">
<violation number="1" location="src/tinfoil/v3/policy.py:492">
P2: When a signed artifact contains a very long decimal version component, `int()` raises before the parser assigns `PROVENANCE_REJECTED`, leaking an unexpected exception from policy authentication. Check the u8 range without converting unbounded input to an integer.</violation>
<violation number="2" location="src/tinfoil/v3/policy.py:612">
P2: When a platform artifact uses uppercase hex for `mrtd` or `rtmr0`, this comparison rejects the matching quote even though `decode_hex` accepts that encoding. Compare decoded bytes (or normalize both values) before matching.</violation>
</file>
<file name="src/tinfoil/conformance/run.py">
<violation number="1" location="src/tinfoil/conformance/run.py:114">
P2: When `verification_time_unix` is an out-of-range integer, `run` raises before stage handling and the CLI returns an internal-error exit code. Validate the timestamp’s supported range during input parsing and raise `MalformedInput` for conversion failures.</violation>
<violation number="2" location="src/tinfoil/conformance/run.py:317">
P2: When the injected Intel root has a non-`CERTIFICATE` PEM label, this precheck accepts it based only on the DER and the verifier later returns `QUOTE_REJECTED`, so malformed input gets exit 10 instead of exit 30. Require the PEM block type to be `CERTIFICATE` before parsing its DER.</violation>
</file>
<file name="src/tinfoil/v3/tdx/pcs.py">
<violation number="1" location="src/tinfoil/v3/tdx/pcs.py:580">
P2: When callers use `raw_top_level_member` directly, malformed JSON can be accepted as a signed member because the scanner does not validate primitive values or trailing bytes. Validate the complete JSON body before returning the extracted member.</violation>
</file>
<file name="src/tinfoil/v3/sev/x509.py">
<violation number="1" location="src/tinfoil/v3/sev/x509.py:130">
P2: When a configured CA has a finite `BasicConstraints.path_length`, `_verify_chain` accepts chains that exceed that limit. Track the number of intermediate CAs and reject the chain when the parent’s path-length constraint is exhausted.</violation>
</file>
<file name="tests/v3/test_tdx_authenticate.py">
<violation number="1" location="tests/v3/test_tdx_authenticate.py:464">
P2: test_expired_certificates_reject passes for the wrong reason: at now=NOT_AFTER+1 day the captured CRLs (default next_update=NOT_AFTER) are already out of window, so PCSReplayGetter rejects during collateral fetch and the certificate-expiry code path never runs. Build the CRLs with windows covering `now` (as test_now_pins_crl_window does) so only the certificates expire, otherwise this test gives false confidence in certificate-expiry rejection.</violation>
</file>
<file name="src/tinfoil/v3/x509common.py">
<violation number="1" location="src/tinfoil/v3/x509common.py:23">
P2: When a Go-compatible PEM block contains header fields, `pem_decode` returns `None` because the regex does not parse headers before the base64 payload. Parse and skip PEM headers before decoding the payload so the shared certificate loaders accept the same blocks as Go.</violation>
</file>
<file name="src/tinfoil/conformance/cli.py">
<violation number="1" location="src/tinfoil/conformance/cli.py:113">
P2: When `live-verify` receives a bare IPv6 literal, `fetch_attestation` constructs an invalid HTTPS URL and the verification fails before reaching the enclave. Bracket IPv6 hosts before passing them to the URL-based fetch, while retaining the original host for socket dialing.</violation>
<violation number="2" location="src/tinfoil/conformance/cli.py:150">
P2: The measurement dicts built inline in _run_live duplicate run.py's _to_measurement helper (both map Measurement.type plus list(registers) into the same "type"/"registers" shape). Keeping two copies forces any future change to the measurement wire format (e.g. adding a field) to be made in two places, which is exactly the kind of divergence the "simple but extendable" goal wants to avoid. Reuse _to_measurement here.</violation>
</file>
<file name="src/tinfoil/v3/measurement.py">
<violation number="1" location="src/tinfoil/v3/measurement.py:42">
P2: When a malformed `Measurement` reaches `fingerprint`, short register lists raise `IndexError` and oversized lists are silently accepted, despite the module’s all-`ValueError` contract. Validate the exact register count for each supported measurement type before dispatching.</violation>
<violation number="2" location="src/tinfoil/v3/measurement.py:42">
P3: Custom agent: **Slop Comments**
These inline labels merely restate the predicate-type branches and do not explain a non-obvious invariant or behavior. Remove `# Source` and `# Runtime` to keep the dispatch readable.</violation>
</file>
<file name="src/tinfoil/v3/sev/kds.py">
<violation number="1" location="src/tinfoil/v3/sev/kds.py:124">
P2: When `TCBParts` is constructed outside the current JSON path, negative components or `ucode_spl > 255` pass validation and produce an invalid packed TCB. Enforce lower bounds for the 0-127 fields and a complete 0-255 range for `ucode_spl` before packing.</violation>
</file>
<file name="tests/v3/test_tdx_expectations.py">
<violation number="1" location="tests/v3/test_tdx_expectations.py:151">
P2: test_td_attributes_fixed0_bits_reported does not test what its docstring claims. The fixed0/fixed1 bit check in expectations._validate_bits runs against the quote's td_attributes field, not the policy option. The module-scoped quote carries td_attributes 0x...40 (bit 30, allowed in _TD_ATTRIBUTES_FIXED0), so no unauthorized tdAttributes violation is produced. The test passes only on the byte-mismatch error from _exact_byte_match, making it an exact duplicate of test_bad_td_attributes_rejects. The fixed0/fixed1 bit-enforcement path is never exercised, and a regression that removed _validate_bits would go uncaught.</violation>
</file>
<file name="src/tinfoil/v3/embedded_roots.py">
<violation number="1" location="src/tinfoil/v3/embedded_roots.py:9">
P2: `SGX_ROOT_CA_PEM` is byte-identical to `INTEL_SGX_ROOT_CA_PEM` already embedded in `src/tinfoil/attestation/intel_root_ca.py`, so the Intel SGX trust anchor now exists in two places. Trust anchors rotate (Intel's SGX root CA is expiring in 2049 but can still be rotated), and keeping two embedded copies means a future rotation or correction must be made in both modules or the v2 and v3 verifiers will silently diverge. Reuse a single source of the cert (e.g. a lightweight shared constant module that both `attestation` and `v3` import) rather than embedding a second copy.</violation>
</file>
Tip: instead of fixing issues one by one fix them all with cubic
Re-trigger cubic
| _TD_ATTRIBUTES_FIXED1 = 0x0 | ||
| # Supported ATTRIBUTES bits: 0 (DEBUG), 28 (SEPT VE DISABLE), 30 (PKS), | ||
| # 63 (PERFMON). If bit X is 0 in tdAttributesFixed0, it must be 0. | ||
| _TD_ATTRIBUTES_FIXED0 = 0x1 | (1 << 28) | (1 << 30) | (1 << 63) |
There was a problem hiding this comment.
P1: TDX debug quotes are accepted because _TD_ATTRIBUTES_FIXED0 includes bit 0 and _validate_bits has no separate DEBUG check. Reject bit 0 unconditionally, since debug TD memory is visible to the host and breaks confidentiality.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/tinfoil/v3/tdx/expectations.py, line 24:
<comment>TDX debug quotes are accepted because `_TD_ATTRIBUTES_FIXED0` includes bit 0 and `_validate_bits` has no separate DEBUG check. Reject bit 0 unconditionally, since debug TD memory is visible to the host and breaks confidentiality.</comment>
<file context>
@@ -0,0 +1,260 @@
+_TD_ATTRIBUTES_FIXED1 = 0x0
+# Supported ATTRIBUTES bits: 0 (DEBUG), 28 (SEPT VE DISABLE), 30 (PKS),
+# 63 (PERFMON). If bit X is 0 in tdAttributesFixed0, it must be 0.
+_TD_ATTRIBUTES_FIXED0 = 0x1 | (1 << 28) | (1 << 30) | (1 << 63)
+
+_UINT64_MASK = (1 << 64) - 1
</file context>
| _TD_ATTRIBUTES_FIXED0 = 0x1 | (1 << 28) | (1 << 30) | (1 << 63) | |
| _TD_ATTRIBUTES_FIXED0 = (1 << 28) | (1 << 30) | (1 << 63) |
| except ValueError as e: | ||
| raise ValueError(f"unable to validate root cert: {e}") from None | ||
| try: | ||
| _validate_certificate(intermediate_cert, root_cert, _INTERMEDIATE_CERT_PHRASE) |
There was a problem hiding this comment.
P1: When a quote's PCK leaf is issued by Intel SGX PCK Processor CA, this unconditional Platform CA check rejects the chain before verification. Select the expected intermediate phrase from pck_cert.issuer_cn so processor PCK quotes can authenticate.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/tinfoil/v3/tdx/verify.py, line 502:
<comment>When a quote's PCK leaf is issued by Intel SGX PCK Processor CA, this unconditional Platform CA check rejects the chain before verification. Select the expected intermediate phrase from `pck_cert.issuer_cn` so processor PCK quotes can authenticate.</comment>
<file context>
@@ -0,0 +1,943 @@
+ except ValueError as e:
+ raise ValueError(f"unable to validate root cert: {e}") from None
+ try:
+ _validate_certificate(intermediate_cert, root_cert, _INTERMEDIATE_CERT_PHRASE)
+ except ValueError as e:
+ raise ValueError(f"unable to validate Intermediate CA certificate: {e}") from None
</file context>
| _validate_certificate(intermediate_cert, root_cert, _INTERMEDIATE_CERT_PHRASE) | |
| _validate_certificate(intermediate_cert, root_cert, _PROCESSOR_ISSUER if pck_cert.issuer_cn == _PROCESSOR_ISSUER else _PLATFORM_ISSUER) |
| _mbz(data, mbz_lo, 0x1A0) | ||
| _mbz(data, 0x1EB, 0x1EC) | ||
| _mbz(data, 0x1EF, 0x1F0) | ||
| _mbz(data, 0x208, SIGNATURE_OFFSET) |
There was a problem hiding this comment.
P1: For report versions below 5, 0x1F8:0x208 is reserved and must be zero, but this check skips that range. Reject those bytes for versions below 5, while retaining 0x208 as the start for v5 reports where the mitigation vectors are defined.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/tinfoil/v3/sev/abi.py, line 283:
<comment>For report versions below 5, `0x1F8:0x208` is reserved and must be zero, but this check skips that range. Reject those bytes for versions below 5, while retaining `0x208` as the start for v5 reports where the mitigation vectors are defined.</comment>
<file context>
@@ -0,0 +1,368 @@
+ _mbz(data, mbz_lo, 0x1A0)
+ _mbz(data, 0x1EB, 0x1EC)
+ _mbz(data, 0x1EF, 0x1F0)
+ _mbz(data, 0x208, SIGNATURE_OFFSET)
+ if signature_algo == SIGN_ECDSA_P384_SHA384:
+ _mbz(data, SIGNATURE_OFFSET + 2 * _ECDSA_RS_SIZE, REPORT_SIZE)
</file context>
| _mbz(data, 0x208, SIGNATURE_OFFSET) | |
| _mbz(data, 0x208 if version >= 5 else 0x1F8, SIGNATURE_OFFSET) |
| "equal to PCEID value from Intel PCS's reported TDX TCB " | ||
| f"info({json.dumps(tcb_info.pce_id)})" | ||
| ) | ||
| if tcb_info.tdx_module.mrsigner != td_quote_body.mr_signer_seam: |
There was a problem hiding this comment.
P1: For a versioned TDX quote, this validates the top-level TdxModule instead of the selected TdxModuleIdentity, leaving the version-specific signer and SEAM attributes unbound. Compare mr_signer_seam and masked seam_attributes with the identity selected from TEE_TCB_SVN[1] before accepting its TCB status.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/tinfoil/v3/tdx/verify.py, line 777:
<comment>For a versioned TDX quote, this validates the top-level `TdxModule` instead of the selected `TdxModuleIdentity`, leaving the version-specific signer and SEAM attributes unbound. Compare `mr_signer_seam` and masked `seam_attributes` with the identity selected from `TEE_TCB_SVN[1]` before accepting its TCB status.</comment>
<file context>
@@ -0,0 +1,943 @@
+ "equal to PCEID value from Intel PCS's reported TDX TCB "
+ f"info({json.dumps(tcb_info.pce_id)})"
+ )
+ if tcb_info.tdx_module.mrsigner != td_quote_body.mr_signer_seam:
+ raise ValueError(
+ "MRSIGNERSEAM value from TD Quote Body is not equal to "
</file context>
| out: list[TLV] = [] | ||
| off = t.content_start | ||
| while off < t.end: | ||
| c = read_tlv(b, off) |
There was a problem hiding this comment.
P2: When a nested TLV extends beyond its parent, tlv_children accepts it if the bytes still fit the outer buffer and may parse sibling bytes as child content. Reject children whose end exceeds t.end.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/tinfoil/v3/tdx/der.py, line 263:
<comment>When a nested TLV extends beyond its parent, `tlv_children` accepts it if the bytes still fit the outer buffer and may parse sibling bytes as child content. Reject children whose `end` exceeds `t.end`.</comment>
<file context>
@@ -0,0 +1,297 @@
+ out: list[TLV] = []
+ off = t.content_start
+ while off < t.end:
+ c = read_tlv(b, off)
+ out.append(c)
+ off = c.end
</file context>
| tdx_validate(e, quote) | ||
|
|
||
|
|
||
| def test_td_attributes_fixed0_bits_reported(quote, code, report_data): |
There was a problem hiding this comment.
P2: test_td_attributes_fixed0_bits_reported does not test what its docstring claims. The fixed0/fixed1 bit check in expectations._validate_bits runs against the quote's td_attributes field, not the policy option. The module-scoped quote carries td_attributes 0x...40 (bit 30, allowed in _TD_ATTRIBUTES_FIXED0), so no unauthorized tdAttributes violation is produced. The test passes only on the byte-mismatch error from _exact_byte_match, making it an exact duplicate of test_bad_td_attributes_rejects. The fixed0/fixed1 bit-enforcement path is never exercised, and a regression that removed _validate_bits would go uncaught.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/v3/test_tdx_expectations.py, line 151:
<comment>test_td_attributes_fixed0_bits_reported does not test what its docstring claims. The fixed0/fixed1 bit check in expectations._validate_bits runs against the quote's td_attributes field, not the policy option. The module-scoped quote carries td_attributes 0x...40 (bit 30, allowed in _TD_ATTRIBUTES_FIXED0), so no unauthorized tdAttributes violation is produced. The test passes only on the byte-mismatch error from _exact_byte_match, making it an exact duplicate of test_bad_td_attributes_rejects. The fixed0/fixed1 bit-enforcement path is never exercised, and a regression that removed _validate_bits would go uncaught.</comment>
<file context>
@@ -0,0 +1,192 @@
+ tdx_validate(e, quote)
+
+
+def test_td_attributes_fixed0_bits_reported(quote, code, report_data):
+ # 0x4242... sets bits outside tdAttributesFixed0; both the byte mismatch
+ # and the fixed-bit violation are reported (multierr.Combine).
</file context>
| "code_digest": verified.code_digest, | ||
| "code_measurement": { | ||
| "type": verified.code_measurement.type, | ||
| "registers": list(verified.code_measurement.registers), |
There was a problem hiding this comment.
P2: The measurement dicts built inline in _run_live duplicate run.py's _to_measurement helper (both map Measurement.type plus list(registers) into the same "type"/"registers" shape). Keeping two copies forces any future change to the measurement wire format (e.g. adding a field) to be made in two places, which is exactly the kind of divergence the "simple but extendable" goal wants to avoid. Reuse _to_measurement here.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/tinfoil/conformance/cli.py, line 150:
<comment>The measurement dicts built inline in _run_live duplicate run.py's _to_measurement helper (both map Measurement.type plus list(registers) into the same "type"/"registers" shape). Keeping two copies forces any future change to the measurement wire format (e.g. adding a field) to be made in two places, which is exactly the kind of divergence the "simple but extendable" goal wants to avoid. Reuse _to_measurement here.</comment>
<file context>
@@ -0,0 +1,205 @@
+ "code_digest": verified.code_digest,
+ "code_measurement": {
+ "type": verified.code_measurement.type,
+ "registers": list(verified.code_measurement.registers),
+ },
+ "enclave_measurement": {
</file context>
| @@ -0,0 +1,9 @@ | |||
| """Embedded production trust anchors, semantically identical to tinfoil-go's | |||
There was a problem hiding this comment.
P2: SGX_ROOT_CA_PEM is byte-identical to INTEL_SGX_ROOT_CA_PEM already embedded in src/tinfoil/attestation/intel_root_ca.py, so the Intel SGX trust anchor now exists in two places. Trust anchors rotate (Intel's SGX root CA is expiring in 2049 but can still be rotated), and keeping two embedded copies means a future rotation or correction must be made in both modules or the v2 and v3 verifiers will silently diverge. Reuse a single source of the cert (e.g. a lightweight shared constant module that both attestation and v3 import) rather than embedding a second copy.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/tinfoil/v3/embedded_roots.py, line 9:
<comment>`SGX_ROOT_CA_PEM` is byte-identical to `INTEL_SGX_ROOT_CA_PEM` already embedded in `src/tinfoil/attestation/intel_root_ca.py`, so the Intel SGX trust anchor now exists in two places. Trust anchors rotate (Intel's SGX root CA is expiring in 2049 but can still be rotated), and keeping two embedded copies means a future rotation or correction must be made in both modules or the v2 and v3 verifiers will silently diverge. Reuse a single source of the cert (e.g. a lightweight shared constant module that both `attestation` and `v3` import) rather than embedding a second copy.</comment>
<file context>
@@ -0,0 +1,9 @@
+TRUSTED_ROOT_JSON = "{\n \"mediaType\": \"application/vnd.dev.sigstore.trustedroot+json;version=0.1\",\n \"tlogs\": [\n {\n \"baseUrl\": \"https://rekor.sigstore.dev\",\n \"hashAlgorithm\": \"SHA2_256\",\n \"publicKey\": {\n \"rawBytes\": \"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwrkBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==\",\n \"keyDetails\": \"PKIX_ECDSA_P256_SHA_256\",\n \"validFor\": {\n \"start\": \"2021-01-12T11:53:27Z\"\n }\n },\n \"logId\": {\n \"keyId\": \"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0=\"\n }\n },\n {\n \"baseUrl\": \"https://log2025-1.rekor.sigstore.dev\",\n \"hashAlgorithm\": \"SHA2_256\",\n \"publicKey\": {\n \"rawBytes\": \"MCowBQYDK2VwAyEAt8rlp1knGwjfbcXAYPYAkn0XiLz1x8O4t0YkEhie244=\",\n \"keyDetails\": \"PKIX_ED25519\",\n \"validFor\": {\n \"start\": \"2025-09-23T00:00:00Z\"\n }\n },\n \"logId\": {\n \"keyId\": \"zxGZFVvd0FEmjR8WrFwMdcAJ9vtaY/QXf44Y1wUeP6A=\"\n }\n }\n ],\n \"certificateAuthorities\": [\n {\n \"subject\": {\n \"organization\": \"sigstore.dev\",\n \"commonName\": \"sigstore\"\n },\n \"uri\": \"https://fulcio.sigstore.dev\",\n \"certChain\": {\n \"certificates\": [\n {\n \"rawBytes\": \"MIIB+DCCAX6gAwIBAgITNVkDZoCiofPDsy7dfm6geLbuhzAKBggqhkjOPQQDAzAqMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIxMDMwNzAzMjAyOVoXDTMxMDIyMzAzMjAyOVowKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLSyA7Ii5k+pNO8ZEWY0ylemWDowOkNa3kL+GZE5Z5GWehL9/A9bRNA3RbrsZ5i0JcastaRL7Sp5fp/jD5dxqc/UdTVnlvS16an+2Yfswe/QuLolRUCrcOE2+2iA5+tzd6NmMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFMjFHQBBmiQpMlEk6w2uSu1KBtPsMB8GA1UdIwQYMBaAFMjFHQBBmiQpMlEk6w2uSu1KBtPsMAoGCCqGSM49BAMDA2gAMGUCMH8liWJfMui6vXXBhjDgY4MwslmN/TJxVe/83WrFomwmNf056y1X48F9c4m3a3ozXAIxAKjRay5/aj/jsKKGIkmQatjI8uupHr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ==\"\n }\n ]\n },\n \"validFor\": {\n \"start\": \"2021-03-07T03:20:29Z\",\n \"end\": \"2022-12-31T23:59:59.999Z\"\n }\n },\n {\n \"subject\": {\n \"organization\": \"sigstore.dev\",\n \"commonName\": \"sigstore\"\n },\n \"uri\": \"https://fulcio.sigstore.dev\",\n \"certChain\": {\n \"certificates\": [\n {\n \"rawBytes\": \"MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow=\"\n },\n {\n \"rawBytes\": \"MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ\"\n }\n ]\n },\n \"validFor\": {\n \"start\": \"2022-04-13T20:06:15Z\"\n }\n }\n ],\n \"ctlogs\": [\n {\n \"baseUrl\": \"https://ctfe.sigstore.dev/test\",\n \"hashAlgorithm\": \"SHA2_256\",\n \"publicKey\": {\n \"rawBytes\": \"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbfwR+RJudXscgRBRpKX1XFDy3PyudDxz/SfnRi1fT8ekpfBd2O1uoz7jr3Z8nKzxA69EUQ+eFCFI3zeubPWU7w==\",\n \"keyDetails\": \"PKIX_ECDSA_P256_SHA_256\",\n \"validFor\": {\n \"start\": \"2021-03-14T00:00:00Z\",\n \"end\": \"2022-10-31T23:59:59.999Z\"\n }\n },\n \"logId\": {\n \"keyId\": \"CGCS8ChS/2hF0dFrJ4ScRWcYrBY9wzjSbea8IgY2b3I=\"\n }\n },\n {\n \"baseUrl\": \"https://ctfe.sigstore.dev/2022\",\n \"hashAlgorithm\": \"SHA2_256\",\n \"publicKey\": {\n \"rawBytes\": \"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEiPSlFi0CmFTfEjCUqF9HuCEcYXNKAaYalIJmBZ8yyezPjTqhxrKBpMnaocVtLJBI1eM3uXnQzQGAJdJ4gs9Fyw==\",\n \"keyDetails\": \"PKIX_ECDSA_P256_SHA_256\",\n \"validFor\": {\n \"start\": \"2022-10-20T00:00:00Z\"\n }\n },\n \"logId\": {\n \"keyId\": \"3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4=\"\n }\n }\n ],\n \"timestampAuthorities\": [\n {\n \"subject\": {\n \"organization\": \"sigstore.dev\",\n \"commonName\": \"sigstore-tsa-selfsigned\"\n },\n \"uri\": \"https://timestamp.sigstore.dev/api/v1/timestamp\",\n \"certChain\": {\n \"certificates\": [\n {\n \"rawBytes\": \"MIICEDCCAZagAwIBAgIUOhNULwyQYe68wUMvy4qOiyojiwwwCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTA0MDgwNjU5NDNaFw0zNTA0MDYwNjU5NDNaMC4xFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEVMBMGA1UEAxMMc2lnc3RvcmUtdHNhMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE4ra2Z8hKNig2T9kFjCAToGG30jky+WQv3BzL+mKvh1SKNR/UwuwsfNCg4sryoYAd8E6isovVA3M4aoNdm9QDi50Z8nTEyvqgfDPtTIwXItfiW/AFf1V7uwkbkAoj0xxco2owaDAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFIn9eUOHz9BlRsMCRscsc1t9tOsDMB8GA1UdIwQYMBaAFJjsAe9/u1H/1JUeb4qImFMHic6/MBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMAoGCCqGSM49BAMDA2gAMGUCMDtpsV/6KaO0qyF/UMsX2aSUXKQFdoGTptQGc0ftq1csulHPGG6dsmyMNd3JB+G3EQIxAOajvBcjpJmKb4Nv+2Taoj8Uc5+b6ih6FXCCKraSqupe07zqswMcXJTe1cExvHvvlw==\"\n },\n {\n \"rawBytes\": \"MIIB9zCCAXygAwIBAgIUV7f0GLDOoEzIh8LXSW80OJiUp14wCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTA0MDgwNjU5NDNaFw0zNTA0MDYwNjU5NDNaMDkxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEgMB4GA1UEAxMXc2lnc3RvcmUtdHNhLXNlbGZzaWduZWQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQUQNtfRT/ou3YATa6wB/kKTe70cfJwyRIBovMnt8RcJph/COE82uyS6FmppLLL1VBPGcPfpQPYJNXzWwi8icwhKQ6W/Qe2h3oebBb2FHpwNJDqo+TMaC/tdfkv/ElJB72jRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSY7AHvf7tR/9SVHm+KiJhTB4nOvzAKBggqhkjOPQQDAwNpADBmAjEAwGEGrfGZR1cen1R8/DTVMI943LssZmJRtDp/i7SfGHmGRP6gRbuj9vOK3b67Z0QQAjEAuT2H673LQEaHTcyQSZrkp4mX7WwkmF+sVbkYY5mXN+RMH13KUEHHOqASaemYWK/E\"\n }\n ]\n },\n \"validFor\": {\n \"start\": \"2025-07-04T00:00:00Z\"\n }\n }\n ]\n}\n"
+GENOA_CERT_CHAIN_PEM = "-----BEGIN CERTIFICATE-----\n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\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\n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\n/wMz1R1BHg==\n-----END CERTIFICATE-----\n"
+TURIN_CERT_CHAIN_PEM = "-----BEGIN CERTIFICATE-----\nMIIGiTCCBDigAwIBAgIDAwABMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC\nBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS\nBgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg\nQ2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp\nY2VzMRIwEAYDVQQDDAlBUkstVHVyaW4wHhcNMjMwNTE1MjAyNTIxWhcNNDgwNTE1\nMjAyNTIxWjB7MRQwEgYDVQQLDAtFbmdpbmVlcmluZzELMAkGA1UEBhMCVVMxFDAS\nBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTEfMB0GA1UECgwWQWR2YW5j\nZWQgTWljcm8gRGV2aWNlczESMBAGA1UEAwwJU0VWLVR1cmluMIICIjANBgkqhkiG\n9w0BAQEFAAOCAg8AMIICCgKCAgEAnvg5Grv2Emd9lAhKdO64RXU3UESb6JTm0Hhz\nevx1PyxinxYqJL329qTJM0XmdozLYb7rsHxgM5I2pU18M8gect2pN/YB2LQ1/bIq\n37TPDbg7ym0MN6KkZ6aERxAX0voYtdDyNxjDAUjpRpCe1FccAev/Es2n/Fz1G1Tm\nC2XepTQqaKpmt6mnDWSCHCVsQoY0gSibeaG6doM6OiNUCbKXaC7KHH5b/96BD1DJ\n84M+JHqPClFhHqUJwzKF5Qxj4wgWAZzK8UPhiNGjrF6+TBdlFGdSzEqw1jOrCTHd\nuYyLK+5OQ3OIw4S+vZeOVoxJajTIWdsqYP2DLc0HkL0qWOumEOrrc2/4DeETShB0\nMyIpH05kSalyQN2eN5P6ptOB84hddCdbJPEepnD+FqQap1ukw3K8uBcgeBSAF23r\n6UtT8Uc5h7MsWX3MoZiEHcSkDQQ8IedTk7CLjsK6S7b/lfKqfYiRhKgGkRvsEd/M\nDNcumHZKIgzasJwgagzSggiUo9jXp3EWm84fqyxNXzSutPB7qD5P/ULAB+q9Qgvr\nzC8XneaLP0MNrHhM80UejmsBTIktMvFoWVIelYDLdcoi0eMD5DRccfsgrYaY6h/+\n/qf9tgg+mX09UJpuSPRF38oyqnNNFMl5v/tWLgUsChPU6NCQC17Qaqr8mu2ynyyu\nHEs5JVUCAwEAAaOBozCBoDAdBgNVHQ4EFgQUbYJXt6v2sMgUALjxD0WvG9aq628w\nHwYDVR0jBBgwFoAUZKBfceMMCmTYO3XlAVmeK+4GA0QwEgYDVR0TAQH/BAgwBgEB\n/wIBADAOBgNVHQ8BAf8EBAMCAQQwOgYDVR0fBDMwMTAvoC2gK4YpaHR0cHM6Ly9r\nZHNpbnRmLmFtZC5jb20vdmNlay92MS9UdXJpbi9jcmwwRgYJKoZIhvcNAQEKMDmg\nDzANBglghkgBZQMEAgIFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgIFAKID\nAgEwowMCAQEDggIBAAXWJ3DPahralt5kXLPMm9oKlFRqeU3HcS7kA+VBlBA1lQRU\nhXkbXnTvW1GZcgdZvNCB/VlET61KbCzoFIhPIESVjjb/xWX2kg3X0HHmh1EtCDbH\naUFM5rq6l+S1h7qOauRZebvrwApDzAANvW0LTHRumfGm/kqh9NDtVCIWPUZ1VQIg\nGx1T3dwmgOK8ncT1J3W5xIyS0Xu3KC6w7oBlq8G2pPgTcCBJ4JBCTXCEXiAAGaTR\n/TJIaSzoZFLhxYhCMjP8WQGToPGDK2i/lZhkcGHnJOQ+lgrXfpLGqBtLlS3QODyV\nP0MomczG4dqw3THP3Y8Aq9c2KE7SylAKsS/bBKCqkj4OrABkDSkMQEz3BBoFD63a\nD5ZG/Qiz+tmhnptyPVcweC9uJlSWYm25KiV4lT52uBjxatDZKQcrpdgcU8+ozzKU\n8ICnZPOwfWeyuNMq/juyd/rzg5IePyyvt+13aJ5MlZBXZxJKoxCYIMKUwZigf0Xs\nBteT8gw10/xk5smIFIB2ERtTQPMuTENgrPTUjOeiqmBg663c2dLVol+MDiT4ltqf\nEm4Kl/cc4f+H6bEwhj1QKAN2ipRf+mP0NfzJb+6ZHNsOvyq/WByYpLXV9JJoiDW/\n8RZwPU/Mn7IuQBauCy78G7FS0ta3q1et74faYBBgeJ6awEasa25CvmsmlU0R\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\n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\nzpacMwFusA==\n-----END CERTIFICATE-----\n"
+SGX_ROOT_CA_PEM = "-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n"
</file context>
| opts.rtmrs = [rtmr0, code.rtmr1, code.rtmr2, code.rtmr3] | ||
| opts.report_data = report_data | ||
|
|
||
| if p.minimum_tcb_evaluation_data_number is None: # _options validated already |
There was a problem hiding this comment.
P3: Custom agent: Nuke belt-and-suspenders
_options(p) already rejects minimum_tcb_evaluation_data_number is None through validate_tdx_policy(p), so this guard is unreachable after a successful call. Remove the duplicate check and keep policy validation centralized in _options.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/tinfoil/v3/tdx/expectations.py, line 106:
<comment>`_options(p)` already rejects `minimum_tcb_evaluation_data_number is None` through `validate_tdx_policy(p)`, so this guard is unreachable after a successful call. Remove the duplicate check and keep policy validation centralized in `_options`.</comment>
<file context>
@@ -0,0 +1,260 @@
+ opts.rtmrs = [rtmr0, code.rtmr1, code.rtmr2, code.rtmr3]
+ opts.report_data = report_data
+
+ if p.minimum_tcb_evaluation_data_number is None: # _options validated already
+ raise _policy_error("policy minimum_tcb_evaluation_data_number is missing")
+ return (
</file context>
| """Compute a fingerprint for a measurement. Single-register measurements | ||
| return the register value directly; multi-register measurements hash the | ||
| type URL concatenated with all register values (no separator).""" | ||
| if m.type == SNP_TDX_MULTI_PLATFORM_V1: # Source |
There was a problem hiding this comment.
P3: Custom agent: Slop Comments
These inline labels merely restate the predicate-type branches and do not explain a non-obvious invariant or behavior. Remove # Source and # Runtime to keep the dispatch readable.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/tinfoil/v3/measurement.py, line 42:
<comment>These inline labels merely restate the predicate-type branches and do not explain a non-obvious invariant or behavior. Remove `# Source` and `# Runtime` to keep the dispatch readable.</comment>
<file context>
@@ -0,0 +1,62 @@
+ """Compute a fingerprint for a measurement. Single-register measurements
+ return the register value directly; multi-register measurements hash the
+ type URL concatenated with all register values (no separator)."""
+ if m.type == SNP_TDX_MULTI_PLATFORM_V1: # Source
+ if target_type == SEV_GUEST_V2:
+ registers = [m.registers[0]]
</file context>
v3 verifier generated using the conformance suite based on Go and JS.
Summary by cubic
Implements the v3 attestation verifier in Python and switches
SecureClient.verify()from the v2 GitHub/sigstore/hardware-measurement flow to the v3 single-request flow, matching the Go and JS SDKs.What's included
tinfoil.v3with strict envelope parsing, Sigstore provenance, and SEV-SNP (Genoa and Turin) and TDX quote verification.tinfoil-conformanceadapter; the shared v3 conformance suite passes.Breaking changes
verify_from_bundleis removed; there is no v2 fallback.SecureClientwith a pinned measurement now raises instead of silently skipping code provenance.AttestationError, with the layer-carryingVerificationErrorattached as the cause.Written for commit 1190ba0. Summary will update on new commits.