Skip to content

feat(NitroEnclaveVerifier): durable on-chain certificate revocation [non-urgent, post-Multiproving]#276

Open
leopoldjoy wants to merge 1 commit into
mainfrom
leopold-joy/nitro-durable-revocation
Open

feat(NitroEnclaveVerifier): durable on-chain certificate revocation [non-urgent, post-Multiproving]#276
leopoldjoy wants to merge 1 commit into
mainfrom
leopold-joy/nitro-durable-revocation

Conversation

@leopoldjoy
Copy link
Copy Markdown
Contributor

Priority

Not urgent. This change can ship after the Multiproving launch (Base V2 upgrade). Multiproving is the primary mitigation for any single-verifier gap; this PR closes a defense-in-depth hole that would otherwise require either a CA key compromise (Tier B) or an honest-but-racing registrar/admin scenario (Tier A) to exploit. There is no known active exploitation path against the current production configuration.

Summary

  • Adds a persistent revokedCerts mapping that survives the _cacheNewCert suffix rewrite, so a previously revoked intermediate cert path cannot be silently re-trusted by submitting a new attestation that re-derives the same accumulated path digest.
  • Adds unrevokeCert(bytes32) onlyOwner for governed re-trust (two-step: unrevoke, then re-cache via the next successful verify).
  • Reverts in _cacheNewCert (Pass 1) and _verifyJournal (Pass 2) when a sentinel-keyed digest is encountered, plus an early short-circuit in checkTrustedIntermediateCerts.
  • Bumps semver 0.3.00.4.0 (additive — no storage layout changes that move existing slots; only a new mapping appended).

Background — Immunefi #75608 / CHAIN-4194

_cacheNewCert previously rewrote suffix entries unconditionally. If the prefix length is 1 (the production registrar default), revoking an intermediate via revokeCert only zeroed the cached entry — a subsequent attestation re-deriving the same accumulated path digest would re-cache and re-trust it. The new revokedCerts[digest] = true sentinel is checked on every code path that would otherwise mark a cert as trusted, making revocation durable across attestations.

Triage: Low. Tier B requires CA key compromise to forge a new chain that hashes back to the revoked digest; Tier A requires a registrar honest-mistake / admin race. Both are mitigated in production today by operational controls and (post-launch) by Multiproving. This PR is hardening, not an incident response.

Changes

  • src/L1/proofs/tee/NitroEnclaveVerifier.sol
    • New storage: mapping(bytes32 => bool) public revokedCerts (appended, layout-safe).
    • revokeCert: sets sentinel + zeroes any existing cached entry, emits CertRevoked.
    • unrevokeCert: clears sentinel only, emits CertUnrevoked (re-trust requires a fresh verify call to re-cache).
    • _cacheNewCert: skips writing trusted suffix entries whose accumulated digest is sentineled.
    • _verifyJournal: rejects with CertificateRevoked(digest) when traversal encounters a sentineled digest.
    • checkTrustedIntermediateCerts: short-circuits to false if any digest in the chain is sentineled.
  • interfaces/L1/proofs/tee/INitroEnclaveVerifier.sol: declares revokedCerts, unrevokeCert, CertUnrevoked event, CertificateNotRevoked error.
  • test/L1/proofs/NitroEnclaveVerifier.t.sol: 8 new tests covering revoke→re-attest rejection, unrevoke flow, sentinel collision behaviour, owner gating, and event emission. All 81/81 NitroEnclaveVerifier and 366/366 L1 proofs tests pass.
  • Snapshots regenerated for NitroEnclaveVerifier only.

Compatibility

  • Storage layout: strictly append-only. Existing slots untouched. Safe for in-place upgrade.
  • Off-chain registrar: the companion offchain PR is backwards compatible with the current (unpatched) deployed contract — it fail-opens (warns + counter-bumps) when revokedCerts is not present, so the offchain change can be deployed in either order relative to this onchain upgrade.

Out of Scope / Notes

  • Snapshot regen also produced unrelated drift in snapshots/abi/AggregateVerifier.json; intentionally not included in this PR.

Defense-in-depth hardening for CHAIN-4194 / Immunefi #75608. Adds a
persistent revokedCerts mapping that survives the _cacheNewCert suffix
rewrite, so a previously revoked intermediate cannot be silently
re-trusted by submitting a new attestation that re-derives the same
accumulated path digest.

Not urgent. Can ship post-Multiproving launch (Base V2 upgrade)
since multiproof is the primary mitigation for any single verifier
gap; this PR closes a defense-in-depth hole that requires either CA
key compromise (Tier B) or an honest registrar/admin race (Tier A).

Bumps semver to 0.4.0 (additive).
@cb-heimdall
Copy link
Copy Markdown
Collaborator

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

leopoldjoy added a commit to base/base that referenced this pull request May 11, 2026
…ation

Adds an optional NitroEnclaveVerifier client to the registrar so that
each CRL cycle pre-screens parsed cert chains against the on-chain
revokedCerts mapping (CHAIN-4194 / Immunefi #75608 hardening) before
issuing any revokeCert tx.

Backwards compatible: the pre-check fail-opens against deployments
that do not yet expose revokedCerts (selector-not-found reverts are
caught, logged via warn!, and counted by the new
onchain_revocation_check_errors metric). The companion onchain PR
(base/contracts#276) is therefore not required to be deployed first
or in lockstep — the registrar functions normally against either the
existing or upgraded NitroEnclaveVerifier.

Production CLI/env compatibility preserved: --crl-nitro-verifier-address
and BASE_REGISTRAR_CRL_NITRO_VERIFIER_ADDRESS unchanged.

Removes dead BoundlessConfig::nitro_verifier_address field and the
unused --nitro-verifier-address flag (was wired to BoundlessArgs but
never consumed by BoundlessProver).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants