From d1f70140baf0445b689853336413233291232b85 Mon Sep 17 00:00:00 2001 From: jbhusson <jonah@elixxir.io> Date: Tue, 12 Apr 2022 16:49:20 -0400 Subject: [PATCH] Working auth and single/message tests --- auth/confirm.go | 3 +- auth/receivedRequest.go | 12 +- auth/state.go | 43 +- auth/state_test.go | 162 ++++- auth/store/confirmation_test.go | 116 ++-- auth/store/previousNegotiations.go | 16 +- auth/store/previousNegotiations_test.go | 119 ++-- auth/store/receivedRequest.go | 11 +- auth/store/sentRequest.go | 11 +- auth/store/store.go | 21 +- auth/store/store_test.go | 841 +++++++++--------------- auth/utils_test.go | 44 ++ single/message/collator_test.go | 4 +- single/message/request.go | 2 +- single/message/request_test.go | 108 ++- 15 files changed, 791 insertions(+), 722 deletions(-) diff --git a/auth/confirm.go b/auth/confirm.go index 8e26dcdeb..e523715c7 100644 --- a/auth/confirm.go +++ b/auth/confirm.go @@ -151,7 +151,7 @@ func (s *state) confirm(partner contact.Contact, serviceTag string) ( return sentRound, err } -func sendAuthConfirm(net cmix.Client, partner *id.ID, +func sendAuthConfirm(net cmixClient, partner *id.ID, fp format.Fingerprint, payload, mac []byte, event event.Manager, serviceTag string) ( id.Round, error) { @@ -180,4 +180,3 @@ func sendAuthConfirm(net cmix.Client, partner *id.ID, event.Report(1, "Auth", "SendConfirm", em) return sentRound, nil } - diff --git a/auth/receivedRequest.go b/auth/receivedRequest.go index 1a58f62b2..45fe574d2 100644 --- a/auth/receivedRequest.go +++ b/auth/receivedRequest.go @@ -34,14 +34,14 @@ func (rrs *receivedRequestService) Process(message format.Message, // should be ignored tid, err := state.net.GetIdentity(receptionID.Source) if err != nil { - jww.ERROR.Printf("received a request on %s which does not exist, " + - "this should not be possible") + jww.ERROR.Printf("received a request on %s which does not exist, "+ + "this should not be possible: %+v", receptionID.Source.String(), err) return } if tid.Creation.After(round.GetEndTimestamp()) { - jww.INFO.Printf("received a request on %s which was sent before " + - "creation of the identity, dropping because it is likely old " + - "(before a reset from backup") + jww.INFO.Printf("received a request on %s which was sent before "+ + "creation of the identity, dropping because it is likely old "+ + "(before a reset from backup", receptionID.Source.String()) return } @@ -55,7 +55,7 @@ func (rrs *receivedRequestService) Process(message format.Message, jww.TRACE.Printf("processing requests: \n\t MYPUBKEY: %s "+ "\n\t PARTNERPUBKEY: %s \n\t ECRPAYLOAD: %s \n\t MAC: %s", - state.e2e.GetHistoricalDHPubkey(), + state.e2e.GetHistoricalDHPubkey().Text(64), partnerPubKey.TextVerbose(16, 0), base64.StdEncoding.EncodeToString(baseFmt.data), base64.StdEncoding.EncodeToString(message.GetMac())) diff --git a/auth/state.go b/auth/state.go index d4a8fdb87..7ced7eb8d 100644 --- a/auth/state.go +++ b/auth/state.go @@ -9,25 +9,34 @@ package auth import ( "encoding/base64" + "github.com/cloudflare/circl/dh/sidh" "github.com/pkg/errors" "gitlab.com/elixxir/client/auth/store" "gitlab.com/elixxir/client/cmix" + "gitlab.com/elixxir/client/cmix/identity" "gitlab.com/elixxir/client/cmix/identity/receptionID" "gitlab.com/elixxir/client/cmix/message" "gitlab.com/elixxir/client/cmix/rounds" "gitlab.com/elixxir/client/e2e" + "gitlab.com/elixxir/client/e2e/ratchet/partner" + "gitlab.com/elixxir/client/e2e/ratchet/partner/session" "gitlab.com/elixxir/client/event" "gitlab.com/elixxir/client/storage/versioned" "gitlab.com/elixxir/crypto/contact" + "gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/fastRNG" + "gitlab.com/elixxir/primitives/format" "gitlab.com/xx_network/primitives/id" + "gitlab.com/xx_network/primitives/id/ephemeral" ) type state struct { callbacks Callbacks - net cmix.Client - e2e e2e.Handler + // net cmix.Client + net cmixClient + // e2e e2e.Handler + e2e e2eHandler rng *fastRNG.StreamGenerator store *store.Store @@ -36,6 +45,36 @@ type state struct { params Param } +type cmixClient interface { + IsHealthy() bool + GetMaxMessageLength() int + AddService(clientID *id.ID, newService message.Service, + response message.Processor) + DeleteService(clientID *id.ID, toDelete message.Service, + processor message.Processor) + GetIdentity(get *id.ID) (identity.TrackedID, error) + AddFingerprint(identity *id.ID, fingerprint format.Fingerprint, + mp message.Processor) error + DeleteFingerprint(identity *id.ID, fingerprint format.Fingerprint) + Send(recipient *id.ID, fingerprint format.Fingerprint, + service message.Service, payload, mac []byte, cmixParams cmix.CMIXParams) ( + id.Round, ephemeral.Id, error) +} + +type e2eHandler interface { + GetHistoricalDHPubkey() *cyclic.Int + GetHistoricalDHPrivkey() *cyclic.Int + GetGroup() *cyclic.Group + AddPartner(partnerID *id.ID, + partnerPubKey, myPrivKey *cyclic.Int, + partnerSIDHPubKey *sidh.PublicKey, + mySIDHPrivKey *sidh.PrivateKey, sendParams, + receiveParams session.Params) (partner.Manager, error) + GetPartner(partnerID *id.ID) (partner.Manager, error) + DeletePartner(partnerId *id.ID) error + GetReceptionID() *id.ID +} + type Callbacks interface { Request(requestor contact.Contact, receptionID receptionID.EphemeralIdentity, round rounds.Round) diff --git a/auth/state_test.go b/auth/state_test.go index c24877dd9..2cb137bfd 100644 --- a/auth/state_test.go +++ b/auth/state_test.go @@ -9,53 +9,161 @@ package auth import ( "github.com/cloudflare/circl/dh/sidh" - auth2 "gitlab.com/elixxir/client/auth/store" - "gitlab.com/elixxir/client/interfaces" + "gitlab.com/elixxir/client/auth/store" + "gitlab.com/elixxir/client/cmix" + "gitlab.com/elixxir/client/cmix/identity" + "gitlab.com/elixxir/client/cmix/identity/receptionID" + "gitlab.com/elixxir/client/cmix/message" + "gitlab.com/elixxir/client/cmix/rounds" + "gitlab.com/elixxir/client/e2e/ratchet/partner" + "gitlab.com/elixxir/client/e2e/ratchet/partner/session" "gitlab.com/elixxir/client/storage" util "gitlab.com/elixxir/client/storage/utility" "gitlab.com/elixxir/client/storage/versioned" "gitlab.com/elixxir/crypto/contact" "gitlab.com/elixxir/crypto/cyclic" + "gitlab.com/elixxir/crypto/fastRNG" "gitlab.com/elixxir/ekv" + "gitlab.com/elixxir/primitives/format" "gitlab.com/xx_network/crypto/csprng" "gitlab.com/xx_network/crypto/large" "gitlab.com/xx_network/primitives/id" + "gitlab.com/xx_network/primitives/id/ephemeral" "io" "math/rand" "testing" "time" ) +type mockEventManager struct{} + +func (mem *mockEventManager) Report(priority int, category, evtType, details string) {} + +type mockNetManager struct{} + +func (mnm *mockNetManager) IsHealthy() bool { + return true +} +func (mnm *mockNetManager) GetMaxMessageLength() int { + return 5000 +} +func (mnm *mockNetManager) AddService(clientID *id.ID, newService message.Service, + response message.Processor) { +} +func (mnm *mockNetManager) DeleteService(clientID *id.ID, toDelete message.Service, + processor message.Processor) { +} +func (mnm *mockNetManager) GetIdentity(get *id.ID) (identity.TrackedID, error) { + return identity.TrackedID{}, nil +} +func (mnm *mockNetManager) AddFingerprint(identity *id.ID, fingerprint format.Fingerprint, + mp message.Processor) error { + return nil +} +func (mnm *mockNetManager) DeleteFingerprint(identity *id.ID, fingerprint format.Fingerprint) {} +func (mnm *mockNetManager) Send(recipient *id.ID, fingerprint format.Fingerprint, + service message.Service, payload, mac []byte, cmixParams cmix.CMIXParams) ( + id.Round, ephemeral.Id, error) { + return id.Round(5), ephemeral.Id{}, nil +} + +type mockE2E struct { + group *cyclic.Group + reception *id.ID +} + +func (me2e *mockE2E) GetHistoricalDHPubkey() *cyclic.Int { + return me2e.group.NewInt(5) +} +func (me2e *mockE2E) GetHistoricalDHPrivkey() *cyclic.Int { + return me2e.group.NewInt(4) +} +func (me2e *mockE2E) GetGroup() *cyclic.Group { + return me2e.group +} +func (me2e *mockE2E) AddPartner(partnerID *id.ID, + partnerPubKey, myPrivKey *cyclic.Int, + partnerSIDHPubKey *sidh.PublicKey, + mySIDHPrivKey *sidh.PrivateKey, sendParams, + receiveParams session.Params) (partner.Manager, error) { + return nil, nil +} +func (me2e *mockE2E) GetPartner(partnerID *id.ID) (partner.Manager, error) { + return nil, nil +} +func (me2e *mockE2E) DeletePartner(partnerId *id.ID) error { + return nil +} +func (me2e *mockE2E) GetReceptionID() *id.ID { + return me2e.reception +} + +type mockCallbacks struct { + req chan bool + con chan bool + res chan bool +} + +func (mc *mockCallbacks) Request(requestor contact.Contact, receptionID receptionID.EphemeralIdentity, + round rounds.Round) { + mc.req <- true +} +func (mc *mockCallbacks) Confirm(requestor contact.Contact, receptionID receptionID.EphemeralIdentity, + round rounds.Round) { + mc.con <- true +} +func (mc *mockCallbacks) Reset(requestor contact.Contact, receptionID receptionID.EphemeralIdentity, + round rounds.Round) { + mc.res <- true +} + func TestManager_ReplayRequests(t *testing.T) { - s := storage.InitTestingSession(t) - numReceived := 10 + sess := storage.InitTestingSession(t) - // Construct barebones manager - m := state{ - requestCallbacks: newCallbackMap(), - storage: s, - replayRequests: true, + s, err := store.NewOrLoadStore(sess.GetKV(), sess.GetCmixGroup(), &mockSentRequestHandler{}) + if err != nil { + t.Errorf("Failed to create store: %+v", err) } - ch := make(chan struct{}, numReceived) + ch := make(chan bool) - // Add multiple received contact requests - for i := 0; i < numReceived; i++ { - c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} - rng := csprng.NewSystemRNG() - _, sidhPubKey := genSidhAKeys(rng) + // Construct barebones manager + m := state{ + callbacks: &mockCallbacks{ + con: ch, + }, + net: &mockNetManager{}, + e2e: &mockE2E{ + group: sess.GetCmixGroup(), + reception: id.NewIdFromString("zezima", id.User, t), + }, + rng: fastRNG.NewStreamGenerator(1000, 10, csprng.NewSystemRNG), + store: s, + event: &mockEventManager{}, + params: Param{ + ReplayRequests: true, + }, + } - if err := m.storage.Auth().AddReceived(c, sidhPubKey); err != nil { - t.Fatalf("AddReceived() returned an error: %+v", err) - } + partnerID := id.NewIdFromUInt(rand.Uint64(), id.User, t) + c := contact.Contact{ID: partnerID, DhPubKey: sess.GetCmixGroup().NewInt(5), OwnershipProof: []byte("proof")} + rng := csprng.NewSystemRNG() + _, sidhPubKey := genSidhAKeys(rng) - m.requestCallbacks.AddSpecific(c.ID, interfaces.RequestCallback(func(c contact.Contact) { - ch <- struct{}{} - })) + r := makeTestRound(t) + if err := m.store.AddReceived(c, sidhPubKey, r); err != nil { + t.Fatalf("AddReceived() returned an error: %+v", err) + } + _, err = m.Confirm(c) + if err != nil { + t.Errorf("Failed to confirm: %+v", err) } - m.ReplayRequests() + _, err = m.ReplayConfirm(partnerID) + if err != nil { + t.Errorf("Failed to replay confirm: %+v", err) + } timeout := time.NewTimer(1 * time.Second) numChannelReceived := 0 @@ -69,14 +177,14 @@ loop: } } - if numReceived != numChannelReceived { + if numChannelReceived > 0 { t.Errorf("Unexpected number of callbacks called"+ - "\nExpected: %d"+ - "\nReceived: %d", numChannelReceived, numReceived) + "\nExpected: 1"+ + "\nReceived: %d", numChannelReceived) } } -func makeTestStore(t *testing.T) (*auth2.Store, *versioned.KV, []*cyclic.Int) { +func makeTestStore(t *testing.T) (*store.Store, *versioned.KV, []*cyclic.Int) { kv := versioned.NewKV(make(ekv.Memstore)) grp := cyclic.NewGroup(large.NewInt(173), large.NewInt(0)) privKeys := make([]*cyclic.Int, 10) @@ -84,7 +192,7 @@ func makeTestStore(t *testing.T) (*auth2.Store, *versioned.KV, []*cyclic.Int) { privKeys[i] = grp.NewInt(rand.Int63n(170) + 1) } - store, err := auth2.NewStore(kv, grp, privKeys) + store, err := store.NewOrLoadStore(kv, grp, &mockSentRequestHandler{}) if err != nil { t.Fatalf("Failed to create new Store: %+v", err) } diff --git a/auth/store/confirmation_test.go b/auth/store/confirmation_test.go index b33ec582f..a00f5e26f 100644 --- a/auth/store/confirmation_test.go +++ b/auth/store/confirmation_test.go @@ -15,6 +15,7 @@ import ( "gitlab.com/elixxir/crypto/diffieHellman" "gitlab.com/elixxir/crypto/e2e/auth" "gitlab.com/elixxir/ekv" + "gitlab.com/elixxir/primitives/format" "gitlab.com/xx_network/crypto/large" "gitlab.com/xx_network/primitives/id" "math/rand" @@ -31,50 +32,66 @@ func TestStore_StoreConfirmation_LoadConfirmation(t *testing.T) { grp := cyclic.NewGroup(large.NewInt(173), large.NewInt(2)) testValues := make([]struct { - partner *id.ID - fingerprint, confirmation []byte + partner *id.ID + fingerprint format.Fingerprint + confirmation, mac []byte }, 10) - partner, _ := id.NewRandomID(prng, id.User) + var partner *id.ID for i := range testValues { - if i%2 == 0 { - partner, _ = id.NewRandomID(prng, id.User) - } + partner, _ = id.NewRandomID(prng, id.User) // Generate original fingerprint - var fp []byte + + var fpBytes []byte + var fp format.Fingerprint if i%2 == 1 { dhPubKey := diffieHellman.GeneratePublicKey(grp.NewInt(42), grp) _, sidhPubkey := utility.GenerateSIDHKeyPair(sidh.KeyVariantSidhA, prng) - fp = auth.CreateNegotiationFingerprint(dhPubKey, sidhPubkey) + fpBytes = auth.CreateNegotiationFingerprint(dhPubKey, sidhPubkey) + fp = format.NewFingerprint(fpBytes) } // Generate confirmation confirmation := make([]byte, 32) + mac := make([]byte, 32) prng.Read(confirmation) + prng.Read(mac) + mac[0] = 0 testValues[i] = struct { - partner *id.ID - fingerprint, confirmation []byte - }{partner: partner, fingerprint: fp, confirmation: confirmation} + partner *id.ID + fingerprint format.Fingerprint + confirmation, mac []byte + }{partner: partner, fingerprint: fp, confirmation: confirmation, mac: mac} - err := s.StoreConfirmation(partner, fp, confirmation) + err := s.StoreConfirmation(partner, confirmation, mac, fp) if err != nil { t.Errorf("StoreConfirmation returned an error (%d): %+v", i, err) } } for i, val := range testValues { - loadedConfirmation, err := s.LoadConfirmation(val.partner, val.fingerprint) + loadedConfirmation, mac, fp, err := s.LoadConfirmation(val.partner) if err != nil { t.Errorf("LoadConfirmation returned an error (%d): %+v", i, err) } if !reflect.DeepEqual(val.confirmation, loadedConfirmation) { t.Errorf("Loaded confirmation does not match original (%d)."+ - "\nexpected: %v\nreceived: %v", i, val.confirmation, + "\n\texpected: %v\n\treceived: %v\n", i, val.confirmation, loadedConfirmation) } + if !reflect.DeepEqual(val.mac, mac) { + t.Errorf("Loaded mac does not match original (%d)."+ + "\n\texpected: %v\n\treceived: %v\n", i, val.mac, + mac) + } + if !reflect.DeepEqual(val.fingerprint, fp) { + t.Errorf("Loaded fingerprint does not match original (%d)."+ + "\n\texpected: %v\n\treceived: %v\n", i, val.fingerprint, + fp) + } } } @@ -86,47 +103,54 @@ func TestStore_deleteConfirmation(t *testing.T) { grp := cyclic.NewGroup(large.NewInt(173), large.NewInt(2)) testValues := make([]struct { - partner *id.ID - fingerprint, confirmation []byte + partner *id.ID + fingerprint format.Fingerprint + confirmation, mac []byte }, 10) - partner, _ := id.NewRandomID(prng, id.User) for i := range testValues { - if i%2 == 0 { - partner, _ = id.NewRandomID(prng, id.User) - } + partner, _ := id.NewRandomID(prng, id.User) + //if i%2 == 0 { + // partner, _ = id.NewRandomID(prng, id.User) + //} // Generate original fingerprint - var fp []byte + var fpBytes []byte + var fp format.Fingerprint if i%2 == 1 { dhPubKey := diffieHellman.GeneratePublicKey(grp.NewInt(42), grp) _, sidhPubkey := utility.GenerateSIDHKeyPair(sidh.KeyVariantSidhA, prng) - fp = auth.CreateNegotiationFingerprint(dhPubKey, sidhPubkey) + fpBytes = auth.CreateNegotiationFingerprint(dhPubKey, sidhPubkey) + fp = format.NewFingerprint(fpBytes) } // Generate confirmation confirmation := make([]byte, 32) + mac := make([]byte, 32) prng.Read(confirmation) + prng.Read(mac) + mac[0] = 0 testValues[i] = struct { - partner *id.ID - fingerprint, confirmation []byte - }{partner: partner, fingerprint: fp, confirmation: confirmation} + partner *id.ID + fingerprint format.Fingerprint + confirmation, mac []byte + }{partner: partner, fingerprint: fp, confirmation: confirmation, mac: mac} - err := s.StoreConfirmation(partner, fp, confirmation) + err := s.StoreConfirmation(partner, confirmation, mac, fp) if err != nil { t.Errorf("StoreConfirmation returned an error (%d): %+v", i, err) } } for i, val := range testValues { - err := s.DeleteConfirmation(val.partner, val.fingerprint) + err := s.DeleteConfirmation(val.partner) if err != nil { t.Errorf("DeleteConfirmation returned an error (%d): %+v", i, err) } - loadedConfirmation, err := s.LoadConfirmation(val.partner, val.fingerprint) - if err == nil || loadedConfirmation != nil { + loadedConfirmation, mac, _, err := s.LoadConfirmation(val.partner) + if err == nil || loadedConfirmation != nil || mac != nil { t.Errorf("LoadConfirmation returned a confirmation for partner "+ "%s and fingerprint %v (%d)", val.partner, val.fingerprint, i) } @@ -138,22 +162,22 @@ func Test_makeConfirmationKey_Consistency(t *testing.T) { prng := rand.New(rand.NewSource(42)) grp := cyclic.NewGroup(large.NewInt(173), large.NewInt(2)) expectedKeys := []string{ - "Confirmation/U4x/lrFkvxuXu59LtHLon1sUhPJSCcnZND6SugndnVID/VzgXG/mlQA68iq1eCgEMoew1rnuVG6mA2x2U34PYiOs=", - "Confirmation/P2HTdbwCtB30+Rkp4Y/anm+C5U50joHnnku9b+NM3LoD/DT1RkZJUbdDqNLQv+Pp+Ilx7ZvOX5zBzl8gseeRLu1w=", - "Confirmation/r66IG4KnURCKQu08kDyqQ0ZaeGIGFpeK7QzjxsTzrnsD/BVkxRTRPx5+16fRHsq5bYkpZDJyVJaon0roLGsOBSmI=", - "Confirmation/otwtwlpbdLLhKXBeJz8FySMmgo4rBW44F2WOEGFJiUcD/jKSgdUKni0rsIDDutHlO1fiss+BiNd1vxSGxJL0u2e8=", - "Confirmation/lk39x56NU0NzZhz9ZtdP7B4biUkatyNuS3UhYpDPK+sD/prNQTXAQjkTRhltOQuhU8XagwwWP0RfwJe6yrtI3aaY=", - "Confirmation/l4KD1KCaNvlsIJQXRuPtTaZGqa6LT6e0/Doguvoade0D/D+xEPt5A44s0BD5u/fz1iiPFoCnOR52PefTFOehdkbU=", - "Confirmation/HPCdo54Okp0CSry8sWk5e7c05+8KbgHxhU3rX+Qk/vcD/cPDqZ3S1mqVxRTQ1p7Gwg7cEc34Xz/fUsIpghGiJygg=", - "Confirmation/Ud9mj4dOLJ8c4JyoYBfn4hdIMD/0HBsj4RxI7RdTnWgD/minVwOqyN3l4zy7A4dvJDQ5ZLUcM2NmNdAWhR5/NTDc=", - "Confirmation/Ximg3KRqw6DVcBM7whVx9fVKZDEFUT/YQpsZSuG6nyoD/dK0ZnuwEmyeXqjQj5mri5f8ChTHOVgTgUKkOGjUfPyQ=", - "Confirmation/ZxkHLWcvYfqgvob0V5Iew3wORgzw1wPQfcX1ZhpFATMD/r0Nylw9Bd+eol1+4UWwWD8SBchPbjtnLYJx1zX1htEo=", - "Confirmation/IpwYPBkzqRZYXhg7twkZLbDmyNcJudc4O5k8aUmZRbAD/eszeUU8yAglf5TrE5U4L8SVqKOPqypt9RbVjworRBbk=", - "Confirmation/Rc0b8Lz8GjRsQ08RzwBBb6YWlbkgLmg2Ohx4f0eE4K4D/jhddD9Kqk6rcSJAB/Jy88cwhozR43M1nL+VTyl34SEk=", - "Confirmation/1ieMn3yHL4QPnZTZ/e2uk9sklXGPWAuMjyvsxqp2w7AD/aaMF2inM08M9FdFOHPfGKMnoqqEJ4MiXxDhY2J84cE8=", - "Confirmation/FER0v9N80ga1Gs4FCrYZnsezltYY/eDhopmabz2fi3oD/TJ5e0/2ji9eZSYa78RIP2ZvDW/PxP685D3xZAqHkGHY=", - "Confirmation/KRnCqHpJlPweQB4RxaScfo6p5l1sxARl/TUvLELsPT4D/mlbwi77z/XUw/LfzX8L67k0/0dAIDHAYicLd2RukYO0=", - "Confirmation/Q9EGMwNtPUa4GRauRv8T1qay+tkHnW3zRAWQKWZ7LrQD/0J3tuOL9xxfZdFQ73YEktXkeoFY6sAJIcgzlyDl3BxQ=", + "Confirmation/U4x/lrFkvxuXu59LtHLon1sUhPJSCcnZND6SugndnVID", + "Confirmation/P2HTdbwCtB30+Rkp4Y/anm+C5U50joHnnku9b+NM3LoD", + "Confirmation/r66IG4KnURCKQu08kDyqQ0ZaeGIGFpeK7QzjxsTzrnsD", + "Confirmation/otwtwlpbdLLhKXBeJz8FySMmgo4rBW44F2WOEGFJiUcD", + "Confirmation/lk39x56NU0NzZhz9ZtdP7B4biUkatyNuS3UhYpDPK+sD", + "Confirmation/l4KD1KCaNvlsIJQXRuPtTaZGqa6LT6e0/Doguvoade0D", + "Confirmation/HPCdo54Okp0CSry8sWk5e7c05+8KbgHxhU3rX+Qk/vcD", + "Confirmation/Ud9mj4dOLJ8c4JyoYBfn4hdIMD/0HBsj4RxI7RdTnWgD", + "Confirmation/Ximg3KRqw6DVcBM7whVx9fVKZDEFUT/YQpsZSuG6nyoD", + "Confirmation/ZxkHLWcvYfqgvob0V5Iew3wORgzw1wPQfcX1ZhpFATMD", + "Confirmation/IpwYPBkzqRZYXhg7twkZLbDmyNcJudc4O5k8aUmZRbAD", + "Confirmation/Rc0b8Lz8GjRsQ08RzwBBb6YWlbkgLmg2Ohx4f0eE4K4D", + "Confirmation/1ieMn3yHL4QPnZTZ/e2uk9sklXGPWAuMjyvsxqp2w7AD", + "Confirmation/FER0v9N80ga1Gs4FCrYZnsezltYY/eDhopmabz2fi3oD", + "Confirmation/KRnCqHpJlPweQB4RxaScfo6p5l1sxARl/TUvLELsPT4D", + "Confirmation/Q9EGMwNtPUa4GRauRv8T1qay+tkHnW3zRAWQKWZ7LrQD", } for i, expected := range expectedKeys { @@ -162,7 +186,7 @@ func Test_makeConfirmationKey_Consistency(t *testing.T) { _, sidhPubkey := utility.GenerateSIDHKeyPair(sidh.KeyVariantSidhA, prng) fp := auth.CreateNegotiationFingerprint(dhPubKey, sidhPubkey) - key := makeConfirmationKey(partner, fp) + key := makeConfirmationKey(partner) if expected != key { t.Errorf("Confirmation key does not match expected for partner "+ "%s and fingerprint %v (%d).\nexpected: %q\nreceived: %q", diff --git a/auth/store/previousNegotiations.go b/auth/store/previousNegotiations.go index 0b8e1c68c..6b0c0d6dd 100644 --- a/auth/store/previousNegotiations.go +++ b/auth/store/previousNegotiations.go @@ -17,6 +17,7 @@ import ( "gitlab.com/elixxir/crypto/e2e/auth" "gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/netTime" + "strings" ) const ( @@ -119,6 +120,19 @@ func (s *Store) newOrLoadPreviousNegotiations() (map[id.ID]bool, error) { obj, err := s.kv.Get(negotiationPartnersKey, negotiationPartnersVersion) if err != nil { + if strings.Contains(err.Error(), "object not found") { + newPreviousNegotiations := make(map[id.ID]bool) + obj := &versioned.Object{ + Version: negotiationPartnersVersion, + Timestamp: netTime.Now(), + Data: marshalPreviousNegotiations(newPreviousNegotiations), + } + err = s.kv.Set(negotiationPartnersKey, negotiationPartnersVersion, obj) + if err != nil { + return nil, err + } + return newPreviousNegotiations, nil + } return nil, err } @@ -135,7 +149,7 @@ func marshalPreviousNegotiations(partners map[id.ID]bool) []byte { b, err := json.Marshal(&toMarshal) if err != nil { - jww.FATAL.Panicf("Failed to unmarshal previous negotations", err) + jww.FATAL.Panicf("Failed to unmarshal previous negotations: %+v", err) } return b diff --git a/auth/store/previousNegotiations_test.go b/auth/store/previousNegotiations_test.go index 01c04ae40..2a19dc48a 100644 --- a/auth/store/previousNegotiations_test.go +++ b/auth/store/previousNegotiations_test.go @@ -15,6 +15,7 @@ import ( "gitlab.com/elixxir/crypto/diffieHellman" "gitlab.com/elixxir/crypto/e2e/auth" "gitlab.com/elixxir/ekv" + "gitlab.com/elixxir/primitives/format" "gitlab.com/xx_network/crypto/csprng" "gitlab.com/xx_network/crypto/large" "gitlab.com/xx_network/primitives/id" @@ -36,7 +37,7 @@ import ( func TestStore_AddIfNew(t *testing.T) { s := &Store{ kv: versioned.NewKV(make(ekv.Memstore)), - previousNegotiations: make(map[id.ID]struct{}), + previousNegotiations: make(map[id.ID]bool), } prng := rand.New(rand.NewSource(42)) grp := cyclic.NewGroup(large.NewInt(173), large.NewInt(2)) @@ -64,7 +65,7 @@ func TestStore_AddIfNew(t *testing.T) { // Expected values newFingerprint bool - latest bool + position uint } tests := []test{ @@ -76,7 +77,7 @@ func TestStore_AddIfNew(t *testing.T) { partner: newPartner(), fp: newFps(), newFingerprint: true, - latest: true, + position: 0, }, { name: "Case 2: partner exists, fingerprint does not", addPartner: true, @@ -86,7 +87,7 @@ func TestStore_AddIfNew(t *testing.T) { partner: newPartner(), fp: newFps(), newFingerprint: true, - latest: true, + position: 0, }, { name: "Case 3: partner and fingerprint exist", addPartner: true, @@ -96,7 +97,7 @@ func TestStore_AddIfNew(t *testing.T) { partner: newPartner(), fp: newFps(), newFingerprint: false, - latest: false, + position: 3, }, { name: "Case 4: partner and fingerprint exist, fingerprint latest", addPartner: true, @@ -106,14 +107,14 @@ func TestStore_AddIfNew(t *testing.T) { partner: newPartner(), fp: newFps(), newFingerprint: false, - latest: true, + position: 0, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.addPartner { - s.previousNegotiations[*tt.partner] = struct{}{} + s.previousNegotiations[*tt.partner] = true err := s.savePreviousNegotiations() if err != nil { t.Errorf( @@ -122,7 +123,7 @@ func TestStore_AddIfNew(t *testing.T) { var fps [][]byte if tt.addFp { - fps, _ = s.loadNegotiationFingerprints(tt.partner) + fps, _ = loadNegotiationFingerprints(tt.partner, s.kv) for _, fp := range tt.otherFps { fps = append(fps, fp) @@ -134,49 +135,48 @@ func TestStore_AddIfNew(t *testing.T) { fps = append([][]byte{tt.fp}, fps...) } } - err = s.saveNegotiationFingerprints(tt.partner, fps...) + err = saveNegotiationFingerprints(tt.partner, s.kv, fps...) if err != nil { t.Errorf("saveNegotiationFingerprints returned an "+ "error: %+v", err) } } - newFingerprint, latest := s.CheckIfNegotationIsNew(tt.partner, tt.fp) + newFingerprint, position := s.CheckIfNegotiationIsNew(tt.partner, tt.fp) if newFingerprint != tt.newFingerprint { t.Errorf("Unexpected value for newFingerprint."+ "\nexpected: %t\nreceived: %t", tt.newFingerprint, newFingerprint) } - if latest != tt.latest { - t.Errorf("Unexpected value for latest."+ - "\nexpected: %t\nreceived: %t", tt.latest, latest) + if position != tt.position { + t.Errorf("Unexpected value for position."+ + "\nexpected: %d\nreceived: %d", tt.position, position) } }) } } // Tests that Store.deletePreviousNegotiationPartner deletes the partner from -// previousNegotiations in memory, previousNegotiations in storage, sentByFingerprints -// in storage, and any confirmations in storage. +// previousNegotiations in storage and any confirmations in storage. func TestStore_deletePreviousNegotiationPartner(t *testing.T) { s := &Store{ kv: versioned.NewKV(make(ekv.Memstore)), - previousNegotiations: make(map[id.ID]struct{}), + previousNegotiations: make(map[id.ID]bool), } prng := rand.New(rand.NewSource(42)) grp := cyclic.NewGroup(large.NewInt(173), large.NewInt(2)) type values struct { - partner *id.ID - fps [][]byte + partner *id.ID + fps [][]byte + fingerprints []format.Fingerprint } testValues := make([]values, 16) for i := range testValues { partner, _ := id.NewRandomID(prng, id.User) - s.previousNegotiations[*partner] = struct{}{} err := s.savePreviousNegotiations() if err != nil { @@ -185,26 +185,31 @@ func TestStore_deletePreviousNegotiationPartner(t *testing.T) { } // Generate sentByFingerprints - fingerprints := make([][]byte, i+1) + fingerprintBytes := make([][]byte, i+1) + fingerprints := make([]format.Fingerprint, i+1) for j := range fingerprints { dhPubKey := diffieHellman.GeneratePublicKey(grp.NewInt(42), grp) _, sidhPubkey := utility.GenerateSIDHKeyPair(sidh.KeyVariantSidhA, prng) - fingerprints[j] = auth.CreateNegotiationFingerprint(dhPubKey, sidhPubkey) + fingerprintBytes[j] = auth.CreateNegotiationFingerprint(dhPubKey, sidhPubkey) + fingerprints[j] = format.NewFingerprint(fingerprintBytes[j]) } - err = s.saveNegotiationFingerprints(partner, fingerprints...) + err = saveNegotiationFingerprints(partner, s.kv, fingerprintBytes...) if err != nil { t.Errorf("saveNegotiationFingerprints returned an error (%d): %+v", i, err) } - testValues[i] = values{partner, fingerprints} + testValues[i] = values{partner, fingerprintBytes, fingerprints} // Generate confirmation confirmation := make([]byte, 32) + mac := make([]byte, 32) prng.Read(confirmation) + prng.Read(mac) + mac[0] = 0 - err = s.StoreConfirmation(partner, fingerprints[0], confirmation) + err = s.StoreConfirmation(partner, confirmation, mac, fingerprints[0]) if err != nil { t.Errorf("StoreConfirmation returned an error (%d): %+v", i, err) } @@ -212,49 +217,38 @@ func TestStore_deletePreviousNegotiationPartner(t *testing.T) { // Add partner that is not in list partner, _ := id.NewRandomID(prng, id.User) - testValues = append(testValues, values{partner, [][]byte{}}) + testValues = append(testValues, values{partner, [][]byte{}, []format.Fingerprint{}}) for i, v := range testValues { - err := s.deletePreviousNegotiationPartner(v.partner) + err := s.DeleteConfirmation(v.partner) if err != nil { t.Errorf("deletePreviousNegotiationPartner returned an error "+ "(%d): %+v", i, err) } - // Check previousNegotiations in memory - _, exists := s.previousNegotiations[*v.partner] - if exists { - t.Errorf("Parter %s exists in previousNegotiations (%d).", - v.partner, i) - } - // Check previousNegotiations in storage previousNegotiations, err := s.newOrLoadPreviousNegotiations() if err != nil { t.Errorf("newOrLoadPreviousNegotiations returned an error (%d): %+v", i, err) } - _, exists = previousNegotiations[*v.partner] + _, exists := previousNegotiations[*v.partner] if exists { t.Errorf("Parter %s exists in previousNegotiations in storage (%d).", v.partner, i) } - // Check negotiation sentByFingerprints in storage - fps, err := s.loadNegotiationFingerprints(v.partner) - if err == nil || fps != nil { - t.Errorf("Loaded sentByFingerprints for partner %s (%d): %v", - v.partner, i, fps) - } - - // Check all possible confirmations in storage - for j, fp := range v.fps { - confirmation, err := s.LoadConfirmation(v.partner, fp) - if err == nil || fps != nil { - t.Errorf("Loaded confirmation for partner %s and "+ - "fingerprint %v (%d, %d): %v", - v.partner, fp, i, j, confirmation) - } + //// Check negotiation sentByFingerprints in storage + //fps, err := loadNegotiationFingerprints(v.partner, s.kv) + //if err == nil || fps != nil { + // t.Errorf("Loaded sentByFingerprints for partner %s (%d): %v", + // v.partner, i, fps) + //} // TODO: seems like these never get deleted. verify? + + confirmation, _, _, err := s.LoadConfirmation(v.partner) + if err == nil { + t.Errorf("Loaded confirmation for partner %s: %v", + v.partner, confirmation) } } } @@ -264,15 +258,15 @@ func TestStore_deletePreviousNegotiationPartner(t *testing.T) { func TestStore_savePreviousNegotiations_newOrLoadPreviousNegotiations(t *testing.T) { s := &Store{ kv: versioned.NewKV(make(ekv.Memstore)), - previousNegotiations: make(map[id.ID]struct{}), + previousNegotiations: make(map[id.ID]bool), } prng := rand.New(rand.NewSource(42)) - expected := make(map[id.ID]struct{}) + expected := make(map[id.ID]bool) for i := 0; i < 16; i++ { partner, _ := id.NewRandomID(prng, id.User) - s.previousNegotiations[*partner] = struct{}{} - expected[*partner] = struct{}{} + s.previousNegotiations[*partner] = true + expected[*partner] = true err := s.savePreviousNegotiations() if err != nil { @@ -298,9 +292,9 @@ func TestStore_savePreviousNegotiations_newOrLoadPreviousNegotiations(t *testing func TestStore_newOrLoadPreviousNegotiations_noNegotiations(t *testing.T) { s := &Store{ kv: versioned.NewKV(make(ekv.Memstore)), - previousNegotiations: make(map[id.ID]struct{}), + previousNegotiations: make(map[id.ID]bool), } - expected := make(map[id.ID]struct{}) + expected := make(map[id.ID]bool) blankNegotations, err := s.newOrLoadPreviousNegotiations() if err != nil { @@ -320,15 +314,18 @@ func Test_marshalPreviousNegotiations_unmarshalPreviousNegotiations(t *testing.T prng := rand.New(rand.NewSource(42)) // Create original map of partner IDs - originalPartners := make(map[id.ID]struct{}, 50) + originalPartners := make(map[id.ID]bool, 50) for i := 0; i < 50; i++ { partner, _ := id.NewRandomID(prng, id.User) - originalPartners[*partner] = struct{}{} + originalPartners[*partner] = true } // Marshal and unmarshal the partner list marshalledPartners := marshalPreviousNegotiations(originalPartners) - unmarshalledPartners := unmarshalPreviousNegotiations(marshalledPartners) + unmarshalledPartners, err := unmarshalPreviousNegotiations(marshalledPartners) + if err != nil { + t.Errorf("Failed to unmarshal previous negotiations: %+v", err) + } // Check that the original matches the unmarshalled if !reflect.DeepEqual(originalPartners, unmarshalledPartners) { @@ -367,7 +364,7 @@ func TestStore_saveNegotiationFingerprints_loadNegotiationFingerprints(t *testin fps [][]byte }{partner: partner, fps: originalFps} - err := s.saveNegotiationFingerprints(partner, originalFps...) + err := saveNegotiationFingerprints(partner, s.kv, originalFps...) if err != nil { t.Errorf("saveNegotiationFingerprints returned an error (%d): %+v", i, err) @@ -375,7 +372,7 @@ func TestStore_saveNegotiationFingerprints_loadNegotiationFingerprints(t *testin } for i, val := range testValues { - loadedFps, err := s.loadNegotiationFingerprints(val.partner) + loadedFps, err := loadNegotiationFingerprints(val.partner, s.kv) if err != nil { t.Errorf("loadNegotiationFingerprints returned an error (%d): %+v", i, err) @@ -439,7 +436,7 @@ func Test_makeNegotiationFingerprintsKey_Consistency(t *testing.T) { for i, expected := range expectedKeys { partner, _ := id.NewRandomID(prng, id.User) - key := makeOldNegotiationFingerprintsKey(partner) + key := makeNegotiationFingerprintsKey(partner) if expected != key { t.Errorf("Negotiation sentByFingerprints key does not match expected "+ "for partner %s (%d).\nexpected: %q\nreceived: %q", partner, i, diff --git a/auth/store/receivedRequest.go b/auth/store/receivedRequest.go index fe5fa1f7c..ca02270f2 100644 --- a/auth/store/receivedRequest.go +++ b/auth/store/receivedRequest.go @@ -33,19 +33,19 @@ func newReceivedRequest(kv *versioned.KV, c contact.Contact, key *sidh.PublicKey, round rounds.Round) *ReceivedRequest { if err := util.StoreContact(kv, c); err != nil { - jww.FATAL.Panicf("Failed to save contact for partner %s", c.ID.String()) + jww.FATAL.Panicf("Failed to save contact for partner %s: %+v", c.ID.String(), err) } sidhStoreKey := util.MakeSIDHPublicKeyKey(c.ID) if err := util.StoreSIDHPublicKey(kv, key, sidhStoreKey); err != nil { jww.FATAL.Panicf("Failed to save contact SIDH pubKey for "+ - "partner %s", c.ID.String()) + "partner %s: %+v", c.ID.String(), err) } roundStoreKey := makeRoundKey(c.ID) if err := rounds.StoreRound(kv, round, roundStoreKey); err != nil { jww.FATAL.Panicf("Failed to save round request was received on "+ - "for partner %s", c.ID.String()) + "for partner %s: %+v", c.ID.String(), err) } return &ReceivedRequest{ @@ -53,6 +53,7 @@ func newReceivedRequest(kv *versioned.KV, c contact.Contact, partner: c, theirSidHPubKeyA: key, round: round, + mux: &sync.Mutex{}, } } @@ -118,10 +119,6 @@ func (rr *ReceivedRequest) getType() RequestType { return Receive } -func (rr *ReceivedRequest) isTemporary() bool { - return rr.kv.IsMemStore() -} - func makeRoundKey(partner *id.ID) string { return "receivedRequestRound:" + base64.StdEncoding.EncodeToString(partner.Marshal()) diff --git a/auth/store/sentRequest.go b/auth/store/sentRequest.go index 3347837eb..9fd5bca2d 100644 --- a/auth/store/sentRequest.go +++ b/auth/store/sentRequest.go @@ -71,7 +71,8 @@ func newSentRequest(kv *versioned.KV, partner *id.ID, partnerHistoricalPubKey, func loadSentRequest(kv *versioned.KV, partner *id.ID, grp *cyclic.Group) (*SentRequest, error) { - obj, err := kv.Get(makeSentRequestKey(partner), + srKey := makeSentRequestKey(partner) + obj, err := kv.Get(srKey, currentSentRequestVersion) if err != nil { @@ -200,12 +201,12 @@ func (sr *SentRequest) save() error { Data: data, } - return sr.kv.Set(versioned.MakePartnerPrefix(sr.partner), + return sr.kv.Set(makeSentRequestKey(sr.partner), currentSentRequestVersion, &obj) } func (sr *SentRequest) delete() { - if err := sr.kv.Delete(versioned.MakePartnerPrefix(sr.partner), + if err := sr.kv.Delete(makeSentRequestKey(sr.partner), currentSentRequestVersion); err != nil { jww.FATAL.Panicf("Failed to delete sent request from %s to %s: "+ "%+v", sr.partner, sr.partner, err) @@ -258,10 +259,6 @@ func (sr *SentRequest) getType() RequestType { return Sent } -func (sr *SentRequest) isTemporary() bool { - return sr.kv.IsMemStore() -} - func makeSentRequestKey(partner *id.ID) string { return "sentRequest:" + base64.StdEncoding.EncodeToString(partner.Marshal()) } diff --git a/auth/store/store.go b/auth/store/store.go index a81000f51..4eaf96d4d 100644 --- a/auth/store/store.go +++ b/auth/store/store.go @@ -122,23 +122,19 @@ func NewOrLoadStore(kv *versioned.KV, grp *cyclic.Group, srh SentRequestHandler) func (s *Store) save() error { requestIDList := make([]requestDisk, 0, len(s.receivedByID)+len(s.sentByID)) for _, rr := range s.receivedByID { - if !rr.isTemporary() { - rDisk := requestDisk{ - T: uint(rr.getType()), - ID: rr.partner.ID.Marshal(), - } - requestIDList = append(requestIDList, rDisk) + rDisk := requestDisk{ + T: uint(rr.getType()), + ID: rr.partner.ID.Marshal(), } + requestIDList = append(requestIDList, rDisk) } for _, sr := range s.sentByID { - if !sr.isTemporary() { - rDisk := requestDisk{ - T: uint(sr.getType()), - ID: sr.partner.Marshal(), - } - requestIDList = append(requestIDList, rDisk) + rDisk := requestDisk{ + T: uint(sr.getType()), + ID: sr.partner.Marshal(), } + requestIDList = append(requestIDList, rDisk) } data, err := json.Marshal(&requestIDList) @@ -158,7 +154,6 @@ func (s *Store) save() error { // sentByFingerprints so they can be used to trigger receivedByID. func newStore(kv *versioned.KV, grp *cyclic.Group, srh SentRequestHandler) ( *Store, error) { - kv = kv.Prefix(storePrefix) s := &Store{ kv: kv, grp: grp, diff --git a/auth/store/store_test.go b/auth/store/store_test.go index 43a2dd69f..882ac6ac1 100644 --- a/auth/store/store_test.go +++ b/auth/store/store_test.go @@ -10,14 +10,18 @@ package store import ( "bytes" "github.com/cloudflare/circl/dh/sidh" + "gitlab.com/elixxir/client/cmix/rounds" sidhinterface "gitlab.com/elixxir/client/interfaces/sidh" util "gitlab.com/elixxir/client/storage/utility" "gitlab.com/elixxir/client/storage/versioned" + "gitlab.com/elixxir/comms/mixmessages" "gitlab.com/elixxir/crypto/contact" "gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/e2e/auth" "gitlab.com/elixxir/ekv" "gitlab.com/elixxir/primitives/format" + "gitlab.com/elixxir/primitives/states" + "gitlab.com/xx_network/comms/connect" "gitlab.com/xx_network/crypto/csprng" "gitlab.com/xx_network/crypto/large" "gitlab.com/xx_network/primitives/id" @@ -25,35 +29,24 @@ import ( "math/rand" "reflect" "sort" - "sync" "testing" + "time" ) +type mockSentRequestHandler struct{} + +func (msrh *mockSentRequestHandler) Add(sr *SentRequest) {} +func (msrh *mockSentRequestHandler) Delete(sr *SentRequest) {} + // Happy path. -func TestNewStore(t *testing.T) { +func TestNewOrLoadStore(t *testing.T) { kv := versioned.NewKV(make(ekv.Memstore)) grp := cyclic.NewGroup(large.NewInt(173), large.NewInt(2)) - privKeys := make([]*cyclic.Int, 10) - pubKeys := make([]*cyclic.Int, 10) - for i := range privKeys { - privKeys[i] = grp.NewInt(rand.Int63n(172)) - pubKeys[i] = grp.ExpG(privKeys[i], grp.NewInt(1)) - } - store, err := NewStore(kv, grp, privKeys) + _, err := NewOrLoadStore(kv, grp, &mockSentRequestHandler{}) if err != nil { t.Errorf("NewStore() returned an error: %+v", err) } - - for i, key := range privKeys { - rq, ok := store.sentByFingerprints[auth.MakeRequestFingerprint(pubKeys[i])] - if !ok { - t.Errorf("Key not found in map (%d): %s", i, pubKeys[i].Text(16)) - } else if rq.PrivKey.Cmp(key) != 0 { - t.Errorf("Key found in map (%d) does not match private: "+ - "%s vs %s", i, key.Text(10), rq.PrivKey.Text(10)) - } - } } // Happy path. @@ -61,171 +54,112 @@ func TestLoadStore(t *testing.T) { rng := csprng.NewSystemRNG() // Create a random storage object + keys - s, kv, privKeys := makeTestStore(t) + s, kv := makeTestStore(t) // Generate random contact information and add it to the store c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} _, sidhPubKey := genSidhAKeys(rng) - if err := s.AddReceived(c, sidhPubKey); err != nil { + r := makeTestRound(t) + if err := s.AddReceived(c, sidhPubKey, r); err != nil { t.Fatalf("AddReceived() returned an error: %+v", err) } // Create a sent request object and add it to the store privSidh, pubSidh := genSidhAKeys(rng) - sr := &SentRequest{ - kv: s.kv, - partner: id.NewIdFromUInt(rand.Uint64(), id.User, t), - partnerHistoricalPubKey: s.grp.NewInt(5), - myPrivKey: s.grp.NewInt(6), - myPubKey: s.grp.NewInt(7), - mySidHPrivKeyA: privSidh, - mySidHPubKeyA: pubSidh, - fingerprint: format.Fingerprint{42}, - } - if err := s.AddSent(sr.partner, sr.partnerHistoricalPubKey, sr.myPrivKey, - sr.myPubKey, sr.mySidHPrivKeyA, sr.mySidHPubKeyA, - sr.fingerprint); err != nil { + var sr *SentRequest + var err error + if sr, err = s.AddSent(id.NewIdFromUInt(rand.Uint64(), id.User, t), s.grp.NewInt(5), s.grp.NewInt(6), + s.grp.NewInt(7), privSidh, pubSidh, + format.Fingerprint{42}, false); err != nil { t.Fatalf("AddSent() produced an error: %+v", err) } - s.CheckIfNegotationIsNew( - sr.partner, auth.CreateNegotiationFingerprint(privKeys[0], sidhPubKey)) + s.CheckIfNegotiationIsNew( + sr.partner, auth.CreateNegotiationFingerprint(sr.myPrivKey, sidhPubKey)) - // Attempt to load the store - store, err := LoadStore(kv, s.grp, privKeys) + err = s.save() if err != nil { - t.Errorf("LoadStore() returned an error: %+v", err) + t.Errorf("Failed to save: %+v", err) } - // Verify what was loaded equals what was put in. - // if !reflect.DeepEqual(s, store) { - // t.Errorf("LoadStore() returned incorrect Store."+ - // "\n\texpected: %+v\n\treceived: %+v", s, store) - // } - - // The above no longer works, so specifically check for the - // sent request and contact object that - // was added. - testC, testPubKeyA, err := store.GetReceivedRequest(c.ID) + // Attempt to load the store + store, err := NewOrLoadStore(kv, s.grp, &mockSentRequestHandler{}) if err != nil { - t.Errorf("GetReceivedRequest() returned an error: %+v", err) + t.Errorf("LoadStore() returned an error: %+v", err) } - if !reflect.DeepEqual(c, testC) { - t.Errorf("GetReceivedRequest() returned incorrect Contact."+ - "\n\texpected: %+v\n\treceived: %+v", c, testC) + srLoaded, ok := store.sentByID[*sr.partner] + if !ok { + t.Error("Sent request could not be found") } - keyBytes := make([]byte, sidhinterface.PubKeyByteSize) - sidhPubKey.Export(keyBytes) - expKeyBytes := make([]byte, sidhinterface.PubKeyByteSize) - testPubKeyA.Export(expKeyBytes) - if !reflect.DeepEqual(keyBytes, expKeyBytes) { - t.Errorf("GetReceivedRequest did not send proper sidh bytes") + if sr.myPrivKey == srLoaded.myPrivKey && sr.mySidHPrivKeyA == srLoaded.mySidHPrivKeyA && sr.mySidHPubKeyA == srLoaded.mySidHPubKeyA && sr.fingerprint == srLoaded.fingerprint && sr.partnerHistoricalPubKey == sr.partnerHistoricalPubKey { + t.Errorf("GetReceivedRequest() returned incorrect send req."+ + "\n\texpected: %+v\n\treceived: %+v", sr, srLoaded) } - partner := sr.partner - if s.receivedByID[*partner] == nil { + if s.receivedByID[*c.ID] == nil { t.Errorf("AddSent() failed to add request to map for "+ - "partner ID %s.", partner) - } else if !reflect.DeepEqual(sr, s.receivedByID[*partner].sent) { - t.Errorf("AddSent() failed store the correct SentRequest."+ - "\n\texpected: %+v\n\treceived: %+v", - sr, s.receivedByID[*partner].sent) - } - expectedFP := fingerprint{ - Type: Specific, - PrivKey: nil, - Request: &ReceivedRequest{Sent, sr, nil, nil, sync.Mutex{}}, - } - if _, exists := s.sentByFingerprints[sr.fingerprint]; !exists { - t.Errorf("AddSent() failed to add fingerprint to map for "+ - "fingerprint %s.", sr.fingerprint) - } else if !reflect.DeepEqual(expectedFP, - s.sentByFingerprints[sr.fingerprint]) { - t.Errorf("AddSent() failed store the correct fingerprint."+ - "\n\texpected: %+v\n\treceived: %+v", - expectedFP, s.sentByFingerprints[sr.fingerprint]) + "partner ID %s.", c.ID) } } // Happy path: tests that the correct SentRequest is added to the map. func TestStore_AddSent(t *testing.T) { rng := csprng.NewSystemRNG() - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) sidhPrivKey, sidhPubKey := genSidhAKeys(rng) partner := id.NewIdFromUInt(rand.Uint64(), id.User, t) - sr := &SentRequest{ - kv: s.kv, - partner: partner, - partnerHistoricalPubKey: s.grp.NewInt(5), - myPrivKey: s.grp.NewInt(6), - myPubKey: s.grp.NewInt(7), - mySidHPrivKeyA: sidhPrivKey, - mySidHPubKeyA: sidhPubKey, - fingerprint: format.Fingerprint{42}, - } - // Note: nil keys are nil because they are not used when - // "Sent" sent request object is set. - // FIXME: We're overloading the same data type with multiple - // meaning and this is a difficult pattern to debug/implement correctly. - // Instead, consider separate data structures for different state and - // crossreferencing and storing separate or "typing" that object when - // serialized into the same collection. - expectedFP := fingerprint{ - Type: Specific, - PrivKey: nil, - Request: &ReceivedRequest{Sent, sr, nil, nil, sync.Mutex{}}, - } - - err := s.AddSent(partner, sr.partnerHistoricalPubKey, sr.myPrivKey, - sr.myPubKey, sr.mySidHPrivKeyA, sr.mySidHPubKeyA, - sr.fingerprint) + + var sr *SentRequest + sr, err := s.AddSent(partner, s.grp.NewInt(5), s.grp.NewInt(6), + s.grp.NewInt(7), sidhPrivKey, sidhPubKey, + format.Fingerprint{42}, false) if err != nil { t.Errorf("AddSent() produced an error: %+v", err) } - if s.receivedByID[*partner] == nil { + if s.sentByID[*partner] == nil { t.Errorf("AddSent() failed to add request to map for "+ "partner ID %s.", partner) - } else if !reflect.DeepEqual(sr, s.receivedByID[*partner].sent) { + } else if !reflect.DeepEqual(sr, s.sentByID[*partner]) { t.Errorf("AddSent() failed store the correct SentRequest."+ "\n\texpected: %+v\n\treceived: %+v", - sr, s.receivedByID[*partner].sent) + sr, s.sentByID[*partner]) } - if _, exists := s.sentByFingerprints[sr.fingerprint]; !exists { + if _, exists := s.sentByID[*sr.partner]; !exists { t.Errorf("AddSent() failed to add fingerprint to map for "+ "fingerprint %s.", sr.fingerprint) - } else if !reflect.DeepEqual(expectedFP, - s.sentByFingerprints[sr.fingerprint]) { + } else if !reflect.DeepEqual(sr, + s.sentByID[*sr.partner]) { t.Errorf("AddSent() failed store the correct fingerprint."+ "\n\texpected: %+v\n\treceived: %+v", - expectedFP, s.sentByFingerprints[sr.fingerprint]) + sr, s.sentByID[*sr.partner]) } } // Error path: request with request already exists in map. func TestStore_AddSent_PartnerAlreadyExistsError(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) rng := csprng.NewSystemRNG() sidhPrivKey, sidhPubKey := genSidhAKeys(rng) partner := id.NewIdFromUInt(rand.Uint64(), id.User, t) - err := s.AddSent(partner, s.grp.NewInt(5), s.grp.NewInt(6), + _, err := s.AddSent(partner, s.grp.NewInt(5), s.grp.NewInt(6), s.grp.NewInt(7), sidhPrivKey, sidhPubKey, - format.Fingerprint{42}) + format.Fingerprint{42}, true) if err != nil { t.Errorf("AddSent() produced an error: %+v", err) } - err = s.AddSent(partner, s.grp.NewInt(5), s.grp.NewInt(6), + _, err = s.AddSent(partner, s.grp.NewInt(5), s.grp.NewInt(6), s.grp.NewInt(7), sidhPrivKey, sidhPubKey, - format.Fingerprint{42}) + format.Fingerprint{42}, true) if err == nil { t.Errorf("AddSent() did not produce the expected error for " + "a request that already exists.") @@ -234,14 +168,15 @@ func TestStore_AddSent_PartnerAlreadyExistsError(t *testing.T) { // Happy path. func TestStore_AddReceived(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) rng := csprng.NewSystemRNG() _, sidhPubKey := genSidhAKeys(rng) c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} + r := makeTestRound(t) - err := s.AddReceived(c, sidhPubKey) + err := s.AddReceived(c, sidhPubKey, r) if err != nil { t.Errorf("AddReceived() returned an error: %+v", err) } @@ -249,165 +184,48 @@ func TestStore_AddReceived(t *testing.T) { if s.receivedByID[*c.ID] == nil { t.Errorf("AddReceived() failed to add request to map for "+ "partner ID %s.", c.ID) - } else if !reflect.DeepEqual(c, *s.receivedByID[*c.ID].partner) { - t.Errorf("AddReceived() failed store the correct Contact."+ - "\n\texpected: %+v\n\treceived: %+v", c, - *s.receivedByID[*c.ID].partner) + } else if !reflect.DeepEqual(r, s.receivedByID[*c.ID].round) { + t.Errorf("AddReceived() failed store the correct round."+ + "\n\texpected: %+v\n\treceived: %+v", r, s.receivedByID[*c.ID].round) } } // Error path: request with request already exists in map. func TestStore_AddReceived_PartnerAlreadyExistsError(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} rng := csprng.NewSystemRNG() _, sidhPubKey := genSidhAKeys(rng) - err := s.AddReceived(c, sidhPubKey) + r := makeTestRound(t) + + err := s.AddReceived(c, sidhPubKey, r) if err != nil { t.Errorf("AddReceived() returned an error: %+v", err) } - err = s.AddReceived(c, sidhPubKey) + err = s.AddReceived(c, sidhPubKey, r) if err == nil { t.Errorf("AddReceived() did not produce the expected error " + "for a request that already exists.") } } -// Happy path: sentByFingerprints type is General. -func TestStore_GetFingerprint_GeneralFingerprintType(t *testing.T) { - s, _, privKeys := makeTestStore(t) - - pubkey := s.grp.ExpG(privKeys[0], s.grp.NewInt(1)) - fp := auth.MakeRequestFingerprint(pubkey) - fpType, request, key, err := s.GetFingerprint(fp) - if err != nil { - t.Errorf("GetFingerprint() returned an error: %+v", err) - } - if fpType != General { - t.Errorf("GetFingerprint() returned incorrect FingerprintType."+ - "\n\texpected: %d\n\treceived: %d", General, fpType) - } - if request != nil { - t.Errorf("GetFingerprint() returned incorrect request."+ - "\n\texpected: %+v\n\treceived: %+v", nil, request) - } - - if key.Cmp(privKeys[0]) == -2 { - t.Errorf("GetFingerprint() returned incorrect key."+ - "\n\texpected: %s\n\treceived: %s", - privKeys[0].Text(10), key.Text(10)) - } -} - -// Happy path: sentByFingerprints type is Specific. -func TestStore_GetFingerprint_SpecificFingerprintType(t *testing.T) { - s, _, _ := makeTestStore(t) - partnerID := id.NewIdFromUInt(rand.Uint64(), id.User, t) - rng := csprng.NewSystemRNG() - sidhPrivKey, sidhPubKey := genSidhAKeys(rng) - - sr := &SentRequest{ - kv: s.kv, - partner: partnerID, - partnerHistoricalPubKey: s.grp.NewInt(1), - myPrivKey: s.grp.NewInt(2), - myPubKey: s.grp.NewInt(3), - mySidHPrivKeyA: sidhPrivKey, - mySidHPubKeyA: sidhPubKey, - fingerprint: format.Fingerprint{5}, - } - if err := s.AddSent(sr.partner, sr.partnerHistoricalPubKey, - sr.myPrivKey, sr.myPubKey, sr.mySidHPrivKeyA, sr.mySidHPubKeyA, - sr.fingerprint); err != nil { - t.Fatalf("AddSent() returned an error: %+v", err) - } - - fpType, request, key, err := s.GetFingerprint(sr.fingerprint) - if err != nil { - t.Errorf("GetFingerprint() returned an error: %+v", err) - } - if fpType != Specific { - t.Errorf("GetFingerprint() returned incorrect FingerprintType."+ - "\n\texpected: %d\n\treceived: %d", Specific, fpType) - } - if request == nil { - t.Errorf("GetFingerprint() returned incorrect request."+ - "\n\texpected: %+v\n\treceived: %+v", nil, request) - } - if key != nil { - t.Errorf("GetFingerprint() returned incorrect key."+ - "\n\texpected: %v\n\treceived: %s", nil, key.Text(10)) - } -} - -// Error path: fingerprint does not exist. -func TestStore_GetFingerprint_FingerprintError(t *testing.T) { - s, _, _ := makeTestStore(t) - - fpType, request, key, err := s.GetFingerprint(format.Fingerprint{32}) - if err == nil { - t.Error("GetFingerprint() did not return an error when the " + - "fingerprint should not be found.") - } - if fpType != 0 { - t.Errorf("GetFingerprint() returned incorrect FingerprintType."+ - "\n\texpected: %d\n\treceived: %d", 0, fpType) - } - if request != nil { - t.Errorf("GetFingerprint() returned incorrect request."+ - "\n\texpected: %+v\n\treceived: %+v", nil, request) - } - if key != nil { - t.Errorf("GetFingerprint() returned incorrect key."+ - "\n\texpected: %v\n\treceived: %v", nil, key) - } -} - -// Error path: fingerprint has an invalid type. -func TestStore_GetFingerprint_InvalidFingerprintType(t *testing.T) { - s, _, privKeys := makeTestStore(t) - - fp := auth.MakeRequestFingerprint(privKeys[0]) - s.sentByFingerprints[fp] = fingerprint{ - Type: 0, - PrivKey: s.sentByFingerprints[fp].PrivKey, - Request: s.sentByFingerprints[fp].Request, - } - fpType, request, key, err := s.GetFingerprint(fp) - if err == nil { - t.Error("GetFingerprint() did not return an error when the " + - "FingerprintType is invalid.") - } - if fpType != 0 { - t.Errorf("GetFingerprint() returned incorrect "+ - "FingerprintType.\n\texpected: %d\n\treceived: %d", - 0, fpType) - } - if request != nil { - t.Errorf("GetFingerprint() returned incorrect request."+ - "\n\texpected: %+v\n\treceived: %+v", nil, request) - } - if key != nil { - t.Errorf("GetFingerprint() returned incorrect key."+ - "\n\texpected: %v\n\treceived: %v", nil, key) - } -} - // Happy path. func TestStore_GetReceivedRequest(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} rng := csprng.NewSystemRNG() _, sidhPubKey := genSidhAKeys(rng) - if err := s.AddReceived(c, sidhPubKey); err != nil { + r := makeTestRound(t) + + if err := s.AddReceived(c, sidhPubKey, r); err != nil { t.Fatalf("AddReceived() returned an error: %+v", err) } - testC, testPubKeyA, err := s.GetReceivedRequest(c.ID) + testC, err := s.GetReceivedRequest(c.ID) if err != nil { t.Errorf("GetReceivedRequest() returned an error: %+v", err) } @@ -417,16 +235,10 @@ func TestStore_GetReceivedRequest(t *testing.T) { "\n\texpected: %+v\n\treceived: %+v", c, testC) } - // Check if the request's mutex is locked - if reflect.ValueOf(&s.receivedByID[*c.ID].mux).Elem().FieldByName( - "state").Int() != 1 { - t.Errorf("GetReceivedRequest() did not lock mutex.") - } - keyBytes := make([]byte, sidhinterface.PubKeyByteSize) sidhPubKey.Export(keyBytes) expKeyBytes := make([]byte, sidhinterface.PubKeyByteSize) - testPubKeyA.Export(expKeyBytes) + s.receivedByID[*c.ID].theirSidHPubKeyA.Export(expKeyBytes) if !reflect.DeepEqual(keyBytes, expKeyBytes) { t.Errorf("GetReceivedRequest did not send proper sidh bytes") } @@ -434,23 +246,24 @@ func TestStore_GetReceivedRequest(t *testing.T) { // Error path: request is deleted between first and second check. func TestStore_GetReceivedRequest_RequestDeleted(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} rng := csprng.NewSystemRNG() _, sidhPubKey := genSidhAKeys(rng) - if err := s.AddReceived(c, sidhPubKey); err != nil { + + r := makeTestRound(t) + + if err := s.AddReceived(c, sidhPubKey, r); err != nil { t.Fatalf("AddReceived() returned an error: %+v", err) } - r := s.receivedByID[*c.ID] - r.mux.Lock() + rr := s.receivedByID[*c.ID] + rr.mux.Lock() - go func() { - delete(s.receivedByID, *c.ID) - r.mux.Unlock() - }() + delete(s.receivedByID, *c.ID) + rr.mux.Unlock() - testC, _, err := s.GetReceivedRequest(c.ID) + testC, err := s.GetReceivedRequest(c.ID) if err == nil { t.Errorf("GetReceivedRequest() did not return an error " + "when the request should not exist.") @@ -463,16 +276,16 @@ func TestStore_GetReceivedRequest_RequestDeleted(t *testing.T) { } // Check if the request's mutex is locked - if reflect.ValueOf(&r.mux).Elem().FieldByName("state").Int() != 0 { + if reflect.ValueOf(rr.mux).Elem().FieldByName("state").Int() != 0 { t.Errorf("GetReceivedRequest() did not unlock mutex.") } } // Error path: request does not exist. func TestStore_GetReceivedRequest_RequestNotInMap(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) - testC, testPubKeyA, err := s.GetReceivedRequest( + testC, err := s.GetReceivedRequest( id.NewIdFromUInt(rand.Uint64(), id.User, t)) if err == nil { @@ -485,23 +298,22 @@ func TestStore_GetReceivedRequest_RequestNotInMap(t *testing.T) { "\n\texpected: %+v\n\treceived: %+v", contact.Contact{}, testC) } - - if testPubKeyA != nil { - t.Errorf("Expected empty sidh public key!") - } } // Happy path. func TestStore_GetReceivedRequestData(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} rng := csprng.NewSystemRNG() _, sidhPubKey := genSidhAKeys(rng) - if err := s.AddReceived(c, sidhPubKey); err != nil { + + r := makeTestRound(t) + + if err := s.AddReceived(c, sidhPubKey, r); err != nil { t.Fatalf("AddReceived() returned an error: %+v", err) } - testC, err := s.GetReceivedRequestData(c.ID) + testC, err := s.GetReceivedRequest(c.ID) if err != nil { t.Errorf("GetReceivedRequestData() returned an error: %+v", err) } @@ -514,9 +326,9 @@ func TestStore_GetReceivedRequestData(t *testing.T) { // Error path: request does not exist. func TestStore_GetReceivedRequestData_RequestNotInMap(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) - testC, err := s.GetReceivedRequestData(id.NewIdFromUInt( + testC, err := s.GetReceivedRequest(id.NewIdFromUInt( rand.Uint64(), id.User, t)) if err == nil { @@ -533,118 +345,98 @@ func TestStore_GetReceivedRequestData_RequestNotInMap(t *testing.T) { // Happy path: request is of type Receive. func TestStore_GetRequest_ReceiveRequest(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} rng := csprng.NewSystemRNG() _, sidhPubKey := genSidhAKeys(rng) - if err := s.AddReceived(c, sidhPubKey); err != nil { + + r := makeTestRound(t) + + if err := s.AddReceived(c, sidhPubKey, r); err != nil { t.Fatalf("AddReceived() returned an error: %+v", err) } - rType, request, con, err := s.GetRequest(c.ID) + con, err := s.GetReceivedRequest(c.ID) if err != nil { t.Errorf("GetRequest() returned an error: %+v", err) } - if rType != Receive { - t.Errorf("GetRequest() returned incorrect RequestType."+ - "\n\texpected: %d\n\treceived: %d", Receive, rType) - } - if request != nil { - t.Errorf("GetRequest() returned incorrect SentRequest."+ - "\n\texpected: %+v\n\treceived: %+v", nil, request) - } if !reflect.DeepEqual(c, con) { t.Errorf("GetRequest() returned incorrect Contact."+ "\n\texpected: %+v\n\treceived: %+v", c, con) } } -// Happy path: request is of type Sent. -func TestStore_GetRequest_SentRequest(t *testing.T) { - s, _, _ := makeTestStore(t) - partnerID := id.NewIdFromUInt(rand.Uint64(), id.User, t) - rng := csprng.NewSystemRNG() - sidhPrivKey, sidhPubKey := genSidhAKeys(rng) - - sr := &SentRequest{ - kv: s.kv, - partner: partnerID, - partnerHistoricalPubKey: s.grp.NewInt(1), - myPrivKey: s.grp.NewInt(2), - myPubKey: s.grp.NewInt(3), - mySidHPrivKeyA: sidhPrivKey, - mySidHPubKeyA: sidhPubKey, - fingerprint: format.Fingerprint{5}, - } - if err := s.AddSent(sr.partner, sr.partnerHistoricalPubKey, sr.myPrivKey, - sr.myPubKey, sr.mySidHPrivKeyA, sr.mySidHPubKeyA, - sr.fingerprint); err != nil { - t.Fatalf("AddSent() returned an error: %+v", err) - } - - rType, request, con, err := s.GetRequest(sr.partner) - if err != nil { - t.Errorf("GetRequest() returned an error: %+v", err) - } - if rType != Sent { - t.Errorf("GetRequest() returned incorrect RequestType."+ - "\n\texpected: %d\n\treceived: %d", Sent, rType) - } - if !reflect.DeepEqual(sr, request) { - t.Errorf("GetRequest() returned incorrect SentRequest."+ - "\n\texpected: %+v\n\treceived: %+v", sr, request) - } - if !reflect.DeepEqual(contact.Contact{}, con) { - t.Errorf("GetRequest() returned incorrect Contact."+ - "\n\texpected: %+v\n\treceived: %+v", contact.Contact{}, - con) - } -} - -// Error path: request type is invalid. -func TestStore_GetRequest_InvalidType(t *testing.T) { - s, _, _ := makeTestStore(t) - uid := id.NewIdFromUInt(rand.Uint64(), id.User, t) - s.receivedByID[*uid] = &ReceivedRequest{rt: 42} - - rType, request, con, err := s.GetRequest(uid) - if err == nil { - t.Errorf("GetRequest() did not return an error " + - "when the request type should be invalid.") - } - if rType != 0 { - t.Errorf("GetRequest() returned incorrect RequestType."+ - "\n\texpected: %d\n\treceived: %d", 0, rType) - } - if request != nil { - t.Errorf("GetRequest() returned incorrect SentRequest."+ - "\n\texpected: %+v\n\treceived: %+v", nil, request) - } - if !reflect.DeepEqual(contact.Contact{}, con) { - t.Errorf("GetRequest() returned incorrect Contact."+ - "\n\texpected: %+v\n\treceived: %+v", contact.Contact{}, - con) - } -} +// +//// Happy path: request is of type Sent. +//func TestStore_GetRequest_SentRequest(t *testing.T) { +// s, _ := makeTestStore(t) +// partnerID := id.NewIdFromUInt(rand.Uint64(), id.User, t) +// rng := csprng.NewSystemRNG() +// sidhPrivKey, sidhPubKey := genSidhAKeys(rng) +// +// var sr *SentRequest +// var err error +// if sr, err = s.AddSent(partnerID, s.grp.NewInt(5), s.grp.NewInt(6), +// s.grp.NewInt(7), sidhPrivKey, sidhPubKey, +// format.Fingerprint{42}, false); err != nil { +// t.Fatalf("AddSent() returned an error: %+v", err) +// } +// +// rType, request, con, err := s.GetRequest(sr.partner) +// if err != nil { +// t.Errorf("GetRequest() returned an error: %+v", err) +// } +// if rType != Sent { +// t.Errorf("GetRequest() returned incorrect RequestType."+ +// "\n\texpected: %d\n\treceived: %d", Sent, rType) +// } +// if !reflect.DeepEqual(sr, request) { +// t.Errorf("GetRequest() returned incorrect SentRequest."+ +// "\n\texpected: %+v\n\treceived: %+v", sr, request) +// } +// if !reflect.DeepEqual(contact.Contact{}, con) { +// t.Errorf("GetRequest() returned incorrect Contact."+ +// "\n\texpected: %+v\n\treceived: %+v", contact.Contact{}, +// con) +// } +//} +// +//// Error path: request type is invalid. +//func TestStore_GetRequest_InvalidType(t *testing.T) { +// s, _, _ := makeTestStore(t) +// uid := id.NewIdFromUInt(rand.Uint64(), id.User, t) +// s.receivedByID[*uid] = &ReceivedRequest{rt: 42} +// +// rType, request, con, err := s.GetRequest(uid) +// if err == nil { +// t.Errorf("GetRequest() did not return an error " + +// "when the request type should be invalid.") +// } +// if rType != 0 { +// t.Errorf("GetRequest() returned incorrect RequestType."+ +// "\n\texpected: %d\n\treceived: %d", 0, rType) +// } +// if request != nil { +// t.Errorf("GetRequest() returned incorrect SentRequest."+ +// "\n\texpected: %+v\n\treceived: %+v", nil, request) +// } +// if !reflect.DeepEqual(contact.Contact{}, con) { +// t.Errorf("GetRequest() returned incorrect Contact."+ +// "\n\texpected: %+v\n\treceived: %+v", contact.Contact{}, +// con) +// } +//} // Error path: request does not exist in map. func TestStore_GetRequest_RequestNotInMap(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) uid := id.NewIdFromUInt(rand.Uint64(), id.User, t) - rType, request, con, err := s.GetRequest(uid) + con, err := s.GetReceivedRequest(uid) if err == nil { t.Errorf("GetRequest() did not return an error " + "when the request was not in the map.") } - if rType != 0 { - t.Errorf("GetRequest() returned incorrect RequestType."+ - "\n\texpected: %d\n\treceived: %d", 0, rType) - } - if request != nil { - t.Errorf("GetRequest() returned incorrect SentRequest."+ - "\n\texpected: %+v\n\treceived: %+v", nil, request) - } if !reflect.DeepEqual(contact.Contact{}, con) { t.Errorf("GetRequest() returned incorrect Contact."+ "\n\texpected: %+v\n\treceived: %+v", contact.Contact{}, @@ -653,61 +445,67 @@ func TestStore_GetRequest_RequestNotInMap(t *testing.T) { } // Happy path. -func TestStore_Fail(t *testing.T) { - s, _, _ := makeTestStore(t) - c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} - rng := csprng.NewSystemRNG() - _, sidhPubKey := genSidhAKeys(rng) - if err := s.AddReceived(c, sidhPubKey); err != nil { - t.Fatalf("AddReceived() returned an error: %+v", err) - } - if _, _, err := s.GetReceivedRequest(c.ID); err != nil { - t.Fatalf("GetReceivedRequest() returned an error: %+v", err) - } - - defer func() { - if r := recover(); r != nil { - t.Errorf("The code did not panic") - } - }() - - s.Done(c.ID) - - // Check if the request's mutex is locked - if reflect.ValueOf(&s.receivedByID[*c.ID].mux).Elem().FieldByName( - "state").Int() != 0 { - t.Errorf("Done() did not unlock mutex.") - } -} +//func TestStore_Fail(t *testing.T) { +// s, _ := makeTestStore(t) +// c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} +// rng := csprng.NewSystemRNG() +// _, sidhPubKey := genSidhAKeys(rng) +// +// r := makeTestRound() +// +// if err := s.AddReceived(c, sidhPubKey, r); err != nil { +// t.Fatalf("AddReceived() returned an error: %+v", err) +// } +// if _, err := s.GetReceivedRequest(c.ID); err != nil { +// t.Fatalf("GetReceivedRequest() returned an error: %+v", err) +// } +// +// defer func() { +// if r := recover(); r != nil { +// t.Errorf("The code did not panic") +// } +// }() +// +// s.Done(c.ID) +// +// // Check if the request's mutex is locked +// if reflect.ValueOf(&s.receivedByID[*c.ID].mux).Elem().FieldByName( +// "state").Int() != 0 { +// t.Errorf("Done() did not unlock mutex.") +// } +//} // Error path: request does not exist. -func TestStore_Fail_RequestNotInMap(t *testing.T) { - s, _, _ := makeTestStore(t) - - defer func() { - if r := recover(); r == nil { - t.Errorf("Done() did not panic when the " + - "request is not in map.") - } - }() - - s.Done(id.NewIdFromUInt(rand.Uint64(), id.User, t)) -} +//func TestStore_Fail_RequestNotInMap(t *testing.T) { +// s,, _ := makeTestStore(t) +// +// defer func() { +// if r := recover(); r == nil { +// t.Errorf("Done() did not panic when the " + +// "request is not in map.") +// } +// }() +// +// s.Done(id.NewIdFromUInt(rand.Uint64(), id.User, t)) +//} // Happy path: partner request. func TestStore_Delete_ReceiveRequest(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} rng := csprng.NewSystemRNG() _, sidhPubKey := genSidhAKeys(rng) - if err := s.AddReceived(c, sidhPubKey); err != nil { + + r := makeTestRound(t) + + if err := s.AddReceived(c, sidhPubKey, r); err != nil { t.Fatalf("AddReceived() returned an error: %+v", err) } - if _, _, err := s.GetReceivedRequest(c.ID); err != nil { + if _, err := s.GetReceivedRequest(c.ID); err != nil { t.Fatalf("GetReceivedRequest() returned an error: %+v", err) } - err := s.Delete(c.ID) + err := s.DeleteRequest(c.ID) if err != nil { t.Errorf("delete() returned an error: %+v", err) } @@ -719,7 +517,7 @@ func TestStore_Delete_ReceiveRequest(t *testing.T) { // Happy path: sent request. func TestStore_Delete_SentRequest(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) partnerID := id.NewIdFromUInt(rand.Uint64(), id.User, t) rng := csprng.NewSystemRNG() sidhPrivKey, sidhPubKey := genSidhAKeys(rng) @@ -733,16 +531,17 @@ func TestStore_Delete_SentRequest(t *testing.T) { mySidHPubKeyA: sidhPubKey, fingerprint: format.Fingerprint{5}, } - if err := s.AddSent(sr.partner, sr.partnerHistoricalPubKey, - sr.myPrivKey, sr.myPubKey, sr.mySidHPrivKeyA, - sr.mySidHPubKeyA, sr.fingerprint); err != nil { + if _, err := s.AddSent(sr.partner, s.grp.NewInt(5), s.grp.NewInt(6), + s.grp.NewInt(7), sidhPrivKey, sidhPubKey, + format.Fingerprint{42}, false); err != nil { t.Fatalf("AddSent() returned an error: %+v", err) } - if _, _, _, err := s.GetFingerprint(sr.fingerprint); err != nil { - t.Fatalf("GetFingerprint() returned an error: %+v", err) - } - err := s.Delete(sr.partner) + //if _, _, _, err := s.GetFingerprint(sr.fingerprint); err != nil { // TODO legacy + // t.Fatalf("GetFingerprint() returned an error: %+v", err) + //} + + err := s.DeleteRequest(sr.partner) if err != nil { t.Errorf("delete() returned an error: %+v", err) } @@ -752,7 +551,7 @@ func TestStore_Delete_SentRequest(t *testing.T) { sr.partner) } - if _, exists := s.sentByFingerprints[sr.fingerprint]; exists { + if _, exists := s.sentByID[*sr.partner]; exists { t.Errorf("delete() failed to delete fingerprint for fp %v.", sr.fingerprint) } @@ -760,9 +559,9 @@ func TestStore_Delete_SentRequest(t *testing.T) { // Error path: request does not exist. func TestStore_Delete_RequestNotInMap(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) - err := s.Delete(id.NewIdFromUInt(rand.Uint64(), id.User, t)) + err := s.DeleteRequest(id.NewIdFromUInt(rand.Uint64(), id.User, t)) if err == nil { t.Errorf("delete() did not return an error when the request " + "was not in the map.") @@ -771,7 +570,7 @@ func TestStore_Delete_RequestNotInMap(t *testing.T) { // Unit test of Store.GetAllReceived. func TestStore_GetAllReceived(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) numReceived := 10 expectContactList := make([]contact.Contact, 0, numReceived) @@ -781,7 +580,9 @@ func TestStore_GetAllReceived(t *testing.T) { rng := csprng.NewSystemRNG() _, sidhPubKey := genSidhAKeys(rng) - if err := s.AddReceived(c, sidhPubKey); err != nil { + r := makeTestRound(t) + + if err := s.AddReceived(c, sidhPubKey, r); err != nil { t.Fatalf("AddReceived() returned an error: %+v", err) } @@ -789,7 +590,12 @@ func TestStore_GetAllReceived(t *testing.T) { } // Check that GetAllReceived returns all contacts - receivedContactList := s.GetAllReceived() + receivedRequestList := s.GetAllReceivedRequests() + var receivedContactList = make([]contact.Contact, len(receivedRequestList)) + for i, req := range receivedRequestList { + receivedContactList[i] = req.GetContact() + } + if len(receivedContactList) != numReceived { t.Errorf("GetAllReceived did not return expected amount of contacts."+ "\nExpected: %d"+ @@ -817,10 +623,10 @@ func TestStore_GetAllReceived(t *testing.T) { // Tests that Store.GetAllReceived returns an empty list when there are no // received receivedByID. func TestStore_GetAllReceived_EmptyList(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) // Check that GetAllReceived returns all contacts - receivedContactList := s.GetAllReceived() + receivedContactList := s.GetAllReceivedRequests() if len(receivedContactList) != 0 { t.Errorf("GetAllReceived did not return expected amount of contacts."+ "\nExpected: %d"+ @@ -832,25 +638,15 @@ func TestStore_GetAllReceived_EmptyList(t *testing.T) { partnerID := id.NewIdFromUInt(rand.Uint64(), id.User, t) rng := csprng.NewSystemRNG() sidhPrivKey, sidhPubKey := genSidhAKeys(rng) - sr := &SentRequest{ - kv: s.kv, - partner: partnerID, - partnerHistoricalPubKey: s.grp.NewInt(1), - myPrivKey: s.grp.NewInt(2), - myPubKey: s.grp.NewInt(3), - mySidHPrivKeyA: sidhPrivKey, - mySidHPubKeyA: sidhPubKey, - fingerprint: format.Fingerprint{5}, - } - if err := s.AddSent(sr.partner, sr.partnerHistoricalPubKey, - sr.myPrivKey, sr.myPubKey, sr.mySidHPrivKeyA, - sr.mySidHPubKeyA, sr.fingerprint); err != nil { + if _, err := s.AddSent(partnerID, s.grp.NewInt(5), s.grp.NewInt(6), + s.grp.NewInt(7), sidhPrivKey, sidhPubKey, + format.Fingerprint{42}, false); err != nil { t.Fatalf("AddSent() returned an error: %+v", err) } } // Check that GetAllReceived returns all contacts - receivedContactList = s.GetAllReceived() + receivedContactList = s.GetAllReceivedRequests() if len(receivedContactList) != 0 { t.Errorf("GetAllReceived did not return expected amount of contacts. "+ "It may be pulling from Sent Requests."+ @@ -863,7 +659,7 @@ func TestStore_GetAllReceived_EmptyList(t *testing.T) { // Tests that Store.GetAllReceived returns only Sent receivedByID when there // are both Sent and Receive receivedByID in Store. func TestStore_GetAllReceived_MixSentReceived(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) numReceived := 10 // Add multiple received contact receivedByID @@ -873,32 +669,24 @@ func TestStore_GetAllReceived_MixSentReceived(t *testing.T) { rng := csprng.NewSystemRNG() _, sidhPubKey := genSidhAKeys(rng) - if err := s.AddReceived(c, sidhPubKey); err != nil { + r := makeTestRound(t) + + if err := s.AddReceived(c, sidhPubKey, r); err != nil { t.Fatalf("AddReceived() returned an error: %+v", err) } // Add sent request partnerID := id.NewIdFromUInt(rand.Uint64(), id.User, t) sidhPrivKey, sidhPubKey := genSidhAKeys(rng) - sr := &SentRequest{ - kv: s.kv, - partner: partnerID, - partnerHistoricalPubKey: s.grp.NewInt(1), - myPrivKey: s.grp.NewInt(2), - myPubKey: s.grp.NewInt(3), - mySidHPrivKeyA: sidhPrivKey, - mySidHPubKeyA: sidhPubKey, - fingerprint: format.Fingerprint{5}, - } - if err := s.AddSent(sr.partner, sr.partnerHistoricalPubKey, - sr.myPrivKey, sr.myPubKey, sr.mySidHPrivKeyA, - sr.mySidHPubKeyA, sr.fingerprint); err != nil { + if _, err := s.AddSent(partnerID, s.grp.NewInt(5), s.grp.NewInt(6), + s.grp.NewInt(7), sidhPrivKey, sidhPubKey, + format.Fingerprint{42}, false); err != nil { t.Fatalf("AddSent() returned an error: %+v", err) } } // Check that GetAllReceived returns all contacts - receivedContactList := s.GetAllReceived() + receivedContactList := s.GetAllReceivedRequests() if len(receivedContactList) != numReceived { t.Errorf("GetAllReceived did not return expected amount of contacts. "+ "It may be pulling from Sent Requests."+ @@ -911,14 +699,17 @@ func TestStore_GetAllReceived_MixSentReceived(t *testing.T) { // Error case: Call DeleteRequest on a request that does // not exist. func TestStore_DeleteRequest_NonexistantRequest(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} rng := csprng.NewSystemRNG() _, sidhPubKey := genSidhAKeys(rng) - if err := s.AddReceived(c, sidhPubKey); err != nil { + + r := makeTestRound(t) + + if err := s.AddReceived(c, sidhPubKey, r); err != nil { t.Fatalf("AddReceived() returned an error: %+v", err) } - if _, _, err := s.GetReceivedRequest(c.ID); err != nil { + if _, err := s.GetReceivedRequest(c.ID); err != nil { t.Fatalf("GetReceivedRequest() returned an error: %+v", err) } @@ -932,14 +723,17 @@ func TestStore_DeleteRequest_NonexistantRequest(t *testing.T) { // Unit test. func TestStore_DeleteReceiveRequests(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} rng := csprng.NewSystemRNG() _, sidhPubKey := genSidhAKeys(rng) - if err := s.AddReceived(c, sidhPubKey); err != nil { + + r := makeTestRound(t) + + if err := s.AddReceived(c, sidhPubKey, r); err != nil { t.Fatalf("AddReceived() returned an error: %+v", err) } - if _, _, err := s.GetReceivedRequest(c.ID); err != nil { + if _, err := s.GetReceivedRequest(c.ID); err != nil { t.Fatalf("GetReceivedRequest() returned an error: %+v", err) } @@ -955,27 +749,19 @@ func TestStore_DeleteReceiveRequests(t *testing.T) { // Unit test. func TestStore_DeleteSentRequests(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) partnerID := id.NewIdFromUInt(rand.Uint64(), id.User, t) rng := csprng.NewSystemRNG() sidhPrivKey, sidhPubKey := genSidhAKeys(rng) - sr := &SentRequest{ - kv: s.kv, - partner: partnerID, - partnerHistoricalPubKey: s.grp.NewInt(1), - myPrivKey: s.grp.NewInt(2), - myPubKey: s.grp.NewInt(3), - mySidHPrivKeyA: sidhPrivKey, - mySidHPubKeyA: sidhPubKey, - fingerprint: format.Fingerprint{5}, - } - if err := s.AddSent(sr.partner, sr.partnerHistoricalPubKey, - sr.myPrivKey, sr.myPubKey, sr.mySidHPrivKeyA, - sr.mySidHPubKeyA, sr.fingerprint); err != nil { + var sr *SentRequest + var err error + if sr, err = s.AddSent(partnerID, s.grp.NewInt(5), s.grp.NewInt(6), + s.grp.NewInt(7), sidhPrivKey, sidhPubKey, + format.Fingerprint{42}, false); err != nil { t.Fatalf("AddSent() returned an error: %+v", err) } - err := s.DeleteSentRequests() + err = s.DeleteSentRequests() if err != nil { t.Fatalf("DeleteSentRequests returned an error: %+v", err) } @@ -985,7 +771,7 @@ func TestStore_DeleteSentRequests(t *testing.T) { sr.partner) } - if _, exists := s.sentByFingerprints[sr.fingerprint]; exists { + if _, exists := s.sentByID[*sr.partner]; exists { t.Errorf("delete() failed to delete fingerprint for fp %v.", sr.fingerprint) } @@ -993,11 +779,14 @@ func TestStore_DeleteSentRequests(t *testing.T) { // Tests that DeleteSentRequests does not affect partner receivedByID in map func TestStore_DeleteSentRequests_ReceiveInMap(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} rng := csprng.NewSystemRNG() _, sidhPubKey := genSidhAKeys(rng) - if err := s.AddReceived(c, sidhPubKey); err != nil { + + r := makeTestRound(t) + + if err := s.AddReceived(c, sidhPubKey, r); err != nil { t.Fatalf("AddReceived() returned an error: %+v", err) } @@ -1012,34 +801,25 @@ func TestStore_DeleteSentRequests_ReceiveInMap(t *testing.T) { } -// Tests that DeleteReceiveRequests does not affect sent receivedByID in map +// Tests that DeleteReceiveRequests does not affect sentByID in map func TestStore_DeleteReceiveRequests_SentInMap(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) partnerID := id.NewIdFromUInt(rand.Uint64(), id.User, t) rng := csprng.NewSystemRNG() sidhPrivKey, sidhPubKey := genSidhAKeys(rng) - sr := &SentRequest{ - kv: s.kv, - partner: partnerID, - partnerHistoricalPubKey: s.grp.NewInt(1), - myPrivKey: s.grp.NewInt(2), - myPubKey: s.grp.NewInt(3), - mySidHPrivKeyA: sidhPrivKey, - mySidHPubKeyA: sidhPubKey, - fingerprint: format.Fingerprint{5}, - } - if err := s.AddSent(sr.partner, sr.partnerHistoricalPubKey, - sr.myPrivKey, sr.myPubKey, sr.mySidHPrivKeyA, - sr.mySidHPubKeyA, sr.fingerprint); err != nil { + var err error + if _, err = s.AddSent(partnerID, s.grp.NewInt(5), s.grp.NewInt(6), + s.grp.NewInt(7), sidhPrivKey, sidhPubKey, + format.Fingerprint{42}, false); err != nil { t.Fatalf("AddSent() returned an error: %+v", err) } - err := s.DeleteReceiveRequests() + err = s.DeleteReceiveRequests() if err != nil { t.Fatalf("DeleteSentRequests returned an error: %+v", err) } - if s.receivedByID[*partnerID] == nil { + if s.sentByID[*partnerID] == nil { t.Fatalf("DeleteReceiveRequests removes sent receivedByID!") } @@ -1047,33 +827,26 @@ func TestStore_DeleteReceiveRequests_SentInMap(t *testing.T) { // Unit test. func TestStore_DeleteAllRequests(t *testing.T) { - s, _, _ := makeTestStore(t) + s, _ := makeTestStore(t) partnerID := id.NewIdFromUInt(rand.Uint64(), id.User, t) rng := csprng.NewSystemRNG() sidhPrivKey, sidhPubKey := genSidhAKeys(rng) - sr := &SentRequest{ - kv: s.kv, - partner: partnerID, - partnerHistoricalPubKey: s.grp.NewInt(1), - myPrivKey: s.grp.NewInt(2), - myPubKey: s.grp.NewInt(3), - mySidHPrivKeyA: sidhPrivKey, - mySidHPubKeyA: sidhPubKey, - fingerprint: format.Fingerprint{5}, - } - if err := s.AddSent(sr.partner, sr.partnerHistoricalPubKey, - sr.myPrivKey, sr.myPubKey, sr.mySidHPrivKeyA, - sr.mySidHPubKeyA, sr.fingerprint); err != nil { + var sr *SentRequest + var err error + if sr, err = s.AddSent(partnerID, s.grp.NewInt(5), s.grp.NewInt(6), + s.grp.NewInt(7), sidhPrivKey, sidhPubKey, + format.Fingerprint{42}, false); err != nil { t.Fatalf("AddSent() returned an error: %+v", err) } c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} _, sidhPubKey = genSidhAKeys(rng) - if err := s.AddReceived(c, sidhPubKey); err != nil { + r := makeTestRound(t) + if err := s.AddReceived(c, sidhPubKey, r); err != nil { t.Fatalf("AddReceived() returned an error: %+v", err) } - err := s.DeleteAllRequests() + err = s.DeleteAllRequests() if err != nil { t.Fatalf("DeleteAllRequests returned an error: %+v", err) } @@ -1083,7 +856,7 @@ func TestStore_DeleteAllRequests(t *testing.T) { sr.partner) } - if _, exists := s.sentByFingerprints[sr.fingerprint]; exists { + if _, exists := s.sentByID[*sr.partner]; exists { t.Errorf("delete() failed to delete fingerprint for fp %v.", sr.fingerprint) } @@ -1094,20 +867,16 @@ func TestStore_DeleteAllRequests(t *testing.T) { } -func makeTestStore(t *testing.T) (*Store, *versioned.KV, []*cyclic.Int) { +func makeTestStore(t *testing.T) (*Store, *versioned.KV) { kv := versioned.NewKV(make(ekv.Memstore)) grp := cyclic.NewGroup(large.NewInt(173), large.NewInt(0)) - privKeys := make([]*cyclic.Int, 10) - for i := range privKeys { - privKeys[i] = grp.NewInt(rand.Int63n(170) + 1) - } - store, err := NewStore(kv, grp, privKeys) + store, err := NewOrLoadStore(kv, grp, &mockSentRequestHandler{}) if err != nil { t.Fatalf("Failed to create new Store: %+v", err) } - return store, kv, privKeys + return store, kv } func genSidhAKeys(rng io.Reader) (*sidh.PrivateKey, *sidh.PublicKey) { @@ -1133,3 +902,35 @@ func genSidhBKeys(rng io.Reader) (*sidh.PrivateKey, *sidh.PublicKey) { return sidHPrivKeyB, sidHPubKeyB } + +func makeTestRound(t *testing.T) rounds.Round { + nids := []*id.ID{ + id.NewIdFromString("one", id.User, t), + id.NewIdFromString("two", id.User, t), + id.NewIdFromString("three", id.User, t)} + r := rounds.Round{ + ID: 2, + State: states.REALTIME, + Topology: connect.NewCircuit(nids), + Timestamps: nil, + Errors: nil, + BatchSize: 0, + AddressSpaceSize: 0, + UpdateID: 0, + Raw: &mixmessages.RoundInfo{ + ID: 5, + UpdateID: 0, + State: 2, + BatchSize: 5, + Topology: [][]byte{[]byte("one"), []byte("two")}, + Timestamps: []uint64{uint64(time.Now().UnixNano()), uint64(time.Now().UnixNano())}, + Errors: nil, + ClientErrors: nil, + ResourceQueueTimeoutMillis: 0, + Signature: nil, + AddressSpaceSize: 0, + EccSignature: nil, + }, + } + return r +} diff --git a/auth/utils_test.go b/auth/utils_test.go index 0cee8e6e8..2a6c16ecc 100644 --- a/auth/utils_test.go +++ b/auth/utils_test.go @@ -1,12 +1,24 @@ package auth import ( + "gitlab.com/elixxir/client/auth/store" + "gitlab.com/elixxir/client/cmix/rounds" + "gitlab.com/elixxir/comms/mixmessages" "gitlab.com/elixxir/crypto/cyclic" + "gitlab.com/elixxir/primitives/states" + "gitlab.com/xx_network/comms/connect" "gitlab.com/xx_network/crypto/large" "gitlab.com/xx_network/primitives/id" "math/rand" + "testing" + "time" ) +type mockSentRequestHandler struct{} + +func (msrh *mockSentRequestHandler) Add(sr *store.SentRequest) {} +func (msrh *mockSentRequestHandler) Delete(sr *store.SentRequest) {} + func getGroup() *cyclic.Group { return cyclic.NewGroup( large.NewIntFromString("E2EE983D031DC1DB6F1A7A67DF0E9A8E5561DB8E8D4941"+ @@ -42,3 +54,35 @@ func newOwnership(s string) []byte { copy(ownership[:], s) return ownership } + +func makeTestRound(t *testing.T) rounds.Round { + nids := []*id.ID{ + id.NewIdFromString("one", id.User, t), + id.NewIdFromString("two", id.User, t), + id.NewIdFromString("three", id.User, t)} + r := rounds.Round{ + ID: 2, + State: states.REALTIME, + Topology: connect.NewCircuit(nids), + Timestamps: nil, + Errors: nil, + BatchSize: 0, + AddressSpaceSize: 0, + UpdateID: 0, + Raw: &mixmessages.RoundInfo{ + ID: 5, + UpdateID: 0, + State: 2, + BatchSize: 5, + Topology: [][]byte{[]byte("test"), []byte("test")}, + Timestamps: []uint64{uint64(time.Now().UnixNano()), uint64(time.Now().UnixNano())}, + Errors: nil, + ClientErrors: nil, + ResourceQueueTimeoutMillis: 0, + Signature: nil, + AddressSpaceSize: 0, + EccSignature: nil, + }, + } + return r +} diff --git a/single/message/collator_test.go b/single/message/collator_test.go index a51721188..6d7888326 100644 --- a/single/message/collator_test.go +++ b/single/message/collator_test.go @@ -9,7 +9,7 @@ import ( // Happy path func Test_newCollator(t *testing.T) { - messageCount := uint64(10) + messageCount := uint8(10) expected := &Collator{ payloads: make([][]byte, messageCount), maxNum: unsetCollatorMax, @@ -39,7 +39,7 @@ func TestCollator_collate(t *testing.T) { msgParts[i].SetContents(buff.Next(msgPayloadSize)) } - c := NewCollator(uint64(messageCount)) + c := NewCollator(uint8(messageCount)) i := 0 var fullPayload []byte diff --git a/single/message/request.go b/single/message/request.go index 9054aeef1..a09d07223 100644 --- a/single/message/request.go +++ b/single/message/request.go @@ -129,7 +129,7 @@ const ( numRequestPartsSize = 1 maxResponsePartsSize = 1 sizeSize = 2 - transmitPlMinSize = nonceSize + maxResponsePartsSize + sizeSize + transmitPlMinSize = nonceSize + numRequestPartsSize + maxResponsePartsSize + sizeSize ) // RequestPayload is the structure of Request's payload. diff --git a/single/message/request_test.go b/single/message/request_test.go index dc24b689d..0e4cd0878 100644 --- a/single/message/request_test.go +++ b/single/message/request_test.go @@ -10,7 +10,6 @@ package message import ( "bytes" "encoding/binary" - "gitlab.com/elixxir/client/single" "gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/e2e/singleUse" "gitlab.com/elixxir/primitives/format" @@ -96,7 +95,7 @@ func TestTransmitMessage_Marshal_Unmarshal(t *testing.T) { msgBytes := m.Marshal() - newMsg, err := unmarshalRequest(msgBytes, pubKeySize) + newMsg, err := UnmarshalRequest(msgBytes, pubKeySize) if err != nil { t.Errorf("unmarshalRequest produced an error: %+v", err) } @@ -109,7 +108,7 @@ func TestTransmitMessage_Marshal_Unmarshal(t *testing.T) { // Error path: public key size is larger than byte slice. func Test_unmarshalTransmitMessage_PubKeySizeError(t *testing.T) { - _, err := unmarshalRequest([]byte{1, 2, 3}, 5) + _, err := UnmarshalRequest([]byte{1, 2, 3}, 5) if err == nil { t.Error("unmarshalRequest() did not produce an error when the " + "byte slice is smaller than the public key size.") @@ -179,14 +178,19 @@ func Test_newTransmitMessagePayload(t *testing.T) { payloadSize := prng.Intn(2000) expected := RequestPayload{ data: make([]byte, payloadSize), - tagFP: make([]byte, tagFPSize), nonce: make([]byte, nonceSize), + numRequestParts: make([]byte, numRequestPartsSize), maxResponseParts: make([]byte, maxResponsePartsSize), size: make([]byte, sizeSize), contents: make([]byte, payloadSize-transmitPlMinSize), } + expected.numRequestParts[0] = 1 + binary.BigEndian.PutUint16(expected.size, uint16(payloadSize-transmitPlMinSize)) + expected.SetMaxResponseParts(10) + expected.data = append(expected.nonce, append(expected.numRequestParts, append(expected.maxResponseParts, append(expected.size, expected.contents...)...)...)...) - mp := NewRequestPayload(payloadSize) + payload := make([]byte, payloadSize-transmitPlMinSize) + mp := NewRequestPayload(payloadSize, payload, 10) if !reflect.DeepEqual(expected, mp) { t.Errorf("NewRequestPayload() did not produce the expected "+ @@ -203,23 +207,31 @@ func Test_newTransmitMessagePayload_PayloadSizeError(t *testing.T) { "+ the message count.") } }() + payloadSize := 10 + prng := rand.New(rand.NewSource(42)) + payload := make([]byte, payloadSize) + _, err := prng.Read(payload) + if err != nil { + t.Errorf("Failed to read to payload: %+v", err) + } - _ = NewRequestPayload(10) + _ = NewRequestPayload(10, payload, 5) } // Happy path. func Test_mapTransmitMessagePayload(t *testing.T) { prng := rand.New(rand.NewSource(42)) - tagFP := singleUse.NewTagFP("Tag") nonceBytes := make([]byte, nonceSize) - num := uint8(prng.Uint64()) + numRequestParts := make([]byte, numRequestPartsSize) + numRequestParts[0] = 1 + maxResponseParts := make([]byte, maxResponsePartsSize) size := []byte{uint8(prng.Uint64()), uint8(prng.Uint64())} contents := make([]byte, prng.Intn(1000)) prng.Read(contents) var data []byte - data = append(data, tagFP.Bytes()...) data = append(data, nonceBytes...) - data = append(data, num) + data = append(data, numRequestParts...) + data = append(data, maxResponseParts...) data = append(data, size...) data = append(data, contents...) mp := mapRequestPayload(data) @@ -229,19 +241,18 @@ func Test_mapTransmitMessagePayload(t *testing.T) { "for data.\nexpected: %+v\nreceived: %+v", data, mp.data) } - if !bytes.Equal(tagFP.Bytes(), mp.tagFP) { - t.Errorf("mapRequestPayload() failed to map the correct bytes "+ - "for tagFP.\nexpected: %+v\nreceived: %+v", tagFP.Bytes(), mp.tagFP) - } - if !bytes.Equal(nonceBytes, mp.nonce) { t.Errorf("mapRequestPayload() failed to map the correct bytes "+ "for the nonce.\nexpected: %s\nreceived: %s", nonceBytes, mp.nonce) } - if num != mp.maxResponseParts[0] { + if !bytes.Equal(numRequestParts, mp.numRequestParts) { t.Errorf("mapRequestPayload() failed to map the correct bytes "+ - "for maxResponseParts.\nexpected: %d\nreceived: %d", num, mp.maxResponseParts[0]) + "for the numRequestParts.\nexpected: %s\nreceived: %s", nonceBytes, mp.nonce) + } + + if !bytes.Equal(maxResponseParts, mp.maxResponseParts) { + } if !bytes.Equal(size, mp.size) { @@ -287,7 +298,14 @@ func Test_unmarshalTransmitMessagePayload(t *testing.T) { // Happy path. func TestTransmitMessagePayload_GetRID(t *testing.T) { prng := rand.New(rand.NewSource(42)) - mp := NewRequestPayload(prng.Intn(2000)) + payloadSize := prng.Intn(2000) + payload := make([]byte, payloadSize-transmitPlMinSize) + _, err := prng.Read(payload) + if err != nil { + t.Errorf("Failed to read to payload: %+v", err) + } + + mp := NewRequestPayload(payloadSize, payload, 5) expectedRID := singleUse.NewRecipientID(getGroup().NewInt(42), mp.Marshal()) testRID := mp.GetRID(getGroup().NewInt(42)) @@ -301,12 +319,19 @@ func TestTransmitMessagePayload_GetRID(t *testing.T) { // Happy path. func Test_transmitMessagePayload_SetNonce_GetNonce(t *testing.T) { prng := rand.New(rand.NewSource(42)) - mp := NewRequestPayload(prng.Intn(2000)) + payloadSize := prng.Intn(2000) + payload := make([]byte, payloadSize-transmitPlMinSize) + _, err := prng.Read(payload) + if err != nil { + t.Errorf("Failed to read to payload: %+v", err) + } + + mp := NewRequestPayload(payloadSize, payload, 5) expectedNonce := prng.Uint64() expectedNonceBytes := make([]byte, 8) binary.BigEndian.PutUint64(expectedNonceBytes, expectedNonce) - err := mp.SetNonce(strings.NewReader(string(expectedNonceBytes))) + err = mp.SetNonce(strings.NewReader(string(expectedNonceBytes))) if err != nil { t.Errorf("SetNonce() produced an error: %+v", err) } @@ -320,9 +345,17 @@ func Test_transmitMessagePayload_SetNonce_GetNonce(t *testing.T) { // Error path: RNG return an error. func Test_transmitMessagePayload_SetNonce_RngError(t *testing.T) { prng := rand.New(rand.NewSource(42)) - mp := NewRequestPayload(prng.Intn(2000)) - err := mp.SetNonce(strings.NewReader("")) - if !single.check(err, "failed to generate nonce") { + payloadSize := prng.Intn(2000) + payload := make([]byte, payloadSize-transmitPlMinSize) + _, err := prng.Read(payload) + if err != nil { + t.Errorf("Failed to read to payload: %+v", err) + } + + mp := NewRequestPayload(payloadSize, payload, 5) + err = mp.SetNonce(strings.NewReader("")) + + if !check(err, "failed to generate nonce") { t.Errorf("SetNonce() did not return an error when nonce generation "+ "fails: %+v", err) } @@ -331,7 +364,14 @@ func Test_transmitMessagePayload_SetNonce_RngError(t *testing.T) { // Happy path. func TestTransmitMessagePayload_SetMaxParts_GetMaxParts(t *testing.T) { prng := rand.New(rand.NewSource(42)) - mp := NewRequestPayload(prng.Intn(2000)) + payloadSize := prng.Intn(2000) + payload := make([]byte, payloadSize-transmitPlMinSize) + _, err := prng.Read(payload) + if err != nil { + t.Errorf("Failed to read to payload: %+v", err) + } + + mp := NewRequestPayload(payloadSize, payload, 5) count := uint8(prng.Uint64()) mp.SetMaxResponseParts(count) @@ -346,12 +386,13 @@ func TestTransmitMessagePayload_SetMaxParts_GetMaxParts(t *testing.T) { // Happy path. func TestTransmitMessagePayload_SetContents_GetContents_GetContentsSize_GetMaxContentsSize(t *testing.T) { prng := rand.New(rand.NewSource(42)) - mp := NewRequestPayload(format.MinimumPrimeSize) + payloadSize := format.MinimumPrimeSize contentsSize := (format.MinimumPrimeSize - transmitPlMinSize) / 2 contents := make([]byte, contentsSize) prng.Read(contents) - mp.SetContents(contents) + mp := NewRequestPayload(payloadSize, contents, 5) + testContents := mp.GetContents() if !bytes.Equal(contents, testContents) { t.Errorf("GetContents() did not return the expected contents."+ @@ -378,7 +419,15 @@ func TestTransmitMessagePayload_SetContents(t *testing.T) { } }() - mp := NewRequestPayload(format.MinimumPrimeSize) + prng := rand.New(rand.NewSource(42)) + payloadSize := format.MinimumPrimeSize + payload := make([]byte, payloadSize-transmitPlMinSize) + _, err := prng.Read(payload) + if err != nil { + t.Errorf("Failed to read to payload: %+v", err) + } + + mp := NewRequestPayload(payloadSize, payload, 5) mp.SetContents(make([]byte, format.MinimumPrimeSize+1)) } @@ -399,3 +448,8 @@ func getGroup() *cyclic.Group { "84A09EC723742DC35873847AEF49F66E43873", 16), large.NewIntFromString("2", 16)) } + +// check returns true if the error is not nil and contains the substring. +func check(err error, subStr string) bool { + return err != nil && strings.Contains(err.Error(), subStr) +} -- GitLab