netbird/encryption/encryption.go

57 lines
1.8 KiB
Go
Raw Normal View History

package encryption
2021-05-01 12:45:37 +02:00
import (
"crypto/rand"
"fmt"
2021-05-01 12:45:37 +02:00
"golang.org/x/crypto/nacl/box"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
const nonceSize = 24
// A set of tools to encrypt/decrypt messages being sent through the Signal Exchange Service or Management Service
2021-05-01 12:45:37 +02:00
// These tools use Golang crypto package (Curve25519, XSalsa20 and Poly1305 to encrypt and authenticate)
// Wireguard keys are used for encryption
// Encrypt encrypts a message using local Wireguard private key and remote peer's public key.
2021-06-03 11:39:19 +02:00
func Encrypt(msg []byte, peerPublicKey wgtypes.Key, privateKey wgtypes.Key) ([]byte, error) {
2021-05-01 12:45:37 +02:00
nonce, err := genNonce()
if err != nil {
return nil, err
}
2021-06-03 11:39:19 +02:00
return box.Seal(nonce[:], msg, nonce, toByte32(peerPublicKey), toByte32(privateKey)), nil
2021-05-01 12:45:37 +02:00
}
// Decrypt decrypts a message that has been encrypted by the remote peer using Wireguard private key and remote peer's public key.
2021-06-03 11:39:19 +02:00
func Decrypt(encryptedMsg []byte, peerPublicKey wgtypes.Key, privateKey wgtypes.Key) ([]byte, error) {
2021-05-01 12:45:37 +02:00
nonce, err := genNonce()
if err != nil {
return nil, err
}
if len(encryptedMsg) < nonceSize {
return nil, fmt.Errorf("invalid encrypted message length")
}
copy(nonce[:], encryptedMsg[:nonceSize])
opened, ok := box.Open(nil, encryptedMsg[nonceSize:], nonce, toByte32(peerPublicKey), toByte32(privateKey))
2021-05-01 12:45:37 +02:00
if !ok {
2021-06-03 11:39:19 +02:00
return nil, fmt.Errorf("failed to decrypt message from peer %s", peerPublicKey.String())
2021-05-01 12:45:37 +02:00
}
return opened, nil
}
// Generates nonce of size 24
func genNonce() (*[nonceSize]byte, error) {
var nonce [nonceSize]byte
2021-05-01 12:45:37 +02:00
if _, err := rand.Read(nonce[:]); err != nil {
return nil, err
}
return &nonce, nil
}
// Converts Wireguard key to byte array of size 32 (a format used by the golang crypto package)
func toByte32(key wgtypes.Key) *[32]byte {
return (*[32]byte)(&key)
}