From 0d2a5aeeb4120999afc79d06619d90e26e2fec5c Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Sun, 4 Mar 2007 15:37:43 +0000 Subject: [PATCH] Fix assumption that a signature on a public key is a revocation We've been assuming that a signature directly on a public key means the key is revoked. This isn't the case; it's used for key preferences for example. Change the structure element names to reflect this (revocations->sigs) and check for revoked status by looking for a signature type of 0x20. --- keydb.c | 4 ++-- keydb_dynamic.c | 4 ++-- keyindex.c | 8 +++----- keystructs.h | 8 +++++--- mem.c | 6 +++--- merge.c | 30 +++++++++++++++++++----------- parsekey.c | 26 +++++++++++++++++++++----- 7 files changed, 55 insertions(+), 31 deletions(-) diff --git a/keydb.c b/keydb.c index 300e9b9..7d33108 100644 --- a/keydb.c +++ b/keydb.c @@ -82,7 +82,7 @@ struct ll *getkeysigs(uint64_t keyid, bool *revoked) sigs = keysigs(sigs, uids->sigs); } if (revoked != NULL) { - *revoked = (publickey->revocations != NULL); + *revoked = publickey->revoked; } free_publickey(publickey); } @@ -188,7 +188,7 @@ int update_keys(struct openpgp_publickey **keys, bool sendsync) */ if (oldkey != NULL) { merge_keys(oldkey, curkey); - if (curkey->revocations == NULL && + if (curkey->sigs == NULL && curkey->uids == NULL && curkey->subkeys == NULL) { if (prev == NULL) { diff --git a/keydb_dynamic.c b/keydb_dynamic.c index 6907144..49d77b8 100644 --- a/keydb_dynamic.c +++ b/keydb_dynamic.c @@ -203,7 +203,7 @@ struct ll *getkeysigs(uint64_t keyid, bool *revoked) sigs = keysigs(sigs, uids->sigs); } if (revoked != NULL) { - *revoked = (publickey->revocations != NULL); + *revoked = publickey->revoked; } free_publickey(publickey); } @@ -342,7 +342,7 @@ int update_keys(struct openpgp_publickey **keys, bool sendsync) */ if (oldkey != NULL) { merge_keys(oldkey, curkey); - if (curkey->revocations == NULL && + if (curkey->sigs == NULL && curkey->uids == NULL && curkey->subkeys == NULL) { if (prev == NULL) { diff --git a/keyindex.c b/keyindex.c index 0732a11..64c99a3 100644 --- a/keyindex.c +++ b/keyindex.c @@ -268,8 +268,7 @@ int key_index(struct openpgp_publickey *keys, bool verbose, bool fingerprint, printf("%s%s%s\n", (html) ? txt2html(buf) : buf, (html) ? "" : "", - (keys->revocations == NULL) ? "" : - " *** REVOKED ***"); + (keys->revoked) ? " *** REVOKED ***" : ""); if (fingerprint) { display_fingerprint(keys); } @@ -279,8 +278,7 @@ int key_index(struct openpgp_publickey *keys, bool verbose, bool fingerprint, curuid = curuid->next; } else { printf("%s\n", - (keys->revocations == NULL) ? "" : - "*** REVOKED ***"); + (keys->revoked) ? "*** REVOKED ***": ""); if (fingerprint) { display_fingerprint(keys); } @@ -354,7 +352,7 @@ int mrkey_index(struct openpgp_publickey *keys) type, length, created_time, - (keys->revocations == NULL) ? "" : "r"); + (keys->revoked) ? "r" : ""); for (curuid = keys->uids; curuid != NULL; curuid = curuid->next) { diff --git a/keystructs.h b/keystructs.h index 6c36bbe..33c6226 100644 --- a/keystructs.h +++ b/keystructs.h @@ -65,15 +65,17 @@ struct openpgp_signedpacket_list { /** * struct openpgp_publickey - An OpenPGP public key complete with sigs. * @publickey: The OpenPGP packet for the public key. - * @revocation: The OpenPGP packet for the revocation [optional] + * @revoked: True if the key is revoked. + * @sigs: Any signatures directly on the publickey packet. * @uids: The list of UIDs with signatures for this key. * @subkeys: The list of subkeys with signatures for this key. * @next: The next public key. */ struct openpgp_publickey { struct openpgp_packet *publickey; - struct openpgp_packet_list *revocations; - struct openpgp_packet_list *last_revocation; + bool revoked; + struct openpgp_packet_list *sigs; + struct openpgp_packet_list *last_sig; struct openpgp_signedpacket_list *uids; struct openpgp_signedpacket_list *last_uid; struct openpgp_signedpacket_list *subkeys; diff --git a/mem.c b/mem.c index 00507ab..47f2967 100644 --- a/mem.c +++ b/mem.c @@ -150,9 +150,9 @@ void free_publickey(struct openpgp_publickey *key) { free_packet(key->publickey); key->publickey = NULL; } - if (key->revocations != NULL) { - free_packet_list(key->revocations); - key->revocations = NULL; + if (key->sigs != NULL) { + free_packet_list(key->sigs); + key->sigs = NULL; } if (key->uids != NULL) { free_signedpacket_list(key->uids); diff --git a/merge.c b/merge.c index 4379596..87f45fc 100644 --- a/merge.c +++ b/merge.c @@ -314,12 +314,12 @@ int merge_keys(struct openpgp_publickey *a, struct openpgp_publickey *b) /* * Key IDs are the same, so I guess we have to merge them. */ - curpacket = b->revocations; + curpacket = b->sigs; while (curpacket != NULL) { nextpacket = curpacket->next; - if (find_packet(a->revocations, curpacket->packet)) { + if (find_packet(a->sigs, curpacket->packet)) { /* - * We already have this revocation, remove it + * We already have this signature, remove it * from the difference list and free the memory * allocated for it. */ @@ -327,8 +327,8 @@ int merge_keys(struct openpgp_publickey *a, struct openpgp_publickey *b) if (lastpacket != NULL) { lastpacket->next = curpacket->next; } else { - log_assert(curpacket == b->revocations); - b->revocations = curpacket->next; + log_assert(curpacket == b->sigs); + b->sigs = curpacket->next; } curpacket->next = NULL; free_packet_list(curpacket); @@ -338,15 +338,15 @@ int merge_keys(struct openpgp_publickey *a, struct openpgp_publickey *b) } curpacket = nextpacket; } - b->last_revocation = lastpacket; + b->last_sig = lastpacket; /* - * Anything left on b->revocations doesn't exist on - * a->revocations, so add them to the list. + * Anything left on b->sigs doesn't exist on + * a->sigs, so add them to the list. */ - packet_list_add(&a->revocations, - &a->last_revocation, - b->revocations); + packet_list_add(&a->sigs, + &a->last_sig, + b->sigs); /* * Merge uids (signed list). @@ -359,5 +359,13 @@ int merge_keys(struct openpgp_publickey *a, struct openpgp_publickey *b) } + /* + * If either key was revoked, make sure both the new ones are marked as + * being so. + */ + if (a->revoked || b->revoked) { + a->revoked = b->revoked = true; + } + return rc; } diff --git a/parsekey.c b/parsekey.c index 687fd9b..6e080af 100644 --- a/parsekey.c +++ b/parsekey.c @@ -48,8 +48,7 @@ int parse_keys(struct openpgp_packet_list *packets, case 2: /* * It's a signature packet. Add it to either the public - * key (it should be a revocation), to the current UID - * or the current subkey. + * key, to the current UID or the current subkey. */ log_assert(curkey != NULL); if (curkey->subkeys != NULL) { @@ -62,8 +61,25 @@ int parse_keys(struct openpgp_packet_list *packets, packet_dup(packets->packet)); } else { ADD_PACKET_TO_LIST_END(curkey, - revocation, + sig, packet_dup(packets->packet)); + /* + * This is a signature on the public key; check + * if it's a revocation. + */ + if (packets->packet->data[0] == 3 && + packets->packet->data[2] == 0x20) { + /* + * Type 3 key, 0x20 == revocation + */ + curkey->revoked = true; + } else if (packets->packet->data[0] == 4 && + packets->packet->data[1] == 0x20) { + /* + * Type 4 key, 0x20 == revocation + */ + curkey->revoked = true; + } } break; case 6: @@ -416,9 +432,9 @@ int flatten_publickey(struct openpgp_publickey *key, } /* - * Now do any revocation signatures on the main key. + * Now do any signatures on the main key. */ - for (tmplist = key->revocations; tmplist != NULL; + for (tmplist = key->sigs; tmplist != NULL; tmplist = tmplist->next) { ADD_PACKET_TO_LIST((*list_end), packet_dup(tmplist->packet)); -- 2.39.2