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:
parent
136c0a5495
commit
54f45d0471
46 changed files with 2588 additions and 1770 deletions
73
crypto/keyring_session.go
Normal file
73
crypto/keyring_session.go
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"golang.org/x/crypto/openpgp/packet"
|
||||
)
|
||||
|
||||
// DecryptSessionKey returns the decrypted session key from a binary encrypted session key packet.
|
||||
func (keyRing *KeyRing) DecryptSessionKey(keyPacket []byte) (*SessionKey, 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 newSessionKeyFromEncrypted(ek)
|
||||
}
|
||||
|
||||
// EncryptSessionKey encrypts the session key with the unarmored
|
||||
// publicKey and returns a binary public-key encrypted session key packet.
|
||||
func (keyRing *KeyRing) EncryptSessionKey(sk *SessionKey) ([]byte, error) {
|
||||
outbuf := &bytes.Buffer{}
|
||||
|
||||
cf, err := sk.GetCipherFunc()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "gopenpgp: unable to encrypt session key")
|
||||
}
|
||||
|
||||
var pub *packet.PublicKey
|
||||
for _, e := range keyRing.entities {
|
||||
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, sk.Key, nil); err != nil {
|
||||
err = fmt.Errorf("gopenpgp: cannot set key: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
return outbuf.Bytes(), nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue