]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add restrict key tag range support
authorMark Andrews <marka@isc.org>
Tue, 6 Aug 2024 04:28:08 +0000 (14:28 +1000)
committerMark Andrews <marka@isc.org>
Thu, 22 Aug 2024 12:12:02 +0000 (12:12 +0000)
to dnssec-keygen and dnssec-keyfromlabel.

bin/dnssec/dnssec-keyfromlabel.c
bin/dnssec/dnssec-keygen.c
bin/dnssec/dnssec-ksr.c
bin/dnssec/dnssectool.c
bin/dnssec/dnssectool.h

index 35dacc3f310c48665eef858170b01c36195142ca..a52980f71ff1158f81ee3a3cc07888f19371401e 100644 (file)
@@ -43,6 +43,8 @@
 
 const char *program = "dnssec-keyfromlabel";
 
+static uint16_t tag_min = 0, tag_max = 0xffff;
+
 ISC_NORETURN static void
 usage(void);
 
@@ -68,6 +70,7 @@ usage(void) {
                        "key files\n");
        fprintf(stderr, "    -k: generate a TYPE=KEY key\n");
        fprintf(stderr, "    -L ttl: default key TTL\n");
+       fprintf(stderr, "    -M <min>:<max>: allowed Key ID range\n");
        fprintf(stderr, "    -n nametype: ZONE | HOST | ENTITY | USER | "
                        "OTHER\n");
        fprintf(stderr, "        (DNSKEY generation defaults to ZONE\n");
