* trustdb.h, trustdb.c (clean_subkeys_from_key): New. Walk through
authorDavid Shaw <dshaw@jabberwocky.com>
Tue, 31 May 2005 03:59:24 +0000 (03:59 +0000)
committerDavid Shaw <dshaw@jabberwocky.com>
Tue, 31 May 2005 03:59:24 +0000 (03:59 +0000)
the subkeys on a key, and mark any that aren't usable for deletion.
Note that a signing subkey is never marked for deletion since these
keys are still useful after expiration or revocation.

* keyedit.c (menu_clean_subkeys_from_key): New function to call
clean_subkeys_from_key() on a key.  Note that the strings here are not
marked for translation yet.  The UI is still in flux, and there is no
point in annoying the translators twice.  (keyedit_menu): Call it here
as part of the "clean" command.

g10/ChangeLog
g10/keyedit.c
g10/trustdb.c
g10/trustdb.h

index 2250bc9..ad94ca7 100644 (file)
@@ -1,3 +1,16 @@
+2005-05-30  David Shaw  <dshaw@jabberwocky.com>
+
+       * trustdb.h, trustdb.c (clean_subkeys_from_key): New.  Walk
+       through the subkeys on a key, and mark any that aren't usable for
+       deletion.  Note that a signing subkey is never marked for deletion
+       since these keys are still useful after expiration or revocation.
+
+       * keyedit.c (menu_clean_subkeys_from_key): New function to call
+       clean_subkeys_from_key() on a key.  Note that the strings here are
+       not marked for translation yet.  The UI is still in flux, and
+       there is no point in annoying the translators twice.
+       (keyedit_menu): Call it here as part of the "clean" command.
+
 2005-05-29  David Shaw  <dshaw@jabberwocky.com>
 
        * trustdb.h, trustdb.c (clean_uids_from_key): New.  Walk through
index d85c888..7412049 100644 (file)
@@ -55,6 +55,7 @@ static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock );
 static int  menu_delsig( KBNODE pub_keyblock );
 static int menu_clean_sigs_from_uids(KBNODE keyblock);
 static int menu_clean_uids_from_key(KBNODE keyblock);
+static int menu_clean_subkeys_from_key(KBNODE keyblock);
 static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
 static int menu_addrevoker( KBNODE pub_keyblock,
                            KBNODE sec_keyblock, int sensitive );
@@ -2146,18 +2147,21 @@ keyedit_menu( const char *username, STRLIST locusr,
                    modified=menu_clean_sigs_from_uids(keyblock);
                  else if(ascii_strcasecmp(arg_string,"uids")==0)
                    redisplay=modified=menu_clean_uids_from_key(keyblock);
+                 else if(ascii_strcasecmp(arg_string,"subkeys")==0)
+                   redisplay=modified=menu_clean_subkeys_from_key(keyblock);
                  else if(ascii_strcasecmp(arg_string,"all")==0)
                    {
                      modified=menu_clean_sigs_from_uids(keyblock);
                      modified+=menu_clean_uids_from_key(keyblock);
+                     modified+=menu_clean_subkeys_from_key(keyblock);
                      redisplay=modified;
                    }
                  else
-                   tty_printf(_("Unable to clean `%s'\n"),arg_string);
+                   tty_printf("Unable to clean `%s'\n",arg_string);
                }
              else
-               tty_printf(_("Please specify item to clean: `sigs',"
-                            " `uids', or `all'\n"));
+               tty_printf("Please specify item to clean: `sigs',"
+                          " `uids', `subkeys', or `all'\n");
            }
            break;
 
@@ -2549,7 +2553,8 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
     /* the keys */
     for( node = keyblock; node; node = node->next ) {
        if( node->pkt->pkttype == PKT_PUBLIC_KEY
-           || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) {
+           || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+               && !is_deleted_kbnode(node)) ) {
            PKT_public_key *pk = node->pkt->pkt.public_key;
            const char *otrust="err",*trust="err";
 
@@ -3150,7 +3155,7 @@ menu_clean_sigs_from_uids(KBNODE keyblock)
   int modified=0;
   int select_all=!count_selected_uids(keyblock);
 
-  for(uidnode=keyblock;uidnode;uidnode=uidnode->next)
+  for(uidnode=keyblock->next;uidnode;uidnode=uidnode->next)
     {
       if(uidnode->pkt->pkttype==PKT_USER_ID
         && (uidnode->flag&NODFLG_SELUID || select_all))
@@ -3163,8 +3168,8 @@ menu_clean_sigs_from_uids(KBNODE keyblock)
          if(deleted)
            {
              tty_printf(deleted==1?
-                        _("User ID \"%s\": %d signature removed.\n"):
-                        _("User ID \"%s\": %d signatures removed.\n"),
+                        "User ID \"%s\": %d signature removed.\n":
+                        "User ID \"%s\": %d signatures removed.\n",
                         user,deleted);
              modified=1;
            }
@@ -3182,9 +3187,7 @@ static int
 menu_clean_uids_from_key(KBNODE keyblock)
 {
   KBNODE node;
-  int modified;
-
-  modified=clean_uids_from_key(keyblock,opt.verbose);
+  int modified=clean_uids_from_key(keyblock,0);
 
   if(modified)
     {
@@ -3203,14 +3206,46 @@ menu_clean_uids_from_key(KBNODE keyblock)
              else
                reason=_("invalid");
 
-             tty_printf(_("User ID \"%s\" removed: %s\n"),user,reason);
+             tty_printf("User ID \"%s\" removed: %s\n",user,reason);
 
              m_free(user);
            }
        }
     }
   else
-    tty_printf(_("No user IDs are removable.\n"));
+    tty_printf("No user IDs are removable.\n");
+
+  return modified;
+}
+
+static int
+menu_clean_subkeys_from_key(KBNODE keyblock)
+{
+  KBNODE node;
+  int modified=clean_subkeys_from_key(keyblock,0);
+
+  if(modified)
+    {
+      for(node=keyblock->next;node;node=node->next)
+       {
+         if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY && is_deleted_kbnode(node))
+           {
+             char *reason;
+
+             if(node->pkt->pkt.public_key->is_revoked)
+               reason=_("revoked");
+             else if(node->pkt->pkt.public_key->has_expired)
+               reason=_("expired");
+             else
+               reason=_("invalid");
+
+             tty_printf("Subkey %s removed: %s\n",
+                        keystr(node->pkt->pkt.public_key->keyid),reason);
+           }
+       }
+    }
+  else
+    tty_printf("No subkeys are removable.\n");
 
   return modified;
 }
