]> the.earth.li Git - onak.git/commitdiff
Fix assumption that a signature on a public key is a revocation
authorJonathan McDowell <noodles@earth.li>
Sun, 4 Mar 2007 15:37:43 +0000 (15:37 +0000)
committerJonathan McDowell <noodles@earth.li>
Sun, 4 Mar 2007 15:37:43 +0000 (15:37 +0000)
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
keydb_dynamic.c
keyindex.c
keystructs.h
mem.c
merge.c
parsekey.c

diff --git a/keydb.c b/keydb.c
index 300e9b9a42690654e37b4649b1d06fbc70033c73..7d3310821b4c97febed997c33db58913a6a2f9f0 100644 (file)
--- 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) {
index 6907144581619699780b671e4381975d36004388..49d77b85e110743b93308460e1587fafe22b239c 100644 (file)
@@ -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) {
index 0732a11156eae085c991428fa7f4bd75641be89c..64c99a3f0552b1ae5e6e8179e709c4602bde0145 100644 (file)
@@ -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) ? "</a>" : "",
-                               (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) {
index 6c36bbec6e771ad04df2bd3ca73ee192fe2b7709..33c6226ed77cf925544c2af78ef763580a6a0b7b 100644 (file)
@@ -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 00507ab8424cc321ac58e3f59e163d2390c2d99a..47f296744d3e1c25e93c8cafd5aeaed913d03297 100644 (file)
--- 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 43795966d848cf41e14f42be5127106c667b185b..87f45fca642cba3c1e1eaec9a5788181b5c828b9 100644 (file)
--- 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;
 }
index 687fd9bd8612c6f9a3cd2c41af96e9269368a620..6e080af36dc66493b0208e9d77c93a705a9e8bfc 100644 (file)
@@ -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));