aboutsummaryrefslogtreecommitdiffstats
path: root/g10/getkey.c
diff options
context:
space:
mode:
authorDavid Shaw <[email protected]>2003-05-21 16:42:22 +0000
committerDavid Shaw <[email protected]>2003-05-21 16:42:22 +0000
commit2e821d77f739d0363c0e3d7beb4332837b0c6f2d (patch)
tree84ca9f1f804063baee26c7aa57f7c229fd86f983 /g10/getkey.c
parent* fileutil.c (is_file_compressed): Fixed checking for "-" filename. (diff)
downloadgnupg-2e821d77f739d0363c0e3d7beb4332837b0c6f2d.tar.gz
gnupg-2e821d77f739d0363c0e3d7beb4332837b0c6f2d.zip
* trustdb.h, trustdb.c (is_disabled), gpgv.c (is_disabled): Rename
is_disabled to cache_disabled_value, which now takes a pk and not just the keyid. This is for speed since there is no need to re-fetch a key when we already have that key handy. Cache the result of the check so we don't need to hit the trustdb more than once. * getkey.c (skip_disabled): New function to get a pk and call is_disabled on it. (key_byname): Use it here. * packet.h, getkey.c (skip_disabled), keylist.c (print_capabilities): New "pk_is_disabled" macro to retrieve the cached disabled value if available, and fill it in via cache_disabled_value if not available. * trustdb.c (get_validity): Cache the disabled value since we have it handy and it might be useful later. * parse-packet.c (parse_key): Clear disabled flag when parsing a new key. Just in case someone forgets to clear the whole key. * getkey.c (merge_selfsigs_main): Add an "if all else fails" path for setting a single user ID primary when there are multiple set primaries all at the same second, or no primaries set and the most recent user IDs are at the same second, or no signed user IDs at all. This is arbitrary, but deterministic. * exec.h, photoid.h: Add copyright message. * keylist.c (list_keyblock_print): Don't dump attribs for revoked/expired/etc uids for non-colon key listings. This is for consistency with --show-photos. * main.h, keylist.c (dump_attribs), mainproc.c (check_sig_and_print): Dump attribs if --attrib-fd is set when verifying signatures. * g10.c (main): New --gnupg option to disable the various --openpgp, --pgpX, etc. options. This is the same as --no-XXXX for those options. * revoke.c (ask_revocation_reason): Clear old reason if user elects to repeat question. This is bug 153. * keyedit.c (sign_uids): Show keyid of the key making the signature.
Diffstat (limited to '')
-rw-r--r--g10/getkey.c104
1 files changed, 85 insertions, 19 deletions
diff --git a/g10/getkey.c b/g10/getkey.c
index 86898141c..44e571ce4 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -1,5 +1,6 @@
/* getkey.c - Get a key from the database
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ * 2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -724,6 +725,27 @@ classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc )
}
+static int
+skip_disabled(void *dummy,u32 *keyid)
+{
+ int rc,disabled=0;
+ PKT_public_key *pk=m_alloc_clear(sizeof(PKT_public_key));
+
+ rc = get_pubkey(pk, keyid);
+ if(rc)
+ {
+ log_error("error checking disabled status of %08lX: %s\n",
+ (ulong)keyid[1],g10_errstr(rc));
+ goto leave;
+ }
+
+ disabled=pk_is_disabled(pk);
+
+ leave:
+ free_public_key(pk);
+ return disabled;
+}
+
/****************
* Try to get the pubkey by the userid. This function looks for the
* first pubkey certificate which has the given name in a user_id.
@@ -774,7 +796,7 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
&& ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR16
&& ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR20
&& ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR)
- ctx->items[n].skipfnc=is_disabled;
+ ctx->items[n].skipfnc=skip_disabled;
}
ctx->kr_handle = keydb_new (secmode);
@@ -1296,12 +1318,12 @@ fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated )
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n);
if (p && n && (p[0] & 0x01))
uid->mdc_feature = 1;
+
/* and the keyserver modify flag */
uid->ks_modify = 1;
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KS_FLAGS, &n);
if (p && n && (p[0] & 0x80))
uid->ks_modify = 0;
-
}
static void
@@ -1670,14 +1692,38 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
if ( k->pkt->pkttype == PKT_USER_ID &&
!k->pkt->pkt.user_id->attrib_data) {
PKT_user_id *uid = k->pkt->pkt.user_id;
- if ( uid->is_primary && uid->created > uiddate ) {
- uiddate = uid->created;
- uidnode = k;
- }
- if ( !uid->is_primary && uid->created > uiddate2 ) {
- uiddate2 = uid->created;
- uidnode2 = k;
- }
+ if (uid->is_primary)
+ {
+ if(uid->created > uiddate)
+ {
+ uiddate = uid->created;
+ uidnode = k;
+ }
+ else if(uid->created==uiddate && uidnode)
+ {
+ /* The dates are equal, so we need to do a
+ different (and arbitrary) comparison. This
+ should rarely, if ever, happen. It's good to
+ try and guarantee that two different GnuPG
+ users with two different keyrings at least pick
+ the same primary. */
+ if(cmp_user_ids(uid,uidnode->pkt->pkt.user_id)>0)
+ uidnode=k;
+ }
+ }
+ else
+ {
+ if(uid->created > uiddate2)
+ {
+ uiddate2 = uid->created;
+ uidnode2 = k;
+ }
+ else if(uid->created==uiddate2 && uidnode2)
+ {
+ if(cmp_user_ids(uid,uidnode2->pkt->pkt.user_id)>0)
+ uidnode2=k;
+ }
+ }
}
}
if ( uidnode ) {
@@ -1692,23 +1738,43 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
}
}
else if( uidnode2 ) {
- /* none is flagged primary - use the latest user ID we have */
+ /* none is flagged primary - use the latest user ID we have,
+ and disambiguate with the arbitrary packet comparison. */
uidnode2->pkt->pkt.user_id->is_primary = 1;
}
else
{
- /* None of our uids were self-signed, so pick the first one to
- be the primary. This is the best we can do here since
- there are no self sigs to date the uids. */
+ /* None of our uids were self-signed, so pick the one that
+ sorts first to be the primary. This is the best we can do
+ here since there are no self sigs to date the uids. */
+
+ uidnode = NULL;
for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
k = k->next )
{
- if(k->pkt->pkttype==PKT_USER_ID &&
- !k->pkt->pkt.user_id->attrib_data)
+ if(k->pkt->pkttype==PKT_USER_ID
+ && !k->pkt->pkt.user_id->attrib_data)
{
- k->pkt->pkt.user_id->is_primary=1;
- break;
+ if(!uidnode)
+ {
+ uidnode=k;
+ uidnode->pkt->pkt.user_id->is_primary=1;
+ continue;
+ }
+ else
+ {
+ if(cmp_user_ids(k->pkt->pkt.user_id,
+ uidnode->pkt->pkt.user_id)>0)
+ {
+ uidnode->pkt->pkt.user_id->is_primary=0;
+ uidnode=k;
+ uidnode->pkt->pkt.user_id->is_primary=1;
+ }
+ else
+ k->pkt->pkt.user_id->is_primary=0; /* just to be
+ safe */
+ }
}
}
}