make storage v1 fileenc methods public for app easy resuse on config storage #311

Merged
sarah merged 1 commits from dan/cwtch:pubEnc into master 2020-06-25 18:26:45 +00:00
7 changed files with 25 additions and 22 deletions

2
go.mod
View File

@ -6,7 +6,7 @@ require (
cwtch.im/tapir v0.1.18
git.openprivacy.ca/openprivacy/connectivity v1.1.2
git.openprivacy.ca/openprivacy/libricochet-go v1.0.13
git.openprivacy.ca/openprivacy/log v1.0.0
git.openprivacy.ca/openprivacy/log v1.0.1
github.com/c-bata/go-prompt v0.2.3
github.com/golang/protobuf v1.3.5
github.com/google/go-cmp v0.4.0 // indirect

2
go.sum
View File

@ -9,6 +9,8 @@ git.openprivacy.ca/openprivacy/libricochet-go v1.0.13 h1:Z86uL9K47onznY1wP1P/wWf
git.openprivacy.ca/openprivacy/libricochet-go v1.0.13/go.mod h1:ZUuX1SOrgV4K18IEcp0hQJNPKszRr2oGb3UeK2iYe5U=
git.openprivacy.ca/openprivacy/log v1.0.0 h1:Rvqm1weUdR4AOnJ79b1upHCc9vC/QF1rhSD2Um7sr1Y=
git.openprivacy.ca/openprivacy/log v1.0.0/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw=
git.openprivacy.ca/openprivacy/log v1.0.1 h1:NWV5oBTatvlSzUE6wtB+UQCulgyMOtm4BXGd34evMys=
git.openprivacy.ca/openprivacy/log v1.0.1/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw=
github.com/c-bata/go-prompt v0.2.3 h1:jjCS+QhG/sULBhAaBdjb2PlMRVaKXQgn+4yzaauvs2s=
github.com/c-bata/go-prompt v0.2.3/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca h1:Q2r7AxHdJwWfLtBZwvW621M3sPqxPc6ITv2j1FGsYpw=

View File

@ -12,8 +12,8 @@ import (
"path"
)
// createKeySalt derives a key from a password: returns key, salt, err
func createKeySalt(password string) ([32]byte, [128]byte, error) {
// CreateKeySalt derives a key and salt from a password: returns key, salt, err
func CreateKeySalt(password string) ([32]byte, [128]byte, error) {
var salt [128]byte
if _, err := io.ReadFull(rand.Reader, salt[:]); err != nil {
log.Errorf("Cannot read from random: %v\n", err)
@ -26,7 +26,8 @@ func createKeySalt(password string) ([32]byte, [128]byte, error) {
return dkr, salt, nil
}
func createKey(password string, salt []byte) [32]byte {
// CreateKey derives a key from a password and salt
func CreateKey(password string, salt []byte) [32]byte {
dk := pbkdf2.Key([]byte(password), salt, 4096, 32, sha3.New512)
var dkr [32]byte
@ -34,8 +35,8 @@ func createKey(password string, salt []byte) [32]byte {
return dkr
}
//encryptFileData encrypts the cwtchPeer via the specified key.
func encryptFileData(data []byte, key [32]byte) ([]byte, error) {
//EncryptFileData encrypts the data with the supplied key
func EncryptFileData(data []byte, key [32]byte) ([]byte, error) {
var nonce [24]byte
if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
@ -47,8 +48,8 @@ func encryptFileData(data []byte, key [32]byte) ([]byte, error) {
return encrypted, nil
}
//decryptFile decrypts the passed ciphertext into a cwtchPeer via the specified key.
func decryptFile(ciphertext []byte, key [32]byte) ([]byte, error) {
//DecryptFile decrypts the passed ciphertext with the supplied key.
func DecryptFile(ciphertext []byte, key [32]byte) ([]byte, error) {
var decryptNonce [24]byte
copy(decryptNonce[:], ciphertext[:24])
decrypted, ok := secretbox.Open(nil, ciphertext[24:], &decryptNonce, &key)
@ -58,11 +59,11 @@ func decryptFile(ciphertext []byte, key [32]byte) ([]byte, error) {
return nil, errors.New("Failed to decrypt")
}
// load instantiates a cwtchPeer from the file store
func readEncryptedFile(directory, filename string, key [32]byte) ([]byte, error) {
// ReadEncryptedFile reads data from an encrypted file in directory with key
func ReadEncryptedFile(directory, filename string, key [32]byte) ([]byte, error) {
encryptedbytes, err := ioutil.ReadFile(path.Join(directory, filename))
if err == nil {
data, err := decryptFile(encryptedbytes, key)
data, err := DecryptFile(encryptedbytes, key)
if err == nil {
return data, nil
}

View File

@ -33,7 +33,7 @@ func NewFileStore(directory string, filename string, key [32]byte) FileStore {
// write serializes a cwtchPeer to a file
func (fps *fileStore) Write(data []byte) error {
encryptedbytes, err := encryptFileData(data, fps.key)
encryptedbytes, err := EncryptFileData(data, fps.key)
if err != nil {
return err
}
@ -43,7 +43,7 @@ func (fps *fileStore) Write(data []byte) error {
}
func (fps *fileStore) Read() ([]byte, error) {
return readEncryptedFile(fps.directory, fps.filename, fps.key)
return ReadEncryptedFile(fps.directory, fps.filename, fps.key)
}
func (fps *fileStore) Delete() {

View File

@ -32,7 +32,7 @@ type ProfileStoreV1 struct {
}
func initV1Directory(directory, password string) ([32]byte, [128]byte, error) {
key, salt, err := createKeySalt(password)
key, salt, err := CreateKeySalt(password)
if err != nil {
log.Errorf("Could not create key for profile store from password: %v\n", err)
return [32]byte{}, [128]byte{}, err
@ -91,7 +91,7 @@ func LoadProfileWriterStore(eventManager event.Manager, directory, password stri
return nil, err
}
key := createKey(password, salt)
key := CreateKey(password, salt)
ps := &ProfileStoreV1{fs: NewFileStore(directory, profileFilename, key), key: key, directory: directory, profile: nil, eventManager: eventManager, streamStores: map[string]StreamStore{}, writer: true}
copy(ps.salt[:], salt)
@ -179,14 +179,14 @@ func (ps *ProfileStoreV1) GetStatusMessages() []*event.Event {
// ChangePassword restores all data under a new password's encryption
func (ps *ProfileStoreV1) ChangePassword(oldpass, newpass, eventID string) {
oldkey := createKey(oldpass, ps.salt[:])
oldkey := CreateKey(oldpass, ps.salt[:])
if oldkey != ps.key {
ps.eventManager.Publish(event.NewEventList(event.ChangePasswordError, event.Error, "Supplied current password does not match", event.EventID, eventID))
return
}
newkey := createKey(newpass, ps.salt[:])
newkey := CreateKey(newpass, ps.salt[:])
newStreamStores := map[string]StreamStore{}
idToNewLocalID := map[string]string{}

View File

@ -57,7 +57,7 @@ func (ss *streamStore) initBuffer() {
func (ss *streamStore) initBufferFromStorage() error {
filename := fmt.Sprintf("%s.%d", ss.filenameBase, 0)
bytes, _ := readEncryptedFile(ss.storeDirectory, filename, ss.key)
bytes, _ := ReadEncryptedFile(ss.storeDirectory, filename, ss.key)
msgs := []model.Message{}
err := json.Unmarshal([]byte(bytes), &msgs)
@ -83,7 +83,7 @@ func (ss *streamStore) updateFile() error {
}
// ENCRYPT
encryptedMsgs, err := encryptFileData(msgs, ss.key)
encryptedMsgs, err := EncryptFileData(msgs, ss.key)
if err != nil {
log.Errorf("Failed to encrypt messages: %v\n", err)
return err
@ -118,7 +118,7 @@ func (ss *streamStore) Read() (messages []model.Message) {
for i := fileStorePartitions - 1; i >= 0; i-- {
filename := fmt.Sprintf("%s.%d", ss.filenameBase, i)
bytes, err := readEncryptedFile(ss.storeDirectory, filename, ss.key)
bytes, err := ReadEncryptedFile(ss.storeDirectory, filename, ss.key)
if err != nil {
continue
}

View File

@ -15,7 +15,7 @@ func TestStreamStoreWriteRead(t *testing.T) {
os.Remove(".test.json")
os.RemoveAll(testingDir)
os.Mkdir(testingDir, 0777)
key, _, _ := createKeySalt(password)
key, _, _ := CreateKeySalt(password)
ss1 := NewStreamStore(testingDir, filenameBase, key)
m := model.Message{Message: line1}
ss1.Write(m)
@ -34,7 +34,7 @@ func TestStreamStoreWriteReadRotate(t *testing.T) {
os.Remove(".test.json")
os.RemoveAll(testingDir)
os.Mkdir(testingDir, 0777)
key, _, _ := createKeySalt(password)
key, _, _ := CreateKeySalt(password)
ss1 := NewStreamStore(testingDir, filenameBase, key)
m := model.Message{Message: line1}
for i := 0; i < 400; i++ {