index f690557..d5e4e23 100644 (file)
@@ -1644,7 +1644,7 @@ clean_sigs_from_uid(KBNODE keyblock,KBNODE uidnode,int noisy)
 int
 clean_uids_from_key(KBNODE keyblock,int noisy)
 {
-  int uidcount=0,delete_until_next,deleted=0;
+  int uidcount=0,delete_until_next=0,deleted=0;
   KBNODE node;
 
   assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
@@ -1667,11 +1667,12 @@ clean_uids_from_key(KBNODE keyblock,int noisy)
     {
       if(node->pkt->pkttype==PKT_USER_ID)
        {
+         PKT_user_id *uid=node->pkt->pkt.user_id;
+
          /* Skip valid user IDs, and non-self-signed user IDs if
             --allow-non-selfsigned-uid is set. */
-         if(node->pkt->pkt.user_id->created
-            || (!node->pkt->pkt.user_id->is_expired
-                && !node->pkt->pkt.user_id->is_revoked
+         if(uid->created
+            || (!uid->is_expired && !uid->is_revoked 
                 && opt.allow_non_selfsigned_uid))
            delete_until_next=0;
          else
@@ -1682,12 +1683,11 @@ clean_uids_from_key(KBNODE keyblock,int noisy)
              if(noisy)
                {
                  char *reason;
-                 char *user=utf8_to_native(node->pkt->pkt.user_id->name,
-                                           node->pkt->pkt.user_id->len,0);
+                 char *user=utf8_to_native(uid->name,uid->len,0);
 
-                 if(node->pkt->pkt.user_id->is_revoked)
+                 if(uid->is_revoked)
                    reason=_("revoked");
-                 else if(node->pkt->pkt.user_id->is_expired)
+                 else if(uid->is_expired)
                    reason=_("expired");
                  else
                    reason=_("invalid");
@@ -1708,6 +1708,66 @@ clean_uids_from_key(KBNODE keyblock,int noisy)
   return deleted;
 }
 
+/* Another cleaning function.  This only cleans encrypt-only subkeys
+   since an expired/revoked encryption key is basically useless, but
+   an expired/revoked key that can sign is still needed to verify old
+   signatures. */
+int
+clean_subkeys_from_key(KBNODE keyblock,int noisy)
+{
+  int delete_until_next=0,deleted=0;
+  KBNODE node;
+  char *main_key=NULL;
+
+  assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
+
+  merge_keys_and_selfsig(keyblock);
+
+  if(noisy)
+    main_key=m_strdup(keystr(keyblock->pkt->pkt.public_key->keyid));
+
+  for(node=keyblock->next;node;node=node->next)
+    {
+      if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
+       {
+         PKT_public_key *pk=node->pkt->pkt.public_key;
+
+         /* If it is valid, not expired, and not revoked, leave it
+            alone.  If a key can make signatures, leave it alone. */
+         if(pk->pubkey_usage!=PUBKEY_USAGE_ENC
+            || (pk->is_valid && !pk->has_expired && !pk->is_revoked))
+           delete_until_next=0;
+         else
+           {
+             delete_until_next=1;
+             deleted++;
+
+             if(noisy)
+               {
+                 char *reason;
+
+                 if(pk->is_revoked)
+                   reason=_("revoked");
+                 else if(pk->has_expired)
+                   reason=_("expired");
+                 else
+                   reason=_("invalid");
+
+                 log_info("removing subkey %s from key %s: %s\n",
+                          keystr_from_pk(pk),main_key,reason);
+               }
+           }
+       }
+
+      if(delete_until_next)
+       delete_kbnode(node);
+    }
+
+  m_free(main_key);
+
+  return deleted;
+}
+
 /* Used by validate_one_keyblock to confirm a regexp within a trust
    signature.  Returns 1 for match, and 0 for no match or regex
    error. */
index b914063..1e19294 100644 (file)
@@ -83,6 +83,7 @@ int clear_ownertrusts (PKT_public_key *pk);
 
 int clean_sigs_from_uid(KBNODE keyblock,KBNODE uidnode,int noisy);
 int clean_uids_from_key(KBNODE keyblock,int noisy);
+int clean_subkeys_from_key(KBNODE keyblock,int noisy);
 
 /*-- tdbdump.c --*/
 void list_trustdb(const char *username);