gnupg/g10 (ChangeLog keyedit.c trustdb.c trustdb.h)
cvs user dshaw
cvs at cvs.gnupg.org
Sun Apr 24 20:18:12 CEST 2005
Date: Sunday, April 24, 2005 @ 20:35:30
Author: dshaw
Path: /cvs/gnupg/gnupg/g10
Modified: ChangeLog keyedit.c trustdb.c trustdb.h
* trustdb.h, trustdb.c (mark_usable_uid_certs): Add flags for the
no-pubkey and chosen revocation cases. (clean_uid): New function to
clean a user ID of unusable (as defined by mark_usable_uid_certs)
certs.
* keyedit.c (keyedit_menu, menu_clean_uids): Call it here for new
"clean" command that removes unusable sigs from a key.
-----------+
ChangeLog | 8 ++++
keyedit.c | 65 ++++++++++++++++++++++++++++++++---
trustdb.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++---------
trustdb.h | 2 +
4 files changed, 164 insertions(+), 21 deletions(-)
Index: gnupg/g10/ChangeLog
diff -u gnupg/g10/ChangeLog:1.725 gnupg/g10/ChangeLog:1.726
--- gnupg/g10/ChangeLog:1.725 Sun Apr 24 18:05:41 2005
+++ gnupg/g10/ChangeLog Sun Apr 24 20:35:30 2005
@@ -1,5 +1,13 @@
2005-04-24 David Shaw <dshaw at jabberwocky.com>
+ * trustdb.h, trustdb.c (mark_usable_uid_certs): Add flags for the
+ no-pubkey and chosen revocation cases.
+ (clean_uid): New function to clean a user ID of unusable (as
+ defined by mark_usable_uid_certs) certs.
+
+ * keyedit.c (keyedit_menu, menu_clean_uids): Call it here for new
+ "clean" command that removes unusable sigs from a key.
+
* trustdb.h, keyedit.c (keyedit_menu, menu_select_uid_namehash):
Allow specifying user ID via the namehash from --with-colons
--fixed-list-mode --list-keys. Suggested by Peter Palfrader.
Index: gnupg/g10/keyedit.c
diff -u gnupg/g10/keyedit.c:1.177 gnupg/g10/keyedit.c:1.178
--- gnupg/g10/keyedit.c:1.177 Sun Apr 24 18:05:41 2005
+++ gnupg/g10/keyedit.c Sun Apr 24 20:35:30 2005
@@ -53,6 +53,7 @@
static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock, int photo );
static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock );
static int menu_delsig( KBNODE pub_keyblock );
+static int menu_clean_uids(KBNODE keyblock);
static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
static int menu_addrevoker( KBNODE pub_keyblock,
KBNODE sec_keyblock, int sensitive );
@@ -1327,7 +1328,7 @@
cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
cmdEXPIRE, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF,
cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
- cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdNOP
+ cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCLEAN, cmdNOP
};
static struct
@@ -1426,6 +1427,7 @@
{ "enable" , cmdENABLEKEY , KEYEDIT_NOT_SK, N_("enable key") },
{ "disable" , cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key") },
{ "showphoto",cmdSHOWPHOTO , 0, N_("show selected photo IDs") },
+ { "clean", cmdCLEAN , KEYEDIT_NOT_SK, NULL },
{ NULL, cmdNONE, 0, NULL }
};
@@ -1952,7 +1954,7 @@
{
int sensitive=0;
- if(arg_string && ascii_strcasecmp(arg_string,"sensitive")==0)
+ if(ascii_strcasecmp(arg_string,"sensitive")==0)
sensitive=1;
if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
redisplay = 1;
@@ -2123,9 +2125,27 @@
}
break;
- case cmdSHOWPHOTO:
- menu_showphoto(keyblock);
- break;
+ case cmdSHOWPHOTO:
+ menu_showphoto(keyblock);
+ break;
+
+ case cmdCLEAN:
+ {
+ if(*arg_string)
+ {
+ if(ascii_strcasecmp(arg_string,"sigs")!=0
+ && ascii_strcasecmp(arg_string,"signatures")!=0
+ && ascii_strcasecmp(arg_string,"certs")!=0
+ && ascii_strcasecmp(arg_string,"certificates")!=0)
+ {
+ tty_printf(_("Unable to clean `%s'\n"),arg_string);
+ break;
+ }
+ }
+
+ modified=menu_clean_uids(keyblock);
+ }
+ break;
case cmdQUIT:
if( have_commands )
@@ -3108,6 +3128,41 @@
return changed;
}
+static int
+menu_clean_uids(KBNODE keyblock)
+{
+ KBNODE uidnode;
+ int modified=0;
+ int select_all=!count_selected_uids(keyblock);
+
+ for(uidnode=keyblock;uidnode;uidnode=uidnode->next)
+ {
+ if(uidnode->pkt->pkttype==PKT_USER_ID
+ && (uidnode->flag&NODFLG_SELUID || select_all))
+ {
+ int deleted;
+ char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
+ uidnode->pkt->pkt.user_id->len,
+ 0);
+ deleted=clean_uid(keyblock,uidnode,opt.verbose);
+ if(deleted)
+ {
+ tty_printf(deleted==1?
+ _("User ID \"%s\": %d signature removed.\n"):
+ _("User ID \"%s\": %d signatures removed.\n"),
+ user,deleted);
+ modified=1;
+ }
+ else
+ tty_printf(_("User ID \"%s\": already clean.\n"),user);
+
+ m_free(user);
+ }
+ }
+
+ return modified;
+}
+
/****************
* Remove some of the secondary keys
Index: gnupg/g10/trustdb.c
diff -u gnupg/g10/trustdb.c:1.137 gnupg/g10/trustdb.c:1.138
--- gnupg/g10/trustdb.c:1.137 Sun Feb 6 18:38:43 2005
+++ gnupg/g10/trustdb.c Sun Apr 24 20:35:30 2005
@@ -1,6 +1,6 @@
/* trustdb.c
- * 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.
*
@@ -1409,8 +1409,9 @@
* To do this, we first revmove all signatures which are not valid and
* from the remain ones we look for the latest one. If this is not a
* certification revocation signature we mark the signature by setting
- * node flag bit 8. Note that flag bits 9 and 10 are used for internal
- * purposes.
+ * node flag bit 8. Revocations are marked with flag 11, and sigs
+ * from unavailable keys are marked with flag 12. Note that flag bits
+ * 9 and 10 are used for internal purposes.
*/
static void
mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode,
@@ -1423,34 +1424,44 @@
/* first check all signatures */
for (node=uidnode->next; node; node = node->next)
{
- node->flag &= ~(1<<8 | 1<<9 | 1<<10);
+ int rc;
+
+ node->flag &= ~(1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12);
if (node->pkt->pkttype == PKT_USER_ID
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
break; /* ready */
if (node->pkt->pkttype != PKT_SIGNATURE)
continue;
-
sig = node->pkt->pkt.signature;
- if (sig->keyid[0] == main_kid[0] && sig->keyid[1] == main_kid[1])
- continue; /* ignore self-signatures */
+ if (main_kid
+ && sig->keyid[0] == main_kid[0] && sig->keyid[1] == main_kid[1])
+ continue; /* ignore self-signatures if we pass in a main_kid */
if (!IS_UID_SIG(sig) && !IS_UID_REV(sig))
continue; /* we only look at these signature classes */
if(sig->sig_class>=0x11 && sig->sig_class<=0x13 &&
sig->sig_class-0x10<opt.min_cert_level)
- continue;
- if (!is_in_klist (klist, sig))
+ continue; /* treat anything under our min_cert_level as an
+ invalid signature */
+ if (klist && !is_in_klist (klist, sig))
continue; /* no need to check it then */
- if (check_key_signature (keyblock, node, NULL))
- continue; /* ignore invalid signatures */
+ if ((rc=check_key_signature (keyblock, node, NULL)))
+ {
+ /* we ignore anything that won't verify, but tag the
+ no_pubkey case */
+ if(rc==G10ERR_NO_PUBKEY)
+ node->flag |= 1<<12;
+ continue;
+ }
node->flag |= 1<<9;
}
/* reset the remaining flags */
for (; node; node = node->next)
- node->flag &= ~(1<<8 | 1<<9 | 1 << 10);
+ node->flag &= ~(1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12);
/* kbnode flag usage: bit 9 is here set for signatures to consider,
* bit 10 will be set by the loop to keep track of keyIDs already
- * processed, bit 8 will be set for the usable signatures */
+ * processed, bit 8 will be set for the usable signatures, and bit
+ * 11 will be set for usable revocations. */
/* for each cert figure out the latest valid one */
for (node=uidnode->next; node; node = node->next)
@@ -1458,7 +1469,7 @@
KBNODE n, signode;
u32 kid[2];
u32 sigdate;
-
+
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
break;
if ( !(node->flag & (1<<9)) )
@@ -1470,6 +1481,8 @@
signode = node;
sigdate = sig->timestamp;
kid[0] = sig->keyid[0]; kid[1] = sig->keyid[1];
+
+ /* Now find the latest and greatest signature */
for (n=uidnode->next; n; n = n->next)
{
if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY)
@@ -1532,6 +1545,7 @@
sigdate = sig->timestamp;
}
}
+
sig = signode->pkt->pkt.signature;
if (IS_UID_SIG (sig))
{ /* this seems to be a usable one which is not revoked.
@@ -1550,11 +1564,75 @@
if (expire==0 || expire > curtime )
{
signode->flag |= (1<<8); /* yeah, found a good cert */
- if (expire && expire < *next_expire)
+ if (next_expire && expire && expire < *next_expire)
*next_expire = expire;
}
}
+ else
+ signode->flag |= (1<<11);
+ }
+}
+
+int
+clean_uid(KBNODE keyblock,KBNODE uidnode,int noisy)
+{
+ int deleted=0;
+ KBNODE node;
+
+ assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
+
+ /* Passing in a 0 for current time here means that we'll never weed
+ out an expired sig. This is correct behavior since we want to
+ keep the most recent expired sig in a series. */
+ mark_usable_uid_certs(keyblock,uidnode,NULL,NULL,0,NULL);
+
+ /* What we want to do here is remove signatures that are not
+ considered as part of the trust calculations. Thus, all invalid
+ signatures are out, as are any signatures that aren't the last of
+ a series of uid sigs or revocations It breaks down like this:
+ coming out of mark_usable_uid_certs, if a sig is unflagged, it is
+ not even a candidate. If a sig has flag 9 or 10, that means it
+ was selected as a candidate and vetted. If a sig has flag 8 it
+ is a usable signature. If a sig has flag 11 it is a usable
+ revocation. If a sig has flag 12 it was issued by an unavailable
+ key. "Usable" here means the most recent valid
+ signature/revocation in a series from a particular signer.
+
+ Delete everything that isn't a usable uid sig (which might be
+ expired), a usable revocation, or a sig from an unavailable
+ key. */
+
+ for(node=uidnode->next;
+ node && node->pkt->pkttype==PKT_SIGNATURE;
+ node=node->next)
+ {
+ /* Keep usable uid sigs ... */
+ if(node->flag & (1<<8))
+ continue;
+
+ /* ... and usable revocations... */
+ if(node->flag & (1<<11))
+ continue;
+
+ /* ... and sigs from unavailable keys. */
+ if(node->flag & (1<<12))
+ continue;
+
+ /* Everything else we delete */
+
+ /* if 9 or 10 is set, but we get this far, it's superceded,
+ otherwise, it's invalid */
+
+ if(noisy)
+ log_info("removing signature issued by key %s: %s\n",
+ keystr(node->pkt->pkt.signature->keyid),
+ node->flag&(1<<9)?"superceded":"invalid");
+
+ delete_kbnode(node);
+ deleted++;
}
+
+ return deleted;
}
/* Used by validate_one_keyblock to confirm a regexp within a trust
Index: gnupg/g10/trustdb.h
diff -u gnupg/g10/trustdb.h:1.51 gnupg/g10/trustdb.h:1.52
--- gnupg/g10/trustdb.h:1.51 Sun Apr 24 18:05:41 2005
+++ gnupg/g10/trustdb.h Sun Apr 24 20:35:30 2005
@@ -81,6 +81,8 @@
void update_ownertrust (PKT_public_key *pk, unsigned int new_trust );
int clear_ownertrusts (PKT_public_key *pk);
+int clean_uid(KBNODE keyblock,KBNODE uidnode,int noisy);
+
/*-- tdbdump.c --*/
void list_trustdb(const char *username);
void export_ownertrust(void);
More information about the Gnupg-commits
mailing list