mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-21 02:17:36 +00:00
tka,types/key: implement direct node-key signatures
Signed-off-by: Tom DNetto <tom@tailscale.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"crypto/subtle"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"go4.org/mem"
|
||||
"golang.org/x/crypto/curve25519"
|
||||
@@ -34,6 +35,10 @@ const (
|
||||
// changed.
|
||||
nodePublicHexPrefix = "nodekey:"
|
||||
|
||||
// nodePublicBinaryPrefix is the prefix used to identify a
|
||||
// binary-encoded node public key.
|
||||
nodePublicBinaryPrefix = "np"
|
||||
|
||||
// NodePublicRawLen is the length in bytes of a NodePublic, when
|
||||
// serialized with AppendTo, Raw32 or WriteRawWithoutAllocating.
|
||||
NodePublicRawLen = 32
|
||||
@@ -297,6 +302,28 @@ func (k *NodePublic) UnmarshalText(b []byte) error {
|
||||
return parseHex(k.k[:], mem.B(b), mem.S(nodePublicHexPrefix))
|
||||
}
|
||||
|
||||
// MarshalBinary implements encoding.BinaryMarshaler.
|
||||
func (k NodePublic) MarshalBinary() (data []byte, err error) {
|
||||
b := make([]byte, len(nodePublicBinaryPrefix)+NodePublicRawLen)
|
||||
copy(b[:len(nodePublicBinaryPrefix)], nodePublicBinaryPrefix)
|
||||
copy(b[len(nodePublicBinaryPrefix):], k.k[:])
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
|
||||
func (k *NodePublic) UnmarshalBinary(in []byte) error {
|
||||
data := mem.B(in)
|
||||
if !mem.HasPrefix(data, mem.S(nodePublicBinaryPrefix)) {
|
||||
return fmt.Errorf("missing/incorrect type prefix %s", nodePublicBinaryPrefix)
|
||||
}
|
||||
if want, got := len(nodePublicBinaryPrefix)+NodePublicRawLen, data.Len(); want != got {
|
||||
return fmt.Errorf("incorrect len for NodePublic (%d != %d)", got, want)
|
||||
}
|
||||
|
||||
data.SliceFrom(len(nodePublicBinaryPrefix)).Copy(k.k[:])
|
||||
return nil
|
||||
}
|
||||
|
||||
// WireGuardGoString prints k in the same format used by wireguard-go.
|
||||
func (k NodePublic) WireGuardGoString() string {
|
||||
// This implementation deliberately matches the overly complicated
|
||||
|
@@ -30,6 +30,20 @@ func TestNodeKey(t *testing.T) {
|
||||
if full, got := string(bs), ":"+p.UntypedHexString(); !strings.HasSuffix(full, got) {
|
||||
t.Fatalf("NodePublic.UntypedHexString is not a suffix of the typed serialization, got %q want suffix of %q", got, full)
|
||||
}
|
||||
bs, err = p.MarshalBinary()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got, want := bs, append([]byte(nodePublicBinaryPrefix), p.k[:]...); !bytes.Equal(got, want) {
|
||||
t.Fatalf("Binary-encoded NodePublic = %x, want %x", got, want)
|
||||
}
|
||||
var decoded NodePublic
|
||||
if err := decoded.UnmarshalBinary(bs); err != nil {
|
||||
t.Fatalf("NodePublic.UnmarshalBinary(%x) failed: %v", bs, err)
|
||||
}
|
||||
if decoded != p {
|
||||
t.Errorf("unmarshaled and original NodePublic differ:\noriginal = %v\ndecoded = %v", p, decoded)
|
||||
}
|
||||
|
||||
z := NodePublic{}
|
||||
if !z.IsZero() {
|
||||
|
Reference in New Issue
Block a user