Follow-up from the #36/#41 session-lifecycle hardening (PR #95).
That PR introduced a shared is_root helper and exempts always-admit roots from all five cert-gate sites it added (rekey re-verify + re-admission gate on both direct/relay paths, and the liveness sweep via member_cert_valid).
The pre-existing initiator-completion cert checks — handle_handshake_resp (~2015) and relayed_handshake_resp (~1281), which verify the responder's msg2 cert via responder_cert_ok — do NOT have the is_root exemption. So a root whose cert lapsed while still in the signed root set, acting as a responder, would be rejected by an initiator.
Severity
Latent / low. Roots mint and present valid certs in practice, so this is only reachable in a cert-less-root configuration (which the #41 root-exemption model otherwise supports). The final whole-branch review flagged it as an optional, non-blocking consistency follow-up (out of PR #95's delta — it's pre-existing 2c code).
Fix
Add !self.is_root(<responder pubkey>) && in front of the responder_cert_ok(&responder_payload, self.peers[idx].pubkey) check at both sites (they are not drop_session teardown sites — they just refuse to complete). Add a test: a root responder with a lapsed cert still completes an initiator's handshake.
Deferred
Also related: the stale-doc cleanup was already done in PR #95 (22f75bc).
Follow-up from the #36/#41 session-lifecycle hardening (PR #95).
That PR introduced a shared
is_roothelper and exempts always-admit roots from all five cert-gate sites it added (rekey re-verify + re-admission gate on both direct/relay paths, and the liveness sweep viamember_cert_valid).The pre-existing initiator-completion cert checks —
handle_handshake_resp(~2015) andrelayed_handshake_resp(~1281), which verify the responder's msg2 cert viaresponder_cert_ok— do NOT have theis_rootexemption. So a root whose cert lapsed while still in the signed root set, acting as a responder, would be rejected by an initiator.Severity
Latent / low. Roots mint and present valid certs in practice, so this is only reachable in a cert-less-root configuration (which the #41 root-exemption model otherwise supports). The final whole-branch review flagged it as an optional, non-blocking consistency follow-up (out of PR #95's delta — it's pre-existing 2c code).
Fix
Add
!self.is_root(<responder pubkey>) &&in front of theresponder_cert_ok(&responder_payload, self.peers[idx].pubkey)check at both sites (they are notdrop_sessionteardown sites — they just refuse to complete). Add a test: a root responder with a lapsed cert still completes an initiator's handshake.Deferred
Also related: the stale-doc cleanup was already done in PR #95 (22f75bc).