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