types/key,cmd/tailscale/cli: support tlpub prefix for tailnet-lock keys

Signed-off-by: Tom DNetto <tom@tailscale.com>
This commit is contained in:
Tom DNetto
2022-11-30 12:30:44 -08:00
committed by Tom
parent 8dd1418774
commit 74c1f632f6
4 changed files with 39 additions and 23 deletions

View File

@@ -15,12 +15,19 @@ import (
const (
// nlPrivateHexPrefix is the prefix used to identify a
// hex-encoded network-lock key.
// hex-encoded tailnet-lock key.
nlPrivateHexPrefix = "nlpriv:"
// nlPublicHexPrefix is the prefix used to identify the public
// side of a hex-encoded network-lock key.
// side of a hex-encoded tailnet-lock key.
nlPublicHexPrefix = "nlpub:"
// nlPublicHexPrefixCLI is the prefix used for tailnet-lock keys
// when shown on the CLI.
// It's not practical for us to change the prefix everywhere due to
// compatibility with existing clients, but we can support both prefixes
// as well as use the CLI form when presenting to the user.
nlPublicHexPrefixCLI = "tlpub:"
)
// NLPrivate is a node-managed network-lock key, used for signing
@@ -116,16 +123,30 @@ func NLPublicFromEd25519Unsafe(public ed25519.PublicKey) NLPublic {
return out
}
// MarshalText implements encoding.TextUnmarshaler.
// UnmarshalText implements encoding.TextUnmarshaler. This function
// is able to decode both the CLI form (tlpub:<hex>) & the
// regular form (nlpub:<hex>).
func (k *NLPublic) UnmarshalText(b []byte) error {
if mem.HasPrefix(mem.B(b), mem.S(nlPublicHexPrefixCLI)) {
return parseHex(k.k[:], mem.B(b), mem.S(nlPublicHexPrefixCLI))
}
return parseHex(k.k[:], mem.B(b), mem.S(nlPublicHexPrefix))
}
// MarshalText implements encoding.TextMarshaler.
// MarshalText implements encoding.TextMarshaler, emitting a
// representation of the form nlpub:<hex>.
func (k NLPublic) MarshalText() ([]byte, error) {
return toHex(k.k[:], nlPublicHexPrefix), nil
}
// CLIString returns a marshalled representation suitable for use
// with tailnet lock commands, of the form tlpub:<hex> instead of
// the nlpub:<hex> form emitted by MarshalText. Both forms can
// be decoded by UnmarshalText.
func (k NLPublic) CLIString() string {
return string(toHex(k.k[:], nlPublicHexPrefixCLI))
}
// Verifier returns a ed25519.PublicKey that can be used to
// verify signatures.
func (k NLPublic) Verifier() ed25519.PublicKey {

View File

@@ -37,4 +37,13 @@ func TestNLPrivate(t *testing.T) {
if !bytes.Equal(decodedPub.k[:], pub.k[:]) {
t.Error("decoded and generated NLPublic bytes differ")
}
// Test decoding with CLI prefix: 'nlpub:' => 'tlpub:'
decodedPub = NLPublic{}
if err := decodedPub.UnmarshalText([]byte(pub.CLIString())); err != nil {
t.Fatal(err)
}
if !bytes.Equal(decodedPub.k[:], pub.k[:]) {
t.Error("decoded and generated NLPublic bytes differ (CLI prefix)")
}
}