@@ -156,7 +159,7 @@ main(int argc, char **argv) {
 
        isc_commandline_errprint = false;
 
-#define CMDLINE_FLAGS "3A:a:Cc:D:E:Ff:GhI:i:kK:L:l:n:P:p:R:S:t:v:Vy"
+#define CMDLINE_FLAGS "3A:a:Cc:D:E:Ff:GhI:i:kK:L:l:M:n:P:p:R:S:t:v:Vy"
        while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
                switch (ch) {
                case '3':
@@ -203,6 +206,20 @@ main(int argc, char **argv) {
                case 'l':
                        label = isc_mem_strdup(mctx, isc_commandline_argument);
                        break;
+               case 'M': {
+                       unsigned long ul;
+                       tag_min = ul = strtoul(isc_commandline_argument, &endp,
+                                              10);
+                       if (*endp != ':' || ul > 0xffff) {
+                               fatal("-M range invalid");
+                       }
+                       tag_max = ul = strtoul(endp + 1, &endp, 10);
+                       if (*endp != '\0' || ul > 0xffff || tag_max <= tag_min)
+                       {
+                               fatal("-M range invalid");
+                       }
+                       break;
+               }
                case 'n':
                        nametype = isc_commandline_argument;
                        break;
@@ -677,7 +694,8 @@ main(int argc, char **argv) {
         * is a risk of ID collision due to this key or another key
         * being revoked.
         */
-       if (key_collision(key, name, directory, mctx, &exact)) {
+       if (key_collision(key, name, directory, mctx, tag_min, tag_max, &exact))
+       {
                isc_buffer_clear(&buf);
                ret = dst_key_buildfilename(key, 0, directory, &buf);
                if (ret != ISC_R_SUCCESS) {
index 5522662994978c017bd29b44ec528e57f4a1288c..9215c594cbca903446deafa6b477326ab702712e 100644 (file)
@@ -89,6 +89,8 @@ struct keygen_ctx {
        char *type;
        int protocol;
        int size;
+       uint16_t tag_min;
+       uint16_t tag_max;
        int signatory;
        dns_rdataclass_t rdclass;
        int options;
@@ -177,6 +179,7 @@ usage(void) {
        fprintf(stderr, "    -f <keyflag>: ZSK | KSK | REVOKE\n");
        fprintf(stderr, "    -F: FIPS mode\n");
        fprintf(stderr, "    -L <ttl>: default key TTL\n");
+       fprintf(stderr, "    -M <min>:<max>: allowed Key ID range\n");
        fprintf(stderr, "    -p <protocol>: (default: 3 [dnssec])\n");
        fprintf(stderr, "    -s <strength>: strength value this key signs DNS "
                        "records with (default: 0)\n");
@@ -753,7 +756,9 @@ keygen(keygen_ctx_t *ctx, isc_mem_t *mctx, int argc, char **argv) {
                 * if there is a risk of ID collision due to this key
                 * or another key being revoked.
                 */
-               if (key_collision(key, name, ctx->directory, mctx, NULL)) {
+               if (key_collision(key, name, ctx->directory, mctx, ctx->tag_min,
+                                 ctx->tag_max, NULL))
+               {
                        conflict = true;
                        if (null_key) {
                                dst_key_free(&key);
@@ -862,8 +867,8 @@ main(int argc, char **argv) {
        /*
         * Process memory debugging argument first.
         */
-#define CMDLINE_FLAGS                                        \
-       "3A:a:b:Cc:D:d:E:Ff:GhI:i:K:k:L:l:m:n:P:p:qR:r:S:s:" \
+#define CMDLINE_FLAGS                                          \
+       "3A:a:b:Cc:D:d:E:Ff:GhI:i:K:k:L:l:M:m:n:P:p:qR:r:S:s:" \
        "T:t:v:V"
        while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
                switch (ch) {
@@ -952,6 +957,21 @@ main(int argc, char **argv) {
                case 'n':
                        ctx.nametype = isc_commandline_argument;
                        break;
+               case 'M': {
+                       unsigned long ul;
+                       ctx.tag_min = ul = strtoul(isc_commandline_argument,
+                                                  &endp, 10);
+                       if (*endp != ':' || ul > 0xffff) {
+                               fatal("-M range invalid");
+                       }
+                       ctx.tag_max = ul = strtoul(endp + 1, &endp, 10);
+                       if (*endp != '\0' || ul > 0xffff ||
+                           ctx.tag_max <= ctx.tag_min)
+                       {
+                               fatal("-M range invalid");
+                       }
+                       break;
+               }
                case 'm':
                        break;
                case 'p':
index aa4522debae236655f44217491c0815c806c5a40..572e2e12077dd9748a5131a9d72c94523b4958b0 100644 (file)
@@ -436,7 +436,9 @@ create_zsk(ksr_ctx_t *ksr, dns_kasp_key_t *kaspkey, dns_dnsseckeylist_t *keys,
                }
 
                /* Do not overwrite an existing key. */
-               if (key_collision(key, name, ksr->keydir, mctx, NULL)) {
+               if (key_collision(key, name, ksr->keydir, mctx, 0, 0xffff,
+                                 NULL))
+               {
                        conflict = true;
                        if (verbose > 0) {
                                isc_buffer_clear(&buf);
index 0d1163f8c6a2f42cc7d7007e3c989c6e1f729b35..820878eaafbfad62a1eb18a549530c638e419473 100644 (file)
@@ -450,7 +450,7 @@ set_keyversion(dst_key_t *key) {
 
 bool
 key_collision(dst_key_t *dstkey, dns_name_t *name, const char *dir,
-             isc_mem_t *mctx, bool *exact) {
+             isc_mem_t *mctx, uint16_t min, uint16_t max, bool *exact) {
        isc_result_t result;
        bool conflict = false;
        dns_dnsseckeylist_t matchkeys;
@@ -468,6 +468,21 @@ key_collision(dst_key_t *dstkey, dns_name_t *name, const char *dir,
        rid = dst_key_rid(dstkey);
        alg = dst_key_alg(dstkey);
 
+       if (min != max) {
+               if (id < min || id > max) {
+                       fprintf(stderr, "Key ID %d outside of [%u..%u]\n", id,
+                               min, max);
+                       return (true);
+               }
+               if (rid < min || rid > max) {
+                       fprintf(stderr,
+                               "Revoked Key ID %d (for tag %d) outside of "
+                               "[%u..%u]\n",
+                               rid, id, min, max);
+                       return (true);
+               }
+       }
+
        ISC_LIST_INIT(matchkeys);
        result = dns_dnssec_findmatchingkeys(name, NULL, dir, NULL, now, mctx,
                                             &matchkeys);
index 3cd0571fd52cd6ffddc00139a319be62c736f87a..dc6a5dfe7574219912242e6eeb20b38d606a6f82 100644 (file)
@@ -106,7 +106,7 @@ set_keyversion(dst_key_t *key);
 
 bool
 key_collision(dst_key_t *key, dns_name_t *name, const char *dir,
-             isc_mem_t *mctx, bool *exact);
+             isc_mem_t *mctx, uint16_t min, uint16_t max, bool *exact);
 
 bool
 isoptarg(const char *arg, char **argv, void (*usage)(void));