Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/Skidbladnir

crates/installer/nordisk-pairing/src/wireguard.rs

//! **The WireGuard driver — on the suite's ONE userspace WireGuard.**
//!
//! `wg-appliance-core` (this workspace) already holds the x25519 keys, the
//! boringtun packet pump (`dataplane::spawn`), the TUN device and the
//! per-peer handshake accounting; tunnr's wg-appliance PID 1 and gunnar's
//! OS-less appliance run on it. This driver only SHAPES an estate into its
//! `TunnelSpec`: every peer the join reply named becomes a `PeerSpec` whose
//! `allowed_ips` is that peer's overlay address alone, the front is the one
//! peer with an endpoint (the others dial it and it learns theirs from the
//! handshake), and a keepalive keeps NATs open.
//!
//! **Mullvad is this data plane with another peer set.** `tunnr-mullvad`
//! (`tunnel_for_relay`) produces a `TunnelSpec` for the same pump;
//! [`WireGuard::from_spec`] takes it. The Mullvad DRIVER (`crate::mullvad`,
//! feature `mullvad`) holds one of these for the estate mesh and a second,
//! from a spec, for the exit. tunnr-mullvad depends on wg-appliance-core and
//! never on this crate, so there is no cycle.
//!
//! **Tailscale has no Rust component in the suite** — see `crate::tailscale`.
//!
//! **A box on the front's relay** (0.5.5, [`WireGuard::box_via_front`]): the
//! shape gunnar found and fixed on its appliance — the overlay ADDRESS is put
//! ON wg0 (`10.44.0.x/24`, so the kernel has the connected route for the whole
//! overlay), and the FRONT is the one peer, owning `10.44.0.0/24` in the
//! pump's router: every other box is reached THROUGH the relay, never dialled.
//! The per-peer shape above left wg0 with no address (nothing on the box could
//! send into the tunnel) and a /32 per peer the box could not reach directly.
//! [`box_plan`] is that plan, pure.
//!
//! Bringing a TUN up needs CAP_NET_ADMIN, so the tests here cover the SHAPE
//! (keys, peers, endpoints, allowed-ips) and the draupnir fleet test covers
//! the wire.

use crate::join::Peer;
use crate::seed::TunnelKind;
use crate::tunnel::{Identity, Tunnel, TunnelError, TunnelStatus};
use crate::Role;
use std::net::{Ipv4Addr, SocketAddrV4};
use wg_appliance_core::{addr, dataplane, decode_key, encode_key, generate_keypair, PeerSpec, TunDevice, TunnelHandle, TunnelSpec, KEY_LEN};

/// The interface name every box uses; the port the FRONT listens on (the
/// others let the kernel pick, they only dial).
pub const IFACE: &str = "wg0";
pub const FRONT_PORT: u16 = 51820;
pub const MTU: u32 = 1420;
pub const KEEPALIVE_S: u16 = 25;

pub struct WireGuard {
    private: [u8; KEY_LEN],
    public_b64: String,
    listen_port: Option<u16>,
    overlay: Option<Ipv4Addr>,
    peers: Vec<Peer>,
    /// A spec handed in whole (Mullvad), used instead of shaping `peers`.
    given: Option<TunnelSpec>,
    /// 0.5.5: a box on the front's relay ([`WireGuard::box_via_front`]).
    via_front: bool,
    /// 0.5.17: the pre-shared key of the link to the front ([`Tunnel::set_preshared_key`]).
    psk: Option<[u8; KEY_LEN]>,
    handle: Option<TunnelHandle>,
}

/// **The route plan of a box on the front's relay** — what wg0 gets.
#[derive(Clone, PartialEq, Eq)]
pub struct BoxPlan {
    /// ON wg0: this box's overlay address with the overlay's prefix, so the
    /// kernel routes the whole overlay into the tunnel (the connected route).
    pub address: (Ipv4Addr, u8),
    /// The one peer: the front, dialled at its fed endpoint, owning the overlay.
    pub front: PeerSpec,
}

impl std::fmt::Debug for BoxPlan {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "BoxPlan {{ address: {}/{}, front: {:?} owning {:?} }}", self.address.0, self.address.1, self.front.endpoint, self.front.allowed_ips)
    }
}

/// **Pure: the plan for a box at `overlay`, from the peers it was fed.** The
/// fed front (role `front`, with an endpoint and a key) is the one peer and
/// owns [`crate::OVERLAY_NET`]; an overlay address outside it, or no front,
/// is refused by name.
pub fn box_plan(overlay: Ipv4Addr, peers: &[Peer]) -> Result<BoxPlan, TunnelError> {
    if !crate::in_overlay(overlay) {
        return Err(TunnelError::Failed(format!("{IFACE}: {overlay} is not in the estate's overlay {}/{}", crate::OVERLAY_NET.0, crate::OVERLAY_NET.1)));
    }
    let front = peers.iter().find(|p| p.role == Role::Front).ok_or_else(|| TunnelError::Failed(format!("{IFACE}: the installer fed no front tunnel; nothing to dial")))?;
    let endpoint = front.endpoint.as_deref().filter(|e| !e.trim().is_empty()).ok_or_else(|| TunnelError::Failed(format!("peer `{}` is the front and names no endpoint; the front is the one box everybody dials", front.name)))?;
    let endpoint = endpoint.parse::<SocketAddrV4>().map_err(|_| TunnelError::Failed(format!("peer `{}`: endpoint `{endpoint}` is not ipv4:port", front.name)))?;
    let public_key = decode_key(&front.tunnel_pubkey).map_err(|e| TunnelError::Failed(format!("peer `{}`: {}", front.name, e.0)))?;
    Ok(BoxPlan {
        address: (overlay, crate::OVERLAY_NET.1),
        front: PeerSpec { public_key, preshared_key: None, endpoint: Some(endpoint), allowed_ips: vec![crate::OVERLAY_NET], persistent_keepalive: Some(KEEPALIVE_S) },
    })
}

/// **Pure: [`box_plan`] with the link's pre-shared key** (0.5.17, A7 row 13; Gunnar 356e8dd2
/// `wg_conf`): the fed `wg_psk` is the front peer's pre-shared key. Checked as a WireGuard key
/// here, so a bad feed is named (and never quoted) instead of raising a link the relay would
/// never answer. `None`: exactly [`box_plan`].
pub fn box_plan_with_psk(overlay: Ipv4Addr, peers: &[Peer], psk: Option<&str>) -> Result<BoxPlan, TunnelError> {
    let mut plan = box_plan(overlay, peers)?;
    plan.front.preshared_key = psk_of(psk)?;
    Ok(plan)
}

/// The fed PSK as key bytes: `None` for none fed, refused by name when it is not one — a
/// BLANK one included (lane D14, decision c1): a fed but blank key is never read as "no key",
/// which would raise the link without one.
fn psk_of(psk: Option<&str>) -> Result<Option<[u8; KEY_LEN]>, TunnelError> {
    match psk.map(str::trim) {
        None => Ok(None),
        Some("") => Err(TunnelError::Failed(format!("REFUSED [wg-psk-blank] {IFACE}: the installer fed a BLANK WireGuard pre-shared key; the link is never raised without its key"))),
        Some(p) => decode_key(p).map(Some).map_err(|_| TunnelError::Failed(format!("{IFACE}: the installer fed a WireGuard pre-shared key that is not one (32 bytes, base64)"))),
    }
}

impl WireGuard {
    /// **A box on the front's relay with the PSK the installer fed it** (0.5.17, A7 row 13):
    /// [`WireGuard::box_via_front`] whose link to the front carries `psk`
    /// ([`box_plan_with_psk`]). A value that is not a key is refused by name.
    pub fn box_via_front_with_psk(private: [u8; KEY_LEN], psk: Option<&str>) -> Result<WireGuard, TunnelError> {
        Ok(WireGuard { psk: psk_of(psk)?, ..WireGuard::box_via_front(private) })
    }

    /// A fresh identity. The caller persists the private key (`private_key`)
    /// so the box keeps its identity across reboots; peers pin the public one.
    pub fn mint(listen_port: Option<u16>) -> WireGuard {
        let (private, public) = generate_keypair();
        WireGuard { private, public_b64: encode_key(&public), listen_port, overlay: None, peers: Vec::new(), given: None, via_front: false, psk: None, handle: None }
    }

    /// The identity a box kept from its first boot.
    pub fn with_key(private: [u8; KEY_LEN], listen_port: Option<u16>) -> WireGuard {
        let public = wg_appliance_core::keys::public_from_private_bytes(&private);
        WireGuard { private, public_b64: encode_key(&public), listen_port, overlay: None, peers: Vec::new(), given: None, via_front: false, psk: None, handle: None }
    }

    /// A spec somebody else shaped — tunnr-mullvad's `tunnel_for_relay`.
    pub fn from_spec(spec: TunnelSpec) -> WireGuard {
        let public = wg_appliance_core::keys::public_from_private_bytes(&spec.private_key);
        WireGuard { private: spec.private_key, public_b64: encode_key(&public), listen_port: spec.listen_port, overlay: None, peers: Vec::new(), given: Some(spec), via_front: false, psk: None, handle: None }
    }

    /// **A box on the front's relay** (0.5.5), with the key it kept from its
    /// first boot (the one its presentation carried): `up` puts the overlay
    /// address on wg0 and dials the front alone ([`box_plan`]).
    pub fn box_via_front(private: [u8; KEY_LEN]) -> WireGuard {
        WireGuard { via_front: true, ..WireGuard::with_key(private, None) }
    }

    pub fn private_key(&self) -> &[u8; KEY_LEN] {
        &self.private
    }

    pub fn public_key(&self) -> &str {
        &self.public_b64
    }

    pub fn identity(&self, overlay: Ipv4Addr) -> Identity {
        Identity { overlay, pubkey: self.public_b64.clone() }
    }

    /// **The estate as a `TunnelSpec`.** One `PeerSpec` per peer that is not
    /// this box, allowed only its own overlay /32; the front's endpoint is
    /// dialled, every other peer is learned from its handshake.
    pub fn spec(&self) -> Result<TunnelSpec, TunnelError> {
        if let Some(g) = &self.given {
            return Ok(TunnelSpec { private_key: g.private_key, listen_port: g.listen_port, peers: g.peers.clone() });
        }
        if self.via_front {
            let overlay = self.overlay.ok_or_else(|| TunnelError::Failed(format!("{IFACE}: no overlay address yet")))?;
            let mut plan = box_plan(overlay, &self.peers)?;
            plan.front.preshared_key = self.psk;
            return Ok(TunnelSpec { private_key: self.private, listen_port: self.listen_port, peers: vec![plan.front] });
        }
        let mut peers = Vec::new();
        for p in &self.peers {
            if p.tunnel_pubkey == self.public_b64 {
                continue;
            }
            let public_key = decode_key(&p.tunnel_pubkey).map_err(|e| TunnelError::Failed(format!("peer `{}`: {}", p.name, e.0)))?;
            let endpoint = match (&p.endpoint, p.role) {
                (Some(e), _) => Some(e.parse::<SocketAddrV4>().map_err(|_| TunnelError::Failed(format!("peer `{}`: endpoint `{e}` is not ipv4:port", p.name)))?),
                (None, Role::Front) => return Err(TunnelError::Failed(format!("peer `{}` is the front and names no endpoint; the front is the one box everybody dials", p.name))),
                (None, _) => None,
            };
            peers.push(PeerSpec {
                public_key,
                preshared_key: None,
                endpoint,
                allowed_ips: vec![(p.overlay, 32)],
                persistent_keepalive: Some(KEEPALIVE_S),
            });
        }
        if peers.is_empty() {
            return Err(TunnelError::Failed("no peers: a tunnel with nobody in it is not up".into()));
        }
        Ok(TunnelSpec { private_key: self.private, listen_port: self.listen_port, peers })
    }

    fn respawn(&mut self) -> Result<(), TunnelError> {
        let spec = self.spec()?;
        if let Some(mut h) = self.handle.take() {
            h.shutdown();
        }
        let tun = TunDevice::create(IFACE, MTU).map_err(|e| TunnelError::Failed(format!("{IFACE}: {e} (CAP_NET_ADMIN?)")))?;
        // A box on the relay: the address ON wg0 (the connected route carries
        // the whole overlay into the tunnel), through the suite's one ioctl
        // address writer — the same one the installer's link uses.
        if let (true, Some(overlay)) = (self.via_front, self.overlay) {
            let (a, p) = box_plan(overlay, &self.peers)?.address;
            addr::assign_ipv4(IFACE, a, p).map_err(|e| TunnelError::Failed(format!("{IFACE} {a}/{p}: {e}")))?;
            addr::link_up(IFACE).map_err(|e| TunnelError::Failed(format!("{IFACE} up: {e}")))?;
        }
        // Named after the estate's peers (`front`, `main`, `twin`), in the
        // order `spec` lists them, so a timer line names the box it is about.
        let names: Vec<&str> = if self.given.is_some() { Vec::new() } else { self.peers.iter().filter(|p| p.tunnel_pubkey != self.public_b64).map(|p| p.name.as_str()).collect() };
        let handle = dataplane::spawn_named(tun, &spec, &names).map_err(|e| TunnelError::Failed(format!("{IFACE}: {e}")))?;
        self.handle = Some(handle);
        Ok(())
    }
}

impl Tunnel for WireGuard {
    fn kind(&self) -> TunnelKind {
        TunnelKind::Wireguard
    }

    fn public_key(&self) -> String {
        self.public_b64.clone()
    }

    /// Idempotent: a tunnel that is up with these peers stays up.
    fn up(&mut self, me: &Identity, peers: &[Peer]) -> Result<(), TunnelError> {
        if me.pubkey != self.public_b64 {
            return Err(TunnelError::Failed("the identity handed in is not this driver's key".into()));
        }
        self.overlay = Some(me.overlay);
        if self.handle.is_some() && self.peers == peers {
            return Ok(());
        }
        self.peers = peers.to_vec();
        self.respawn()
    }

    /// **Re-point** (0.5.17, A7 row 7): the dial this box makes now against the one these
    /// peers ask for — on the relay, the front alone (its key, its endpoint) and this box's
    /// address. A running pump that dials another is stopped and raised again on the same
    /// interface ([`WireGuard::respawn`]); with no pump yet the peers are kept for the raise.
    fn repoint(&mut self, me: &Identity, peers: &[Peer]) -> Result<bool, TunnelError> {
        if me.pubkey != self.public_b64 {
            return Err(TunnelError::Failed("the identity handed in is not this driver's key".into()));
        }
        let dial = |overlay: Option<Ipv4Addr>, peers: &[Peer]| -> Option<(Ipv4Addr, String, Option<String>)> {
            let f = peers.iter().find(|p| p.role == Role::Front)?;
            Some((overlay?, f.tunnel_pubkey.trim().to_string(), f.endpoint.clone()))
        };
        let same = if self.via_front { dial(self.overlay, &self.peers).is_some() && dial(self.overlay, &self.peers) == dial(Some(me.overlay), peers) } else { self.overlay == Some(me.overlay) && self.peers == peers };
        self.overlay = Some(me.overlay);
        if same && self.handle.is_some() {
            return Ok(false);
        }
        self.peers = peers.to_vec();
        if self.handle.is_none() {
            return Ok(false);
        }
        self.respawn().map(|()| true)
    }

    fn set_preshared_key(&mut self, psk: Option<&str>) -> Result<bool, TunnelError> {
        let psk = psk_of(psk)?;
        if psk == self.psk {
            return Ok(false);
        }
        self.psk = psk;
        if self.handle.is_some() {
            self.respawn()?;
        }
        Ok(true)
    }

