diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c5d708..d096970 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Security - Updated underlying crypto library +- Improved memory zeroing in helpers ### Fixed - Fixed test `TestMultipleKeyMessageEncryption` - Fixed garbage collection issues when compiled on gomobile, by copying byte slices +- Password encrypted binary files now have the correct flags +- Fixed missing space in `Hash` header of cleartext messages + +## Changed +- Providing empty passphrase does no longer throw an error when unlocking an unencrypted private key ### Added - SHA256 fingerprint support diff --git a/constants/armor.go b/constants/armor.go index ac20ea9..28db229 100644 --- a/constants/armor.go +++ b/constants/armor.go @@ -3,7 +3,7 @@ package constants // Constants for armored data. const ( - ArmorHeaderVersion = "GopenPGP 0.0.1 (" + Version + ")" + ArmorHeaderVersion = "GopenPGP 2.0.0" ArmorHeaderComment = "https://gopenpgp.org" PGPMessageHeader = "PGP MESSAGE" PGPSignatureHeader = "PGP SIGNATURE" diff --git a/crypto/key.go b/crypto/key.go index 106c33f..349bed4 100644 --- a/crypto/key.go +++ b/crypto/key.go @@ -104,6 +104,10 @@ func (key *Key) Lock(passphrase []byte) (*Key, error) { return nil, err } + if passphrase == nil { + return lockedKey, nil + } + err = lockedKey.entity.PrivateKey.Encrypt(passphrase) if err != nil { return nil, errors.Wrap(err, "gopenpgp: error in locking key") @@ -136,6 +140,9 @@ func (key *Key) Unlock(passphrase []byte) (*Key, error) { } if !isLocked { + if passphrase == nil { + return key.Copy() + } return nil, errors.New("gopenpgp: key is not locked") } diff --git a/crypto/message.go b/crypto/message.go index b2cc259..10ab8a4 100644 --- a/crypto/message.go +++ b/crypto/message.go @@ -366,7 +366,7 @@ func (msg *ClearTextMessage) GetArmored() (string, error) { return "", err } - str := "-----BEGIN PGP SIGNED MESSAGE-----\r\nHash:SHA512\r\n\r\n" + str := "-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: SHA512\r\n\r\n" str += msg.GetString() str += "\r\n" str += armSignature diff --git a/crypto/password.go b/crypto/password.go index 8230626..ea718b6 100644 --- a/crypto/password.go +++ b/crypto/password.go @@ -15,7 +15,7 @@ import ( // * password: A password that will be derived into an encryption key // * output : The encrypted data as PGPMessage func EncryptMessageWithPassword(message *PlainMessage, password []byte) (*PGPMessage, error) { - encrypted, err := passwordEncrypt(message.GetBinary(), password) + encrypted, err := passwordEncrypt(message.GetBinary(), password, message.IsBinary()) if err != nil { return nil, err } @@ -99,14 +99,16 @@ func EncryptSessionKeyWithPassword(sk *SessionKey, password []byte) ([]byte, err // ----- INTERNAL FUNCTIONS ------ -func passwordEncrypt(message []byte, password []byte) ([]byte, error) { +func passwordEncrypt(message []byte, password []byte, isBinary bool) ([]byte, error) { var outBuf bytes.Buffer config := &packet.Config{ Time: getTimeGenerator(), } - encryptWriter, err := openpgp.SymmetricallyEncrypt(&outBuf, password, nil, config) + hints := &openpgp.FileHints{IsBinary: isBinary} + + encryptWriter, err := openpgp.SymmetricallyEncrypt(&outBuf, password, hints, config) if err != nil { return nil, err } diff --git a/helper/cleartext.go b/helper/cleartext.go index 1eab67c..a8c07e5 100644 --- a/helper/cleartext.go +++ b/helper/cleartext.go @@ -19,6 +19,7 @@ func SignCleartextMessageArmored(privateKey string, passphrase []byte, text stri if err != nil { return "", err } + defer unlockedKey.ClearPrivateParams() keyRing, err := crypto.NewKeyRing(unlockedKey) if err != nil { diff --git a/helper/helper.go b/helper/helper.go index c232eb1..892f975 100644 --- a/helper/helper.go +++ b/helper/helper.go @@ -94,6 +94,7 @@ func EncryptSignMessageArmored( if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil { return "", err } + defer unlockedKeyObj.ClearPrivateParams() if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil { return "", err @@ -126,6 +127,7 @@ func DecryptMessageArmored( if privateKeyUnlocked, err = privateKeyObj.Unlock(passphrase); err != nil { return "", err } + defer privateKeyUnlocked.ClearPrivateParams() if privateKeyRing, err = crypto.NewKeyRing(privateKeyUnlocked); err != nil { return "", err @@ -168,6 +170,7 @@ func DecryptVerifyMessageArmored( if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil { return "", err } + defer unlockedKeyObj.ClearPrivateParams() if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil { return "", err @@ -214,6 +217,7 @@ func DecryptVerifyAttachment( if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil { return nil, err } + defer unlockedKeyObj.ClearPrivateParams() if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil { return nil, err diff --git a/helper/key.go b/helper/key.go index a1a695b..1ef0a8a 100644 --- a/helper/key.go +++ b/helper/key.go @@ -19,13 +19,13 @@ func UpdatePrivateKeyPassphrase( if err != nil { return "", err } + defer unlocked.ClearPrivateParams() locked, err := unlocked.Lock(newPassphrase) if err != nil { return "", err } - unlocked.ClearPrivateParams() return locked.Armor() } @@ -37,13 +37,13 @@ func GenerateKey(name, email string, passphrase []byte, keyType string, bits int if err != nil { return "", err } + defer key.ClearPrivateParams() locked, err := key.Lock(passphrase) if err != nil { return "", err } - key.ClearPrivateParams() return locked.Armor() } diff --git a/helper/sign_attachment.go b/helper/sign_attachment.go index 2cb0003..c5b413b 100644 --- a/helper/sign_attachment.go +++ b/helper/sign_attachment.go @@ -33,6 +33,7 @@ func EncryptSignAttachment( if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil { return nil, nil, nil, err } + defer unlockedKeyObj.ClearPrivateParams() if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil { return nil, nil, nil, err