cmd/nodekey: add a tool to print nodekey

This commit is contained in:
Anton Tolchanov 2025-11-19 09:40:48 +00:00
parent 99f8039101
commit 0b89e31739

85
cmd/nodekey/nodekey.go Normal file
View File

@ -0,0 +1,85 @@
package main
import (
"fmt"
"log"
"os"
"go4.org/mem"
"tailscale.com/types/key"
)
func main() {
for _, arg := range os.Args[1:] {
k, err := key.ParseNodePublicUntyped(mem.B([]byte(arg)))
if err != nil {
log.Printf("invalid node key %q: %v", arg, err)
}
b, err := parseDebug32(arg)
if err != nil {
log.Printf("invalid debug32 format for %q: %v", arg, err)
}
k = key.NodePublicFromRaw32(mem.B(b[:]))
log.Printf("node key: %s", k.ShortString())
log.Printf("node key: %s", k.String())
}
}
// parseDebug32 attempts to reconstruct the first 4 bytes of a key
// from the Tailscale debug representation like "[abcde]".
// The remaining bytes will be zero.
func parseDebug32(s string) ([32]byte, error) {
var k [32]byte
if s == "" {
return k, nil
}
if len(s) != 7 || s[0] != '[' || s[6] != ']' {
return k, fmt.Errorf("invalid debug32 format %q", s)
}
decode64 := func(c byte) (byte, bool) {
switch {
case 'A' <= c && c <= 'Z':
return c - 'A', true
case 'a' <= c && c <= 'z':
return c - 'a' + 26, true
case '0' <= c && c <= '9':
return c - '0' + 52, true
case c == '+':
return 62, true
case c == '/':
return 63, true
default:
return 0, false
}
}
v0, ok := decode64(s[1])
if !ok {
return k, fmt.Errorf("invalid debug32 format %q", s)
}
v1, ok := decode64(s[2])
if !ok {
return k, fmt.Errorf("invalid debug32 format %q", s)
}
v2, ok := decode64(s[3])
if !ok {
return k, fmt.Errorf("invalid debug32 format %q", s)
}
v3, ok := decode64(s[4])
if !ok {
return k, fmt.Errorf("invalid debug32 format %q", s)
}
v4, ok := decode64(s[5])
if !ok {
return k, fmt.Errorf("invalid debug32 format %q", s)
}
k[0] = v0<<2 | v1>>4
k[1] = v1<<4 | v2>>2
k[2] = v2<<6 | v3
k[3] = v4 << 2 // low 2 bits were discarded by debug32
return k, nil
}