gpg: Improve skipping of PGP-2 keys.
authorWerner Koch <wk@gnupg.org>
Thu, 22 Jan 2015 15:36:28 +0000 (16:36 +0100)
committerWerner Koch <wk@gnupg.org>
Thu, 22 Jan 2015 15:36:28 +0000 (16:36 +0100)
* g10/keydb.c (keydb_search_first, keydb_search_next): Skip legacy
keys.
* g10/keyring.c (keyring_get_keyblock): Handle GPG_ERR_LEGACY_KEY.
(prepare_search): Ditto.
(keyring_rebuild_cache): Skip legacy keys.
* g10/keyserver.c (keyidlist): Ditto.
* g10/trustdb.c (validate_key_list): Ditto.
--

This is not the most elegant way to handle it but it reduces the
chance for unwanted side effects.

GnuPG-bug-id: 1816
Signed-off-by: Werner Koch <wk@gnupg.org>
g10/keydb.c
g10/keylist.c
g10/keyring.c
g10/keyserver.c
g10/trustdb.c

index 263b504..401478a 100644 (file)
@@ -1489,24 +1489,40 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
 }
 
 
+/* Note that in contrast to using keydb_search in search first mode,
+   this function skips legacy keys.  */
 gpg_error_t
 keydb_search_first (KEYDB_HANDLE hd)
 {
+  gpg_error_t err;
   KEYDB_SEARCH_DESC desc;
 
   memset (&desc, 0, sizeof desc);
   desc.mode = KEYDB_SEARCH_MODE_FIRST;
-  return keydb_search (hd, &desc, 1, NULL);
+  err = keydb_search (hd, &desc, 1, NULL);
+  if (gpg_err_code (err) == GPG_ERR_LEGACY_KEY)
+    err = keydb_search_next (hd);
+  return err;
 }
 
+
+/* Note that in contrast to using keydb_search in search next mode,
+   this fucntion skips legacy keys.  */
 gpg_error_t
 keydb_search_next (KEYDB_HANDLE hd)
 {
+  gpg_error_t err;
   KEYDB_SEARCH_DESC desc;
 
-  memset (&desc, 0, sizeof desc);
-  desc.mode = KEYDB_SEARCH_MODE_NEXT;
-  return keydb_search (hd, &desc, 1, NULL);
+  do
+    {
+      memset (&desc, 0, sizeof desc);
+      desc.mode = KEYDB_SEARCH_MODE_NEXT;
+      err = keydb_search (hd, &desc, 1, NULL);
+    }
+  while (gpg_err_code (err) == GPG_ERR_LEGACY_KEY);
+
+  return err;
 }
 
 gpg_error_t
index daabc7d..5fd9eb8 100644 (file)
@@ -466,6 +466,8 @@ list_all (int secret, int mark_secret)
       rc = keydb_get_keyblock (hd, &keyblock);
       if (rc)
        {
+          if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
+            continue;  /* Skip legacy keys.  */
          log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
          goto leave;
        }
index 34829e7..6060f08 100644 (file)
@@ -398,6 +398,8 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
            init_packet (pkt);
            continue;
        }
+        if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
+          break;  /* Upper layer needs to handle this.  */
        if (rc) {
             log_error ("keyring_get_keyblock: read error: %s\n",
                        gpg_strerror (rc) );
@@ -654,8 +656,14 @@ keyring_search_reset (KEYRING_HANDLE hd)
 static int
 prepare_search (KEYRING_HANDLE hd)
 {
-    if (hd->current.error)
-        return hd->current.error; /* still in error state */
+    if (hd->current.error) {
+        /* If the last key was a legacy key, we simply ignore the error so that
+           we can easily use search_next.  */
+        if (gpg_err_code (hd->current.error) == GPG_ERR_LEGACY_KEY)
+            hd->current.error = 0;
+        else
+            return hd->current.error; /* still in error state */
+    }
 
     if (hd->current.kr && !hd->current.eof) {
         if ( !hd->current.iobuf )
@@ -1354,8 +1362,12 @@ keyring_rebuild_cache (void *token,int noisy)
   if(rc)
     goto leave;
 
-  while ( !(rc = keyring_search (hd, &desc, 1, NULL)) )
+  for (;;)
     {
+      rc = keyring_search (hd, &desc, 1, NULL);
+      if (rc && gpg_err_code (rc) != GPG_ERR_LEGACY_KEY)
+        break;  /* ready.  */
+
       desc.mode = KEYDB_SEARCH_MODE_NEXT;
       resname = keyring_get_resource_name (hd);
       if (lastresname != resname )
@@ -1387,10 +1399,15 @@ keyring_rebuild_cache (void *token,int noisy)
             goto leave;
         }
 
+      if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
+        continue;
+
       release_kbnode (keyblock);
       rc = keyring_get_keyblock (hd, &keyblock);
       if (rc)
         {
+          if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
+            continue;  /* Skip legacy keys.  */
           log_error ("keyring_get_keyblock failed: %s\n", gpg_strerror (rc));
           goto leave;
         }
@@ -1416,7 +1433,9 @@ keyring_rebuild_cache (void *token,int noisy)
              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.  */
+             using an older gpg version will always be available.
+             Note: This test is actually superfluous because we
+             already acted upon GPG_ERR_LEGACY_KEY.      */
         }
       else
         {
index 0530907..035cd03 100644 (file)
@@ -1248,16 +1248,25 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
        }
     }
 
-  while (!(rc = keydb_search (kdbhd, desc, ndesc, NULL)))
+  for (;;)
     {
+      rc = keydb_search (kdbhd, desc, ndesc, NULL);
+      if (rc && gpg_err_code (rc) != GPG_ERR_LEGACY_KEY)
+        break;  /* ready.  */
+
       if (!users)
        desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
 
+      if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
+        continue;
+
       /* read the keyblock */
       rc = keydb_get_keyblock (kdbhd, &keyblock );
       if( rc )
        {
-         log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) );
+          if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
+            continue;
+          log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) );
          goto leave;
        }
 
index 84179f0..08f6cf4 100644 (file)
@@ -1604,6 +1604,9 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
     {
       PKT_public_key *pk;
 
+      if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
+        continue;
+
       rc = keydb_get_keyblock (hd, &keyblock);
       if (rc)
         {
@@ -1660,7 +1663,8 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
       release_kbnode (keyblock);
       keyblock = NULL;
     }
-  while (!(rc = keydb_search (hd, &desc, 1, NULL)));
+  while (!(rc = keydb_search (hd, &desc, 1, NULL))
+         || gpg_err_code (rc) == GPG_ERR_LEGACY_KEY);
 
   if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
     {