From: Mark Andrews Date: Tue, 6 Aug 2024 04:28:08 +0000 (+1000) Subject: Add restrict key tag range support X-Git-Tag: v9.21.1~19^2~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=329e5eee9b5f10b6d3b4f78a298f38d762682bfc;p=thirdparty%2Fbind9.git Add restrict key tag range support to dnssec-keygen and dnssec-keyfromlabel. --- diff --git a/bin/dnssec/dnssec-keyfromlabel.c b/bin/dnssec/dnssec-keyfromlabel.c index 35dacc3f310..a52980f71ff 100644 --- a/bin/dnssec/dnssec-keyfromlabel.c +++ b/bin/dnssec/dnssec-keyfromlabel.c @@ -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 :: 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) { diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c index 55226629949..9215c594cbc 100644 --- a/bin/dnssec/dnssec-keygen.c +++ b/bin/dnssec/dnssec-keygen.c @@ -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 : ZSK | KSK | REVOKE\n"); fprintf(stderr, " -F: FIPS mode\n"); fprintf(stderr, " -L : default key TTL\n"); + fprintf(stderr, " -M :: allowed Key ID range\n"); fprintf(stderr, " -p : (default: 3 [dnssec])\n"); fprintf(stderr, " -s : 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': diff --git a/bin/dnssec/dnssec-ksr.c b/bin/dnssec/dnssec-ksr.c index aa4522debae..572e2e12077 100644 --- a/bin/dnssec/dnssec-ksr.c +++ b/bin/dnssec/dnssec-ksr.c @@ -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); diff --git a/bin/dnssec/dnssectool.c b/bin/dnssec/dnssectool.c index 0d1163f8c6a..820878eaafb 100644 --- a/bin/dnssec/dnssectool.c +++ b/bin/dnssec/dnssectool.c @@ -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); diff --git a/bin/dnssec/dnssectool.h b/bin/dnssec/dnssectool.h index 3cd0571fd52..dc6a5dfe757 100644 --- a/bin/dnssec/dnssectool.h +++ b/bin/dnssec/dnssectool.h @@ -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));