diff --git a/tailcfg/tailcfg.go b/tailcfg/tailcfg.go index 7ead5835e..2f00e4b3a 100644 --- a/tailcfg/tailcfg.go +++ b/tailcfg/tailcfg.go @@ -1160,6 +1160,9 @@ func (k *NodeKey) UnmarshalText(text []byte) error { nk.AppendTo(k[:0]) return nil } +func (k NodeKey) AsNodePublic() key.NodePublic { + return key.NodePublicFromRaw32(mem.B(k[:])) +} // IsZero reports whether k is the zero value. func (k NodeKey) IsZero() bool { return k == NodeKey{} } diff --git a/tailcfg/tailcfg_test.go b/tailcfg/tailcfg_test.go index c7a12472f..9d86ef403 100644 --- a/tailcfg/tailcfg_test.go +++ b/tailcfg/tailcfg_test.go @@ -5,6 +5,7 @@ package tailcfg import ( + "bytes" "encoding" "encoding/json" "reflect" @@ -415,6 +416,44 @@ func TestNodeKeyMarshal(t *testing.T) { testKey(t, "nodekey:", k1, &k2) } +func TestNodeKeyRoundTrip(t *testing.T) { + serialized := `{ + "Pub":"nodekey:50d20b455ecf12bc453f83c2cfdb2a24925d06cf2598dcaa54e91af82ce9f765" + }` + + // Carefully check that the expected serialized data decodes and + // re-encodes to the expected keys. These types are serialized to + // disk all over the place and need to be stable. + pub := NodeKey{ + 0x50, 0xd2, 0xb, 0x45, 0x5e, 0xcf, 0x12, 0xbc, 0x45, 0x3f, 0x83, + 0xc2, 0xcf, 0xdb, 0x2a, 0x24, 0x92, 0x5d, 0x6, 0xcf, 0x25, 0x98, + 0xdc, 0xaa, 0x54, 0xe9, 0x1a, 0xf8, 0x2c, 0xe9, 0xf7, 0x65, + } + + type key struct { + Pub NodeKey + } + + var a key + if err := json.Unmarshal([]byte(serialized), &a); err != nil { + t.Fatal(err) + } + if a.Pub != pub { + t.Errorf("wrong deserialization of public key, got %#v want %#v", a.Pub, pub) + } + + bs, err := json.MarshalIndent(a, "", " ") + if err != nil { + t.Fatal(err) + } + + var b bytes.Buffer + json.Indent(&b, []byte(serialized), "", " ") + if got, want := string(bs), b.String(); got != want { + t.Error("json serialization doesn't roundtrip") + } +} + func TestDiscoKeyMarshal(t *testing.T) { var k1, k2 DiscoKey for i := range k1 {