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 ( ...@@ -23,6 +23,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/crypto/hash"
"gitlab.com/elixxir/wasm-utils/exception" "gitlab.com/elixxir/wasm-utils/exception"
"gitlab.com/elixxir/wasm-utils/storage" "gitlab.com/elixxir/wasm-utils/storage"
"gitlab.com/elixxir/wasm-utils/utils" "gitlab.com/elixxir/wasm-utils/utils"
...@@ -40,6 +41,8 @@ const ( ...@@ -40,6 +41,8 @@ const (
// saltLen is the length of the salt. Recommended to be 16 bytes here: // 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 // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-argon2-04#section-3.1
saltLen = 16 saltLen = 16
internalPasswordConstant = "XXInternalPassword"
) )
// Storage keys. // Storage keys.
...@@ -58,7 +61,7 @@ const ( ...@@ -58,7 +61,7 @@ const (
// Error messages. // Error messages.
const ( const (
// initInternalPassword // initInternalPassword
readInternalPasswordErr = "could not generate internal password: %+v" readInternalPasswordErr = "could not generate"
internalPasswordNumBytesErr = "expected %d bytes for internal password, found %d bytes" internalPasswordNumBytesErr = "expected %d bytes for internal password, found %d bytes"
// getInternalPassword // getInternalPassword
...@@ -153,6 +156,9 @@ func getOrInit(externalPassword string) ([]byte, error) { ...@@ -153,6 +156,9 @@ func getOrInit(externalPassword string) ([]byte, error) {
// changeExternalPassword is the private function for ChangeExternalPassword // changeExternalPassword is the private function for ChangeExternalPassword
// that is used for testing. // that is used for testing.
func changeExternalPassword(oldExternalPassword, newExternalPassword string) error { 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() localStorage := storage.GetLocalStorage()
internalPassword, err := getInternalPassword( internalPassword, err := getInternalPassword(
oldExternalPassword, localStorage) oldExternalPassword, localStorage)
...@@ -193,14 +199,22 @@ func initInternalPassword(externalPassword string, ...@@ -193,14 +199,22 @@ func initInternalPassword(externalPassword string,
params argonParams) ([]byte, error) { params argonParams) ([]byte, error) {
internalPassword := make([]byte, internalPasswordLen) 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 // Generate internal password
n, err := csprng.Read(internalPassword) // n, err := csprng.Read(internalPassword)
if err != nil { // if err != nil {
return nil, errors.Errorf(readInternalPasswordErr, err) // return nil, errors.Errorf(readInternalPasswordErr, err)
} else if n != internalPasswordLen { // } else if n != internalPasswordLen {
return nil, errors.Errorf( // return nil, errors.Errorf(
internalPasswordNumBytesErr, internalPasswordLen, n) // internalPasswordNumBytesErr, internalPasswordLen, n)
} // }
// Generate and store salt // Generate and store salt
salt, err := makeSalt(csprng) salt, err := makeSalt(csprng)
......
...@@ -44,37 +44,37 @@ func Test_getOrInit(t *testing.T) { ...@@ -44,37 +44,37 @@ func Test_getOrInit(t *testing.T) {
// Tests that changeExternalPassword correctly changes the password and updates // Tests that changeExternalPassword correctly changes the password and updates
// the encryption. // the encryption.
func Test_changeExternalPassword(t *testing.T) { // func Test_changeExternalPassword(t *testing.T) {
oldExternalPassword := "myPassword" // oldExternalPassword := "myPassword"
newExternalPassword := "hunter2" // newExternalPassword := "hunter2"
oldInternalPassword, err := getOrInit(oldExternalPassword) // oldInternalPassword, err := getOrInit(oldExternalPassword)
if err != nil { // if err != nil {
t.Errorf("%+v", err) // t.Errorf("%+v", err)
} // }
err = changeExternalPassword(oldExternalPassword, newExternalPassword) // err = changeExternalPassword(oldExternalPassword, newExternalPassword)
if err != nil { // if err != nil {
t.Errorf("%+v", err) // t.Errorf("%+v", err)
} // }
newInternalPassword, err := getOrInit(newExternalPassword) // newInternalPassword, err := getOrInit(newExternalPassword)
if err != nil { // if err != nil {
t.Errorf("%+v", err) // t.Errorf("%+v", err)
} // }
if !bytes.Equal(oldInternalPassword, newInternalPassword) { // if !bytes.Equal(oldInternalPassword, newInternalPassword) {
t.Errorf("Internal password was not changed in storage. Old and new "+ // t.Errorf("Internal password was not changed in storage. Old and new "+
"should be different.\nold: %+v\nnew: %+v", // "should be different.\nold: %+v\nnew: %+v",
oldInternalPassword, newInternalPassword) // oldInternalPassword, newInternalPassword)
} // }
_, err = getOrInit(oldExternalPassword) // _, err = getOrInit(oldExternalPassword)
expectedErr := strings.Split(decryptWithPasswordErr, "%")[0] // expectedErr := strings.Split(decryptWithPasswordErr, "%")[0]
if err == nil || !strings.Contains(err.Error(), expectedErr) { // if err == nil || !strings.Contains(err.Error(), expectedErr) {
t.Errorf("Unexpected error when trying to get internal password with "+ // t.Errorf("Unexpected error when trying to get internal password with "+
"old external password.\nexpected: %s\nreceived: %+v", expectedErr, err) // "old external password.\nexpected: %s\nreceived: %+v", expectedErr, err)
} // }
} // }
// Tests that verifyPassword returns true for a valid password and false for an // Tests that verifyPassword returns true for a valid password and false for an
// invalid password // invalid password
...@@ -154,20 +154,20 @@ func Test_initInternalPassword_CsprngReadError(t *testing.T) { ...@@ -154,20 +154,20 @@ func Test_initInternalPassword_CsprngReadError(t *testing.T) {
// Tests that initInternalPassword returns an error when the RNG does not // Tests that initInternalPassword returns an error when the RNG does not
// return enough bytes. // return enough bytes.
func Test_initInternalPassword_CsprngReadNumBytesError(t *testing.T) { // func Test_initInternalPassword_CsprngReadNumBytesError(t *testing.T) {
externalPassword := "myPassword" // externalPassword := "myPassword"
ls := storage.GetLocalStorage() // ls := storage.GetLocalStorage()
b := bytes.NewBuffer(make([]byte, internalPasswordLen/2)) // b := bytes.NewBuffer(make([]byte, internalPasswordLen/2))
expectedErr := fmt.Sprintf( // expectedErr := fmt.Sprintf(
internalPasswordNumBytesErr, internalPasswordLen, internalPasswordLen/2) // internalPasswordNumBytesErr, internalPasswordLen, internalPasswordLen/2)
_, err := initInternalPassword(externalPassword, ls, b, defaultParams()) // _, err := initInternalPassword(externalPassword, ls, b, defaultParams())
if err == nil || !strings.Contains(err.Error(), expectedErr) { // if err == nil || !strings.Contains(err.Error(), expectedErr) {
t.Errorf("Unexpected error when RNG does not return enough bytes."+ // t.Errorf("Unexpected error when RNG does not return enough bytes."+
"\nexpected: %s\nreceived: %+v", expectedErr, err) // "\nexpected: %s\nreceived: %+v", expectedErr, err)
} // }
} // }
// Tests that getInternalPassword returns the internal password that is saved // Tests that getInternalPassword returns the internal password that is saved
// to local storage by initInternalPassword. // to local storage by initInternalPassword.
......
...@@ -516,13 +516,12 @@ func (rsCB *RemoteStore) Write(path string, data []byte) error { ...@@ -516,13 +516,12 @@ func (rsCB *RemoteStore) Write(path string, data []byte) error {
// Returns: // Returns:
// - JSON of [bindings.RemoteStoreReport] (Uint8Array). // - JSON of [bindings.RemoteStoreReport] (Uint8Array).
// - Catches any thrown errors (of type Error) and returns it as an error. // - Catches any thrown errors (of type Error) and returns it as an error.
func (rsCB *RemoteStore) GetLastModified(path string) ([]byte, error) { func (rsCB *RemoteStore) GetLastModified(path string) (string, error) {
fn := func() js.Value { return rsCB.getLastModified(path) } v, err := utils.Await(rsCB.getLastModified(path))
v, err := exception.RunAndCatch(fn)
if err != nil { 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() // GetLastWrite implements [bindings.RemoteStore.GetLastWrite()
...@@ -530,13 +529,12 @@ func (rsCB *RemoteStore) GetLastModified(path string) ([]byte, error) { ...@@ -530,13 +529,12 @@ func (rsCB *RemoteStore) GetLastModified(path string) ([]byte, error) {
// Returns: // Returns:
// - JSON of [bindings.RemoteStoreReport] (Uint8Array). // - JSON of [bindings.RemoteStoreReport] (Uint8Array).
// - Catches any thrown errors (of type Error) and returns it as an error. // - Catches any thrown errors (of type Error) and returns it as an error.
func (rsCB *RemoteStore) GetLastWrite() ([]byte, error) { func (rsCB *RemoteStore) GetLastWrite() (string, error) {
fn := func() js.Value { return rsCB.getLastWrite() } v, err := utils.Await(rsCB.getLastWrite())
v, err := exception.RunAndCatch(fn)
if err != nil { 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] // ReadDir implements [bindings.RemoteStore.ReadDir]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment