diff --git a/bindings/e2e.go b/bindings/e2e.go index beef52f655626f9fead21961f60a5aedc78df966..22438e73df9db897e20b785b871d78aadba73307 100644 --- a/bindings/e2e.go +++ b/bindings/e2e.go @@ -8,6 +8,7 @@ package bindings import ( + "gitlab.com/xx_network/primitives/id" "sync" "github.com/pkg/errors" @@ -125,6 +126,44 @@ func (e *E2e) GetContact() []byte { return e.api.GetReceptionIdentity().GetContact().Marshal() } +// GetUdAddressFromNdf retrieve the User Discovery's network address fom the NDF. +func (e *E2e) GetUdAddressFromNdf() string { + return e.api.GetCmix().GetInstance().GetPartialNdf(). + Get().UDB.Address +} + +// GetUdCertFromNdf retrieves the User Discovery's TLS certificate from the NDF. +func (e *E2e) GetUdCertFromNdf() []byte { + return []byte(e.api.GetCmix().GetInstance().GetPartialNdf().Get().UDB.Cert) +} + +// GetUdContactFromNdf assembles the User Discovery's contact file from the data +// within the NDF. +// +// Returns +// - []byte - A byte marshalled contact.Contact. +func (e *E2e) GetUdContactFromNdf() ([]byte, error) { + udIdData := e.api.GetCmix().GetInstance().GetPartialNdf().Get().UDB.ID + udId, err := id.Unmarshal(udIdData) + if err != nil { + return nil, err + } + + udDhPubKeyData := e.api.GetCmix().GetInstance().GetPartialNdf().Get().UDB.DhPubKey + udDhPubKey := e.api.GetE2E().GetGroup().NewInt(1) + err = udDhPubKey.UnmarshalJSON(udDhPubKeyData) + if err != nil { + return nil, err + } + + udContact := contact.Contact{ + ID: udId, + DhPubKey: udDhPubKey, + } + + return udContact.Marshal(), nil +} + // AuthCallbacks is the bindings-specific interface for auth.Callbacks methods. type AuthCallbacks interface { Request(contact, receptionId []byte, ephemeralId, roundId int64) diff --git a/bindings/ud.go b/bindings/ud.go index b4e2dc395e3e3d0fe557588f899a536fea770f9e..6ce8f8b3af073057e210675ff3203ef5ba364746 100644 --- a/bindings/ud.go +++ b/bindings/ud.go @@ -105,17 +105,34 @@ type UdNetworkStatus interface { // Manager functions // //////////////////////////////////////////////////////////////////////////////// -// LoadOrNewUserDiscovery creates a bindings-level user discovery manager. +// NewOrLoadUd loads an existing Manager from storage or creates a +// new one if there is no extant storage information. Parameters need be provided +// to specify how to connect to the User Discovery service. These parameters may be used +// to contact either the UD server hosted by the xx network team or a custom +// third-party operated server. For the former, all the information may be pulled from the +// NDF using the bindings. // -// Parameters: +// Params // - e2eID - e2e object ID in the tracker // - follower - network follower func wrapped in UdNetworkStatus // - username - the username the user wants to register with UD. // If the user is already registered, this field may be blank -// - registrationValidationSignature - the signature provided by the xx network. -// This signature is optional for other consumers who deploy their own UD. -func LoadOrNewUserDiscovery(e2eID int, follower UdNetworkStatus, - username string, registrationValidationSignature []byte) ( +// - networkValidationSig is a signature provided by the network (i.e. the client registrar). +// This may be nil, however UD may return an error in some cases (e.g. in a production level +// environment). +// - cert is the TLS certificate for the UD server this call will connect with. +// You may use the UD server run by the xx network team by using E2e.GetUdCertFromNdf. +// - contactFile is the data within a marshalled contact.Contact. This represents the +// contact file of the server this call will connect with. +// You may use the UD server run by the xx network team by using E2e.GetUdContactFromNdf. +// - address is the IP address of the UD server this call will connect with. +// You may use the UD server run by the xx network team by using E2e.GetUdAddressFromNdf. +// +// Returns +// - A Manager object which is registered to the specified UD service. +func NewOrLoadUd(e2eID int, follower UdNetworkStatus, + username string, registrationValidationSignature, + cert, contactFile []byte, address string) ( *UserDiscovery, error) { // Get user from singleton @@ -124,16 +141,20 @@ func LoadOrNewUserDiscovery(e2eID int, follower UdNetworkStatus, return nil, err } + // Construct callback UdNetworkStatusFn := func() xxdk.Status { return xxdk.Status(follower.UdNetworkStatus()) } - u, err := ud.LoadOrNewManager(user.api, user.api.GetComms(), - UdNetworkStatusFn, username, registrationValidationSignature) + // Build manager + u, err := ud.NewOrLoad(user.api, user.api.GetComms(), + UdNetworkStatusFn, username, registrationValidationSignature, + cert, contactFile, address) if err != nil { return nil, err } + // Track and return manager return udTrackerSingleton.make(u), nil } @@ -146,8 +167,15 @@ func LoadOrNewUserDiscovery(e2eID int, follower UdNetworkStatus, // - follower - network follower func wrapped in UdNetworkStatus // - emailFactJson - nullable JSON marshalled email fact.Fact // - phoneFactJson - nullable JSON marshalled phone fact.Fact +// - cert is the TLS certificate for the UD server this call will connect with. +// You may use the UD server run by the xx network team by using E2e.GetUdCertFromNdf. +// - contactFile is the data within a marshalled contact.Contact. This represents the +// contact file of the server this call will connect with. +// You may use the UD server run by the xx network team by using E2e.GetUdContactFromNdf. +// - address is the IP address of the UD server this call will connect with. +// You may use the UD server run by the xx network team by using E2e.GetUdAddressFromNdf. func NewUdManagerFromBackup(e2eID int, follower UdNetworkStatus, emailFactJson, - phoneFactJson []byte) (*UserDiscovery, error) { + phoneFactJson []byte, cert, contactFile []byte, address string) (*UserDiscovery, error) { // Get user from singleton user, err := e2eTrackerSingleton.get(e2eID) @@ -175,7 +203,9 @@ func NewUdManagerFromBackup(e2eID int, follower UdNetworkStatus, emailFactJson, } u, err := ud.NewManagerFromBackup( - user.api, user.api.GetComms(), UdNetworkStatusFn, email, phone) + user.api, user.api.GetComms(), UdNetworkStatusFn, + email, phone, + cert, contactFile, address) if err != nil { return nil, err } @@ -196,12 +226,7 @@ func (ud *UserDiscovery) GetFacts() []byte { // GetContact returns the marshalled bytes of the contact.Contact for UD as // retrieved from the NDF. func (ud *UserDiscovery) GetContact() ([]byte, error) { - c, err := ud.api.GetContact() - if err != nil { - return nil, err - } - - return json.Marshal(c) + return ud.api.GetContact().Marshal(), nil } // ConfirmFact confirms a fact first registered via AddFact. The confirmation ID @@ -263,22 +288,6 @@ func (ud *UserDiscovery) RemoveFact(factJson []byte) error { return ud.api.RemoveFact(f) } -// SetAlternativeUserDiscovery sets the alternativeUd object within manager. -// Once set, any user discovery operation will go through the alternative -// user discovery service. -// -// To undo this operation, use UnsetAlternativeUserDiscovery. -func (ud *UserDiscovery) SetAlternativeUserDiscovery( - altCert, altAddress, contactFile []byte) error { - return ud.api.SetAlternativeUserDiscovery(altCert, altAddress, contactFile) -} - -// UnsetAlternativeUserDiscovery clears out the information from the Manager -// object. -func (ud *UserDiscovery) UnsetAlternativeUserDiscovery() error { - return ud.api.UnsetAlternativeUserDiscovery() -} - //////////////////////////////////////////////////////////////////////////////// // User Discovery Lookup // //////////////////////////////////////////////////////////////////////////////// diff --git a/cmd/ud.go b/cmd/ud.go index 10d423889ff8c1dcc2a363ad821af820db76beaa..73a47f02d60e32f588fa1e0f24395a082c23d689 100644 --- a/cmd/ud.go +++ b/cmd/ud.go @@ -10,6 +10,9 @@ package cmd import ( "fmt" + "gitlab.com/elixxir/client/xxdk" + "gitlab.com/elixxir/crypto/cyclic" + "gitlab.com/xx_network/primitives/id" "time" "gitlab.com/elixxir/client/single" @@ -60,11 +63,17 @@ var udCmd = &cobra.Command{ jww.TRACE.Printf("[UD] Connected!") + cert, contactFile, address, err := getUdContactInfo(user) + if err != nil { + jww.FATAL.Panicf("Failed to load UD contact information from NDF: %+v", err) + } + // Make user discovery manager userToRegister := viper.GetString(udRegisterFlag) jww.TRACE.Printf("[UD] Registering identity %v...", userToRegister) - userDiscoveryMgr, err := ud.LoadOrNewManager(user, user.GetComms(), - user.NetworkFollowerStatus, userToRegister, nil) + userDiscoveryMgr, err := ud.NewOrLoad(user, user.GetComms(), + user.NetworkFollowerStatus, userToRegister, nil, + cert, contactFile, address) if err != nil { jww.FATAL.Panicf("Failed to load or create new UD manager: %+v", err) } @@ -115,11 +124,7 @@ var udCmd = &cobra.Command{ jww.INFO.Printf("[UD] Confirmed %v", confirmID) } - udContact, err := userDiscoveryMgr.GetContact() - if err != nil { - fmt.Printf("Failed to get user discovery contact object: %+v", err) - jww.FATAL.Printf("Failed to get user discovery contact object: %+v", err) - } + udContact := userDiscoveryMgr.GetContact() // Handle lookup (verification) process // Note: Cryptographic verification occurs above the bindings layer @@ -243,6 +248,42 @@ var udCmd = &cobra.Command{ }, } +// getUdContactInfo is a helper function which retrieves the necessary information +// to contact UD. +func getUdContactInfo(user *xxdk.E2e) (cert, contactFile []byte, address string, err error) { + // Retrieve address + address = string([]byte(user.GetCmix().GetInstance().GetPartialNdf(). + Get().UDB.Address)) + + // Retrieve certificate + cert = []byte(user.GetCmix().GetInstance().GetPartialNdf().Get().UDB.Cert) + + // Retrieve ID + udIdData := user.GetCmix().GetInstance().GetPartialNdf().Get().UDB.ID + udId, err := id.Unmarshal(udIdData) + if err != nil { + return nil, nil, "", err + } + + // Retrieve DH Pub Key + udDhPubKeyData := user.GetCmix().GetInstance().GetPartialNdf().Get().UDB.DhPubKey + var udDhPubKey *cyclic.Int + err = udDhPubKey.UnmarshalJSON(udDhPubKeyData) + if err != nil { + return nil, nil, "", err + } + + // Construct contact + udContact := contact.Contact{ + ID: udId, + DhPubKey: udDhPubKey, + } + + contactFile = udContact.Marshal() + + return +} + func init() { // User Discovery subcommand Options udCmd.Flags().StringP(udRegisterFlag, "r", "", diff --git a/ud/addFact.go b/ud/addFact.go index c107636c365bfeedd449e67c9ebab426365551fd..719e7d137ab1f9c3e5ce4d414c9db08876d668a4 100644 --- a/ud/addFact.go +++ b/ud/addFact.go @@ -30,12 +30,6 @@ func (m *Manager) SendRegisterFact(f fact.Fact) (string, error) { func (m *Manager) addFact(inFact fact.Fact, myId *id.ID, aFC addFactComms) (string, error) { - // get UD host - udHost, err := m.getOrAddUdHost() - if err != nil { - return "", err - } - // Create a primitives Fact so we can hash it f, err := fact.NewFact(inFact.T, inFact.Fact) if err != nil { @@ -68,7 +62,7 @@ func (m *Manager) addFact(inFact fact.Fact, myId *id.ID, } // Send the message - response, err := aFC.SendRegisterFact(udHost, &remFactMsg) + response, err := aFC.SendRegisterFact(m.ud.host, &remFactMsg) confirmationID := "" if response != nil { diff --git a/ud/alternate.go b/ud/alternate.go deleted file mode 100644 index f53281c43470d44ed24b40f65a02c143c8d785e3..0000000000000000000000000000000000000000 --- a/ud/alternate.go +++ /dev/null @@ -1,64 +0,0 @@ -package ud - -import ( - "github.com/pkg/errors" - "gitlab.com/elixxir/crypto/contact" - "gitlab.com/xx_network/comms/connect" - "gitlab.com/xx_network/primitives/id" -) - -// alternateUd is an alternative user discovery service. -// This is used for testing, so client can avoid contacting -// the production server. This requires an alternative, -// deployed UD service. -type alternateUd struct { - host *connect.Host - dhPubKey []byte -} - -// SetAlternativeUserDiscovery sets the alternativeUd object within manager. -// Once set, any user discovery operation will go through the alternative -// user discovery service. -// -// To undo this operation, use UnsetAlternativeUserDiscovery. -func (m *Manager) SetAlternativeUserDiscovery(altCert, altAddress, - contactFile []byte) error { - params := connect.GetDefaultHostParams() - params.AuthEnabled = false - - udIdBytes, dhPubKey, err := contact.ReadContactFromFile(contactFile) - if err != nil { - return err - } - - udID, err := id.Unmarshal(udIdBytes) - if err != nil { - return err - } - - // Add a new host and return it if it does not already exist - host, err := m.comms.AddHost(udID, string(altAddress), - altCert, params) - if err != nil { - return errors.WithMessage(err, "User Discovery host object could "+ - "not be constructed.") - } - - m.alternativeUd = &alternateUd{ - host: host, - dhPubKey: dhPubKey, - } - - return nil -} - -// UnsetAlternativeUserDiscovery clears out the information from -// the Manager object. -func (m *Manager) UnsetAlternativeUserDiscovery() error { - if m.alternativeUd == nil { - return errors.New("Alternative User Discovery is already unset.") - } - - m.alternativeUd = nil - return nil -} diff --git a/ud/confirmFact.go b/ud/confirmFact.go index fb81b7a9ee78e373fb54aaa6504d22c4eb1fa35b..a55da37566945a03b5c0a276f92b7e30ec220f4d 100644 --- a/ud/confirmFact.go +++ b/ud/confirmFact.go @@ -19,17 +19,11 @@ func (m *Manager) ConfirmFact(confirmationID, code string) error { // confirmFact is a helper function for ConfirmFact. func (m *Manager) confirmFact(confirmationID, code string, comm confirmFactComm) error { - // get UD host - udHost, err := m.getOrAddUdHost() - if err != nil { - return err - } - msg := &pb.FactConfirmRequest{ ConfirmationID: confirmationID, Code: code, } - _, err = comm.SendConfirmFact(udHost, msg) + _, err := comm.SendConfirmFact(m.ud.host, msg) if err != nil { return err } diff --git a/ud/lookup_test.go b/ud/lookup_test.go index de7fd3f3d488bf5867d9df84a16e18ca897deea9..2b168e4a30c3b04e9840225c43b5e1aab039759c 100644 --- a/ud/lookup_test.go +++ b/ud/lookup_test.go @@ -37,11 +37,6 @@ func TestManager_Lookup(t *testing.T) { // Set up mock manager m, tnm := newTestManager(t) - udContact, err := m.GetContact() - if err != nil { - t.Fatalf("Failed to get contact: %v", err) - } - uid := id.NewIdFromUInt(0x500000000000000, id.User, t) expectedContact := contact.Contact{ ID: uid, @@ -87,7 +82,7 @@ func TestManager_Lookup(t *testing.T) { } // Run the lookup - _, _, err = Lookup(m.user, udContact, callback, uid, p) + _, _, err = Lookup(m.user, m.GetContact(), callback, uid, p) if err != nil { t.Errorf("Lookup() returned an error: %+v", err) } diff --git a/ud/manager.go b/ud/manager.go index 845d2b800d86170b19a1954a1530bff639617d52..0a4247fb809d876b4c0659639827bc2929ba3b83 100644 --- a/ud/manager.go +++ b/ud/manager.go @@ -1,11 +1,6 @@ package ud import ( - "fmt" - "gitlab.com/elixxir/crypto/fastRNG" - "sync" - "time" - "github.com/pkg/errors" jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/event" @@ -13,9 +8,9 @@ import ( store "gitlab.com/elixxir/client/ud/store" "gitlab.com/elixxir/client/xxdk" "gitlab.com/elixxir/crypto/contact" + "gitlab.com/elixxir/crypto/fastRNG" "gitlab.com/elixxir/primitives/fact" - "gitlab.com/xx_network/comms/connect" - "gitlab.com/xx_network/primitives/id" + "sync" ) // Manager is the control structure for the contacting the user discovery service. @@ -39,74 +34,56 @@ type Manager struct { // may cause unexpected behaviour. factMux sync.Mutex - // alternativeUd is an alternate User discovery service to circumvent - // production. This is for testing with a separately deployed UD service. - alternativeUd *alternateUd + // ud is the tracker for the contact information of the specified UD server. + // This information is specified in Manager's constructors (NewOrLoad and NewManagerFromBackup). + ud *userDiscovery } -// LoadOrNewManager loads an existing Manager from storage or creates a -// new one if there is no extant storage information. +// NewOrLoad loads an existing Manager from storage or creates a +// new one if there is no extant storage information. Parameters need be provided +// to specify how to connect to the User Discovery service. These parameters may be used +// to contact either the UD server hosted by the xx network team or a custom +// third-party operated server. // // Params // - user is an interface that adheres to the xxdk.E2e object. // - comms is an interface that adheres to client.Comms object. // - follower is a method off of xxdk.Cmix which returns the network follower's status. // - username is the name of the user as it is registered with UD. This will be what the end user -// provides if through the bindings. +// provides if through the bindings. // - networkValidationSig is a signature provided by the network (i.e. the client registrar). This may -// be nil, however UD may return an error in some cases (e.g. in a production level environment). -func LoadOrNewManager(user udE2e, comms Comms, follower udNetworkStatus, - username string, networkValidationSig []byte) (*Manager, error) { - jww.INFO.Println("ud.LoadOrNewManager()") - - if follower() != xxdk.Running { - return nil, errors.New( - "cannot start UD Manager when network follower is not running.") - } - - // Initialize manager - m := &Manager{ - user: user, - comms: comms, - } +// be nil, however UD may return an error in some cases (e.g. in a production level environment). +// - cert is the TLS certificate for the UD server this call will connect with. +// - contactFile is the data within a marshalled contact.Contact. This represents the +// contact file of the server this call will connect with. +// - address is the IP address of the UD server this call will connect with. +// +// Returns +// - A Manager object which is registered to the specified UD service. +func NewOrLoad(user udE2e, comms Comms, follower udNetworkStatus, + username string, networkValidationSig, + cert, contactFile []byte, address string) (*Manager, error) { - if m.isRegistered() { - // Load manager if already registered - var err error - m.store, err = store.NewOrLoadStore(m.getKv()) - if err != nil { - return nil, errors.Errorf("Failed to initialize store: %v", err) - } - return m, nil - } + jww.INFO.Println("ud.NewOrLoad()") - // Initialize store - var err error - m.store, err = store.NewOrLoadStore(m.getKv()) + // Construct manager + m, err := loadOrNewManager(user, comms, follower) if err != nil { - return nil, errors.Errorf("Failed to initialize store: %v", err) + return nil, err } - // Initialize/Get host - udHost, err := m.getOrAddUdHost() + // Set user discovery + err = m.setUserDiscovery(cert, contactFile, address) if err != nil { - return nil, errors.WithMessage(err, "User Discovery host object could "+ - "not be constructed.") + return nil, err } - // Register with user discovery - stream := m.getRng().GetStream() - defer stream.Close() - err = m.register(username, networkValidationSig, stream, m.comms, udHost) + // Register manager + rng := m.getRng().GetStream() + defer rng.Close() + err = m.register(username, networkValidationSig, rng, comms) if err != nil { - return nil, errors.Errorf("Failed to register: %v", err) - } - - // Set storage to registered - if err = setRegistered(m.getKv()); err != nil && m.getEventReporter() != nil { - m.getEventReporter().Report(1, "UserDiscovery", "Registration", - fmt.Sprintf("User Registered with UD: %+v", - username)) + return nil, err } return m, nil @@ -115,8 +92,26 @@ func LoadOrNewManager(user udE2e, comms Comms, follower udNetworkStatus, // NewManagerFromBackup builds a new user discover manager from a backup. // It will construct a manager that is already registered and restore // already registered facts into store. +// +// Params +// - user is an interface that adheres to the xxdk.E2e object. +// - comms is an interface that adheres to client.Comms object. +// - follower is a method off of xxdk.Cmix which returns the network follower's status. +// - username is the name of the user as it is registered with UD. This will be what the end user +// provides if through the bindings. +// - networkValidationSig is a signature provided by the network (i.e. the client registrar). This may +// be nil, however UD may return an error in some cases (e.g. in a production level environment). +// - email is a fact.Fact (type Email) which has been registered with UD already. +// - phone is a fact.Fact (type Phone) which has been registered with UD already. +// - cert is the TLS certificate for the UD server this call will connect with. +// - contactFile is the data within a marshalled contact.Contact. This represents the +// contact file of the server this call will connect with. +// - address is the IP address of the UD server this call will connect with. +// +// Returns +// - A Manager object which is registered to the specified UD service. func NewManagerFromBackup(user udE2e, comms Comms, follower udNetworkStatus, - email, phone fact.Fact) (*Manager, error) { + email, phone fact.Fact, cert, contactFile []byte, address string) (*Manager, error) { jww.INFO.Println("ud.NewManagerFromBackup()") if follower() != xxdk.Running { return nil, errors.New( @@ -151,11 +146,9 @@ func NewManagerFromBackup(user udE2e, comms Comms, follower udNetworkStatus, "registered with user discovery.") } - // Create the user discovery host object - _, err = m.getOrAddUdHost() + err = m.setUserDiscovery(cert, contactFile, address) if err != nil { - return nil, errors.WithMessage(err, "User Discovery host object could "+ - "not be constructed.") + return nil, err } return m, nil @@ -199,96 +192,44 @@ func (m *Manager) GetStringifiedFacts() []string { return m.store.GetStringifiedFacts() } -// GetContact returns the contact for UD as retrieved from the NDF. -func (m *Manager) GetContact() (contact.Contact, error) { - grp, err := m.user.GetReceptionIdentity().GetGroup() - if err != nil { - return contact.Contact{}, err - } - // Return alternative User discovery contact if set - if m.alternativeUd != nil { - // Unmarshal UD DH public key - alternativeDhPubKey := grp.NewInt(1) - if err := alternativeDhPubKey. - UnmarshalJSON(m.alternativeUd.dhPubKey); err != nil { - return contact.Contact{}, - errors.WithMessage(err, "Failed to unmarshal UD "+ - "DH public key.") - } - - return contact.Contact{ - ID: m.alternativeUd.host.GetId(), - DhPubKey: alternativeDhPubKey, - OwnershipProof: nil, - Facts: nil, - }, nil - } - - netDef := m.getCmix().GetInstance().GetPartialNdf().Get() - - // Unmarshal UD ID from the NDF - udID, err := id.Unmarshal(netDef.UDB.ID) - if err != nil { - return contact.Contact{}, - errors.Errorf("failed to unmarshal UD ID from NDF: %+v", err) - } - - // Unmarshal UD DH public key - dhPubKey := grp.NewInt(1) - if err = dhPubKey.UnmarshalJSON(netDef.UDB.DhPubKey); err != nil { - return contact.Contact{}, - errors.WithMessage(err, "Failed to unmarshal UD DH "+ - "public key.") - } - - return contact.Contact{ - ID: udID, - DhPubKey: dhPubKey, - OwnershipProof: nil, - Facts: nil, - }, nil +// GetContact returns the contact.Contact for UD. +func (m *Manager) GetContact() contact.Contact { + return m.ud.contact } -// getOrAddUdHost returns the current UD host for the UD ID found in the NDF. -// If the host does not exist, then it is added and returned. -func (m *Manager) getOrAddUdHost() (*connect.Host, error) { - // Return alternative User discovery service if it has been set - if m.alternativeUd != nil { - return m.alternativeUd.host, nil - } - - netDef := m.getCmix().GetInstance().GetPartialNdf().Get() - if netDef.UDB.Cert == "" { - return nil, errors.New("NDF does not have User Discovery information, " + - "is there network access?: Cert not present.") +// loadOrNewManager is a helper function which loads from storage or +// creates a new Manager object. +func loadOrNewManager(user udE2e, comms Comms, + follower udNetworkStatus) (*Manager, error) { + if follower() != xxdk.Running { + return nil, errors.New( + "cannot start UD Manager when network follower is not running.") } - // Unmarshal UD ID from the NDF - udID, err := id.Unmarshal(netDef.UDB.ID) - if err != nil { - return nil, errors.Errorf("failed to "+ - "unmarshal UD ID from NDF: %+v", err) + // Initialize manager + m := &Manager{ + user: user, + comms: comms, } - // Return the host, if it exists - host, exists := m.comms.GetHost(udID) - if exists { - return host, nil + if m.isRegistered() { + // Load manager if already registered + var err error + m.store, err = store.NewOrLoadStore(m.getKv()) + if err != nil { + return nil, errors.Errorf("Failed to initialize store: %v", err) + } + return m, nil } - params := connect.GetDefaultHostParams() - params.AuthEnabled = false - params.SendTimeout = 20 * time.Second - - // Add a new host and return it if it does not already exist - host, err = m.comms.AddHost(udID, netDef.UDB.Address, - []byte(netDef.UDB.Cert), params) + // Initialize store + var err error + m.store, err = store.NewOrLoadStore(m.getKv()) if err != nil { - return nil, errors.WithMessage(err, "User Discovery host "+ - "object could not be constructed.") + return nil, errors.Errorf("Failed to initialize store: %v", err) } - return host, nil + return m, nil } //////////////////////////////////////////////////////////////////////////////// diff --git a/ud/manager_test.go b/ud/manager_test.go index 1bf18a58b4f3aa41915eddecc789c2c1f240fb4f..b214c9600302170cc0822b8806ac8c8fe6de943b 100644 --- a/ud/manager_test.go +++ b/ud/manager_test.go @@ -49,12 +49,12 @@ EnretBzQkeKeBwoB2u6NTiOmUjk= var testContact = `<xxc(2)LF2ccT+sdqh0AIKlFFeDOJdnxzbQQYhGStgxhOXmijIDkAZiB9kZo+Dl3bRSbBi5pXZ82rOu2IQXz9+5sspChvoccZqgC/dXGhlesmiNy/EbKxWtptTF4tcNyQxtnmCXg1p/HwKey4G2XDekTw86lq6Lpmj72jozvRWlQisqvWz/5deiPaeFGKDKC0OrrDFnIib7WnKqdYt4XyTKdmObnmbvdCbliZq0zBl7J40qKy5FypYXGlZjStIm0R1qtD4XHMZMsrMJEGxdM55zJdSzknXbR8MNahUrGMyUOTivXLHzojYLht0gFQifKMVWhrDjUoVQV43KOLPmdBwY/2Kc5KvVloDeuDXYY0i7tD63gNIp9JA3gJQUJymDdwqbS13riT1DMHHkdTzKEyGdHS+v2l7AVSlJBiTKuyM00FBNuXhhIcFR7ONFCf8cRPOPPBx3Q6iHNsvsca3KPNhwOJBgaQvHSkjIMsudiR954QbwG9rbi2vxVobIgWYMl5j6vlBS/9rfbE/uLdTEQZfNsLKDCIVCCI4I1bYZxZrDLPrfXTrN6W0sCLE7a/kRBQAAAgA7+LwJqiv9O1ogLnS4TYkSEg==xxc>` -func TestManager_SetAlternativeUserDiscovery(t *testing.T) { +func TestManager_setUserDiscovery(t *testing.T) { m, _ := newTestManager(t) altAddr := "0.0.0.0:11420" - err := m.SetAlternativeUserDiscovery([]byte(testCert), []byte(altAddr), []byte(testContact)) + err := m.setUserDiscovery([]byte(testCert), []byte(testContact), string([]byte(altAddr))) if err != nil { - t.Fatalf("Unexpected error in SetAlternativeUserDiscovery: %v", err) + t.Fatalf("Unexpected error in setUserDiscovery: %v", err) } } diff --git a/ud/mockE2e_test.go b/ud/mockE2e_test.go index 28ddaeb0badeab3fd2eb0d18e0cacaba137927e0..c57e148fe6a63845a480bebb1aa939789b600bfc 100644 --- a/ud/mockE2e_test.go +++ b/ud/mockE2e_test.go @@ -29,13 +29,14 @@ import ( /////////////////////////////////////////////////////////////////////////////// type mockE2e struct { - grp *cyclic.Group - events event.Reporter - rng *fastRNG.StreamGenerator - kv *versioned.KV - network cmix.Client - t testing.TB - key *rsa.PrivateKey + grp *cyclic.Group + events event.Reporter + rng *fastRNG.StreamGenerator + kv *versioned.KV + network cmix.Client + mockStore mockStorage + t testing.TB + key *rsa.PrivateKey } func (m mockE2e) GetE2E() e2e.Handler { @@ -89,8 +90,7 @@ func (m mockE2e) GetCmix() cmix.Client { } func (m mockE2e) GetStorage() storage.Session { - //TODO implement me - panic("implement me") + return m.mockStore } /////////////////////////////////////////////////////////////////////////////// diff --git a/ud/mockStore_test.go b/ud/mockStore_test.go new file mode 100644 index 0000000000000000000000000000000000000000..5031f491bbfa8b8f24ca35c9f57d3b5dd6df0575 --- /dev/null +++ b/ud/mockStore_test.go @@ -0,0 +1,160 @@ +package ud + +import ( + "gitlab.com/elixxir/client/storage" + "gitlab.com/elixxir/client/storage/user" + "gitlab.com/elixxir/client/storage/versioned" + "gitlab.com/elixxir/crypto/cyclic" + "gitlab.com/elixxir/ekv" + "gitlab.com/elixxir/primitives/version" + "gitlab.com/xx_network/crypto/signature/rsa" + "gitlab.com/xx_network/primitives/id" + "gitlab.com/xx_network/primitives/ndf" + "time" +) + +type mockStorage struct{} + +func (m mockStorage) GetKV() *versioned.KV { + return versioned.NewKV(ekv.MakeMemstore()) +} + +func (m mockStorage) GetClientVersion() version.Version { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) Get(key string) (*versioned.Object, error) { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) Set(key string, object *versioned.Object) error { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) Delete(key string) error { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) GetCmixGroup() *cyclic.Group { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) GetE2EGroup() *cyclic.Group { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) ForwardRegistrationStatus(regStatus storage.RegistrationStatus) error { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) GetRegistrationStatus() storage.RegistrationStatus { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) SetRegCode(regCode string) { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) GetRegCode() (string, error) { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) SetNDF(def *ndf.NetworkDefinition) { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) GetNDF() *ndf.NetworkDefinition { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) GetTransmissionID() *id.ID { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) GetTransmissionSalt() []byte { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) GetReceptionID() *id.ID { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) GetReceptionSalt() []byte { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) GetReceptionRSA() *rsa.PrivateKey { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) GetTransmissionRSA() *rsa.PrivateKey { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) IsPrecanned() bool { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) SetUsername(username string) error { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) GetUsername() (string, error) { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) PortableUserInfo() user.Info { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) GetTransmissionRegistrationValidationSignature() []byte { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) GetReceptionRegistrationValidationSignature() []byte { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) GetRegistrationTimestamp() time.Time { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) SetTransmissionRegistrationValidationSignature(b []byte) { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) SetReceptionRegistrationValidationSignature(b []byte) { + //TODO implement me + panic("implement me") +} + +func (m mockStorage) SetRegistrationTimestamp(tsNano int64) { + //TODO implement me + panic("implement me") +} diff --git a/ud/register.go b/ud/register.go index f41532bd5605ae7d45ddf90baea152293c489d3e..495d50da5e1fb51dd0e9d0e9d0211547d3314946 100644 --- a/ud/register.go +++ b/ud/register.go @@ -1,13 +1,13 @@ package ud import ( + "fmt" "github.com/pkg/errors" pb "gitlab.com/elixxir/comms/mixmessages" "gitlab.com/elixxir/crypto/diffieHellman" "gitlab.com/elixxir/crypto/factID" "gitlab.com/elixxir/crypto/hash" "gitlab.com/elixxir/primitives/fact" - "gitlab.com/xx_network/comms/connect" "gitlab.com/xx_network/crypto/csprng" "gitlab.com/xx_network/crypto/signature/rsa" ) @@ -15,9 +15,9 @@ import ( // register initiates registration with user discovery given a specified // username. Provided a comms sub-interface to facilitate testing. func (m *Manager) register(username string, networkSignature []byte, - rng csprng.Source, comm registerUserComms, udHost *connect.Host) error { + rng csprng.Source, comm registerUserComms) error { - var err error + // Retrieve data used for registration identity := m.user.GetReceptionIdentity() privKey, err := identity.GetRSAPrivatePem() if err != nil { @@ -63,6 +63,9 @@ func (m *Manager) register(username string, networkSignature []byte, // Hash and sign fact hashedFact := factID.Fingerprint(usernameFact) signedFact, err := rsa.Sign(rng, privKey, hash.CMixHash, hashedFact, nil) + if err != nil { + return errors.Errorf("Failed to sign fact: %v", err) + } // Add username fact register request to the user registration message msg.Frs = &pb.FactRegisterRequest{ @@ -75,6 +78,17 @@ func (m *Manager) register(username string, networkSignature []byte, } // Register user with user discovery - _, err = comm.SendRegisterUser(udHost, msg) + _, err = comm.SendRegisterUser(m.ud.host, msg) + if err != nil { + return err + } + + // Set storage to registered + if err = setRegistered(m.getKv()); err != nil && m.getEventReporter() != nil { + m.getEventReporter().Report(1, "UserDiscovery", "Registration", + fmt.Sprintf("User Registered with UD: %+v", + username)) + } + return err } diff --git a/ud/register_test.go b/ud/register_test.go index 3a521042c31d8703e752efd439a1456ce8b789af..f5c4f57828f27826ebd025354bc91a13cb81ec49 100644 --- a/ud/register_test.go +++ b/ud/register_test.go @@ -26,17 +26,12 @@ func (t *testRegisterComm) SendRegisterUser(_ *connect.Host, msg *pb.UDBUserRegi func TestManager_register(t *testing.T) { m, _ := newTestManager(t) - udHost, err := m.getOrAddUdHost() - if err != nil { - t.Fatalf("Failed to get/add ud host: %+v", err) - } - c := &testRegisterComm{} prng := NewPrng(42) mockSig := []byte("mock") - err = m.register("testUser", mockSig, prng, c, udHost) + err := m.register("testUser", mockSig, prng, c) if err != nil { t.Errorf("register() returned an error: %+v", err) } diff --git a/ud/remove.go b/ud/remove.go index 5502096c716110456247c9126f7f11d6da93a642..ebb809c0022ab0bbc81237c092c106bcbf946bd2 100644 --- a/ud/remove.go +++ b/ud/remove.go @@ -28,12 +28,6 @@ func (m *Manager) RemoveFact(f fact.Fact) error { func (m *Manager) removeFact(f fact.Fact, rFC removeFactComms) error { - // Get UD host - udHost, err := m.getOrAddUdHost() - if err != nil { - return err - } - // Construct the message to send // Convert our Fact to a mixmessages Fact for sending mmFact := mixmessages.Fact{ @@ -65,7 +59,7 @@ func (m *Manager) removeFact(f fact.Fact, } // Send the message - _, err = rFC.SendRemoveFact(udHost, &remFactMsg) + _, err = rFC.SendRemoveFact(m.ud.host, &remFactMsg) if err != nil { return err } @@ -83,19 +77,13 @@ func (m *Manager) PermanentDeleteAccount(f fact.Fact) error { return errors.New(fmt.Sprintf("PermanentDeleteAccount must only remove "+ "a username. Cannot remove fact %q", f.Fact)) } - - udHost, err := m.getOrAddUdHost() - if err != nil { - return err - } - identity := m.user.GetReceptionIdentity() privKey, err := identity.GetRSAPrivatePem() if err != nil { return err } - return m.permanentDeleteAccount(f, identity.ID, privKey, m.comms, udHost) + return m.permanentDeleteAccount(f, identity.ID, privKey, m.comms, m.ud.host) } // permanentDeleteAccount is a helper function for PermanentDeleteAccount. diff --git a/ud/remove_test.go b/ud/remove_test.go index a7cd32bc1e94347262147df7faa674d4e91aa000..53b61b3fae3070c08dad9d5d9d8c9d69503b0371 100644 --- a/ud/remove_test.go +++ b/ud/remove_test.go @@ -86,9 +86,9 @@ package ud // // tRFC := testRFC{} // -// udHost, err := m.getOrAddUdHost() +// udHost, err := m.getHost() // if err != nil { -// t.Fatalf("getOrAddUdHost error: %v", err) +// t.Fatalf("getHost error: %v", err) // } // // err = m.permanentDeleteAccount(f, mockId, &tRFC, udHost) diff --git a/ud/search_test.go b/ud/search_test.go index 865f09d1ecc7e27e1ebbe6aade79e82858b21562..3130e4f9b524a0cd79360a1bbcd42c4430052e8d 100644 --- a/ud/search_test.go +++ b/ud/search_test.go @@ -47,10 +47,8 @@ func TestManager_Search(t *testing.T) { grp = getGroup() var contacts []*Contact - udContact, err := m.GetContact() - if err != nil { - t.Fatalf("Failed to get ud contact: %v", err) - } + udContact := m.GetContact() + contacts = append(contacts, &Contact{ UserID: udContact.ID.Bytes(), PubKey: udContact.DhPubKey.Bytes(), diff --git a/ud/ud.go b/ud/ud.go new file mode 100644 index 0000000000000000000000000000000000000000..5fb27e619de9d5196b24022b35277f1f26c37837 --- /dev/null +++ b/ud/ud.go @@ -0,0 +1,59 @@ +package ud + +import ( + "github.com/pkg/errors" + "gitlab.com/elixxir/crypto/contact" + "gitlab.com/xx_network/comms/connect" + "gitlab.com/xx_network/primitives/id" + "time" +) + +// userDiscovery is the user discovery's contact information. +type userDiscovery struct { + host *connect.Host + contact contact.Contact +} + +// setUserDiscovery sets the ud object within Manager. +// The specified the contact information will be used for +// all further Manager operations which contact the UD server. +func (m *Manager) setUserDiscovery(cert, + contactFile []byte, address string) error { + params := connect.GetDefaultHostParams() + params.AuthEnabled = false + params.SendTimeout = 20 * time.Second + + udIdBytes, dhPubKeyBytes, err := contact.ReadContactFromFile(contactFile) + if err != nil { + return err + } + + udID, err := id.Unmarshal(udIdBytes) + if err != nil { + return err + } + + // Add a new host and return it if it does not already exist + host, err := m.comms.AddHost(udID, address, + cert, params) + if err != nil { + return errors.WithMessage(err, "User Discovery host object could "+ + "not be constructed.") + } + + dhPubKey := m.user.GetE2E().GetGroup().NewInt(1) + err = dhPubKey.UnmarshalJSON(dhPubKeyBytes) + if err != nil { + return err + } + + m.ud = &userDiscovery{ + host: host, + contact: contact.Contact{ + ID: udID, + DhPubKey: dhPubKey, + }, + } + + return nil +} diff --git a/ud/utils_test.go b/ud/utils_test.go index c4082605b959ef94d3ab4d031970c0b370893d05..8a1fb7f826ddea93ebbaca272260a018eedef4d3 100644 --- a/ud/utils_test.go +++ b/ud/utils_test.go @@ -35,14 +35,6 @@ import ( "gitlab.com/xx_network/primitives/ndf" ) -// Base64 encoded dh private key using a pre-seeded prng -// prng := NewPrng(42) -const dhPrivKeyEnc = `U4x/lrFkvxuXu59LtHLon1sUhPJSCcnZND6SugndnVLf15tNdkKbYXoMn58NO6VbDMDWFEyIhTWEGsvgcJsHWAg/YdN1vAK0HfT5GSnhj9qeb4LlTnSOgeeeS71v40zcuoQ+6NY+jE/+HOvqVG2PrBPdGqwEzi6ih3xVec+ix44bC6+uiBuCp1EQikLtPJA8qkNGWnhiBhaXiu0M48bE8657w+BJW1cS/v2+DBAoh+EA2s0tiF9pLLYH2gChHBxwceeWotwtwlpbdLLhKXBeJz8FySMmgo4rBW44F2WOEGFJiUf980RBDtTBFgI/qONXa2/tJ/+JdLrAyv2a0FaSsTYZ5ziWTf3Hno1TQ3NmHP1m10/sHhuJSRq3I25LdSFikM8r60LDyicyhWDxqsBnzqbov0bUqytGgEAsX7KCDohdMmDx3peCg9Sgmjb5bCCUF0bj7U2mRqmui0+ntPw6ILr6GnXtMnqGuLDDmvHP0rO1EhnqeVM6v0SNLEedMmB1M5BZFMjMHPCdo54Okp0C` - -const searchMessageEnc = `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` -const dhKeyEnc = `hQj4FKeaQDt34eO/BQe5OSk571WMQBu4YNqMQ0TFeuzjzCM9lLMuOsQhcyjZcIo4qanfv0egkwW7YgSAAt+WaOc6S1rzbxidb6v00KCEVkXAl3NSYk3ms8Jp0uzejOKEI6I3TCjX+71GZ6304xRKQSXDnuYG7ypvx+tYgj6EWx/sh5DsdIyT0KVxo9c/msT0cT6Fq1Hz1S3TkQc2dLcamn86gtKs4cSNuG/b7HFvyKSCK4KqQ2wrQWhiJCh0L6UhXEqTVwyoVgjH8pA/R+eTIE3QL4rDPy+gFdaZOVbr2jOOEvgYTJxWU7VPygXkPtTTHL8eD5IXoj9b46ll6CAHC5xwkCfiqO+HLE2Cg6nVmIq7eCZOLH1WnrYcjv7TQrYNCdb2hGDZznbI2wVswiIW7CilHaKH5KmiVfZG3cPKfwcTATRFR5oNVcav4wikObzB7gAmP57lGTwF1WqfLlGAxDF1R+Qiljfp1U1f0s7MBjG62gFwxpxs4AgA8lZDnvlRgeM1P0zsaypUbrHXFhu6` -const lookupRequestEnc = `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` - func newTestManager(t *testing.T) (*Manager, *testNetworkManager) { kv := versioned.NewKV(ekv.MakeMemstore()) udStore, err := store.NewOrLoadStore(kv) @@ -84,16 +76,33 @@ func newTestManager(t *testing.T) (*Manager, *testNetworkManager) { params.SendTimeout = 20 * time.Second // Add a new host and return it if it does not already exist - _, err = m.comms.AddHost(udID, netDef.UDB.Address, + host, err := m.comms.AddHost(udID, netDef.UDB.Address, []byte(netDef.UDB.Cert), params) if err != nil { t.Fatalf("User Discovery host " + "object could not be constructed.") } - udContact, err := m.GetContact() + udIdData := netDef.UDB.ID + udId, err := id.Unmarshal(udIdData) + if err != nil { + t.Fatalf(err.Error()) + } + + udDhPubKeyData := netDef.UDB.DhPubKey + udDhPubKey := getGroup().NewInt(1) + err = udDhPubKey.UnmarshalJSON(udDhPubKeyData) if err != nil { - t.Fatalf("Failed to get contact: %v", err) + t.Fatalf(err.Error()) + } + + udContact := contact.Contact{ + ID: udId, + DhPubKey: udDhPubKey, + } + m.ud = &userDiscovery{ + host: host, + contact: udContact, } tnm.c = udContact diff --git a/xxmutils/restoreContacts.go b/xxmutils/restoreContacts.go index d7b842725c718a8f5f9fd5abb5cee6f5c48e0989..9f43d294e35b7f6d601ba780b93b69bb0966a002 100644 --- a/xxmutils/restoreContacts.go +++ b/xxmutils/restoreContacts.go @@ -42,11 +42,6 @@ func RestoreContactsFromBackup(backupPartnerIDs []byte, user *xxdk.E2e, updatesCb interfaces.RestoreContactsUpdater) ([]*id.ID, []*id.ID, []error, error) { - udContact, err := udManager.GetContact() - if err != nil { - return nil, nil, nil, err - } - var restored, failed []*id.ID var errs []error @@ -99,7 +94,7 @@ func RestoreContactsFromBackup(backupPartnerIDs []byte, user *xxdk.E2e, rsWg := &sync.WaitGroup{} rsWg.Add(numRoutines) for i := 0; i < numRoutines; i++ { - go LookupContacts(lookupCh, foundCh, failCh, user, udContact, lcWg) + go LookupContacts(lookupCh, foundCh, failCh, user, udManager.GetContact(), lcWg) go ResetSessions(resetContactCh, restoredCh, failCh, user, rsWg) } @@ -131,6 +126,7 @@ func RestoreContactsFromBackup(backupPartnerIDs []byte, user *xxdk.E2e, // Event Processing done := false + var err error for !done { // NOTE: Timer is reset every loop timeoutTimer := time.NewTimer(restoreTimeout)