Openpgp security update (V2) (#31)

* Change keyring unlock functionalities

* Add keyring#Lock, keyring#CheckIntegrity, tests

* Update helpers, fix bugs

* Update go.mod with ProtonMail/crypto commit

* Change key management system

* Clear keys from memory + tests

* Create SessionKey with direct encryption for datapackets. Move symmetrickey to password.

* Fix upstream dependencies

* Update module to V2, documentation

* Add linter

* Add v2 folder to .gitignore

* Minor changes to KeyID getters

* Remove old changelog

* Improve docs, remove compilation script
This commit is contained in:
wussler 2019-12-27 19:35:43 +01:00 committed by GitHub
parent 136c0a5495
commit 54f45d0471
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 2588 additions and 1770 deletions

View file

@ -1,86 +0,0 @@
package crypto
import (
"bytes"
"errors"
"fmt"
"io"
"golang.org/x/crypto/openpgp/packet"
)
// RandomToken generated a random token of the same size of the keysize of the default cipher.
func RandomToken() ([]byte, error) {
config := &packet.Config{DefaultCipher: packet.CipherAES256}
return RandomTokenSize(config.DefaultCipher.KeySize())
}
// RandomTokenSize generates a random token with the specified key size
func RandomTokenSize(size int) ([]byte, error) {
config := &packet.Config{DefaultCipher: packet.CipherAES256}
symKey := make([]byte, size)
if _, err := io.ReadFull(config.Random(), symKey); err != nil {
return nil, err
}
return symKey, nil
}
// DecryptSessionKey returns the decrypted session key from a binary encrypted session key packet.
func (keyRing *KeyRing) DecryptSessionKey(keyPacket []byte) (*SymmetricKey, error) {
keyReader := bytes.NewReader(keyPacket)
packets := packet.NewReader(keyReader)
var p packet.Packet
var err error
if p, err = packets.Next(); err != nil {
return nil, err
}
ek := p.(*packet.EncryptedKey)
var decryptErr error
for _, key := range keyRing.entities.DecryptionKeys() {
priv := key.PrivateKey
if priv.Encrypted {
continue
}
if decryptErr = ek.Decrypt(priv, nil); decryptErr == nil {
break
}
}
if decryptErr != nil {
return nil, decryptErr
}
if ek == nil {
return nil, errors.New("gopenpgp: unable to decrypt session key")
}
return newSymmetricKeyFromEncrypted(ek)
}
// EncryptSessionKey encrypts the session key with the unarmored
// publicKey and returns a binary public-key encrypted session key packet.
func (keyRing *KeyRing) EncryptSessionKey(sessionSplit *SymmetricKey) ([]byte, error) {
outbuf := &bytes.Buffer{}
cf := sessionSplit.GetCipherFunc()
var pub *packet.PublicKey
for _, e := range keyRing.GetEntities() {
if encryptionKey, ok := e.EncryptionKey(getNow()); ok {
pub = encryptionKey.PublicKey
break
}
}
if pub == nil {
return nil, errors.New("cannot set key: no public key available")
}
if err := packet.SerializeEncryptedKey(outbuf, pub, cf, sessionSplit.Key, nil); err != nil {
err = fmt.Errorf("gopenpgp: cannot set key: %v", err)
return nil, err
}
return outbuf.Bytes(), nil
}