You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tailscale/types/key/nl.go

75 lines
1.9 KiB
Go

// Copyright (c) 2022 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 (
"crypto/ed25519"
"go4.org/mem"
"tailscale.com/tka"
"tailscale.com/types/structs"
)
const (
// nlPrivateHexPrefix is the prefix used to identify a
// hex-encoded network-lock key.
nlPrivateHexPrefix = "nlpriv:"
)
// NLPrivate is a node-managed network-lock key, used for signing
// node-key signatures and authority update messages.
type NLPrivate struct {
_ structs.Incomparable // because == isn't constant-time
k [ed25519.PrivateKeySize]byte
}
// NewNLPrivate creates and returns a new network-lock key.
func NewNLPrivate() NLPrivate {
// ed25519.GenerateKey 'clamps' the key, not that it
// matters given we don't do Diffie-Hellman.
_, priv, err := ed25519.GenerateKey(nil) // nil == crypto/rand
if err != nil {
panic(err)
}
var out NLPrivate
copy(out.k[:], priv)
return out
}
// MarshalText implements encoding.TextUnmarshaler.
func (k *NLPrivate) UnmarshalText(b []byte) error {
return parseHex(k.k[:], mem.B(b), mem.S(nlPrivateHexPrefix))
}
// MarshalText implements encoding.TextMarshaler.
func (k NLPrivate) MarshalText() ([]byte, error) {
return toHex(k.k[:], nlPrivateHexPrefix), nil
}
// Public returns the public component of this key.
func (k NLPrivate) Public() ed25519.PublicKey {
return ed25519.PrivateKey(k.k[:]).Public().(ed25519.PublicKey)
}
// KeyID returns an identifier for this key.
func (k NLPrivate) KeyID() tka.KeyID {
return tka.Key{
Kind: tka.Key25519,
Public: k.Public(),
}.ID()
}
// SignAUM implements tka.UpdateSigner.
func (k NLPrivate) SignAUM(a *tka.AUM) error {
sigHash := a.SigHash()
a.Signatures = append(a.Signatures, tka.Signature{
KeyID: k.KeyID(),
Signature: ed25519.Sign(k.k[:], sigHash[:]),
})
return nil
}