2021-07-22 15:23:24 +02:00
|
|
|
package encryption
|
2021-05-01 12:45:37 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/rand"
|
|
|
|
"fmt"
|
2023-03-29 10:40:31 +02:00
|
|
|
|
2021-05-01 12:45:37 +02:00
|
|
|
"golang.org/x/crypto/nacl/box"
|
|
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
|
|
)
|
|
|
|
|
2023-03-29 10:40:31 +02:00
|
|
|
const nonceSize = 24
|
|
|
|
|
2021-07-22 15:23:24 +02:00
|
|
|
// 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
|
|
|
|
|
2021-05-15 12:20:49 +02:00
|
|
|
// 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
|
|
|
}
|
|
|
|
|
2021-05-15 12:20:49 +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
|
|
|
|
}
|
2023-03-29 10:40:31 +02:00
|
|
|
if len(encryptedMsg) < nonceSize {
|
2023-11-01 17:11:16 +01:00
|
|
|
return nil, fmt.Errorf("invalid encrypted message length")
|
2023-03-29 10:40:31 +02:00
|
|
|
}
|
|
|
|
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
|
2023-03-29 10:40:31 +02:00
|
|
|
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)
|
|
|
|
}
|