]> the.earth.li Git - onak.git/commitdiff
Add ability to drop overly large packets
authorJonathan McDowell <noodles@earth.li>
Tue, 9 Apr 2019 19:54:57 +0000 (20:54 +0100)
committerJonathan McDowell <noodles@earth.li>
Tue, 9 Apr 2019 19:54:57 +0000 (20:54 +0100)
As per draft-dkg-openpgp-abuse-resistant-keystore add the ability to
drop "large" packets. These are defined as UIDs more than 1024 bytes
long, UATs greater than 64k in size and all other packets larger than
8383 bytes (the maximum that will fit in a 2 byte new format packet
length). Disabled by default, enable with "check_packet_size" in the
verification config section.

cleankey.c
cleankey.h
onak-conf.c

index 3ef76f9167679b61316f03f817fd81816ac7437c..fe24c3b6a31a7502de8554ce12bf692b3d18dbb5 100644 (file)
@@ -26,7 +26,7 @@
 #include "log.h"
 #include "mem.h"
 #include "merge.h"
-#include "onak-conf.h"
+#include "openpgp.h"
 #include "sigcheck.h"
 
 /**
@@ -179,6 +179,54 @@ int clean_key_sighashes(struct openpgp_publickey *key)
        return removed;
 }
 
+#define UAT_LIMIT      0xFFFF
+#define UID_LIMIT      1024
+#define PACKET_LIMIT   8383            /* Fits in 2 byte packet length */
+int clean_large_packets(struct openpgp_publickey *key)
+{
+       struct openpgp_signedpacket_list **curuid = NULL;
+       struct openpgp_signedpacket_list *tmp = NULL;
+       bool                              drop;
+       int                               dropped = 0;
+
+       log_assert(key != NULL);
+       curuid = &key->uids;
+       while (*curuid != NULL) {
+               drop = false;
+               switch ((*curuid)->packet->tag) {
+               case OPENPGP_PACKET_UID:
+                       if ((*curuid)->packet->length > UID_LIMIT)
+                               drop = true;
+                       break;
+               case OPENPGP_PACKET_UAT:
+                       if ((*curuid)->packet->length > UAT_LIMIT)
+                               drop = true;
+                       break;
+               default:
+                       if ((*curuid)->packet->length > PACKET_LIMIT)
+                               drop = true;
+                       break;
+               }
+
+               if (drop) {
+                       logthing(LOGTHING_INFO,
+                                       "Dropping large (%d) packet, type %d",
+                                       (*curuid)->packet->length,
+                                       (*curuid)->packet->tag);
+                       /* Remove the entire large signed packet list */
+                       tmp = *curuid;
+                       *curuid = (*curuid)->next;
+                       tmp->next = NULL;
+                       free_signedpacket_list(tmp);
+                       dropped++;
+               } else {
+                       curuid = &(*curuid)->next;
+               }
+       }
+
+       return dropped;
+}
+
 /**
  *     cleankeys - Apply all available cleaning options on a list of keys.
  *     @policies: The cleaning policies to apply.
@@ -192,14 +240,17 @@ int clean_key_sighashes(struct openpgp_publickey *key)
 int cleankeys(struct openpgp_publickey **keys, uint64_t policies)
 {
        struct openpgp_publickey *curkey;
-       int changed = 0, count;
+       int changed = 0, count = 0;
 
        if (keys == NULL)
                return 0;
 
        curkey = *keys;
        while (curkey != NULL) {
-               count = dedupuids(curkey);
+               if (policies & ONAK_CLEAN_LARGE_PACKETS) {
+                       count += clean_large_packets(curkey);
+               }
+               count += dedupuids(curkey);
                count += dedupsubkeys(curkey);
                if (policies & ONAK_CLEAN_CHECK_SIGHASH) {
                        count += clean_key_sighashes(curkey);
index 073ef666000af646d7d145296a51fda94f367fda..350e75df329bebc585ec1fc3468683f0804dffa0 100644 (file)
@@ -22,6 +22,7 @@
 #include "keystructs.h"
 
 #define ONAK_CLEAN_CHECK_SIGHASH       (1 << 0)
+#define ONAK_CLEAN_LARGE_PACKETS       (1 << 1)
 #define ONAK_CLEAN_ALL                 (uint64_t) -1
 
 /**
index e6b645c48057bf4bf10fb4143ebcd82f87a1dc14..5a4400315551694d19eadc6c104223dcada44526 100644 (file)
@@ -288,6 +288,15 @@ static bool parseconfigline(char *line)
                                config.clean_policies &=
                                        ~ONAK_CLEAN_CHECK_SIGHASH;
                        }
+               } else if (MATCH("verification", "check_packet_size")) {
+                       if (parsebool(value, config.clean_policies &
+                                       ONAK_CLEAN_LARGE_PACKETS)) {
+                               config.clean_policies |=
+                                       ONAK_CLEAN_LARGE_PACKETS;
+                       } else {
+                               config.clean_policies &=
+                                       ~ONAK_CLEAN_LARGE_PACKETS;
+                       }
                } else {
                        return false;
                }