No file saved on decryption if signing certificate is not available
Testing, HighPublic

Assigned To
None
Authored By
ebo
Wed, Aug 5, 4:05 PM

Description

How to reproduce: Decrypt an OpenPGP signed and encrypted file on the command line without the signing certificate in your keyring. The command gives no error:

C:\Users\g10code.WIN-TEST3\Documents>gpg -o xxx.pdf -d test_doc.pdf.gpg
gpg: verschlüsselt mit RSA Schlüssel, ID CD573B2B0736643A
gpg: verschlüsselt mit cv25519 Schlüssel, ID F4FD55519F948049, erzeugt 2026-08-03
      "g10code"
gpg: Signatur vom 08/05/26 15:13:14 Mitteleuropische Sommerzeit
gpg:                mittels RSA-Schlüssel 98111E67AE06F2BEFD2BDE10C5D6C919005F36A4
gpg: Signatur kann nicht geprüft werden: Kein öffentlicher Schlüssel

But xxx.pdf is not saved. If you put compatibility-flags no-partial-file-guard in gpg.conf and repeat the command, the file will be saved.

This seems to be a regression from T7873: Decrypt to foo.gpg.part files and rename. It breaks behavior in Kleopatra, too.

Details

External Link
https://bugs.kde.org/show_bug.cgi?id=523837
Version
Gpg4win-5.1.0

Event Timeline

ebo created this object with edit policy "Contributor (Project)".
ebo changed Version from Gpg4win-5.0.1 to Gpg4win-5.1.0 .Wed, Aug 5, 4:10 PM

I tested with GnuPG 2.5.21 and gpg returned with error.
There error counter is increased by log_error in mainproc.c: check_sig_and_print.
If the error count is not 0 at exit the partial file is deleted by gpg.c: gnupg_process_partial_file.

Would resetting the error counter on successful decryption work?
Edit: We should not reset the error count. Please ignore the patch.

diff --git a/g10/gpg.c b/g10/gpg.c
index 8fab82bc7..96065d5c2 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -4734,18 +4734,24 @@ main (int argc, char **argv)
 	break;
 
       case aDecrypt:
-        if (multifile)
-	  decrypt_messages (ctrl, argc, argv);
-	else
-	  {
-	    if( argc > 1 )
-	      wrong_args("--decrypt [filename]");
-	    if( (rc = decrypt_message (ctrl, fname, NULL) ))
-              {
-                write_status_failure ("decrypt", rc);
-                log_error("decrypt_message failed: %s\n", gpg_strerror (rc) );
-              }
-	  }
+        {
+          int errcount = log_get_errorcount (0);
+
+          if (multifile)
+            decrypt_messages (ctrl, argc, argv);
+          else
+            {
+              if( argc > 1 )
+                wrong_args("--decrypt [filename]");
+              if( (rc = decrypt_message (ctrl, fname, NULL) ))
+                {
+                  write_status_failure ("decrypt", rc);
+                  log_error("decrypt_message failed: %s\n", gpg_strerror (rc) );
+                }
+            }
+
+          if (!errcount && !rc)
+            log_get_errorcount (1); /* clear counter */
+        }
 	break;
 
       case aQuickSignKey:

I'm wondering whether we should disable the partial file guard by default. The downside is that we wouldn't have noticed this bug so quickly because almost nobody would enable this feature. On the other hand, for Kleopatra (which uses QGpgME) we already have such a guard in QGpgME.

gniibe mentioned this in Unknown Object (Maniphest Task).Mon, Aug 10, 3:55 AM

Here is the change of GnuPG to disable the partial file guard with ".part" already:

+ || has_suffix (fname, EXTSEP_S "part", 5))

Is somewhat surprising because it is not clear that EXTSEP_P has a length of 1. Woul'd it be better to drop the suffix_len arg from has_suffix and instead use an strlen inside of has_suffix?

@gniibe I would like to push this patch if you don't see any issues:

Note:

  • The .part file is removed only if decryption fails.
  • The changes in g10/misc.c is just splitting the gnupg_process_partial_file into two functions (not clear in the diff).

Would it be better to drop the suffix_len arg from has_suffix and instead use an strlen inside of has_suffix?

OK. I'm going to push revised version.

In T8399#221926, @pl13 wrote:

@gniibe I would like to push this patch if you don't see any issues:

Ack. No problem at all. Please go ahead.

pl13 changed the task status from Open to Testing.Wed, Aug 12, 8:45 AM
pl13 mentioned this in Unknown Object (Maniphest Task).Mon, Aug 17, 9:19 AM