From c23d0f688aed9fa52fa6c959190efbf75fba3b28 Mon Sep 17 00:00:00 2001 From: Jake Taylor <jake@elixxir.io> Date: Tue, 5 Jul 2022 17:08:11 -0500 Subject: [PATCH] made ud package use e2e.ReceptionID --- cmd/ud.go | 14 ++------ ud/addFact.go | 7 ++-- ud/interfaces.go | 35 +++++++++----------- ud/manager.go | 86 ++++++++++++++++++++++-------------------------- ud/register.go | 33 +++++++++++++------ ud/remove.go | 17 +++++++--- xxdk/cmix.go | 13 ++++---- xxdk/e2e.go | 2 ++ xxdk/identity.go | 9 +++-- 9 files changed, 114 insertions(+), 102 deletions(-) diff --git a/cmd/ud.go b/cmd/ud.go index 2310b172c..a4ff2dbe2 100644 --- a/cmd/ud.go +++ b/cmd/ud.go @@ -82,19 +82,11 @@ var udCmd = &cobra.Command{ // Make user discovery manager rng := client.GetRng() userToRegister := viper.GetString("register") - userDiscoveryMgr, err := ud.NewManager(client.GetCmix(), - client.GetE2E(), client.NetworkFollowerStatus, - client.GetEventReporter(), - client.GetComms(), client.GetStorage(), - rng, - userToRegister, client.GetStorage().GetKV()) + userDiscoveryMgr, err := ud.NewManager(client, + client.NetworkFollowerStatus, userToRegister, nil) if err != nil { if strings.Contains(err.Error(), ud.IsRegisteredErr) { - userDiscoveryMgr, err = ud.LoadManager(client.GetCmix(), - client.GetE2E(), client.GetEventReporter(), - client.GetComms(), - client.GetStorage(), client.GetRng(), - client.GetStorage().GetKV()) + userDiscoveryMgr, err = ud.LoadManager(client) if err != nil { jww.FATAL.Panicf("Failed to load UD manager: %+v", err) } diff --git a/ud/addFact.go b/ud/addFact.go index 3c2b0af54..f5174a0ed 100644 --- a/ud/addFact.go +++ b/ud/addFact.go @@ -22,7 +22,7 @@ func (m *Manager) SendRegisterFact(f fact.Fact) (string, error) { jww.INFO.Printf("ud.SendRegisterFact(%s)", f.Stringify()) m.factMux.Lock() defer m.factMux.Unlock() - return m.addFact(f, m.e2e.GetReceptionID(), m.comms) + return m.addFact(f, m.e2e.GetReceptionIdentity().ID, m.comms) } // addFact is the helper function for SendRegisterFact. @@ -45,7 +45,10 @@ func (m *Manager) addFact(inFact fact.Fact, myId *id.ID, fHash := factID.Fingerprint(f) // Sign our inFact for putting into the request - privKey := m.user.PortableUserInfo().ReceptionRSA + privKey, err := m.e2e.GetReceptionIdentity().GetRSAPrivatePem() + if err != nil { + return "", err + } stream := m.rng.GetStream() defer stream.Close() fSig, err := rsa.Sign(stream, privKey, hash.CMixHash, fHash, nil) diff --git a/ud/interfaces.go b/ud/interfaces.go index db7f0b603..d085103ec 100644 --- a/ud/interfaces.go +++ b/ud/interfaces.go @@ -1,11 +1,14 @@ package ud import ( + "gitlab.com/elixxir/client/cmix" + "gitlab.com/elixxir/client/e2e" + "gitlab.com/elixxir/client/event" "gitlab.com/elixxir/client/single" - "gitlab.com/elixxir/client/storage/user" + "gitlab.com/elixxir/client/storage" "gitlab.com/elixxir/client/xxdk" - "gitlab.com/elixxir/crypto/cyclic" - "gitlab.com/xx_network/primitives/id" + "gitlab.com/elixxir/comms/client" + "gitlab.com/elixxir/crypto/fastRNG" ) // CMix is a sub-interface of the cmix.Client. It contains the methods @@ -16,25 +19,17 @@ type CMix interface { single.Cmix } -// E2E is a sub-interface of the e2e.Handler. It contains the methods +// E2E is a sub-interface of the xxdk.E2e. It contains the methods // relevant to what is used in this package. type E2E interface { - // GetGroup returns the cyclic group used for end to end encruption - GetGroup() *cyclic.Group - - // GetReceptionID returns the default IDs - GetReceptionID() *id.ID - - // GetHistoricalDHPubkey returns the user's Historical DH - // Public Key - GetHistoricalDHPubkey() *cyclic.Int -} - -// UserInfo is a sub-interface for the user.User object in storage. -// It contains the methods relevant to what is used in this package. -type UserInfo interface { - PortableUserInfo() user.Info - GetReceptionRegistrationValidationSignature() []byte + GetReceptionIdentity() xxdk.ReceptionIdentity + GetCmix() cmix.Client + GetE2E() e2e.Handler + GetEventReporter() event.Reporter + GetComms() *client.Comms + GetRng() *fastRNG.StreamGenerator + GetStorage() storage.Session + GetTransmissionIdentity() xxdk.TransmissionIdentity } // NetworkStatus is an interface for the xxdk.Cmix's diff --git a/ud/manager.go b/ud/manager.go index 77dbc01f4..258bb36d6 100644 --- a/ud/manager.go +++ b/ud/manager.go @@ -43,11 +43,6 @@ type Manager struct { // with the UD service store *store.Store - // user is a sub-interface of the user.User object in the storage package. - // This allows the Manager to pull user information for registration - // and verifying the client's identity - user UserInfo - // comms is a sub-interface of the client.Comms interface. It contains // gRPC functions for registering and fact operations. comms Comms @@ -69,16 +64,18 @@ type Manager struct { // rng is a fastRNG.StreamGenerator which is used to generate random // data. This is used for signatures for adding/removing facts. rng *fastRNG.StreamGenerator + + // registrationValidationSignature for the ReceptionID + // Optional, depending on UD configuration + registrationValidationSignature []byte } // NewManager builds a new user discovery manager. // It requires that an updated // NDF is available and will error if one is not. -func NewManager(services CMix, e2e E2E, - follower NetworkStatus, - events event.Reporter, comms Comms, userStore UserInfo, - rng *fastRNG.StreamGenerator, username string, - kv *versioned.KV) (*Manager, error) { +// registrationValidationSignature may be set to nil +func NewManager(e2e E2E, follower NetworkStatus, + username string, registrationValidationSignature []byte) (*Manager, error) { jww.INFO.Println("ud.NewManager()") if follower() != xxdk.Running { @@ -88,13 +85,13 @@ func NewManager(services CMix, e2e E2E, // Initialize manager m := &Manager{ - network: services, - e2e: e2e, - events: events, - comms: comms, - user: userStore, - kv: kv, - rng: rng, + network: e2e.GetCmix(), + e2e: e2e, + events: e2e.GetEventReporter(), + comms: e2e.GetComms(), + kv: e2e.GetStorage().GetKV(), + rng: e2e.GetRng(), + registrationValidationSignature: registrationValidationSignature, } if m.isRegistered() { @@ -103,7 +100,7 @@ func NewManager(services CMix, e2e E2E, // Initialize store var err error - m.store, err = store.NewOrLoadStore(kv) + m.store, err = store.NewOrLoadStore(m.kv) if err != nil { return nil, errors.Errorf("Failed to initialize store: %v", err) } @@ -116,15 +113,15 @@ func NewManager(services CMix, e2e E2E, } // Register with user discovery - stream := rng.GetStream() + stream := m.rng.GetStream() defer stream.Close() - err = m.register(username, stream, comms, udHost) + err = m.register(username, stream, m.comms, udHost) if err != nil { return nil, errors.Errorf("Failed to register: %v", err) } // Set storage to registered - if err = setRegistered(kv); err != nil && m.events != nil { + if err = setRegistered(m.kv); err != nil && m.events != nil { m.events.Report(1, "UserDiscovery", "Registration", fmt.Sprintf("User Registered with UD: %+v", username)) @@ -136,11 +133,8 @@ func NewManager(services CMix, e2e E2E, // 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. -func NewManagerFromBackup(services CMix, - e2e E2E, follower NetworkStatus, - events event.Reporter, comms Comms, userStore UserInfo, - rng *fastRNG.StreamGenerator, - email, phone fact.Fact, kv *versioned.KV) (*Manager, error) { +func NewManagerFromBackup(e2e E2E, follower NetworkStatus, + email, phone fact.Fact) (*Manager, error) { jww.INFO.Println("ud.NewManagerFromBackup()") if follower() != xxdk.Running { return nil, errors.New( @@ -150,18 +144,17 @@ func NewManagerFromBackup(services CMix, // Initialize manager m := &Manager{ - network: services, - e2e: e2e, - events: events, - comms: comms, - user: userStore, - kv: kv, - rng: rng, + network: e2e.GetCmix(), + e2e: e2e(), + events: e2e.GetEventReporter(), + comms: e2e.GetComms(), + kv: e2e.GetStorage().GetKV(), + rng: e2e.GetRng(), } // Initialize our store var err error - m.store, err = store.NewOrLoadStore(kv) + m.store, err = store.NewOrLoadStore(m.kv) if err != nil { return nil, err } @@ -175,7 +168,7 @@ func NewManagerFromBackup(services CMix, // Set as registered. Since it's from a backup, // the client is already registered - if err = setRegistered(kv); err != nil { + if err = setRegistered(m.kv); err != nil { return nil, errors.WithMessage(err, "failed to set client as "+ "registered with user discovery.") } @@ -219,19 +212,15 @@ func InitStoreFromBackup(kv *versioned.KV, // LoadManager loads the state of the Manager // from disk. This is meant to be called after any the first // instantiation of the manager by NewUserDiscovery. -func LoadManager(services CMix, e2e E2E, - events event.Reporter, comms Comms, userStore UserInfo, - rng *fastRNG.StreamGenerator, - kv *versioned.KV) (*Manager, error) { +func LoadManager(e2e E2E) (*Manager, error) { m := &Manager{ - network: services, + network: e2e.GetCmix(), e2e: e2e, - events: events, - comms: comms, - user: userStore, - rng: rng, - kv: kv, + events: e2e.GetEventReporter(), + comms: e2e.GetComms(), + rng: e2e.GetRng(), + kv: e2e.GetStorage().GetKV(), } if !m.isRegistered() { @@ -240,7 +229,7 @@ func LoadManager(services CMix, e2e E2E, } var err error - m.store, err = store.NewOrLoadStore(kv) + m.store, err = store.NewOrLoadStore(m.kv) if err != nil { return nil, errors.Errorf("Failed to initialize store: %v", err) } @@ -262,7 +251,10 @@ func (m *Manager) GetStringifiedFacts() []string { // GetContact returns the contact for UD as retrieved from the NDF. func (m *Manager) GetContact() (contact.Contact, error) { - grp := m.e2e.GetGroup() + grp, err := m.e2e.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 diff --git a/ud/register.go b/ud/register.go index 3df8edd64..591a1cf1f 100644 --- a/ud/register.go +++ b/ud/register.go @@ -17,24 +17,37 @@ func (m *Manager) register(username string, rng csprng.Source, comm registerUserComms, udHost *connect.Host) error { var err error - cryptoUser := m.user.PortableUserInfo() + identity := m.e2e.GetReceptionIdentity() + privKey, err := identity.GetRSAPrivatePem() + if err != nil { + return err + } + grp, err := identity.GetGroup() + if err != nil { + return err + } + dhKeyPriv, err := identity.GetDHKeyPrivate() + if err != nil { + return err + } + dhKeyPub := grp.ExpG(dhKeyPriv, grp.NewInt(1)) // Construct the user registration message msg := &pb.UDBUserRegistration{ - PermissioningSignature: m.user.GetReceptionRegistrationValidationSignature(), - RSAPublicPem: string(rsa.CreatePublicKeyPem(cryptoUser.ReceptionRSA.GetPublic())), + PermissioningSignature: m.registrationValidationSignature, + RSAPublicPem: string(rsa.CreatePublicKeyPem(privKey.GetPublic())), IdentityRegistration: &pb.Identity{ Username: username, - DhPubKey: m.e2e.GetHistoricalDHPubkey().Bytes(), - Salt: cryptoUser.ReceptionSalt, + DhPubKey: dhKeyPub.Bytes(), + Salt: identity.Salt, }, - UID: cryptoUser.ReceptionID.Marshal(), - Timestamp: cryptoUser.RegistrationTimestamp, + UID: identity.ID.Marshal(), + Timestamp: m.e2e.GetTransmissionIdentity().RegistrationTimestamp, } // Sign the identity data and add to user registration message identityDigest := msg.IdentityRegistration.Digest() - msg.IdentitySignature, err = rsa.Sign(rng, cryptoUser.ReceptionRSA, + msg.IdentitySignature, err = rsa.Sign(rng, privKey, hash.CMixHash, identityDigest, nil) if err != nil { return errors.Errorf("Failed to sign user's IdentityRegistration: %+v", err) @@ -48,11 +61,11 @@ func (m *Manager) register(username string, rng csprng.Source, // Hash and sign fact hashedFact := factID.Fingerprint(usernameFact) - signedFact, err := rsa.Sign(rng, cryptoUser.ReceptionRSA, hash.CMixHash, hashedFact, nil) + signedFact, err := rsa.Sign(rng, privKey, hash.CMixHash, hashedFact, nil) // Add username fact register request to the user registration message msg.Frs = &pb.FactRegisterRequest{ - UID: cryptoUser.ReceptionID.Marshal(), + UID: identity.ID.Marshal(), Fact: &pb.Fact{ Fact: username, FactType: 0, diff --git a/ud/remove.go b/ud/remove.go index b64a218e6..97fbc8a19 100644 --- a/ud/remove.go +++ b/ud/remove.go @@ -45,7 +45,11 @@ func (m *Manager) removeFact(f fact.Fact, fHash := factID.Fingerprint(f) // Sign our inFact for putting into the request - privKey := m.user.PortableUserInfo().ReceptionRSA + identity := m.e2e.GetReceptionIdentity() + privKey, err := identity.GetRSAPrivatePem() + if err != nil { + return err + } stream := m.rng.GetStream() defer stream.Close() fSig, err := rsa.Sign(stream, privKey, hash.CMixHash, fHash, nil) @@ -55,7 +59,7 @@ func (m *Manager) removeFact(f fact.Fact, // Create our Fact Removal Request message data remFactMsg := mixmessages.FactRemovalRequest{ - UID: m.e2e.GetReceptionID().Marshal(), + UID: identity.ID.Marshal(), RemovalData: &mmFact, FactSig: fSig, } @@ -84,9 +88,14 @@ func (m *Manager) PermanentDeleteAccount(f fact.Fact) error { if err != nil { return err } - privKey := m.user.PortableUserInfo().ReceptionRSA - return m.permanentDeleteAccount(f, m.e2e.GetReceptionID(), privKey, m.comms, udHost) + identity := m.e2e.GetReceptionIdentity() + privKey, err := identity.GetRSAPrivatePem() + if err != nil { + return err + } + + return m.permanentDeleteAccount(f, identity.ID, privKey, m.comms, udHost) } // permanentDeleteAccount is a helper function for PermanentDeleteAccount. diff --git a/xxdk/cmix.go b/xxdk/cmix.go index fbc08044b..6bc1f0915 100644 --- a/xxdk/cmix.go +++ b/xxdk/cmix.go @@ -213,12 +213,12 @@ func LoadCmix(storageDir string, password []byte, parameters CMIXParams) (*Cmix, return nil, err } - jww.INFO.Printf("Cmix Logged in: \n\tTransmissionID: %s "+ - "\n\tReceptionID: %s", c.storage.GetTransmissionID(), c.storage.GetReceptionID()) + jww.INFO.Printf("Client loaded: \n\tTransmissionID: %s", + c.GetTransmissionIdentity().ID) def := c.storage.GetNDF() - //initialize registration + //initialize registration. if def.Registration.Address != "" { err = c.initPermissioning(def) if err != nil { @@ -257,13 +257,14 @@ func (c *Cmix) initComms() error { var err error //get the user from session - privKey := c.storage.GetTransmissionRSA() + transmissionIdentity := c.GetTransmissionIdentity() + privKey := transmissionIdentity.RSAPrivatePem pubPEM := rsa.CreatePublicKeyPem(privKey.GetPublic()) privPEM := rsa.CreatePrivateKeyPem(privKey) //start comms - c.comms, err = client.NewClientComms(c.storage.GetTransmissionID(), - pubPEM, privPEM, c.storage.GetTransmissionSalt()) + c.comms, err = client.NewClientComms(transmissionIdentity.ID, + pubPEM, privPEM, transmissionIdentity.Salt) if err != nil { return errors.WithMessage(err, "failed to load client") } diff --git a/xxdk/e2e.go b/xxdk/e2e.go index 55c83b6f4..0e5592536 100644 --- a/xxdk/e2e.go +++ b/xxdk/e2e.go @@ -248,6 +248,8 @@ func login(client *Cmix, callbacks AuthCallbacks, identity ReceptionIdentity, } client.network.AddIdentity(identity.ID, time.Time{}, true) + jww.INFO.Printf("Client logged in: \n\tReceptionID: %s", + identity.ID) return m, err } diff --git a/xxdk/identity.go b/xxdk/identity.go index 97de12400..96100eddf 100644 --- a/xxdk/identity.go +++ b/xxdk/identity.go @@ -81,6 +81,12 @@ func (r ReceptionIdentity) GetRSAPrivatePem() (*rsa.PrivateKey, error) { return rsa.LoadPrivateKeyFromPem(r.RSAPrivatePem) } +// GetGroup returns the cyclic.Group in go format +func (r ReceptionIdentity) GetGroup() (*cyclic.Group, error) { + grp := &cyclic.Group{} + return grp, grp.UnmarshalJSON(r.E2eGrp) +} + // MakeReceptionIdentity generates a new cryptographic identity // for receiving messages. func MakeReceptionIdentity(client *Cmix) (ReceptionIdentity, error) { @@ -155,8 +161,7 @@ func (r ReceptionIdentity) DeepCopy() ReceptionIdentity { // GetContact accepts a xxdk.ReceptionIdentity object and returns a contact.Contact object func (r ReceptionIdentity) GetContact() contact.Contact { - grp := &cyclic.Group{} - _ = grp.UnmarshalJSON(r.E2eGrp) + grp, _ := r.GetGroup() dhKeyPriv, _ := r.GetDHKeyPrivate() dhPub := grp.ExpG(dhKeyPriv, grp.NewInt(1)) -- GitLab