Browse Source

Merge pull request 'make storage v1 fileenc methods public for app easy resuse on config storage' (#311) from dan/cwtch:pubEnc into master

master
Sarah Jamie Lewis 1 week ago
parent
commit
3529e21b0e
7 changed files with 25 additions and 22 deletions
  1. +1
    -1
      go.mod
  2. +2
    -0
      go.sum
  3. +11
    -10
      storage/v1/file_enc.go
  4. +2
    -2
      storage/v1/file_store.go
  5. +4
    -4
      storage/v1/profile_store.go
  6. +3
    -3
      storage/v1/stream_store.go
  7. +2
    -2
      storage/v1/stream_store_test.go

+ 1
- 1
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
- 0
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=


+ 11
- 10
storage/v1/file_enc.go 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
}


+ 2
- 2
storage/v1/file_store.go 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() {


+ 4
- 4
storage/v1/profile_store.go 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{}


+ 3
- 3
storage/v1/stream_store.go 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
}


+ 2
- 2
storage/v1/stream_store_test.go 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++ {


Loading…
Cancel
Save