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/crypto/csprng" "gitlab.com/xx_network/crypto/signature/rsa" ) // 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) error { // Retrieve data used for registration identity := m.user.GetReceptionIdentity() privKey, err := identity.GetRSAPrivateKey() if err != nil { return err } grp, err := identity.GetGroup() if err != nil { return err } dhKeyPriv, err := identity.GetDHKeyPrivate() if err != nil { return err } dhKeyPub := diffieHellman.GeneratePublicKey(dhKeyPriv, grp) // Construct the user registration message msg := &pb.UDBUserRegistration{ PermissioningSignature: networkSignature, RSAPublicPem: string(rsa.CreatePublicKeyPem(privKey.GetPublic())), IdentityRegistration: &pb.Identity{ Username: username, DhPubKey: dhKeyPub.Bytes(), Salt: identity.Salt, }, UID: identity.ID.Marshal(), Timestamp: m.user.GetTransmissionIdentity().RegistrationTimestamp, } // Sign the identity data and add to user registration message identityDigest := msg.IdentityRegistration.Digest() 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) } // Create new username fact usernameFact, err := fact.NewFact(fact.Username, username) if err != nil { return errors.Errorf("Failed to create new username fact: %+v", err) } // 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{ UID: identity.ID.Marshal(), Fact: &pb.Fact{ Fact: username, FactType: 0, }, FactSig: signedFact, } // Register user with user discovery _, 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 }