diff --git a/bindings/e2e.go b/bindings/e2e.go index beef52f655626f9fead21961f60a5aedc78df966..1a89bd8b3358eeed43f34c7bc9842ed58cdaf006 100644 --- a/bindings/e2e.go +++ b/bindings/e2e.go @@ -8,6 +8,8 @@ package bindings import ( + "gitlab.com/elixxir/crypto/cyclic" + "gitlab.com/xx_network/primitives/id" "sync" "github.com/pkg/errors" @@ -125,6 +127,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() []byte { + return []byte(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 + var udDhPubKey *cyclic.Int + 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 fcb7a00a1bcd31961653fa6a1765e5c7fcc93aba..b967aa05390cc1b3449147752c64a88e26a661a4 100644 --- a/bindings/ud.go +++ b/bindings/ud.go @@ -105,50 +105,12 @@ type UdNetworkStatus interface { // Manager functions // //////////////////////////////////////////////////////////////////////////////// -// NewOrLoadUdFromNdf loads an existing Manager from storage or creates a -// new one if there is no extant storage information. This will default to connecting with -// the xx network's UD server as found in the NDF. For connecting to a custom server, use -// NewOrLoadUd. -// -// Parameters: -// - 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 may be nil, however UD may return an error in some cases (e.g. in a production level -// environment). -func NewOrLoadUdFromNdf(e2eID int, follower UdNetworkStatus, - username string, registrationValidationSignature []byte) ( - *UserDiscovery, error) { - - // Get user from singleton - user, err := e2eTrackerSingleton.get(e2eID) - if err != nil { - return nil, err - } - - // Construct callback - UdNetworkStatusFn := func() xxdk.Status { - return xxdk.Status(follower.UdNetworkStatus()) - } - - // Build manager - u, err := ud.NewOrLoadFromNdf(user.api, user.api.GetComms(), - UdNetworkStatusFn, username, registrationValidationSignature) - if err != nil { - return nil, err - } - - // Track and return manager - return udTrackerSingleton.make(u), nil -} - // NewOrLoadUd loads an existing Manager from storage or creates a -// new one if there is no extant storage information. This is different from NewOrLoadUdFromNdf -// in that it allows the user to provide alternate User Discovery contact information. -// These parameters may be used to contact a separate UD server than the one run by the -// xx network team, one the user or a third-party may operate. +// 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. // // Params // - e2eID - e2e object ID in the tracker @@ -158,15 +120,15 @@ func NewOrLoadUdFromNdf(e2eID int, follower UdNetworkStatus, // - 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). -// - customCert is the TLS certificate for the alternate UD server. -// - customAddress is the IP address of the alternate UD server. -// - customContactFile is the data within a marshalled contact.Contact. +// - cert is the TLS certificate for the alternate UD server. +// - address is the IP address of the alternate UD server. +// - contactFile is the data within a marshalled contact.Contact. // // Returns // - A Manager object which is registered to the specified alternate UD service. func NewOrLoadUd(e2eID int, follower UdNetworkStatus, username string, registrationValidationSignature, - customCert, customAddress, customContactFile []byte) ( + cert, address, contactFile []byte) ( *UserDiscovery, error) { // Get user from singleton @@ -183,7 +145,7 @@ func NewOrLoadUd(e2eID int, follower UdNetworkStatus, // Build manager u, err := ud.NewOrLoad(user.api, user.api.GetComms(), UdNetworkStatusFn, username, registrationValidationSignature, - customCert, customAddress, customContactFile) + cert, address, contactFile) if err != nil { return nil, err } diff --git a/cmd/ud.go b/cmd/ud.go index fc950c9526293d097a7ad620c1dc1e641c0bc281..af002d63d5810d1ef870f56a775ec1d244828076 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!") + address, cert, contactFile, 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.NewOrLoadFromNdf(user, user.GetComms(), - user.NetworkFollowerStatus, userToRegister, nil) + userDiscoveryMgr, err := ud.NewOrLoad(user, user.GetComms(), + user.NetworkFollowerStatus, userToRegister, nil, + cert, address, contactFile) if err != nil { jww.FATAL.Panicf("Failed to load or create new UD manager: %+v", err) } @@ -243,6 +252,42 @@ var udCmd = &cobra.Command{ }, } +// getUdContactInfo is a helper function which retrieves the necessary information +// to contact UD. +func getUdContactInfo(user *xxdk.E2e) (cert, address, contactFile []byte, err error) { + // Retrieve address + address = []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, 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, 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/manager.go b/ud/manager.go index 90c5ca458877b4ba97aaa74659b237163b262cee..91ba31ec0bce63c3bc548a2b90e8ec3de683a340 100644 --- a/ud/manager.go +++ b/ud/manager.go @@ -43,23 +43,31 @@ type Manager struct { alternativeUd *alternateUd } -// NewOrLoadFromNdf loads an existing Manager from storage or creates a -// new one if there is no extant storage information. This will default to connecting with -// the xx network's UD server as found in the NDF. For connecting to a custom server, use -// NewOrLoad. +// 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. -// - 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 NewOrLoadFromNdf(user udE2e, comms Comms, follower udNetworkStatus, - username string, networkValidationSig []byte) (*Manager, error) { - jww.INFO.Println("ud.NewOrLoadFromNdf()") +// - 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). +// - customCert is the TLS certificate for the alternate UD server. +// - customAddress is the IP address of the alternate UD server. +// - customContactFile is the data within a marshalled contact.Contact. +// +// Returns +// - A Manager object which is registered to the specified alternate UD service. +func NewOrLoad(user udE2e, comms Comms, follower udNetworkStatus, + username string, networkValidationSig []byte, + customCert, customAddress, customContactFile []byte) (*Manager, error) { + + jww.INFO.Println("ud.NewOrLoad()") // Construct manager m, err := loadOrNewManager(user, comms, follower) @@ -67,6 +75,12 @@ func NewOrLoadFromNdf(user udE2e, comms Comms, follower udNetworkStatus, return nil, err } + // Set alternative user discovery + err = m.setAlternateUserDiscovery(customCert, customAddress, customContactFile) + if err != nil { + return nil, err + } + // Register manager rng := m.getRng().GetStream() defer rng.Close() @@ -128,54 +142,6 @@ func NewManagerFromBackup(user udE2e, comms Comms, follower udNetworkStatus, return m, nil } -// NewOrLoad loads an existing Manager from storage or creates a -// new one if there is no extant storage information. This call allows the user to provide -// custom UD contact information. These parameters may be used to contact a separate UD server -// than the one hosted by the xx network team, i.e. one the user or a third-party may operate. -// -// 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). -// - customCert is the TLS certificate for the alternate UD server. -// - customAddress is the IP address of the alternate UD server. -// - customContactFile is the data within a marshalled contact.Contact. -// -// Returns -// - A Manager object which is registered to the specified alternate UD service. -func NewOrLoad(user udE2e, comms Comms, follower udNetworkStatus, - username string, networkValidationSig []byte, - customCert, customAddress, customContactFile []byte) (*Manager, error) { - - jww.INFO.Println("ud.NewOrLoad()") - - // Construct manager - m, err := loadOrNewManager(user, comms, follower) - if err != nil { - return nil, err - } - - // Set alternative user discovery - err = m.setAlternateUserDiscovery(customCert, customAddress, customContactFile) - if err != nil { - return nil, err - } - - // Register manager - rng := m.getRng().GetStream() - defer rng.Close() - err = m.register(username, networkValidationSig, rng, comms) - if err != nil { - return nil, err - } - - return m, nil -} - // InitStoreFromBackup initializes the UD storage from the backup subsystem. func InitStoreFromBackup(kv *versioned.KV, username, email, phone fact.Fact) error {