diff --git a/crypto/decrypt.go b/crypto/decrypt.go deleted file mode 100644 index 9004d5aa028585d9ff05dd7894f6d9d80041ea32..0000000000000000000000000000000000000000 --- a/crypto/decrypt.go +++ /dev/null @@ -1,77 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright © 2019 Privategrity Corporation / -// / -// All rights reserved. / -//////////////////////////////////////////////////////////////////////////////// - -package crypto - -import ( - "github.com/pkg/errors" - "gitlab.com/elixxir/crypto/cyclic" - "gitlab.com/elixxir/crypto/e2e" - "gitlab.com/elixxir/crypto/hash" - "gitlab.com/elixxir/primitives/format" -) - -// E2EDecrypt uses the E2E key to decrypt the message -// It returns an error in case of HMAC verification failure -// or in case of a decryption error (related to padding) -// If it succeeds, it modifies the passed message -func E2EDecrypt(grp *cyclic.Group, key *cyclic.Int, - msg *format.Message) error { - // First thing to do is check MAC - if !hash.VerifyHMAC(msg.Contents.Get(), msg.GetMAC(), key.Bytes()) { - return errors.New("HMAC verification failed for E2E message") - } - var iv [e2e.AESBlockSize]byte - fp := msg.GetKeyFP() - copy(iv[:], fp[:e2e.AESBlockSize]) - // decrypt the timestamp in the associated data - decryptedTimestamp, err := e2e.DecryptAES256WithIV( - key.Bytes(), iv, msg.GetTimestamp()) - if err != nil { - return errors.New("Timestamp decryption failed for E2E message: " + err.Error()) - } - // TODO deserialize this somewhere along the line and provide methods - // to mobile developers on the bindings to interact with the timestamps - decryptedTimestamp = append(decryptedTimestamp, 0) - msg.SetTimestamp(decryptedTimestamp) - // Decrypt e2e - decryptedPayload, err := e2e.Decrypt(grp, key, msg.Contents.Get()) - - if err != nil { - return errors.New("Failed to decrypt E2E message: " + err.Error()) - } - msg.Contents.SetRightAligned(decryptedPayload) - return nil -} - -// E2EDecryptUnsafe uses the E2E key to decrypt the message -// It returns an error in case of HMAC verification failure -// It doesn't expect the payload to be padded -// If it succeeds, it modifies the passed message -func E2EDecryptUnsafe(grp *cyclic.Group, key *cyclic.Int, - msg *format.Message) error { - // First thing to do is check MAC - if !hash.VerifyHMAC(msg.Contents.Get(), msg.GetMAC(), key.Bytes()) { - return errors.New("HMAC verification failed for E2E message") - } - var iv [e2e.AESBlockSize]byte - fp := msg.GetKeyFP() - copy(iv[:], fp[:e2e.AESBlockSize]) - // decrypt the timestamp in the associated data - decryptedTimestamp, err := e2e.DecryptAES256WithIV( - key.Bytes(), iv, msg.GetTimestamp()) - if err != nil { - return errors.New("Timestamp decryption failed for E2E message: " + err.Error()) - } - // TODO deserialize this somewhere along the line and provide methods - // to mobile developers on the bindings to interact with the timestamps - decryptedTimestamp = append(decryptedTimestamp, 0) - msg.SetTimestamp(decryptedTimestamp) - // Decrypt e2e - decryptedPayload := e2e.DecryptUnsafe(grp, key, msg.Contents.Get()) - msg.Contents.Set(decryptedPayload) - return nil -} diff --git a/crypto/encrypt.go b/crypto/encrypt.go deleted file mode 100644 index 7686521401474733e45bc47b508e90501d4ef8ea..0000000000000000000000000000000000000000 --- a/crypto/encrypt.go +++ /dev/null @@ -1,112 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright © 2019 Privategrity Corporation / -// / -// All rights reserved. / -//////////////////////////////////////////////////////////////////////////////// - -package crypto - -import ( - "gitlab.com/elixxir/client/globals" - "gitlab.com/elixxir/client/user" - "gitlab.com/elixxir/crypto/cmix" - "gitlab.com/elixxir/crypto/cyclic" - "gitlab.com/elixxir/crypto/e2e" - "gitlab.com/elixxir/crypto/hash" - "gitlab.com/elixxir/primitives/format" - "gitlab.com/xx_network/comms/connect" -) - -// CMIX Encrypt performs the encryption -// of the msg to a team of nodes -// It returns a new msg -func CMIXEncrypt(session user.Session, topology *connect.Circuit, salt []byte, - msg *format.Message) (*format.Message, [][]byte) { - // Generate the encryption key - nodeKeys := session.GetNodeKeys(topology) - - baseKeys := make([]*cyclic.Int, len(nodeKeys)) - for i, key := range nodeKeys { - baseKeys[i] = key.TransmissionKey - } - - ecrMsg := cmix.ClientEncrypt(session.GetCmixGroup(), msg, salt, baseKeys) - - h, err := hash.NewCMixHash() - if err != nil { - globals.Log.ERROR.Printf("Cound not get hash for KMAC generation: %+v", h) - } - - KMAC := cmix.GenerateKMACs(salt, baseKeys, h) - - return ecrMsg, KMAC -} - -// E2EEncrypt uses the E2E key to encrypt msg -// to its intended recipient -// It also properly populates the associated data -// It modifies the passed msg instead of returning a new one -func E2EEncrypt(grp *cyclic.Group, - key *cyclic.Int, keyFP format.Fingerprint, - msg *format.Message) { - msg.SetKeyFP(keyFP) - - // Encrypt the timestamp using key - // Timestamp bytes were previously stored - // and GO only uses 15 bytes, so use those - var iv [e2e.AESBlockSize]byte - copy(iv[:], keyFP[:e2e.AESBlockSize]) - encryptedTimestamp, err := - e2e.EncryptAES256WithIV(key.Bytes(), iv, - msg.GetTimestamp()[:15]) - if err != nil { - panic(err) - } - msg.SetTimestamp(encryptedTimestamp) - - // E2E encrypt the msg - encPayload, err := e2e.Encrypt(grp, key, msg.Contents.GetRightAligned()) - if err != nil { - globals.Log.ERROR.Panicf(err.Error()) - } - msg.Contents.Set(encPayload) - - // MAC is HMAC(key, ciphertext) - // Currently, the MAC doesn't include any of the associated data - MAC := hash.CreateHMAC(encPayload, key.Bytes()) - msg.SetMAC(MAC) -} - -// E2EEncryptUnsafe uses the E2E key to encrypt msg -// to its intended recipient -// It doesn't apply padding to the payload, so it can be unsafe -// if the payload is small -// It also properly populates the associated data -// It modifies the passed msg instead of returning a new one -func E2EEncryptUnsafe(grp *cyclic.Group, - key *cyclic.Int, keyFP format.Fingerprint, - msg *format.Message) { - msg.SetKeyFP(keyFP) - - // Encrypt the timestamp using key - // Timestamp bytes were previously stored - // and GO only uses 15 bytes, so use those - var iv [e2e.AESBlockSize]byte - copy(iv[:], keyFP[:e2e.AESBlockSize]) - encryptedTimestamp, err := - e2e.EncryptAES256WithIV(key.Bytes(), iv, - msg.GetTimestamp()[:15]) - if err != nil { - panic(err) - } - msg.SetTimestamp(encryptedTimestamp) - - // E2E encrypt the msg - encPayload := e2e.EncryptUnsafe(grp, key, msg.Contents.Get()) - msg.Contents.Set(encPayload) - - // MAC is HMAC(key, ciphertext) - // Currently, the MAC doesn't include any of the associated data - MAC := hash.CreateHMAC(encPayload, key.Bytes()) - msg.SetMAC(MAC) -} diff --git a/crypto/encryptdecrypt_test.go b/crypto/encryptdecrypt_test.go deleted file mode 100644 index 3e7d30506a5504abee1f285806fb9eda01d7192b..0000000000000000000000000000000000000000 --- a/crypto/encryptdecrypt_test.go +++ /dev/null @@ -1,398 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright © 2019 Privategrity Corporation / -// / -// All rights reserved. / -//////////////////////////////////////////////////////////////////////////////// - -package crypto - -import ( - "bytes" - "encoding/binary" - "gitlab.com/elixxir/client/user" - pb "gitlab.com/elixxir/comms/mixmessages" - "gitlab.com/elixxir/crypto/cmix" - "gitlab.com/elixxir/crypto/cyclic" - "gitlab.com/elixxir/crypto/hash" - "gitlab.com/elixxir/crypto/large" - "gitlab.com/elixxir/primitives/format" - "gitlab.com/xx_network/comms/connect" - "gitlab.com/xx_network/primitives/id" - "golang.org/x/crypto/blake2b" - "os" - "testing" - "time" -) - -const numNodes = 5 - -var salt = []byte( - "fdecfa52a8ad1688dbfa7d16df74ebf27e535903c469cefc007ebbe1ee895064") - -var session user.Session -var serverPayloadAKey *cyclic.Int -var serverPayloadBKey *cyclic.Int - -var topology *connect.Circuit - -func setup() { - - cmixGrp, e2eGrp := getGroups() - - user.InitUserRegistry(cmixGrp) - - UID := new(id.ID) - binary.BigEndian.PutUint64(UID[:], 18) - UID.SetType(id.User) - u, ok := user.Users.GetUser(UID) - if !ok { - panic("Didn't get user 18 from registry") - } - - var nodeSlice []*id.ID - - //build topology - for i := 0; i < numNodes; i++ { - nodeId := new(id.ID) - nodeId[0] = byte(i) - nodeId.SetType(id.Node) - nodeSlice = append(nodeSlice, nodeId) - } - - topology = connect.NewCircuit(nodeSlice) - - tempKey := cmixGrp.NewInt(1) - serverPayloadAKey = cmixGrp.NewInt(1) - serverPayloadBKey = cmixGrp.NewInt(1) - - h, _ := blake2b.New256(nil) - - session = user.NewSession(nil, u, nil, nil, - nil, nil, nil, - nil, nil, cmixGrp, e2eGrp, "password") - - for i := 0; i < numNodes; i++ { - - nk := user.NodeKeys{} - - h.Reset() - h.Write(salt) - - nk.TransmissionKey = cmixGrp.NewInt(int64(2 + i)) - cmix.NodeKeyGen(cmixGrp, salt, nk.TransmissionKey, tempKey) - cmixGrp.Mul(serverPayloadAKey, tempKey, serverPayloadAKey) - - cmix.NodeKeyGen(cmixGrp, h.Sum(nil), nk.TransmissionKey, tempKey) - cmixGrp.Mul(serverPayloadBKey, tempKey, serverPayloadBKey) - - session.PushNodeKey(topology.GetNodeAtIndex(i), nk) - - } - -} - -func TestMain(m *testing.M) { - setup() - os.Exit(m.Run()) -} - -func TestFullEncryptDecrypt(t *testing.T) { - cmixGrp, e2eGrp := getGroups() - - sender := id.NewIdFromUInt(38, id.User, t) - recipient := id.NewIdFromUInt(29, id.User, t) - msg := format.NewMessage() - msg.SetRecipient(recipient) - msgPayload := []byte("help me, i'm stuck in an" + - " EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory") - // Normally, msgPayload would be the right length due to padding - //msgPayload = append(msgPayload, make([]byte, - // format.ContentsLen-len(msgPayload)-format.PadMinLen)...) - msg.Contents.SetRightAligned(msgPayload) - now := time.Now() - nowBytes, _ := now.MarshalBinary() - // Normally, nowBytes would be the right length due to AES encryption - nowBytes = append(nowBytes, make([]byte, format.TimestampLen-len(nowBytes))...) - msg.SetTimestamp(nowBytes) - - key := e2eGrp.NewInt(42) - h, _ := hash.NewCMixHash() - h.Write(key.Bytes()) - fp := format.Fingerprint{} - copy(fp[:], h.Sum(nil)) - - // E2E Encryption - E2EEncrypt(e2eGrp, key, fp, msg) - - // CMIX Encryption - encMsg, _ := CMIXEncrypt(session, topology, salt, msg) - - // Server will decrypt payload (which is OK because the payload is now e2e) - // This block imitates what the server does during the realtime - payloadA := cmixGrp.NewIntFromBytes(encMsg.GetPayloadA()) - payloadB := cmixGrp.NewIntFromBytes(encMsg.GetPayloadB()) - // Multiply payloadA and associated data by serverPayloadBkey - cmixGrp.Mul(payloadA, serverPayloadAKey, payloadA) - // Multiply payloadB data only by serverPayloadAkey - cmixGrp.Mul(payloadB, serverPayloadBKey, payloadB) - - decMsg := format.NewMessage() - decMsg.SetPayloadA(payloadA.LeftpadBytes(uint64(format.PayloadLen))) - decMsg.SetDecryptedPayloadB(payloadB.LeftpadBytes(uint64(format.PayloadLen))) - - // E2E Decryption - err := E2EDecrypt(e2eGrp, key, decMsg) - - if err != nil { - t.Errorf("E2EDecrypt returned error: %v", err.Error()) - } - - decryptedRecipient, err := decMsg.GetRecipient() - if err != nil { - t.Fatal(err) - } - - if !decryptedRecipient.Cmp(recipient) { - t.Errorf("Recipient differed from expected: Got %q, expected %q", - decryptedRecipient, sender) - } - if !bytes.Equal(decMsg.Contents.GetRightAligned(), msgPayload) { - t.Errorf("Decrypted payload differed from expected: Got %q, "+ - "expected %q", decMsg.Contents.Get(), msgPayload) - } -} - -// E2E unsafe functions should only be used when the payload -// to be sent occupies the whole payload structure, i.e. 256 bytes -func TestFullEncryptDecrypt_Unsafe(t *testing.T) { - cmixGrp, e2eGrp := getGroups() - sender := id.NewIdFromUInt(38, id.User, t) - recipient := id.NewIdFromUInt(29, id.User, t) - msg := format.NewMessage() - msg.SetRecipient(recipient) - msgPayload := []byte( - " EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory" + - " EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory" + - " EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory" + - " EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory" + - " EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory" + - " EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory" + - " EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory") - msg.Contents.Set(msgPayload[:format.ContentsLen]) - - msg.SetTimestamp(make([]byte, 16)) - - key := e2eGrp.NewInt(42) - h, _ := hash.NewCMixHash() - h.Write(key.Bytes()) - fp := format.Fingerprint{} - copy(fp[:], h.Sum(nil)) - - // E2E Encryption without padding - E2EEncryptUnsafe(e2eGrp, key, fp, msg) - - // CMIX Encryption - encMsg, _ := CMIXEncrypt(session, topology, salt, msg) - - // Server will decrypt payload (which is OK because the payload is now e2e) - // This block imitates what the server does during the realtime - var encryptedNet *pb.Slot - { - payload := cmixGrp.NewIntFromBytes(encMsg.GetPayloadA()) - assocData := cmixGrp.NewIntFromBytes(encMsg.GetPayloadB()) - // Multiply payload and associated data by transmission key only - cmixGrp.Mul(payload, serverPayloadAKey, payload) - // Multiply associated data only by transmission key - cmixGrp.Mul(assocData, serverPayloadBKey, assocData) - encryptedNet = &pb.Slot{ - SenderID: sender.Bytes(), - Salt: salt, - PayloadA: payload.LeftpadBytes(uint64(format.PayloadLen)), - PayloadB: assocData.LeftpadBytes(uint64(format.PayloadLen)), - } - } - - decMsg := format.NewMessage() - decMsg.SetPayloadA(encryptedNet.PayloadA) - decMsg.SetDecryptedPayloadB(encryptedNet.PayloadB) - - // E2E Decryption - err := E2EDecryptUnsafe(e2eGrp, key, decMsg) - - if err != nil { - t.Errorf("E2EDecryptUnsafe returned error: %v", err.Error()) - } - - decryptedRecipient, err := decMsg.GetRecipient() - if err != nil { - t.Fatal(err) - } - - if !decryptedRecipient.Cmp(recipient) { - t.Errorf("Recipient differed from expected: Got %q, expected %q", - decryptedRecipient, sender) - } - if !bytes.Equal(decMsg.Contents.Get(), msgPayload[:format.ContentsLen]) { - t.Errorf("Decrypted payload differed from expected: Got %q, "+ - "expected %q", decMsg.Contents.Get(), msgPayload[:format.ContentsLen]) - } -} - -// Test that E2EEncrypt panics if the payload is too big (can't be padded) -func TestE2EEncrypt_Panic(t *testing.T) { - _, e2eGrp := getGroups() - recipient := id.NewIdFromUInt(29, id.User, t) - msg := format.NewMessage() - msg.SetRecipient(recipient) - msgPayload := []byte("help me, i'm stuck in an" + - " EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory" + - " EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory" + - " EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory" + - " EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory" + - " EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory" + - " EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory") - msgPayload = msgPayload[:format.ContentsLen] - msg.Contents.Set(msgPayload) - msg.SetTimestamp(make([]byte, 16)) - - key := e2eGrp.NewInt(42) - h, _ := hash.NewCMixHash() - h.Write(key.Bytes()) - fp := format.Fingerprint{} - copy(fp[:], h.Sum(nil)) - - defer func() { - if r := recover(); r == nil { - t.Errorf("E2EEncrypt should panic on payload too large") - } - }() - - // E2E Encryption Panics - E2EEncrypt(e2eGrp, key, fp, msg) -} - -// Test that E2EDecrypt and E2EDecryptUnsafe handle errors correctly -func TestE2EDecrypt_Errors(t *testing.T) { - _, e2eGrp := getGroups() - recipient := id.NewIdFromUInt(29, id.User, t) - msg := format.NewMessage() - msg.SetRecipient(recipient) - msgPayload := []byte("help me, i'm stuck in an EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory ") - msg.Contents.SetRightAligned(msgPayload) - msg.SetTimestamp(make([]byte, 16)) - - key := e2eGrp.NewInt(42) - h, _ := hash.NewCMixHash() - h.Write(key.Bytes()) - fp := format.Fingerprint{} - copy(fp[:], h.Sum(nil)) - - // E2E Encryption - E2EEncrypt(e2eGrp, key, fp, msg) - - // Copy message - badMsg := format.NewMessage() - badMsg.SetPayloadA(msg.GetPayloadA()) - badMsg.SetPayloadB(msg.GetPayloadB()) - - // Corrupt MAC to make decryption fail - badMsg.SetMAC([]byte("sakfaskfajskasfkkaskfanjffffjnaf")) - - // E2E Decryption returns error - err := E2EDecrypt(e2eGrp, key, badMsg) - - if err == nil { - t.Errorf("E2EDecrypt should have returned error") - } else { - t.Logf("E2EDecrypt error: %v", err.Error()) - } - - // Unsafe E2E Decryption returns error - err = E2EDecryptUnsafe(e2eGrp, key, badMsg) - - if err == nil { - t.Errorf("E2EDecryptUnsafe should have returned error") - } else { - t.Logf("E2EDecryptUnsafe error: %v", err.Error()) - } - - // Set correct MAC again - badMsg.SetMAC(msg.GetMAC()) - - // Corrupt timestamp to make decryption fail - badMsg.SetTimestamp([]byte("ABCDEF1234567890")) - - // E2E Decryption returns error - err = E2EDecrypt(e2eGrp, key, badMsg) - - if err == nil { - t.Errorf("E2EDecrypt should have returned error") - } else { - t.Logf("E2EDecrypt error: %v", err.Error()) - } - - // Unsafe E2E Decryption returns error - err = E2EDecryptUnsafe(e2eGrp, key, badMsg) - - if err == nil { - t.Errorf("E2EDecryptUnsafe should have returned error") - } else { - t.Logf("E2EDecryptUnsafe error: %v", err.Error()) - } - - // Set correct Timestamp again - badMsg.SetTimestamp(msg.GetTimestamp()) - - // Corrupt payload to make decryption fail - badMsg.Contents.SetRightAligned([]byte( - "sakomnsfjeiknheuijhgfyaistuajhfaiuojfkhufijsahufiaij")) - - // Calculate new MAC to avoid failing on that verification again - newMAC := hash.CreateHMAC(badMsg.Contents.Get(), key.Bytes()) - badMsg.SetMAC(newMAC) - - // E2E Decryption returns error - err = E2EDecrypt(e2eGrp, key, badMsg) - - if err == nil { - t.Errorf("E2EDecrypt should have returned error") - } else { - t.Logf("E2EDecrypt error: %v", err.Error()) - } -} - -func getGroups() (*cyclic.Group, *cyclic.Group) { - - cmixGrp := cyclic.NewGroup( - large.NewIntFromString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"+ - "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"+ - "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"+ - "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"+ - "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"+ - "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"+ - "83655D23DCA3AD961C62F356208552BB9ED529077096966D"+ - "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"+ - "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"+ - "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"+ - "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 16), - large.NewIntFromString("2", 16)) - - e2eGrp := cyclic.NewGroup( - large.NewIntFromString("E2EE983D031DC1DB6F1A7A67DF0E9A8E5561DB8E8D49413394C049B"+ - "7A8ACCEDC298708F121951D9CF920EC5D146727AA4AE535B0922C688B55B3DD2AE"+ - "DF6C01C94764DAB937935AA83BE36E67760713AB44A6337C20E7861575E745D31F"+ - "8B9E9AD8412118C62A3E2E29DF46B0864D0C951C394A5CBBDC6ADC718DD2A3E041"+ - "023DBB5AB23EBB4742DE9C1687B5B34FA48C3521632C4A530E8FFB1BC51DADDF45"+ - "3B0B2717C2BC6669ED76B4BDD5C9FF558E88F26E5785302BEDBCA23EAC5ACE9209"+ - "6EE8A60642FB61E8F3D24990B8CB12EE448EEF78E184C7242DD161C7738F32BF29"+ - "A841698978825B4111B4BC3E1E198455095958333D776D8B2BEEED3A1A1A221A6E"+ - "37E664A64B83981C46FFDDC1A45E3D5211AAF8BFBC072768C4F50D7D7803D2D4F2"+ - "78DE8014A47323631D7E064DE81C0C6BFA43EF0E6998860F1390B5D3FEACAF1696"+ - "015CB79C3F9C2D93D961120CD0E5F12CBB687EAB045241F96789C38E89D796138E"+ - "6319BE62E35D87B1048CA28BE389B575E994DCA755471584A09EC723742DC35873"+ - "847AEF49F66E43873", 16), - large.NewIntFromString("2", 16)) - - return cmixGrp, e2eGrp - -} diff --git a/network/interface.go b/network/interface.go deleted file mode 100644 index 5ce575fe2168d31597089634a2d899b95608f0e4..0000000000000000000000000000000000000000 --- a/network/interface.go +++ /dev/null @@ -1,38 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright © 2019 Privategrity Corporation / -// / -// All rights reserved. / -//////////////////////////////////////////////////////////////////////////////// - -package network - -import ( - "gitlab.com/elixxir/client/parse" - "gitlab.com/elixxir/client/user" - "gitlab.com/elixxir/primitives/switchboard" - "gitlab.com/xx_network/comms/connect" - "gitlab.com/xx_network/primitives/id" - "time" -) - -// Communication interface implements send/receive functionality with the server -type Communications interface { - // SendMessage to the server - - // TODO(nen) Can we get rid of the crypto type param here? - SendMessage(session user.Session, topology *connect.Circuit, - recipientID *id.ID, cryptoType parse.CryptoType, message []byte, - transmissionHost *connect.Host) error - // SendMessage without partitions to the server - // This is used to send rekey messages - SendMessageNoPartition(session user.Session, topology *connect.Circuit, - recipientID *id.ID, cryptoType parse.CryptoType, message []byte, - transmissionHost *connect.Host) error - // MessageReceiver thread to get new messages - MessageReceiver(session user.Session, delay time.Duration, - receptionHost *connect.Host, callback func(error)) - - // GetSwitchboard returns the active switchboard for local message - // listening. - GetSwitchboard() *switchboard.Switchboard -} diff --git a/network/keyExchange/init.go b/network/keyExchange/init.go index 854eb34f7b3ab26e2f84c3ec314baacae5b51774..65c17e19fab13895e583d77187177c706d4608d0 100644 --- a/network/keyExchange/init.go +++ b/network/keyExchange/init.go @@ -1,12 +1,9 @@ package keyExchange import ( - "github.com/golang/protobuf/proto" - jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/context" "gitlab.com/elixxir/client/context/message" "gitlab.com/elixxir/client/context/stoppable" - "gitlab.com/elixxir/client/storage/e2e" "gitlab.com/xx_network/primitives/id" ) @@ -26,12 +23,12 @@ func Init(ctx *context.Context) stoppable.Stoppable { select { case <-triggerStop.Quit(): return - case request := <-rekeyRequestCh: - ctx.Session.request.Sender + // case request := <-rekeyRequestCh: + // return + //ctx.Session.request.Sender } } - () - } -} - + }() + return triggerStop +} diff --git a/network/keyExchange/trigger.go b/network/keyExchange/trigger.go index 5e3925868a9162d23b098fc0d56b1d864edff8be..6e5aca2780da31b67facdea850f974b32150a7cb 100644 --- a/network/keyExchange/trigger.go +++ b/network/keyExchange/trigger.go @@ -1,6 +1,7 @@ package keyExchange import ( + "fmt" "github.com/golang/protobuf/proto" "github.com/pkg/errors" jww "github.com/spf13/jwalterweatherman" @@ -15,42 +16,46 @@ import ( "time" ) -func handleTrigger(ctx *context.Context, request message.Receive) { +const ( + errBadTrigger = "non-e2e trigger from partner %s" + errUnknown = "unknown trigger from partner %s" +) + +func handleTrigger(ctx *context.Context, request message.Receive) error { //ensure the message was encrypted properly if request.Encryption != message.E2E { - jww.ERROR.Printf("Received non-e2e encrypted Key Exchange "+ - "Trigger from partner %s", request.Sender) - return + errMsg := fmt.Sprintf(errBadTrigger, request.Sender) + jww.ERROR.Printf(errMsg) + return errors.New(errMsg) } //Get the partner partner, err := ctx.Session.E2e().GetPartner(request.Sender) if err != nil { - jww.ERROR.Printf("Received Key Exchange Trigger with unknown "+ - "partner %s", request.Sender) - return + errMsg := fmt.Sprintf(errUnknown, request.Sender) + jww.ERROR.Printf(errMsg) + return errors.New(errMsg) } //unmarshal the message oldSessionID, PartnerPublicKey, err := unmarshalKeyExchangeTrigger( ctx.Session.E2e().GetGroup(), request.Payload) if err != nil { - jww.ERROR.Printf("Failed to unmarshal Key Exchange Trigger with "+ - "partner %s: %s", request.Sender, err) - return + jww.ERROR.Printf("could not unmarshal partner %s: %s", + request.Sender, err) + return err } //get the old session which triggered the exchange oldSession := partner.GetSendSession(oldSessionID) if oldSession == nil { - jww.ERROR.Printf("Failed to find parent session %s for Key "+ - "Exchange Trigger from partner %s: %s", oldSession, request.Sender, - err) - return + jww.ERROR.Printf("no session %s for partner %s: %s", + oldSession, request.Sender, err) + return err } //create the new session - newSession, duplicate := partner.NewReceiveSession(PartnerPublicKey, + session, duplicate := partner.NewReceiveSession(PartnerPublicKey, e2e.GetDefaultSessionParams(), oldSession) // new session being nil means the session was a duplicate. This is possible // in edge cases where the partner crashes during operation. The session @@ -59,24 +64,24 @@ func handleTrigger(ctx *context.Context, request message.Receive) { if duplicate { jww.INFO.Printf("New session from Key Exchange Trigger to "+ "create session %s for partner %s is a duplicate, request ignored", - newSession.GetID(), request.Sender) + session.GetID(), request.Sender) } //Send the Confirmation Message //build the payload payload, err := proto.Marshal(&RekeyConfirm{ - SessionID: newSession.GetTrigger().Marshal(), + SessionID: session.GetTrigger().Marshal(), }) //If the payload cannot be marshaled, panic if err != nil { - jww.FATAL.Printf("Failed to marshal payload for Key "+ - "Negotation Confirmation with %s", newSession.GetPartner()) + jww.FATAL.Panicf("Failed to marshal payload for Key "+ + "Negotation Confirmation with %s", session.GetPartner()) } //build the message m := message.Send{ - Recipient: newSession.GetPartner(), + Recipient: session.GetPartner(), Payload: payload, MessageType: message.KeyExchangeConfirm, } @@ -115,7 +120,7 @@ func handleTrigger(ctx *context.Context, request message.Receive) { session) session.SetNegotiationStatus(e2e.Sent) - + return nil } func unmarshalKeyExchangeTrigger(grp *cyclic.Group, payload []byte) (e2e.SessionID, diff --git a/network/manager.go b/network/manager.go index dc0673995c711f0db0ca0af55c5acba406db4b34..66d1db1536fb6996109d94b1c1852633e9f74b7c 100644 --- a/network/manager.go +++ b/network/manager.go @@ -18,7 +18,7 @@ import ( "gitlab.com/elixxir/comms/network" "gitlab.com/xx_network/crypto/signature/rsa" "gitlab.com/xx_network/primitives/id" - "gitlab.com/xx_network/primitives/ndf" + // "gitlab.com/xx_network/primitives/ndf" "time" ) @@ -66,7 +66,9 @@ func NewManager(ctx *context.Context) (*Manager, error) { } //start network instance - instance, err := network.NewInstance(comms.ProtoComms, partial, nil, nil) + // TODO: Need to parse/retrieve the ntework string and load it + // from the context storage session! + instance, err := network.NewInstance(comms.ProtoComms, nil, nil, nil) if err != nil { return nil, errors.WithMessage(err, "failed to create"+ " client network manager") @@ -119,6 +121,7 @@ func (m *Manager) StartRunners() error { m.health.Start() m.runners.Add(m.health) + return nil } // GetRunners returns the network goroutines such that they can be named diff --git a/network/nodes.go b/network/nodes.go index 8f7422f23da635f65b6f93d75b185b9fc870d2ba..2b9206b4c1403a74356faba5e38936ab731be9a1 100644 --- a/network/nodes.go +++ b/network/nodes.go @@ -9,41 +9,41 @@ package network // nodes.go implements add/remove of nodes from network and node key exchange. import ( - "github.com/pkg/errors" + // "github.com/pkg/errors" "gitlab.com/elixxir/client/context" "gitlab.com/elixxir/client/context/stoppable" - "gitlab.com/elixxir/comms/client" - "gitlab.com/elixxir/primitives/format" - "gitlab.com/elixxir/primitives/switchboard" + // "gitlab.com/elixxir/comms/client" + // "gitlab.com/elixxir/primitives/format" + // "gitlab.com/elixxir/primitives/switchboard" "gitlab.com/xx_network/primitives/id" - "sync" - "time" + // "sync" + // "time" ) // StartNodeKeyExchange kicks off a worker pool of node key exchange routines -func StartNodeKeyExchange(ctx *context.Context) stoppable.Stopable { +func StartNodeKeyExchange(ctx *context.Context) stoppable.Stoppable { stoppers := stoppable.NewMulti("NodeKeyExchangers") - keyCh := ctx.GetNetwork().GetNodeKeysCh() - for i := 0; i < ctx.GetNumNodeKeyExchangers(); i++ { - stopper := stoppable.NewSingle("NodeKeyExchange" + i) - go ExchangeNodeKeys(ctx, keyCh, stopper.Quit()) - stoppers.Add(stopper) - } + // keyCh := ctx.Manager.GetNodeKeysCh() + // for i := 0; i < ctx.GetNumNodeKeyExchangers(); i++ { + // stopper := stoppable.NewSingle("NodeKeyExchange" + i) + // go ExchangeNodeKeys(ctx, keyCh, stopper.Quit()) + // stoppers.Add(stopper) + // } return stoppers } // ExchangeNodeKeys adds a given node to a client and stores the keys // exchanged between the client and the node. -func ExchangeNodeKeys(ctx *context.Context, keyCh chan node.ID, +func ExchangeNodeKeys(ctx *context.Context, keyCh chan id.ID, quitCh <-chan struct{}) { done := false for !done { select { case <-quitCh: done = true - case nid := <-keyCh: - nodekey := RegisterNode(ctx, nid) // defined elsewhere... - ctx.GetStorage().SetNodeKey(nid, nodekey) + // case nid := <-keyCh: + // nodekey := RegisterNode(ctx, nid) // defined elsewhere... + // ctx.GetStorage().SetNodeKey(nid, nodekey) } } } @@ -51,25 +51,25 @@ func ExchangeNodeKeys(ctx *context.Context, keyCh chan node.ID, // StartNodeRemover starts node remover worker pool func StartNodeRemover(ctx *context.Context) stoppable.Stoppable { stoppers := stoppable.NewMulti("NodeKeyExchangers") - remCh := ctx.GetNetwork().GetNodeRemCh() - for i := 0; i < ctx.GetNumNodeRemovers(); i++ { - stopper := stoppable.NewSingle("NodeKeyExchange" + i) - go RemoveNode(ctx, remCh, quitCh) - stoppers.Add(stopper) - } + // remCh := ctx.GetNetwork().GetNodeRemCh() + // for i := 0; i < ctx.GetNumNodeRemovers(); i++ { + // stopper := stoppable.NewSingle("NodeKeyExchange" + i) + // go RemoveNode(ctx, remCh, quitCh) + // stoppers.Add(stopper) + // } return stoppers } // RemoveNode removes node ids from the client, deleting their keys. -func RemoveNode(ctx *context.Context, remCh chan node.ID, +func RemoveNode(ctx *context.Context, remCh chan id.ID, quitCh <-chan struct{}) { done := false for !done { select { case <-quitCh: done = true - case nid := <-keyCh: - ctx.GetStorage().RemoveNodeKey(nid) + // case nid := <-keyCh: + // ctx.GetStorage().RemoveNodeKey(nid) } } } diff --git a/network/receive.go b/network/receive.go index 1a541fa2eb576d95c78bd9649f4b33cabfafe070..b8b11e47bf17e4ded817b28915227986ae5cf710 100644 --- a/network/receive.go +++ b/network/receive.go @@ -7,40 +7,26 @@ package network import ( - "fmt" - "github.com/pkg/errors" + "gitlab.com/elixxir/client/context" "gitlab.com/elixxir/client/context/stoppable" - "gitlab.com/elixxir/client/crypto" - "gitlab.com/elixxir/client/globals" - "gitlab.com/elixxir/client/network/keyExchange" - "gitlab.com/elixxir/client/parse" - "gitlab.com/elixxir/client/storage" - "gitlab.com/elixxir/client/user" - pb "gitlab.com/elixxir/comms/mixmessages" - "gitlab.com/elixxir/crypto/e2e" "gitlab.com/elixxir/primitives/format" - "gitlab.com/elixxir/primitives/switchboard" - "gitlab.com/xx_network/comms/connect" - "gitlab.com/xx_network/primitives/id" - "strings" - "time" ) // ReceiveMessage is called by a MessageReceiver routine whenever a new CMIX // message is available. -func ReceiveMessage(ctx *Context, m *CMIXMessage) { - decrypted, err := decrypt(ctx, m) // Returns MessagePart - if err != nil { - // Add to error/garbled messages list - jww.WARN.Errorf("Could not decode message: %+v", err) - ctx.GetGarbledMesssages().Add(m) - } +func ReceiveMessage(ctx *context.Context, m *format.Message) { + // decrypted, err := decrypt(ctx, m) // Returns MessagePart + // if err != nil { + // // Add to error/garbled messages list + // jww.WARN.Errorf("Could not decode message: %+v", err) + // ctx.GetGarbledMesssages().Add(m) + // } - // Reconstruct the partitioned message - completeMsg := constructMessageFromPartition(ctx, decrypted) // Returns ClientMessage - if completeMsg != nil { - ctx.GetSwitchBoard().Say(completeMsg) - } + // // Reconstruct the partitioned message + // completeMsg := constructMessageFromPartition(ctx, decrypted) // Returns ClientMessage + // if completeMsg != nil { + // ctx.GetSwitchBoard().Say(completeMsg) + // } } // StartMessageReceivers starts a worker pool of message receivers, which listen @@ -51,26 +37,26 @@ func StartMessageReceivers(ctx *context.Context) stoppable.Stoppable { // message receivers (would also make sense to .Close it instead of // using quit channel, which somewhat simplifies for loop later. stoppers := stoppable.NewMulti("MessageReceivers") - receiverCh := ctx.GetNetwork().GetMessageReceiverCh() - for i := 0; i < ctx.GetNumReceivers(); i++ { - stopper := stoppable.NewSingle("MessageReceiver" + i) - go MessageReceiver(ctx, messagesCh, stopper.Quit()) - stoppers.Add(stopper) - } + // receiverCh := ctx.GetNetwork().GetMessageReceiverCh() + // for i := 0; i < ctx.GetNumReceivers(); i++ { + // stopper := stoppable.NewSingle("MessageReceiver" + i) + // go MessageReceiver(ctx, messagesCh, stopper.Quit()) + // stoppers.Add(stopper) + // } return stoppers } // MessageReceiver waits until quit signal or there is a message // available on the messages channel. -func MessageReceiver(ctx *context.Context, messagesCh chan ClientMessage, +func MessageReceiver(ctx *context.Context, messagesCh chan format.Message, quitCh <-chan struct{}) { done := false for !done { select { case <-quitCh: done = true - case m := <-messagesCh: - ReceiveMessage(ctx, m) + // case m := <-messagesCh: + // ReceiveMessage(ctx, m) } } } diff --git a/network/rounds.go b/network/rounds.go index 900d136f6a31fce87dc358bf01c1b70dc3ef915a..032ecb3a049f2723ba4f2c36f50a5ad17352c513 100644 --- a/network/rounds.go +++ b/network/rounds.go @@ -7,23 +7,10 @@ package network import ( - "fmt" - "github.com/pkg/errors" + "gitlab.com/elixxir/client/context" "gitlab.com/elixxir/client/context/stoppable" - "gitlab.com/elixxir/client/crypto" - "gitlab.com/elixxir/client/globals" - "gitlab.com/elixxir/client/network/keyExchange" - "gitlab.com/elixxir/client/parse" - "gitlab.com/elixxir/client/storage" - "gitlab.com/elixxir/client/user" pb "gitlab.com/elixxir/comms/mixmessages" - "gitlab.com/elixxir/crypto/e2e" - "gitlab.com/elixxir/primitives/format" - "gitlab.com/elixxir/primitives/switchboard" - "gitlab.com/xx_network/comms/connect" - "gitlab.com/xx_network/primitives/id" - "strings" - "time" + // "time" ) // StartProcessHistoricalRounds starts a worker for processing round @@ -38,41 +25,44 @@ func StartProcessHistoricalRounds(ctx *context.Context) stoppable.Stoppable { // needs to check for messages at any of the gateways which completed // those rounds. func ProcessHistoricalRounds(ctx *context.Context, quitCh <-chan struct{}) { - ticker := timer.NewTicker(ctx.GetTrackNetworkPeriod()) - var rounds []RoundID + // ticker := time.NewTicker(ctx.GetTrackNetworkPeriod()) + // var rounds []RoundID done := false for !done { - shouldProcess := false + //shouldProcess := false select { case <-quitCh: done = true - case <-ticker: - if len(rounds) > 0 { - shouldProcess = true - } - case rid := <-ctx.GetHistoricalRoundsCh(): - rounds = append(rounds, rid) - if len(rounds) > ctx.GetSendSize() { - shouldProcess = true - } - } - if !shouldProcess { - continue - } + // case <-ticker: + // if len(rounds) > 0 { + // shouldProcess = true + // } + // case rid := <-ctx.GetHistoricalRoundsCh(): + // rounds = append(rounds, rid) + // if len(rounds) > ctx.GetSendSize() { + // shouldProcess = true + // } + // } + // if !shouldProcess { + // continue + // } - var roundInfos []*RoundInfo - roundInfos := processHistoricalRounds(ctx, rounds) - rounds := make([]RoundID) - for _, ri := range roundInfos { - ctx.GetMessagesCh() <- ri + // var roundInfos []*RoundInfo + // roundInfos = processHistoricalRounds(ctx, rounds) + // rounds := make([]RoundID) + // for _, ri := range roundInfos { + // ctx.GetMessagesCh() <- ri + // } } } } -func processHistoricalRounds(ctx *context.Context, rids []RoundID) []*RoundInfo { +func processHistoricalRounds(ctx *context.Context, + rids []uint64) []*pb.RoundInfo { // for loop over rids? - network := ctx.GetNetwork() - gw := network.GetGateway() - ris := gw.GetHistoricalRounds(ctx.GetRoundList()) - return ris + // network := ctx.GetNetwork() + // gw := network.GetGateway() + // ris := gw.GetHistoricalRounds(ctx.GetRoundList()) + // return ris + return nil } diff --git a/network/send.go b/network/send.go index 12f6087f47790c33c98b95e4c4943a9c9e8fee2c..70e6171a56912465f61d87102c85e6af8309dee4 100644 --- a/network/send.go +++ b/network/send.go @@ -9,9 +9,9 @@ package network import ( "github.com/golang-collections/collections/set" "github.com/pkg/errors" + jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/context/message" "gitlab.com/elixxir/client/context/params" - "gitlab.com/elixxir/client/context/stoppable" "gitlab.com/elixxir/comms/mixmessages" "gitlab.com/elixxir/comms/network" "gitlab.com/elixxir/crypto/csprng" @@ -19,7 +19,6 @@ import ( "gitlab.com/xx_network/comms/connect" "gitlab.com/xx_network/primitives/id" "time" - jww "github.com/spf13/jwalterweatherman" ) // SendE2E sends an end-to-end payload to the provided recipient with @@ -33,7 +32,6 @@ func (m *Manager) SendE2E(msg message.Send, e2eP params.E2E, cmixP params.CMIX) "network is not healthy") } - return nil, nil } @@ -74,7 +72,8 @@ func (m *Manager) sendCMIX(msg format.Message, param params.CMIX) (id.Round, err remainingTime := param.Timeout - elapsed //find the best round to send to, excluding roudn which have been attempted - bestRound, _ := m.instance.GetWaitingRounds().GetUpcomingRealtime(remainingTime, attempted) + //bestRound, _ := m.instance.GetWaitingRounds().GetUpcomingRealtime(remainingTime, attempted) + bestRound, _ := m.instance.GetWaitingRounds().GetUpcomingRealtime(remainingTime) topology, firstNode := buildToplogy(bestRound.Topology) //get they keys for the round, reject if any nodes do not have @@ -143,12 +142,11 @@ func (m *Manager) sendCMIX(msg format.Message, param params.CMIX) (id.Round, err } func buildToplogy(nodes [][]byte) (*connect.Circuit, *id.ID) { - idList := make([]*id.ID, len(nodes)) - for i, n := range nodes { - - } + //idList := make([]*id.ID, len(nodes)) + // for i, n := range nodes { + // } + return nil, nil } func handleMissingNodeKeys(nodes []*id.ID) {} - diff --git a/network/updates.go b/network/updates.go index 49c8d2ec8a5111a76bdb7ea5815cb7c2b4504c62..fd0af53b3d832880f4c8bccff017d32f73b0a232 100644 --- a/network/updates.go +++ b/network/updates.go @@ -20,6 +20,7 @@ package network import ( "gitlab.com/elixxir/client/context" "gitlab.com/elixxir/client/context/stoppable" + "gitlab.com/elixxir/comms/network" ) // GetUpdates polls the network for updates. @@ -37,46 +38,46 @@ func StartTrackNetwork(ctx *context.Context) stoppable.Stoppable { // TrackNetwork polls the network to get updated on the state of nodes, the // round status, and informs the client when messages can be retrieved. func TrackNetwork(ctx *context.Context, quitCh <-chan struct{}) { - ticker := timer.NewTicker(ctx.GetTrackNetworkPeriod()) + // ticker := timer.NewTicker(ctx.GetTrackNetworkPeriod()) done := false for !done { select { case <-quitCh: done = true - case <-ticker: - trackNetwork(ctx) + // case <-ticker: + // trackNetwork(ctx) } } } func trackNetwork(ctx *context.Context) { - gateway, err := ctx.Session.GetNodeKeys().GetGatewayForSending() - if err != nil { - //... - } + // gateway, err := ctx.Session.GetNodeKeys().GetGatewayForSending() + // if err != nil { + // //... + // } - network := ctx.GetNetwork() - ndf, err := network.PollNDF(ctx, gateway) - if err != nil { - // .... - } + // network := ctx.GetNetwork() + // ndf, err := network.PollNDF(ctx, gateway) + // if err != nil { + // // .... + // } - newNodes, removedNodes := network.UpdateNDF(ndf) - for _, n := range newNodes { - network.addNodeCh <- n - } - for _, n := range removedNodes { - network.removeNodeCh <- n - } + // newNodes, removedNodes := network.UpdateNDF(ndf) + // for _, n := range newNodes { + // network.addNodeCh <- n + // } + // for _, n := range removedNodes { + // network.removeNodeCh <- n + // } - rounds, err = network.UpdateRounds(ctx, ndf) - if err != nil { - // ... - } + // rounds, err = network.UpdateRounds(ctx, ndf) + // if err != nil { + // // ... + // } - err = rounds.GetKnownRound().MaskedRange(gateway, - network.CheckRoundsFunction) - if err != nil { - // ... - } + // err = rounds.GetKnownRound().MaskedRange(gateway, + // network.CheckRoundsFunction) + // if err != nil { + // // ... + // } }