Files
netbird/client/internal/lazyconn/peercfg.go
T
riccardom 3cfc5c82a8 [client] pqkem: install strict-mode keys on idle lazy peers
ML-KEM strict mode promises that no traffic crosses on a non-PQ key. Under
lazy connections an idle peer is still installed in WireGuard, so that
traffic towards it can wake it, and it accepts a handshake the remote
initiates directly. Both lazy listeners installed it without a preshared
key, so a freshly created idle peer accepted a classical session before any
KEM exchange, for example from a remote whose WireGuard still targets the
victim's real endpoint (security review of #7098, finding F-002). The
strict sentinel only reached WireGuard later, on the normal connection
path.

Let the lazy peer config carry a key provider that the listeners install
with the idle peer. In strict mode it yields the PQ PSK once derived and
the sentinel until then; it is read at install time so it is never stale.
Outside strict mode it yields nothing and the idle peer's key is left
unchanged, as before.
2026-10-19 17:02:15 +02:00

31 lines
835 B
Go

package lazyconn
import (
"net/netip"
log "github.com/sirupsen/logrus"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"github.com/netbirdio/netbird/client/internal/peer/id"
)
type PeerConfig struct {
PublicKey string
AllowedIPs []netip.Prefix
PeerConnID id.ConnID
Log *log.Entry
// PresharedKey returns the key to install with the idle WireGuard peer, or nil to
// leave the peer's key as it is. It is read when the peer is installed, not when the
// config is built, so it reflects keys derived after the peer joined. A nil func
// leaves the key unchanged too.
PresharedKey func() *wgtypes.Key
}
// IdlePresharedKey is the key to install with the idle WireGuard peer (nil: unchanged).
func (c PeerConfig) IdlePresharedKey() *wgtypes.Key {
if c.PresharedKey == nil {
return nil
}
return c.PresharedKey()
}