Extract common server encryption logic (#65)

* refactor: extract common message encryption logic
* refactor: move letsencrypt logic to common
* refactor: rename common package to encryption
* test: add encryption tests
This commit is contained in:
Mikhail Bragin
2021-07-22 15:23:24 +02:00
committed by GitHub
parent c98be683bf
commit 2172d6f1b9
16 changed files with 343 additions and 141 deletions
+5 -11
View File
@@ -4,8 +4,8 @@ import (
"context"
"fmt"
"github.com/cenkalti/backoff/v4"
pb "github.com/golang/protobuf/proto" //nolint
log "github.com/sirupsen/logrus"
"github.com/wiretrustee/wiretrustee/encryption"
"github.com/wiretrustee/wiretrustee/signal/proto"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"google.golang.org/grpc"
@@ -162,12 +162,9 @@ func (c *Client) decryptMessage(msg *proto.EncryptedMessage) (*proto.Message, er
if err != nil {
return nil, err
}
decryptedBody, err := Decrypt(msg.GetBody(), remoteKey, c.key)
if err != nil {
return nil, err
}
body := &proto.Body{}
err = pb.Unmarshal(decryptedBody, body)
err = encryption.DecryptMessage(remoteKey, c.key, msg.GetBody(), body)
if err != nil {
return nil, err
}
@@ -181,16 +178,13 @@ func (c *Client) decryptMessage(msg *proto.EncryptedMessage) (*proto.Message, er
// encryptMessage encrypts the body of the msg using Wireguard private key and Remote peer's public key
func (c *Client) encryptMessage(msg *proto.Message) (*proto.EncryptedMessage, error) {
body, err := pb.Marshal(msg.GetBody())
if err != nil {
return nil, err
}
remoteKey, err := wgtypes.ParseKey(msg.RemoteKey)
if err != nil {
return nil, err
}
encryptedBody, err := Encrypt(body, remoteKey, c.key)
encryptedBody, err := encryption.EncryptMessage(remoteKey, c.key, msg.Body)
if err != nil {
return nil, err
}
-52
View File
@@ -1,52 +0,0 @@
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.
// 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.
// 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.
func Encrypt(msg []byte, peerPublicKey wgtypes.Key, privateKey wgtypes.Key) ([]byte, error) {
nonce, err := genNonce()
if err != nil {
return nil, err
}
return box.Seal(nonce[:], msg, nonce, toByte32(peerPublicKey), toByte32(privateKey)), nil
}
// Decrypt decrypts a message that has been encrypted by the remote peer using Wireguard private key and remote peer's public key.
func Decrypt(encryptedMsg []byte, peerPublicKey wgtypes.Key, privateKey wgtypes.Key) ([]byte, error) {
nonce, err := genNonce()
if err != nil {
return nil, err
}
copy(nonce[:], encryptedMsg[:24])
opened, ok := box.Open(nil, encryptedMsg[24:], nonce, toByte32(peerPublicKey), toByte32(privateKey))
if !ok {
return nil, fmt.Errorf("failed to decrypt message from peer %s", peerPublicKey.String())
}
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)
}
+3 -2
View File
@@ -1,6 +1,7 @@
package signal
import (
"github.com/wiretrustee/wiretrustee/encryption"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"testing"
)
@@ -21,13 +22,13 @@ func TestEncryptDecrypt(t *testing.T) {
return
}
encryptedMessage, err := Encrypt(bytesMsg, peerBKey.PublicKey(), peerAKey)
encryptedMessage, err := encryption.Encrypt(bytesMsg, peerBKey.PublicKey(), peerAKey)
if err != nil {
t.Error(err)
return
}
decryptedMessage, err := Decrypt(encryptedMessage, peerAKey.PublicKey(), peerBKey)
decryptedMessage, err := encryption.Decrypt(encryptedMessage, peerAKey.PublicKey(), peerBKey)
if err != nil {
t.Error(err)
return