From 1d8c818ec4f1c18e1334e31c3805888c4185d185 Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Tue, 22 Aug 2023 23:45:37 +0000 Subject: [PATCH] wireguard: make PrivateKey and PublicKey two distinct types Signed-off-by: Alejandro Mery --- pkg/wireguard/config.go | 8 ++-- pkg/wireguard/keys.go | 90 ++++++++++++++++++++++++++++++++++------- 2 files changed, 79 insertions(+), 19 deletions(-) diff --git a/pkg/wireguard/config.go b/pkg/wireguard/config.go index ab22c69..931e37b 100644 --- a/pkg/wireguard/config.go +++ b/pkg/wireguard/config.go @@ -31,13 +31,13 @@ func (f *Config) Peers() int { // InterfaceConfig represents the [Interface] section type InterfaceConfig struct { Address netip.Addr - PrivateKey BinaryKey + PrivateKey PrivateKey ListenPort uint16 } // PeerConfig represents a [Peer] section type PeerConfig struct { - PublicKey BinaryKey + PublicKey PublicKey Endpoint EndpointAddress AllowedIPs []netip.Prefix } @@ -135,7 +135,7 @@ func (p interfaceConfig) Export() (InterfaceConfig, error) { ListenPort: p.ListenPort, } - out.PrivateKey, err = BinaryKeyFromBase64(p.PrivateKey) + out.PrivateKey, err = PrivateKeyFromBase64(p.PrivateKey) if err != nil { err = core.Wrap(err, "PrivateKey") return InterfaceConfig{}, err @@ -162,7 +162,7 @@ func (v *intermediateConfig) ExportPeer(i int) (PeerConfig, error) { } // PublicKey - out.PublicKey, err = BinaryKeyFromBase64(v.Peer.PublicKey[i]) + out.PublicKey, err = PublicKeyFromBase64(v.Peer.PublicKey[i]) if err != nil { err = core.Wrap(err, "PublicKey") return out, err diff --git a/pkg/wireguard/keys.go b/pkg/wireguard/keys.go index 12bf58e..c6acea0 100644 --- a/pkg/wireguard/keys.go +++ b/pkg/wireguard/keys.go @@ -3,34 +3,94 @@ package wireguard import ( "bytes" "encoding/base64" + "errors" ) -// BinaryKey is a binary blob -type BinaryKey []byte +const ( + // PrivateKeySize is the length in bytes of a Wireguard Private Key + PrivateKeySize = 32 + // PublicKeySize is the length in bytes of a Wireguard Public Key + PublicKeySize = 32 +) + +var ( + // ErrInvalidKeySize indicates the key size is wrong + ErrInvalidKeySize = errors.New("invalid key size") +) + +type ( + // PrivateKey is a binary Wireguard Private Key + PrivateKey []byte + // PublicKey is a binary Wireguard Public Key + PublicKey []byte +) + +func (key PrivateKey) String() string { + return encodeKey(key) +} + +func (pub PublicKey) String() string { + return encodeKey(pub) +} -func (k BinaryKey) String() string { - return base64.StdEncoding.EncodeToString(k) +// IsZero tells if the key hasn't been set +func (key PrivateKey) IsZero() bool { + return len(key) == 0 } // IsZero tells if the key hasn't been set -func (k BinaryKey) IsZero() bool { - return len(k) == 0 +func (pub PublicKey) IsZero() bool { + return len(pub) == 0 +} + +// Equal checks if two private keys are identical +func (key PrivateKey) Equal(alter PrivateKey) bool { + return bytes.Equal(key, alter) +} + +// Equal checks if two public keys are identical +func (pub PublicKey) Equal(alter PublicKey) bool { + return bytes.Equal(pub, alter) +} + +// PrivateKeyFromBase64 decodes a base64-based string into +// a [PrivateKey] +func PrivateKeyFromBase64(data string) (PrivateKey, error) { + b, err := decodeKey(data, PrivateKeySize) + return b, err +} + +// PublicKeyFromBase64 decodes a base64-based string into +// a [PublicKey] +func PublicKeyFromBase64(data string) (PublicKey, error) { + b, err := decodeKey(data, PublicKeySize) + return b, err } -// Equal checks if two keys are identical -func (k BinaryKey) Equal(alter BinaryKey) bool { - return bytes.Equal(k, alter) +func encodeKey(b []byte) string { + switch { + case len(b) == 0: + return "" + default: + return base64.StdEncoding.EncodeToString(b) + } } -// BinaryKeyFromBase64 decodes a base64-based string into -// a [BinaryKey] -func BinaryKeyFromBase64(data string) (BinaryKey, error) { +func decodeKey(data string, size int) ([]byte, error) { b, err := base64.StdEncoding.DecodeString(data) - return BinaryKey(b), err + switch { + case err != nil: + return []byte{}, err + case len(b) != size: + err = ErrInvalidKeySize + return []byte{}, err + default: + return b, nil + } } // KeyPair holds a Key pair type KeyPair struct { - PrivateKey BinaryKey - PublicKey BinaryKey + PrivateKey PrivateKey + PublicKey PublicKey }