    /// A peer learned later: the spec is reshaped and the pump restarted
    /// (boringtun's pump takes its peer set at spawn; a restart is a few
    /// milliseconds and the handshakes come back on their own).
    fn add_peer(&mut self, peer: &Peer) -> Result<(), TunnelError> {
        if self.peers.iter().any(|p| p.name == peer.name && p.tunnel_pubkey == peer.tunnel_pubkey) {
            return Ok(());
        }
        self.peers.retain(|p| p.name != peer.name);
        self.peers.push(peer.clone());
        if self.handle.is_some() {
            self.respawn()?;
        }
        Ok(())
    }

    fn status(&self) -> TunnelStatus {
        let up = self.handle.is_some();
        let reachable = match &self.handle {
            Some(h) => {
                let stats = h.peers();
                self.peers
                    .iter()
                    .filter(|p| p.tunnel_pubkey != self.public_b64 && (!self.via_front || p.role == Role::Front))
                    .enumerate()
                    .filter(|(i, _)| stats.get(*i).is_some_and(|s| s.handshaken()))
                    .map(|(_, p)| p.name.clone())
                    .collect()
            }
            None => Vec::new(),
        };
        TunnelStatus {
            kind: TunnelKind::Wireguard,
            up,
            reachable,
            detail: format!("{IFACE} · {} peer(s) · {}", self.peers.len(), self.overlay.map(|o| o.to_string()).unwrap_or_else(|| "no address yet".into())),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    fn peer(name: &str, role: Role, overlay: Ipv4Addr, endpoint: Option<&str>) -> Peer {
        let (_, public) = generate_keypair();
        Peer { name: name.into(), role, tunnel_pubkey: encode_key(&public), overlay, endpoint: endpoint.map(str::to_string), utility: None }
    }

    #[test]
    fn the_estate_is_shaped_into_a_spec_with_the_front_dialled_and_the_others_learned() {
        let mut wg = WireGuard::mint(None);
        let front = peer("front", Role::Front, crate::OVERLAY_FRONT, Some("95.111.211.189:51820"));
        let other = peer("twin", Role::Twin, crate::OVERLAY_BOX_B, None);
        let me = Peer { name: "main".into(), role: Role::Primary, tunnel_pubkey: wg.public_key().to_string(), overlay: crate::OVERLAY_BOX_A, endpoint: None, utility: None };
        wg.peers = vec![front.clone(), me, other.clone()];
        let spec = wg.spec().unwrap();
        assert_eq!(spec.peers.len(), 2, "this box is not its own peer");
        assert_eq!(spec.peers[0].endpoint, Some("95.111.211.189:51820".parse().unwrap()));
        assert_eq!(spec.peers[0].allowed_ips, vec![(crate::OVERLAY_FRONT, 32)]);
        assert_eq!(spec.peers[1].endpoint, None, "a box behind NAT is learned from its handshake");
        assert_eq!(spec.peers[1].allowed_ips, vec![(crate::OVERLAY_BOX_B, 32)]);
        assert_eq!(spec.peers[0].persistent_keepalive, Some(KEEPALIVE_S));
        assert_eq!(&spec.private_key, wg.private_key());
    }

    #[test]
    fn a_front_without_an_endpoint_a_bad_key_and_no_peers_are_refused_by_name() {
        let mut wg = WireGuard::mint(Some(FRONT_PORT));
        wg.peers = vec![peer("front", Role::Front, crate::OVERLAY_FRONT, None)];
        assert!(wg.spec().unwrap_err().to_string().contains("names no endpoint"));
        let mut bad = peer("twin", Role::Twin, crate::OVERLAY_BOX_B, None);
        bad.tunnel_pubkey = "not-a-key".into();
        wg.peers = vec![bad];
        assert!(wg.spec().unwrap_err().to_string().contains("peer `twin`"));
        wg.peers.clear();
        assert!(wg.spec().unwrap_err().to_string().contains("no peers"));
        let s = wg.status();
        assert!(!s.up && s.reachable.is_empty());
    }

    #[test]
    fn a_box_on_the_relay_puts_its_address_on_wg0_and_the_front_owns_the_overlay() {
        let front = peer("front", Role::Front, crate::OVERLAY_FRONT, Some("10.13.8.1:51820"));
        let twin = peer("twin", Role::Twin, crate::OVERLAY_BOX_B, None);
        let plan = box_plan(crate::OVERLAY_BOX_A, &[twin.clone(), front.clone()]).unwrap();
        assert_eq!(plan.address, (crate::OVERLAY_BOX_A, 24), "the address ON wg0, with the overlay's /24");
        assert_eq!(plan.front.allowed_ips, vec![crate::OVERLAY_NET], "the /24 is routed via the front");
        assert_eq!(plan.front.endpoint, Some("10.13.8.1:51820".parse().unwrap()));
        assert_eq!(plan.front.persistent_keepalive, Some(KEEPALIVE_S));
        let mut wg = WireGuard::box_via_front(*WireGuard::mint(None).private_key());
        wg.overlay = Some(crate::OVERLAY_BOX_A);
        wg.peers = vec![front.clone(), twin];
        let spec = wg.spec().unwrap();
        assert_eq!(spec.peers.len(), 1, "the other box is reached THROUGH the relay, never dialled");
        assert!(spec.peers[0] == plan.front);
        let router = dataplane::Router::new(&spec.peers);
        assert_eq!(router.select(crate::OVERLAY_BOX_B), Some(0), "the twin's address goes to the front");
        assert_eq!(router.select(Ipv4Addr::new(8, 8, 8, 8)), None, "never a default route");
        assert!(box_plan(Ipv4Addr::new(10, 13, 9, 2), std::slice::from_ref(&front)).unwrap_err().to_string().contains("not in the estate's overlay"));
        assert!(box_plan(crate::OVERLAY_BOX_A, &[]).unwrap_err().to_string().contains("no front"));
        let mut blind = front;
        blind.endpoint = None;
        assert!(box_plan(crate::OVERLAY_BOX_A, &[blind]).unwrap_err().to_string().contains("names no endpoint"));
        assert!(!WireGuard::mint(None).via_front, "the per-peer shape is unchanged");
    }

    #[test]
    fn with_key_reproduces_the_same_public_key_and_from_spec_keeps_a_given_spec() {
        let a = WireGuard::mint(None);
        let b = WireGuard::with_key(*a.private_key(), None);
        assert_eq!(a.public_key(), b.public_key());
        let (_, public) = generate_keypair();
        let given = TunnelSpec {
            private_key: *a.private_key(),
            listen_port: None,
            peers: vec![PeerSpec { public_key: public, preshared_key: None, endpoint: Some("10.0.0.1:51820".parse().unwrap()), allowed_ips: vec![(Ipv4Addr::new(0, 0, 0, 0), 0)], persistent_keepalive: None }],
        };
        let m = WireGuard::from_spec(given);
        assert_eq!(m.spec().unwrap().peers[0].allowed_ips, vec![(Ipv4Addr::new(0, 0, 0, 0), 0)], "a Mullvad exit takes everything");
        assert_eq!(m.kind(), TunnelKind::Wireguard);
    }

    const PSK: &str = "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=";

    /// ★ 0.5.17 (A7 row 13, Gunnar 356e8dd2 `wg_conf`): the box's link to the front carries
    /// the fed PSK as the front peer's pre-shared key; a value that is not a 32-byte key is
    /// refused by name and never the key itself; none fed is exactly the old plan.
    /// ★ Lane D14, decision c1: a pre-shared key fed BLANK is refused by name, never read as
    /// "no key"; `None` (an estate laid before PSKs) still raises the link as before.
    #[test]
    fn a_blank_fed_psk_is_refused_never_read_as_no_key() {
        let front = peer("vm1", Role::Front, crate::OVERLAY_FRONT, Some("10.13.8.1:51820"));
        for blank in ["", "   "] {
            assert!(box_plan_with_psk(crate::OVERLAY_BOX_A, std::slice::from_ref(&front), Some(blank)).is_err(), "{blank:?}");
            assert!(WireGuard::box_via_front_with_psk([3u8; 32], Some(blank)).is_err(), "{blank:?}");
            assert!(WireGuard::box_via_front([3u8; 32]).set_preshared_key(Some(blank)).is_err(), "{blank:?}");
        }
        assert!(box_plan_with_psk(crate::OVERLAY_BOX_A, &[front], None).unwrap().front.preshared_key.is_none());
    }

    #[test]
    fn a_box_on_the_relay_dials_the_front_with_the_fed_psk() {
        let front = peer("front", Role::Front, crate::OVERLAY_FRONT, Some("10.13.8.1:51820"));
        let plan = box_plan_with_psk(crate::OVERLAY_BOX_A, std::slice::from_ref(&front), Some(PSK)).unwrap();
        assert_eq!(plan.front.preshared_key, Some(decode_key(PSK).unwrap()));
        let plain = box_plan_with_psk(crate::OVERLAY_BOX_A, std::slice::from_ref(&front), None).unwrap();
        assert!(plain == box_plan(crate::OVERLAY_BOX_A, std::slice::from_ref(&front)).unwrap() && plain.front.preshared_key.is_none(), "none fed: the old plan");
        let e = box_plan_with_psk(crate::OVERLAY_BOX_A, std::slice::from_ref(&front), Some("not-a-key")).unwrap_err().to_string();
        assert!(e.contains("pre-shared key") && !e.contains("not-a-key"), "{e}");
        let mut wg = WireGuard::box_via_front_with_psk(*WireGuard::mint(None).private_key(), Some(PSK)).unwrap();
        wg.overlay = Some(crate::OVERLAY_BOX_A);
        wg.peers = vec![front.clone()];
        assert_eq!(wg.spec().unwrap().peers[0].preshared_key, Some(decode_key(PSK).unwrap()));
        assert!(WireGuard::box_via_front_with_psk([1; 32], Some("short")).is_err());
        // Set later (a re-feed): the next spec carries it.
        let mut later = WireGuard::box_via_front(*WireGuard::mint(None).private_key());
        later.overlay = Some(crate::OVERLAY_BOX_A);
        later.peers = vec![front];
        assert!(later.set_preshared_key(Some(PSK)).unwrap(), "a new PSK is a change");
        assert!(!later.set_preshared_key(Some(PSK)).unwrap(), "the same one is not");
        assert_eq!(later.spec().unwrap().peers[0].preshared_key, Some(decode_key(PSK).unwrap()));
    }

    /// ★ 0.5.17 (A7 row 7): a re-point of a driver that runs no pump yet raises nothing (that
    /// is the tunnel step's): the next raise dials the new front; the same front is no change.
    #[test]
    fn a_repoint_before_the_pump_runs_keeps_the_new_front_for_the_raise() {
        let first = peer("front", Role::Front, crate::OVERLAY_FRONT, Some("10.13.8.1:51820"));
        let moved = Peer { endpoint: Some("10.13.8.9:51820".into()), ..peer("front", Role::Front, crate::OVERLAY_FRONT, None) };
        let mut wg = WireGuard::box_via_front(*WireGuard::mint(None).private_key());
        let me = wg.identity(crate::OVERLAY_BOX_A);
        assert!(!wg.repoint(&me, std::slice::from_ref(&first)).unwrap(), "no pump: nothing re-pointed");
        assert!(!wg.repoint(&me, std::slice::from_ref(&moved)).unwrap());
        assert_eq!(wg.spec().unwrap().peers[0].endpoint, Some("10.13.8.9:51820".parse().unwrap()), "the raise dials the new front");
        assert!(wg.repoint(&Identity { overlay: crate::OVERLAY_BOX_A, pubkey: "other".into() }, &[moved]).is_err(), "never another key");
    }
}