Compare commits

..

2 Commits

Author SHA1 Message Date
amery 47d79f7576 wireguard: introduce KeyPair.Validate()
it will also set the PublicKey field is empty

Signed-off-by: Alejandro Mery <amery@jpi.io>
2023-08-23 00:29:15 +00:00
amery e2f831fd6a wireguard: introduce NewKeyPair, NewPrivateKey, and PrivateKey.Public()
Signed-off-by: Alejandro Mery <amery@jpi.io>
2023-08-23 00:18:31 +00:00
3 changed files with 79 additions and 0 deletions
+1
View File
@@ -10,6 +10,7 @@ require (
github.com/burntSushi/toml v0.3.1
github.com/mgechev/revive v1.3.2
github.com/spf13/cobra v1.7.0
golang.org/x/crypto v0.12.0
gopkg.in/gcfg.v1 v1.2.3
)
+2
View File
@@ -70,6 +70,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+76
View File
@@ -2,8 +2,11 @@ package wireguard
import (
"bytes"
"crypto/rand"
"encoding/base64"
"errors"
"golang.org/x/crypto/curve25519"
)
const (
@@ -16,6 +19,10 @@ const (
var (
// ErrInvalidKeySize indicates the key size is wrong
ErrInvalidKeySize = errors.New("invalid key size")
// ErrInvalidPrivateKey indicates the private key is invalid
ErrInvalidPrivateKey = errors.New("invalid private key")
// ErrInvalidPublicKey indicates the public key is invalid
ErrInvalidPublicKey = errors.New("invalid public key")
)
type (
@@ -89,8 +96,77 @@ func decodeKey(data string, size int) ([]byte, error) {
}
}
// NewPrivateKey creates a new PrivateKey
func NewPrivateKey() (PrivateKey, error) {
var s [PrivateKeySize]byte
_, err := rand.Read(s[:])
if err != nil {
return []byte{}, err
}
// apply same clamping as wireguard-go/device/noise-helpers.go
s[0] &= 0xf8
s[31] = (s[31] & 0x7f) | 0x40
return s[:], nil
}
// Public generates the corresponding PublicKey
func (key PrivateKey) Public() PublicKey {
if len(key) != PrivateKeySize {
return []byte{}
}
out := [PublicKeySize]byte{}
in := (*[PrivateKeySize]byte)(key)
curve25519.ScalarBaseMult(&out, in)
return out[:]
}
// KeyPair holds a Key pair
type KeyPair struct {
PrivateKey PrivateKey
PublicKey PublicKey
}
// Validate checks the PublicKey matches the PrivateKey,
// and sets the PublicKey if missing
func (kp *KeyPair) Validate() error {
keyLen := len(kp.PrivateKey)
pubLen := len(kp.PublicKey)
switch {
case keyLen != PrivateKeySize:
// bad private key
return ErrInvalidPrivateKey
case pubLen == 0:
// no public key, set it
kp.PublicKey = kp.PrivateKey.Public()
return nil
case pubLen != PublicKeySize:
// bad public key
return ErrInvalidPublicKey
case !kp.PrivateKey.Public().Equal(kp.PublicKey):
// wrong public key
return ErrInvalidPublicKey
default:
// correct public key
return nil
}
}
// NewKeyPair creates a new KeyPair for Wireguard
func NewKeyPair() (*KeyPair, error) {
key, err := NewPrivateKey()
if err != nil {
return nil, err
}
out := &KeyPair{
PrivateKey: key,
PublicKey: key.Public(),
}
return out, nil
}