types/key: rename NLPublic/Private to TLPublic/Private

The NL prefix is one of the last references to the "Network Lock" name
which we're cleaning up.

Updates tailscale/corp#37904

Change-Id: I751194e0b49447e97a65ed6975e3da680226ce85
Signed-off-by: Alex Chan <alexc@tailscale.com>
This commit is contained in:
Alex Chan authored and Alex Chan committed 2026-10-02 16:03:51 +01:00
1 parent 3ce5e20997
commit 9128778b65
33 files changed
+170 -141

No files matched your search

+3 -3
View File
@@ -59,7 +59,7 @@ func (lc *Client) NetworkLockInit(ctx context.Context, keys []tka.Key, disableme
// TailnetLockWrapPreauthKey wraps a pre-auth key with information to // TailnetLockWrapPreauthKey wraps a pre-auth key with information to
// enable unattended bringup in the locked tailnet. // enable unattended bringup in the locked tailnet.
func (lc *Client) TailnetLockWrapPreauthKey(ctx context.Context, preauthKey string, tkaKey key.NLPrivate) (string, error) { func (lc *Client) TailnetLockWrapPreauthKey(ctx context.Context, preauthKey string, tkaKey key.TLPrivate) (string, error) {
encodedPrivate, err := tkaKey.MarshalText() encodedPrivate, err := tkaKey.MarshalText()
if err != nil { if err != nil {
return "", err return "", err
@@ -68,7 +68,7 @@ func (lc *Client) TailnetLockWrapPreauthKey(ctx context.Context, preauthKey stri
var b bytes.Buffer var b bytes.Buffer
type wrapRequest struct { type wrapRequest struct {
TSKey string TSKey string
TKAKey string // key.NLPrivate.MarshalText TKAKey string // key.TLPrivate.MarshalText
} }
if err := json.NewEncoder(&b).Encode(wrapRequest{TSKey: preauthKey, TKAKey: string(encodedPrivate)}); err != nil { if err := json.NewEncoder(&b).Encode(wrapRequest{TSKey: preauthKey, TKAKey: string(encodedPrivate)}); err != nil {
return "", err return "", err
@@ -82,7 +82,7 @@ func (lc *Client) TailnetLockWrapPreauthKey(ctx context.Context, preauthKey stri
} }
// Deprecated: use [Client.TailnetLockWrapPreauthKey] instead. // Deprecated: use [Client.TailnetLockWrapPreauthKey] instead.
func (lc *Client) NetworkLockWrapPreauthKey(ctx context.Context, preauthKey string, tkaKey key.NLPrivate) (string, error) { func (lc *Client) NetworkLockWrapPreauthKey(ctx context.Context, preauthKey string, tkaKey key.TLPrivate) (string, error) {
return lc.TailnetLockWrapPreauthKey(ctx, preauthKey, tkaKey) return lc.TailnetLockWrapPreauthKey(ctx, preauthKey, tkaKey)
} }
+4 -4
View File
@@ -408,7 +408,7 @@ of the Tailscale network. Proceed with caution.
// parseTLArgs parses a slice of strings into slices of tka.Key & disablement // parseTLArgs parses a slice of strings into slices of tka.Key & disablement
// values/secrets. // values/secrets.
// The keys encoded in args should be specified using their key.NLPublic.MarshalText // The keys encoded in args should be specified using their [key.TLPublic.MarshalText]
// representation with an optional '?<votes>' suffix. // representation with an optional '?<votes>' suffix.
// Disablement values or secrets must be encoded in hex with a prefix of 'disablement:' or // Disablement values or secrets must be encoded in hex with a prefix of 'disablement:' or
// 'disablement-secret:'. // 'disablement-secret:'.
@@ -430,7 +430,7 @@ func parseTLArgs(args []string, parseKeys, parseDisablements bool) (keys []tka.K
return nil, nil, fmt.Errorf("parsing argument %d: expected value with \"disablement:\" or \"disablement-secret:\" prefix, got %q", i+1, a) return nil, nil, fmt.Errorf("parsing argument %d: expected value with \"disablement:\" or \"disablement-secret:\" prefix, got %q", i+1, a)
} }
var nlpk key.NLPublic var nlpk key.TLPublic
spl := strings.SplitN(a, "?", 2) spl := strings.SplitN(a, "?", 2)
if err := nlpk.UnmarshalText([]byte(spl[0])); err != nil { if err := nlpk.UnmarshalText([]byte(spl[0])); err != nil {
return nil, nil, fmt.Errorf("parsing key %d: %v", i+1, err) return nil, nil, fmt.Errorf("parsing key %d: %v", i+1, err)
@@ -511,7 +511,7 @@ func runTailnetLockSign(ctx context.Context, args []string) error {
var ( var (
nodeKey key.NodePublic nodeKey key.NodePublic
rotationKey key.NLPublic rotationKey key.TLPublic
) )
if len(args) == 0 || len(args) > 2 { if len(args) == 0 || len(args) > 2 {
@@ -764,7 +764,7 @@ func wrapAuthKey(ctx context.Context, keyStr string, status *ipnstate.Status) er
// Generate a separate tailnet-lock key just for the credential signature. // Generate a separate tailnet-lock key just for the credential signature.
// We use the free-form meta strings to mark a little bit of metadata about this // We use the free-form meta strings to mark a little bit of metadata about this
// key. // key.
priv := key.NewNLPrivate() priv := key.NewTLPrivate()
m := map[string]string{ m := map[string]string{
"purpose": "pre-auth key", "purpose": "pre-auth key",
"wrapper_stableid": string(status.Self.ID), "wrapper_stableid": string(status.Self.ID),
+2 -2
View File
@@ -217,9 +217,9 @@ func TestTailnetLockStatusOutput(t *testing.T) {
nodeKey2 := key.NodePublicFromRaw32(mem.B(bytes.Repeat([]byte{2}, 32))) nodeKey2 := key.NodePublicFromRaw32(mem.B(bytes.Repeat([]byte{2}, 32)))
nodeKey3 := key.NodePublicFromRaw32(mem.B(bytes.Repeat([]byte{3}, 32))) nodeKey3 := key.NodePublicFromRaw32(mem.B(bytes.Repeat([]byte{3}, 32)))
nlPub := key.NLPublicFromEd25519Unsafe(bytes.Repeat([]byte{4}, 32)) nlPub := key.TLPublicFromEd25519Unsafe(bytes.Repeat([]byte{4}, 32))
trustedNlPub := key.NLPublicFromEd25519Unsafe(bytes.Repeat([]byte{5}, 32)) trustedNlPub := key.TLPublicFromEd25519Unsafe(bytes.Repeat([]byte{5}, 32))
tailnetIPv4_A, tailnetIPv6_A := netip.MustParseAddr("100.99.99.99"), netip.MustParseAddr("fd7a:115c:a1e0::701:b62a") tailnetIPv4_A, tailnetIPv6_A := netip.MustParseAddr("100.99.99.99"), netip.MustParseAddr("fd7a:115c:a1e0::701:b62a")
tailnetIPv4_B, tailnetIPv6_B := netip.MustParseAddr("100.88.88.88"), netip.MustParseAddr("fd7a:115c:a1e0::4101:512f") tailnetIPv4_B, tailnetIPv6_B := netip.MustParseAddr("100.88.88.88"), netip.MustParseAddr("fd7a:115c:a1e0::4101:512f")
+1 -1
View File
@@ -78,7 +78,7 @@ func print(info string, nodeKey key.NodePublic, sig tka.NodeKeySignature) {
if ln := chainLength(sig); ln > *maxRotations { if ln := chainLength(sig); ln > *maxRotations {
log.Printf("%s: chain length %d, printing command to re-sign", info, ln) log.Printf("%s: chain length %d, printing command to re-sign", info, ln)
wrapping, _ := sig.UnverifiedWrappingPublic() wrapping, _ := sig.UnverifiedWrappingPublic()
fmt.Printf("tailscale lock sign %s %s\n", nodeKey, key.NLPublicFromEd25519Unsafe(wrapping).CLIString()) fmt.Printf("tailscale lock sign %s %s\n", nodeKey, key.TLPublicFromEd25519Unsafe(wrapping).CLIString())
} else { } else {
log.Printf("%s: does not need re-signing", info) log.Printf("%s: does not need re-signing", info)
} }
+2
View File
@@ -46,6 +46,8 @@ var PureIsZeroMethodsInTailscaleModule = map[string]set.Set[string]{
"tailscale.com/types/key": set.Of( "tailscale.com/types/key": set.Of(
"NLPrivate", "NLPrivate",
"NLPublic", "NLPublic",
"TLPrivate",
"TLPublic",
"DERPMesh", "DERPMesh",
"MachinePrivate", "MachinePrivate",
"MachinePublic", "MachinePublic",
+1 -1
View File
@@ -719,7 +719,7 @@ func (c *Direct) doLogin(ctx context.Context, opt loginOpt) (mustRegen bool, new
oldNodeKey = persist.OldPrivateNodeKey.Public() oldNodeKey = persist.OldPrivateNodeKey.Public()
} }
if persist.NetworkLockKey.IsZero() { if persist.NetworkLockKey.IsZero() {
persist.NetworkLockKey = key.NewNLPrivate() persist.NetworkLockKey = key.NewTLPrivate()
} }
nlPub := persist.NetworkLockKey.Public() nlPub := persist.NetworkLockKey.Public()
+2 -2
View File
@@ -22,7 +22,7 @@ func TestHandleC2NDebugTKA(t *testing.T) {
return nil, nil return nil, nil
} }
signerKey := key.NewNLPrivate() signerKey := key.NewTLPrivate()
key1 := tka.Key{Kind: tka.Key25519, Public: signerKey.Public().Verifier(), Votes: 2} key1 := tka.Key{Kind: tka.Key25519, Public: signerKey.Public().Verifier(), Votes: 2}
state := tka.CreateStateForTest(key1) state := tka.CreateStateForTest(key1)
@@ -34,7 +34,7 @@ func TestHandleC2NDebugTKA(t *testing.T) {
for range length - 1 { for range length - 1 {
updater := authority.NewUpdater(signerKey) updater := authority.NewUpdater(signerKey)
key2 := tka.Key{Kind: tka.Key25519, Public: key.NewNLPrivate().Public().Verifier(), Votes: 2} key2 := tka.Key{Kind: tka.Key25519, Public: key.NewTLPrivate().Public().Verifier(), Votes: 2}
updater.AddKey(key2) updater.AddKey(key2)
aums := must.Get(updater.Finalize(chonk)) aums := must.Get(updater.Finalize(chonk))
must.Do(authority.Inform(chonk, aums)) must.Do(authority.Inform(chonk, aums))
+5 -5
View File
@@ -618,7 +618,7 @@ func TestExtensionHostProfileStateChangeCallback(t *testing.T) {
NodeID: "12345", NodeID: "12345",
PrivateNodeKey: key.NewNode(), PrivateNodeKey: key.NewNode(),
OldPrivateNodeKey: key.NewNode(), OldPrivateNodeKey: key.NewNode(),
NetworkLockKey: key.NewNLPrivate(), NetworkLockKey: key.NewTLPrivate(),
UserProfile: tailcfg.UserProfile{ UserProfile: tailcfg.UserProfile{
ID: 12345, ID: 12345,
LoginName: "test@example.com", LoginName: "test@example.com",
@@ -635,7 +635,7 @@ func TestExtensionHostProfileStateChangeCallback(t *testing.T) {
NodeID: "12345", NodeID: "12345",
PrivateNodeKey: key.NodePrivate{}, // stripped PrivateNodeKey: key.NodePrivate{}, // stripped
OldPrivateNodeKey: key.NodePrivate{}, // stripped OldPrivateNodeKey: key.NodePrivate{}, // stripped
NetworkLockKey: key.NLPrivate{}, // stripped NetworkLockKey: key.TLPrivate{}, // stripped
UserProfile: tailcfg.UserProfile{ UserProfile: tailcfg.UserProfile{
ID: 12345, ID: 12345,
LoginName: "test@example.com", LoginName: "test@example.com",
@@ -690,7 +690,7 @@ func TestExtensionHostProfileStateChangeCallback(t *testing.T) {
NodeID: "12345", NodeID: "12345",
PrivateNodeKey: key.NewNode(), PrivateNodeKey: key.NewNode(),
OldPrivateNodeKey: key.NewNode(), OldPrivateNodeKey: key.NewNode(),
NetworkLockKey: key.NewNLPrivate(), NetworkLockKey: key.NewTLPrivate(),
UserProfile: tailcfg.UserProfile{ UserProfile: tailcfg.UserProfile{
ID: 12345, ID: 12345,
LoginName: "test@example.com", LoginName: "test@example.com",
@@ -706,7 +706,7 @@ func TestExtensionHostProfileStateChangeCallback(t *testing.T) {
NodeID: "12345", NodeID: "12345",
PrivateNodeKey: key.NewNode(), PrivateNodeKey: key.NewNode(),
OldPrivateNodeKey: key.NewNode(), OldPrivateNodeKey: key.NewNode(),
NetworkLockKey: key.NewNLPrivate(), NetworkLockKey: key.NewTLPrivate(),
UserProfile: tailcfg.UserProfile{ UserProfile: tailcfg.UserProfile{
ID: 12345, ID: 12345,
LoginName: "test@example.com", LoginName: "test@example.com",
@@ -727,7 +727,7 @@ func TestExtensionHostProfileStateChangeCallback(t *testing.T) {
NodeID: "12345", NodeID: "12345",
PrivateNodeKey: key.NodePrivate{}, // stripped PrivateNodeKey: key.NodePrivate{}, // stripped
OldPrivateNodeKey: key.NodePrivate{}, // stripped OldPrivateNodeKey: key.NodePrivate{}, // stripped
NetworkLockKey: key.NLPrivate{}, // stripped NetworkLockKey: key.TLPrivate{}, // stripped
UserProfile: tailcfg.UserProfile{ UserProfile: tailcfg.UserProfile{
ID: 12345, ID: 12345,
LoginName: "test@example.com", LoginName: "test@example.com",
+1 -1
View File
@@ -1448,7 +1448,7 @@ func stripKeysFromPrefs(p ipn.PrefsView) ipn.PrefsView {
p2 := p.AsStruct() p2 := p.AsStruct()
p2.Persist.PrivateNodeKey = key.NodePrivate{} p2.Persist.PrivateNodeKey = key.NodePrivate{}
p2.Persist.OldPrivateNodeKey = key.NodePrivate{} p2.Persist.OldPrivateNodeKey = key.NodePrivate{}
p2.Persist.NetworkLockKey = key.NLPrivate{} p2.Persist.NetworkLockKey = key.TLPrivate{}
p2.Persist.AttestationKey = nil p2.Persist.AttestationKey = nil
return p2.View() return p2.View()
} }
+1 -1
View File
@@ -9140,7 +9140,7 @@ func TestStripKeysFromPrefs(t *testing.T) {
"Notify.Prefs.ж.Persist.NetworkLockKey": func() ipn.Notify { "Notify.Prefs.ж.Persist.NetworkLockKey": func() ipn.Notify {
return ipn.Notify{ return ipn.Notify{
Prefs: new((&ipn.Prefs{ Prefs: new((&ipn.Prefs{
Persist: &persist.Persist{NetworkLockKey: key.NewNLPrivate()}, Persist: &persist.Persist{NetworkLockKey: key.NewTLPrivate()},
}).View()), }).View()),
} }
}, },
+10 -10
View File
@@ -591,7 +591,7 @@ func (b *LocalBackend) TailnetLockStatus() *ipnstate.TailnetLockStatus {
var ( var (
nodeKey *key.NodePublic nodeKey *key.NodePublic
nlPriv key.NLPrivate nlPriv key.TLPrivate
) )
if p := b.pm.CurrentPrefs(); p.Valid() && p.Persist().Valid() && !p.Persist().PrivateNodeKey().IsZero() { if p := b.pm.CurrentPrefs(); p.Valid() && p.Persist().Valid() && !p.Persist().PrivateNodeKey().IsZero() {
nkp := p.Persist().PublicNodeKey() nkp := p.Persist().PublicNodeKey()
@@ -632,7 +632,7 @@ func (b *LocalBackend) TailnetLockStatus() *ipnstate.TailnetLockStatus {
for i, k := range keys { for i, k := range keys {
outKeys[i] = ipnstate.TKAKey{ outKeys[i] = ipnstate.TKAKey{
Kind: k.Kind.String(), Kind: k.Kind.String(),
Key: key.NLPublicFromEd25519Unsafe(k.Public), Key: key.TLPublicFromEd25519Unsafe(k.Public),
Metadata: k.Meta, Metadata: k.Meta,
Votes: k.Votes, Votes: k.Votes,
} }
@@ -704,7 +704,7 @@ func tkaStateFromPeer(p tailcfg.NodeView) ipnstate.TKAPeer {
// Control has everything it needs to atomically enable tailnet lock. // Control has everything it needs to atomically enable tailnet lock.
func (b *LocalBackend) TailnetLockInit(keys []tka.Key, disablementValues [][]byte, supportDisablement []byte) error { func (b *LocalBackend) TailnetLockInit(keys []tka.Key, disablementValues [][]byte, supportDisablement []byte) error {
var ourNodeKey key.NodePublic var ourNodeKey key.NodePublic
var nlPriv key.NLPrivate var nlPriv key.TLPrivate
b.mu.Lock() b.mu.Lock()
if p := b.pm.CurrentPrefs(); p.Valid() && p.Persist().Valid() && !p.Persist().PrivateNodeKey().IsZero() { if p := b.pm.CurrentPrefs(); p.Valid() && p.Persist().Valid() && !p.Persist().PrivateNodeKey().IsZero() {
@@ -846,7 +846,7 @@ func (b *LocalBackend) TailnetLockSign(nodeKey key.NodePublic, rotationPublic []
b.mu.Lock() b.mu.Lock()
defer b.mu.Unlock() defer b.mu.Unlock()
var nlPriv key.NLPrivate var nlPriv key.TLPrivate
if p := b.pm.CurrentPrefs(); p.Valid() && p.Persist().Valid() { if p := b.pm.CurrentPrefs(); p.Valid() && p.Persist().Valid() {
nlPriv = p.Persist().NetworkLockKey() nlPriv = p.Persist().NetworkLockKey()
} }
@@ -913,7 +913,7 @@ func (b *LocalBackend) TailnetLockModify(addKeys, removeKeys []tka.Key) (err err
return errors.New("no node-key: is tailscale logged in?") return errors.New("no node-key: is tailscale logged in?")
} }
var nlPriv key.NLPrivate var nlPriv key.TLPrivate
if p := b.pm.CurrentPrefs(); p.Valid() && p.Persist().Valid() { if p := b.pm.CurrentPrefs(); p.Valid() && p.Persist().Valid() {
nlPriv = p.Persist().NetworkLockKey() nlPriv = p.Persist().NetworkLockKey()
} }
@@ -1132,7 +1132,7 @@ func (b *LocalBackend) TailnetLockGenerateRecoveryAUM(removeKeys []tkatype.KeyID
if b.tka == nil { if b.tka == nil {
return nil, errTailnetLockNotActive return nil, errTailnetLockNotActive
} }
var nlPriv key.NLPrivate var nlPriv key.TLPrivate
if p := b.pm.CurrentPrefs(); p.Valid() && p.Persist().Valid() { if p := b.pm.CurrentPrefs(); p.Valid() && p.Persist().Valid() {
nlPriv = p.Persist().NetworkLockKey() nlPriv = p.Persist().NetworkLockKey()
} }
@@ -1170,7 +1170,7 @@ func (b *LocalBackend) TailnetLockCosignRecoveryAUM(aum *tka.AUM) (*tka.AUM, err
if b.tka == nil { if b.tka == nil {
return nil, errTailnetLockNotActive return nil, errTailnetLockNotActive
} }
var nlPriv key.NLPrivate var nlPriv key.TLPrivate
if p := b.pm.CurrentPrefs(); p.Valid() && p.Persist().Valid() { if p := b.pm.CurrentPrefs(); p.Valid() && p.Persist().Valid() {
nlPriv = p.Persist().NetworkLockKey() nlPriv = p.Persist().NetworkLockKey()
} }
@@ -1231,7 +1231,7 @@ var tkaSuffixEncoder = base64.RawStdEncoding
// The provided trusted tailnet-lock key is used to sign // The provided trusted tailnet-lock key is used to sign
// a SigCredential structure, which is encoded along with the // a SigCredential structure, which is encoded along with the
// private key and appended to the pre-auth key. // private key and appended to the pre-auth key.
func (b *LocalBackend) TailnetLockWrapPreauthKey(preauthKey string, tkaKey key.NLPrivate) (string, error) { func (b *LocalBackend) TailnetLockWrapPreauthKey(preauthKey string, tkaKey key.TLPrivate) (string, error) {
b.mu.Lock() b.mu.Lock()
defer b.mu.Unlock() defer b.mu.Unlock()
if b.tka == nil { if b.tka == nil {
@@ -1258,7 +1258,7 @@ func (b *LocalBackend) TailnetLockWrapPreauthKey(preauthKey string, tkaKey key.N
} }
// Deprecated: use [LocalBackend.TailnetLockWrapPreauthKey] instead. // Deprecated: use [LocalBackend.TailnetLockWrapPreauthKey] instead.
func (b *LocalBackend) NetworkLockWrapPreauthKey(preauthKey string, tkaKey key.NLPrivate) (string, error) { func (b *LocalBackend) NetworkLockWrapPreauthKey(preauthKey string, tkaKey key.TLPrivate) (string, error) {
return b.TailnetLockWrapPreauthKey(preauthKey, tkaKey) return b.TailnetLockWrapPreauthKey(preauthKey, tkaKey)
} }
@@ -1279,7 +1279,7 @@ func (b *LocalBackend) NetworkLockVerifySigningDeeplink(url string) tka.Deeplink
return b.TailnetLockVerifySigningDeeplink(url) return b.TailnetLockVerifySigningDeeplink(url)
} }
func signNodeKey(nodeInfo tailcfg.TKASignInfo, signer key.NLPrivate) (*tka.NodeKeySignature, error) { func signNodeKey(nodeInfo tailcfg.TKASignInfo, signer key.TLPrivate) (*tka.NodeKeySignature, error) {
p, err := nodeInfo.NodePublic.MarshalBinary() p, err := nodeInfo.NodePublic.MarshalBinary()
if err != nil { if err != nil {
return nil, err return nil, err
+18 -18
View File
@@ -105,7 +105,7 @@ func newLocalBackendForTKA(t *testing.T, varRoot string, client *http.Client, pm
} }
} }
func setupProfileManager(t *testing.T, nodePriv key.NodePrivate, nlPriv key.NLPrivate) *profileManager { func setupProfileManager(t *testing.T, nodePriv key.NodePrivate, nlPriv key.TLPrivate) *profileManager {
t.Helper() t.Helper()
pm := must.Get(newProfileManager(new(mem.Store), t.Logf, health.NewTracker(eventbustest.NewBus(t)))) pm := must.Get(newProfileManager(new(mem.Store), t.Logf, health.NewTracker(eventbustest.NewBus(t))))
must.Do(pm.SetPrefs((&ipn.Prefs{ must.Do(pm.SetPrefs((&ipn.Prefs{
@@ -134,7 +134,7 @@ func TestTKAEnablementFlow(t *testing.T) {
// Make a fake TKA authority, getting a usable genesis AUM which // Make a fake TKA authority, getting a usable genesis AUM which
// our mock server can communicate. // our mock server can communicate.
nlPriv := key.NewNLPrivate() nlPriv := key.NewTLPrivate()
key := tka.Key{Kind: tka.Key25519, Public: nlPriv.Public().Verifier(), Votes: 2} key := tka.Key{Kind: tka.Key25519, Public: nlPriv.Public().Verifier(), Votes: 2}
state := tka.CreateStateForTest(key) state := tka.CreateStateForTest(key)
chonk := tka.ChonkMem() chonk := tka.ChonkMem()
@@ -215,7 +215,7 @@ func TestTKADisablementFlow(t *testing.T) {
// Make a fake TKA authority, to seed local state. // Make a fake TKA authority, to seed local state.
disablementSecret := bytes.Repeat([]byte{0xa5}, 32) disablementSecret := bytes.Repeat([]byte{0xa5}, 32)
nlPriv := key.NewNLPrivate() nlPriv := key.NewTLPrivate()
key := tka.Key{Kind: tka.Key25519, Public: nlPriv.Public().Verifier(), Votes: 2} key := tka.Key{Kind: tka.Key25519, Public: nlPriv.Public().Verifier(), Votes: 2}
pm := setupProfileManager(t, nodePriv, nlPriv) pm := setupProfileManager(t, nodePriv, nlPriv)
@@ -299,7 +299,7 @@ func TestTKADisablementFlow(t *testing.T) {
} }
func TestTKASync(t *testing.T) { func TestTKASync(t *testing.T) {
someKeyPriv := key.NewNLPrivate() someKeyPriv := key.NewTLPrivate()
someKey := tka.Key{Kind: tka.Key25519, Public: someKeyPriv.Public().Verifier(), Votes: 1} someKey := tka.Key{Kind: tka.Key25519, Public: someKeyPriv.Public().Verifier(), Votes: 1}
type tkaSyncScenario struct { type tkaSyncScenario struct {
@@ -374,7 +374,7 @@ func TestTKASync(t *testing.T) {
for _, tc := range tcs { for _, tc := range tcs {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
nodePriv := key.NewNode() nodePriv := key.NewNode()
nlPriv := key.NewNLPrivate() nlPriv := key.NewTLPrivate()
pm := setupProfileManager(t, nodePriv, nlPriv) pm := setupProfileManager(t, nodePriv, nlPriv)
// Setup the tka authority on the control plane. // Setup the tka authority on the control plane.
@@ -450,11 +450,11 @@ func TestTKASync(t *testing.T) {
// Whenever we run a TKA sync and get new state from control, we compact the // Whenever we run a TKA sync and get new state from control, we compact the
// local state. // local state.
func TestTKASyncTriggersCompact(t *testing.T) { func TestTKASyncTriggersCompact(t *testing.T) {
someKeyPriv := key.NewNLPrivate() someKeyPriv := key.NewTLPrivate()
someKey := tka.Key{Kind: tka.Key25519, Public: someKeyPriv.Public().Verifier(), Votes: 1} someKey := tka.Key{Kind: tka.Key25519, Public: someKeyPriv.Public().Verifier(), Votes: 1}
nodePriv := key.NewNode() nodePriv := key.NewNode()
nlPriv := key.NewNLPrivate() nlPriv := key.NewTLPrivate()
pm := setupProfileManager(t, nodePriv, nlPriv) pm := setupProfileManager(t, nodePriv, nlPriv)
// Create a clock, and roll it back by 30 days. // Create a clock, and roll it back by 30 days.
@@ -583,7 +583,7 @@ func TestTKASyncTriggersCompact(t *testing.T) {
} }
func TestTKAFilterNetmap(t *testing.T) { func TestTKAFilterNetmap(t *testing.T) {
nlPriv := key.NewNLPrivate() nlPriv := key.NewTLPrivate()
nlKey := tka.Key{Kind: tka.Key25519, Public: nlPriv.Public().Verifier(), Votes: 2} nlKey := tka.Key{Kind: tka.Key25519, Public: nlPriv.Public().Verifier(), Votes: 2}
state := tka.CreateStateForTest(nlKey) state := tka.CreateStateForTest(nlKey)
storage := tka.ChonkMem() storage := tka.ChonkMem()
@@ -610,13 +610,13 @@ func TestTKAFilterNetmap(t *testing.T) {
n4Sig.Signature[3] = 42 // mess up the signature n4Sig.Signature[3] = 42 // mess up the signature
n4Sig.Signature[4] = 42 // mess up the signature n4Sig.Signature[4] = 42 // mess up the signature
n5nl := key.NewNLPrivate() n5nl := key.NewTLPrivate()
n5InitialSig, err := signNodeKey(tailcfg.TKASignInfo{NodePublic: n5.Public(), RotationPubkey: n5nl.Public().Verifier()}, nlPriv) n5InitialSig, err := signNodeKey(tailcfg.TKASignInfo{NodePublic: n5.Public(), RotationPubkey: n5nl.Public().Verifier()}, nlPriv)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
resign := func(nl key.NLPrivate, currentSig tkatype.MarshaledSignature) (key.NodePrivate, tkatype.MarshaledSignature) { resign := func(nl key.TLPrivate, currentSig tkatype.MarshaledSignature) (key.NodePrivate, tkatype.MarshaledSignature) {
nk := key.NewNode() nk := key.NewNode()
sig, err := tka.ResignNKS(nl, nk.Public(), currentSig) sig, err := tka.ResignNKS(nl, nk.Public(), currentSig)
if err != nil { if err != nil {
@@ -736,7 +736,7 @@ func TestTKADisable(t *testing.T) {
// Make a fake TKA authority, to seed local state. // Make a fake TKA authority, to seed local state.
disablementSecret := bytes.Repeat([]byte{0xa5}, 32) disablementSecret := bytes.Repeat([]byte{0xa5}, 32)
nlPriv := key.NewNLPrivate() nlPriv := key.NewTLPrivate()
key := tka.Key{Kind: tka.Key25519, Public: nlPriv.Public().Verifier(), Votes: 2} key := tka.Key{Kind: tka.Key25519, Public: nlPriv.Public().Verifier(), Votes: 2}
pm := setupProfileManager(t, nodePriv, nlPriv) pm := setupProfileManager(t, nodePriv, nlPriv)
@@ -802,7 +802,7 @@ func TestTKADisable(t *testing.T) {
func TestTKASign(t *testing.T) { func TestTKASign(t *testing.T) {
nodePriv := key.NewNode() nodePriv := key.NewNode()
toSign := key.NewNode() toSign := key.NewNode()
nlPriv := key.NewNLPrivate() nlPriv := key.NewTLPrivate()
pm := setupProfileManager(t, nodePriv, nlPriv) pm := setupProfileManager(t, nodePriv, nlPriv)
@@ -843,7 +843,7 @@ func TestTKAForceDisable(t *testing.T) {
nodePriv := key.NewNode() nodePriv := key.NewNode()
// Make a fake TKA authority, to seed local state. // Make a fake TKA authority, to seed local state.
nlPriv := key.NewNLPrivate() nlPriv := key.NewTLPrivate()
key := tka.Key{Kind: tka.Key25519, Public: nlPriv.Public().Verifier(), Votes: 2} key := tka.Key{Kind: tka.Key25519, Public: nlPriv.Public().Verifier(), Votes: 2}
state := tka.CreateStateForTest(key) state := tka.CreateStateForTest(key)
@@ -920,7 +920,7 @@ func TestTKAForceDisable(t *testing.T) {
func TestTKAAffectedSigs(t *testing.T) { func TestTKAAffectedSigs(t *testing.T) {
nodePriv := key.NewNode() nodePriv := key.NewNode()
// toSign := key.NewNode() // toSign := key.NewNode()
nlPriv := key.NewNLPrivate() nlPriv := key.NewTLPrivate()
pm := setupProfileManager(t, nodePriv, nlPriv) pm := setupProfileManager(t, nodePriv, nlPriv)
@@ -934,7 +934,7 @@ func TestTKAAffectedSigs(t *testing.T) {
t.Fatalf("tka.Create() failed: %v", err) t.Fatalf("tka.Create() failed: %v", err)
} }
untrustedKey := key.NewNLPrivate() untrustedKey := key.NewTLPrivate()
tcs := []struct { tcs := []struct {
name string name string
makeSig func() *tka.NodeKeySignature makeSig func() *tka.NodeKeySignature
@@ -1024,9 +1024,9 @@ func TestTKAAffectedSigs(t *testing.T) {
func TestTKARecoverCompromisedKeyFlow(t *testing.T) { func TestTKARecoverCompromisedKeyFlow(t *testing.T) {
nodePriv := key.NewNode() nodePriv := key.NewNode()
nlPriv := key.NewNLPrivate() nlPriv := key.NewTLPrivate()
cosignPriv := key.NewNLPrivate() cosignPriv := key.NewTLPrivate()
compromisedPriv := key.NewNLPrivate() compromisedPriv := key.NewTLPrivate()
pm := setupProfileManager(t, nodePriv, nlPriv) pm := setupProfileManager(t, nodePriv, nlPriv)
+2 -2
View File
@@ -93,7 +93,7 @@ type Status struct {
// TKAKey describes a key trusted by tailnet lock. // TKAKey describes a key trusted by tailnet lock.
type TKAKey struct { type TKAKey struct {
Kind string Kind string
Key key.NLPublic Key key.TLPublic
Metadata map[string]string Metadata map[string]string
Votes uint Votes uint
} }
@@ -121,7 +121,7 @@ type TailnetLockStatus struct {
// PublicKey describes the node's tailnet-lock public key. // PublicKey describes the node's tailnet-lock public key.
// It may be zero if the node has not logged in. // It may be zero if the node has not logged in.
PublicKey key.NLPublic PublicKey key.TLPublic
// NodeKey describes the node's current node-key. This field is not // NodeKey describes the node's current node-key. This field is not
// populated if the node is not operating (i.e. waiting for a login). // populated if the node is not operating (i.e. waiting for a login).
+2 -2
View File
@@ -159,14 +159,14 @@ func (h *Handler) serveTKAWrapPreauthKey(w http.ResponseWriter, r *http.Request)
type wrapRequest struct { type wrapRequest struct {
TSKey string TSKey string
TKAKey string // key.NLPrivate.MarshalText TKAKey string // key.TLPrivate.MarshalText
} }
var req wrapRequest var req wrapRequest
if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, 12*1024)).Decode(&req); err != nil { if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, 12*1024)).Decode(&req); err != nil {
http.Error(w, "invalid JSON body", http.StatusBadRequest) http.Error(w, "invalid JSON body", http.StatusBadRequest)
return return
} }
var priv key.NLPrivate var priv key.TLPrivate
if err := priv.UnmarshalText([]byte(req.TKAKey)); err != nil { if err := priv.UnmarshalText([]byte(req.TKAKey)); err != nil {
http.Error(w, "invalid JSON body", http.StatusBadRequest) http.Error(w, "invalid JSON body", http.StatusBadRequest)
return return
+1 -1
View File
@@ -1327,7 +1327,7 @@ type RegisterRequest struct {
NodeKey key.NodePublic NodeKey key.NodePublic
OldNodeKey key.NodePublic OldNodeKey key.NodePublic
NLKey key.NLPublic NLKey key.TLPublic
Auth *RegisterResponseAuth `json:",omitempty"` Auth *RegisterResponseAuth `json:",omitempty"`
// Expiry optionally specifies the requested key expiry. // Expiry optionally specifies the requested key expiry.
// The server policy may override. // The server policy may override.
+1 -1
View File
@@ -381,7 +381,7 @@ var _RegisterRequestCloneNeedsRegeneration = RegisterRequest(struct {
Version CapabilityVersion Version CapabilityVersion
NodeKey key.NodePublic NodeKey key.NodePublic
OldNodeKey key.NodePublic OldNodeKey key.NodePublic
NLKey key.NLPublic NLKey key.TLPublic
Auth *RegisterResponseAuth Auth *RegisterResponseAuth
Expiry time.Time Expiry time.Time
Followup string Followup string
+2 -2
View File
@@ -1351,7 +1351,7 @@ func (v *RegisterRequestView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
func (v RegisterRequestView) Version() CapabilityVersion { return v.ж.Version } func (v RegisterRequestView) Version() CapabilityVersion { return v.ж.Version }
func (v RegisterRequestView) NodeKey() key.NodePublic { return v.ж.NodeKey } func (v RegisterRequestView) NodeKey() key.NodePublic { return v.ж.NodeKey }
func (v RegisterRequestView) OldNodeKey() key.NodePublic { return v.ж.OldNodeKey } func (v RegisterRequestView) OldNodeKey() key.NodePublic { return v.ж.OldNodeKey }
func (v RegisterRequestView) NLKey() key.NLPublic { return v.ж.NLKey } func (v RegisterRequestView) NLKey() key.TLPublic { return v.ж.NLKey }
func (v RegisterRequestView) Auth() RegisterResponseAuthView { return v.ж.Auth.View() } func (v RegisterRequestView) Auth() RegisterResponseAuthView { return v.ж.Auth.View() }
// Expiry optionally specifies the requested key expiry. // Expiry optionally specifies the requested key expiry.
@@ -1414,7 +1414,7 @@ var _RegisterRequestViewNeedsRegeneration = RegisterRequest(struct {
Version CapabilityVersion Version CapabilityVersion
NodeKey key.NodePublic NodeKey key.NodePublic
OldNodeKey key.NodePublic OldNodeKey key.NodePublic
NLKey key.NLPublic NLKey key.TLPublic
Auth *RegisterResponseAuth Auth *RegisterResponseAuth
Expiry time.Time Expiry time.Time
Followup string Followup string
+1 -1
View File
@@ -150,7 +150,7 @@ func DecodeWrappedAuthkey(wrappedAuthKey string, logf logger.Logf) (authKey stri
return wrappedAuthKey, false, nil, nil return wrappedAuthKey, false, nil, nil
} }
func ResignNKS(priv key.NLPrivate, nodeKey key.NodePublic, oldNKS tkatype.MarshaledSignature) (tkatype.MarshaledSignature, error) { func ResignNKS(priv key.TLPrivate, nodeKey key.NodePublic, oldNKS tkatype.MarshaledSignature) (tkatype.MarshaledSignature, error) {
return nil, nil return nil, nil
} }
+3 -3
View File
@@ -65,11 +65,11 @@ func TestVerify25519(t *testing.T) {
} }
} }
func TestNLPrivate(t *testing.T) { func TestTLPrivate(t *testing.T) {
p := key.NewNLPrivate() p := key.NewTLPrivate()
pub := p.Public() pub := p.Public()
// Test that key.NLPrivate implements Signer by making a new // Test that key.TLPrivate implements Signer by making a new
// authority. // authority.
k := Key{Kind: Key25519, Public: pub.Verifier(), Votes: 1} k := Key{Kind: Key25519, Public: pub.Verifier(), Votes: 1}
state := CreateStateForTest(k) state := CreateStateForTest(k)
+4 -4
View File
@@ -122,11 +122,11 @@ func (s NodeKeySignature) String() string {
b.WriteString(indent + "Pubkey: " + pubKey + "\n") b.WriteString(indent + "Pubkey: " + pubKey + "\n")
} }
if len(sig.KeyID) > 0 { if len(sig.KeyID) > 0 {
keyID := key.NLPublicFromEd25519Unsafe(sig.KeyID).CLIString() keyID := key.TLPublicFromEd25519Unsafe(sig.KeyID).CLIString()
b.WriteString(indent + "KeyID: " + keyID + "\n") b.WriteString(indent + "KeyID: " + keyID + "\n")
} }
if len(sig.WrappingPubkey) > 0 { if len(sig.WrappingPubkey) > 0 {
pubKey := key.NLPublicFromEd25519Unsafe(sig.WrappingPubkey).CLIString() pubKey := key.TLPublicFromEd25519Unsafe(sig.WrappingPubkey).CLIString()
b.WriteString(indent + "WrappingPubkey: " + pubKey + "\n") b.WriteString(indent + "WrappingPubkey: " + pubKey + "\n")
} }
if sig.Nested != nil { if sig.Nested != nil {
@@ -357,7 +357,7 @@ func (s *NodeKeySignature) rotationDetails() (*RotationDetails, error) {
// The signature itself is a SigRotation signature, which embeds the old signature // The signature itself is a SigRotation signature, which embeds the old signature
// and certifies the new node-key as a replacement for the old by signing the new // and certifies the new node-key as a replacement for the old by signing the new
// signature with RotationPubkey (which is the node's own tailnet-lock key). // signature with RotationPubkey (which is the node's own tailnet-lock key).
func ResignNKS(priv key.NLPrivate, nodeKey key.NodePublic, oldNKS tkatype.MarshaledSignature) (tkatype.MarshaledSignature, error) { func ResignNKS(priv key.TLPrivate, nodeKey key.NodePublic, oldNKS tkatype.MarshaledSignature) (tkatype.MarshaledSignature, error) {
var oldSig NodeKeySignature var oldSig NodeKeySignature
if err := oldSig.Unserialize(oldNKS); err != nil { if err := oldSig.Unserialize(oldNKS); err != nil {
return nil, fmt.Errorf("decoding NKS: %w", err) return nil, fmt.Errorf("decoding NKS: %w", err)
@@ -393,7 +393,7 @@ func ResignNKS(priv key.NLPrivate, nodeKey key.NodePublic, oldNKS tkatype.Marsha
// maybeTrimRotationSignatureChain truncates rotation signature chain to ensure // maybeTrimRotationSignatureChain truncates rotation signature chain to ensure
// it contains no more than 15 node keys. // it contains no more than 15 node keys.
func maybeTrimRotationSignatureChain(sig NodeKeySignature, priv key.NLPrivate) (NodeKeySignature, error) { func maybeTrimRotationSignatureChain(sig NodeKeySignature, priv key.TLPrivate) (NodeKeySignature, error) {
if sig.SigKind != SigRotation { if sig.SigKind != SigRotation {
return sig, nil return sig, nil
} }
+1 -1
View File
@@ -506,7 +506,7 @@ func TestResignNKS(t *testing.T) {
authKey := Key{Kind: Key25519, Public: authPub, Votes: 2} authKey := Key{Kind: Key25519, Public: authPub, Votes: 2}
// Node's own tailnet lock key used to sign rotation signatures. // Node's own tailnet lock key used to sign rotation signatures.
tlPriv := key.NewNLPrivate() tlPriv := key.NewTLPrivate()
// The original (oldest) node key, signed by a signing node. // The original (oldest) node key, signed by a signing node.
origNode := key.NewNode() origNode := key.NewNode()
+3 -3
View File
@@ -219,7 +219,7 @@ func BenchmarkTailchonkFSOpenLongChain(b *testing.B) {
// size does not depend on checkpoint cadence. // size does not depend on checkpoint cadence.
const targetAUMs = maxScanIterations const targetAUMs = maxScanIterations
signer := key.NewNLPrivate() signer := key.NewTLPrivate()
trustedKey := Key{Kind: Key25519, Public: signer.Public().Verifier(), Votes: 1} trustedKey := Key{Kind: Key25519, Public: signer.Public().Verifier(), Votes: 1}
storage := ChonkMem() storage := ChonkMem()
authority, _, err := Create(storage, CreateStateForTest(trustedKey), signer) authority, _, err := Create(storage, CreateStateForTest(trustedKey), signer)
@@ -694,9 +694,9 @@ func TestCompact(t *testing.T) {
} }
func TestCompactLongButYoung(t *testing.T) { func TestCompactLongButYoung(t *testing.T) {
ourPriv := key.NewNLPrivate() ourPriv := key.NewTLPrivate()
ourKey := Key{Kind: Key25519, Public: ourPriv.Public().Verifier(), Votes: 1} ourKey := Key{Kind: Key25519, Public: ourPriv.Public().Verifier(), Votes: 1}
someOtherKey := Key{Kind: Key25519, Public: key.NewNLPrivate().Public().Verifier(), Votes: 1} someOtherKey := Key{Kind: Key25519, Public: key.NewTLPrivate().Public().Verifier(), Votes: 1}
state := CreateStateForTest(ourKey, someOtherKey) state := CreateStateForTest(ourKey, someOtherKey)
storage := ChonkMem() storage := ChonkMem()
+3 -3
View File
@@ -507,10 +507,10 @@ func TestAuthorityInformLinear(t *testing.T) {
} }
func TestInteropWithNLKey(t *testing.T) { func TestInteropWithNLKey(t *testing.T) {
priv1 := key.NewNLPrivate() priv1 := key.NewTLPrivate()
pub1 := priv1.Public() pub1 := priv1.Public()
pub2 := key.NewNLPrivate().Public() pub2 := key.NewTLPrivate().Public()
pub3 := key.NewNLPrivate().Public() pub3 := key.NewTLPrivate().Public()
state := CreateStateForTest( state := CreateStateForTest(
Key{Kind: Key25519, Votes: 1, Public: pub1.KeyID()}, Key{Kind: Key25519, Votes: 1, Public: pub1.KeyID()},
+6 -6
View File
@@ -123,7 +123,7 @@ func setupTailnetLockedServer(t *testing.T, ctx context.Context, extraTrustedKey
// (unexported) signNodeKey in ipn/ipnlocal/tailnet-lock.go, replicated // (unexported) signNodeKey in ipn/ipnlocal/tailnet-lock.go, replicated
// here so tsnet tests can mint valid signatures without cyclically // here so tsnet tests can mint valid signatures without cyclically
// depending on ipnlocal internals. // depending on ipnlocal internals.
func signNodeKeyForTest(t *testing.T, nodeKey key.NodePublic, nlPriv key.NLPrivate) tkatype.MarshaledSignature { func signNodeKeyForTest(t *testing.T, nodeKey key.NodePublic, nlPriv key.TLPrivate) tkatype.MarshaledSignature {
t.Helper() t.Helper()
pub, err := nodeKey.MarshalBinary() pub, err := nodeKey.MarshalBinary()
if err != nil { if err != nil {
@@ -151,7 +151,7 @@ func signNodeKeyForTest(t *testing.T, nodeKey key.NodePublic, nlPriv key.NLPriva
// [LocalBackend.UpdateNetmapDelta]. That makes the absence-of-fixture // [LocalBackend.UpdateNetmapDelta]. That makes the absence-of-fixture
// assertion race-free without having to wait a fixed timeout for // assertion race-free without having to wait a fixed timeout for
// "nothing to happen". // "nothing to happen".
func signedMarkerPeer(t *testing.T, nlPriv key.NLPrivate) *tailcfg.Node { func signedMarkerPeer(t *testing.T, nlPriv key.TLPrivate) *tailcfg.Node {
t.Helper() t.Helper()
markerKey := key.NewNode().Public() markerKey := key.NewNode().Public()
markerAddr := netip.MustParsePrefix("100.64.99.250/32") markerAddr := netip.MustParsePrefix("100.64.99.250/32")
@@ -178,7 +178,7 @@ func signedMarkerPeer(t *testing.T, nlPriv key.NLPrivate) *tailcfg.Node {
// [LocalBackend.NetMapWithPeers]. markerNL must be a private NL key // [LocalBackend.NetMapWithPeers]. markerNL must be a private NL key
// whose public verifier is trusted by the tailnet-lock state on s // whose public verifier is trusted by the tailnet-lock state on s
// (e.g. an extra key passed to [setupTailnetLockedServer]). // (e.g. an extra key passed to [setupTailnetLockedServer]).
func injectPeersChangedAndAssertFiltered(t *testing.T, ctx context.Context, s *Server, control *testcontrol.Server, dst key.NodePublic, badPeer *tailcfg.Node, markerNL key.NLPrivate) { func injectPeersChangedAndAssertFiltered(t *testing.T, ctx context.Context, s *Server, control *testcontrol.Server, dst key.NodePublic, badPeer *tailcfg.Node, markerNL key.TLPrivate) {
t.Helper() t.Helper()
marker := signedMarkerPeer(t, markerNL) marker := signedMarkerPeer(t, markerNL)
if !control.AddRawMapResponse(dst, &tailcfg.MapResponse{ if !control.AddRawMapResponse(dst, &tailcfg.MapResponse{
@@ -243,7 +243,7 @@ func TestTailnetLockFiltersUnsignedDeltaPeer(t *testing.T) {
// Trust an extra NL key the test holds so it can mint signed marker // Trust an extra NL key the test holds so it can mint signed marker
// peers for delta-sync below. // peers for delta-sync below.
markerNL := key.NewNLPrivate() markerNL := key.NewTLPrivate()
s1, control, s1Key := setupTailnetLockedServer(t, ctx, tka.Key{ s1, control, s1Key := setupTailnetLockedServer(t, ctx, tka.Key{
Kind: tka.Key25519, Kind: tka.Key25519,
Public: markerNL.Public().Verifier(), Public: markerNL.Public().Verifier(),
@@ -297,7 +297,7 @@ func TestTailnetLockFiltersUnsignedDeltaPeerReplacement(t *testing.T) {
// Trust an extra NL key the test holds, so the test can mint valid // Trust an extra NL key the test holds, so the test can mint valid
// signatures for the fake peer without colluding with the node's // signatures for the fake peer without colluding with the node's
// own NL private key (which lives only in s1's prefs). // own NL private key (which lives only in s1's prefs).
testNL := key.NewNLPrivate() testNL := key.NewTLPrivate()
s1, control, s1Key := setupTailnetLockedServer(t, ctx, tka.Key{ s1, control, s1Key := setupTailnetLockedServer(t, ctx, tka.Key{
Kind: tka.Key25519, Kind: tka.Key25519,
Public: testNL.Public().Verifier(), Public: testNL.Public().Verifier(),
@@ -372,7 +372,7 @@ func TestTailnetLockFiltersDeltaPeerWithInvalidSignature(t *testing.T) {
ctx, cancel := context.WithTimeout(t.Context(), 120*time.Second) ctx, cancel := context.WithTimeout(t.Context(), 120*time.Second)
defer cancel() defer cancel()
testNL := key.NewNLPrivate() testNL := key.NewTLPrivate()
s1, control, s1Key := setupTailnetLockedServer(t, ctx, tka.Key{ s1, control, s1Key := setupTailnetLockedServer(t, ctx, tka.Key{
Kind: tka.Key25519, Kind: tka.Key25519,
Public: testNL.Public().Verifier(), Public: testNL.Public().Verifier(),
+7 -2
View File
@@ -1307,9 +1307,9 @@ func (n *TestNode) PublicKey() string {
return st.Self.PublicKey return st.Self.PublicKey
} }
// NLPublicKey returns the hex-encoded tailnet lock public key of // TLPublicKey returns the hex-encoded tailnet lock public key of
// this node, e.g. `tlpub:123456abc` // this node, e.g. `tlpub:123456abc`
func (n *TestNode) NLPublicKey() string { func (n *TestNode) TLPublicKey() string {
tb := n.env.t tb := n.env.t
tb.Helper() tb.Helper()
cmd := n.Tailscale("lock", "status", "--json") cmd := n.Tailscale("lock", "status", "--json")
@@ -1326,6 +1326,11 @@ func (n *TestNode) NLPublicKey() string {
return st.PublicKey return st.PublicKey
} }
// Deprecated: use [TestNode.TLPublicKey] instead.
func (n *TestNode) NLPublicKey() string {
return n.TLPublicKey()
}
// trafficTrap is an HTTP proxy handler to note whether any // trafficTrap is an HTTP proxy handler to note whether any
// HTTP traffic tries to leave localhost from tailscaled. We don't // HTTP traffic tries to leave localhost from tailscaled. We don't
// expect any, so any request triggers a failure. // expect any, so any request triggers a failure.
+1 -1
View File
@@ -2539,7 +2539,7 @@ func TestTailnetLock(t *testing.T) {
initCmd := signing1.Tailscale("lock", "init", initCmd := signing1.Tailscale("lock", "init",
"--gen-disablements", "10", "--gen-disablements", "10",
"--confirm", "--confirm",
signing1.NLPublicKey(), signing2.NLPublicKey(), signing1.TLPublicKey(), signing2.TLPublicKey(),
) )
out, err := initCmd.CombinedOutput() out, err := initCmd.CombinedOutput()
if err != nil { if err != nil {
+67 -45
View File
@@ -13,37 +13,46 @@ import (
) )
const ( const (
// nlPrivateHexPrefix is the prefix used to identify a // tlPrivateHexPrefix is the prefix used to identify a
// hex-encoded tailnet-lock key. // hex-encoded tailnet-lock key.
nlPrivateHexPrefix = "nlpriv:" //
// "nl" is a reference to "Network Lock", the pre-release name for
// Tailnet Lock.
tlPrivateHexPrefix = "nlpriv:"
// nlPublicHexPrefix is the prefix used to identify the public // tlPublicHexPrefix is the prefix used to identify the public
// side of a hex-encoded tailnet-lock key. // side of a hex-encoded tailnet-lock key.
nlPublicHexPrefix = "nlpub:" //
// "nl" is a reference to "Network Lock", the pre-release name for
// Tailnet Lock.
tlPublicHexPrefix = "nlpub:"
// nlPublicHexPrefixCLI is the prefix used for tailnet-lock keys // tlPublicHexPrefixCLI is the prefix used for tailnet-lock keys
// when shown on the CLI. // when shown on the CLI.
// It's not practical for us to change the prefix everywhere due to // It's not practical for us to change the prefix everywhere due to
// compatibility with existing clients, but we can support both prefixes // compatibility with existing clients, but we can support both prefixes
// as well as use the CLI form when presenting to the user. // as well as use the CLI form when presenting to the user.
nlPublicHexPrefixCLI = "tlpub:" tlPublicHexPrefixCLI = "tlpub:"
) )
// NLPrivate is a node-managed tailnet-lock key, used for signing // TLPrivate is a node-managed tailnet-lock key, used for signing
// node-key signatures and authority update messages. // node-key signatures and authority update messages.
type NLPrivate struct { type TLPrivate struct {
_ structs.Incomparable // because == isn't constant-time _ structs.Incomparable // because == isn't constant-time
k [ed25519.PrivateKeySize]byte k [ed25519.PrivateKeySize]byte
} }
// Deprecated: use [TLPrivate] instead.
type NLPrivate = TLPrivate
// IsZero reports whether k is the zero value. // IsZero reports whether k is the zero value.
func (k NLPrivate) IsZero() bool { func (k TLPrivate) IsZero() bool {
empty := NLPrivate{} empty := TLPrivate{}
return subtle.ConstantTimeCompare(k.k[:], empty.k[:]) == 1 return subtle.ConstantTimeCompare(k.k[:], empty.k[:]) == 1
} }
// NewNLPrivate creates and returns a new tailnet-lock key. // NewTLPrivate creates and returns a new tailnet-lock key.
func NewNLPrivate() NLPrivate { func NewTLPrivate() TLPrivate {
// ed25519.GenerateKey 'clamps' the key, not that it // ed25519.GenerateKey 'clamps' the key, not that it
// matters given we don't do Diffie-Hellman. // matters given we don't do Diffie-Hellman.
_, priv, err := ed25519.GenerateKey(nil) // nil == crypto/rand _, priv, err := ed25519.GenerateKey(nil) // nil == crypto/rand
@@ -51,40 +60,45 @@ func NewNLPrivate() NLPrivate {
panic(err) panic(err)
} }
var out NLPrivate var out TLPrivate
copy(out.k[:], priv) copy(out.k[:], priv)
return out return out
} }
// Deprecated: use [NewTLPrivate] instead.
func NewNLPrivate() TLPrivate {
return NewTLPrivate()
}
// MarshalText implements encoding.TextUnmarshaler. // MarshalText implements encoding.TextUnmarshaler.
func (k *NLPrivate) UnmarshalText(b []byte) error { func (k *TLPrivate) UnmarshalText(b []byte) error {
return parseHex(k.k[:], mem.B(b), mem.S(nlPrivateHexPrefix)) return parseHex(k.k[:], mem.B(b), mem.S(tlPrivateHexPrefix))
} }
// AppendText implements encoding.TextAppender. // AppendText implements encoding.TextAppender.
func (k NLPrivate) AppendText(b []byte) ([]byte, error) { func (k TLPrivate) AppendText(b []byte) ([]byte, error) {
return appendHexKey(b, nlPrivateHexPrefix, k.k[:]), nil return appendHexKey(b, tlPrivateHexPrefix, k.k[:]), nil
} }
// MarshalText implements encoding.TextMarshaler. // MarshalText implements encoding.TextMarshaler.
func (k NLPrivate) MarshalText() ([]byte, error) { func (k TLPrivate) MarshalText() ([]byte, error) {
return k.AppendText(nil) return k.AppendText(nil)
} }
// Equal reports whether k and other are the same key. // Equal reports whether k and other are the same key.
func (k NLPrivate) Equal(other NLPrivate) bool { func (k TLPrivate) Equal(other TLPrivate) bool {
return subtle.ConstantTimeCompare(k.k[:], other.k[:]) == 1 return subtle.ConstantTimeCompare(k.k[:], other.k[:]) == 1
} }
// Public returns the public component of this key. // Public returns the public component of this key.
func (k NLPrivate) Public() NLPublic { func (k TLPrivate) Public() TLPublic {
var out NLPublic var out TLPublic
copy(out.k[:], ed25519.PrivateKey(k.k[:]).Public().(ed25519.PublicKey)) copy(out.k[:], ed25519.PrivateKey(k.k[:]).Public().(ed25519.PublicKey))
return out return out
} }
// KeyID returns an identifier for this key. // KeyID returns an identifier for this key.
func (k NLPrivate) KeyID() tkatype.KeyID { func (k TLPrivate) KeyID() tkatype.KeyID {
// The correct way to compute this is: // The correct way to compute this is:
// return tka.Key{ // return tka.Key{
// Kind: tka.Key25519, // Kind: tka.Key25519,
@@ -99,7 +113,7 @@ func (k NLPrivate) KeyID() tkatype.KeyID {
} }
// SignAUM implements tka.Signer. // SignAUM implements tka.Signer.
func (k NLPrivate) SignAUM(sigHash tkatype.AUMSigHash) ([]tkatype.Signature, error) { func (k TLPrivate) SignAUM(sigHash tkatype.AUMSigHash) ([]tkatype.Signature, error) {
return []tkatype.Signature{{ return []tkatype.Signature{{
KeyID: k.KeyID(), KeyID: k.KeyID(),
Signature: ed25519.Sign(ed25519.PrivateKey(k.k[:]), sigHash[:]), Signature: ed25519.Sign(ed25519.PrivateKey(k.k[:]), sigHash[:]),
@@ -107,44 +121,52 @@ func (k NLPrivate) SignAUM(sigHash tkatype.AUMSigHash) ([]tkatype.Signature, err
} }
// SignNKS signs the tka.NodeKeySignature identified by sigHash. // SignNKS signs the tka.NodeKeySignature identified by sigHash.
func (k NLPrivate) SignNKS(sigHash tkatype.NKSSigHash) ([]byte, error) { func (k TLPrivate) SignNKS(sigHash tkatype.NKSSigHash) ([]byte, error) {
return ed25519.Sign(ed25519.PrivateKey(k.k[:]), sigHash[:]), nil return ed25519.Sign(ed25519.PrivateKey(k.k[:]), sigHash[:]), nil
} }
// NLPublic is the public portion of a NLPrivate. // TLPublic is the public portion of a [TLPrivate].
type NLPublic struct { type TLPublic struct {
k [ed25519.PublicKeySize]byte k [ed25519.PublicKeySize]byte
} }
// NLPublicFromEd25519Unsafe converts an ed25519 public key into // Deprecated: use [TLPublic] instead.
// a type of NLPublic. type NLPublic = TLPublic
// TLPublicFromEd25519Unsafe converts an ed25519 public key into
// a type of [TLPublic].
// //
// New uses of this function should be avoided, as it's possible to // New uses of this function should be avoided, as it's possible to
// accidentally construct an NLPublic from a non tailnet-lock key. // accidentally construct an TLPublic from a non tailnet-lock key.
func NLPublicFromEd25519Unsafe(public ed25519.PublicKey) NLPublic { func TLPublicFromEd25519Unsafe(public ed25519.PublicKey) TLPublic {
var out NLPublic var out TLPublic
copy(out.k[:], public) copy(out.k[:], public)
return out return out
} }
// Deprecated: use [TLPublicFromEd25519Unsafe] instead.
func NLPublicFromEd25519Unsafe(public ed25519.PublicKey) TLPublic {
return TLPublicFromEd25519Unsafe(public)
}
// UnmarshalText implements encoding.TextUnmarshaler. This function // UnmarshalText implements encoding.TextUnmarshaler. This function
// is able to decode both the CLI form (tlpub:<hex>) & the // is able to decode both the CLI form (tlpub:<hex>) & the
// regular form (nlpub:<hex>). // regular form (nlpub:<hex>).
func (k *NLPublic) UnmarshalText(b []byte) error { func (k *TLPublic) UnmarshalText(b []byte) error {
if mem.HasPrefix(mem.B(b), mem.S(nlPublicHexPrefix)) { if mem.HasPrefix(mem.B(b), mem.S(tlPublicHexPrefix)) {
return parseHex(k.k[:], mem.B(b), mem.S(nlPublicHexPrefix)) return parseHex(k.k[:], mem.B(b), mem.S(tlPublicHexPrefix))
} }
return parseHex(k.k[:], mem.B(b), mem.S(nlPublicHexPrefixCLI)) return parseHex(k.k[:], mem.B(b), mem.S(tlPublicHexPrefixCLI))
} }
// AppendText implements encoding.TextAppender. // AppendText implements encoding.TextAppender.
func (k NLPublic) AppendText(b []byte) ([]byte, error) { func (k TLPublic) AppendText(b []byte) ([]byte, error) {
return appendHexKey(b, nlPublicHexPrefix, k.k[:]), nil return appendHexKey(b, tlPublicHexPrefix, k.k[:]), nil
} }
// MarshalText implements encoding.TextMarshaler, emitting a // MarshalText implements encoding.TextMarshaler, emitting a
// representation of the form nlpub:<hex>. // representation of the form nlpub:<hex>.
func (k NLPublic) MarshalText() ([]byte, error) { func (k TLPublic) MarshalText() ([]byte, error) {
return k.AppendText(nil) return k.AppendText(nil)
} }
@@ -152,27 +174,27 @@ func (k NLPublic) MarshalText() ([]byte, error) {
// with tailnet lock commands, of the form tlpub:<hex> instead of // with tailnet lock commands, of the form tlpub:<hex> instead of
// the nlpub:<hex> form emitted by MarshalText. Both forms can // the nlpub:<hex> form emitted by MarshalText. Both forms can
// be decoded by UnmarshalText. // be decoded by UnmarshalText.
func (k NLPublic) CLIString() string { func (k TLPublic) CLIString() string {
return string(appendHexKey(nil, nlPublicHexPrefixCLI, k.k[:])) return string(appendHexKey(nil, tlPublicHexPrefixCLI, k.k[:]))
} }
// Verifier returns a ed25519.PublicKey that can be used to // Verifier returns a ed25519.PublicKey that can be used to
// verify signatures. // verify signatures.
func (k NLPublic) Verifier() ed25519.PublicKey { func (k TLPublic) Verifier() ed25519.PublicKey {
return ed25519.PublicKey(k.k[:]) return ed25519.PublicKey(k.k[:])
} }
// IsZero reports whether k is the zero value. // IsZero reports whether k is the zero value.
func (k NLPublic) IsZero() bool { func (k TLPublic) IsZero() bool {
return k.Equal(NLPublic{}) return k.Equal(TLPublic{})
} }
// Equal reports whether k and other are the same key. // Equal reports whether k and other are the same key.
func (k NLPublic) Equal(other NLPublic) bool { func (k TLPublic) Equal(other TLPublic) bool {
return subtle.ConstantTimeCompare(k.k[:], other.k[:]) == 1 return subtle.ConstantTimeCompare(k.k[:], other.k[:]) == 1
} }
// KeyID returns a tkatype.KeyID that can be used with a tka.Authority. // KeyID returns a tkatype.KeyID that can be used with a tka.Authority.
func (k NLPublic) KeyID() tkatype.KeyID { func (k TLPublic) KeyID() tkatype.KeyID {
return k.k[:] return k.k[:]
} }
@@ -8,41 +8,41 @@ import (
"testing" "testing"
) )
func TestNLPrivate(t *testing.T) { func TestTLPrivate(t *testing.T) {
p := NewNLPrivate() p := NewTLPrivate()
encoded, err := p.MarshalText() encoded, err := p.MarshalText()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
var decoded NLPrivate var decoded TLPrivate
if err := decoded.UnmarshalText(encoded); err != nil { if err := decoded.UnmarshalText(encoded); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if !bytes.Equal(decoded.k[:], p.k[:]) { if !bytes.Equal(decoded.k[:], p.k[:]) {
t.Error("decoded and generated NLPrivate bytes differ") t.Error("decoded and generated TLPrivate bytes differ")
} }
// Test NLPublic // Test TLPublic
pub := p.Public() pub := p.Public()
encoded, err = pub.MarshalText() encoded, err = pub.MarshalText()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
var decodedPub NLPublic var decodedPub TLPublic
if err := decodedPub.UnmarshalText(encoded); err != nil { if err := decodedPub.UnmarshalText(encoded); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if !bytes.Equal(decodedPub.k[:], pub.k[:]) { if !bytes.Equal(decodedPub.k[:], pub.k[:]) {
t.Error("decoded and generated NLPublic bytes differ") t.Error("decoded and generated TLPublic bytes differ")
} }
// Test decoding with CLI prefix: 'nlpub:' => 'tlpub:' // Test decoding with CLI prefix: 'nlpub:' => 'tlpub:'
decodedPub = NLPublic{} decodedPub = TLPublic{}
if err := decodedPub.UnmarshalText([]byte(pub.CLIString())); err != nil { if err := decodedPub.UnmarshalText([]byte(pub.CLIString())); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if !bytes.Equal(decodedPub.k[:], pub.k[:]) { if !bytes.Equal(decodedPub.k[:], pub.k[:]) {
t.Error("decoded and generated NLPublic bytes differ (CLI prefix)") t.Error("decoded and generated TLPublic bytes differ (CLI prefix)")
} }
} }
+1 -1
View File
@@ -129,7 +129,7 @@ func PrivateTypesForTest() set.Set[reflect.Type] {
reflect.TypeFor[DiscoPrivate](), reflect.TypeFor[DiscoPrivate](),
reflect.TypeFor[MachinePrivate](), reflect.TypeFor[MachinePrivate](),
reflect.TypeFor[NodePrivate](), reflect.TypeFor[NodePrivate](),
reflect.TypeFor[NLPrivate](), reflect.TypeFor[TLPrivate](),
reflect.TypeFor[HardwareAttestationKey](), reflect.TypeFor[HardwareAttestationKey](),
) )
} }
+1 -1
View File
@@ -27,7 +27,7 @@ type Persist struct {
// NetworkLockKey is the node's Tailnet Lock private key. // NetworkLockKey is the node's Tailnet Lock private key.
// "Network Lock" was the pre-release name for Tailnet Lock. // "Network Lock" was the pre-release name for Tailnet Lock.
NetworkLockKey key.NLPrivate NetworkLockKey key.TLPrivate
NodeID tailcfg.StableNodeID NodeID tailcfg.StableNodeID
AttestationKey key.HardwareAttestationKey `json:",omitzero"` AttestationKey key.HardwareAttestationKey `json:",omitzero"`
+1 -1
View File
@@ -33,7 +33,7 @@ var _PersistCloneNeedsRegeneration = Persist(struct {
PrivateNodeKey key.NodePrivate PrivateNodeKey key.NodePrivate
OldPrivateNodeKey key.NodePrivate OldPrivateNodeKey key.NodePrivate
UserProfile tailcfg.UserProfile UserProfile tailcfg.UserProfile
NetworkLockKey key.NLPrivate NetworkLockKey key.TLPrivate
NodeID tailcfg.StableNodeID NodeID tailcfg.StableNodeID
AttestationKey key.HardwareAttestationKey AttestationKey key.HardwareAttestationKey
DisallowedTKAStateIDs []string DisallowedTKAStateIDs []string
+2 -2
View File
@@ -28,7 +28,7 @@ func TestPersistEqual(t *testing.T) {
} }
k1 := key.NewNode() k1 := key.NewNode()
nl1 := key.NewNLPrivate() nl1 := key.NewTLPrivate()
tests := []struct { tests := []struct {
a, b *Persist a, b *Persist
want bool want bool
@@ -86,7 +86,7 @@ func TestPersistEqual(t *testing.T) {
}, },
{ {
&Persist{NetworkLockKey: nl1}, &Persist{NetworkLockKey: nl1},
&Persist{NetworkLockKey: key.NewNLPrivate()}, &Persist{NetworkLockKey: key.NewTLPrivate()},
false, false,
}, },
{ {
+2 -2
View File
@@ -94,7 +94,7 @@ func (v PersistView) UserProfile() tailcfg.UserProfileView { return v.ж.UserPro
// NetworkLockKey is the node's Tailnet Lock private key. // NetworkLockKey is the node's Tailnet Lock private key.
// "Network Lock" was the pre-release name for Tailnet Lock. // "Network Lock" was the pre-release name for Tailnet Lock.
func (v PersistView) NetworkLockKey() key.NLPrivate { return v.ж.NetworkLockKey } func (v PersistView) NetworkLockKey() key.TLPrivate { return v.ж.NetworkLockKey }
func (v PersistView) NodeID() tailcfg.StableNodeID { return v.ж.NodeID } func (v PersistView) NodeID() tailcfg.StableNodeID { return v.ж.NodeID }
func (v PersistView) AttestationKey() tailcfg.StableNodeID { panic("unsupported") } func (v PersistView) AttestationKey() tailcfg.StableNodeID { panic("unsupported") }
@@ -112,7 +112,7 @@ var _PersistViewNeedsRegeneration = Persist(struct {
PrivateNodeKey key.NodePrivate PrivateNodeKey key.NodePrivate
OldPrivateNodeKey key.NodePrivate OldPrivateNodeKey key.NodePrivate
UserProfile tailcfg.UserProfile UserProfile tailcfg.UserProfile
NetworkLockKey key.NLPrivate NetworkLockKey key.TLPrivate
NodeID tailcfg.StableNodeID NodeID tailcfg.StableNodeID
AttestationKey key.HardwareAttestationKey AttestationKey key.HardwareAttestationKey
DisallowedTKAStateIDs []string DisallowedTKAStateIDs []string