Improve error handling, fix linter (#92)

* Improve error handling, fix linter
This commit is contained in:
wussler 2020-10-29 12:42:32 +01:00 committed by GitHub
parent 6b2ac0b11c
commit 53a85837e0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 194 additions and 186 deletions

View file

@ -3,6 +3,7 @@ package helper
import (
"github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/gopenpgp/v2/internal"
"github.com/pkg/errors"
)
// SignCleartextMessageArmored signs text given a private key and its
@ -11,18 +12,18 @@ import (
func SignCleartextMessageArmored(privateKey string, passphrase []byte, text string) (string, error) {
signingKey, err := crypto.NewKeyFromArmored(privateKey)
if err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: error in creating key object")
}
unlockedKey, err := signingKey.Unlock(passphrase)
if err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: error in unlocking key")
}
defer unlockedKey.ClearPrivateParams()
keyRing, err := crypto.NewKeyRing(unlockedKey)
if err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: error in creating keyring")
}
return SignCleartextMessage(keyRing, text)
@ -34,12 +35,12 @@ func SignCleartextMessageArmored(privateKey string, passphrase []byte, text stri
func VerifyCleartextMessageArmored(publicKey, armored string, verifyTime int64) (string, error) {
signingKey, err := crypto.NewKeyFromArmored(publicKey)
if err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: error in creating key object")
}
verifyKeyRing, err := crypto.NewKeyRing(signingKey)
if err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: error in creating key ring")
}
return VerifyCleartextMessage(verifyKeyRing, armored, verifyTime)
@ -53,7 +54,7 @@ func SignCleartextMessage(keyRing *crypto.KeyRing, text string) (string, error)
signature, err := keyRing.SignDetached(message)
if err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: error in signing cleartext message")
}
return crypto.NewClearTextMessage(message.GetBinary(), signature.GetBinary()).GetArmored()
@ -65,14 +66,14 @@ func SignCleartextMessage(keyRing *crypto.KeyRing, text string) (string, error)
func VerifyCleartextMessage(keyRing *crypto.KeyRing, armored string, verifyTime int64) (string, error) {
clearTextMessage, err := crypto.NewClearTextMessageFromArmored(armored)
if err != nil {
return "", err
return "", errors.Wrap(err, "gopengpp: unable to unarmor cleartext message")
}
message := crypto.NewPlainMessageFromString(clearTextMessage.GetString())
signature := crypto.NewPGPSignature(clearTextMessage.GetBinarySignature())
err = keyRing.VerifyDetached(message, signature, verifyTime)
if err != nil {
return "", err
return "", errors.Wrap(err, "gopengpp: unable to verify cleartext message")
}
return message.GetString(), nil

View file

@ -2,9 +2,8 @@
package helper
import (
"errors"
"github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/pkg/errors"
)
// EncryptMessageWithPassword encrypts a string with a passphrase using AES256.
@ -14,11 +13,11 @@ func EncryptMessageWithPassword(password []byte, plaintext string) (ciphertext s
var message = crypto.NewPlainMessageFromString(plaintext)
if pgpMessage, err = crypto.EncryptMessageWithPassword(message, password); err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to encrypt message with password")
}
if ciphertext, err = pgpMessage.GetArmored(); err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to armor ciphertext")
}
return ciphertext, nil
@ -31,11 +30,11 @@ func DecryptMessageWithPassword(password []byte, ciphertext string) (plaintext s
var pgpMessage *crypto.PGPMessage
if pgpMessage, err = crypto.NewPGPMessageFromArmored(ciphertext); err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to unarmor ciphertext")
}
if message, err = crypto.DecryptMessageWithPassword(pgpMessage, password); err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to decrypt message with password")
}
return message.GetString(), nil
@ -63,24 +62,24 @@ func EncryptSignMessageArmored(
}
if privateKeyObj, err = crypto.NewKeyFromArmored(privateKey); err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to read key")
}
if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to unlock key")
}
defer unlockedKeyObj.ClearPrivateParams()
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to create new keyring")
}
if pgpMessage, err = publicKeyRing.Encrypt(message, privateKeyRing); err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to encrypt message")
}
if ciphertext, err = pgpMessage.GetArmored(); err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to armor ciphertext")
}
return ciphertext, nil
@ -116,24 +115,24 @@ func DecryptVerifyMessageArmored(
}
if privateKeyObj, err = crypto.NewKeyFromArmored(privateKey); err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to unarmor private key")
}
if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to unlock private key")
}
defer unlockedKeyObj.ClearPrivateParams()
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to create new keyring")
}
if pgpMessage, err = crypto.NewPGPMessageFromArmored(ciphertext); err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to unarmor ciphertext")
}
if message, err = privateKeyRing.Decrypt(pgpMessage, publicKeyRing, crypto.GetUnixTime()); err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to decrypt message")
}
return message.GetString(), nil
@ -191,31 +190,31 @@ func encryptSignArmoredDetached(
publicKey, privateKey string,
passphrase, plainData []byte,
) (ciphertext, encryptedSignature string, err error) {
var message *crypto.PlainMessage = crypto.NewPlainMessage(plainData)
var message = crypto.NewPlainMessage(plainData)
// We generate the session key
sessionKey, err := crypto.GenerateSessionKey()
if err != nil {
return "", "", err
return "", "", errors.Wrap(err, "gopenpgp: unable to generate session key")
}
// We encrypt the message with the session key
messageDataPacket, err := sessionKey.Encrypt(message)
if err != nil {
return "", "", err
return "", "", errors.Wrap(err, "gopenpgp: unable to encrypt message")
}
// We sign the message
detachedSignature, err := signDetached(privateKey, passphrase, message)
if err != nil {
return "", "", err
return "", "", errors.Wrap(err, "gopenpgp: unable to sign the message")
}
// We encrypt the signature with the session key
signaturePlaintext := crypto.NewPlainMessage(detachedSignature.GetBinary())
signatureDataPacket, err := sessionKey.Encrypt(signaturePlaintext)
if err != nil {
return "", "", err
return "", "", errors.Wrap(err, "gopenpgp: unable to encrypt signature")
}
// We encrypt the session key
@ -227,11 +226,11 @@ func encryptSignArmoredDetached(
// We join the key packets and datapackets and armor the message
ciphertext, err = crypto.NewPGPSplitMessage(keyPacket, messageDataPacket).GetArmored()
if err != nil {
return "", "", err
return "", "", errors.Wrap(err, "gopenpgp: unable to armor message")
}
encryptedSignature, err = crypto.NewPGPSplitMessage(keyPacket, signatureDataPacket).GetArmored()
if err != nil {
return "", "", err
return "", "", errors.Wrap(err, "gopenpgp: unable to armor signature")
}
return ciphertext, encryptedSignature, nil
@ -323,45 +322,44 @@ func DecryptSessionKey(
passphrase, encryptedSessionKey []byte,
) (sessionKey *crypto.SessionKey, err error) {
privateKeyObj, err := crypto.NewKeyFromArmored(privateKey)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to read armored key")
}
privateKeyUnlocked, err := privateKeyObj.Unlock(passphrase)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to unlock private key")
}
defer privateKeyUnlocked.ClearPrivateParams()
privateKeyRing, err := crypto.NewKeyRing(privateKeyUnlocked)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to create new keyring")
}
sessionKey, err = privateKeyRing.DecryptSessionKey(encryptedSessionKey)
return
if err != nil {
return nil, errors.Wrap(err, "gopenpgp: unable to decrypt session key")
}
return sessionKey, nil
}
func encryptMessageArmored(key string, message *crypto.PlainMessage) (string, error) {
publicKeyRing, err := createPublicKeyRing(key)
if err != nil {
return "", err
}
pgpMessage, err := publicKeyRing.Encrypt(message, nil)
if err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to encrypt message")
}
ciphertext, err := pgpMessage.GetArmored()
if err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to armor message")
}
return ciphertext, nil
@ -369,35 +367,30 @@ func encryptMessageArmored(key string, message *crypto.PlainMessage) (string, er
func decryptMessageArmored(privateKey string, passphrase []byte, ciphertext string) (*crypto.PlainMessage, error) {
privateKeyObj, err := crypto.NewKeyFromArmored(privateKey)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to parse private key")
}
privateKeyUnlocked, err := privateKeyObj.Unlock(passphrase)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to unlock private key")
}
defer privateKeyUnlocked.ClearPrivateParams()
privateKeyRing, err := crypto.NewKeyRing(privateKeyUnlocked)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to create new keyring")
}
pgpMessage, err := crypto.NewPGPMessageFromArmored(ciphertext)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to unarmor ciphertext")
}
message, err := privateKeyRing.Decrypt(pgpMessage, nil, 0)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to decrypt message")
}
return message, nil
@ -405,29 +398,25 @@ func decryptMessageArmored(privateKey string, passphrase []byte, ciphertext stri
func signDetached(privateKey string, passphrase []byte, message *crypto.PlainMessage) (detachedSignature *crypto.PGPSignature, err error) {
privateKeyObj, err := crypto.NewKeyFromArmored(privateKey)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to parse private key")
}
privateKeyUnlocked, err := privateKeyObj.Unlock(passphrase)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to unlock key")
}
defer privateKeyUnlocked.ClearPrivateParams()
privateKeyRing, err := crypto.NewKeyRing(privateKeyUnlocked)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to create new keyring")
}
detachedSignature, err = privateKeyRing.SignDetached(message)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to sign message")
}
return detachedSignature, nil
@ -438,7 +427,7 @@ func verifyDetachedArmored(publicKey string, message *crypto.PlainMessage, armor
// We unarmor the signature
if detachedSignature, err = crypto.NewPGPSignatureFromArmored(armoredSignature); err != nil {
return false, err
return false, errors.Wrap(err, "gopenpgp: unable to unarmor signature")
}
// we verify the signature
return verifyDetached(publicKey, message, detachedSignature)
@ -471,40 +460,41 @@ func decryptAttachment(
// prepare the private key for decryption
if privateKeyObj, err = crypto.NewKeyFromArmored(privateKey); err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to parse private key")
}
if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to unlock private key")
}
defer unlockedKeyObj.ClearPrivateParams()
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to create new keyring")
}
if message, err = privateKeyRing.DecryptAttachment(packets); err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to decrypt attachment")
}
return message, nil
}
func createPublicKeyRing(
publicKey string,
) (publicKeyRing *crypto.KeyRing, err error) {
func createPublicKeyRing(publicKey string) (*crypto.KeyRing, error) {
publicKeyObj, err := crypto.NewKeyFromArmored(publicKey)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to parse public key")
}
if publicKeyObj.IsPrivate() {
publicKeyObj, err = publicKeyObj.ToPublic()
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to extract public key from private key")
}
}
publicKeyRing, err = crypto.NewKeyRing(publicKeyObj)
return
publicKeyRing, err := crypto.NewKeyRing(publicKeyObj)
if err != nil {
return nil, errors.Wrap(err, "gopenpgp: unable to create new keyring")
}
return publicKeyRing, nil
}

