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:
parent
8dd1418774
commit
74c1f632f6
|
@ -99,7 +99,7 @@ func runNetworkLockInit(ctx context.Context, args []string) error {
|
|||
|
||||
fmt.Println("You are initializing tailnet lock with trust in the following keys:")
|
||||
for _, k := range keys {
|
||||
fmt.Printf(" - %x (%s key)\n", k.Public, k.Kind.String())
|
||||
fmt.Printf(" - tlpub:%x (%s key)\n", k.Public, k.Kind.String())
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
|
@ -172,37 +172,23 @@ func runNetworkLockStatus(ctx context.Context, args []string) error {
|
|||
if st.NodeKeySigned {
|
||||
fmt.Println("This node is accessible under tailnet-lock.")
|
||||
} else {
|
||||
p, err := st.PublicKey.MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("This node is LOCKED OUT by tailnet-lock, and action is required to establish connectivity.")
|
||||
fmt.Printf("Run the following command on a node with a trusted key:\n\ttailscale lock sign %v %s\n", st.NodeKey, p)
|
||||
fmt.Printf("Run the following command on a node with a trusted key:\n\ttailscale lock sign %v %s\n", st.NodeKey, st.PublicKey.CLIString())
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
if !st.PublicKey.IsZero() {
|
||||
p, err := st.PublicKey.MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("This node's tailnet-lock key: %s\n", p)
|
||||
fmt.Printf("This node's tailnet-lock key: %s\n", st.PublicKey.CLIString())
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
if st.Enabled && len(st.TrustedKeys) > 0 {
|
||||
fmt.Println("Keys trusted to make changes to tailnet-lock:")
|
||||
for _, k := range st.TrustedKeys {
|
||||
key, err := k.Key.MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var line strings.Builder
|
||||
line.WriteString("\t")
|
||||
line.WriteString(string(key))
|
||||
line.WriteString(k.Key.CLIString())
|
||||
line.WriteString("\t")
|
||||
line.WriteString(fmt.Sprint(k.Votes))
|
||||
line.WriteString("\t")
|
||||
|
|
|
@ -499,7 +499,7 @@ func (b *LocalBackend) NetworkLockInit(keys []tka.Key, disablementValues [][]byt
|
|||
|
||||
b.logf("Generated genesis AUM to initialize network lock, trusting the following keys:")
|
||||
for i, k := range genesisAUM.State.Keys {
|
||||
b.logf(" - key[%d] = nlpub:%x with %d votes", i, k.Public, k.Votes)
|
||||
b.logf(" - key[%d] = tlpub:%x with %d votes", i, k.Public, k.Votes)
|
||||
}
|
||||
|
||||
// Phase 1/2 of initialization: Transmit the genesis AUM to Control.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue