Page MenuHome GnuPG

GnuPG behaves inconsistently across versions when a secret key is not found during decryption
Closed, ResolvedPublic

Description

The behaviour of GnuPG is inconsistent with respect to the messages it puts out when asked to decrypt, but there is no secret key corresponding to the public key used to encrypt the message. Here's GnuPG 1.4.22:

2021-08-20 21:43:58,058 DEBUG gnupg      Thread-10   980 [GNUPG:] ENC_TO 24819C9B75BCAD8D 16 0
2021-08-20 21:43:58,058 DEBUG gnupg      Thread-10   980 gpg: encrypted with ELG-E key, ID 75BCAD8D
2021-08-20 21:43:58,058 DEBUG gnupg      Thread-10   980 [GNUPG:] NO_SECKEY 24819C9B75BCAD8D
2021-08-20 21:43:58,058 DEBUG gnupg      Thread-10   980 [GNUPG:] BEGIN_DECRYPTION
2021-08-20 21:43:58,058 DEBUG gnupg      Thread-10   980 [GNUPG:] DECRYPTION_FAILED
2021-08-20 21:43:58,058 DEBUG gnupg      Thread-10   980 gpg: decryption failed: secret key not available
2021-08-20 21:43:58,058 DEBUG gnupg      Thread-10   980 [GNUPG:] END_DECRYPTION

and here's 2.2.19, which behaves similarly:

2021-08-20 20:25:39,629 DEBUG gnupg      Thread-10   980 [GNUPG:] ENC_TO 1A453EB8AC49419F 16 0
2021-08-20 20:25:39,629 DEBUG gnupg      Thread-10   980 gpg: encrypted with ELG key, ID 1A453EB8AC49419F
2021-08-20 20:25:39,629 DEBUG gnupg      Thread-10   980 [GNUPG:] NO_SECKEY 1A453EB8AC49419F
2021-08-20 20:25:39,629 DEBUG gnupg      Thread-10   980 [GNUPG:] BEGIN_DECRYPTION
2021-08-20 20:25:39,629 DEBUG gnupg      Thread-10   980 [GNUPG:] DECRYPTION_FAILED
2021-08-20 20:25:39,629 DEBUG gnupg      Thread-10   980 gpg: decryption failed: No secret key
2021-08-20 20:25:39,629 DEBUG gnupg      Thread-10   980 [GNUPG:] END_DECRYPTION

but in 2.3.1, the behaviour has changed:

2021-08-20 21:44:42,520 DEBUG gnupg      Thread-10   980 [GNUPG:] ENC_TO 031F36181FE503A2 16 0
2021-08-20 21:44:42,520 DEBUG gnupg      Thread-10   980 gpg: encrypted with ELG key, ID 031F36181FE503A2
2021-08-20 21:44:42,521 DEBUG gnupg      Thread-10   980 gpg: public key decryption failed: No secret key
2021-08-20 21:44:42,521 DEBUG gnupg      Thread-10   980 [GNUPG:] ERROR pkdecrypt_failed 33554449
2021-08-20 21:44:42,521 WARNING gnupg      Thread-10   651 potential problem: ERROR: pkdecrypt_failed 33554449
2021-08-20 21:44:42,521 DEBUG gnupg      Thread-10   980 [GNUPG:] BEGIN_DECRYPTION
2021-08-20 21:44:42,521 DEBUG gnupg      Thread-10   980 [GNUPG:] DECRYPTION_FAILED
2021-08-20 21:44:42,521 DEBUG gnupg      Thread-10   980 gpg: decryption failed: No secret key
2021-08-20 21:44:42,524 DEBUG gnupg      Thread-10   980 [GNUPG:] END_DECRYPTION
2021-08-20 21:44:42,524 DEBUG gnupg      Thread-10   980 gpg: [don't know]: invalid packet (ctb=73)
2021-08-20 21:44:42,524 DEBUG gnupg      Thread-10   980 [GNUPG:] NODATA 3

Clearly GnuPG 2.3.1 knows there's no secret key, but no [GNUPG:] NO_SECKEY XXX is emitted - and this causes breakage because useful information is lost due to the absence of that message.

Related Objects

Event Timeline

vsajip created this object in space S1 Public.
werner added a project: Bug Report.

In GnuPG 2.3, the procedure of decryption has been changed;
It now collects all ENC_TO packet, keeping it to ->PKENC_LIST field, and then process ENCRYPTED packet with the list.

For some use cases, it is true that GnuPG 2.3.1 doesn't emit [GNUPG:] NO_SECRETKEY status.
Example case is when there is no public OpenPGP key available for the list.

Perhaps, it would be better doing following for better backward compatibility.

diff --git a/g10/mainproc.c b/g10/mainproc.c
index 821378ee6..9f6935aed 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -589,7 +589,7 @@ proc_encrypted (CTX c, PACKET *pkt)
           struct pubkey_enc_list *list;
 
           for (list = c->pkenc_list; list; list = list->next)
-            if (list->result && list->result != -1)
+            if (list->result)
               {
                 char buf[20];
                 snprintf (buf, sizeof buf, "%08lX%08lX",

A cursory look doesn't show me where list->result is set to something else than -1. Can you give me a hint?

Oh yes, I was blind.

I agree that we should always output NO_SECKEY lines for all keys - regardless of whether get_session_key even considered them.