forked from cwtch.im/cwtch
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:
parent
2b039b2e9f
commit
21817f936d
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue