Skip to content

Handshake anti-replay (timestamp) + authenticated endpoint learning #34

Description

@vxfemboy

Context

Milestone 2a (multi-peer data plane, branch feat/multipeer-2a) introduced the in-loop lazy Noise-IK handshake in bin/yipd/src/peer_manager.rs. The whole-branch review surfaced a design-level gap that 2a deliberately defers (handshake hardening is #3 / NAT-roaming is 2b), tracked here.

Problem

The handshake carries no anti-replay token (unlike WireGuard's TAI64N timestamp in the initiation). Two consequences:

  1. Endpoint hijack via replay. handle_handshake_init learns a peer's endpoint from the datagram source (endpoint = src) after admission. An on-path adversary (in-threat-model for a censorship-resistance VPN) who captures one genuine HandshakeInit from configured peer P can replay it from a spoofed source S: start_responder succeeds, recovers P's real static key (so admission passes), and our outbound traffic for P is redirected to S. Admission itself is sound — an unconfigured/forged key allocates nothing — the exposure is specifically trusting an unauthenticated-freshness Init for endpoint learning.

  2. No safe session rebuild on genuine peer restart. Because a replayed old Init is indistinguishable from a genuine re-initiation, an Established responder cannot safely rebuild its session when a peer restarts with a fresh ephemeral (rebuilding on any differing Init would let a replayed old Init tear down a live session — a DoS). 2a works around the loss case by having the initiator retransmit the SAME Init within HANDSHAKE_TOTAL_MS (see the constant's doc comment in peer_manager.rs and commit 9954bfd), which is safe and closes the common wedge — but a genuine peer restart mid-session still cannot be recovered until the responder's own attempt path times out.

Fix (future milestone — handshake hardening / rekey)

  • Add an anti-replay token to the initiation (monotonic timestamp / counter, TAI64N-style), rejecting any Init not strictly newer than the last accepted one from that static key.
  • With anti-replay: (a) only update endpoint from an Init that passes the freshness check; (b) allow an Established responder to rebuild its session on a newer Init (genuine restart/rekey), safely.
  • Revisit by_tag eviction on rebuild (documented on the field) once rebuild becomes reachable.

Scope note

Out of scope for 2a (data plane). Belongs with the session-rekey / PQ-hybrid handshake work and the anti-DPI hardening track. Referenced from the HANDSHAKE_TOTAL_MS doc comment in peer_manager.rs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions