diff options
Diffstat (limited to 'g10/getkey.c')
-rw-r--r-- | g10/getkey.c | 80 |
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 */ + } } } } |