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