From 6845737736d3264d7ee8b7364d908951010084c9 Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Wed, 16 Sep 2015 15:01:45 +0200 Subject: g10: Be more careful when merging self-signed data. * g10/getkey.c (merge_selfsigs_main): Stop looking for self-signed data belonging to the public key when we encounter an attribute packet or a subkey packet, not just a user id packet. When looking for self-signed data belonging to a user id packet, stop when we see a user attribute packet. -- Signed-off-by: Neal H. Walfield . --- g10/getkey.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/g10/getkey.c b/g10/getkey.c index e430a6f5c..ba29c3dca 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1536,7 +1536,15 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked, signode = NULL; sigdate = 0; /* Helper variable to find the latest signature. */ - for (k = keyblock; k && k->pkt->pkttype != PKT_USER_ID; k = k->next) + + /* According to Section 11.1 of RFC 4880, the public key comes first + and is immediately followed by any signature packets that modify + it. */ + for (k = keyblock; + k && k->pkt->pkttype != PKT_USER_ID + && k->pkt->pkttype != PKT_ATTRIBUTE + && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; + k = k->next) { if (k->pkt->pkttype == PKT_SIGNATURE) { @@ -1694,11 +1702,16 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked, } /* Second pass: Look at the self-signature of all user IDs. */ + + /* According to RFC 4880 section 11.1, user id and attribute packets + are in the second section, after the public key packet and before + the subkey packets. */ signode = uidnode = NULL; sigdate = 0; /* Helper variable to find the latest signature in one UID. */ for (k = keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next) { - if (k->pkt->pkttype == PKT_USER_ID) + if (k->pkt->pkttype == PKT_USER_ID || k->pkt->pkttype == PKT_ATTRIBUTE) + /* New user id packet. */ { if (uidnode && signode) /* Apply the data from the most recent self-signed packet @@ -1707,7 +1720,12 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked, fixup_uidnode (uidnode, signode, keytimestamp); pk->flags.valid = 1; } - uidnode = k; + /* Clear SIGNODE. The only relevant self-signed data for + UIDNODE follows it. */ + if (k->pkt->pkttype == PKT_USER_ID) + uidnode = k; + else + uidnode = NULL; signode = NULL; sigdate = 0; } -- cgit v1.2.3