View file

@ -18,7 +18,8 @@ func TestAESEncryption(t *testing.T) {
}
_, err = DecryptMessageWithPassword([]byte("Wrong passphrase"), ciphertext)
assert.EqualError(t, err, "gopenpgp: wrong password in symmetric decryption")
assert.EqualError(t, err, "gopenpgp: unable to decrypt message with password: "+
"gopenpgp: error in reading password protected message: gopenpgp: wrong password in symmetric decryption")
decrypted, err := DecryptMessageWithPassword(passphrase, ciphertext)
if err != nil {
@ -71,7 +72,7 @@ func TestArmoredTextMessageEncryptionVerification(t *testing.T) {
testMailboxPassword, // Password defined in base_test
armored,
)
assert.EqualError(t, err, "Signature Verification Error: No matching signature")
assert.EqualError(t, err, "gopenpgp: unable to decrypt message: Signature Verification Error: No matching signature")
decrypted, err := DecryptVerifyMessageArmored(
readTestFile("keyring_privateKey", false),

View file

@ -2,6 +2,7 @@ package helper
import (
"github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/pkg/errors"
)
// UpdatePrivateKeyPassphrase decrypts the given armored privateKey with oldPassphrase,
@ -12,21 +13,26 @@ func UpdatePrivateKeyPassphrase(
) (string, error) {
key, err := crypto.NewKeyFromArmored(privateKey)
if err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to parse key")
}
unlocked, err := key.Unlock(oldPassphrase)
if err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to unlock old key")
}
defer unlocked.ClearPrivateParams()
locked, err := unlocked.Lock(newPassphrase)
if err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to lock new key")
}
return locked.Armor()
armored, err := locked.Armor()
if err != nil {
return "", errors.Wrap(err, "gopenpgp: unable to armor new key")
}
return armored, nil
}
// GenerateKey generates a key of the given keyType ("rsa" or "x25519"), encrypts it, and returns an armored string.
@ -35,13 +41,13 @@ func UpdatePrivateKeyPassphrase(
func GenerateKey(name, email string, passphrase []byte, keyType string, bits int) (string, error) {
key, err := crypto.GenerateKey(name, email, keyType, bits)
if err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to generate new key")
}
defer key.ClearPrivateParams()
locked, err := key.Lock(passphrase)
if err != nil {
return "", err
return "", errors.Wrap(err, "gopenpgp: unable to lock new key")
}
return locked.Armor()
@ -50,7 +56,7 @@ func GenerateKey(name, email string, passphrase []byte, keyType string, bits int
func GetSHA256Fingerprints(publicKey string) ([]string, error) {
key, err := crypto.NewKeyFromArmored(publicKey)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to parse key")
}
return key.GetSHA256Fingerprints(), nil

View file

@ -2,8 +2,10 @@ package helper
import (
"encoding/json"
goerrors "errors"
"github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/pkg/errors"
)
type ExplicitVerifyMessage struct {
@ -24,14 +26,15 @@ func DecryptExplicitVerify(
message, err := privateKeyRing.Decrypt(pgpMessage, publicKeyRing, verifyTime)
if err != nil {
castedErr, isType := err.(crypto.SignatureVerificationError)
castedErr := &crypto.SignatureVerificationError{}
isType := goerrors.As(err, castedErr)
if !isType {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to decrypt message")
}
explicitVerify = &ExplicitVerifyMessage{
Message: message,
SignatureVerificationError: &castedErr,
SignatureVerificationError: castedErr,
}
} else {
explicitVerify = &ExplicitVerifyMessage{
@ -51,7 +54,7 @@ func DecryptAttachment(keyPacket []byte, dataPacket []byte, keyRing *crypto.KeyR
decrypted, err := keyRing.DecryptAttachment(splitMessage)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to decrypt attachment")
}
return decrypted, nil
}
@ -64,7 +67,7 @@ func EncryptAttachment(plainData []byte, filename string, keyRing *crypto.KeyRin
plainMessage := crypto.NewPlainMessageFromFile(plainData, filename, uint32(crypto.GetUnixTime()))
decrypted, err := keyRing.EncryptAttachment(plainMessage, "")
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to encrypt attachment")
}
return decrypted, nil
}
@ -74,7 +77,7 @@ func EncryptAttachment(plainData []byte, filename string, keyRing *crypto.KeyRin
func GetJsonSHA256Fingerprints(publicKey string) ([]byte, error) {
key, err := crypto.NewKeyFromArmored(publicKey)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "gopenpgp: unable to parse key")
}
return json.Marshal(key.GetSHA256Fingerprints())
@ -94,5 +97,9 @@ func EncryptSignArmoredDetachedMobile(
if err != nil {
return nil, err
}
return &EncryptSignArmoredDetachedMobileResult{ciphertext, encryptedSignature}, nil
return &EncryptSignArmoredDetachedMobileResult{
Ciphertext: ciphertext,
EncryptedSignature: encryptedSignature,
}, nil
}

View file

@ -5,6 +5,7 @@ package helper
import (
"github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/pkg/errors"
)
// EncryptSignAttachment encrypts an attachment using a detached signature, given a publicKey, a privateKey
@ -13,46 +14,36 @@ import (
func EncryptSignAttachment(
publicKey, privateKey string, passphrase []byte, filename string, plainData []byte,
) (keyPacket, dataPacket, signature []byte, err error) {
var publicKeyObj, privateKeyObj, unlockedKeyObj *crypto.Key
var privateKeyObj, unlockedKeyObj *crypto.Key
var publicKeyRing, privateKeyRing *crypto.KeyRing
var packets *crypto.PGPSplitMessage
var signatureObj *crypto.PGPSignature
var binMessage = crypto.NewPlainMessageFromFile(plainData, filename, uint32(crypto.GetUnixTime()))
if publicKeyObj, err = crypto.NewKeyFromArmored(publicKey); err != nil {
return nil, nil, nil, err
}
if publicKeyObj.IsPrivate() {
publicKeyObj, err = publicKeyObj.ToPublic()
if err != nil {
return nil, nil, nil, err
}
}
if publicKeyRing, err = crypto.NewKeyRing(publicKeyObj); err != nil {
if publicKeyRing, err = createPublicKeyRing(publicKey); err != nil {
return nil, nil, nil, err
}
if privateKeyObj, err = crypto.NewKeyFromArmored(privateKey); err != nil {
return nil, nil, nil, err
return nil, nil, nil, errors.Wrap(err, "gopenpgp: unable to parse private key")
}
if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil {
return nil, nil, nil, err
return nil, nil, nil, errors.Wrap(err, "gopenpgp: unable to unlock key")
}
defer unlockedKeyObj.ClearPrivateParams()
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
return nil, nil, nil, err
return nil, nil, nil, errors.Wrap(err, "gopenpgp: unable to create private keyring")
}
if packets, err = publicKeyRing.EncryptAttachment(binMessage, ""); err != nil {
return nil, nil, nil, err
return nil, nil, nil, errors.Wrap(err, "gopenpgp: unable to encrypt attachment")
}
if signatureObj, err = privateKeyRing.SignDetached(binMessage); err != nil {
return nil, nil, nil, err
return nil, nil, nil, errors.Wrap(err, "gopenpgp: unable to sign attachment")
}
return packets.GetBinaryKeyPacket(), packets.GetBinaryDataPacket(), signatureObj.GetBinary(), nil