gpg: Fix --rebuild-keydb-caches.
authorWerner Koch <wk@gnupg.org>
Fri, 31 Oct 2014 09:29:02 +0000 (10:29 +0100)
committerWerner Koch <wk@gnupg.org>
Fri, 31 Oct 2014 09:31:11 +0000 (10:31 +0100)
* g10/parse-packet.c (parse_key): Store even unsupported packet
versions.
* g10/keyring.c (keyring_rebuild_cache): Do not copy keys with
versions less than 4.
--

That function, which is implicitly called while checking the keydb, led
to corruption of v3 key packets in the keyring which would later spit
out "packet(6)too short" messages.

Signed-off-by: Werner Koch <wk@gnupg.org>
NEWS
g10/keyring.c
g10/parse-packet.c

diff --git a/NEWS b/NEWS
index d371b80..908a12b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,7 +8,8 @@ Noteworthy changes in version 2.1.0 (unreleased)
    used.
 
  * gpg: All support for v3 (PGP 2) keys has been dropped.  All
-   signatures are now created as v4 signatures.
+   signatures are now created as v4 signatures.  v3 keys will be
+   removed from the keyring.
 
  * gpg: With pinentry-0.9.0 the passphrase "enter again" prompt shows
    up in the same window as the "new passphrase" prompt.
index 6f75b6a..a1936b3 100644 (file)
@@ -1409,40 +1409,51 @@ keyring_rebuild_cache (void *token,int noisy)
           goto leave;
         }
 
-      /* check all signature to set the signature's cache flags */
-      for (node=keyblock; node; node=node->next)
+      if (keyblock->pkt->pkt.public_key->version < 4)
         {
-         /* Note that this doesn't cache the result of a revocation
-            issued by a designated revoker.  This is because the pk
-            in question does not carry the revkeys as we haven't
-            merged the key and selfsigs.  It is questionable whether
-            this matters very much since there are very very few
-            designated revoker revocation packets out there. */
-
-          if (node->pkt->pkttype == PKT_SIGNATURE)
+          /* We do not copy/cache v3 keys or any other unknown
+             packets.  It is better to remove them from the keyring.
+             The code required to keep them in the keyring would be
+             too complicated.  Given that we do not touch the old
+             secring.gpg a suitable backup for decryption of v3 stuff
+             using an older gpg version will always be available.  */
+        }
+      else
+        {
+          /* Check all signature to set the signature's cache flags. */
+          for (node=keyblock; node; node=node->next)
             {
-             PKT_signature *sig=node->pkt->pkt.signature;
+              /* Note that this doesn't cache the result of a
+                 revocation issued by a designated revoker.  This is
+                 because the pk in question does not carry the revkeys
+                 as we haven't merged the key and selfsigs.  It is
+                 questionable whether this matters very much since
+                 there are very very few designated revoker revocation
+                 packets out there. */
+              if (node->pkt->pkttype == PKT_SIGNATURE)
+                {
+                  PKT_signature *sig=node->pkt->pkt.signature;
 
-             if(!opt.no_sig_cache && sig->flags.checked && sig->flags.valid
-                && (openpgp_md_test_algo(sig->digest_algo)
-                    || openpgp_pk_test_algo(sig->pubkey_algo)))
-               sig->flags.checked=sig->flags.valid=0;
-             else
-               check_key_signature (keyblock, node, NULL);
+                  if(!opt.no_sig_cache && sig->flags.checked && sig->flags.valid
+                     && (openpgp_md_test_algo(sig->digest_algo)
+                         || openpgp_pk_test_algo(sig->pubkey_algo)))
+                    sig->flags.checked=sig->flags.valid=0;
+                  else
+                    check_key_signature (keyblock, node, NULL);
 
-              sigcount++;
+                  sigcount++;
+                }
             }
-        }
 
-      /* write the keyblock to the temporary file */
-      rc = write_keyblock (tmpfp, keyblock);
-      if (rc)
-        goto leave;
-
-      if ( !(++count % 50) && noisy && !opt.quiet)
-        log_info(_("%lu keys cached so far (%lu signatures)\n"),
-                 count, sigcount );
+          /* Write the keyblock to the temporary file.  */
+          rc = write_keyblock (tmpfp, keyblock);
+          if (rc)
+            goto leave;
 
+          if ( !(++count % 50) && noisy && !opt.quiet)
+            log_info(_("%lu keys cached so far (%lu signatures)\n"),
+                     count, sigcount );
+        }
     } /* end main loop */
   if (rc == -1)
     rc = 0;
index 7787825..039f085 100644 (file)
@@ -1953,6 +1953,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
         log_info ("packet(%d) with obsolete version %d\n", pkttype, version);
       if (list_mode)
         es_fprintf (listfp, ":key packet: [obsolete version %d]\n", version);
+      pk->version = version;
       err = gpg_error (GPG_ERR_INV_PACKET);
       goto leave;
     }