aboutsummaryrefslogtreecommitdiffstats
path: root/g10/getkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/getkey.c')
-rw-r--r--g10/getkey.c80
1 files changed, 62 insertions, 18 deletions
diff --git a/g10/getkey.c b/g10/getkey.c
index fe98d49a0..e5facda96 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.
*
@@ -1331,7 +1332,6 @@ 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;
-
}
static void
@@ -1694,14 +1694,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 ) {
@@ -1716,23 +1740,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 */
+ }
}
}
}