From c9bf77331230c61bf2070bc298592beb360993fd Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 28 Oct 2021 11:07:25 -0700 Subject: [PATCH] wgengine/magicsock: replace use of wgkey with new node key type. Signed-off-by: David Anderson --- wgengine/magicsock/magicsock.go | 17 ++++++------ wgengine/magicsock/magicsock_test.go | 41 ++++++++++++---------------- wgengine/userspace.go | 2 +- 3 files changed, 26 insertions(+), 34 deletions(-) diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go index 025395458..7df3de46b 100644 --- a/wgengine/magicsock/magicsock.go +++ b/wgengine/magicsock/magicsock.go @@ -27,6 +27,7 @@ import ( "sync/atomic" "time" + "go4.org/mem" "golang.org/x/crypto/nacl/box" "golang.zx2c4.com/wireguard/conn" "inet.af/netaddr" @@ -51,7 +52,6 @@ import ( "tailscale.com/types/logger" "tailscale.com/types/netmap" "tailscale.com/types/nettype" - "tailscale.com/types/wgkey" "tailscale.com/util/uniq" "tailscale.com/version" "tailscale.com/wgengine/monitor" @@ -2123,11 +2123,11 @@ func (c *Conn) SetPreferredPort(port uint16) { // // If the private key changes, any DERP connections are torn down & // recreated when needed. -func (c *Conn) SetPrivateKey(privateKey wgkey.Private) error { +func (c *Conn) SetPrivateKey(privateKey key.NodePrivate) error { c.mu.Lock() defer c.mu.Unlock() - oldKey, newKey := c.privateKey, key.Private(privateKey) + oldKey, newKey := c.privateKey, privateKey.AsPrivate() if newKey == oldKey { return nil } @@ -2277,7 +2277,7 @@ func (c *Conn) SetNetworkMap(nm *netmap.NetworkMap) { ep.discoKey = n.DiscoKey ep.discoShort = n.DiscoKey.ShortString() } - ep.wgEndpoint = (wgkey.Key(n.Key)).HexString() + ep.wgEndpoint = key.NodePublicFromRaw32(mem.B(n.Key[:])).UntypedHexString() ep.initFakeUDPAddr() c.logf("magicsock: created endpoint key=%s: disco=%s; %v", n.Key.ShortString(), n.DiscoKey.ShortString(), logger.ArgWriter(func(w *bufio.Writer) { const derpPrefix = "127.3.3.40:" @@ -2819,18 +2819,18 @@ func packIPPort(ua netaddr.IPPort) []byte { // ParseEndpoint is called by WireGuard to connect to an endpoint. func (c *Conn) ParseEndpoint(nodeKeyStr string) (conn.Endpoint, error) { - k, err := wgkey.ParseHex(nodeKeyStr) + k, err := key.ParseNodePublicUntyped(mem.S(nodeKeyStr)) if err != nil { return nil, fmt.Errorf("magicsock: ParseEndpoint: parse failed on %q: %w", nodeKeyStr, err) } - pk := tailcfg.NodeKey(k) + pk := tailcfg.NodeKeyFromNodePublic(k) c.mu.Lock() defer c.mu.Unlock() if c.closed { return nil, errConnClosed } - ep, ok := c.peerMap.endpointForNodeKey(tailcfg.NodeKey(pk)) + ep, ok := c.peerMap.endpointForNodeKey(pk) if !ok { // We should never be telling WireGuard about a new peer // before magicsock knows about it. @@ -3019,8 +3019,7 @@ func simpleDur(d time.Duration) time.Duration { } func peerShort(k key.Public) string { - k2 := wgkey.Key(k) - return k2.ShortString() + return key.NodePublicFromRaw32(mem.B(k[:])).ShortString() } func sbPrintAddr(sb *strings.Builder, a netaddr.IPPort) { diff --git a/wgengine/magicsock/magicsock_test.go b/wgengine/magicsock/magicsock_test.go index 4ef0ce753..ea2db2a4a 100644 --- a/wgengine/magicsock/magicsock_test.go +++ b/wgengine/magicsock/magicsock_test.go @@ -131,7 +131,7 @@ func runDERPAndStun(t *testing.T, logf logger.Logf, l nettype.PacketListener, st // necessary to send and receive packets to test e2e wireguard // happiness. type magicStack struct { - privateKey wgkey.Private + privateKey key.NodePrivate epCh chan []tailcfg.Endpoint // endpoint updates produced by this peer conn *Conn // the magicsock itself tun *tuntest.ChannelTUN // TUN device to send/receive packets @@ -144,15 +144,11 @@ type magicStack struct { // friends. You need to call conn.SetNetworkMap and dev.Reconfig // before anything interesting happens. func newMagicStack(t testing.TB, logf logger.Logf, l nettype.PacketListener, derpMap *tailcfg.DERPMap) *magicStack { - privateKey, err := wgkey.NewPrivate() - if err != nil { - t.Fatalf("generating private key: %v", err) - } - + privateKey := key.NewNode() return newMagicStackWithKey(t, logf, l, derpMap, privateKey) } -func newMagicStackWithKey(t testing.TB, logf logger.Logf, l nettype.PacketListener, derpMap *tailcfg.DERPMap, privateKey wgkey.Private) *magicStack { +func newMagicStackWithKey(t testing.TB, logf logger.Logf, l nettype.PacketListener, derpMap *tailcfg.DERPMap, privateKey key.NodePrivate) *magicStack { t.Helper() epCh := make(chan []tailcfg.Endpoint, 100) // arbitrary @@ -215,7 +211,7 @@ func (s *magicStack) Close() { } func (s *magicStack) Public() key.Public { - return key.Public(s.privateKey.Public()) + return s.privateKey.Public().AsPublic() } func (s *magicStack) Status() *ipnstate.Status { @@ -256,8 +252,8 @@ func meshStacks(logf logger.Logf, mutateNetmap func(idx int, nm *netmap.NetworkM buildNetmapLocked := func(myIdx int) *netmap.NetworkMap { me := ms[myIdx] nm := &netmap.NetworkMap{ - PrivateKey: key.NodePrivateFromRaw32(mem.B(me.privateKey[:])), - NodeKey: tailcfg.NodeKey(me.privateKey.Public()), + PrivateKey: me.privateKey, + NodeKey: tailcfg.NodeKeyFromNodePublic(me.privateKey.Public()), Addresses: []netaddr.IPPrefix{netaddr.IPPrefixFrom(netaddr.IPv4(1, 0, 0, byte(myIdx+1)), 32)}, } for i, peer := range ms { @@ -268,7 +264,7 @@ func meshStacks(logf logger.Logf, mutateNetmap func(idx int, nm *netmap.NetworkM peer := &tailcfg.Node{ ID: tailcfg.NodeID(i + 1), Name: fmt.Sprintf("node%d", i+1), - Key: tailcfg.NodeKey(peer.privateKey.Public()), + Key: tailcfg.NodeKeyFromNodePublic(peer.privateKey.Public()), DiscoKey: peer.conn.DiscoPublicKey(), Addresses: addrs, AllowedIPs: addrs, @@ -363,7 +359,7 @@ func TestNewConn(t *testing.T) { } defer conn.Close() conn.SetDERPMap(stuntest.DERPMapOf(stunAddr.String())) - conn.SetPrivateKey(wgkey.Private(key.NewPrivate())) + conn.SetPrivateKey(key.NewNode()) go func() { var pkt [64 << 10]byte @@ -666,10 +662,7 @@ func TestDiscokeyChange(t *testing.T) { derpMap, cleanup := runDERPAndStun(t, t.Logf, localhostListener{}, netaddr.IPv4(127, 0, 0, 1)) defer cleanup() - m1Key, err := wgkey.NewPrivate() - if err != nil { - t.Fatalf("generating nodekey: %v", err) - } + m1Key := key.NewNode() m1 := newMagicStackWithKey(t, t.Logf, localhostListener{}, derpMap, m1Key) defer m1.Close() m2 := newMagicStack(t, t.Logf, localhostListener{}, derpMap) @@ -1007,10 +1000,10 @@ func testTwoDevicePing(t *testing.T, d *devices) { // Wait for magicsock to be told about peers from meshStacks. tstest.WaitFor(10*time.Second, func() error { - if p := m1.Status().Peer[key.Public(m2.privateKey.Public())]; p == nil || !p.InMagicSock { + if p := m1.Status().Peer[m2.privateKey.Public().AsPublic()]; p == nil || !p.InMagicSock { return errors.New("m1 not ready") } - if p := m2.Status().Peer[key.Public(m1.privateKey.Public())]; p == nil || !p.InMagicSock { + if p := m2.Status().Peer[m1.privateKey.Public().AsPublic()]; p == nil || !p.InMagicSock { return errors.New("m2 not ready") } return nil @@ -1018,11 +1011,11 @@ func testTwoDevicePing(t *testing.T, d *devices) { m1cfg := &wgcfg.Config{ Name: "peer1", - PrivateKey: key.NodePrivateFromRaw32(mem.B(m1.privateKey[:])), + PrivateKey: m1.privateKey, Addresses: []netaddr.IPPrefix{netaddr.MustParseIPPrefix("1.0.0.1/32")}, Peers: []wgcfg.Peer{ wgcfg.Peer{ - PublicKey: key.NodePrivateFromRaw32(mem.B(m2.privateKey[:])).Public(), + PublicKey: m2.privateKey.Public(), DiscoKey: m2.conn.DiscoPublicKey(), AllowedIPs: []netaddr.IPPrefix{netaddr.MustParseIPPrefix("1.0.0.2/32")}, }, @@ -1030,11 +1023,11 @@ func testTwoDevicePing(t *testing.T, d *devices) { } m2cfg := &wgcfg.Config{ Name: "peer2", - PrivateKey: key.NodePrivateFromRaw32(mem.B(m2.privateKey[:])), + PrivateKey: m2.privateKey, Addresses: []netaddr.IPPrefix{netaddr.MustParseIPPrefix("1.0.0.2/32")}, Peers: []wgcfg.Peer{ wgcfg.Peer{ - PublicKey: key.NodePrivateFromRaw32(mem.B(m1.privateKey[:])).Public(), + PublicKey: m1.privateKey.Public(), DiscoKey: m1.conn.DiscoPublicKey(), AllowedIPs: []netaddr.IPPrefix{netaddr.MustParseIPPrefix("1.0.0.1/32")}, }, @@ -1251,7 +1244,7 @@ func addTestEndpoint(tb testing.TB, conn *Conn, sendConn net.PacketConn) (tailcf }, }, }) - conn.SetPrivateKey(wgkey.Private{0: 1}) + conn.SetPrivateKey(key.NodePrivateFromRaw32(mem.B([]byte{0: 1, 31: 0}))) _, err := conn.ParseEndpoint(wgkey.Key(nodeKey).HexString()) if err != nil { tb.Fatal(err) @@ -1410,7 +1403,7 @@ func TestSetNetworkMapChangingNodeKey(t *testing.T) { var buf tstest.MemLogger conn.logf = buf.Logf - conn.SetPrivateKey(wgkey.Private{0: 1}) + conn.SetPrivateKey(key.NodePrivateFromRaw32(mem.B([]byte{0: 1, 31: 0}))) discoKey := tailcfg.DiscoKey{31: 1} nodeKey1 := tailcfg.NodeKey{0: 'N', 1: 'K', 2: '1'} diff --git a/wgengine/userspace.go b/wgengine/userspace.go index b54c9a1df..0add62f99 100644 --- a/wgengine/userspace.go +++ b/wgengine/userspace.go @@ -867,7 +867,7 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, // (which is needed by DERP) before wgdev gets it, as wgdev // will start trying to handshake, which we want to be able to // go over DERP. - if err := e.magicConn.SetPrivateKey(cfg.PrivateKey.AsWGPrivate()); err != nil { + if err := e.magicConn.SetPrivateKey(cfg.PrivateKey); err != nil { e.logf("wgengine: Reconfig: SetPrivateKey: %v", err) } e.magicConn.UpdatePeers(peerSet)