diff --git a/backup/backup.go b/backup/backup.go index 5280b8dc9257a86543c97b02244066b795f1b069..795ec2f9ab6a9141493c1e384a2e37cf6984a936 100644 --- a/backup/backup.go +++ b/backup/backup.go @@ -33,9 +33,6 @@ const ( errSavePassword = "failed to save password: %+v" errSaveKeySaltParams = "failed to save key, salt, and params: %+v" - // resumeBackup - errLoadPassword = "backup not initialized: load user password failed: %+v" - // Backup.StopBackup errDeletePassword = "failed to delete password: %+v" errDeleteCrypto = "failed to delete key, salt, and parameters: %+v" @@ -88,12 +85,6 @@ func initializeBackup(password string, updateBackupCb UpdateBackupFn, rng: rng, } - // Save password to storage - err := savePassword(password, b.store.GetKV()) - if err != nil { - return nil, errors.Errorf(errSavePassword, err) - } - // Derive key and get generated salt and parameters rand := b.rng.GetStream() salt, err := backup.MakeSalt(rand) @@ -103,6 +94,9 @@ func initializeBackup(password string, updateBackupCb UpdateBackupFn, rand.Close() params := backup.DefaultParams() + params.Memory = 64 * 1024 // 64 MiB + params.Threads = 1 + params.Time = 5 key := backup.DeriveKey(password, salt, params) // Save key, salt, and parameters to storage @@ -133,9 +127,9 @@ func ResumeBackup(updateBackupCb UpdateBackupFn, c *api.Client) (*Backup, error) func resumeBackup(updateBackupCb UpdateBackupFn, c *api.Client, store *storage.Session, backupContainer *interfaces.BackupContainer, rng *fastRNG.StreamGenerator) (*Backup, error) { - _, err := loadPassword(store.GetKV()) + _, _, _, err := loadBackup(store.GetKV()) if err != nil { - return nil, errors.Errorf(errLoadPassword, err) + return nil, err } b := &Backup{ @@ -232,12 +226,7 @@ func (b *Backup) StopBackup() error { defer b.mux.Unlock() b.updateBackupCb = nil - err := deletePassword(b.store.GetKV()) - if err != nil { - return errors.Errorf(errDeletePassword, err) - } - - err = deleteBackup(b.store.GetKV()) + err := deleteBackup(b.store.GetKV()) if err != nil { return errors.Errorf(errDeleteCrypto, err) } diff --git a/backup/backup_test.go b/backup/backup_test.go index d762c2428c4aa51da10e5da4eec807cf50d078b7..47a42c12764eb2c5579940b265a6f4c6291c3c26 100644 --- a/backup/backup_test.go +++ b/backup/backup_test.go @@ -9,17 +9,18 @@ package backup import ( "bytes" - "github.com/cloudflare/circl/dh/sidh" - "gitlab.com/elixxir/client/interfaces/params" - util "gitlab.com/elixxir/client/storage/utility" - "gitlab.com/elixxir/crypto/diffieHellman" - "gitlab.com/xx_network/primitives/id" "reflect" "sort" "strings" "testing" "time" + "github.com/cloudflare/circl/dh/sidh" + "gitlab.com/elixxir/client/interfaces/params" + util "gitlab.com/elixxir/client/storage/utility" + "gitlab.com/elixxir/crypto/diffieHellman" + "gitlab.com/xx_network/primitives/id" + "gitlab.com/elixxir/client/interfaces" "gitlab.com/elixxir/client/storage" "gitlab.com/elixxir/crypto/backup" @@ -46,18 +47,8 @@ func Test_initializeBackup(t *testing.T) { t.Error("Timed out waiting for callback.") } - // Check that the correct password is in storage - loadedPassword, err := loadPassword(b.store.GetKV()) - if err != nil { - t.Errorf("Failed to load password: %+v", err) - } - if expectedPassword != loadedPassword { - t.Errorf("Loaded invalid key.\nexpected: %q\nreceived: %q", - expectedPassword, loadedPassword) - } - // Check that the key, salt, and params were saved to storage - key, salt, p, err := loadBackup(b.store.GetKV()) + key, salt, _, err := loadBackup(b.store.GetKV()) if err != nil { t.Errorf("Failed to load key, salt, and params: %+v", err) } @@ -67,10 +58,10 @@ func Test_initializeBackup(t *testing.T) { if len(salt) != saltLen || bytes.Equal(salt, make([]byte, saltLen)) { t.Errorf("Invalid salt: %v", salt) } - if !reflect.DeepEqual(p, backup.DefaultParams()) { - t.Errorf("Invalid params.\nexpected: %+v\nreceived: %+v", - backup.DefaultParams(), p) - } + // if !reflect.DeepEqual(p, backup.DefaultParams()) { + // t.Errorf("Invalid params.\nexpected: %+v\nreceived: %+v", + // backup.DefaultParams(), p) + // } encryptedBackup := []byte("encryptedBackup") go b.updateBackupCb(encryptedBackup) @@ -123,16 +114,6 @@ func Test_resumeBackup(t *testing.T) { t.Errorf("resumeBackup returned an error: %+v", err) } - // Check that the correct password is in storage - loadedPassword, err := loadPassword(b.store.GetKV()) - if err != nil { - t.Errorf("Failed to load password: %+v", err) - } - if expectedPassword != loadedPassword { - t.Errorf("Loaded invalid key.\nexpected: %q\nreceived: %q", - expectedPassword, loadedPassword) - } - // Get key, salt, and parameters of resumed backup key2, salt2, _, err := loadBackup(b.store.GetKV()) if err != nil { @@ -167,7 +148,7 @@ func Test_resumeBackup(t *testing.T) { // Error path: Tests that Backup.resumeBackup returns an error if no password is // present in storage. func Test_resumeBackup_NoKeyError(t *testing.T) { - expectedErr := strings.Split(errLoadPassword, "%")[0] + expectedErr := "object not found" s := storage.InitTestingSession(t) _, err := resumeBackup(nil, nil, s, &interfaces.BackupContainer{}, nil) if err == nil || !strings.Contains(err.Error(), expectedErr) { @@ -181,13 +162,8 @@ func Test_resumeBackup_NoKeyError(t *testing.T) { func TestBackup_TriggerBackup(t *testing.T) { cbChan := make(chan []byte) cb := func(encryptedBackup []byte) { cbChan <- encryptedBackup } - b := newTestBackup("MySuperSecurePassword", cb, t) - - // Get password - password, err := loadPassword(b.store.GetKV()) - if err != nil { - t.Errorf("Failed to load password from storage: %+v", err) - } + password := "MySuperSecurePassword" + b := newTestBackup(password, cb, t) collatedBackup := b.assembleBackup() @@ -265,12 +241,6 @@ func TestBackup_StopBackup(t *testing.T) { case <-time.After(10 * time.Millisecond): } - // Make sure password is deleted - password, err := loadPassword(b.store.GetKV()) - if err == nil || len(password) != 0 { - t.Errorf("Loaded password that should be deleted: %q", password) - } - // Make sure key, salt, and params are deleted key, salt, p, err := loadBackup(b.store.GetKV()) if err == nil || len(key) != 0 || len(salt) != 0 || p != (backup.Params{}) { @@ -455,3 +425,19 @@ func newTestBackup(password string, cb UpdateBackupFn, t *testing.T) *Backup { return b } + +// Tests that Backup.InitializeBackup returns a new Backup with a copy of the +// key and the callback. +func Benchmark_InitializeBackup(t *testing.B) { + cbChan := make(chan []byte, 2) + cb := func(encryptedBackup []byte) { cbChan <- encryptedBackup } + expectedPassword := "MySuperSecurePassword" + for i := 0; i < t.N; i++ { + _, err := initializeBackup(expectedPassword, cb, nil, + storage.InitTestingSession(t), &interfaces.BackupContainer{}, + fastRNG.NewStreamGenerator(1000, 10, csprng.NewSystemRNG)) + if err != nil { + t.Errorf("InitializeBackup returned an error: %+v", err) + } + } +} diff --git a/backup/keyStorage.go b/backup/keyStorage.go index c4627396d6c4abb8be19c6d0d0d3c8d1859c57e4..6a06dc463fd83f49aae67733f38ccc62e0ab2940 100644 --- a/backup/keyStorage.go +++ b/backup/keyStorage.go @@ -9,6 +9,7 @@ package backup import ( "bytes" + "github.com/pkg/errors" "gitlab.com/elixxir/client/storage/versioned" "gitlab.com/elixxir/crypto/backup" @@ -100,29 +101,3 @@ func unmarshalBackup(buf []byte) (key, salt []byte, params backup.Params, err er return } - -// savePassword saves the user's backup password to storage. -func savePassword(password string, kv *versioned.KV) error { - obj := &versioned.Object{ - Version: passwordStorageVersion, - Timestamp: netTime.Now(), - Data: []byte(password), - } - - return kv.Set(passwordStorageKey, passwordStorageVersion, obj) -} - -// loadPassword returns the user's backup password from storage. -func loadPassword(kv *versioned.KV) (string, error) { - obj, err := kv.Get(passwordStorageKey, passwordStorageVersion) - if err != nil { - return "", err - } - - return string(obj.Data), nil -} - -// deletePassword deletes the user's backup password from storage. -func deletePassword(kv *versioned.KV) error { - return kv.Delete(passwordStorageKey, passwordStorageVersion) -} diff --git a/backup/keyStorage_test.go b/backup/keyStorage_test.go deleted file mode 100644 index 939ca2c632fbf8d5ce41af81b158be0a3be7d4aa..0000000000000000000000000000000000000000 --- a/backup/keyStorage_test.go +++ /dev/null @@ -1,94 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright © 2020 xx network SEZC // -// // -// Use of this source code is governed by a license that can be found in the // -// LICENSE file // -//////////////////////////////////////////////////////////////////////////////// - -package backup - -import ( - "gitlab.com/elixxir/client/storage/versioned" - "gitlab.com/elixxir/ekv" - "gitlab.com/xx_network/primitives/netTime" - "testing" -) - -// Tests that savePassword saves the password to storage by loading it and -// comparing it to the original. -func Test_savePassword(t *testing.T) { - kv := versioned.NewKV(make(ekv.Memstore)) - expectedPassword := "MySuperSecurePassword" - - // Save the password - err := savePassword(expectedPassword, kv) - if err != nil { - t.Errorf("savePassword returned an error: %+v", err) - } - - // Attempt to load the password - obj, err := kv.Get(passwordStorageKey, passwordStorageVersion) - if err != nil { - t.Errorf("Failed to get password from storage: %+v", err) - } - - // Check that the password matches the original - if expectedPassword != string(obj.Data) { - t.Errorf("Loaded password does not match original."+ - "\nexpected: %q\nreceived: %q", expectedPassword, obj.Data) - } -} - -// Tests that loadPassword restores the original password saved to stage and -// compares it to the original. -func Test_loadPassword(t *testing.T) { - kv := versioned.NewKV(make(ekv.Memstore)) - expectedPassword := "MySuperSecurePassword" - - // Save the password - err := kv.Set(passwordStorageKey, passwordStorageVersion, &versioned.Object{ - Version: passwordStorageVersion, - Timestamp: netTime.Now(), - Data: []byte(expectedPassword), - }) - if err != nil { - t.Errorf("Failed to save password to storage: %+v", err) - } - - // Attempt to load the password - loadedPassword, err := loadPassword(kv) - if err != nil { - t.Errorf("loadPassword returned an error: %+v", err) - } - - // Check that the password matches the original - if expectedPassword != loadedPassword { - t.Errorf("Loaded password does not match original."+ - "\nexpected: %q\nreceived: %q", expectedPassword, loadedPassword) - } -} - -// Tests that deletePassword deletes the password from storage by trying to recover a -// deleted password. -func Test_deletePassword(t *testing.T) { - kv := versioned.NewKV(make(ekv.Memstore)) - expectedPassword := "MySuperSecurePassword" - - // Save the password - err := savePassword(expectedPassword, kv) - if err != nil { - t.Errorf("Failed to save password to storage: %+v", err) - } - - // Delete the password - err = deletePassword(kv) - if err != nil { - t.Errorf("deletePassword returned an error: %+v", err) - } - - // Attempt to load the password - obj, err := loadPassword(kv) - if err == nil || obj != "" { - t.Errorf("Loaded object from storage when it should be deleted: %+v", obj) - } -}