diff --git a/auth/params.go b/auth/params.go index 8832b06d1881b3a6df3cc986996aac9e81012a7e..01078076b8db90b31448c7bff892249d5eb583e1 100644 --- a/auth/params.go +++ b/auth/params.go @@ -1 +1,8 @@ package auth + +type Param struct { + ReplayRequests bool + + RequestTag string + ResetTag string +} diff --git a/auth/receivedConfirm.go b/auth/receivedConfirm.go index ed6ccdd7654b92705f6e5d4ae82b82f015c6b391..96d88f4b64cfa50cc949adf7901996334f9a1383 100644 --- a/auth/receivedConfirm.go +++ b/auth/receivedConfirm.go @@ -26,6 +26,15 @@ func (rcs *receivedConfirmService) Process(msg format.Message, state := rcs.s + // lookup keypair + kp, exist := state.getRegisteredIDs(receptionID.Source) + + if !exist { + jww.ERROR.Printf("received a confirm for %s, " + + "but they are not registered with auth, cannot process") + return + } + //parse the confirm baseFmt, partnerPubKey, err := handleBaseFormat(msg, state.e2e.GetGroup()) if err != nil { @@ -35,9 +44,6 @@ func (rcs *receivedConfirmService) Process(msg format.Message, return } - // lookup keypair - kp := state.registeredIDs[*receptionID.Source] - jww.TRACE.Printf("processing confirm: \n\t MYPUBKEY: %s "+ "\n\t PARTNERPUBKEY: %s \n\t ECRPAYLOAD: %s \n\t MAC: %s", kp.pubkey.TextVerbose(16, 0), diff --git a/auth/receivedRequest.go b/auth/receivedRequest.go index 327a746ed4b1130e0d95632c526ba01606b306a1..70e43ab01b8d8b0026bcd2bc7e0b99be9849a178 100644 --- a/auth/receivedRequest.go +++ b/auth/receivedRequest.go @@ -29,6 +29,15 @@ func (rrs *receivedRequestService) Process(message format.Message, state := rrs.s + //lookup the keypair + kp, exist := state.getRegisteredIDs(receptionID.Source) + + if !exist { + jww.ERROR.Printf("received a confirm for %s, " + + "but they are not registered with auth, cannot process") + return + } + // check if the timestamp is before the id was created and therefore // should be ignored tid, err := state.net.GetIdentity(receptionID.Source) @@ -52,9 +61,6 @@ func (rrs *receivedRequestService) Process(message format.Message, return } - //lookup the keypair - kp := state.registeredIDs[*receptionID.Source] - jww.TRACE.Printf("processing requests: \n\t MYPUBKEY: %s "+ "\n\t PARTNERPUBKEY: %s \n\t ECRPAYLOAD: %s \n\t MAC: %s", kp.pubkey.TextVerbose(16, 0), @@ -126,7 +132,7 @@ func (rrs *receivedRequestService) Process(message format.Message, // do not need to be handled _, _ = sendAuthConfirm(state.net, partnerID, receptionID.Source, keyfp, confirmPayload, mac, state.event) - } else if state.replayRequests { + } else if state.params.ReplayRequests { //if we did not already accept, auto replay the request if cb, exist := state.requestCallbacks.Get(receptionID.Source); exist { cb(c, receptionID, round) diff --git a/auth/registeredIDs.go b/auth/registeredIDs.go new file mode 100644 index 0000000000000000000000000000000000000000..cc1d1adb49645f47a6903b55a15169cfa1255e14 --- /dev/null +++ b/auth/registeredIDs.go @@ -0,0 +1,42 @@ +package auth + +import ( + "gitlab.com/elixxir/crypto/cyclic" + "gitlab.com/xx_network/primitives/id" + "sync" +) + +type registeredIDs struct { + r map[id.ID]keypair + mux sync.RWMutex +} + +type keypair struct { + privkey *cyclic.Int + //generated from pubkey on instantiation + pubkey *cyclic.Int +} + +func newRegisteredIDs() *registeredIDs { + return ®isteredIDs{ + r: make(map[id.ID]keypair), + mux: sync.RWMutex{}, + } +} + +func (rids *registeredIDs) addRegisteredIDs(id *id.ID, privkey, pubkey *cyclic.Int) { + rids.mux.Lock() + defer rids.mux.Unlock() + rids.r[*id] = keypair{ + privkey: privkey, + pubkey: pubkey, + } +} + +func (rids *registeredIDs) getRegisteredIDs(id *id.ID) (keypair, bool) { + rids.mux.Lock() + defer rids.mux.Unlock() + + kp, exists := rids.r[*id] + return kp, exists +} diff --git a/auth/state.go b/auth/state.go index 6cb7f5ebc1453d5cc6a7acb8b5bb4475e768f546..698e157e0b38492924fd288ae51721f849d3d834 100644 --- a/auth/state.go +++ b/auth/state.go @@ -15,6 +15,7 @@ import ( "gitlab.com/elixxir/client/interfaces/message" "gitlab.com/elixxir/client/network" "gitlab.com/elixxir/client/storage" + "gitlab.com/elixxir/client/storage/versioned" "gitlab.com/elixxir/client/switchboard" "gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/fastRNG" @@ -33,33 +34,28 @@ type State struct { store *store.Store event event.Manager - registeredIDs map[id.ID]keypair + registeredIDs - replayRequests bool + params Param } -type keypair struct { - privkey *cyclic.Int - //generated from pubkey on instantiation - pubkey *cyclic.Int -} - -func NewManager(sw interfaces.Switchboard, storage *storage.Session, - net interfaces.NetworkManager, rng *fastRNG.StreamGenerator, - backupTrigger interfaces.TriggerBackup, replayRequests bool) *State { +func NewManager(kv *versioned.KV, net network.Manager, e2e e2e.Handler, + rng *fastRNG.StreamGenerator, event event.Manager, params Param) *State { m := &State{ requestCallbacks: newCallbackMap(), confirmCallbacks: newCallbackMap(), resetCallbacks: newCallbackMap(), - rawMessages: make(chan message.Receive, 1000), - storage: storage, - net: net, - rng: rng, - backupTrigger: backupTrigger, - replayRequests: replayRequests, - } - sw.RegisterChannel("Auth", switchboard.AnyUser(), message.Raw, m.rawMessages) + net: net, + e2e: e2e, + rng: rng, + + params: params, + event: event, + + //created lazily in add identity, see add identity for more details + store: nil, + } return m } @@ -77,3 +73,25 @@ func (s *State) ReplayRequests() { } } } + +// AddIdentity adds an identity and its callbacks to receive requests. +// This auto registers the appropriate services +// Note: the internal storage for auth is loaded on the first added identity, +// with that identity as the default identity. This is to allow v2.0 +// instantiations of this library (pre April 2022) to load, before requests were +// keyed on both parties IDs +func (s *State) AddIdentity(identity *id.ID, pubkey, privkey *cyclic.Int, + request, confirm, reset Callback) { + if s.store == nil { + //load store + } + +} + +func (s *State) AddDefaultIdentity(identity *id.ID, pubkey, privkey *cyclic.Int, + request, confirm, reset Callback) { + if s.store == nil { + //load store + } + +} diff --git a/auth/store/store.go b/auth/store/store.go index eb4d5a610ecae9f46b66f2cdb03b483d27599eef..9fcf821dbb7ca04c64fb5f6ac4a71b7ce49e7c25 100644 --- a/auth/store/store.go +++ b/auth/store/store.go @@ -40,6 +40,8 @@ type Store struct { srh SentRequestHandler + unloadedDefault []requestDisk + mux sync.RWMutex } @@ -95,7 +97,6 @@ func LoadStore(kv *versioned.KV, defaultID *id.ID, grp *cyclic.Group, srh SentRe jww.TRACE.Printf("%d found when loading AuthStore", len(requestList)) - //process receivedByID for _, rDisk := range requestList { requestType := RequestType(rDisk.T) @@ -109,7 +110,8 @@ func LoadStore(kv *versioned.KV, defaultID *id.ID, grp *cyclic.Group, srh SentRe // load the self id used. If it is blank, that means this is an older // version request, and replace it with the default ID if len(rDisk.MyID) == 0 { - myID = defaultID + s.unloadedDefault = append(s.unloadedDefault, rDisk) + continue } else { myID, err = id.Unmarshal(rDisk.ID) if err != nil {