Page MenuHome GnuPG

Expire subkey violates assertion "! sig->hashed"
Closed, ResolvedPublic

Description

Upon "save" after setting the expiry date of an old ElGamma2048 Subkey in "gpg --edit-key" an assertion is violated an the application terminated. The output is

gpg> save
gpg: Ohhhh jeeee: Assertion "! sig->hashed" in do_signature failed (../../g10/build-packet.c:1508)
Aborted

The key in question was created with gpg on a Linux PC in March 2001, DSA1024/ElGamal2048. The error is reliably reproducible on that same key. I can not reproduce the error on a newly created key of the same kind.

Steps to reproduce the error:
(1) Take an old DSA/ElGamal unexpired key secret/public pair in your keyring
(2) gpg --edit-key <key-id>
(3) key 1
(4) expire ...
(5) save
Expected behaviour: the key is saved and gpg terminates successfully
Observed behaviour: assertion error thrown as above, gpg aborted, leaving lock behind.

If this is an interesting case and you need more data to reproduce the problem, please direct me to resources explaining how to collect the data.

Thanks

Details

Version
gpg (GnuPG) 2.2.27, libgcrypt 1.8.8, Debian 5.10.92-1 i686 GNU/Linux 5.10.0-11-686

Event Timeline

erlandm renamed this task from Expire subkey violates asserion "! sig->hashed" to Expire subkey violates assertion "! sig->hashed".Feb 1 2022, 3:03 PM
erlandm created this task.
erlandm updated the task description. (Show Details)

This code

if ((only_mainkey && main_pk->version < 4)
     || (!only_mainkey && sub_pk->version < 4))
{
  log_info (_("You can't change the expiration date of a v3 key\n"));
  return gpg_error (GPG_ERR_LEGACY_KEY);
}

should have kicked in but it didn't for your key. Would you mind to check that key using --list-packets to view the versions of the the public key and public sub key packets? (gpg --export YOURKEY | gpg --list-packets | less)

Here is the output of --list-packets of the offending key, anonymised:

  1. off=0 ctb=99 tag=6 hlen=3 plen=418 :public key packet: version 4, algo 17, created 985690138, expires 0 pkey[0]: [1024 bits] pkey[1]: [160 bits] pkey[2]: [1024 bits] pkey[3]: [1023 bits] keyid: <KEY_ID>
  2. off=421 ctb=b4 tag=13 hlen=2 plen=35 :user ID packet: "XXXXXXXXXXXXX"
  3. off=458 ctb=88 tag=2 hlen=2 plen=120 :signature packet: algo 17, keyid <KEY_ID> version 4, created 1629537425, md5len 0, sigclass 0x13 digest algo 2, begin of digest a8 22 hashed subpkt 33 len 21 (issuer fpr v4 <XXXXXXXXXXXXXX><KEY_ID>) hashed subpkt 2 len 4 (sig created 2021-08-21) hashed subpkt 27 len 1 (key flags: 23) hashed subpkt 11 len 4 (pref-sym-algos: 9 8 7 2) hashed subpkt 21 len 5 (pref-hash-algos: 8 9 10 11 2) hashed subpkt 22 len 3 (pref-zip-algos: 2 3 1) hashed subpkt 30 len 1 (features: 01) hashed subpkt 23 len 1 (keyserver preferences: 80) subpkt 16 len 8 (issuer key ID <KEY_ID>) data: [158 bits] data: [159 bits]
  4. off=580 ctb=b9 tag=14 hlen=3 plen=525 :public sub key packet: version 4, algo 16, created 985690139, expires 0 pkey[0]: [2048 bits] pkey[1]: [2 bits] pkey[2]: [2046 bits] keyid: YYYYYYYYYYYYYYY
  5. off=1108 ctb=88 tag=2 hlen=2 plen=63 :signature packet: algo 17, keyid <KEY_ID> version 3, created 985690139, md5len 5, sigclass 0x18 digest algo 2, begin of digest 94 e5 data: [159 bits] data: [156 bits]

Thanks for looking into this

I think that this commit rG8fd150b05b74: gpg: Remove all support for v3 keys and always create v4-signatures. matters.

Perhaps, something like this is needed to avoid generating v3 signature:

diff --git a/g10/sign.c b/g10/sign.c
index 2ab76c99b..8547a3ab6 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -1928,6 +1928,10 @@ update_keysig_packet (ctrl_t ctrl,
   /* Create a new signature packet.  */
   sig = copy_signature (NULL, orig_sig);
 
+  /* Don't generate version 3 signature, but newer.  */
+  if (sig->version == 3)
+    sig->version = pk->version;
+
   sig->digest_algo = digest_algo;
 
   /* We need to create a new timestamp so that new sig expiration
gniibe added a project: Restricted Project.

Not applying the change to GnuPG 2.2, users can use GnuPG 2.3 for that.

  • Fixed in 2.3
  • assert replaced by a fatal error message