diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a979ae..e99a14d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,10 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Decryption tests for attachments +### Fixed +- Armoring headers for public or private keys +- Session key decoding on invalid keys + ## [2.1.5] 2021-02-19 ## Changed -- Removed an unecessary cloning in the attachment processor, to perform better in low memory settings +- Removed an unnecessary cloning in the attachment processor, to perform better in low memory settings ## [2.1.4] 2021-01-08 ### Added diff --git a/crypto/attachment_test.go b/crypto/attachment_test.go index 9465019..bc3334a 100644 --- a/crypto/attachment_test.go +++ b/crypto/attachment_test.go @@ -103,7 +103,7 @@ func TestAttachmentDecrypt(t *testing.T) { assert.Exactly(t, message, redecData) } -func TestAttachmentDecrypt2(t *testing.T) { +func TestAttachmentDecryptStatic(t *testing.T) { passphrase := []byte("wUMuF/lkDPYWH/0ZqqY8kJKw7YJg6kS") keyPacket, err := base64.StdEncoding.DecodeString(readTestFile("att_keypacket", false)) if err != nil { diff --git a/crypto/key.go b/crypto/key.go index 95db474..e5231a6 100644 --- a/crypto/key.go +++ b/crypto/key.go @@ -200,7 +200,11 @@ func (key *Key) Armor() (string, error) { return "", err } - return armor.ArmorWithType(serialized, constants.PrivateKeyHeader) + if key.IsPrivate() { + return armor.ArmorWithType(serialized, constants.PrivateKeyHeader) + } + + return armor.ArmorWithType(serialized, constants.PublicKeyHeader) } // ArmorWithCustomHeaders returns the armored key as a string, with diff --git a/crypto/keyring_session.go b/crypto/keyring_session.go index f0a7d93..ca2a94f 100644 --- a/crypto/keyring_session.go +++ b/crypto/keyring_session.go @@ -55,15 +55,15 @@ Loop: } if !hasPacket { - return nil, errors.Wrap(err, "gopenpgp: couldn't find a session key packet that could be decrypted") + return nil, errors.Wrap(err, "gopenpgp: couldn't find a session key packet") } if decryptErr != nil { return nil, errors.Wrap(decryptErr, "gopenpgp: error in decrypting") } - if ek == nil { - return nil, errors.New("gopenpgp: unable to decrypt session key") + if ek == nil || ek.Key == nil { + return nil, errors.New("gopenpgp: unable to decrypt session key: no valid decryption key") } return newSessionKeyFromEncrypted(ek) diff --git a/crypto/sessionkey_test.go b/crypto/sessionkey_test.go index 90ea9bf..f2739bd 100644 --- a/crypto/sessionkey_test.go +++ b/crypto/sessionkey_test.go @@ -1,6 +1,7 @@ package crypto import ( + "encoding/base64" "testing" "github.com/ProtonMail/gopenpgp/v2/constants" @@ -210,3 +211,31 @@ func TestDataPacketEncryptionWithCompression(t *testing.T) { } assert.Exactly(t, message.GetString(), decrypted.GetString()) } + +func TestAsymmetricKeyPacketDecryptionFailure(t *testing.T) { + passphrase := []byte("passphrase") + keyPacket, err := base64.StdEncoding.DecodeString(readTestFile("sessionkey_packet", false)) + if err != nil { + t.Error("Expected no error while decoding key packet, got:" + err.Error()) + } + + pk, err := NewKeyFromArmored(readTestFile("sessionkey_key", false)) + if err != nil { + t.Error("Expected no error while unarmoring private key, got:" + err.Error()) + } + + uk, err := pk.Unlock(passphrase) + if err != nil { + t.Error("Expected no error while unlocking private key, got:" + err.Error()) + } + + defer uk.ClearPrivateParams() + + ukr, err := NewKeyRing(uk) + if err != nil { + t.Error("Expected no error while building private keyring, got:" + err.Error()) + } + + _, err = ukr.DecryptSessionKey(keyPacket) + assert.Error(t, err, "gopenpgp: unable to decrypt session key") +} diff --git a/crypto/testdata/sessionkey_key b/crypto/testdata/sessionkey_key new file mode 100644 index 0000000..c64b1c5 --- /dev/null +++ b/crypto/testdata/sessionkey_key @@ -0,0 +1,31 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- +Version: BCPG C# v1.8.8.0 + +lQOyBF/H5jYBCACIUtGN3wGf8I4Kl+fwz54nrJcPYf88hyUDNOY2esSBqd7RrJCU +RrWFKmuYHXdstfLwS9h8FLboLB5Gkq+hNnWq66CFC3H93rvmvm8IEU3DcJyUSIMr +QlQn4+/lsMhHjerwhHJrY/moNaDzZ85WEvnkbptEy8AUJLw0t8wMbujyUfdQnmCK +CRTB/s/Ol9gq+eRar6YPonr/8R/YM/kColk+7VKENayslb2217X8SZ99MzeWbafP +9JRq/sl0dAfYH0Gbw+1tTyP5lB5LAbdZ0OVYPW0tnJ9yKjDBjrwn5C/3hDS4fYzk +FZAix1baNBuqtgRUzCnu0AjZW9LfFrZts6aVAAUT/wkDAsUlnOW3SOQLYLnYo/Td +zOwk7Myzttd++zQ7rCZOksGFk3qVJOA18z1CKMKg/NB+hDWpw7gw9HejnnFOxZ1x +ONCQ09x7/nrza13XiLGoeOCgIz4VKkUDiup1l4x9/9P6jVNwSmtSdzgVb+4lv8X2 +YFkt3o/SxlztM2s9ZiFz2IBXMF4FgXogG9417RmXKJc0Ham5rZQ0PEVWqCVmXcPq +pbb5z/TgwfScAzpKvjFXusR7s+jDYk2PZ8NN4ncOlFRSXOEBTJ98hyx0A520Kqkz +NqB15SQRIUIwbpsHud+bEYS5jfEMb1fg4GAr/lCeu++g4ckmFeoehSUTRLiQcpZ8 +8iVUrF5VJqj3D4h6hJPaLplA1uqA29cVo8c1OO0RUtOnUEi4MRoGDyf2kFHcKvqk +lPnb+UxeBI4LLiUWcAKGEHIZujTWfwvfJdBFM5aDZbHFAi7YIX7OBSrQPpa/3uSK +V6I0jJWtXGw693EQ9BGdlScHp4/iSdSb6cjHjTxqe/jJOadnY5OPb+mHSGs/AWQ8 +4dGERmjRE9nfV8Pau1/3Hk7h5ELjDrDu3X2t4Gc/U8I7I1kWywmQbxJVvfsMjZio +jOBnaBigjWT2sEFyvgNd96IEpWBIlF25y7AaR9f1oe7INzl0I48xXjyb8JPZyLU3 +9NbWob6MscqQw9ePai/xCeXS5VUYc/VqAp2SYrNuh5YFh52arWjABPWcZxAOSRmT +OTXf8Oqs4XINYK2uuu25DMwAA7Y0NTEUYETkSOJQ0hrs+vXDabIJIunkr9V4o5kR +l8ivGEFvKyuq4djPgINbybwtKg5wDAupik8x7vipiGNmkrICDJOaUqhy/JU+QXrU +an1BvMoFz4bqI2yhjV5OqgLpZFJIoirWb6igkkMhXzbThtq/HrQAiQEcBBABAgAG +BQJfx+Y2AAoJECkFqdVSI1GtKtAH/jzA+CkPkSaN6A29RP/BWSRSeCEMP9+ihrhh +AZ2xZYUgeUnvv/UMqI6oq6ytvttMJYlaF8sRVLy/1IPCs3j8uHwqYZTbrfU3U3pC +52NoalCzYV82QM1RViiOO+yYuR7uR66ETpMmKzl3J9l78756Ti6aYU/mY06QQLc7 +5iGmjv0vQTGLnrmTR60PBWoC1M66v/keJg1caW0o05dQCDScP8TSA/VhDyf2Sn84 +RMNkzQymCb/PpUcDbfcM/7izOsn1A/ypX3p1B7LRr044QylxjrisM0Yyk5ATHWkU +s9IcG0hCAeASb2stvyioO4GMbelxFOdfDh/2bEWlfUYIMnDToHg= +=grHo +-----END PGP PRIVATE KEY BLOCK----- \ No newline at end of file diff --git a/crypto/testdata/sessionkey_packet b/crypto/testdata/sessionkey_packet new file mode 100644 index 0000000..cc3390b --- /dev/null +++ b/crypto/testdata/sessionkey_packet @@ -0,0 +1 @@ +wcBMAykFqdVSI1GtAQf+ID+pqYcKMsHUeos3qQ/2zJ+8XguKg8/bpW66XXQJOlXO/yWP5NplcuBIZcDfnJ9gk8cpOg8QXCzgk4BqmpuDVrShn0M4UnmcISC43i5L8+tS63Vv0LHxdcj5ADYAFKz0bRKjhf3JFjibttn8nuEEJJVNi4zUwC2lVr8v5THxj6SpZtNrBeFaaQ0Y78q8rNqPZtNqq2TcCmlVj4d+VnNnbkEOrizw97I9P784L169s0kVb3S0t0r1Y/mOPxq3T1EXDbo37quveZjKHgkuT/1FTOEO2yzqPOhyRlF6MuQYlPJMZv9pHwNDCyfm8WQutzpRK+MI4AcqVyALC4rU3w9JNg== \ No newline at end of file