Page MenuHome GnuPG

Kleopatra: Cannot decrypt packets with hybrid cipher without using symmetric passphrase
Open, NormalPublic

Description

Originally reported on KDE's bug tracker for gpg4win 4.3.1 (https://bugs.kde.org/show_bug.cgi?id=492756).

Input: A file that is encrypted for an OpenPGP key and with a passphrase.

Try to decrypt this file with Kleopatra. A pinentry asking for the (symmetric) "passphrase for decryption" pops up.

Note for testing: Restart the background processes after each case to clear the password caches.

Case 1: Cancel the pinentry dialog asking for the symmetric passphrase

-> Kleopatra shows

Decryption canceled.

Expected: A pinentry asking for the passphrase of the OpenPGP key pops up.

Case 2: Enter an empty symmetric passphrase (i.e. simply press Return)

-> A pinentry asking for the passphrase of the OpenPGP key pops up.

Enter the correct passphrase for the key.

-> Kleopatra shows

Decryption failed: Bad passphrase.

Expected: Kleopatra reports success and allows to save the decrypted file.

Case 3: Enter a wrong symmetric passphrase

-> A pinentry asking for the passphrase of the OpenPGP key pops up.

Enter the correct passphrase for the key.

-> Kleopatra reports success and allows to save the decrypted file.

This is the expected behavior.

Note: In all cases, gpg asks for the passphrase of the OpenPGP key and then decrypts the data.

Event Timeline

In the first case, gpg emits a CANCELED_BY_USER status. This makes gpgme abort the operation. We may have to wait/watch for BEGIN_DECRYPTION / END_DECRYPTION.

Status output of gpg:

[GNUPG:] ENC_TO 547ECA3FEAB73FC2 18 0
[GNUPG:] NEED_PASSPHRASE_SYM 9 3 2
[GNUPG:] WARNING server_version_mismatch 0 server 'gpg-agent' is older than us (2.4.5 < 2.4.6-beta102)
[GNUPG:] PINENTRY_LAUNCHED 455567 qt 1.3.1 /dev/pts/16 xterm-256color :0 20600/1000/5 1000/1000 0

Cancel pinentry

[GNUPG:] CANCELED_BY_USER
[GNUPG:] KEY_CONSIDERED 3A8536D46F57779C49F0CF542C0444CB59852D29 0
[GNUPG:] KEY_CONSIDERED 5F4C389C9265ABDE08B21CEA41FAC215ADE1CB46 0
[GNUPG:] KEY_CONSIDERED CC2750526E7D9CA70F599CD3F612794A4EB653DD 0
[GNUPG:] KEY_CONSIDERED 8C8AFD6AEF9F30C4F6D80CF6089F4ED80F384779 0
[GNUPG:] KEYEXPIRED 1667038797
[GNUPG:] KEY_CONSIDERED 8DF42AB4B60250D675F3416B02BC64C000116E2C 0
[GNUPG:] KEYEXPIRED 1667038967
[GNUPG:] KEY_CONSIDERED E30272C0D092381922B914A7A5B048367DBFF9B2 0
[GNUPG:] KEYEXPIRED 1671200444
[GNUPG:] KEY_CONSIDERED CEEF61A3A792C6CAA40914B36E10BD5CA0946C1B 0
[GNUPG:] KEYEXPIRED 1671620400
[GNUPG:] KEY_CONSIDERED 377EAE5E59B976010A7D2EDC0E41874D72E1A302 0
[GNUPG:] KEY_CONSIDERED 3A8536D46F57779C49F0CF542C0444CB59852D29 0
[GNUPG:] PINENTRY_LAUNCHED 455594 qt 1.3.1 /dev/pts/16 xterm-256color :0 20600/1000/5 1000/1000 0
[GNUPG:] KEY_CONSIDERED 3A8536D46F57779C49F0CF542C0444CB59852D29 0
[GNUPG:] DECRYPTION_KEY 4DE4678D1CB12ECD4E9D8B6E547ECA3FEAB73FC2 3A8536D46F57779C49F0CF542C0444CB59852D29 u
[GNUPG:] BEGIN_DECRYPTION
[GNUPG:] DECRYPTION_INFO 0 9 2
[GNUPG:] PLAINTEXT 62 1630576688 
[GNUPG:] PLAINTEXT_LENGTH 31
[GNUPG:] DECRYPTION_OKAY
[GNUPG:] GOODMDC
[GNUPG:] END_DECRYPTION

In the second case, gpg emits a FAILURE gpg-exit 33554433 status at the end. I think this makes gpgme consider the operation failed. I think this is a bug in gpg because gpg does not emit a FAILURE status if a wrong symmetric passphrase is entered.

Status output of gpg:

[GNUPG:] ENC_TO 547ECA3FEAB73FC2 18 0
[GNUPG:] NEED_PASSPHRASE_SYM 9 3 2
[GNUPG:] WARNING server_version_mismatch 0 server 'gpg-agent' is older than us (2.4.5 < 2.4.6-beta102)
[GNUPG:] PINENTRY_LAUNCHED 455875 qt 1.3.1 /dev/pts/16 xterm-256color :0 20600/1000/5 1000/1000 0

Enter empty passphrase

[GNUPG:] MISSING_PASSPHRASE
gpg: gcry_kdf_derive failed: Invalid data[GNUPG:] MISSING_PASSPHRASE

^interesting log output

[GNUPG:] KEY_CONSIDERED 3A8536D46F57779C49F0CF542C0444CB59852D29 0
[GNUPG:] KEY_CONSIDERED 5F4C389C9265ABDE08B21CEA41FAC215ADE1CB46 0
[GNUPG:] KEY_CONSIDERED CC2750526E7D9CA70F599CD3F612794A4EB653DD 0
[GNUPG:] KEY_CONSIDERED 8C8AFD6AEF9F30C4F6D80CF6089F4ED80F384779 0
[GNUPG:] KEYEXPIRED 1667038797
[GNUPG:] KEY_CONSIDERED 8DF42AB4B60250D675F3416B02BC64C000116E2C 0
[GNUPG:] KEYEXPIRED 1667038967
[GNUPG:] KEY_CONSIDERED E30272C0D092381922B914A7A5B048367DBFF9B2 0
[GNUPG:] KEYEXPIRED 1671200444
[GNUPG:] KEY_CONSIDERED CEEF61A3A792C6CAA40914B36E10BD5CA0946C1B 0
[GNUPG:] KEYEXPIRED 1671620400
[GNUPG:] KEY_CONSIDERED 377EAE5E59B976010A7D2EDC0E41874D72E1A302 0
[GNUPG:] KEY_CONSIDERED 3A8536D46F57779C49F0CF542C0444CB59852D29 0
[GNUPG:] PINENTRY_LAUNCHED 455901 qt 1.3.1 /dev/pts/16 xterm-256color :0 20600/1000/5 1000/1000 0
[GNUPG:] KEY_CONSIDERED 3A8536D46F57779C49F0CF542C0444CB59852D29 0
[GNUPG:] DECRYPTION_KEY 4DE4678D1CB12ECD4E9D8B6E547ECA3FEAB73FC2 3A8536D46F57779C49F0CF542C0444CB59852D29 u
[GNUPG:] BEGIN_DECRYPTION
[GNUPG:] DECRYPTION_INFO 0 9 2
[GNUPG:] PLAINTEXT 62 1630576688 
[GNUPG:] PLAINTEXT_LENGTH 31
[GNUPG:] DECRYPTION_OKAY
[GNUPG:] GOODMDC
[GNUPG:] END_DECRYPTION
[GNUPG:] FAILURE gpg-exit 33554433

For the second case, I think that gcry_kdf_defive should not be called with pw="". The result of FAILURE gpg-exit 33554433 comes from the log_error after failure of gcry_kdf_derive.

For gpg, something like following is needed:

diff --git a/g10/passphrase.c b/g10/passphrase.c
index c5ec8eae4..82160e3b0 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -384,8 +384,16 @@ passphrase_to_dek (int cipher_algo, STRING2KEY *s2k,
      get_last_passphrase(). */
   dek = xmalloc_secure_clear ( sizeof *dek );
   dek->algo = cipher_algo;
-  if ( (!pw || !*pw) && create)
-    dek->keylen = 0;
+  if (!pw || !*pw)
+    {
+      if (create)
+        dek->keylen = 0;
+      else
+        {
+          xfree (dek);
+          return NULL;
+        }
+    }
   else
     {
       gpg_error_t err;
ebo triaged this task as Normal priority.Oct 24 2024, 12:19 PM
ebo added a project: gpd5x (gpd-5.0.0).
ebo added a subscriber: ebo.

Regarding triage: This is not widely encountered and a workaround exists

When checking this out with gpg4win-Beta-64 I can reproduce case 1 (and of course 3) but not case 2:

After returning the empty symmetric password and giving the correct password for the private key the decryption is successful.

This would leave only case 1 as open bug.

I can still reproduce case 2 with gnupg 2.4. I have to check how my local setup differs from gpg4win-Beta-64.

gnupg 2.2 behaves completely different. gnupg 2.2 first asks for the password of the OpenPGP key. If I enter an empty password and then enter the correct symmetric password then decryption is successful in Kleopatra.