* keydb.h, kbnode.c (undelete_kbnode): New function to undelete a
authorDavid Shaw <dshaw@jabberwocky.com>
Fri, 10 Jun 2005 02:52:41 +0000 (02:52 +0000)
committerDavid Shaw <dshaw@jabberwocky.com>
Fri, 10 Jun 2005 02:52:41 +0000 (02:52 +0000)
kbnode.

* trustdb.c (clean_uids_from_key): Further tweak the algorithm so that
the last good selfsig is kept when the chosen selfsig is a revocation.

g10/ChangeLog
g10/kbnode.c
g10/keydb.h
g10/trustdb.c

index 48a6e6e..e31dc6a 100644 (file)
@@ -1,3 +1,12 @@
+2005-06-09  David Shaw  <dshaw@jabberwocky.com>
+
+       * keydb.h, kbnode.c (undelete_kbnode): New function to undelete a
+       kbnode.
+
+       * trustdb.c (clean_uids_from_key): Further tweak the algorithm so
+       that the last good selfsig is kept when the chosen selfsig is a
+       revocation.
+
 2005-06-08  David Shaw  <dshaw@jabberwocky.com>
 
        * trustdb.c (clean_uids_from_key), keyedit.c
index ecfac82..cd3bf5f 100644 (file)
@@ -1,5 +1,6 @@
 /* kbnode.c -  keyblock node utility functions
- * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ *               2005 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -113,6 +114,11 @@ delete_kbnode( KBNODE node )
     node->private_flag |= 1;
 }
 
+void
+undelete_kbnode( KBNODE node )
+{
+    node->private_flag &= ~1;
+}
 
 
 /****************
index db3d9e3..f716a73 100644 (file)
@@ -1,6 +1,6 @@
 /* keydb.h - Key database
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
- *               2004 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+ *               2005 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -293,6 +293,7 @@ KBNODE new_kbnode( PACKET *pkt );
 KBNODE clone_kbnode( KBNODE node );
 void release_kbnode( KBNODE n );
 void delete_kbnode( KBNODE node );
+void undelete_kbnode( KBNODE node );
 void add_kbnode( KBNODE root, KBNODE node );
 void insert_kbnode( KBNODE root, KBNODE node, int pkttype );
 void move_kbnode( KBNODE *root, KBNODE node, KBNODE where );
index 19dcb0a..9f71f63 100644 (file)
@@ -1644,12 +1644,18 @@ clean_sigs_from_uid(KBNODE keyblock,KBNODE uidnode,int noisy)
    removed.  To "remove" a user ID, we simply remove ALL signatures
    except the self-sig that caused the user ID to be remove-worthy.
    We don't actually remove the user ID packet itself since it might
-   be ressurected in a later merge. */
+   be ressurected in a later merge.
+
+   If this self-sig is a revocation, we also include the most recent
+   valid regular sig since it is hard to import the user ID otherwise.
+   TODO: change the import code to allow importing a uid with only a
+   revocation if the uid already exists on the keyring. */
 int
 clean_uids_from_key(KBNODE keyblock,int noisy)
 {
   int delete_until_next=0,deleted=0;
-  KBNODE node;
+  KBNODE node,signode=NULL;
+  u32 sigdate=0;
 
   assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
 
@@ -1663,6 +1669,12 @@ clean_uids_from_key(KBNODE keyblock,int noisy)
        {
          PKT_user_id *uid=node->pkt->pkt.user_id;
 
+         if(signode && !signode->pkt->pkt.signature->flags.chosen_selfsig)
+           undelete_kbnode(signode);
+
+         sigdate=0;
+         signode=NULL;
+
          /* Skip valid user IDs, and non-self-signed user IDs if
             --allow-non-selfsigned-uid is set. */
          if(uid->created
@@ -1694,12 +1706,27 @@ clean_uids_from_key(KBNODE keyblock,int noisy)
                }
            }
        }
-      else if(node->pkt->pkttype==PKT_SIGNATURE
-             && delete_until_next
-             && !node->pkt->pkt.signature->flags.chosen_selfsig)
-       delete_kbnode(node);
+      else if(node->pkt->pkttype==PKT_SIGNATURE)
+       {
+         PKT_signature *sig=node->pkt->pkt.signature;
+
+         /* This isn't actually slow - the key signature validation
+            is cached from merge_keys_and_selfsig() */
+         if(IS_UID_SIG(sig) && sig->timestamp>sigdate
+            && check_key_signature(keyblock,node,NULL)==0)
+           {
+             sigdate=sig->timestamp;
+             signode=node;
+           }
+
+         if(delete_until_next && !sig->flags.chosen_selfsig)
+           delete_kbnode(node);
+       }
     }
-    
+
+  if(signode && !signode->pkt->pkt.signature->flags.chosen_selfsig)
+    undelete_kbnode(signode);
+
   return deleted;
 }