2021-05-01 12:45:37 +02:00
|
|
|
package signal
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/rand"
|
|
|
|
"fmt"
|
|
|
|
"golang.org/x/crypto/nacl/box"
|
|
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
|
|
)
|
|
|
|
|
|
|
|
// As set of tools to encrypt/decrypt messages being sent through the Signal Exchange Service.
|
2021-05-05 10:40:53 +02:00
|
|
|
// We want to make sure that the Connection Candidates and other irrelevant (to the Signal Exchange)
|
|
|
|
// information can't be read anywhere else but the Peer the message is being sent to.
|
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
|
|
|
|
}
|
2021-05-05 10:40:53 +02:00
|
|
|
copy(nonce[:], encryptedMsg[:24])
|
2021-06-03 11:39:19 +02:00
|
|
|
opened, ok := box.Open(nil, encryptedMsg[24:], 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() (*[24]byte, error) {
|
|
|
|
var nonce [24]byte
|
|
|
|
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)
|
|
|
|
}
|