Skip to content
Snippets Groups Projects
Commit 4f21a72b authored by Josh Brooks's avatar Josh Brooks
Browse files

WIP: Work on UD manager

parent 3d2544f9
No related branches found
No related tags found
4 merge requests!510Release,!207WIP: Client Restructure,!203Symmetric broadcast,!199Xx 3866/user discovery
...@@ -96,7 +96,7 @@ func NewUserDiscoveryFromBackup(client *Client, ...@@ -96,7 +96,7 @@ func NewUserDiscoveryFromBackup(client *Client,
jww.WARN.Printf("Loading manager without a registered phone number") jww.WARN.Printf("Loading manager without a registered phone number")
} }
m, err := ud.NewManagerFromBackup(&client.api, single, emailFact, phoneFact) m, err := ud.NewManagerFromBackup(&client.api, single, phoneFact)
if err != nil { if err != nil {
return nil, errors.WithMessage(err, "Failed to create User Discovery Manager") return nil, errors.WithMessage(err, "Failed to create User Discovery Manager")
} else { } else {
......
...@@ -21,7 +21,7 @@ import ( ...@@ -21,7 +21,7 @@ import (
// called along with the code to finalize the fact. // called along with the code to finalize the fact.
func (m *Manager) SendRegisterFact(f fact.Fact) (string, error) { func (m *Manager) SendRegisterFact(f fact.Fact) (string, error) {
jww.INFO.Printf("ud.SendRegisterFact(%s)", f.Stringify()) jww.INFO.Printf("ud.SendRegisterFact(%s)", f.Stringify())
return m.addFact(f, m.myID, m.comms) return m.addFact(f, m.e2e.GetReceptionID(), m.comms)
} }
func (m *Manager) addFact(inFact fact.Fact, myId *id.ID, aFC addFactComms) (string, error) { func (m *Manager) addFact(inFact fact.Fact, myId *id.ID, aFC addFactComms) (string, error) {
...@@ -42,7 +42,8 @@ func (m *Manager) addFact(inFact fact.Fact, myId *id.ID, aFC addFactComms) (stri ...@@ -42,7 +42,8 @@ func (m *Manager) addFact(inFact fact.Fact, myId *id.ID, aFC addFactComms) (stri
fHash := factID.Fingerprint(f) fHash := factID.Fingerprint(f)
// Sign our inFact for putting into the request // Sign our inFact for putting into the request
fSig, err := rsa.Sign(rand.Reader, m.privKey, hash.CMixHash, fHash, nil) privKey := m.user.PortableUserInfo().ReceptionRSA
fSig, err := rsa.Sign(rand.Reader, privKey, hash.CMixHash, fHash, nil)
if err != nil { if err != nil {
return "", err return "", err
} }
......
package ud
import (
"gitlab.com/elixxir/client/cmix"
"gitlab.com/elixxir/client/cmix/identity/receptionID"
"gitlab.com/elixxir/client/interfaces/user"
"gitlab.com/elixxir/client/single"
"gitlab.com/elixxir/client/stoppable"
"gitlab.com/elixxir/crypto/contact"
"gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/xx_network/crypto/csprng"
"gitlab.com/xx_network/primitives/id"
)
type Userinfo interface {
PortableUserInfo() user.Info
GetUsername() (string, error)
GetReceptionRegistrationValidationSignature() []byte
}
type SingleInterface interface {
TransmitRequest(recipient contact.Contact, tag string, payload []byte,
callback single.Response, param single.RequestParams, net cmix.Client, rng csprng.Source,
e2eGrp *cyclic.Group) (id.Round, receptionID.EphemeralIdentity, error)
StartProcesses() (stoppable.Stoppable, error)
}
...@@ -104,6 +104,8 @@ func lookup(services cmix.Client, callback single.Response, ...@@ -104,6 +104,8 @@ func lookup(services cmix.Client, callback single.Response,
// will be passed into the callback. // will be passed into the callback.
func (m *Manager) lookupResponseProcess(uid *id.ID, cb single.Response, func (m *Manager) lookupResponseProcess(uid *id.ID, cb single.Response,
payload []byte, err error) { payload []byte, err error) {
grp := m.e2e.GetGroup()
if err != nil { if err != nil {
go cb.Callback(contact.Contact{}, errors.WithMessage(err, "Failed to lookup.")) go cb.Callback(contact.Contact{}, errors.WithMessage(err, "Failed to lookup."))
return return
...@@ -124,7 +126,7 @@ func (m *Manager) lookupResponseProcess(uid *id.ID, cb single.Response, ...@@ -124,7 +126,7 @@ func (m *Manager) lookupResponseProcess(uid *id.ID, cb single.Response,
c := contact.Contact{ c := contact.Contact{
ID: uid, ID: uid,
DhPubKey: m.grp.NewIntFromBytes(lookupResponse.PubKey), DhPubKey: grp.NewIntFromBytes(lookupResponse.PubKey),
} }
if lookupResponse.Username != "" { if lookupResponse.Username != "" {
......
...@@ -6,43 +6,21 @@ import ( ...@@ -6,43 +6,21 @@ import (
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/api" "gitlab.com/elixxir/client/api"
"gitlab.com/elixxir/client/cmix" "gitlab.com/elixxir/client/cmix"
"gitlab.com/elixxir/client/cmix/identity/receptionID"
"gitlab.com/elixxir/client/e2e" "gitlab.com/elixxir/client/e2e"
"gitlab.com/elixxir/client/event" "gitlab.com/elixxir/client/event"
"gitlab.com/elixxir/client/interfaces/user"
"gitlab.com/elixxir/client/single"
"gitlab.com/elixxir/client/stoppable"
"gitlab.com/elixxir/client/storage/versioned" "gitlab.com/elixxir/client/storage/versioned"
store "gitlab.com/elixxir/client/ud/store/ud"
"gitlab.com/elixxir/comms/client" "gitlab.com/elixxir/comms/client"
"gitlab.com/elixxir/crypto/contact" "gitlab.com/elixxir/crypto/contact"
"gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/elixxir/crypto/fastRNG" "gitlab.com/elixxir/crypto/fastRNG"
"gitlab.com/elixxir/primitives/fact" "gitlab.com/elixxir/primitives/fact"
"gitlab.com/xx_network/comms/connect" "gitlab.com/xx_network/comms/connect"
"gitlab.com/xx_network/crypto/csprng"
"gitlab.com/xx_network/crypto/signature/rsa" "gitlab.com/xx_network/crypto/signature/rsa"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"math" "math"
"time" "time"
) )
type SingleInterface interface {
TransmitRequest(recipient contact.Contact, tag string, payload []byte,
callback single.Response, param single.RequestParams, net cmix.Client, rng csprng.Source,
e2eGrp *cyclic.Group) (id.Round, receptionID.EphemeralIdentity, error)
StartProcesses() (stoppable.Stoppable, error)
}
type Userinfo interface {
PortableUserInfo() user.Info
GetUsername() (string, error)
GetReceptionRegistrationValidationSignature() []byte
}
const (
// todo: populate with err messages
)
// todo: newuserDiscRegistratration, loadUserDiscRegistration // todo: newuserDiscRegistratration, loadUserDiscRegistration
// neworLoad? // neworLoad?
// fixme: search/lookup off ud object // fixme: search/lookup off ud object
...@@ -68,13 +46,6 @@ type Manager struct { ...@@ -68,13 +46,6 @@ type Manager struct {
kv *versioned.KV kv *versioned.KV
// Loaded from external access
privKey *rsa.PrivateKey
grp *cyclic.Group
// internal structures
myID *id.ID
// alternate User discovery service to circumvent production // alternate User discovery service to circumvent production
alternativeUd *alternateUd alternativeUd *alternateUd
} }
...@@ -90,9 +61,9 @@ type alternateUd struct { ...@@ -90,9 +61,9 @@ type alternateUd struct {
// NewManager builds a new user discovery manager. It requires that an updated // NewManager builds a new user discovery manager. It requires that an updated
// NDF is available and will error if one is not. // NDF is available and will error if one is not.
// todo: docstring, organize the order of arguments in a meaningful way // todo: docstring, organize the order of arguments in a meaningful way
func NewManager(services cmix.Client, e2e e2e.Handler, events event.Manager, func NewManager(services cmix.Client, e2e e2e.Handler,
comms Comms, userStore Userinfo, rng *fastRNG.StreamGenerator, events event.Manager, comms Comms, userStore Userinfo,
privKey *rsa.PrivateKey, username string, rng *fastRNG.StreamGenerator, username string,
kv *versioned.KV) (*Manager, error) { kv *versioned.KV) (*Manager, error) {
jww.INFO.Println("ud.NewManager()") jww.INFO.Println("ud.NewManager()")
...@@ -114,9 +85,6 @@ func NewManager(services cmix.Client, e2e e2e.Handler, events event.Manager, ...@@ -114,9 +85,6 @@ func NewManager(services cmix.Client, e2e e2e.Handler, events event.Manager,
comms: comms, comms: comms,
rng: rng, rng: rng,
store: udStore, store: udStore,
myID: e2e.GetReceptionID(),
grp: e2e.GetGroup(),
privKey: privKey,
user: userStore, user: userStore,
kv: kv, kv: kv,
} }
...@@ -129,13 +97,6 @@ func NewManager(services cmix.Client, e2e e2e.Handler, events event.Manager, ...@@ -129,13 +97,6 @@ func NewManager(services cmix.Client, e2e e2e.Handler, events event.Manager,
"information, is there network access?: Cert not present.") "information, is there network access?: Cert not present.")
} }
// Pull user discovery ID from NDF
udID, err := id.Unmarshal(def.UDB.ID)
if err != nil {
return nil, errors.Errorf("failed to unmarshal UD ID "+
"from NDF: %+v", err)
}
udHost, err := m.getOrAddUdHost() udHost, err := m.getOrAddUdHost()
if err != nil { if err != nil {
return nil, errors.WithMessage(err, "User Discovery host object could "+ return nil, errors.WithMessage(err, "User Discovery host object could "+
...@@ -162,36 +123,38 @@ func NewManager(services cmix.Client, e2e e2e.Handler, events event.Manager, ...@@ -162,36 +123,38 @@ func NewManager(services cmix.Client, e2e e2e.Handler, events event.Manager,
// NewManagerFromBackup builds a new user discover manager from a backup. // NewManagerFromBackup builds a new user discover manager from a backup.
// It will construct a manager that is already registered and restore // It will construct a manager that is already registered and restore
// already registered facts into store. // already registered facts into store.
func NewManagerFromBackup(client *api.Client, single *single.Manager, func NewManagerFromBackup(services cmix.Client, e2e e2e.Handler, comms Comms, userStore Userinfo, rng *fastRNG.StreamGenerator, email, phone fact.Fact, kv *versioned.KV) (*Manager, error) {
email, phone fact.Fact) (*Manager, error) {
jww.INFO.Println("ud.NewManagerFromBackup()") jww.INFO.Println("ud.NewManagerFromBackup()")
if client.NetworkFollowerStatus() != api.Running { if client.NetworkFollowerStatus() != api.Running {
return nil, errors.New( return nil, errors.New(
"cannot start UD Manager when network follower is not running.") "cannot start UD Manager when " +
"network follower is not running.")
} }
registered := uint32(0)
m := &Manager{ m := &Manager{
client: client, services: services,
comms: client.GetComms(), e2e: e2e,
rng: client.GetRng(), comms: comms,
sw: client.GetSwitchboard(), user: userStore,
storage: client.GetStorage(), rng: rng,
net: client.GetNetworkInterface(), kv: kv,
single: single, }
registered: &registered,
} udStore, err := store.NewOrLoadStore(kv)
if err != nil {
err := m.client.GetStorage().GetUd(). return nil, err
BackUpMissingFacts(email, phone) }
m.store = udStore
err = m.store.BackUpMissingFacts(email, phone)
if err != nil { if err != nil {
return nil, errors.WithMessage(err, "Failed to restore UD store "+ return nil, errors.WithMessage(err, "Failed to restore UD store "+
"from backup") "from backup")
} }
// check that user discovery is available in the NDF // check that user discovery is available in the NDF
def := m.net.GetInstance().GetPartialNdf().Get() def := m.services.GetInstance().GetPartialNdf().Get()
if def.UDB.Cert == "" { if def.UDB.Cert == "" {
return nil, errors.New("NDF does not have User Discovery information, " + return nil, errors.New("NDF does not have User Discovery information, " +
...@@ -206,21 +169,14 @@ func NewManagerFromBackup(client *api.Client, single *single.Manager, ...@@ -206,21 +169,14 @@ func NewManagerFromBackup(client *api.Client, single *single.Manager,
hp.SendTimeout = 3 * time.Second hp.SendTimeout = 3 * time.Second
hp.AuthEnabled = false hp.AuthEnabled = false
m.myID = m.storage.User().GetCryptographicIdentity().GetReceptionID()
// Get the commonly used data from storage
m.privKey = m.storage.GetUser().ReceptionRSA
// Set as registered. Since it's from a backup, // Set as registered. Since it's from a backup,
// the client is already registered // the client is already registered
// todo: maybe we don't need this?
if err = m.setRegistered(); err != nil { if err = m.setRegistered(); err != nil {
return nil, errors.WithMessage(err, "failed to set client as "+ return nil, errors.WithMessage(err, "failed to set client as "+
"registered with user discovery.") "registered with user discovery.")
} }
// Store the pointer to the group locally for easy access
m.grp = m.storage.E2e().GetGroup()
return m, nil return m, nil
} }
...@@ -235,7 +191,6 @@ func LoadManager(services cmix.Client, e2e e2e.Handler, events event.Manager, ...@@ -235,7 +191,6 @@ func LoadManager(services cmix.Client, e2e e2e.Handler, events event.Manager,
comms: comms, comms: comms,
user: userStore, user: userStore,
rng: rng, rng: rng,
privKey: privKey,
kv: kv, kv: kv,
} }
...@@ -314,10 +269,11 @@ func (m *Manager) GetStringifiedFacts() []string { ...@@ -314,10 +269,11 @@ func (m *Manager) GetStringifiedFacts() []string {
// GetContact returns the contact for UD as retrieved from the NDF. // GetContact returns the contact for UD as retrieved from the NDF.
func (m *Manager) GetContact() (contact.Contact, error) { func (m *Manager) GetContact() (contact.Contact, error) {
grp := m.e2e.GetGroup()
// Return alternative User discovery contact if set // Return alternative User discovery contact if set
if m.alternativeUd != nil { if m.alternativeUd != nil {
// Unmarshal UD DH public key // Unmarshal UD DH public key
alternativeDhPubKey := m.grp.NewInt(1) alternativeDhPubKey := grp.NewInt(1)
if err := alternativeDhPubKey. if err := alternativeDhPubKey.
UnmarshalJSON(m.alternativeUd.dhPubKey); err != nil { UnmarshalJSON(m.alternativeUd.dhPubKey); err != nil {
return contact.Contact{}, return contact.Contact{},
...@@ -343,7 +299,7 @@ func (m *Manager) GetContact() (contact.Contact, error) { ...@@ -343,7 +299,7 @@ func (m *Manager) GetContact() (contact.Contact, error) {
} }
// Unmarshal UD DH public key // Unmarshal UD DH public key
dhPubKey := m.grp.NewInt(1) dhPubKey := grp.NewInt(1)
if err = dhPubKey.UnmarshalJSON(netDef.UDB.DhPubKey); err != nil { if err = dhPubKey.UnmarshalJSON(netDef.UDB.DhPubKey); err != nil {
return contact.Contact{}, return contact.Contact{},
errors.WithMessage(err, "Failed to unmarshal UD DH "+ errors.WithMessage(err, "Failed to unmarshal UD DH "+
......
...@@ -42,14 +42,15 @@ func (m *Manager) removeFact(f fact.Fact, ...@@ -42,14 +42,15 @@ func (m *Manager) removeFact(f fact.Fact,
fHash := factID.Fingerprint(f) fHash := factID.Fingerprint(f)
// Sign our inFact for putting into the request // Sign our inFact for putting into the request
fSig, err := rsa.Sign(rand.Reader, m.privKey, hash.CMixHash, fHash, nil) privKey := m.user.PortableUserInfo().ReceptionRSA
fSig, err := rsa.Sign(rand.Reader, privKey, hash.CMixHash, fHash, nil)
if err != nil { if err != nil {
return err return err
} }
// Create our Fact Removal Request message data // Create our Fact Removal Request message data
remFactMsg := mixmessages.FactRemovalRequest{ remFactMsg := mixmessages.FactRemovalRequest{
UID: m.myID.Marshal(), UID: m.e2e.GetReceptionID().Marshal(),
RemovalData: &mmFact, RemovalData: &mmFact,
FactSig: fSig, FactSig: fSig,
} }
...@@ -77,8 +78,9 @@ func (m *Manager) RemoveUser(f fact.Fact) error { ...@@ -77,8 +78,9 @@ func (m *Manager) RemoveUser(f fact.Fact) error {
if err != nil { if err != nil {
return err return err
} }
privKey := m.user.PortableUserInfo().ReceptionRSA
return removeUser(f, m.myID, m.privKey, m.comms, udHost) return removeUser(f, m.e2e.GetReceptionID(), privKey, m.comms, udHost)
} }
func removeUser(f fact.Fact, myId *id.ID, privateKey *rsa.PrivateKey, func removeUser(f fact.Fact, myId *id.ID, privateKey *rsa.PrivateKey,
......
...@@ -139,7 +139,7 @@ func hashFactList(list fact.FactList) ([]*HashFact, map[string]fact.Fact) { ...@@ -139,7 +139,7 @@ func hashFactList(list fact.FactList) ([]*HashFact, map[string]fact.Fact) {
func (m *Manager) parseContacts(response []*Contact, func (m *Manager) parseContacts(response []*Contact,
hashMap map[string]fact.Fact) ([]contact.Contact, error) { hashMap map[string]fact.Fact) ([]contact.Contact, error) {
contacts := make([]contact.Contact, len(response)) contacts := make([]contact.Contact, len(response))
grp := m.e2e.GetGroup()
// Convert each contact message into a new contact.Contact // Convert each contact message into a new contact.Contact
for i, c := range response { for i, c := range response {
// Unmarshal user ID bytes // Unmarshal user ID bytes
...@@ -154,7 +154,7 @@ func (m *Manager) parseContacts(response []*Contact, ...@@ -154,7 +154,7 @@ func (m *Manager) parseContacts(response []*Contact,
// Create new Contact // Create new Contact
contacts[i] = contact.Contact{ contacts[i] = contact.Contact{
ID: uid, ID: uid,
DhPubKey: m.grp.NewIntFromBytes(c.PubKey), DhPubKey: grp.NewIntFromBytes(c.PubKey),
Facts: facts, Facts: facts,
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment