Browse Source

initial chunk approach

0xdcarns 3 years ago
parent
commit
83250980eb
4 changed files with 115 additions and 30 deletions
  1. 3 3
      mq/util.go
  2. 3 3
      netclient/functions/daemon.go
  3. 109 0
      netclient/ncutils/encryption.go
  4. 0 24
      netclient/ncutils/netclientutils.go

+ 3 - 3
mq/util.go

@@ -10,7 +10,7 @@ import (
 
 func decryptMsg(node *models.Node, msg []byte) ([]byte, error) {
 	if len(msg) <= 24 { // make sure message is of appropriate length
-		return nil, fmt.Errorf("recieved invalid message from broker %s", string(msg))
+		return nil, fmt.Errorf("recieved invalid message from broker %v", msg)
 	}
 
 	trafficKey, trafficErr := logic.RetrievePrivateTrafficKey() // get server private key
@@ -26,7 +26,7 @@ func decryptMsg(node *models.Node, msg []byte) ([]byte, error) {
 		return nil, err
 	}
 
-	return ncutils.BoxDecrypt(msg, nodePubTKey, serverPrivTKey)
+	return ncutils.DeChunk(msg, nodePubTKey, serverPrivTKey)
 }
 
 func encryptMsg(node *models.Node, msg []byte) ([]byte, error) {
@@ -46,7 +46,7 @@ func encryptMsg(node *models.Node, msg []byte) ([]byte, error) {
 		return nil, err
 	}
 
-	return ncutils.BoxEncrypt(msg, nodePubKey, serverPrivKey)
+	return ncutils.Chunk(msg, nodePubKey, serverPrivKey)
 }
 
 func publish(node *models.Node, dest string, msg []byte) error {

+ 3 - 3
netclient/functions/daemon.go

@@ -553,7 +553,7 @@ func publish(cfg *config.ClientConfig, dest string, msg []byte) error {
 
 	client := SetupMQTT(cfg, true)
 	defer client.Disconnect(250)
-	encrypted, err := ncutils.BoxEncrypt(msg, serverPubKey, trafficPrivKey)
+	encrypted, err := ncutils.Chunk(msg, serverPubKey, trafficPrivKey)
 	if err != nil {
 		return err
 	}
@@ -570,7 +570,7 @@ func parseNetworkFromTopic(topic string) string {
 
 func decryptMsg(cfg *config.ClientConfig, msg []byte) ([]byte, error) {
 	if len(msg) <= 24 { // make sure message is of appropriate length
-		return nil, fmt.Errorf("recieved invalid message from broker %s", string(msg))
+		return nil, fmt.Errorf("recieved invalid message from broker %v", msg)
 	}
 
 	// setup the keys
@@ -584,7 +584,7 @@ func decryptMsg(cfg *config.ClientConfig, msg []byte) ([]byte, error) {
 		return nil, err
 	}
 
-	return ncutils.BoxDecrypt(msg, serverPubKey, diskKey)
+	return ncutils.DeChunk(msg, serverPubKey, diskKey)
 }
 
 func pingServer(cfg *config.ClientConfig) error {

+ 109 - 0
netclient/ncutils/encryption.go

@@ -0,0 +1,109 @@
+package ncutils
+
+import (
+	"bytes"
+	"crypto/rand"
+	"encoding/gob"
+	"fmt"
+	"io"
+
+	"golang.org/x/crypto/nacl/box"
+)
+
+const (
+	chunkSize = 16128 // 16128 bytes max message size
+)
+
+// BoxEncrypt - encrypts traffic box
+func BoxEncrypt(message []byte, recipientPubKey *[32]byte, senderPrivateKey *[32]byte) ([]byte, error) {
+	var nonce [24]byte // 192 bits of randomization
+	if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
+		return nil, err
+	}
+
+	encrypted := box.Seal(nonce[:], message, &nonce, recipientPubKey, senderPrivateKey)
+	return encrypted, nil
+}
+
+// BoxDecrypt - decrypts traffic box
+func BoxDecrypt(encrypted []byte, senderPublicKey *[32]byte, recipientPrivateKey *[32]byte) ([]byte, error) {
+	var decryptNonce [24]byte
+	copy(decryptNonce[:], encrypted[:24])
+	decrypted, ok := box.Open(nil, encrypted[24:], &decryptNonce, senderPublicKey, recipientPrivateKey)
+	if !ok {
+		return nil, fmt.Errorf("could not decrypt message")
+	}
+	return decrypted, nil
+}
+
+// Chunk - chunks a message and encrypts each chunk
+func Chunk(message []byte, recipientPubKey *[32]byte, senderPrivateKey *[32]byte) ([]byte, error) {
+	var chunks [][]byte
+	for i := 0; i < len(message); i += chunkSize {
+		end := i + chunkSize
+
+		// necessary check to avoid slicing beyond
+		// slice capacity
+		if end > len(message) {
+			end = len(message)
+		}
+
+		encryptedMsgSlice, err := BoxEncrypt(message[i:end], recipientPubKey, senderPrivateKey)
+		if err != nil {
+			return nil, err
+		}
+
+		chunks = append(chunks, encryptedMsgSlice)
+	}
+
+	chunkedMsg, err := convertBytesToMsg(chunks) // encode the array into some bytes to decode on receiving end
+	if err != nil {
+		return nil, err
+	}
+
+	return chunkedMsg, nil
+}
+
+// DeChunk - "de" chunks and decrypts a message
+func DeChunk(chunkedMsg []byte, senderPublicKey *[32]byte, recipientPrivateKey *[32]byte) ([]byte, error) {
+	chunks, err := convertMsgToBytes(chunkedMsg)
+	if err != nil {
+		return nil, err
+	}
+
+	var totalMsg []byte
+	for i := range chunks {
+		decodedMsg, err := BoxDecrypt(chunks[i], senderPublicKey, recipientPrivateKey)
+		if err != nil {
+			return nil, err
+		}
+		totalMsg = append(totalMsg, decodedMsg...)
+	}
+	return totalMsg, nil
+}
+
+// == private ==
+
+// ConvertMsgToBytes - converts a message (MQ) to it's chunked version
+// decode action
+func convertMsgToBytes(msg []byte) ([][]byte, error) {
+	var buffer = bytes.NewBuffer(msg)
+	var dec = gob.NewDecoder(buffer)
+	var result [][]byte
+	var err = dec.Decode(&result)
+	if err != nil {
+		return nil, err
+	}
+	return result, err
+}
+
+// ConvertBytesToMsg - converts the chunked message into a MQ message
+// encode action
+func convertBytesToMsg(b [][]byte) ([]byte, error) {
+	var buffer bytes.Buffer
+	var enc = gob.NewEncoder(&buffer)
+	if err := enc.Encode(b); err != nil {
+		return nil, err
+	}
+	return buffer.Bytes(), nil
+}

+ 0 - 24
netclient/ncutils/netclientutils.go

@@ -2,7 +2,6 @@ package ncutils
 
 import (
 	"bytes"
-	crand "crypto/rand"
 	"crypto/tls"
 	"encoding/gob"
 	"errors"
@@ -22,7 +21,6 @@ import (
 	"time"
 
 	"github.com/gravitl/netmaker/models"
-	"golang.org/x/crypto/nacl/box"
 	"golang.zx2c4.com/wireguard/wgctrl"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 	"google.golang.org/grpc"
@@ -613,28 +611,6 @@ func ServerAddrSliceContains(slice []models.ServerAddr, item models.ServerAddr)
 	return false
 }
 
-// BoxEncrypt - encrypts traffic box
-func BoxEncrypt(message []byte, recipientPubKey *[32]byte, senderPrivateKey *[32]byte) ([]byte, error) {
-	var nonce [24]byte // 192 bits of randomization
-	if _, err := io.ReadFull(crand.Reader, nonce[:]); err != nil {
-		return nil, err
-	}
-
-	encrypted := box.Seal(nonce[:], message, &nonce, recipientPubKey, senderPrivateKey)
-	return encrypted, nil
-}
-
-// BoxDecrypt - decrypts traffic box
-func BoxDecrypt(encrypted []byte, senderPublicKey *[32]byte, recipientPrivateKey *[32]byte) ([]byte, error) {
-	var decryptNonce [24]byte
-	copy(decryptNonce[:], encrypted[:24])
-	decrypted, ok := box.Open(nil, encrypted[24:], &decryptNonce, senderPublicKey, recipientPrivateKey)
-	if !ok {
-		return nil, fmt.Errorf("could not decrypt message")
-	}
-	return decrypted, nil
-}
-
 // MakeRandomString - generates a random string of len n
 func MakeRandomString(n int) string {
 	sb := strings.Builder{}