Skip to content
Snippets Groups Projects
Commit 03fe45d2 authored by Jake Taylor's avatar Jake Taylor :lips:
Browse files

Merge branch 'project/HavenBeta' into xx-4671/shared-db-cipher

# Conflicts:
#	go.mod
#	go.sum
parents ebc410aa 567e15ce
No related branches found
No related tags found
3 merge requests!128Project/base32768,!124Update for single DB cipher object,!109Project/haven beta
......@@ -23,6 +23,7 @@ import (
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/crypto/hash"
"gitlab.com/elixxir/wasm-utils/exception"
"gitlab.com/elixxir/wasm-utils/storage"
"gitlab.com/elixxir/wasm-utils/utils"
......@@ -40,6 +41,8 @@ const (
// saltLen is the length of the salt. Recommended to be 16 bytes here:
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-argon2-04#section-3.1
saltLen = 16
internalPasswordConstant = "XXInternalPassword"
)
// Storage keys.
......@@ -58,7 +61,7 @@ const (
// Error messages.
const (
// initInternalPassword
readInternalPasswordErr = "could not generate internal password: %+v"
readInternalPasswordErr = "could not generate"
internalPasswordNumBytesErr = "expected %d bytes for internal password, found %d bytes"
// getInternalPassword
......@@ -153,6 +156,9 @@ func getOrInit(externalPassword string) ([]byte, error) {
// changeExternalPassword is the private function for ChangeExternalPassword
// that is used for testing.
func changeExternalPassword(oldExternalPassword, newExternalPassword string) error {
// NOTE: the following no longer works in synchronized environments, so
// disabled in produciton.
jww.FATAL.Panicf("cannot change password, unimplemented")
localStorage := storage.GetLocalStorage()
internalPassword, err := getInternalPassword(
oldExternalPassword, localStorage)
......@@ -193,14 +199,22 @@ func initInternalPassword(externalPassword string,
params argonParams) ([]byte, error) {
internalPassword := make([]byte, internalPasswordLen)
// FIXME: The internal password is now just an expansion of
// the users password text. We couldn't preserve the following
// when doing cross-device sync.
h := hash.CMixHash.New()
h.Write([]byte(externalPassword))
h.Write(internalPassword)
copy(internalPassword, h.Sum(nil)[:internalPasswordLen])
// Generate internal password
n, err := csprng.Read(internalPassword)
if err != nil {
return nil, errors.Errorf(readInternalPasswordErr, err)
} else if n != internalPasswordLen {
return nil, errors.Errorf(
internalPasswordNumBytesErr, internalPasswordLen, n)
}
// n, err := csprng.Read(internalPassword)
// if err != nil {
// return nil, errors.Errorf(readInternalPasswordErr, err)
// } else if n != internalPasswordLen {
// return nil, errors.Errorf(
// internalPasswordNumBytesErr, internalPasswordLen, n)
// }
// Generate and store salt
salt, err := makeSalt(csprng)
......
......@@ -44,37 +44,37 @@ func Test_getOrInit(t *testing.T) {
// Tests that changeExternalPassword correctly changes the password and updates
// the encryption.
func Test_changeExternalPassword(t *testing.T) {
oldExternalPassword := "myPassword"
newExternalPassword := "hunter2"
oldInternalPassword, err := getOrInit(oldExternalPassword)
if err != nil {
t.Errorf("%+v", err)
}
err = changeExternalPassword(oldExternalPassword, newExternalPassword)
if err != nil {
t.Errorf("%+v", err)
}
newInternalPassword, err := getOrInit(newExternalPassword)
if err != nil {
t.Errorf("%+v", err)
}
if !bytes.Equal(oldInternalPassword, newInternalPassword) {
t.Errorf("Internal password was not changed in storage. Old and new "+
"should be different.\nold: %+v\nnew: %+v",
oldInternalPassword, newInternalPassword)
}
_, err = getOrInit(oldExternalPassword)
expectedErr := strings.Split(decryptWithPasswordErr, "%")[0]
if err == nil || !strings.Contains(err.Error(), expectedErr) {
t.Errorf("Unexpected error when trying to get internal password with "+
"old external password.\nexpected: %s\nreceived: %+v", expectedErr, err)
}
}
// func Test_changeExternalPassword(t *testing.T) {
// oldExternalPassword := "myPassword"
// newExternalPassword := "hunter2"
// oldInternalPassword, err := getOrInit(oldExternalPassword)
// if err != nil {
// t.Errorf("%+v", err)
// }
// err = changeExternalPassword(oldExternalPassword, newExternalPassword)
// if err != nil {
// t.Errorf("%+v", err)
// }
// newInternalPassword, err := getOrInit(newExternalPassword)
// if err != nil {
// t.Errorf("%+v", err)
// }
// if !bytes.Equal(oldInternalPassword, newInternalPassword) {
// t.Errorf("Internal password was not changed in storage. Old and new "+
// "should be different.\nold: %+v\nnew: %+v",
// oldInternalPassword, newInternalPassword)
// }
// _, err = getOrInit(oldExternalPassword)
// expectedErr := strings.Split(decryptWithPasswordErr, "%")[0]
// if err == nil || !strings.Contains(err.Error(), expectedErr) {
// t.Errorf("Unexpected error when trying to get internal password with "+
// "old external password.\nexpected: %s\nreceived: %+v", expectedErr, err)
// }
// }
// Tests that verifyPassword returns true for a valid password and false for an
// invalid password
......@@ -154,20 +154,20 @@ func Test_initInternalPassword_CsprngReadError(t *testing.T) {
// Tests that initInternalPassword returns an error when the RNG does not
// return enough bytes.
func Test_initInternalPassword_CsprngReadNumBytesError(t *testing.T) {
externalPassword := "myPassword"
ls := storage.GetLocalStorage()
b := bytes.NewBuffer(make([]byte, internalPasswordLen/2))
expectedErr := fmt.Sprintf(
internalPasswordNumBytesErr, internalPasswordLen, internalPasswordLen/2)
_, err := initInternalPassword(externalPassword, ls, b, defaultParams())
if err == nil || !strings.Contains(err.Error(), expectedErr) {
t.Errorf("Unexpected error when RNG does not return enough bytes."+
"\nexpected: %s\nreceived: %+v", expectedErr, err)
}
}
// func Test_initInternalPassword_CsprngReadNumBytesError(t *testing.T) {
// externalPassword := "myPassword"
// ls := storage.GetLocalStorage()
// b := bytes.NewBuffer(make([]byte, internalPasswordLen/2))
// expectedErr := fmt.Sprintf(
// internalPasswordNumBytesErr, internalPasswordLen, internalPasswordLen/2)
// _, err := initInternalPassword(externalPassword, ls, b, defaultParams())
// if err == nil || !strings.Contains(err.Error(), expectedErr) {
// t.Errorf("Unexpected error when RNG does not return enough bytes."+
// "\nexpected: %s\nreceived: %+v", expectedErr, err)
// }
// }
// Tests that getInternalPassword returns the internal password that is saved
// to local storage by initInternalPassword.
......
......@@ -516,13 +516,12 @@ func (rsCB *RemoteStore) Write(path string, data []byte) error {
// Returns:
// - JSON of [bindings.RemoteStoreReport] (Uint8Array).
// - Catches any thrown errors (of type Error) and returns it as an error.
func (rsCB *RemoteStore) GetLastModified(path string) ([]byte, error) {
fn := func() js.Value { return rsCB.getLastModified(path) }
v, err := exception.RunAndCatch(fn)
func (rsCB *RemoteStore) GetLastModified(path string) (string, error) {
v, err := utils.Await(rsCB.getLastModified(path))
if err != nil {
return nil, err
return "", js.Error{Value: err[0]}
}
return utils.CopyBytesToGo(v), err
return v[0].String(), nil
}
// GetLastWrite implements [bindings.RemoteStore.GetLastWrite()
......@@ -530,13 +529,12 @@ func (rsCB *RemoteStore) GetLastModified(path string) ([]byte, error) {
// Returns:
// - JSON of [bindings.RemoteStoreReport] (Uint8Array).
// - Catches any thrown errors (of type Error) and returns it as an error.
func (rsCB *RemoteStore) GetLastWrite() ([]byte, error) {
fn := func() js.Value { return rsCB.getLastWrite() }
v, err := exception.RunAndCatch(fn)
func (rsCB *RemoteStore) GetLastWrite() (string, error) {
v, err := utils.Await(rsCB.getLastWrite())
if err != nil {
return nil, err
return "", js.Error{Value: err[0]}
}
return utils.CopyBytesToGo(v), err
return v[0].String(), nil
}
// ReadDir implements [bindings.RemoteStore.ReadDir]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment