Skip to content
Snippets Groups Projects
Commit 92d1d953 authored by Benjamin Wenger's avatar Benjamin Wenger
Browse files

fixed file transfer, tests broken

parent aa2e4aec
Branches
Tags
3 merge requests!170Release,!128Xx 3678/ft cha cha20,!126Dev
......@@ -388,7 +388,6 @@ func TestManager_Resend_NoFingerprints(t *testing.T) {
func TestManager_CloseSend_NoFingerprints(t *testing.T) {
m, sti, _ := newTestManagerWithTransfers(
[]uint16{16}, false, false, nil, nil, nil, t)
prng := NewPrng(42)
partSize, _ := m.getPartSize()
// Use up all the fingerprints in the transfer
......
......@@ -8,7 +8,6 @@
package fileTransfer
import (
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/interfaces/message"
"gitlab.com/elixxir/client/stoppable"
......@@ -64,16 +63,8 @@ func (m *Manager) readMessage(msg message.Receive) (format.Message, error) {
return cMixMsg, err
}
// Unmarshal cMix message contents into a file part message
partMsg, err := unmarshalPartMessage(cMixMsg.GetContents())
if err != nil {
return cMixMsg, errors.Errorf(unmarshalPartMessageErr, err)
}
// Add part to received transfer
rt, tid, completed, err := m.received.AddPart(partMsg.getPart(),
partMsg.getPadding(), cMixMsg.GetMac(), partMsg.getPartNum(),
cMixMsg.GetKeyFP())
rt, tid, completed, err := m.received.AddPart(cMixMsg)
if err != nil {
return cMixMsg, err
}
......
......@@ -51,7 +51,7 @@ func TestManager_receiveNewFileTransfer(t *testing.T) {
}
marshalledMsg, err := proto.Marshal(protoMsg)
if err != nil {
t.Errorf("Failed to marshal proto message: %+v", err)
t.Errorf("Failed to Marshal proto message: %+v", err)
}
receiveMsg := message.Receive{
Payload: marshalledMsg,
......@@ -120,7 +120,7 @@ func TestManager_receiveNewFileTransfer_Stop(t *testing.T) {
}
marshalledMsg, err := proto.Marshal(protoMsg)
if err != nil {
t.Errorf("Failed to marshal proto message: %+v", err)
t.Errorf("Failed to Marshal proto message: %+v", err)
}
receiveMsg := message.Receive{
Payload: marshalledMsg,
......
......@@ -364,30 +364,14 @@ func (m *Manager) newCmixMessage(transfer *ftStorage.SentTransfer,
// Create new empty cMix message
cmixMsg := format.NewMessage(m.store.Cmix().GetGroup().GetP().ByteLen())
// Create new empty file part message of size equal to the available payload
// size in the cMix message
partMsg, err := newPartMessage(cmixMsg.ContentsSize())
if err != nil {
return cmixMsg, err
}
// Get encrypted file part, file part MAC, padding (nonce), and fingerprint
encPart, mac, padding, fp, err := transfer.GetEncryptedPart(
partNum, partMsg.getPartSize(), rng)
if err != nil {
return cmixMsg, err
}
// Construct file part message from padding (
partMsg.setPadding(padding)
partMsg.setPartNum(partNum)
err = partMsg.setPart(encPart)
// Get encrypted file part, file part MAC, nonce (nonce), and fingerprint
encPart, mac, fp, err := transfer.GetEncryptedPart(partNum, cmixMsg.ContentsSize())
if err != nil {
return cmixMsg, err
return format.Message{}, err
}
// Construct cMix message
cmixMsg.SetContents(partMsg.marshal())
cmixMsg.SetContents(encPart)
cmixMsg.SetKeyFP(fp)
cmixMsg.SetMac(mac)
......@@ -566,12 +550,12 @@ func (m *Manager) getPartSize() (int, error) {
// Create new empty file part message of size equal to the available payload
// size in the cMix message
partMsg, err := newPartMessage(cmixMsg.ContentsSize())
partMsg, err := ftStorage.NewPartMessage(cmixMsg.ContentsSize())
if err != nil {
return 0, err
}
return partMsg.getPartSize(), nil
return partMsg.GetPartSize(), nil
}
// partitionFile splits the file into parts of the specified part size.
......
......@@ -662,13 +662,13 @@ func TestManager_newCmixMessage(t *testing.T) {
"\nexpected: %s\nrecieved: %s", fp, cmixMsg.GetKeyFP())
}
partMsg, err := unmarshalPartMessage(cmixMsg.GetContents())
partMsg, err := ftStorage.UnmarshalPartMessage(cmixMsg.GetContents())
if err != nil {
t.Errorf("Failed to unmarshal part message: %+v", err)
}
decrPart, err := ftCrypto.DecryptPart(key, partMsg.getPart(),
partMsg.getPadding(), cmixMsg.GetMac(), partMsg.getPartNum())
decrPart, err := ftCrypto.DecryptPart(key, partMsg.GetPart(),
partMsg.getNonce(), cmixMsg.GetMac(), partMsg.GetPartNum())
if err != nil {
t.Errorf("Failed to decrypt file part: %+v", err)
}
......@@ -998,7 +998,7 @@ func Test_makeListOfPartNums(t *testing.T) {
}
}
// Tests that the part size returned by Manager.getPartSize matches the manually
// Tests that the part size returned by Manager.GetPartSize matches the manually
// calculated part size.
func TestManager_getPartSize(t *testing.T) {
m := newTestManager(false, nil, nil, nil, nil, t)
......@@ -1006,13 +1006,13 @@ func TestManager_getPartSize(t *testing.T) {
// Calculate the expected part size
primeByteLen := m.store.Cmix().GetGroup().GetP().ByteLen()
cmixMsgUsedLen := format.AssociatedDataSize
filePartMsgUsedLen := fmMinSize
filePartMsgUsedLen := ftStorage.fmMinSize
expected := 2*primeByteLen - cmixMsgUsedLen - filePartMsgUsedLen-1
// Get the part size
partSize, err := m.getPartSize()
if err != nil {
t.Errorf("getPartSize returned an error: %+v", err)
t.Errorf("GetPartSize returned an error: %+v", err)
}
if expected != partSize {
......
......@@ -20,7 +20,7 @@ require (
github.com/spf13/viper v1.7.1
gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228
gitlab.com/elixxir/comms v0.0.4-0.20220104174855-044783c5c1e6
gitlab.com/elixxir/crypto v0.0.7-0.20220104174238-dbd761b30553
gitlab.com/elixxir/crypto v0.0.7-0.20220108004933-8da1344a8e69
gitlab.com/elixxir/ekv v0.1.6
gitlab.com/elixxir/primitives v0.0.3-0.20220104173924-275cb9d7834f
gitlab.com/xx_network/comms v0.0.4-0.20211227194445-c099754b3cda
......
......@@ -277,6 +277,8 @@ gitlab.com/elixxir/crypto v0.0.3/go.mod h1:ZNgBOblhYToR4m8tj4cMvJ9UsJAUKq+p0gCp0
gitlab.com/elixxir/crypto v0.0.7-0.20211230230452-bca020488964/go.mod h1:fexaw14nwGMlT6vL9eIJ1ixgiomyAp88hSHl0Yx0/xU=
gitlab.com/elixxir/crypto v0.0.7-0.20220104174238-dbd761b30553 h1:BPwepGZspxgiY4QMUwVFMgVIEs8ziuMcT/uXmPQQ9Gs=
gitlab.com/elixxir/crypto v0.0.7-0.20220104174238-dbd761b30553/go.mod h1:fexaw14nwGMlT6vL9eIJ1ixgiomyAp88hSHl0Yx0/xU=
gitlab.com/elixxir/crypto v0.0.7-0.20220108004933-8da1344a8e69 h1:MweUKTjmKvTxWswRhgAyV5cGZubqzlLQ+thdOpUPG+c=
gitlab.com/elixxir/crypto v0.0.7-0.20220108004933-8da1344a8e69/go.mod h1:qmW0OGPB21GcaGg1Jvt527/qUw7ke6W8DKCiYBfsx48=
gitlab.com/elixxir/ekv v0.1.5 h1:R8M1PA5zRU1HVnTyrtwybdABh7gUJSCvt1JZwUSeTzk=
gitlab.com/elixxir/ekv v0.1.5/go.mod h1:e6WPUt97taFZe5PFLPb1Dupk7tqmDCTQu1kkstqJvw4=
gitlab.com/elixxir/ekv v0.1.6 h1:M2hUSNhH/ChxDd+s8xBqSEKgoPtmE6hOEBqQ73KbN6A=
......
......@@ -61,7 +61,7 @@ func handleConfirm(sess *storage.Session, confirmation message.Receive) {
confirmedSession := partner.GetSendSession(confimedSessionID)
if confirmedSession == nil {
jww.ERROR.Printf("[REKEY] Failed to find confirmed session %s from "+
"partner %s: %s", confimedSessionID, confirmation.Sender, err)
"partner %s", confimedSessionID, confirmation.Sender)
return
}
......
......@@ -10,14 +10,12 @@ package fileTransfer
import (
"encoding/binary"
"github.com/pkg/errors"
ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
)
// Size constants.
const (
paddingLen = ftCrypto.NonceSize // The length of the padding in bytes
partNumLen = 2 // The length of the part number in bytes
fmMinSize = partNumLen + paddingLen // Minimum size for the partMessage
fmMinSize = partNumLen // Minimum size for the PartMessage
)
// Error messages.
......@@ -36,85 +34,76 @@ const (
+---------+-------------+-----------------+
*/
// partMessage contains part of the data being transferred and 256-bit padding
// PartMessage contains part of the data being transferred and 256-bit nonce
// that is used as a nonce.
type partMessage struct {
type PartMessage struct {
data []byte // Serial of all contents
padding []byte // Random padding bytes
partNum []byte // The part number of the file
part []byte // File part data
}
// newPartMessage generates a new part message that fits into the specified
// NewPartMessage generates a new part message that fits into the specified
// external payload size. An error is returned if the external payload size is
// too small to fit the part message.
func newPartMessage(externalPayloadSize int) (partMessage, error) {
func NewPartMessage(externalPayloadSize int) (PartMessage, error) {
if externalPayloadSize < fmMinSize {
return partMessage{},
return PartMessage{},
errors.Errorf(newFmSizeErr, externalPayloadSize, fmMinSize)
}
return mapPartMessage(make([]byte, externalPayloadSize)), nil
return MapPartMessage(make([]byte, externalPayloadSize)), nil
}
// mapPartMessage maps the data to the components of a partMessage. It is mapped
// MapPartMessage maps the data to the components of a PartMessage. It is mapped
// by reference; a copy is not made.
func mapPartMessage(data []byte) partMessage {
return partMessage{
func MapPartMessage(data []byte) PartMessage {
return PartMessage{
data: data,
padding: data[:paddingLen],
partNum: data[paddingLen : paddingLen+partNumLen],
part: data[paddingLen+partNumLen:],
partNum: data[:partNumLen],
part: data[partNumLen:],
}
}
// unmarshalPartMessage converts the bytes into a partMessage. An error is
// returned if the size of the data is too small for a partMessage.
func unmarshalPartMessage(b []byte) (partMessage, error) {
// UnmarshalPartMessage converts the bytes into a PartMessage. An error is
// returned if the size of the data is too small for a PartMessage.
func UnmarshalPartMessage(b []byte) (PartMessage, error) {
if len(b) < fmMinSize {
return partMessage{},
return PartMessage{},
errors.Errorf(unmarshalFmSizeErr, len(b), fmMinSize)
}
return mapPartMessage(b), nil
return MapPartMessage(b), nil
}
// marshal returns the byte representation of the partMessage.
func (m partMessage) marshal() []byte {
return m.data
// Marshal returns the byte representation of the PartMessage.
func (m PartMessage) Marshal() []byte {
b := make([]byte, len(m.data))
copy(b,m.data)
return b
}
// getPadding returns the padding in the message.
func (m partMessage) getPadding() []byte {
return m.padding
}
// setPadding sets the partMessage padding to the given bytes. Note that this
// padding should be random bytes generated via the appropriate crypto function.
func (m partMessage) setPadding(b []byte) {
copy(m.padding, b)
}
// getPartNum returns the file part number.
func (m partMessage) getPartNum() uint16 {
// GetPartNum returns the file part number.
func (m PartMessage) GetPartNum() uint16 {
return binary.LittleEndian.Uint16(m.partNum)
}
// setPartNum sets the file part number.
func (m partMessage) setPartNum(num uint16) {
// SetPartNum sets the file part number.
func (m PartMessage) SetPartNum(num uint16) {
b := make([]byte, partNumLen)
binary.LittleEndian.PutUint16(b, num)
copy(m.partNum, b)
}
// getPart returns the file part data from the message.
func (m partMessage) getPart() []byte {
return m.part
// GetPart returns the file part data from the message.
func (m PartMessage) GetPart() []byte {
b := make([]byte, len(m.part))
copy(b,m.part)
return b
}
// setPart sets the partMessage part to the given bytes. An error is returned if
// SetPart sets the PartMessage part to the given bytes. An error is returned if
// the size of the provided part data is too large to store.
func (m partMessage) setPart(b []byte) error {
func (m PartMessage) SetPart(b []byte) error {
if len(b) > len(m.part) {
return errors.Errorf(setFileFmErr, len(b), len(m.part))
}
......@@ -124,7 +113,7 @@ func (m partMessage) setPart(b []byte) error {
return nil
}
// getPartSize returns the number of bytes available to store part data.
func (m partMessage) getPartSize() int {
// GetPartSize returns the number of bytes available to store part data.
func (m PartMessage) GetPartSize() int {
return len(m.part)
}
......@@ -15,54 +15,49 @@ import (
"testing"
)
// Tests that newPartMessage returns a partMessage of the expected size.
// Tests that NewPartMessage returns a PartMessage of the expected size.
func Test_newPartMessage(t *testing.T) {
externalPayloadSize := 256
fm, err := newPartMessage(externalPayloadSize)
fm, err := NewPartMessage(externalPayloadSize)
if err != nil {
t.Errorf("newPartMessage returned an error: %+v", err)
t.Errorf("NewPartMessage returned an error: %+v", err)
}
if len(fm.data) != externalPayloadSize {
t.Errorf("Size of partMessage data does not match payload size."+
t.Errorf("Size of PartMessage data does not match payload size."+
"\nexpected: %d\nreceived: %d", externalPayloadSize, len(fm.data))
}
}
// Error path: tests that newPartMessage returns the expected error when the
// Error path: tests that NewPartMessage returns the expected error when the
// external payload size is too small.
func Test_newPartMessage_SmallPayloadSizeError(t *testing.T) {
externalPayloadSize := fmMinSize - 1
expectedErr := fmt.Sprintf(newFmSizeErr, externalPayloadSize, fmMinSize)
_, err := newPartMessage(externalPayloadSize)
_, err := NewPartMessage(externalPayloadSize)
if err == nil || err.Error() != expectedErr {
t.Errorf("newPartMessage did not return the expected error when the "+
t.Errorf("NewPartMessage did not return the expected error when the "+
"given external payload size is too small."+
"\nexpected: %s\nreceived: %+v", expectedErr, err)
}
}
// Tests that mapPartMessage maps the data to the correct parts of the
// partMessage.
// Tests that MapPartMessage maps the data to the correct parts of the
// PartMessage.
func Test_mapPartMessage(t *testing.T) {
// Generate expected values
_, expectedData, expectedPadding, expectedPartNum, expectedFile :=
_, expectedData, expectedPartNum, expectedFile :=
newRandomFileMessage()
fm := mapPartMessage(expectedData)
fm := MapPartMessage(expectedData)
if !bytes.Equal(expectedData, fm.data) {
t.Errorf("Incorrect data.\nexpected: %q\nreceived: %q",
expectedData, fm.data)
}
if !bytes.Equal(expectedPadding, fm.padding) {
t.Errorf("Incorrect padding data.\nexpected: %q\nreceived: %q",
expectedPadding, fm.padding)
}
if !bytes.Equal(expectedPartNum, fm.partNum) {
t.Errorf("Incorrect part number.\nexpected: %q\nreceived: %q",
expectedPartNum, fm.partNum)
......@@ -75,16 +70,16 @@ func Test_mapPartMessage(t *testing.T) {
}
// Tests that unmarshalPartMessage returns a partMessage with the expected
// Tests that UnmarshalPartMessage returns a PartMessage with the expected
// values.
func Test_unmarshalPartMessage(t *testing.T) {
// Generate expected values
_, expectedData, expectedPadding, expectedPartNumb, expectedFile :=
_, expectedData, expectedPartNumb, expectedFile :=
newRandomFileMessage()
fm, err := unmarshalPartMessage(expectedData)
fm, err := UnmarshalPartMessage(expectedData)
if err != nil {
t.Errorf("unmarshalPartMessage return an error: %+v", err)
t.Errorf("UnmarshalPartMessage return an error: %+v", err)
}
if !bytes.Equal(expectedData, fm.data) {
......@@ -92,11 +87,6 @@ func Test_unmarshalPartMessage(t *testing.T) {
expectedData, fm.data)
}
if !bytes.Equal(expectedPadding, fm.padding) {
t.Errorf("Incorrect padding data.\nexpected: %q\nreceived: %q",
expectedPadding, fm.padding)
}
if !bytes.Equal(expectedPartNumb, fm.partNum) {
t.Errorf("Incorrect part number.\nexpected: %q\nreceived: %q",
expectedPartNumb, fm.partNum)
......@@ -108,25 +98,25 @@ func Test_unmarshalPartMessage(t *testing.T) {
}
}
// Error path: tests that unmarshalPartMessage returns the expected error when
// the provided data is too small to be unmarshalled into a partMessage.
// Error path: tests that UnmarshalPartMessage returns the expected error when
// the provided data is too small to be unmarshalled into a PartMessage.
func Test_unmarshalPartMessage_SizeError(t *testing.T) {
data := make([]byte, fmMinSize-1)
expectedErr := fmt.Sprintf(unmarshalFmSizeErr, len(data), fmMinSize)
_, err := unmarshalPartMessage(data)
_, err := UnmarshalPartMessage(data)
if err == nil || err.Error() != expectedErr {
t.Errorf("unmarshalPartMessage did not return the expected error when "+
"the given bytes are too small to be a partMessage."+
t.Errorf("UnmarshalPartMessage did not return the expected error when "+
"the given bytes are too small to be a PartMessage."+
"\nexpected: %s\nreceived: %+v", expectedErr, err)
}
}
// Tests that partMessage.marshal returns the correct data.
// Tests that PartMessage.Marshal returns the correct data.
func Test_fileMessage_marshal(t *testing.T) {
fm, expectedData, _, _, _ := newRandomFileMessage()
fm, expectedData, _, _ := newRandomFileMessage()
data := fm.marshal()
data := fm.Marshal()
if !bytes.Equal(expectedData, data) {
t.Errorf("Marshalled data does not match expected."+
......@@ -134,41 +124,11 @@ func Test_fileMessage_marshal(t *testing.T) {
}
}
// Tests that partMessage.getPadding returns the correct padding data.
func Test_fileMessage_getPadding(t *testing.T) {
fm, _, expectedPadding, _, _ := newRandomFileMessage()
padding := fm.getPadding()
if !bytes.Equal(expectedPadding, padding) {
t.Errorf("Padding data does not match expected."+
"\nexpected: %q\nreceived: %q", expectedPadding, padding)
}
}
// Tests that partMessage.setPadding sets the correct data.
func Test_fileMessage_setPadding(t *testing.T) {
fm, err := newPartMessage(256)
if err != nil {
t.Errorf("Failed to create new partMessage: %+v", err)
}
expectedPadding := make([]byte, paddingLen)
rand.New(rand.NewSource(42)).Read(expectedPadding)
fm.setPadding(expectedPadding)
if !bytes.Equal(expectedPadding, fm.getPadding()) {
t.Errorf("Failed to set correct padding.\nexpected: %q\nreceived: %q",
expectedPadding, fm.getPadding())
}
}
// Tests that partMessage.getPartNum returns the correct part number.
// Tests that PartMessage.GetPartNum returns the correct part number.
func Test_fileMessage_getPartNum(t *testing.T) {
fm, _, _, expectedPartNum, _ := newRandomFileMessage()
fm, _, expectedPartNum, _ := newRandomFileMessage()
partNum := fm.getPartNum()
partNum := fm.GetPartNum()
expected := binary.LittleEndian.Uint16(expectedPartNum)
if expected != partNum {
......@@ -177,30 +137,30 @@ func Test_fileMessage_getPartNum(t *testing.T) {
}
}
// Tests that partMessage.setPartNum sets the correct part number.
// Tests that PartMessage.SetPartNum sets the correct part number.
func Test_fileMessage_setPartNum(t *testing.T) {
fm, err := newPartMessage(256)
fm, err := NewPartMessage(256)
if err != nil {
t.Errorf("Failed to create new partMessage: %+v", err)
t.Errorf("Failed to create new PartMessage: %+v", err)
}
expectedPartNum := make([]byte, partNumLen)
rand.New(rand.NewSource(42)).Read(expectedPartNum)
expected := binary.LittleEndian.Uint16(expectedPartNum)
fm.setPartNum(expected)
fm.SetPartNum(expected)
if expected != fm.getPartNum() {
if expected != fm.GetPartNum() {
t.Errorf("Failed to set correct part number.\nexpected: %d\nreceived: %d",
expected, fm.getPartNum())
expected, fm.GetPartNum())
}
}
// Tests that partMessage.getPart returns the correct part data.
// Tests that PartMessage.GetPart returns the correct part data.
func Test_fileMessage_getFile(t *testing.T) {
fm, _, _, _, expectedFile := newRandomFileMessage()
fm, _, _, expectedFile := newRandomFileMessage()
file := fm.getPart()
file := fm.GetPart()
if !bytes.Equal(expectedFile, file) {
t.Errorf("File data does not match expected."+
......@@ -208,76 +168,74 @@ func Test_fileMessage_getFile(t *testing.T) {
}
}
// Tests that partMessage.setPart sets the correct part data.
// Tests that PartMessage.SetPart sets the correct part data.
func Test_fileMessage_setFile(t *testing.T) {
fm, err := newPartMessage(256)
fm, err := NewPartMessage(256)
if err != nil {
t.Errorf("Failed to create new partMessage: %+v", err)
t.Errorf("Failed to create new PartMessage: %+v", err)
}
fileData := make([]byte, 64)
rand.New(rand.NewSource(42)).Read(fileData)
expectedFile := make([]byte, fm.getPartSize())
expectedFile := make([]byte, fm.GetPartSize())
copy(expectedFile, fileData)
err = fm.setPart(expectedFile)
err = fm.SetPart(expectedFile)
if err != nil {
t.Errorf("setPart returned an error: %+v", err)
t.Errorf("SetPart returned an error: %+v", err)
}
if !bytes.Equal(expectedFile, fm.getPart()) {
if !bytes.Equal(expectedFile, fm.GetPart()) {
t.Errorf("Failed to set correct part data.\nexpected: %q\nreceived: %q",
expectedFile, fm.getPart())
expectedFile, fm.GetPart())
}
}
// Error path: tests that partMessage.setPart returns the expected error when
// Error path: tests that PartMessage.SetPart returns the expected error when
// the provided part data is too large for the message.
func Test_fileMessage_setFile_FileTooLargeError(t *testing.T) {
fm, err := newPartMessage(fmMinSize + 1)
fm, err := NewPartMessage(fmMinSize + 1)
if err != nil {
t.Errorf("Failed to create new partMessage: %+v", err)
t.Errorf("Failed to create new PartMessage: %+v", err)
}
expectedErr := fmt.Sprintf(setFileFmErr, fm.getPartSize()+1, fm.getPartSize())
expectedErr := fmt.Sprintf(setFileFmErr, fm.GetPartSize()+1, fm.GetPartSize())
err = fm.setPart(make([]byte, fm.getPartSize()+1))
err = fm.SetPart(make([]byte, fm.GetPartSize()+1))
if err == nil || err.Error() != expectedErr {
t.Errorf("setPart did not return the expected error when the given "+
"part data is too large to fit in the partMessage."+
t.Errorf("SetPart did not return the expected error when the given "+
"part data is too large to fit in the PartMessage."+
"\nexpected: %s\nreceived: %+v", expectedErr, err)
}
}
// Tests that partMessage.getPartSize returns the expected available space for
// Tests that PartMessage.GetPartSize returns the expected available space for
// the part data.
func Test_fileMessage_getFileSize(t *testing.T) {
expectedSize := 256
fm, err := newPartMessage(fmMinSize + expectedSize)
fm, err := NewPartMessage(fmMinSize + expectedSize)
if err != nil {
t.Errorf("Failed to create new partMessage: %+v", err)
t.Errorf("Failed to create new PartMessage: %+v", err)
}
if expectedSize != fm.getPartSize() {
if expectedSize != fm.GetPartSize() {
t.Errorf("File size incorrect.\nexpected: %d\nreceived: %d",
expectedSize, fm.getPartSize())
expectedSize, fm.GetPartSize())
}
}
// newRandomFileMessage generates a new partMessage filled with random data and
// return the partMessage and its individual parts.
func newRandomFileMessage() (partMessage, []byte, []byte, []byte, []byte) {
// newRandomFileMessage generates a new PartMessage filled with random data and
// return the PartMessage and its individual parts.
func newRandomFileMessage() (PartMessage, []byte, []byte, []byte) {
prng := rand.New(rand.NewSource(42))
padding := make([]byte, paddingLen)
prng.Read(padding)
partNum := make([]byte, partNumLen)
prng.Read(partNum)
part := make([]byte, 64)
prng.Read(part)
data := append(append(padding, partNum...), part...)
data := append(partNum, part...)
fm := mapPartMessage(data)
fm := MapPartMessage(data)
return fm, data, padding, partNum, part
return fm, data, partNum, part
}
......@@ -176,17 +176,18 @@ func (rft *ReceivedFileTransfersStore) DeleteTransfer(tid ftCrypto.TransferID) e
// transfer that the part was added to so that a progress callback can be
// called. Returns the transfer ID so that it can be used for logging. Also
// returns of the transfer is complete after adding the part.
func (rft *ReceivedFileTransfersStore) AddPart(encryptedPart, padding,
mac []byte, partNum uint16, fp format.Fingerprint) (*ReceivedTransfer,
func (rft *ReceivedFileTransfersStore) AddPart(cmixMsg format.Message) (*ReceivedTransfer,
ftCrypto.TransferID, bool, error) {
rft.mux.Lock()
defer rft.mux.Unlock()
keyfp := cmixMsg.GetKeyFP()
// Lookup the part info for the given fingerprint
info, exists := rft.info[fp]
info, exists := rft.info[cmixMsg.GetKeyFP()]
if !exists {
return nil, ftCrypto.TransferID{}, false,
errors.Errorf(noFingerprintErr, fp)
errors.Errorf(noFingerprintErr, keyfp)
}
// Lookup the transfer with the ID in the part info
......@@ -197,15 +198,14 @@ func (rft *ReceivedFileTransfersStore) AddPart(encryptedPart, padding,
}
// Add the part to the transfer
completed, err := transfer.AddPart(
encryptedPart, padding, mac, partNum, info.fpNum)
completed, err := transfer.AddPart(cmixMsg, info.fpNum)
if err != nil {
return transfer, info.id, false, errors.Errorf(
addPartErr, partNum, transfer.numParts, info.id, err)
addPartErr, transfer.numParts, info.id, err)
}
// Remove the part info from the map
delete(rft.info, fp)
delete(rft.info, keyfp)
return transfer, info.id, completed, nil
}
......
......@@ -391,9 +391,12 @@ func TestReceivedFileTransfersStore_AddPart_NoFingerprintError(t *testing.T) {
// Create encrypted part
fp := format.NewFingerprint([]byte("invalidTransferKey"))
msg := format.NewMessage(1000)
msg.SetKeyFP(fp)
// Add encrypted part
expectedErr := fmt.Sprintf(noFingerprintErr, fp)
_, _, _, err = rft.AddPart([]byte{}, []byte{}, []byte{}, 0, fp)
_, _, _, err = rft.AddPart(msg)
if err == nil || err.Error() != expectedErr {
t.Errorf("AddPart did not return the expected error when no part for "+
"the fingerprint exists.\nexpected: %s\nreceived: %+v",
......@@ -425,9 +428,12 @@ func TestReceivedFileTransfersStore_AddPart_NoTransferError(t *testing.T) {
invalidTid, _ := ftCrypto.NewTransferID(prng)
rft.info[fp].id = invalidTid
msg := format.NewMessage(1000)
msg.SetKeyFP(fp)
// Add encrypted part
expectedErr := fmt.Sprintf(getReceivedTransferErr, invalidTid)
_, _, _, err = rft.AddPart([]byte{}, []byte{}, []byte{}, 0, fp)
_, _, _, err = rft.AddPart(msg)
if err == nil || err.Error() != expectedErr {
t.Errorf("AddPart did not return the expected error when no transfer "+
"for the ID exists.\nexpected: %s\nreceived: %+v", expectedErr, err)
......
......@@ -16,6 +16,7 @@ import (
"gitlab.com/elixxir/client/storage/utility"
"gitlab.com/elixxir/client/storage/versioned"
ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
"gitlab.com/elixxir/primitives/format"
"gitlab.com/xx_network/primitives/netTime"
"sync"
"time"
......@@ -276,20 +277,25 @@ func (rt *ReceivedTransfer) AddProgressCB(
// AddPart decrypts an encrypted file part, adds it to the list of received
// parts and marks its fingerprint as used. Returns true if the part added was
// the last in the transfer.
func (rt *ReceivedTransfer) AddPart(encryptedPart, padding, mac []byte, partNum,
func (rt *ReceivedTransfer) AddPart(cmixMsg format.Message,
fpNum uint16) (bool, error) {
rt.mux.Lock()
defer rt.mux.Unlock()
// Decrypt the encrypted file part
decryptedPart, err := ftCrypto.DecryptPart(
rt.key, encryptedPart, padding, mac, fpNum)
decryptedPart, err := ftCrypto.DecryptPart(rt.key,
cmixMsg.GetContents(), cmixMsg.GetMac(), fpNum, cmixMsg.GetKeyFP())
if err != nil {
return false, err
}
part, err := UnmarshalPartMessage(decryptedPart)
if err != nil {
return false, err
}
// Add the part to the list of parts
err = rt.receivedParts.addPart(decryptedPart, partNum)
err = rt.receivedParts.addPart(part.GetPart(), part.GetPartNum())
if err != nil {
return false, err
}
......@@ -298,7 +304,7 @@ func (rt *ReceivedTransfer) AddPart(encryptedPart, padding, mac []byte, partNum,
rt.fpVector.Use(uint32(fpNum))
// Mark part as received
rt.receivedStatus.Use(uint32(partNum))
rt.receivedStatus.Use(uint32(part.GetPartNum()))
if rt.receivedStatus.GetNumUsed() >= uint32(rt.numParts) {
return true, nil
......
......@@ -17,7 +17,6 @@ import (
"gitlab.com/elixxir/client/storage/versioned"
ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
"gitlab.com/elixxir/primitives/format"
"gitlab.com/xx_network/crypto/csprng"
"gitlab.com/xx_network/primitives/id"
"gitlab.com/xx_network/primitives/netTime"
"sync"
......@@ -427,31 +426,44 @@ func (st *SentTransfer) AddProgressCB(cb interfaces.SentProgressCallback,
// GetEncryptedPart gets the specified part, encrypts it, and returns the
// encrypted part along with its MAC, padding, and fingerprint.
func (st *SentTransfer) GetEncryptedPart(partNum uint16, partSize int,
rng csprng.Source) (encPart, mac, padding []byte, fp format.Fingerprint,
err error) {
func (st *SentTransfer) GetEncryptedPart(partNum uint16, contentsSize int) (encPart, mac []byte,
fp format.Fingerprint, err error) {
st.mux.Lock()
defer st.mux.Unlock()
// Create new empty file part message of size equal to the available payload
// size in the cMix message
partMsg, err := NewPartMessage(contentsSize)
if err != nil {
return nil, nil, format.Fingerprint{}, err
}
partMsg.SetPartNum(partNum)
// Lookup part
part, exists := st.sentParts.getPart(partNum)
if !exists {
return nil, nil, nil, format.Fingerprint{},
return nil, nil, format.Fingerprint{},
errors.Errorf(noPartNumErr, partNum)
}
if err = partMsg.SetPart(part); err != nil{
return nil, nil, format.Fingerprint{},
err
}
// If all fingerprints have been used but parts still remain, then change
// the status to stopping and return an error specifying that all the
// retries have been used
if st.fpVector.GetNumAvailable() < 1 {
st.status = Stopping
return nil, nil, nil, format.Fingerprint{}, MaxRetriesErr
return nil, nil, format.Fingerprint{}, MaxRetriesErr
}
// Get next unused fingerprint number and mark it as used
nextKey, err := st.fpVector.Next()
if err != nil {
return nil, nil, nil, format.Fingerprint{},
return nil, nil, format.Fingerprint{},
errors.Errorf(fingerprintErr, err)
}
fpNum := uint16(nextKey)
......@@ -460,16 +472,13 @@ func (st *SentTransfer) GetEncryptedPart(partNum uint16, partSize int,
fp = ftCrypto.GenerateFingerprint(st.key, fpNum)
// Encrypt the file part and generate the file part MAC and padding (nonce)
maxLengthPart := make([]byte, partSize)
copy(maxLengthPart, part)
encPart, mac, padding, err = ftCrypto.EncryptPart(
st.key, maxLengthPart, fpNum, rng)
encPart, mac, err = ftCrypto.EncryptPart(st.key, partMsg.Marshal(), fpNum, fp)
if err != nil {
return nil, nil, nil, format.Fingerprint{},
return nil, nil, format.Fingerprint{},
errors.Errorf(encryptPartErr, partNum, err)
}
return encPart, mac, padding, fp, err
return encPart, mac, fp, err
}
// SetInProgress adds the specified file part numbers to the in-progress
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment