modified: ../../peer/cwtch_peer.go

Corrected documentation
Changed 'password' to 'key' where appropriate
Reloaded the salt into the LoadCwtchPeer function
This commit is contained in:
Angus Champion de Crespigny 2018-06-26 20:32:37 -04:00 committed by Gogs
parent 2b039b2e9f
commit 21817f936d
1 changed files with 32 additions and 24 deletions

View File

@ -36,7 +36,7 @@ type cwtchPeer struct {
Log chan string `json:"-"` Log chan string `json:"-"`
connectionsManager *connections.Manager connectionsManager *connections.Manager
profilefile string profilefile string
password [32]byte key [32]byte
salt [128]byte salt [128]byte
} }
@ -74,44 +74,45 @@ type CwtchPeerInterface interface {
Shutdown() Shutdown()
} }
// CreateKey derives a key and salt for use in encrypting the Profile // createKey derives a key and salt for use in encrypting cwtchPeers
func CreateKey(key string) ([32]byte, [128]byte) { func createKey(password string) ([32]byte, [128]byte) {
var salt [128]byte var salt [128]byte
if _, err := io.ReadFull(rand.Reader, salt[:]); err != nil { if _, err := io.ReadFull(rand.Reader, salt[:]); err != nil {
panic(err) panic(err)
} }
dk := pbkdf2.Key([]byte(key), salt[:], 4096, 32, sha3.New512) dk := pbkdf2.Key([]byte(password), salt[:], 4096, 32, sha3.New512)
var dkr [32]byte var dkr [32]byte
copy(dkr[:], dk) copy(dkr[:], dk)
return dkr, salt return dkr, salt
} }
//EncryptMessage takes a message and encrypts the message under the group key. //encryptProfile encrypts the cwtchPeer via the specified key.
func EncryptProfile(p *cwtchPeer, password [32]byte) []byte { func encryptProfile(p *cwtchPeer, key [32]byte) []byte {
var nonce [24]byte var nonce [24]byte
if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil { if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
panic(err) panic(err)
} }
//copy Peer struct, then remove password and save the copy
//copy the struct, then remove the key and salt before saving the copy
cpc := &cwtchPeer{} cpc := &cwtchPeer{}
deepcopier.Copy(p).To(cpc) deepcopier.Copy(p).To(cpc)
var blankpass [32]byte var blankkey [32]byte
var blanksalt [128]byte var blanksalt [128]byte
cpc.password = blankpass cpc.key = blankkey
cpc.salt = blanksalt cpc.salt = blanksalt
bytes, _ := json.Marshal(cpc) bytes, _ := json.Marshal(cpc)
encrypted := secretbox.Seal(nonce[:], []byte(bytes), &nonce, &key)
encrypted := secretbox.Seal(nonce[:], []byte(bytes), &nonce, &password)
return encrypted return encrypted
} }
//EncryptMessage takes a message and encrypts the message under the group key. //decryptProfile decrypts the passed ciphertext into a cwtchPeer via the specified key.
func DecryptProfile(ciphertext []byte, password [32]byte) (error, *cwtchPeer) { func decryptProfile(ciphertext []byte, key [32]byte) (error, *cwtchPeer) {
var decryptNonce [24]byte var decryptNonce [24]byte
copy(decryptNonce[:], ciphertext[:24]) copy(decryptNonce[:], ciphertext[:24])
decrypted, ok := secretbox.Open(nil, ciphertext[24:], &decryptNonce, &password) decrypted, ok := secretbox.Open(nil, ciphertext[24:], &decryptNonce, &key)
if ok { if ok {
cp := &cwtchPeer{} cp := &cwtchPeer{}
err := json.Unmarshal(decrypted, &cp) err := json.Unmarshal(decrypted, &cp)
@ -149,8 +150,8 @@ func NewCwtchPeer(name string, password string) CwtchPeerInterface {
cp := new(cwtchPeer) cp := new(cwtchPeer)
cp.Profile = model.GenerateNewProfile(name) cp.Profile = model.GenerateNewProfile(name)
cp.setup() cp.setup()
pass, salt := CreateKey(password) key, salt := createKey(password)
cp.password = pass cp.key = key
cp.salt = salt cp.salt = salt
return cp return cp
} }
@ -158,7 +159,9 @@ func NewCwtchPeer(name string, password string) CwtchPeerInterface {
// Save saves the cwtchPeer profile state to a file. // Save saves the cwtchPeer profile state to a file.
func (cp *cwtchPeer) Save(profilefile string) error { func (cp *cwtchPeer) Save(profilefile string) error {
cp.mutex.Lock() cp.mutex.Lock()
encryptedbytes := EncryptProfile(cp, cp.password) encryptedbytes := encryptProfile(cp, cp.key)
// the salt for the derived key is appended to the front of the file
encryptedbytes = append(cp.salt[:], encryptedbytes...) encryptedbytes = append(cp.salt[:], encryptedbytes...)
err := ioutil.WriteFile(profilefile, encryptedbytes, 0600) err := ioutil.WriteFile(profilefile, encryptedbytes, 0600)
cp.profilefile = profilefile cp.profilefile = profilefile
@ -170,18 +173,23 @@ func (cp *cwtchPeer) Save(profilefile string) error {
func LoadCwtchPeer(profilefile string, password string) (CwtchPeerInterface, error) { func LoadCwtchPeer(profilefile string, password string) (CwtchPeerInterface, error) {
encryptedbytes, _ := ioutil.ReadFile(profilefile) encryptedbytes, _ := ioutil.ReadFile(profilefile)
//get the salt
salt, encryptedbytes := encryptedbytes[0:128], encryptedbytes[128:]
dk := pbkdf2.Key([]byte(password), salt, 4096, 32, sha3.New512)
var dkr [32]byte var dkr [32]byte
copy(dkr[:], dk) var salty [128]byte
err, cp := DecryptProfile(encryptedbytes, dkr) //Separate the salt from the encrypted bytes, then generate the derived key
salt, encryptedbytes := encryptedbytes[0:128], encryptedbytes[128:]
dk := pbkdf2.Key([]byte(password), salt, 4096, 32, sha3.New512)
//cast to arrays
copy(dkr[:], dk)
copy(salty[:], salt)
err, cp := decryptProfile(encryptedbytes, dkr)
if err == nil { if err == nil {
cp.setup() cp.setup()
cp.profilefile = profilefile cp.profilefile = profilefile
cp.password = dkr cp.key = dkr
cp.salt = salty
return cp, nil return cp, nil
} else { } else {
return nil, err return nil, err