Add optional range directive to keys in dnssec-policy

This commit is contained in:
Mark Andrews 2024-08-06 14:41:50 +10:00
parent 25bf77fac6
commit c5bc0a1805
5 changed files with 102 additions and 3 deletions

View file

@ -1235,6 +1235,8 @@ main(int argc, char **argv) {
ctx.ksk = true;
ctx.zsk = true;
ctx.lifetime = 0;
ctx.tag_min = 0;
ctx.tag_max = 0xffff;
keygen(&ctx, mctx, argc, argv);
} else {
@ -1283,6 +1285,8 @@ main(int argc, char **argv) {
if (ctx.keystore != NULL) {
check_keystore_options(&ctx);
}
ctx.tag_min = dns_kasp_key_tagmin(kaspkey);
ctx.tag_max = dns_kasp_key_tagmax(kaspkey);
if ((ctx.ksk && !ctx.wantksk && ctx.wantzsk) ||
(ctx.zsk && !ctx.wantzsk && ctx.wantksk))
{

View file

@ -436,8 +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, 0, 0xffff,
NULL))
if (key_collision(key, name, ksr->keydir, mctx,
dns_kasp_key_tagmin(kaspkey),
dns_kasp_key_tagmax(kaspkey), NULL))
{
conflict = true;
if (verbose > 0) {

View file

@ -15,7 +15,7 @@ dnssec-policy <string> {
cds-digest-types { <string>; ... };
dnskey-ttl <duration>;
inline-signing <boolean>;
keys { ( csk | ksk | zsk ) [ key-directory | key-store <string> ] lifetime <duration_or_unlimited> algorithm <string> [ <integer> ]; ... };
keys { ( csk | ksk | zsk ) [ key-directory | key-store <string> ] lifetime <duration_or_unlimited> algorithm <string> [ tag-range <integer> <integer> ] [ <integer> ]; ... };
max-zone-ttl <duration>;
nsec3param [ iterations <integer> ] [ optout <boolean> ] [ salt-length <integer> ];
offline-ksk <boolean>;

View file

@ -117,6 +117,7 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
uint32_t ksk_min_lifetime, uint32_t zsk_min_lifetime) {
isc_result_t result;
dns_kasp_key_t *key = NULL;
const cfg_obj_t *tagrange = NULL;
/* Create a new key reference. */
result = dns_kasp_key_create(kasp, &key);
@ -291,6 +292,38 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
key->length = size;
}
tagrange = cfg_tuple_get(config, "tag-range");
if (cfg_obj_istuple(tagrange)) {
uint32_t tag_min = 0, tag_max = 0xffff;
obj = cfg_tuple_get(tagrange, "tag-min");
tag_min = cfg_obj_asuint32(obj);
if (tag_min > 0xffff) {
cfg_obj_log(obj, ISC_LOG_ERROR,
"dnssec-policy: tag-min "
"too big");
result = ISC_R_RANGE;
goto cleanup;
}
obj = cfg_tuple_get(tagrange, "tag-max");
tag_max = cfg_obj_asuint32(obj);
if (tag_max > 0xffff) {
cfg_obj_log(obj, ISC_LOG_ERROR,
"dnssec-policy: tag-max "
"too big");
result = ISC_R_RANGE;
goto cleanup;
}
if (tag_min >= tag_max) {
cfg_obj_log(
obj, ISC_LOG_ERROR,
"dnssec-policy: tag-min >= tag_max");
result = ISC_R_RANGE;
goto cleanup;
}
key->tag_min = tag_min;
key->tag_max = tag_max;
}
}
dns_kasp_addkey(kasp, key);

View file

@ -649,12 +649,73 @@ static keyword_type_t lifetime_kw = { "lifetime",
static cfg_type_t cfg_type_lifetime = { "lifetime", parse_keyvalue,
print_keyvalue, doc_keyvalue,
&cfg_rep_duration, &lifetime_kw };
/*
*
*/
static void
print_tagrange(cfg_printer_t *pctx, const cfg_obj_t *obj) {
REQUIRE(pctx != NULL);
REQUIRE(obj != NULL);
REQUIRE(obj->type->rep == &cfg_rep_tuple);
if (cfg_obj_istuple(obj)) {
cfg_print_cstr(pctx, "tag-range ");
cfg_print_tuple(pctx, obj);
}
}
static cfg_tuplefielddef_t tagrange_fields[] = {
{ "tag-min", &cfg_type_uint32, 0 },
{ "tag-max", &cfg_type_uint32, 0 },
{ NULL, NULL, 0 }
};
static cfg_type_t cfg_type_tagrange = { "tagrange", cfg_parse_tuple,
print_tagrange, cfg_doc_tuple,
&cfg_rep_tuple, tagrange_fields };
static keyword_type_t tagrange_kw = { "tag-range", &cfg_type_tagrange };
static void
doc_optionaltagrange(cfg_printer_t *pctx, const cfg_type_t *type) {
UNUSED(type);
cfg_print_cstr(pctx, "[ tag-range <integer> <integer> ]");
}
static isc_result_t
parse_optionaltagrange(cfg_parser_t *pctx, const cfg_type_t *type,
cfg_obj_t **ret) {
isc_result_t result;
cfg_obj_t *obj = NULL;
UNUSED(type);
CHECK(cfg_peektoken(pctx, 0));
if (pctx->token.type == isc_tokentype_string &&
strcasecmp(TOKEN_STRING(pctx), "tag-range") == 0)
{
CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING));
CHECK(cfg_parse_obj(pctx, &cfg_type_tagrange, &obj));
} else {
CHECK(cfg_parse_void(pctx, NULL, &obj));
}
*ret = obj;
cleanup:
return (result);
}
static cfg_type_t cfg_type_optional_tagrange = {
"optionaltagrange", parse_optionaltagrange, NULL,
doc_optionaltagrange, &cfg_rep_tuple, &tagrange_kw
};
static cfg_tuplefielddef_t kaspkey_fields[] = {
{ "role", &cfg_type_dnsseckeyrole, 0 },
{ "keystorage", &cfg_type_optional_keystore, 0 },
{ "lifetime", &cfg_type_lifetime, 0 },
{ "algorithm", &cfg_type_algorithm, 0 },
{ "tag-range", &cfg_type_optional_tagrange, 0 },
{ "length", &cfg_type_optional_uint32, 0 },
{ NULL, NULL, 0 }
};