1 /* $NetBSD: kasp.c,v 1.6 2024/02/21 22:52:06 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 /*! \file */ 17 18 #include <string.h> 19 20 #include <isc/assertions.h> 21 #include <isc/buffer.h> 22 #include <isc/file.h> 23 #include <isc/hex.h> 24 #include <isc/log.h> 25 #include <isc/mem.h> 26 #include <isc/util.h> 27 28 #include <dns/kasp.h> 29 #include <dns/keyvalues.h> 30 #include <dns/log.h> 31 32 /* Default TTLsig (maximum zone ttl) */ 33 #define DEFAULT_TTLSIG 604800 /* one week */ 34 35 isc_result_t 36 dns_kasp_create(isc_mem_t *mctx, const char *name, dns_kasp_t **kaspp) { 37 dns_kasp_t *kasp; 38 dns_kasp_t k = { 39 .magic = DNS_KASP_MAGIC, 40 }; 41 42 REQUIRE(name != NULL); 43 REQUIRE(kaspp != NULL && *kaspp == NULL); 44 45 kasp = isc_mem_get(mctx, sizeof(*kasp)); 46 *kasp = k; 47 48 kasp->mctx = NULL; 49 isc_mem_attach(mctx, &kasp->mctx); 50 kasp->name = isc_mem_strdup(mctx, name); 51 isc_mutex_init(&kasp->lock); 52 isc_refcount_init(&kasp->references, 1); 53 54 ISC_LINK_INIT(kasp, link); 55 ISC_LIST_INIT(kasp->keys); 56 57 *kaspp = kasp; 58 return (ISC_R_SUCCESS); 59 } 60 61 void 62 dns_kasp_attach(dns_kasp_t *source, dns_kasp_t **targetp) { 63 REQUIRE(DNS_KASP_VALID(source)); 64 REQUIRE(targetp != NULL && *targetp == NULL); 65 66 isc_refcount_increment(&source->references); 67 *targetp = source; 68 } 69 70 static void 71 destroy(dns_kasp_t *kasp) { 72 dns_kasp_key_t *key; 73 dns_kasp_key_t *key_next; 74 75 REQUIRE(!ISC_LINK_LINKED(kasp, link)); 76 77 for (key = ISC_LIST_HEAD(kasp->keys); key != NULL; key = key_next) { 78 key_next = ISC_LIST_NEXT(key, link); 79 ISC_LIST_UNLINK(kasp->keys, key, link); 80 dns_kasp_key_destroy(key); 81 } 82 INSIST(ISC_LIST_EMPTY(kasp->keys)); 83 84 isc_mutex_destroy(&kasp->lock); 85 isc_mem_free(kasp->mctx, kasp->name); 86 isc_mem_putanddetach(&kasp->mctx, kasp, sizeof(*kasp)); 87 } 88 89 void 90 dns_kasp_detach(dns_kasp_t **kaspp) { 91 REQUIRE(kaspp != NULL && DNS_KASP_VALID(*kaspp)); 92 93 dns_kasp_t *kasp = *kaspp; 94 *kaspp = NULL; 95 96 if (isc_refcount_decrement(&kasp->references) == 1) { 97 destroy(kasp); 98 } 99 } 100 101 const char * 102 dns_kasp_getname(dns_kasp_t *kasp) { 103 REQUIRE(DNS_KASP_VALID(kasp)); 104 105 return (kasp->name); 106 } 107 108 void 109 dns_kasp_freeze(dns_kasp_t *kasp) { 110 REQUIRE(DNS_KASP_VALID(kasp)); 111 REQUIRE(!kasp->frozen); 112 113 kasp->frozen = true; 114 } 115 116 void 117 dns_kasp_thaw(dns_kasp_t *kasp) { 118 REQUIRE(DNS_KASP_VALID(kasp)); 119 REQUIRE(kasp->frozen); 120 121 kasp->frozen = false; 122 } 123 124 uint32_t 125 dns_kasp_signdelay(dns_kasp_t *kasp) { 126 REQUIRE(DNS_KASP_VALID(kasp)); 127 REQUIRE(kasp->frozen); 128 129 return (kasp->signatures_validity - kasp->signatures_refresh); 130 } 131 132 uint32_t 133 dns_kasp_sigrefresh(dns_kasp_t *kasp) { 134 REQUIRE(DNS_KASP_VALID(kasp)); 135 REQUIRE(kasp->frozen); 136 137 return (kasp->signatures_refresh); 138 } 139 140 void 141 dns_kasp_setsigrefresh(dns_kasp_t *kasp, uint32_t value) { 142 REQUIRE(DNS_KASP_VALID(kasp)); 143 REQUIRE(!kasp->frozen); 144 145 kasp->signatures_refresh = value; 146 } 147 148 uint32_t 149 dns_kasp_sigvalidity(dns_kasp_t *kasp) { 150 REQUIRE(DNS_KASP_VALID(kasp)); 151 REQUIRE(kasp->frozen); 152 153 return (kasp->signatures_validity); 154 } 155 156 void 157 dns_kasp_setsigvalidity(dns_kasp_t *kasp, uint32_t value) { 158 REQUIRE(DNS_KASP_VALID(kasp)); 159 REQUIRE(!kasp->frozen); 160 161 kasp->signatures_validity = value; 162 } 163 164 uint32_t 165 dns_kasp_sigvalidity_dnskey(dns_kasp_t *kasp) { 166 REQUIRE(DNS_KASP_VALID(kasp)); 167 REQUIRE(kasp->frozen); 168 169 return (kasp->signatures_validity_dnskey); 170 } 171 172 void 173 dns_kasp_setsigvalidity_dnskey(dns_kasp_t *kasp, uint32_t value) { 174 REQUIRE(DNS_KASP_VALID(kasp)); 175 REQUIRE(!kasp->frozen); 176 177 kasp->signatures_validity_dnskey = value; 178 } 179 180 dns_ttl_t 181 dns_kasp_dnskeyttl(dns_kasp_t *kasp) { 182 REQUIRE(DNS_KASP_VALID(kasp)); 183 REQUIRE(kasp->frozen); 184 185 return (kasp->dnskey_ttl); 186 } 187 188 void 189 dns_kasp_setdnskeyttl(dns_kasp_t *kasp, dns_ttl_t ttl) { 190 REQUIRE(DNS_KASP_VALID(kasp)); 191 REQUIRE(!kasp->frozen); 192 193 kasp->dnskey_ttl = ttl; 194 } 195 196 uint32_t 197 dns_kasp_purgekeys(dns_kasp_t *kasp) { 198 REQUIRE(DNS_KASP_VALID(kasp)); 199 REQUIRE(kasp->frozen); 200 201 return (kasp->purge_keys); 202 } 203 204 void 205 dns_kasp_setpurgekeys(dns_kasp_t *kasp, uint32_t value) { 206 REQUIRE(DNS_KASP_VALID(kasp)); 207 REQUIRE(!kasp->frozen); 208 209 kasp->purge_keys = value; 210 } 211 212 uint32_t 213 dns_kasp_publishsafety(dns_kasp_t *kasp) { 214 REQUIRE(DNS_KASP_VALID(kasp)); 215 REQUIRE(kasp->frozen); 216 217 return (kasp->publish_safety); 218 } 219 220 void 221 dns_kasp_setpublishsafety(dns_kasp_t *kasp, uint32_t value) { 222 REQUIRE(DNS_KASP_VALID(kasp)); 223 REQUIRE(!kasp->frozen); 224 225 kasp->publish_safety = value; 226 } 227 228 uint32_t 229 dns_kasp_retiresafety(dns_kasp_t *kasp) { 230 REQUIRE(DNS_KASP_VALID(kasp)); 231 REQUIRE(kasp->frozen); 232 233 return (kasp->retire_safety); 234 } 235 236 void 237 dns_kasp_setretiresafety(dns_kasp_t *kasp, uint32_t value) { 238 REQUIRE(DNS_KASP_VALID(kasp)); 239 REQUIRE(!kasp->frozen); 240 241 kasp->retire_safety = value; 242 } 243 244 dns_ttl_t 245 dns_kasp_zonemaxttl(dns_kasp_t *kasp, bool fallback) { 246 REQUIRE(DNS_KASP_VALID(kasp)); 247 REQUIRE(kasp->frozen); 248 249 if (kasp->zone_max_ttl == 0 && fallback) { 250 return (DEFAULT_TTLSIG); 251 } 252 return (kasp->zone_max_ttl); 253 } 254 255 void 256 dns_kasp_setzonemaxttl(dns_kasp_t *kasp, dns_ttl_t ttl) { 257 REQUIRE(DNS_KASP_VALID(kasp)); 258 REQUIRE(!kasp->frozen); 259 260 kasp->zone_max_ttl = ttl; 261 } 262 263 uint32_t 264 dns_kasp_zonepropagationdelay(dns_kasp_t *kasp) { 265 REQUIRE(DNS_KASP_VALID(kasp)); 266 REQUIRE(kasp->frozen); 267 268 return (kasp->zone_propagation_delay); 269 } 270 271 void 272 dns_kasp_setzonepropagationdelay(dns_kasp_t *kasp, uint32_t value) { 273 REQUIRE(DNS_KASP_VALID(kasp)); 274 REQUIRE(!kasp->frozen); 275 276 kasp->zone_propagation_delay = value; 277 } 278 279 dns_ttl_t 280 dns_kasp_dsttl(dns_kasp_t *kasp) { 281 REQUIRE(DNS_KASP_VALID(kasp)); 282 REQUIRE(kasp->frozen); 283 284 return (kasp->parent_ds_ttl); 285 } 286 287 void 288 dns_kasp_setdsttl(dns_kasp_t *kasp, dns_ttl_t ttl) { 289 REQUIRE(DNS_KASP_VALID(kasp)); 290 REQUIRE(!kasp->frozen); 291 292 kasp->parent_ds_ttl = ttl; 293 } 294 295 uint32_t 296 dns_kasp_parentpropagationdelay(dns_kasp_t *kasp) { 297 REQUIRE(DNS_KASP_VALID(kasp)); 298 REQUIRE(kasp->frozen); 299 300 return (kasp->parent_propagation_delay); 301 } 302 303 void 304 dns_kasp_setparentpropagationdelay(dns_kasp_t *kasp, uint32_t value) { 305 REQUIRE(DNS_KASP_VALID(kasp)); 306 REQUIRE(!kasp->frozen); 307 308 kasp->parent_propagation_delay = value; 309 } 310 311 isc_result_t 312 dns_kasplist_find(dns_kasplist_t *list, const char *name, dns_kasp_t **kaspp) { 313 dns_kasp_t *kasp = NULL; 314 315 REQUIRE(kaspp != NULL && *kaspp == NULL); 316 317 if (list == NULL) { 318 return (ISC_R_NOTFOUND); 319 } 320 321 for (kasp = ISC_LIST_HEAD(*list); kasp != NULL; 322 kasp = ISC_LIST_NEXT(kasp, link)) 323 { 324 if (strcmp(kasp->name, name) == 0) { 325 break; 326 } 327 } 328 329 if (kasp == NULL) { 330 return (ISC_R_NOTFOUND); 331 } 332 333 dns_kasp_attach(kasp, kaspp); 334 return (ISC_R_SUCCESS); 335 } 336 337 dns_kasp_keylist_t 338 dns_kasp_keys(dns_kasp_t *kasp) { 339 REQUIRE(DNS_KASP_VALID(kasp)); 340 REQUIRE(kasp->frozen); 341 342 return (kasp->keys); 343 } 344 345 bool 346 dns_kasp_keylist_empty(dns_kasp_t *kasp) { 347 REQUIRE(DNS_KASP_VALID(kasp)); 348 349 return (ISC_LIST_EMPTY(kasp->keys)); 350 } 351 352 void 353 dns_kasp_addkey(dns_kasp_t *kasp, dns_kasp_key_t *key) { 354 REQUIRE(DNS_KASP_VALID(kasp)); 355 REQUIRE(!kasp->frozen); 356 REQUIRE(key != NULL); 357 358 ISC_LIST_APPEND(kasp->keys, key, link); 359 } 360 361 isc_result_t 362 dns_kasp_key_create(dns_kasp_t *kasp, dns_kasp_key_t **keyp) { 363 dns_kasp_key_t *key; 364 365 REQUIRE(DNS_KASP_VALID(kasp)); 366 REQUIRE(keyp != NULL && *keyp == NULL); 367 368 key = isc_mem_get(kasp->mctx, sizeof(*key)); 369 key->mctx = NULL; 370 isc_mem_attach(kasp->mctx, &key->mctx); 371 372 ISC_LINK_INIT(key, link); 373 374 key->lifetime = 0; 375 key->algorithm = 0; 376 key->length = -1; 377 key->role = 0; 378 *keyp = key; 379 return (ISC_R_SUCCESS); 380 } 381 382 void 383 dns_kasp_key_destroy(dns_kasp_key_t *key) { 384 REQUIRE(key != NULL); 385 386 isc_mem_putanddetach(&key->mctx, key, sizeof(*key)); 387 } 388 389 uint32_t 390 dns_kasp_key_algorithm(dns_kasp_key_t *key) { 391 REQUIRE(key != NULL); 392 393 return (key->algorithm); 394 } 395 396 unsigned int 397 dns_kasp_key_size(dns_kasp_key_t *key) { 398 unsigned int size = 0; 399 unsigned int min = 0; 400 401 REQUIRE(key != NULL); 402 403 switch (key->algorithm) { 404 case DNS_KEYALG_RSASHA1: 405 case DNS_KEYALG_NSEC3RSASHA1: 406 case DNS_KEYALG_RSASHA256: 407 case DNS_KEYALG_RSASHA512: 408 min = (key->algorithm == DNS_KEYALG_RSASHA512) ? 1024 : 512; 409 if (key->length > -1) { 410 size = (unsigned int)key->length; 411 if (size < min) { 412 size = min; 413 } 414 if (size > 4096) { 415 size = 4096; 416 } 417 } else { 418 size = 2048; 419 } 420 break; 421 case DNS_KEYALG_ECDSA256: 422 size = 256; 423 break; 424 case DNS_KEYALG_ECDSA384: 425 size = 384; 426 break; 427 case DNS_KEYALG_ED25519: 428 size = 256; 429 break; 430 case DNS_KEYALG_ED448: 431 size = 456; 432 break; 433 default: 434 /* unsupported */ 435 break; 436 } 437 return (size); 438 } 439 440 uint32_t 441 dns_kasp_key_lifetime(dns_kasp_key_t *key) { 442 REQUIRE(key != NULL); 443 444 return (key->lifetime); 445 } 446 447 bool 448 dns_kasp_key_ksk(dns_kasp_key_t *key) { 449 REQUIRE(key != NULL); 450 451 return (key->role & DNS_KASP_KEY_ROLE_KSK); 452 } 453 454 bool 455 dns_kasp_key_zsk(dns_kasp_key_t *key) { 456 REQUIRE(key != NULL); 457 458 return (key->role & DNS_KASP_KEY_ROLE_ZSK); 459 } 460 461 uint8_t 462 dns_kasp_nsec3iter(dns_kasp_t *kasp) { 463 REQUIRE(kasp != NULL); 464 REQUIRE(kasp->frozen); 465 REQUIRE(kasp->nsec3); 466 467 return (kasp->nsec3param.iterations); 468 } 469 470 uint8_t 471 dns_kasp_nsec3flags(dns_kasp_t *kasp) { 472 REQUIRE(kasp != NULL); 473 REQUIRE(kasp->frozen); 474 REQUIRE(kasp->nsec3); 475 476 if (kasp->nsec3param.optout) { 477 return (0x01); 478 } 479 return (0x00); 480 } 481 482 uint8_t 483 dns_kasp_nsec3saltlen(dns_kasp_t *kasp) { 484 REQUIRE(kasp != NULL); 485 REQUIRE(kasp->frozen); 486 REQUIRE(kasp->nsec3); 487 488 return (kasp->nsec3param.saltlen); 489 } 490 491 bool 492 dns_kasp_nsec3(dns_kasp_t *kasp) { 493 REQUIRE(kasp != NULL); 494 REQUIRE(kasp->frozen); 495 496 return kasp->nsec3; 497 } 498 499 void 500 dns_kasp_setnsec3(dns_kasp_t *kasp, bool nsec3) { 501 REQUIRE(kasp != NULL); 502 REQUIRE(!kasp->frozen); 503 504 kasp->nsec3 = nsec3; 505 } 506 507 void 508 dns_kasp_setnsec3param(dns_kasp_t *kasp, uint8_t iter, bool optout, 509 uint8_t saltlen) { 510 REQUIRE(kasp != NULL); 511 REQUIRE(!kasp->frozen); 512 REQUIRE(kasp->nsec3); 513 514 kasp->nsec3param.iterations = iter; 515 kasp->nsec3param.optout = optout; 516 kasp->nsec3param.saltlen = saltlen; 517 } 518