Skip to content

fix(cert): exempt roots from the responder-cert checks (symmetric with the init-side gates)#97

Merged
vxfemboy merged 1 commit into
mainfrom
fix/root-exempt-resp-cert-checks
Jul 23, 2026
Merged

fix(cert): exempt roots from the responder-cert checks (symmetric with the init-side gates)#97
vxfemboy merged 1 commit into
mainfrom
fix/root-exempt-resp-cert-checks

Conversation

@vxfemboy

Copy link
Copy Markdown
Member

Closes #96. Follow-up from the #36/#41 session-lifecycle hardening (PR #95).

Problem

PR #95 introduced a shared is_root helper and exempts always-admit roots from all five init-side cert gates it added (rekey re-verify + re-admission gate on both direct/relay paths, and the liveness sweep). The three pre-existing responder-cert checks — an initiator verifying the responder's msg2 cert in handle_handshake_resp, relayed_handshake_resp, and rekey_resp_core — were left without the exemption.

So a root whose cert lapsed while still in the signed root set, acting as a responder, would be rejected by an initiator completing a handshake with it. Roots are trusted via the signed root set, not a member cert (you revoke a root by removing it from the root set), so this is an inconsistency with the exemption model the rest of the code follows.

Fix

Gate all three responder-cert checks on !self.is_root(self.peers[idx].pubkey) too — a root responder is admitted even with a missing/lapsed cert; a non-root responder still requires a valid cert. These are not drop_session teardown sites; they only refuse to complete.

Testing

  • New initiator_admits_root_responder_despite_missing_cert: an initiator completing a handshake with a root responder that presents no cert establishes (confirmed failing before the fix, passing after).
  • initiator_rejects_responder_with_bad_cert (non-root) stays green — proving the exemption is root-only.
  • 237 unit tests, clippy -D warnings, fmt — all clean.

…h the init-side gates) (#96)

Follow-up from the #36/#41 hardening (PR #95). That branch added is_root
exemption to all five init-side cert gates. The three pre-existing
responder-cert checks — an initiator verifying the responder's msg2 cert in
handle_handshake_resp, relayed_handshake_resp, and rekey_resp_core — lacked it,
so a root whose cert lapsed while still in the signed root set, acting as a
responder, would be rejected by an initiator. Roots are trusted via the signed
root set, not a member cert, so gate all three on !is_root(responder pubkey)
too. New test initiator_admits_root_responder_despite_missing_cert (root
establishes despite no cert); initiator_rejects_responder_with_bad_cert stays
green (non-root still rejected). 237 unit green, clippy clean.
@vxfemboy
vxfemboy merged commit b1ea671 into main Jul 23, 2026
9 checks passed
@vxfemboy
vxfemboy deleted the fix/root-exempt-resp-cert-checks branch July 23, 2026 04:17
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.

Symmetric is_root exemption on the responder-cert checks (handle_handshake_resp / relayed_handshake_resp)

1 participant