From 810c1e9704e4898543cc3b050c5b80f9f7d64df5 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Fri, 27 Mar 2020 13:03:35 -0700 Subject: [PATCH] types/key: make Public implement TextMarshaler, TextUnmarshaler So it can be a map key with encoding/json --- types/key/key.go | 22 ++++++++++++++++++++++ types/key/key_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 types/key/key_test.go diff --git a/types/key/key.go b/types/key/key.go index e000520bb..34becba31 100644 --- a/types/key/key.go +++ b/types/key/key.go @@ -7,6 +7,8 @@ package key import ( "encoding/base64" + "errors" + "fmt" "golang.org/x/crypto/curve25519" ) @@ -35,6 +37,26 @@ func (p Public) ShortString() string { return "[" + base64.StdEncoding.EncodeToString(p[:])[:5] + "]" } +func (p Public) MarshalText() ([]byte, error) { + buf := make([]byte, base64.StdEncoding.EncodedLen(len(p))) + base64.StdEncoding.Encode(buf, p[:]) + return buf, nil +} + +func (p *Public) UnmarshalText(txt []byte) error { + if *p != (Public{}) { + return errors.New("refusing to unmarshal into non-zero key.Public") + } + n, err := base64.StdEncoding.Decode(p[:], txt) + if err != nil { + return err + } + if n != 32 { + return fmt.Errorf("short decode of %d; want 32", n) + } + return nil +} + // B32 returns k as the *[32]byte type that's used by the // golang.org/x/crypto packages. This allocates; it might // not be appropriate for performance-sensitive paths. diff --git a/types/key/key_test.go b/types/key/key_test.go new file mode 100644 index 000000000..b2fc88618 --- /dev/null +++ b/types/key/key_test.go @@ -0,0 +1,24 @@ +// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package key + +import ( + "testing" +) + +func TestTextUnmarshal(t *testing.T) { + p := Public{1, 2} + text, err := p.MarshalText() + if err != nil { + t.Fatal(err) + } + var p2 Public + if err := p2.UnmarshalText(text); err != nil { + t.Fatal(err) + } + if p != p2 { + t.Fatalf("mismatch; got %x want %x", p2, p) + } +}