From 24f70007624aab3b2daa958a455868fea5d6dd85 Mon Sep 17 00:00:00 2001 From: jbhusson <jonah@elixxir.io> Date: Wed, 20 Jul 2022 14:32:36 -0400 Subject: [PATCH] Fix payload size, comments from review --- broadcast/asymmetric.go | 18 ++++++++++++++---- broadcast/broadcastClient.go | 4 ++++ broadcast/processor.go | 14 ++++++++------ broadcast/symmetric.go | 2 +- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/broadcast/asymmetric.go b/broadcast/asymmetric.go index ed731ff21..8fab1b5a2 100644 --- a/broadcast/asymmetric.go +++ b/broadcast/asymmetric.go @@ -8,6 +8,7 @@ package broadcast import ( + "encoding/binary" "github.com/pkg/errors" "gitlab.com/elixxir/client/cmix" "gitlab.com/elixxir/client/cmix/message" @@ -19,6 +20,7 @@ import ( const ( asymmetricBroadcastServiceTag = "AsymmBcast" asymmCMixSendTag = "AsymmetricBroadcast" + internalPayloadSizeLength = 2 ) // MaxAsymmetricPayloadSize returns the maximum size for an asymmetric broadcast payload @@ -28,20 +30,26 @@ func (bc *broadcastClient) maxAsymmetricPayload() int { // BroadcastAsymmetric broadcasts the payload to the channel. Requires a healthy network state to send // Payload must be equal to bc.MaxAsymmetricPayloadSize, and the channel PrivateKey must be passed in -// When a payload is sent, it is split into partitons of size bc.channel.MaxAsymmetricPayloadSize -// which are each encrypted using multicastRSA func (bc *broadcastClient) BroadcastAsymmetric(pk multicastRSA.PrivateKey, payload []byte, cMixParams cmix.CMIXParams) ( id.Round, ephemeral.Id, error) { + // Confirm network health if !bc.net.IsHealthy() { return 0, ephemeral.Id{}, errors.New(errNetworkHealth) } - if len(payload) != bc.MaxAsymmetricPayloadSize() { + // Check payload size + if len(payload) > bc.MaxAsymmetricPayloadSize() { return 0, ephemeral.Id{}, errors.Errorf(errPayloadSize, len(payload), bc.maxAsymmetricPayload()) } + payloadLength := uint16(len(payload)) - encryptedPayload, mac, fp, err := bc.channel.EncryptAsymmetric(payload, pk, bc.rng.GetStream()) + finalPayload := make([]byte, bc.maxAsymmetricPayloadSizeRaw()) + binary.BigEndian.PutUint16(finalPayload[:internalPayloadSizeLength], payloadLength) + copy(finalPayload[internalPayloadSizeLength:], payload) + + // Encrypt payload + encryptedPayload, mac, fp, err := bc.channel.EncryptAsymmetric(finalPayload, pk, bc.rng.GetStream()) if err != nil { return 0, ephemeral.Id{}, errors.WithMessage(err, "Failed to encrypt asymmetric broadcast message") } @@ -56,7 +64,9 @@ func (bc *broadcastClient) BroadcastAsymmetric(pk multicastRSA.PrivateKey, paylo cMixParams.DebugTag = asymmCMixSendTag } + // Create payload sized for sending over cmix sizedPayload := make([]byte, bc.net.GetMaxMessageLength()) + // Read random data into sized payload _, err = bc.rng.GetStream().Read(sizedPayload) if err != nil { return 0, ephemeral.Id{}, errors.WithMessage(err, "Failed to add random data to sized broadcast") diff --git a/broadcast/broadcastClient.go b/broadcast/broadcastClient.go index c80f4a50e..6e1c7391c 100644 --- a/broadcast/broadcastClient.go +++ b/broadcast/broadcastClient.go @@ -102,5 +102,9 @@ func (bc *broadcastClient) MaxPayloadSize() int { } func (bc *broadcastClient) MaxAsymmetricPayloadSize() int { + return bc.maxAsymmetricPayloadSizeRaw() - internalPayloadSizeLength +} + +func (bc *broadcastClient) maxAsymmetricPayloadSizeRaw() int { return bc.channel.MaxAsymmetricPayloadSize() } diff --git a/broadcast/processor.go b/broadcast/processor.go index b747eac00..651974c4c 100644 --- a/broadcast/processor.go +++ b/broadcast/processor.go @@ -8,6 +8,7 @@ package broadcast import ( + "encoding/binary" jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/cmix/identity/receptionID" "gitlab.com/elixxir/client/cmix/rounds" @@ -35,14 +36,15 @@ func (p *processor) Process(msg format.Message, var err error switch p.method { case Asymmetric: - // We use sized broadcast to fill any remaining bytes in the cmix payload, decode it here - encPartSize := p.c.RsaPubKey.Size() // Size of each chunk returned by multicast RSA encryption - encodedMessage := msg.GetContents()[:encPartSize] - payload, err = p.c.DecryptAsymmetric(encodedMessage) - if err != nil { - jww.ERROR.Printf(errDecrypt, p.c.ReceptionID, p.c.Name, err) + encPartSize := p.c.RsaPubKey.Size() // Size returned by multicast RSA encryption + encodedMessage := msg.GetContents()[:encPartSize] // Only one message is encoded, rest of it is random data + decodedMessage, decryptErr := p.c.DecryptAsymmetric(encodedMessage) + if decryptErr != nil { + jww.ERROR.Printf(errDecrypt, p.c.ReceptionID, p.c.Name, decryptErr) return } + size := binary.BigEndian.Uint16(decodedMessage[:internalPayloadSizeLength]) + payload = decodedMessage[internalPayloadSizeLength : size+internalPayloadSizeLength] case Symmetric: payload, err = p.c.DecryptSymmetric(msg.GetContents(), msg.GetMac(), msg.GetKeyFP()) diff --git a/broadcast/symmetric.go b/broadcast/symmetric.go index 10ca5a5b3..e9b96f75c 100644 --- a/broadcast/symmetric.go +++ b/broadcast/symmetric.go @@ -19,7 +19,7 @@ import ( const ( // symmetricClient.Broadcast errNetworkHealth = "cannot send broadcast when the network is not healthy" - errPayloadSize = "size of payload %d must be %d" + errPayloadSize = "size of payload %d must be less than %d" errBroadcastMethodType = "cannot call %s broadcast using %s channel" ) -- GitLab