Skip to content
Snippets Groups Projects
Commit b73aabf6 authored by Richard T. Carback III's avatar Richard T. Carback III
Browse files

Move NewClientFromBackup to messenger, and modify UD to allow init of storage

parent 9a95ec40
No related branches found
No related tags found
3 merge requests!510Release,!226WIP: Api2.0,!207WIP: Client Restructure
...@@ -25,7 +25,6 @@ import ( ...@@ -25,7 +25,6 @@ import (
"gitlab.com/elixxir/client/storage" "gitlab.com/elixxir/client/storage"
"gitlab.com/elixxir/client/storage/user" "gitlab.com/elixxir/client/storage/user"
"gitlab.com/elixxir/comms/client" "gitlab.com/elixxir/comms/client"
cryptoBackup "gitlab.com/elixxir/crypto/backup"
"gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/elixxir/crypto/fastRNG" "gitlab.com/elixxir/crypto/fastRNG"
"gitlab.com/elixxir/primitives/version" "gitlab.com/elixxir/primitives/version"
...@@ -74,18 +73,18 @@ func NewClient(ndfJSON, storageDir string, password []byte, ...@@ -74,18 +73,18 @@ func NewClient(ndfJSON, storageDir string, password []byte,
rngStreamGen := fastRNG.NewStreamGenerator(12, 1024, rngStreamGen := fastRNG.NewStreamGenerator(12, 1024,
csprng.NewSystemRNG) csprng.NewSystemRNG)
def, err := parseNDF(ndfJSON) def, err := ParseNDF(ndfJSON)
if err != nil { if err != nil {
return err return err
} }
cmixGrp, e2eGrp := decodeGroups(def) cmixGrp, e2eGrp := DecodeGroups(def)
start := netTime.Now() start := netTime.Now()
protoUser := createNewUser(rngStreamGen) protoUser := createNewUser(rngStreamGen)
jww.DEBUG.Printf("PortableUserInfo generation took: %s", jww.DEBUG.Printf("PortableUserInfo generation took: %s",
netTime.Now().Sub(start)) netTime.Now().Sub(start))
_, err = checkVersionAndSetupStorage(def, storageDir, password, _, err = CheckVersionAndSetupStorage(def, storageDir, password,
protoUser, cmixGrp, e2eGrp, registrationCode) protoUser, cmixGrp, e2eGrp, registrationCode)
if err != nil { if err != nil {
return err return err
...@@ -107,16 +106,16 @@ func NewVanityClient(ndfJSON, storageDir string, password []byte, ...@@ -107,16 +106,16 @@ func NewVanityClient(ndfJSON, storageDir string, password []byte,
csprng.NewSystemRNG) csprng.NewSystemRNG)
rngStream := rngStreamGen.GetStream() rngStream := rngStreamGen.GetStream()
def, err := parseNDF(ndfJSON) def, err := ParseNDF(ndfJSON)
if err != nil { if err != nil {
return err return err
} }
cmixGrp, e2eGrp := decodeGroups(def) cmixGrp, e2eGrp := DecodeGroups(def)
protoUser := createNewVanityUser(rngStream, cmixGrp, e2eGrp, protoUser := createNewVanityUser(rngStream, cmixGrp, e2eGrp,
userIdPrefix) userIdPrefix)
_, err = checkVersionAndSetupStorage(def, storageDir, password, _, err = CheckVersionAndSetupStorage(def, storageDir, password,
protoUser, cmixGrp, e2eGrp, registrationCode) protoUser, cmixGrp, e2eGrp, registrationCode)
if err != nil { if err != nil {
return err return err
...@@ -125,53 +124,6 @@ func NewVanityClient(ndfJSON, storageDir string, password []byte, ...@@ -125,53 +124,6 @@ func NewVanityClient(ndfJSON, storageDir string, password []byte,
return nil return nil
} }
// NewClientFromBackup constructs a new Client from an encrypted
// backup. The backup is decrypted using the backupPassphrase. On
// success a successful client creation, the function will return a
// JSON encoded list of the E2E partners contained in the backup and a
// json-encoded string containing parameters stored in the backup
func NewClientFromBackup(ndfJSON, storageDir string, sessionPassword,
backupPassphrase []byte, backupFileContents []byte) ([]*id.ID,
string, error) {
backUp := &cryptoBackup.Backup{}
err := backUp.Decrypt(string(backupPassphrase), backupFileContents)
if err != nil {
return nil, "", errors.WithMessage(err,
"Failed to unmarshal decrypted client contents.")
}
usr := user.NewUserFromBackup(backUp)
def, err := parseNDF(ndfJSON)
if err != nil {
return nil, "", err
}
cmixGrp, e2eGrp := decodeGroups(def)
// Note we do not need registration here
storageSess, err := checkVersionAndSetupStorage(def, storageDir,
[]byte(sessionPassword), usr, cmixGrp, e2eGrp,
backUp.RegistrationCode)
storageSess.SetReceptionRegistrationValidationSignature(
backUp.ReceptionIdentity.RegistrarSignature)
storageSess.SetTransmissionRegistrationValidationSignature(
backUp.TransmissionIdentity.RegistrarSignature)
storageSess.SetRegistrationTimestamp(backUp.RegistrationTimestamp)
//move the registration state to indicate registered with
// registration on proto client
err = storageSess.ForwardRegistrationStatus(
storage.PermissioningComplete)
if err != nil {
return nil, "", err
}
return backUp.Contacts.Identities, backUp.JSONParams, nil
}
// OpenClient session, but don't connect to the network or log in // OpenClient session, but don't connect to the network or log in
func OpenClient(storageDir string, password []byte, func OpenClient(storageDir string, password []byte,
parameters Params) (*Client, error) { parameters Params) (*Client, error) {
...@@ -224,12 +176,12 @@ func NewProtoClient_Unsafe(ndfJSON, storageDir string, password, ...@@ -224,12 +176,12 @@ func NewProtoClient_Unsafe(ndfJSON, storageDir string, password,
protoClientJSON []byte) error { protoClientJSON []byte) error {
jww.INFO.Printf("NewProtoClient_Unsafe") jww.INFO.Printf("NewProtoClient_Unsafe")
def, err := parseNDF(ndfJSON) def, err := ParseNDF(ndfJSON)
if err != nil { if err != nil {
return err return err
} }
cmixGrp, e2eGrp := decodeGroups(def) cmixGrp, e2eGrp := DecodeGroups(def)
protoUser := &user.Proto{} protoUser := &user.Proto{}
err = json.Unmarshal(protoClientJSON, protoUser) err = json.Unmarshal(protoClientJSON, protoUser)
...@@ -239,7 +191,7 @@ func NewProtoClient_Unsafe(ndfJSON, storageDir string, password, ...@@ -239,7 +191,7 @@ func NewProtoClient_Unsafe(ndfJSON, storageDir string, password,
usr := user.NewUserFromProto(protoUser) usr := user.NewUserFromProto(protoUser)
storageSess, err := checkVersionAndSetupStorage(def, storageDir, storageSess, err := CheckVersionAndSetupStorage(def, storageDir,
password, usr, cmixGrp, e2eGrp, protoUser.RegCode) password, usr, cmixGrp, e2eGrp, protoUser.RegCode)
if err != nil { if err != nil {
return err return err
...@@ -325,7 +277,7 @@ func LoginWithNewBaseNDF_UNSAFE(storageDir string, password []byte, ...@@ -325,7 +277,7 @@ func LoginWithNewBaseNDF_UNSAFE(storageDir string, password []byte,
params Params) (*Client, error) { params Params) (*Client, error) {
jww.INFO.Printf("LoginWithNewBaseNDF_UNSAFE()") jww.INFO.Printf("LoginWithNewBaseNDF_UNSAFE()")
def, err := parseNDF(newBaseNdf) def, err := ParseNDF(newBaseNdf)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -370,7 +322,7 @@ func LoginWithProtoClient(storageDir string, password []byte, ...@@ -370,7 +322,7 @@ func LoginWithProtoClient(storageDir string, password []byte,
params Params) (*Client, error) { params Params) (*Client, error) {
jww.INFO.Printf("LoginWithProtoClient()") jww.INFO.Printf("LoginWithProtoClient()")
def, err := parseNDF(newBaseNdf) def, err := ParseNDF(newBaseNdf)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -689,9 +641,9 @@ func (c *Client) GetPreferredBins(countryCode string) ([]string, error) { ...@@ -689,9 +641,9 @@ func (c *Client) GetPreferredBins(countryCode string) ([]string, error) {
} }
// ----- Utility Functions ----- // ----- Utility Functions -----
// parseNDF parses the initial ndf string for the client. do not check the // ParseNDF parses the initial ndf string for the client. do not check the
// signature, it is deprecated. // signature, it is deprecated.
func parseNDF(ndfString string) (*ndf.NetworkDefinition, error) { func ParseNDF(ndfString string) (*ndf.NetworkDefinition, error) {
if ndfString == "" { if ndfString == "" {
return nil, errors.New("ndf file empty") return nil, errors.New("ndf file empty")
} }
...@@ -704,8 +656,8 @@ func parseNDF(ndfString string) (*ndf.NetworkDefinition, error) { ...@@ -704,8 +656,8 @@ func parseNDF(ndfString string) (*ndf.NetworkDefinition, error) {
return netDef, nil return netDef, nil
} }
// decodeGroups returns the e2e and cmix groups from the ndf // DecodeGroups returns the e2e and cmix groups from the ndf
func decodeGroups(ndf *ndf.NetworkDefinition) (cmixGrp, e2eGrp *cyclic.Group) { func DecodeGroups(ndf *ndf.NetworkDefinition) (cmixGrp, e2eGrp *cyclic.Group) {
largeIntBits := 16 largeIntBits := 16
//Generate the cmix group //Generate the cmix group
...@@ -720,10 +672,10 @@ func decodeGroups(ndf *ndf.NetworkDefinition) (cmixGrp, e2eGrp *cyclic.Group) { ...@@ -720,10 +672,10 @@ func decodeGroups(ndf *ndf.NetworkDefinition) (cmixGrp, e2eGrp *cyclic.Group) {
return cmixGrp, e2eGrp return cmixGrp, e2eGrp
} }
// checkVersionAndSetupStorage is common code shared by NewClient, // CheckVersionAndSetupStorage is common code shared by NewClient,
// NewPrecannedClient and NewVanityClient it checks client version and // NewPrecannedClient and NewVanityClient it checks client version and
// creates a new storage for user data // creates a new storage for user data
func checkVersionAndSetupStorage(def *ndf.NetworkDefinition, func CheckVersionAndSetupStorage(def *ndf.NetworkDefinition,
storageDir string, password []byte, protoUser user.Info, storageDir string, password []byte, protoUser user.Info,
cmixGrp, e2eGrp *cyclic.Group, registrationCode string) ( cmixGrp, e2eGrp *cyclic.Group, registrationCode string) (
storage.Session, error) { storage.Session, error) {
......
...@@ -69,11 +69,20 @@ func LoadOrInitE2e(client *api.Client) (e2e.Handler, error) { ...@@ -69,11 +69,20 @@ func LoadOrInitE2e(client *api.Client) (e2e.Handler, error) {
//generate the key //generate the key
var privkey *cyclic.Int var privkey *cyclic.Int
if client.GetStorage().IsPrecanned() { if client.GetStorage().IsPrecanned() {
precannedID := binary.BigEndian.Uint64(client.GetStorage().GetReceptionID()[:]) jww.WARN.Printf("Using Precanned DH key")
privkey = generatePrecanDHKeypair(uint(precannedID), client.GetStorage().GetE2EGroup()) precannedID := binary.BigEndian.Uint64(
client.GetStorage().GetReceptionID()[:])
privkey = generatePrecanDHKeypair(
uint(precannedID),
client.GetStorage().GetE2EGroup())
} else if usr.E2eDhPrivateKey != nil {
jww.INFO.Printf("Using pre-existing DH key")
privkey = usr.E2eDhPrivateKey
} else { } else {
jww.INFO.Printf("Generating new DH key")
rngStream := client.GetRng().GetStream() rngStream := client.GetRng().GetStream()
privkey = diffieHellman.GeneratePrivateKey(len(e2eGrp.GetPBytes()), privkey = diffieHellman.GeneratePrivateKey(
len(e2eGrp.GetPBytes()),
e2eGrp, rngStream) e2eGrp, rngStream)
rngStream.Close() rngStream.Close()
} }
......
...@@ -9,6 +9,7 @@ package api ...@@ -9,6 +9,7 @@ package api
import ( import (
"encoding/binary" "encoding/binary"
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/storage" "gitlab.com/elixxir/client/storage"
"gitlab.com/elixxir/client/storage/user" "gitlab.com/elixxir/client/storage/user"
...@@ -59,15 +60,15 @@ func NewPrecannedClient(precannedID uint, defJSON, storageDir string, ...@@ -59,15 +60,15 @@ func NewPrecannedClient(precannedID uint, defJSON, storageDir string,
csprng.NewSystemRNG) csprng.NewSystemRNG)
rngStream := rngStreamGen.GetStream() rngStream := rngStreamGen.GetStream()
def, err := parseNDF(defJSON) def, err := ParseNDF(defJSON)
if err != nil { if err != nil {
return err return err
} }
cmixGrp, e2eGrp := decodeGroups(def) cmixGrp, e2eGrp := DecodeGroups(def)
protoUser := CreatePrecannedUser(precannedID, rngStream) protoUser := CreatePrecannedUser(precannedID, rngStream)
store, err := checkVersionAndSetupStorage(def, storageDir, password, store, err := CheckVersionAndSetupStorage(def, storageDir, password,
protoUser, cmixGrp, e2eGrp, "") protoUser, cmixGrp, e2eGrp, "")
if err != nil { if err != nil {
return err return err
......
...@@ -560,8 +560,11 @@ func createClient() *api.Client { ...@@ -560,8 +560,11 @@ func createClient() *api.Client {
} }
// Construct client from backup data // Construct client from backup data
backupIdList, _, err := api.NewClientFromBackup(string(ndfJSON), storeDir, backupIdList, _, err := messenger.NewClientFromBackup(string(ndfJSON), storeDir,
pass, backupPass, backupFile) pass, backupPass, backupFile)
if err != nil {
jww.FATAL.Panicf("%+v", err)
}
backupIdListPath := viper.GetString("backupIdList") backupIdListPath := viper.GetString("backupIdList")
if backupIdListPath != "" { if backupIdListPath != "" {
......
...@@ -2,6 +2,9 @@ package ud ...@@ -2,6 +2,9 @@ package ud
import ( import (
"fmt" "fmt"
"sync"
"time"
"github.com/pkg/errors" "github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/api" "gitlab.com/elixxir/client/api"
...@@ -13,8 +16,6 @@ import ( ...@@ -13,8 +16,6 @@ import (
"gitlab.com/xx_network/comms/connect" "gitlab.com/xx_network/comms/connect"
"gitlab.com/xx_network/crypto/csprng" "gitlab.com/xx_network/crypto/csprng"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"sync"
"time"
) )
const ( const (
...@@ -116,7 +117,7 @@ func NewManager(services CMix, e2e E2E, ...@@ -116,7 +117,7 @@ func NewManager(services CMix, e2e E2E,
} }
// Set storage to registered // Set storage to registered
if err = m.setRegistered(); err != nil && m.events != nil { if err = setRegistered(kv); err != nil && m.events != nil {
m.events.Report(1, "UserDiscovery", "Registration", m.events.Report(1, "UserDiscovery", "Registration",
fmt.Sprintf("User Registered with UD: %+v", fmt.Sprintf("User Registered with UD: %+v",
username)) username))
...@@ -163,6 +164,13 @@ func NewManagerFromBackup(services CMix, ...@@ -163,6 +164,13 @@ func NewManagerFromBackup(services CMix,
"from backup") "from backup")
} }
// Set as registered. Since it's from a backup,
// the client is already registered
if err = setRegistered(kv); err != nil {
return nil, errors.WithMessage(err, "failed to set client as "+
"registered with user discovery.")
}
// Create the user discovery host object // Create the user discovery host object
_, err = m.getOrAddUdHost() _, err = m.getOrAddUdHost()
if err != nil { if err != nil {
...@@ -170,14 +178,33 @@ func NewManagerFromBackup(services CMix, ...@@ -170,14 +178,33 @@ func NewManagerFromBackup(services CMix,
"not be constructed.") "not be constructed.")
} }
return m, nil
}
// InitStoreFromBackup initializes the UD storage from the backup subsystem
func InitStoreFromBackup(kv *versioned.KV,
username, email, phone fact.Fact) error {
// Initialize our store
udStore, err := store.NewOrLoadStore(kv)
if err != nil {
return err
}
// Put any passed in missing facts into store
err = udStore.BackUpMissingFacts(email, phone)
if err != nil {
return errors.WithMessage(err, "Failed to restore UD store "+
"from backup")
}
// 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
if err = m.setRegistered(); err != nil { if err = setRegistered(kv); err != nil {
return nil, errors.WithMessage(err, "failed to set client as "+ return errors.WithMessage(err, "failed to set client as "+
"registered with user discovery.") "registered with user discovery.")
} }
return m, nil return nil
} }
// LoadManager loads the state of the Manager // LoadManager loads the state of the Manager
......
...@@ -2,6 +2,7 @@ package ud ...@@ -2,6 +2,7 @@ package ud
import ( import (
"encoding/binary" "encoding/binary"
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/storage/versioned" "gitlab.com/elixxir/client/storage/versioned"
"gitlab.com/xx_network/primitives/netTime" "gitlab.com/xx_network/primitives/netTime"
...@@ -21,8 +22,8 @@ func (m *Manager) isRegistered() bool { ...@@ -21,8 +22,8 @@ func (m *Manager) isRegistered() bool {
return true return true
} }
// isRegistered returns if the client is registered with user discovery // setRegistered sets the user to registered
func (m *Manager) setRegistered() error { func setRegistered(kv *versioned.KV) error {
data := make([]byte, 4) data := make([]byte, 4)
binary.BigEndian.PutUint32(data, 1) binary.BigEndian.PutUint32(data, 1)
obj := &versioned.Object{ obj := &versioned.Object{
...@@ -31,7 +32,7 @@ func (m *Manager) setRegistered() error { ...@@ -31,7 +32,7 @@ func (m *Manager) setRegistered() error {
Data: data, Data: data,
} }
if err := m.kv.Set(isRegisteredKey, isRegisteredVersion, obj); err != nil { if err := kv.Set(isRegisteredKey, isRegisteredVersion, obj); err != nil {
jww.FATAL.Panicf("Failed to store that the client is "+ jww.FATAL.Panicf("Failed to store that the client is "+
"registered: %+v", err) "registered: %+v", err)
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment