1*bcda20f6Schristos /* $NetBSD: kasp.c,v 1.8 2025/01/26 16:25:23 christos Exp $ */ 27f30a007Schristos 37f30a007Schristos /* 47f30a007Schristos * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 57f30a007Schristos * 68596601aSchristos * SPDX-License-Identifier: MPL-2.0 78596601aSchristos * 87f30a007Schristos * This Source Code Form is subject to the terms of the Mozilla Public 97f30a007Schristos * License, v. 2.0. If a copy of the MPL was not distributed with this 10fce770bdSchristos * file, you can obtain one at https://mozilla.org/MPL/2.0/. 117f30a007Schristos * 127f30a007Schristos * See the COPYRIGHT file distributed with this work for additional 137f30a007Schristos * information regarding copyright ownership. 147f30a007Schristos */ 157f30a007Schristos 167f30a007Schristos /*! \file */ 177f30a007Schristos 187f30a007Schristos #include <string.h> 197f30a007Schristos 207f30a007Schristos #include <isc/assertions.h> 21fce770bdSchristos #include <isc/buffer.h> 227f30a007Schristos #include <isc/file.h> 23fce770bdSchristos #include <isc/hex.h> 247f30a007Schristos #include <isc/log.h> 257f30a007Schristos #include <isc/mem.h> 267f30a007Schristos #include <isc/util.h> 277f30a007Schristos 287f30a007Schristos #include <dns/kasp.h> 297f30a007Schristos #include <dns/keyvalues.h> 307f30a007Schristos #include <dns/log.h> 317f30a007Schristos 32*bcda20f6Schristos #include <dst/dst.h> 33*bcda20f6Schristos 34bb5aa156Schristos /* Default TTLsig (maximum zone ttl) */ 35bb5aa156Schristos #define DEFAULT_TTLSIG 604800 /* one week */ 36bb5aa156Schristos 377f30a007Schristos isc_result_t 387f30a007Schristos dns_kasp_create(isc_mem_t *mctx, const char *name, dns_kasp_t **kaspp) { 397f30a007Schristos dns_kasp_t *kasp; 40bb5aa156Schristos dns_kasp_t k = { 41bb5aa156Schristos .magic = DNS_KASP_MAGIC, 42*bcda20f6Schristos .digests = ISC_LIST_INITIALIZER, 43*bcda20f6Schristos .keys = ISC_LIST_INITIALIZER, 44*bcda20f6Schristos .link = ISC_LINK_INITIALIZER, 45bb5aa156Schristos }; 467f30a007Schristos 477f30a007Schristos REQUIRE(name != NULL); 487f30a007Schristos REQUIRE(kaspp != NULL && *kaspp == NULL); 497f30a007Schristos 507f30a007Schristos kasp = isc_mem_get(mctx, sizeof(*kasp)); 51bb5aa156Schristos *kasp = k; 52bb5aa156Schristos 537f30a007Schristos kasp->mctx = NULL; 547f30a007Schristos isc_mem_attach(mctx, &kasp->mctx); 557f30a007Schristos kasp->name = isc_mem_strdup(mctx, name); 567f30a007Schristos isc_mutex_init(&kasp->lock); 577f30a007Schristos isc_refcount_init(&kasp->references, 1); 587f30a007Schristos 597f30a007Schristos *kaspp = kasp; 60*bcda20f6Schristos return ISC_R_SUCCESS; 617f30a007Schristos } 627f30a007Schristos 637f30a007Schristos void 647f30a007Schristos dns_kasp_attach(dns_kasp_t *source, dns_kasp_t **targetp) { 657f30a007Schristos REQUIRE(DNS_KASP_VALID(source)); 667f30a007Schristos REQUIRE(targetp != NULL && *targetp == NULL); 677f30a007Schristos 687f30a007Schristos isc_refcount_increment(&source->references); 697f30a007Schristos *targetp = source; 707f30a007Schristos } 717f30a007Schristos 728596601aSchristos static void 737f30a007Schristos destroy(dns_kasp_t *kasp) { 74*bcda20f6Schristos dns_kasp_key_t *key, *key_next; 75*bcda20f6Schristos dns_kasp_digest_t *digest, *digest_next; 767f30a007Schristos 777f30a007Schristos REQUIRE(!ISC_LINK_LINKED(kasp, link)); 787f30a007Schristos 797f30a007Schristos for (key = ISC_LIST_HEAD(kasp->keys); key != NULL; key = key_next) { 807f30a007Schristos key_next = ISC_LIST_NEXT(key, link); 817f30a007Schristos ISC_LIST_UNLINK(kasp->keys, key, link); 827f30a007Schristos dns_kasp_key_destroy(key); 837f30a007Schristos } 847f30a007Schristos INSIST(ISC_LIST_EMPTY(kasp->keys)); 857f30a007Schristos 86*bcda20f6Schristos for (digest = ISC_LIST_HEAD(kasp->digests); digest != NULL; 87*bcda20f6Schristos digest = digest_next) 88*bcda20f6Schristos { 89*bcda20f6Schristos digest_next = ISC_LIST_NEXT(digest, link); 90*bcda20f6Schristos ISC_LIST_UNLINK(kasp->digests, digest, link); 91*bcda20f6Schristos isc_mem_put(kasp->mctx, digest, sizeof(*digest)); 92*bcda20f6Schristos } 93*bcda20f6Schristos INSIST(ISC_LIST_EMPTY(kasp->digests)); 94*bcda20f6Schristos 957f30a007Schristos isc_mutex_destroy(&kasp->lock); 967f30a007Schristos isc_mem_free(kasp->mctx, kasp->name); 977f30a007Schristos isc_mem_putanddetach(&kasp->mctx, kasp, sizeof(*kasp)); 987f30a007Schristos } 997f30a007Schristos 1007f30a007Schristos void 1017f30a007Schristos dns_kasp_detach(dns_kasp_t **kaspp) { 1027f30a007Schristos REQUIRE(kaspp != NULL && DNS_KASP_VALID(*kaspp)); 1037f30a007Schristos 1047f30a007Schristos dns_kasp_t *kasp = *kaspp; 1057f30a007Schristos *kaspp = NULL; 1067f30a007Schristos 1077f30a007Schristos if (isc_refcount_decrement(&kasp->references) == 1) { 1087f30a007Schristos destroy(kasp); 1097f30a007Schristos } 1107f30a007Schristos } 1117f30a007Schristos 1127f30a007Schristos const char * 1137f30a007Schristos dns_kasp_getname(dns_kasp_t *kasp) { 1147f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 1157f30a007Schristos 116*bcda20f6Schristos return kasp->name; 1177f30a007Schristos } 1187f30a007Schristos 1197f30a007Schristos void 1207f30a007Schristos dns_kasp_freeze(dns_kasp_t *kasp) { 1217f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 1227f30a007Schristos REQUIRE(!kasp->frozen); 1237f30a007Schristos 1247f30a007Schristos kasp->frozen = true; 1257f30a007Schristos } 1267f30a007Schristos 1277f30a007Schristos void 1287f30a007Schristos dns_kasp_thaw(dns_kasp_t *kasp) { 1297f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 1307f30a007Schristos REQUIRE(kasp->frozen); 1317f30a007Schristos 1327f30a007Schristos kasp->frozen = false; 1337f30a007Schristos } 1347f30a007Schristos 1357f30a007Schristos uint32_t 1367f30a007Schristos dns_kasp_signdelay(dns_kasp_t *kasp) { 1377f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 1387f30a007Schristos REQUIRE(kasp->frozen); 1397f30a007Schristos 140*bcda20f6Schristos return kasp->signatures_validity - kasp->signatures_refresh; 1417f30a007Schristos } 1427f30a007Schristos 1437f30a007Schristos uint32_t 144dff692fcSchristos dns_kasp_sigjitter(dns_kasp_t *kasp) { 145dff692fcSchristos REQUIRE(DNS_KASP_VALID(kasp)); 146dff692fcSchristos REQUIRE(kasp->frozen); 147dff692fcSchristos 148*bcda20f6Schristos return kasp->signatures_jitter; 149dff692fcSchristos } 150dff692fcSchristos 151dff692fcSchristos void 152dff692fcSchristos dns_kasp_setsigjitter(dns_kasp_t *kasp, uint32_t value) { 153dff692fcSchristos REQUIRE(DNS_KASP_VALID(kasp)); 154dff692fcSchristos REQUIRE(!kasp->frozen); 155dff692fcSchristos 156dff692fcSchristos kasp->signatures_jitter = value; 157dff692fcSchristos } 158dff692fcSchristos 159dff692fcSchristos uint32_t 1607f30a007Schristos dns_kasp_sigrefresh(dns_kasp_t *kasp) { 1617f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 1627f30a007Schristos REQUIRE(kasp->frozen); 1637f30a007Schristos 164*bcda20f6Schristos return kasp->signatures_refresh; 1657f30a007Schristos } 1667f30a007Schristos 1677f30a007Schristos void 1687f30a007Schristos dns_kasp_setsigrefresh(dns_kasp_t *kasp, uint32_t value) { 1697f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 1707f30a007Schristos REQUIRE(!kasp->frozen); 1717f30a007Schristos 1727f30a007Schristos kasp->signatures_refresh = value; 1737f30a007Schristos } 1747f30a007Schristos 1757f30a007Schristos uint32_t 1767f30a007Schristos dns_kasp_sigvalidity(dns_kasp_t *kasp) { 1777f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 1787f30a007Schristos REQUIRE(kasp->frozen); 1797f30a007Schristos 180*bcda20f6Schristos return kasp->signatures_validity; 1817f30a007Schristos } 1827f30a007Schristos 1837f30a007Schristos void 1847f30a007Schristos dns_kasp_setsigvalidity(dns_kasp_t *kasp, uint32_t value) { 1857f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 1867f30a007Schristos REQUIRE(!kasp->frozen); 1877f30a007Schristos 1887f30a007Schristos kasp->signatures_validity = value; 1897f30a007Schristos } 1907f30a007Schristos 1917f30a007Schristos uint32_t 1927f30a007Schristos dns_kasp_sigvalidity_dnskey(dns_kasp_t *kasp) { 1937f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 1947f30a007Schristos REQUIRE(kasp->frozen); 1957f30a007Schristos 196*bcda20f6Schristos return kasp->signatures_validity_dnskey; 1977f30a007Schristos } 1987f30a007Schristos 1997f30a007Schristos void 2007f30a007Schristos dns_kasp_setsigvalidity_dnskey(dns_kasp_t *kasp, uint32_t value) { 2017f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 2027f30a007Schristos REQUIRE(!kasp->frozen); 2037f30a007Schristos 204fce770bdSchristos kasp->signatures_validity_dnskey = value; 2057f30a007Schristos } 2067f30a007Schristos 2077f30a007Schristos dns_ttl_t 2087f30a007Schristos dns_kasp_dnskeyttl(dns_kasp_t *kasp) { 2097f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 2107f30a007Schristos REQUIRE(kasp->frozen); 2117f30a007Schristos 212*bcda20f6Schristos return kasp->dnskey_ttl; 2137f30a007Schristos } 2147f30a007Schristos 2157f30a007Schristos void 2167f30a007Schristos dns_kasp_setdnskeyttl(dns_kasp_t *kasp, dns_ttl_t ttl) { 2177f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 2187f30a007Schristos REQUIRE(!kasp->frozen); 2197f30a007Schristos 2207f30a007Schristos kasp->dnskey_ttl = ttl; 2217f30a007Schristos } 2227f30a007Schristos 2237f30a007Schristos uint32_t 22499a1c298Schristos dns_kasp_purgekeys(dns_kasp_t *kasp) { 22599a1c298Schristos REQUIRE(DNS_KASP_VALID(kasp)); 22699a1c298Schristos REQUIRE(kasp->frozen); 22799a1c298Schristos 228*bcda20f6Schristos return kasp->purge_keys; 22999a1c298Schristos } 23099a1c298Schristos 23199a1c298Schristos void 23299a1c298Schristos dns_kasp_setpurgekeys(dns_kasp_t *kasp, uint32_t value) { 23399a1c298Schristos REQUIRE(DNS_KASP_VALID(kasp)); 23499a1c298Schristos REQUIRE(!kasp->frozen); 23599a1c298Schristos 23699a1c298Schristos kasp->purge_keys = value; 23799a1c298Schristos } 23899a1c298Schristos 23999a1c298Schristos uint32_t 2407f30a007Schristos dns_kasp_publishsafety(dns_kasp_t *kasp) { 2417f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 2427f30a007Schristos REQUIRE(kasp->frozen); 2437f30a007Schristos 244*bcda20f6Schristos return kasp->publish_safety; 2457f30a007Schristos } 2467f30a007Schristos 2477f30a007Schristos void 2487f30a007Schristos dns_kasp_setpublishsafety(dns_kasp_t *kasp, uint32_t value) { 2497f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 2507f30a007Schristos REQUIRE(!kasp->frozen); 2517f30a007Schristos 2527f30a007Schristos kasp->publish_safety = value; 2537f30a007Schristos } 2547f30a007Schristos 2557f30a007Schristos uint32_t 2567f30a007Schristos dns_kasp_retiresafety(dns_kasp_t *kasp) { 2577f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 2587f30a007Schristos REQUIRE(kasp->frozen); 2597f30a007Schristos 260*bcda20f6Schristos return kasp->retire_safety; 2617f30a007Schristos } 2627f30a007Schristos 2637f30a007Schristos void 2647f30a007Schristos dns_kasp_setretiresafety(dns_kasp_t *kasp, uint32_t value) { 2657f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 2667f30a007Schristos REQUIRE(!kasp->frozen); 2677f30a007Schristos 2687f30a007Schristos kasp->retire_safety = value; 2697f30a007Schristos } 2707f30a007Schristos 271*bcda20f6Schristos bool 272*bcda20f6Schristos dns_kasp_inlinesigning(dns_kasp_t *kasp) { 273*bcda20f6Schristos REQUIRE(DNS_KASP_VALID(kasp)); 274*bcda20f6Schristos REQUIRE(kasp->frozen); 275*bcda20f6Schristos 276*bcda20f6Schristos return kasp->inline_signing; 277*bcda20f6Schristos } 278*bcda20f6Schristos 279*bcda20f6Schristos void 280*bcda20f6Schristos dns_kasp_setinlinesigning(dns_kasp_t *kasp, bool value) { 281*bcda20f6Schristos REQUIRE(DNS_KASP_VALID(kasp)); 282*bcda20f6Schristos REQUIRE(!kasp->frozen); 283*bcda20f6Schristos 284*bcda20f6Schristos kasp->inline_signing = value; 285*bcda20f6Schristos } 286*bcda20f6Schristos 2877f30a007Schristos dns_ttl_t 288bb5aa156Schristos dns_kasp_zonemaxttl(dns_kasp_t *kasp, bool fallback) { 2897f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 2907f30a007Schristos REQUIRE(kasp->frozen); 2917f30a007Schristos 292bb5aa156Schristos if (kasp->zone_max_ttl == 0 && fallback) { 293*bcda20f6Schristos return DEFAULT_TTLSIG; 294bb5aa156Schristos } 295*bcda20f6Schristos return kasp->zone_max_ttl; 2967f30a007Schristos } 2977f30a007Schristos 2987f30a007Schristos void 2997f30a007Schristos dns_kasp_setzonemaxttl(dns_kasp_t *kasp, dns_ttl_t ttl) { 3007f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 3017f30a007Schristos REQUIRE(!kasp->frozen); 3027f30a007Schristos 3037f30a007Schristos kasp->zone_max_ttl = ttl; 3047f30a007Schristos } 3057f30a007Schristos 3067f30a007Schristos uint32_t 3077f30a007Schristos dns_kasp_zonepropagationdelay(dns_kasp_t *kasp) { 3087f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 3097f30a007Schristos REQUIRE(kasp->frozen); 3107f30a007Schristos 311*bcda20f6Schristos return kasp->zone_propagation_delay; 3127f30a007Schristos } 3137f30a007Schristos 3147f30a007Schristos void 3157f30a007Schristos dns_kasp_setzonepropagationdelay(dns_kasp_t *kasp, uint32_t value) { 3167f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 3177f30a007Schristos REQUIRE(!kasp->frozen); 3187f30a007Schristos 3197f30a007Schristos kasp->zone_propagation_delay = value; 3207f30a007Schristos } 3217f30a007Schristos 3227f30a007Schristos dns_ttl_t 3237f30a007Schristos dns_kasp_dsttl(dns_kasp_t *kasp) { 3247f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 3257f30a007Schristos REQUIRE(kasp->frozen); 3267f30a007Schristos 327*bcda20f6Schristos return kasp->parent_ds_ttl; 3287f30a007Schristos } 3297f30a007Schristos 3307f30a007Schristos void 3317f30a007Schristos dns_kasp_setdsttl(dns_kasp_t *kasp, dns_ttl_t ttl) { 3327f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 3337f30a007Schristos REQUIRE(!kasp->frozen); 3347f30a007Schristos 3357f30a007Schristos kasp->parent_ds_ttl = ttl; 3367f30a007Schristos } 3377f30a007Schristos 3387f30a007Schristos uint32_t 3397f30a007Schristos dns_kasp_parentpropagationdelay(dns_kasp_t *kasp) { 3407f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 3417f30a007Schristos REQUIRE(kasp->frozen); 3427f30a007Schristos 343*bcda20f6Schristos return kasp->parent_propagation_delay; 3447f30a007Schristos } 3457f30a007Schristos 3467f30a007Schristos void 3477f30a007Schristos dns_kasp_setparentpropagationdelay(dns_kasp_t *kasp, uint32_t value) { 3487f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 3497f30a007Schristos REQUIRE(!kasp->frozen); 3507f30a007Schristos 3517f30a007Schristos kasp->parent_propagation_delay = value; 3527f30a007Schristos } 3537f30a007Schristos 3547f30a007Schristos isc_result_t 3557f30a007Schristos dns_kasplist_find(dns_kasplist_t *list, const char *name, dns_kasp_t **kaspp) { 3567f30a007Schristos dns_kasp_t *kasp = NULL; 3577f30a007Schristos 3587f30a007Schristos REQUIRE(kaspp != NULL && *kaspp == NULL); 3597f30a007Schristos 3607f30a007Schristos if (list == NULL) { 361*bcda20f6Schristos return ISC_R_NOTFOUND; 3627f30a007Schristos } 3637f30a007Schristos 3647f30a007Schristos for (kasp = ISC_LIST_HEAD(*list); kasp != NULL; 3657f30a007Schristos kasp = ISC_LIST_NEXT(kasp, link)) 3667f30a007Schristos { 3677f30a007Schristos if (strcmp(kasp->name, name) == 0) { 3687f30a007Schristos break; 3697f30a007Schristos } 3707f30a007Schristos } 3717f30a007Schristos 3727f30a007Schristos if (kasp == NULL) { 373*bcda20f6Schristos return ISC_R_NOTFOUND; 3747f30a007Schristos } 3757f30a007Schristos 3767f30a007Schristos dns_kasp_attach(kasp, kaspp); 377*bcda20f6Schristos return ISC_R_SUCCESS; 3787f30a007Schristos } 3797f30a007Schristos 3807f30a007Schristos dns_kasp_keylist_t 3817f30a007Schristos dns_kasp_keys(dns_kasp_t *kasp) { 3827f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 3837f30a007Schristos REQUIRE(kasp->frozen); 3847f30a007Schristos 385*bcda20f6Schristos return kasp->keys; 3867f30a007Schristos } 3877f30a007Schristos 3887f30a007Schristos bool 3897f30a007Schristos dns_kasp_keylist_empty(dns_kasp_t *kasp) { 3907f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 3917f30a007Schristos 392*bcda20f6Schristos return ISC_LIST_EMPTY(kasp->keys); 3937f30a007Schristos } 3947f30a007Schristos 3957f30a007Schristos void 3967f30a007Schristos dns_kasp_addkey(dns_kasp_t *kasp, dns_kasp_key_t *key) { 3977f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 3987f30a007Schristos REQUIRE(!kasp->frozen); 3997f30a007Schristos REQUIRE(key != NULL); 4007f30a007Schristos 4017f30a007Schristos ISC_LIST_APPEND(kasp->keys, key, link); 4027f30a007Schristos } 4037f30a007Schristos 4047f30a007Schristos isc_result_t 4057f30a007Schristos dns_kasp_key_create(dns_kasp_t *kasp, dns_kasp_key_t **keyp) { 406*bcda20f6Schristos dns_kasp_key_t *key = NULL; 407*bcda20f6Schristos dns_kasp_key_t k = { .tag_max = 0xffff, .length = -1 }; 4087f30a007Schristos 4097f30a007Schristos REQUIRE(DNS_KASP_VALID(kasp)); 4107f30a007Schristos REQUIRE(keyp != NULL && *keyp == NULL); 4117f30a007Schristos 4127f30a007Schristos key = isc_mem_get(kasp->mctx, sizeof(*key)); 413*bcda20f6Schristos *key = k; 414*bcda20f6Schristos 4157f30a007Schristos key->mctx = NULL; 4167f30a007Schristos isc_mem_attach(kasp->mctx, &key->mctx); 4177f30a007Schristos 4187f30a007Schristos ISC_LINK_INIT(key, link); 4197f30a007Schristos 4207f30a007Schristos *keyp = key; 421*bcda20f6Schristos return ISC_R_SUCCESS; 4227f30a007Schristos } 4237f30a007Schristos 4247f30a007Schristos void 4257f30a007Schristos dns_kasp_key_destroy(dns_kasp_key_t *key) { 4267f30a007Schristos REQUIRE(key != NULL); 4277f30a007Schristos 428*bcda20f6Schristos if (key->keystore != NULL) { 429*bcda20f6Schristos dns_keystore_detach(&key->keystore); 430*bcda20f6Schristos } 4317f30a007Schristos isc_mem_putanddetach(&key->mctx, key, sizeof(*key)); 4327f30a007Schristos } 4337f30a007Schristos 4347f30a007Schristos uint32_t 4357f30a007Schristos dns_kasp_key_algorithm(dns_kasp_key_t *key) { 4367f30a007Schristos REQUIRE(key != NULL); 4377f30a007Schristos 438*bcda20f6Schristos return key->algorithm; 4397f30a007Schristos } 4407f30a007Schristos 4417f30a007Schristos unsigned int 4427f30a007Schristos dns_kasp_key_size(dns_kasp_key_t *key) { 4437f30a007Schristos unsigned int size = 0; 4447f30a007Schristos unsigned int min = 0; 4457f30a007Schristos 4467f30a007Schristos REQUIRE(key != NULL); 4477f30a007Schristos 4487f30a007Schristos switch (key->algorithm) { 4497f30a007Schristos case DNS_KEYALG_RSASHA1: 4507f30a007Schristos case DNS_KEYALG_NSEC3RSASHA1: 4517f30a007Schristos case DNS_KEYALG_RSASHA256: 4527f30a007Schristos case DNS_KEYALG_RSASHA512: 453fce770bdSchristos min = (key->algorithm == DNS_KEYALG_RSASHA512) ? 1024 : 512; 4547f30a007Schristos if (key->length > -1) { 4557f30a007Schristos size = (unsigned int)key->length; 4567f30a007Schristos if (size < min) { 4577f30a007Schristos size = min; 4587f30a007Schristos } 4597f30a007Schristos if (size > 4096) { 4607f30a007Schristos size = 4096; 4617f30a007Schristos } 4627f30a007Schristos } else { 4637f30a007Schristos size = 2048; 4647f30a007Schristos } 4657f30a007Schristos break; 4667f30a007Schristos case DNS_KEYALG_ECDSA256: 4677f30a007Schristos size = 256; 4687f30a007Schristos break; 4697f30a007Schristos case DNS_KEYALG_ECDSA384: 4707f30a007Schristos size = 384; 4717f30a007Schristos break; 4727f30a007Schristos case DNS_KEYALG_ED25519: 473fce770bdSchristos size = 256; 4747f30a007Schristos break; 4757f30a007Schristos case DNS_KEYALG_ED448: 476fce770bdSchristos size = 456; 4777f30a007Schristos break; 4787f30a007Schristos default: 4797f30a007Schristos /* unsupported */ 4807f30a007Schristos break; 4817f30a007Schristos } 482*bcda20f6Schristos return size; 4837f30a007Schristos } 4847f30a007Schristos 4857f30a007Schristos uint32_t 4867f30a007Schristos dns_kasp_key_lifetime(dns_kasp_key_t *key) { 4877f30a007Schristos REQUIRE(key != NULL); 4887f30a007Schristos 489*bcda20f6Schristos return key->lifetime; 490*bcda20f6Schristos } 491*bcda20f6Schristos 492*bcda20f6Schristos dns_keystore_t * 493*bcda20f6Schristos dns_kasp_key_keystore(dns_kasp_key_t *key) { 494*bcda20f6Schristos REQUIRE(key != NULL); 495*bcda20f6Schristos 496*bcda20f6Schristos return key->keystore; 4977f30a007Schristos } 4987f30a007Schristos 4997f30a007Schristos bool 5007f30a007Schristos dns_kasp_key_ksk(dns_kasp_key_t *key) { 5017f30a007Schristos REQUIRE(key != NULL); 5027f30a007Schristos 503*bcda20f6Schristos return key->role & DNS_KASP_KEY_ROLE_KSK; 5047f30a007Schristos } 5057f30a007Schristos 5067f30a007Schristos bool 5077f30a007Schristos dns_kasp_key_zsk(dns_kasp_key_t *key) { 5087f30a007Schristos REQUIRE(key != NULL); 5097f30a007Schristos 510*bcda20f6Schristos return key->role & DNS_KASP_KEY_ROLE_ZSK; 511*bcda20f6Schristos } 512*bcda20f6Schristos 513*bcda20f6Schristos uint16_t 514*bcda20f6Schristos dns_kasp_key_tagmin(dns_kasp_key_t *key) { 515*bcda20f6Schristos REQUIRE(key != NULL); 516*bcda20f6Schristos return key->tag_min; 517*bcda20f6Schristos } 518*bcda20f6Schristos 519*bcda20f6Schristos uint16_t 520*bcda20f6Schristos dns_kasp_key_tagmax(dns_kasp_key_t *key) { 521*bcda20f6Schristos REQUIRE(key != NULL); 522*bcda20f6Schristos return key->tag_min; 523*bcda20f6Schristos } 524*bcda20f6Schristos 525*bcda20f6Schristos bool 526*bcda20f6Schristos dns_kasp_key_match(dns_kasp_key_t *key, dns_dnsseckey_t *dkey) { 527*bcda20f6Schristos isc_result_t ret; 528*bcda20f6Schristos bool role = false; 529*bcda20f6Schristos 530*bcda20f6Schristos REQUIRE(key != NULL); 531*bcda20f6Schristos REQUIRE(dkey != NULL); 532*bcda20f6Schristos 533*bcda20f6Schristos /* Matching algorithms? */ 534*bcda20f6Schristos if (dst_key_alg(dkey->key) != dns_kasp_key_algorithm(key)) { 535*bcda20f6Schristos return false; 536*bcda20f6Schristos } 537*bcda20f6Schristos /* Matching length? */ 538*bcda20f6Schristos if (dst_key_size(dkey->key) != dns_kasp_key_size(key)) { 539*bcda20f6Schristos return false; 540*bcda20f6Schristos } 541*bcda20f6Schristos /* Matching role? */ 542*bcda20f6Schristos ret = dst_key_getbool(dkey->key, DST_BOOL_KSK, &role); 543*bcda20f6Schristos if (ret != ISC_R_SUCCESS || role != dns_kasp_key_ksk(key)) { 544*bcda20f6Schristos return false; 545*bcda20f6Schristos } 546*bcda20f6Schristos ret = dst_key_getbool(dkey->key, DST_BOOL_ZSK, &role); 547*bcda20f6Schristos if (ret != ISC_R_SUCCESS || role != dns_kasp_key_zsk(key)) { 548*bcda20f6Schristos return false; 549*bcda20f6Schristos } 550*bcda20f6Schristos /* Valid key tag range? */ 551*bcda20f6Schristos uint16_t id = dst_key_id(dkey->key); 552*bcda20f6Schristos uint16_t rid = dst_key_rid(dkey->key); 553*bcda20f6Schristos if (id < key->tag_min || id > key->tag_max) { 554*bcda20f6Schristos return false; 555*bcda20f6Schristos } 556*bcda20f6Schristos if (rid < key->tag_min || rid > key->tag_max) { 557*bcda20f6Schristos return false; 558*bcda20f6Schristos } 559*bcda20f6Schristos 560*bcda20f6Schristos /* Found a match. */ 561*bcda20f6Schristos return true; 5627f30a007Schristos } 563fce770bdSchristos 564fce770bdSchristos uint8_t 565fce770bdSchristos dns_kasp_nsec3iter(dns_kasp_t *kasp) { 566fce770bdSchristos REQUIRE(kasp != NULL); 567fce770bdSchristos REQUIRE(kasp->frozen); 568fce770bdSchristos REQUIRE(kasp->nsec3); 569fce770bdSchristos 570*bcda20f6Schristos return kasp->nsec3param.iterations; 571fce770bdSchristos } 572fce770bdSchristos 573fce770bdSchristos uint8_t 574fce770bdSchristos dns_kasp_nsec3flags(dns_kasp_t *kasp) { 575fce770bdSchristos REQUIRE(kasp != NULL); 576fce770bdSchristos REQUIRE(kasp->frozen); 577fce770bdSchristos REQUIRE(kasp->nsec3); 578fce770bdSchristos 579fce770bdSchristos if (kasp->nsec3param.optout) { 580*bcda20f6Schristos return 0x01; 581fce770bdSchristos } 582*bcda20f6Schristos return 0x00; 583fce770bdSchristos } 584fce770bdSchristos 585fce770bdSchristos uint8_t 586fce770bdSchristos dns_kasp_nsec3saltlen(dns_kasp_t *kasp) { 587fce770bdSchristos REQUIRE(kasp != NULL); 588fce770bdSchristos REQUIRE(kasp->frozen); 589fce770bdSchristos REQUIRE(kasp->nsec3); 590fce770bdSchristos 591*bcda20f6Schristos return kasp->nsec3param.saltlen; 592fce770bdSchristos } 593fce770bdSchristos 594fce770bdSchristos bool 595fce770bdSchristos dns_kasp_nsec3(dns_kasp_t *kasp) { 596fce770bdSchristos REQUIRE(kasp != NULL); 597fce770bdSchristos REQUIRE(kasp->frozen); 598fce770bdSchristos 599fce770bdSchristos return kasp->nsec3; 600fce770bdSchristos } 601fce770bdSchristos 602fce770bdSchristos void 603fce770bdSchristos dns_kasp_setnsec3(dns_kasp_t *kasp, bool nsec3) { 604fce770bdSchristos REQUIRE(kasp != NULL); 605fce770bdSchristos REQUIRE(!kasp->frozen); 606fce770bdSchristos 607fce770bdSchristos kasp->nsec3 = nsec3; 608fce770bdSchristos } 609fce770bdSchristos 610fce770bdSchristos void 611fce770bdSchristos dns_kasp_setnsec3param(dns_kasp_t *kasp, uint8_t iter, bool optout, 612fce770bdSchristos uint8_t saltlen) { 613fce770bdSchristos REQUIRE(kasp != NULL); 614fce770bdSchristos REQUIRE(!kasp->frozen); 615fce770bdSchristos REQUIRE(kasp->nsec3); 616fce770bdSchristos 617fce770bdSchristos kasp->nsec3param.iterations = iter; 618fce770bdSchristos kasp->nsec3param.optout = optout; 619fce770bdSchristos kasp->nsec3param.saltlen = saltlen; 620fce770bdSchristos } 621*bcda20f6Schristos 622*bcda20f6Schristos bool 623*bcda20f6Schristos dns_kasp_offlineksk(dns_kasp_t *kasp) { 624*bcda20f6Schristos REQUIRE(kasp != NULL); 625*bcda20f6Schristos REQUIRE(kasp->frozen); 626*bcda20f6Schristos 627*bcda20f6Schristos return kasp->offlineksk; 628*bcda20f6Schristos } 629*bcda20f6Schristos 630*bcda20f6Schristos void 631*bcda20f6Schristos dns_kasp_setofflineksk(dns_kasp_t *kasp, bool offlineksk) { 632*bcda20f6Schristos REQUIRE(kasp != NULL); 633*bcda20f6Schristos REQUIRE(!kasp->frozen); 634*bcda20f6Schristos 635*bcda20f6Schristos kasp->offlineksk = offlineksk; 636*bcda20f6Schristos } 637*bcda20f6Schristos 638*bcda20f6Schristos bool 639*bcda20f6Schristos dns_kasp_cdnskey(dns_kasp_t *kasp) { 640*bcda20f6Schristos REQUIRE(kasp != NULL); 641*bcda20f6Schristos REQUIRE(kasp->frozen); 642*bcda20f6Schristos 643*bcda20f6Schristos return kasp->cdnskey; 644*bcda20f6Schristos } 645*bcda20f6Schristos 646*bcda20f6Schristos void 647*bcda20f6Schristos dns_kasp_setcdnskey(dns_kasp_t *kasp, bool cdnskey) { 648*bcda20f6Schristos REQUIRE(kasp != NULL); 649*bcda20f6Schristos REQUIRE(!kasp->frozen); 650*bcda20f6Schristos 651*bcda20f6Schristos kasp->cdnskey = cdnskey; 652*bcda20f6Schristos } 653*bcda20f6Schristos 654*bcda20f6Schristos dns_kasp_digestlist_t 655*bcda20f6Schristos dns_kasp_digests(dns_kasp_t *kasp) { 656*bcda20f6Schristos REQUIRE(DNS_KASP_VALID(kasp)); 657*bcda20f6Schristos REQUIRE(kasp->frozen); 658*bcda20f6Schristos 659*bcda20f6Schristos return kasp->digests; 660*bcda20f6Schristos } 661*bcda20f6Schristos 662*bcda20f6Schristos void 663*bcda20f6Schristos dns_kasp_adddigest(dns_kasp_t *kasp, dns_dsdigest_t alg) { 664*bcda20f6Schristos dns_kasp_digest_t *digest; 665*bcda20f6Schristos 666*bcda20f6Schristos REQUIRE(DNS_KASP_VALID(kasp)); 667*bcda20f6Schristos REQUIRE(!kasp->frozen); 668*bcda20f6Schristos 669*bcda20f6Schristos /* Suppress unsupported algorithms */ 670*bcda20f6Schristos if (!dst_ds_digest_supported(alg)) { 671*bcda20f6Schristos return; 672*bcda20f6Schristos } 673*bcda20f6Schristos 674*bcda20f6Schristos /* Suppress duplicates */ 675*bcda20f6Schristos for (dns_kasp_digest_t *d = ISC_LIST_HEAD(kasp->digests); d != NULL; 676*bcda20f6Schristos d = ISC_LIST_NEXT(d, link)) 677*bcda20f6Schristos { 678*bcda20f6Schristos if (d->digest == alg) { 679*bcda20f6Schristos return; 680*bcda20f6Schristos } 681*bcda20f6Schristos } 682*bcda20f6Schristos 683*bcda20f6Schristos digest = isc_mem_get(kasp->mctx, sizeof(*digest)); 684*bcda20f6Schristos digest->digest = alg; 685*bcda20f6Schristos ISC_LINK_INIT(digest, link); 686*bcda20f6Schristos ISC_LIST_APPEND(kasp->digests, digest, link); 687*bcda20f6Schristos } 688