118 lines
2.7 KiB
Go
118 lines
2.7 KiB
Go
|
package util
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"errors"
|
||
|
"regexp"
|
||
|
"strings"
|
||
|
|
||
|
"tailscale.com/types/key"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
|
||
|
// These constants are copied from the upstream tailscale.com/types/key
|
||
|
// library, because they are not exported.
|
||
|
// https://github.com/tailscale/tailscale/tree/main/types/key
|
||
|
|
||
|
// nodePublicHexPrefix is the prefix used to identify a
|
||
|
// hex-encoded node public key.
|
||
|
//
|
||
|
// This prefix is used in the control protocol, so cannot be
|
||
|
// changed.
|
||
|
nodePublicHexPrefix = "nodekey:"
|
||
|
|
||
|
// machinePublicHexPrefix is the prefix used to identify a
|
||
|
// hex-encoded machine public key.
|
||
|
//
|
||
|
// This prefix is used in the control protocol, so cannot be
|
||
|
// changed.
|
||
|
machinePublicHexPrefix = "mkey:"
|
||
|
|
||
|
// discoPublicHexPrefix is the prefix used to identify a
|
||
|
// hex-encoded disco public key.
|
||
|
//
|
||
|
// This prefix is used in the control protocol, so cannot be
|
||
|
// changed.
|
||
|
discoPublicHexPrefix = "discokey:"
|
||
|
|
||
|
// privateKey prefix.
|
||
|
privateHexPrefix = "privkey:"
|
||
|
|
||
|
PermissionFallback = 0o700
|
||
|
|
||
|
ZstdCompression = "zstd"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
NodePublicKeyRegex = regexp.MustCompile("nodekey:[a-fA-F0-9]+")
|
||
|
ErrCannotDecryptResponse = errors.New("cannot decrypt response")
|
||
|
)
|
||
|
|
||
|
func MachinePublicKeyStripPrefix(machineKey key.MachinePublic) string {
|
||
|
return strings.TrimPrefix(machineKey.String(), machinePublicHexPrefix)
|
||
|
}
|
||
|
|
||
|
func NodePublicKeyStripPrefix(nodeKey key.NodePublic) string {
|
||
|
return strings.TrimPrefix(nodeKey.String(), nodePublicHexPrefix)
|
||
|
}
|
||
|
|
||
|
func DiscoPublicKeyStripPrefix(discoKey key.DiscoPublic) string {
|
||
|
return strings.TrimPrefix(discoKey.String(), discoPublicHexPrefix)
|
||
|
}
|
||
|
|
||
|
func MachinePublicKeyEnsurePrefix(machineKey string) string {
|
||
|
if !strings.HasPrefix(machineKey, machinePublicHexPrefix) {
|
||
|
return machinePublicHexPrefix + machineKey
|
||
|
}
|
||
|
|
||
|
return machineKey
|
||
|
}
|
||
|
|
||
|
func NodePublicKeyEnsurePrefix(nodeKey string) string {
|
||
|
if !strings.HasPrefix(nodeKey, nodePublicHexPrefix) {
|
||
|
return nodePublicHexPrefix + nodeKey
|
||
|
}
|
||
|
|
||
|
return nodeKey
|
||
|
}
|
||
|
|
||
|
func DiscoPublicKeyEnsurePrefix(discoKey string) string {
|
||
|
if !strings.HasPrefix(discoKey, discoPublicHexPrefix) {
|
||
|
return discoPublicHexPrefix + discoKey
|
||
|
}
|
||
|
|
||
|
return discoKey
|
||
|
}
|
||
|
|
||
|
func PrivateKeyEnsurePrefix(privateKey string) string {
|
||
|
if !strings.HasPrefix(privateKey, privateHexPrefix) {
|
||
|
return privateHexPrefix + privateKey
|
||
|
}
|
||
|
|
||
|
return privateKey
|
||
|
}
|
||
|
|
||
|
func DecodeAndUnmarshalNaCl(
|
||
|
msg []byte,
|
||
|
output interface{},
|
||
|
pubKey *key.MachinePublic,
|
||
|
privKey *key.MachinePrivate,
|
||
|
) error {
|
||
|
// log.Trace().
|
||
|
// Str("pubkey", pubKey.ShortString()).
|
||
|
// Int("length", len(msg)).
|
||
|
// Msg("Trying to decrypt")
|
||
|
|
||
|
decrypted, ok := privKey.OpenFrom(*pubKey, msg)
|
||
|
if !ok {
|
||
|
return ErrCannotDecryptResponse
|
||
|
}
|
||
|
|
||
|
if err := json.Unmarshal(decrypted, output); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|