1 /* $NetBSD: keymgr.c,v 1.3 2020/08/03 17:23:41 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 <inttypes.h> 17 #include <stdbool.h> 18 #include <stdlib.h> 19 20 #include <isc/buffer.h> 21 #include <isc/dir.h> 22 #include <isc/mem.h> 23 #include <isc/print.h> 24 #include <isc/string.h> 25 #include <isc/util.h> 26 27 #include <dns/dnssec.h> 28 #include <dns/kasp.h> 29 #include <dns/keymgr.h> 30 #include <dns/keyvalues.h> 31 #include <dns/log.h> 32 #include <dns/result.h> 33 34 #include <dst/dst.h> 35 #include <dst/result.h> 36 37 #define RETERR(x) \ 38 do { \ 39 result = (x); \ 40 if (result != ISC_R_SUCCESS) \ 41 goto failure; \ 42 } while (/*CONSTCOND*/0) 43 44 /* 45 * Set key state to `target` state and change last changed 46 * to `time`, only if key state has not been set before. 47 */ 48 #define INITIALIZE_STATE(key, state, timing, target, time) \ 49 do { \ 50 dst_key_state_t s; \ 51 if (dst_key_getstate((key), (state), &s) == ISC_R_NOTFOUND) { \ 52 dst_key_setstate((key), (state), (target)); \ 53 dst_key_settime((key), (timing), time); \ 54 } \ 55 } while (/*CONSTCOND*/0) 56 57 /* Shorter keywords for better readability. */ 58 #define HIDDEN DST_KEY_STATE_HIDDEN 59 #define RUMOURED DST_KEY_STATE_RUMOURED 60 #define OMNIPRESENT DST_KEY_STATE_OMNIPRESENT 61 #define UNRETENTIVE DST_KEY_STATE_UNRETENTIVE 62 #define NA DST_KEY_STATE_NA 63 64 /* Quickly get key state timing metadata. */ 65 #define NUM_KEYSTATES (DST_MAX_KEYSTATES) 66 static int keystatetimes[NUM_KEYSTATES] = { DST_TIME_DNSKEY, DST_TIME_ZRRSIG, 67 DST_TIME_KRRSIG, DST_TIME_DS }; 68 /* Readable key state types and values. */ 69 static const char *keystatetags[NUM_KEYSTATES] = { "DNSKEY", "ZRRSIG", "KRRSIG", 70 "DS" }; 71 static const char *keystatestrings[4] = { "HIDDEN", "RUMOURED", "OMNIPRESENT", 72 "UNRETENTIVE" }; 73 74 /* 75 * Print key role. 76 * 77 */ 78 static const char * 79 keymgr_keyrole(dst_key_t *key) { 80 bool ksk, zsk; 81 dst_key_getbool(key, DST_BOOL_KSK, &ksk); 82 dst_key_getbool(key, DST_BOOL_ZSK, &zsk); 83 if (ksk && zsk) { 84 return ("CSK"); 85 } else if (ksk) { 86 return ("KSK"); 87 } else if (zsk) { 88 return ("ZSK"); 89 } 90 return ("NOSIGN"); 91 } 92 93 /* 94 * Set the remove time on key given its retire time. 95 * 96 */ 97 static void 98 keymgr_settime_remove(dns_dnsseckey_t *key, dns_kasp_t *kasp) { 99 isc_stdtime_t retire = 0, remove = 0, ksk_remove = 0, zsk_remove = 0; 100 bool zsk = false, ksk = false; 101 isc_result_t ret; 102 103 REQUIRE(key != NULL); 104 REQUIRE(key->key != NULL); 105 106 ret = dst_key_gettime(key->key, DST_TIME_INACTIVE, &retire); 107 if (ret != ISC_R_SUCCESS) { 108 return; 109 } 110 111 ret = dst_key_getbool(key->key, DST_BOOL_ZSK, &zsk); 112 if (ret == ISC_R_SUCCESS && zsk) { 113 /* ZSK: Iret = Dsgn + Dprp + TTLsig */ 114 zsk_remove = retire + dns_kasp_zonemaxttl(kasp) + 115 dns_kasp_zonepropagationdelay(kasp) + 116 dns_kasp_retiresafety(kasp) + 117 dns_kasp_signdelay(kasp); 118 } 119 ret = dst_key_getbool(key->key, DST_BOOL_KSK, &ksk); 120 if (ret == ISC_R_SUCCESS && ksk) { 121 /* KSK: Iret = DprpP + TTLds */ 122 ksk_remove = retire + dns_kasp_dsttl(kasp) + 123 dns_kasp_parentpropagationdelay(kasp) + 124 dns_kasp_retiresafety(kasp); 125 } 126 if (zsk && ksk) { 127 ksk_remove += dns_kasp_parentregistrationdelay(kasp); 128 } 129 130 remove = ksk_remove > zsk_remove ? ksk_remove : zsk_remove; 131 dst_key_settime(key->key, DST_TIME_DELETE, remove); 132 } 133 134 /* 135 * Set the SyncPublish time (when the DS may be submitted to the parent) 136 * 137 */ 138 static void 139 keymgr_settime_syncpublish(dns_dnsseckey_t *key, dns_kasp_t *kasp, bool first) { 140 isc_stdtime_t published, syncpublish; 141 bool ksk = false; 142 isc_result_t ret; 143 144 REQUIRE(key != NULL); 145 REQUIRE(key->key != NULL); 146 147 ret = dst_key_gettime(key->key, DST_TIME_PUBLISH, &published); 148 if (ret != ISC_R_SUCCESS) { 149 return; 150 } 151 152 ret = dst_key_getbool(key->key, DST_BOOL_KSK, &ksk); 153 if (ret != ISC_R_SUCCESS || !ksk) { 154 return; 155 } 156 157 syncpublish = published + dst_key_getttl(key->key) + 158 dns_kasp_zonepropagationdelay(kasp) + 159 dns_kasp_publishsafety(kasp); 160 if (first) { 161 /* Also need to wait until the signatures are omnipresent. */ 162 isc_stdtime_t zrrsig_present; 163 zrrsig_present = published + dns_kasp_zonemaxttl(kasp) + 164 dns_kasp_zonepropagationdelay(kasp) + 165 dns_kasp_publishsafety(kasp); 166 if (zrrsig_present > syncpublish) { 167 syncpublish = zrrsig_present; 168 } 169 } 170 dst_key_settime(key->key, DST_TIME_SYNCPUBLISH, syncpublish); 171 } 172 173 /* 174 * Calculate prepublication time of a successor key of 'key'. 175 * This function can have side effects: 176 * 1. If there is no active time set, which would be super weird, set it now. 177 * 2. If there is no published time set, also super weird, set it now. 178 * 3. If there is no syncpublished time set, set it now. 179 * 4. If the lifetime is not set, it will be set now. 180 * 5. If there should be a retire time and it is not set, it will be set now. 181 * 6. The removed time is adjusted accordingly. 182 * 183 * This returns when the successor key needs to be published in the zone. 184 * A special value of 0 means there is no need for a successor. 185 * 186 */ 187 static isc_stdtime_t 188 keymgr_prepublication_time(dns_dnsseckey_t *key, dns_kasp_t *kasp, 189 uint32_t lifetime, isc_stdtime_t now) { 190 isc_result_t ret; 191 isc_stdtime_t active, retire, pub, prepub; 192 bool zsk = false, ksk = false; 193 194 REQUIRE(key != NULL); 195 REQUIRE(key->key != NULL); 196 197 active = 0; 198 pub = 0; 199 retire = 0; 200 201 /* 202 * An active key must have publish and activate timing 203 * metadata. 204 */ 205 ret = dst_key_gettime(key->key, DST_TIME_ACTIVATE, &active); 206 if (ret != ISC_R_SUCCESS) { 207 /* Super weird, but if it happens, set it to now. */ 208 dst_key_settime(key->key, DST_TIME_ACTIVATE, now); 209 active = now; 210 } 211 ret = dst_key_gettime(key->key, DST_TIME_PUBLISH, &pub); 212 if (ret != ISC_R_SUCCESS) { 213 /* Super weird, but if it happens, set it to now. */ 214 dst_key_settime(key->key, DST_TIME_PUBLISH, now); 215 pub = now; 216 } 217 218 /* 219 * Calculate prepublication time. 220 */ 221 prepub = dst_key_getttl(key->key) + dns_kasp_publishsafety(kasp) + 222 dns_kasp_zonepropagationdelay(kasp); 223 ret = dst_key_getbool(key->key, DST_BOOL_KSK, &ksk); 224 if (ret == ISC_R_SUCCESS && ksk) { 225 isc_stdtime_t syncpub; 226 227 /* 228 * Set PublishCDS if not set. 229 */ 230 ret = dst_key_gettime(key->key, DST_TIME_SYNCPUBLISH, &syncpub); 231 if (ret != ISC_R_SUCCESS) { 232 uint32_t tag; 233 isc_stdtime_t syncpub1, syncpub2; 234 235 syncpub1 = pub + prepub; 236 syncpub2 = 0; 237 ret = dst_key_getnum(key->key, DST_NUM_PREDECESSOR, 238 &tag); 239 if (ret != ISC_R_SUCCESS) { 240 /* 241 * No predecessor, wait for zone to be 242 * completely signed. 243 */ 244 syncpub2 = pub + dns_kasp_zonemaxttl(kasp) + 245 dns_kasp_publishsafety(kasp) + 246 dns_kasp_zonepropagationdelay(kasp); 247 } 248 249 syncpub = syncpub1 > syncpub2 ? syncpub1 : syncpub2; 250 dst_key_settime(key->key, DST_TIME_SYNCPUBLISH, 251 syncpub); 252 } 253 } 254 255 (void)dst_key_getbool(key->key, DST_BOOL_ZSK, &zsk); 256 if (!zsk && ksk) { 257 /* 258 * Include registration delay in prepublication time. 259 */ 260 prepub += dns_kasp_parentregistrationdelay(kasp); 261 } 262 263 ret = dst_key_gettime(key->key, DST_TIME_INACTIVE, &retire); 264 if (ret != ISC_R_SUCCESS) { 265 uint32_t klifetime = 0; 266 267 ret = dst_key_getnum(key->key, DST_NUM_LIFETIME, &klifetime); 268 if (ret != ISC_R_SUCCESS) { 269 dst_key_setnum(key->key, DST_NUM_LIFETIME, lifetime); 270 klifetime = lifetime; 271 } 272 if (klifetime == 0) { 273 /* 274 * No inactive time and no lifetime, 275 * so no need to start a rollover. 276 */ 277 return (0); 278 } 279 280 retire = active + klifetime; 281 dst_key_settime(key->key, DST_TIME_INACTIVE, retire); 282 } 283 284 /* 285 * Update remove time. 286 */ 287 keymgr_settime_remove(key, kasp); 288 289 /* 290 * Publish successor 'prepub' time before the 'retire' time of 'key'. 291 */ 292 if (prepub > retire) { 293 /* We should have already prepublished the new key. */ 294 return (now); 295 } 296 return (retire - prepub); 297 } 298 299 static void 300 keymgr_key_retire(dns_dnsseckey_t *key, dns_kasp_t *kasp, isc_stdtime_t now) { 301 char keystr[DST_KEY_FORMATSIZE]; 302 isc_result_t ret; 303 isc_stdtime_t retire; 304 dst_key_state_t s; 305 bool ksk, zsk; 306 307 REQUIRE(key != NULL); 308 REQUIRE(key->key != NULL); 309 310 /* This key wants to retire and hide in a corner. */ 311 ret = dst_key_gettime(key->key, DST_TIME_INACTIVE, &retire); 312 if (ret != ISC_R_SUCCESS || (retire > now)) { 313 dst_key_settime(key->key, DST_TIME_INACTIVE, now); 314 } 315 dst_key_setstate(key->key, DST_KEY_GOAL, HIDDEN); 316 keymgr_settime_remove(key, kasp); 317 318 /* This key may not have key states set yet. Pretend as if they are 319 * in the OMNIPRESENT state. 320 */ 321 if (dst_key_getstate(key->key, DST_KEY_DNSKEY, &s) != ISC_R_SUCCESS) { 322 dst_key_setstate(key->key, DST_KEY_DNSKEY, OMNIPRESENT); 323 dst_key_settime(key->key, DST_TIME_DNSKEY, now); 324 } 325 326 (void)dst_key_getbool(key->key, DST_BOOL_KSK, &ksk); 327 if (ksk) { 328 if (dst_key_getstate(key->key, DST_KEY_KRRSIG, &s) != 329 ISC_R_SUCCESS) { 330 dst_key_setstate(key->key, DST_KEY_KRRSIG, OMNIPRESENT); 331 dst_key_settime(key->key, DST_TIME_KRRSIG, now); 332 } 333 if (dst_key_getstate(key->key, DST_KEY_DS, &s) != ISC_R_SUCCESS) 334 { 335 dst_key_setstate(key->key, DST_KEY_DS, OMNIPRESENT); 336 dst_key_settime(key->key, DST_TIME_DS, now); 337 } 338 } 339 (void)dst_key_getbool(key->key, DST_BOOL_ZSK, &zsk); 340 if (zsk) { 341 if (dst_key_getstate(key->key, DST_KEY_ZRRSIG, &s) != 342 ISC_R_SUCCESS) { 343 dst_key_setstate(key->key, DST_KEY_ZRRSIG, OMNIPRESENT); 344 dst_key_settime(key->key, DST_TIME_ZRRSIG, now); 345 } 346 } 347 348 dst_key_format(key->key, keystr, sizeof(keystr)); 349 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_DNSSEC, 350 ISC_LOG_INFO, "keymgr: retire DNSKEY %s (%s)", keystr, 351 keymgr_keyrole(key->key)); 352 } 353 354 /* 355 * Check if a dnsseckey matches kasp key configuration. A dnsseckey matches 356 * if it has the same algorithm and size, and if it has the same role as the 357 * kasp key configuration. 358 * 359 */ 360 static bool 361 keymgr_dnsseckey_kaspkey_match(dns_dnsseckey_t *dkey, dns_kasp_key_t *kkey) { 362 dst_key_t *key; 363 isc_result_t ret; 364 bool role = false; 365 366 REQUIRE(dkey != NULL); 367 REQUIRE(kkey != NULL); 368 369 key = dkey->key; 370 371 /* Matching algorithms? */ 372 if (dst_key_alg(key) != dns_kasp_key_algorithm(kkey)) { 373 return (false); 374 } 375 /* Matching length? */ 376 if (dst_key_size(key) != dns_kasp_key_size(kkey)) { 377 return (false); 378 } 379 /* Matching role? */ 380 ret = dst_key_getbool(key, DST_BOOL_KSK, &role); 381 if (ret != ISC_R_SUCCESS || role != dns_kasp_key_ksk(kkey)) { 382 return (false); 383 } 384 ret = dst_key_getbool(key, DST_BOOL_ZSK, &role); 385 if (ret != ISC_R_SUCCESS || role != dns_kasp_key_zsk(kkey)) { 386 return (false); 387 } 388 389 /* Found a match. */ 390 return (true); 391 } 392 393 /* 394 * Create a new key for 'origin' given the kasp key configuration 'kkey'. 395 * This will check for key id collisions with keys in 'keylist'. 396 * The created key will be stored in 'dst_key'. 397 * 398 */ 399 static isc_result_t 400 keymgr_createkey(dns_kasp_key_t *kkey, const dns_name_t *origin, 401 dns_rdataclass_t rdclass, isc_mem_t *mctx, 402 dns_dnsseckeylist_t *keylist, dst_key_t **dst_key) { 403 bool conflict; 404 int keyflags = DNS_KEYOWNER_ZONE; 405 isc_result_t result = ISC_R_SUCCESS; 406 dst_key_t *newkey = NULL; 407 408 do { 409 uint16_t id; 410 uint32_t rid; 411 uint32_t algo = dns_kasp_key_algorithm(kkey); 412 int size = dns_kasp_key_size(kkey); 413 414 conflict = false; 415 416 if (dns_kasp_key_ksk(kkey)) { 417 keyflags |= DNS_KEYFLAG_KSK; 418 } 419 RETERR(dst_key_generate(origin, algo, size, 0, keyflags, 420 DNS_KEYPROTO_DNSSEC, rdclass, mctx, 421 &newkey, NULL)); 422 423 /* Key collision? */ 424 id = dst_key_id(newkey); 425 rid = dst_key_rid(newkey); 426 for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keylist); 427 dkey != NULL; dkey = ISC_LIST_NEXT(dkey, link)) 428 { 429 if (dst_key_alg(dkey->key) != algo) { 430 continue; 431 } 432 if (dst_key_id(dkey->key) == id || 433 dst_key_rid(dkey->key) == id || 434 dst_key_id(dkey->key) == rid || 435 dst_key_rid(dkey->key) == rid) 436 { 437 /* Try again. */ 438 conflict = true; 439 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, 440 DNS_LOGMODULE_DNSSEC, 441 ISC_LOG_WARNING, 442 "keymgr: key collision id %d", 443 dst_key_id(newkey)); 444 dst_key_free(&newkey); 445 } 446 } 447 } while (conflict); 448 449 INSIST(!conflict); 450 dst_key_setnum(newkey, DST_NUM_LIFETIME, dns_kasp_key_lifetime(kkey)); 451 dst_key_setbool(newkey, DST_BOOL_KSK, dns_kasp_key_ksk(kkey)); 452 dst_key_setbool(newkey, DST_BOOL_ZSK, dns_kasp_key_zsk(kkey)); 453 *dst_key = newkey; 454 return (ISC_R_SUCCESS); 455 456 failure: 457 return (result); 458 } 459 460 /* 461 * Return the desired state for this record 'type'. The desired state depends 462 * on whether the key wants to be active, or wants to retire. This implements 463 * the edges of our state machine: 464 * 465 * ----> OMNIPRESENT ---- 466 * | | 467 * | \|/ 468 * 469 * RUMOURED <----> UNRETENTIVE 470 * 471 * /|\ | 472 * | | 473 * ---- HIDDEN <---- 474 * 475 * A key that wants to be active eventually wants to have its record types 476 * in the OMNIPRESENT state (that is, all resolvers that know about these 477 * type of records know about these records specifically). 478 * 479 * A key that wants to be retired eventually wants to have its record types 480 * in the HIDDEN state (that is, all resolvers that know about these type 481 * of records specifically don't know about these records). 482 * 483 */ 484 static dst_key_state_t 485 keymgr_desiredstate(dns_dnsseckey_t *key, dst_key_state_t state) { 486 dst_key_state_t goal; 487 488 if (dst_key_getstate(key->key, DST_KEY_GOAL, &goal) != ISC_R_SUCCESS) { 489 /* No goal? No movement. */ 490 return (state); 491 } 492 493 if (goal == HIDDEN) { 494 switch (state) { 495 case RUMOURED: 496 case OMNIPRESENT: 497 return (UNRETENTIVE); 498 case HIDDEN: 499 case UNRETENTIVE: 500 return (HIDDEN); 501 default: 502 return (state); 503 } 504 } else if (goal == OMNIPRESENT) { 505 switch (state) { 506 case RUMOURED: 507 case OMNIPRESENT: 508 return (OMNIPRESENT); 509 case HIDDEN: 510 case UNRETENTIVE: 511 return (RUMOURED); 512 default: 513 return (state); 514 } 515 } 516 517 /* Unknown goal. */ 518 return (state); 519 } 520 521 /* 522 * Check if 'key' matches specific 'states'. 523 * A state in 'states' that is NA matches any state. 524 * A state in 'states' that is HIDDEN also matches if the state is not set. 525 * If 'next_state' is set (not NA), we are pretending as if record 'type' of 526 * 'subject' key already transitioned to the 'next state'. 527 * 528 */ 529 static bool 530 keymgr_key_match_state(dst_key_t *key, dst_key_t *subject, int type, 531 dst_key_state_t next_state, dst_key_state_t states[4]) { 532 REQUIRE(key != NULL); 533 534 for (int i = 0; i < 4; i++) { 535 dst_key_state_t state; 536 if (states[i] == NA) { 537 continue; 538 } 539 if (next_state != NA && i == type && 540 dst_key_id(key) == dst_key_id(subject)) { 541 /* Check next state rather than current state. */ 542 state = next_state; 543 } else if (dst_key_getstate(key, i, &state) != ISC_R_SUCCESS) { 544 /* This is fine only if expected state is HIDDEN. */ 545 if (states[i] != HIDDEN) { 546 return (false); 547 } 548 continue; 549 } 550 if (state != states[i]) { 551 return (false); 552 } 553 } 554 /* Match. */ 555 return (true); 556 } 557 558 /* 559 * Check if a 'k2' is a successor of 'k1'. This is a simplified version of 560 * Equation(2) of "Flexible and Robust Key Rollover" which defines a 561 * recursive relation. 562 * 563 */ 564 static bool 565 keymgr_key_is_successor(dst_key_t *k1, dst_key_t *k2) { 566 uint32_t suc = 0, pre = 0; 567 if (dst_key_getnum(k1, DST_NUM_SUCCESSOR, &suc) != ISC_R_SUCCESS) { 568 return (false); 569 } 570 if (dst_key_getnum(k2, DST_NUM_PREDECESSOR, &pre) != ISC_R_SUCCESS) { 571 return (false); 572 } 573 return (dst_key_id(k1) == pre && dst_key_id(k2) == suc); 574 } 575 576 /* 577 * Check if a key exists in 'keyring' that matches 'states'. 578 * 579 * If 'match_algorithms', the key must also match the algorithm of 'key'. 580 * If 'next_state' is not NA, we are actually looking for a key as if 581 * 'key' already transitioned to the next state. 582 * If 'check_successor', we also want to make sure there is a successor 583 * relationship with the found key that matches 'states2'. 584 */ 585 static bool 586 keymgr_key_exists_with_state(dns_dnsseckeylist_t *keyring, dns_dnsseckey_t *key, 587 int type, dst_key_state_t next_state, 588 dst_key_state_t states[4], 589 dst_key_state_t states2[4], bool check_successor, 590 bool match_algorithms) { 591 for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); dkey != NULL; 592 dkey = ISC_LIST_NEXT(dkey, link)) 593 { 594 if (match_algorithms && 595 (dst_key_alg(dkey->key) != dst_key_alg(key->key))) { 596 continue; 597 } 598 599 if (check_successor && 600 keymgr_key_match_state(dkey->key, key->key, type, 601 next_state, states2)) 602 { 603 /* Found a possible successor, look for predecessor. */ 604 for (dns_dnsseckey_t *pkey = ISC_LIST_HEAD(*keyring); 605 pkey != NULL; pkey = ISC_LIST_NEXT(pkey, link)) 606 { 607 if (pkey == dkey) { 608 continue; 609 } 610 if (!keymgr_key_match_state(pkey->key, key->key, 611 type, next_state, 612 states)) { 613 continue; 614 } 615 616 /* 617 * Found a possible predecessor, check 618 * relationship. 619 */ 620 if (keymgr_key_is_successor(pkey->key, 621 dkey->key)) { 622 return (true); 623 } 624 } 625 } 626 627 if (!check_successor && 628 keymgr_key_match_state(dkey->key, key->key, type, 629 next_state, states)) 630 { 631 return (true); 632 } 633 } 634 /* No match. */ 635 return (false); 636 } 637 638 /* 639 * Check if a key has a successor. 640 */ 641 static bool 642 keymgr_key_has_successor(dns_dnsseckey_t *predecessor, 643 dns_dnsseckeylist_t *keyring) { 644 for (dns_dnsseckey_t *successor = ISC_LIST_HEAD(*keyring); 645 successor != NULL; successor = ISC_LIST_NEXT(successor, link)) 646 { 647 if (keymgr_key_is_successor(predecessor->key, successor->key)) { 648 return (true); 649 } 650 } 651 return (false); 652 } 653 654 /* 655 * Check if all keys have their DS hidden. If not, then there must be at 656 * least one key with an OMNIPRESENT DNSKEY. 657 * 658 * If 'next_state' is not NA, we are actually looking for a key as if 659 * 'key' already transitioned to the next state. 660 * If 'match_algorithms', only consider keys with same algorithm of 'key'. 661 * 662 */ 663 static bool 664 keymgr_ds_hidden_or_chained(dns_dnsseckeylist_t *keyring, dns_dnsseckey_t *key, 665 int type, dst_key_state_t next_state, 666 bool match_algorithms, bool must_be_hidden) { 667 dst_key_state_t dnskey_omnipresent[4] = { OMNIPRESENT, NA, OMNIPRESENT, 668 NA }; /* (3e) */ 669 dst_key_state_t ds_hidden[4] = { NA, NA, NA, HIDDEN }; /* (3e) */ 670 dst_key_state_t na[4] = { NA, NA, NA, NA }; /* successor n/a */ 671 672 for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); dkey != NULL; 673 dkey = ISC_LIST_NEXT(dkey, link)) 674 { 675 char keystr[DST_KEY_FORMATSIZE]; 676 dst_key_format(dkey->key, keystr, sizeof(keystr)); 677 678 if (match_algorithms && 679 (dst_key_alg(dkey->key) != dst_key_alg(key->key))) { 680 continue; 681 } 682 683 if (keymgr_key_match_state(dkey->key, key->key, type, 684 next_state, ds_hidden)) { 685 /* This key has its DS hidden. */ 686 continue; 687 } 688 689 if (must_be_hidden) { 690 return (false); 691 } 692 693 /* 694 * This key does not have its DS hidden. There must be at 695 * least one key with the same algorithm that provides a 696 * chain of trust (can be this key). 697 */ 698 dnskey_omnipresent[DST_KEY_DS] = NA; 699 if (next_state != NA && 700 dst_key_id(dkey->key) == dst_key_id(key->key)) { 701 /* Check next state rather than current state. */ 702 dnskey_omnipresent[DST_KEY_DS] = next_state; 703 } else { 704 (void)dst_key_getstate(dkey->key, DST_KEY_DS, 705 &dnskey_omnipresent[DST_KEY_DS]); 706 } 707 if (!keymgr_key_exists_with_state( 708 keyring, key, type, next_state, dnskey_omnipresent, 709 na, false, match_algorithms)) 710 { 711 /* There is no chain of trust. */ 712 return (false); 713 } 714 } 715 /* All good. */ 716 return (true); 717 } 718 719 /* 720 * Check if all keys have their DNSKEY hidden. If not, then there must be at 721 * least one key with an OMNIPRESENT ZRRSIG. 722 * 723 * If 'next_state' is not NA, we are actually looking for a key as if 724 * 'key' already transitioned to the next state. 725 * If 'match_algorithms', only consider keys with same algorithm of 'key'. 726 * 727 */ 728 static bool 729 keymgr_dnskey_hidden_or_chained(dns_dnsseckeylist_t *keyring, 730 dns_dnsseckey_t *key, int type, 731 dst_key_state_t next_state, 732 bool match_algorithms) { 733 dst_key_state_t rrsig_omnipresent[4] = { NA, OMNIPRESENT, NA, 734 NA }; /* (3i) */ 735 dst_key_state_t dnskey_hidden[4] = { HIDDEN, NA, NA, NA }; /* (3i) */ 736 dst_key_state_t na[4] = { NA, NA, NA, NA }; /* successor n/a */ 737 738 for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); dkey != NULL; 739 dkey = ISC_LIST_NEXT(dkey, link)) 740 { 741 if (match_algorithms && 742 (dst_key_alg(dkey->key) != dst_key_alg(key->key))) { 743 continue; 744 } 745 746 if (keymgr_key_match_state(dkey->key, key->key, type, 747 next_state, dnskey_hidden)) 748 { 749 /* This key has its DNSKEY hidden. */ 750 continue; 751 } 752 753 /* 754 * This key does not have its DNSKEY hidden. There must be at 755 * least one key with the same algorithm that has its RRSIG 756 * records OMNIPRESENT. 757 */ 758 rrsig_omnipresent[DST_KEY_DNSKEY] = NA; 759 (void)dst_key_getstate(dkey->key, DST_KEY_DNSKEY, 760 &rrsig_omnipresent[DST_KEY_DNSKEY]); 761 if (!keymgr_key_exists_with_state(keyring, key, type, 762 next_state, rrsig_omnipresent, 763 na, false, match_algorithms)) 764 { 765 /* There is no chain of trust. */ 766 return (false); 767 } 768 } 769 /* All good. */ 770 return (true); 771 } 772 773 /* 774 * Check for existence of DS. 775 * 776 */ 777 static bool 778 keymgr_have_ds(dns_dnsseckeylist_t *keyring, dns_dnsseckey_t *key, int type, 779 dst_key_state_t next_state) { 780 dst_key_state_t states[2][4] = { 781 /* DNSKEY, ZRRSIG, KRRSIG, DS */ 782 { NA, NA, NA, OMNIPRESENT }, /* DS present */ 783 { NA, NA, NA, RUMOURED } /* DS introducing */ 784 }; 785 dst_key_state_t na[4] = { NA, NA, NA, NA }; /* successor n/a */ 786 787 /* 788 * Equation (3a): 789 * There is a key with the DS in either RUMOURD or OMNIPRESENT state. 790 */ 791 return (keymgr_key_exists_with_state(keyring, key, type, next_state, 792 states[0], na, false, false) || 793 keymgr_key_exists_with_state(keyring, key, type, next_state, 794 states[1], na, false, false)); 795 } 796 797 /* 798 * Check for existence of DNSKEY, or at least a good DNSKEY state. 799 * See equations what are good DNSKEY states. 800 * 801 */ 802 static bool 803 keymgr_have_dnskey(dns_dnsseckeylist_t *keyring, dns_dnsseckey_t *key, int type, 804 dst_key_state_t next_state) { 805 dst_key_state_t states[9][4] = { 806 /* DNSKEY, ZRRSIG, KRRSIG, DS */ 807 { OMNIPRESENT, NA, OMNIPRESENT, OMNIPRESENT }, /* (3b) */ 808 809 { OMNIPRESENT, NA, OMNIPRESENT, UNRETENTIVE }, /* (3c)p */ 810 { OMNIPRESENT, NA, OMNIPRESENT, RUMOURED }, /* (3c)s */ 811 812 { UNRETENTIVE, NA, UNRETENTIVE, OMNIPRESENT }, /* (3d)p */ 813 { OMNIPRESENT, NA, UNRETENTIVE, OMNIPRESENT }, /* (3d)p */ 814 { UNRETENTIVE, NA, OMNIPRESENT, OMNIPRESENT }, /* (3d)p */ 815 { RUMOURED, NA, RUMOURED, OMNIPRESENT }, /* (3d)s */ 816 { OMNIPRESENT, NA, RUMOURED, OMNIPRESENT }, /* (3d)s */ 817 { RUMOURED, NA, OMNIPRESENT, OMNIPRESENT }, /* (3d)s */ 818 }; 819 dst_key_state_t na[4] = { NA, NA, NA, NA }; /* successor n/a */ 820 821 return ( 822 /* 823 * Equation (3b): 824 * There is a key with the same algorithm with its DNSKEY, 825 * KRRSIG and DS records in OMNIPRESENT state. 826 */ 827 keymgr_key_exists_with_state(keyring, key, type, next_state, 828 states[0], na, false, true) || 829 /* 830 * Equation (3c): 831 * There are two or more keys with an OMNIPRESENT DNSKEY and 832 * the DS records get swapped. These keys must be in a 833 * successor relation. 834 */ 835 keymgr_key_exists_with_state(keyring, key, type, next_state, 836 states[1], states[2], true, 837 true) || 838 /* 839 * Equation (3d): 840 * There are two or more keys with an OMNIPRESENT DS and 841 * the DNSKEY records and its KRRSIG records get swapped. 842 * These keys must be in a successor relation. Since the 843 * state for DNSKEY and KRRSIG move independently, we have 844 * to check all combinations for DNSKEY and KRRSIG in 845 * OMNIPRESENT/UNRETENTIVE state for the predecessor, and 846 * OMNIPRESENT/RUMOURED state for the successor. 847 */ 848 keymgr_key_exists_with_state(keyring, key, type, next_state, 849 states[3], states[6], true, 850 true) || 851 keymgr_key_exists_with_state(keyring, key, type, next_state, 852 states[3], states[7], true, 853 true) || 854 keymgr_key_exists_with_state(keyring, key, type, next_state, 855 states[3], states[8], true, 856 true) || 857 keymgr_key_exists_with_state(keyring, key, type, next_state, 858 states[4], states[6], true, 859 true) || 860 keymgr_key_exists_with_state(keyring, key, type, next_state, 861 states[4], states[7], true, 862 true) || 863 keymgr_key_exists_with_state(keyring, key, type, next_state, 864 states[4], states[8], true, 865 true) || 866 keymgr_key_exists_with_state(keyring, key, type, next_state, 867 states[5], states[6], true, 868 true) || 869 keymgr_key_exists_with_state(keyring, key, type, next_state, 870 states[5], states[7], true, 871 true) || 872 keymgr_key_exists_with_state(keyring, key, type, next_state, 873 states[5], states[8], true, 874 true) || 875 /* 876 * Equation (3e): 877 * The key may be in any state as long as all keys have their 878 * DS HIDDEN, or when their DS is not HIDDEN, there must be a 879 * key with its DS in the same state and its DNSKEY omnipresent. 880 * In other words, if a DS record for the same algorithm is 881 * is still available to some validators, there must be a 882 * chain of trust for those validators. 883 */ 884 keymgr_ds_hidden_or_chained(keyring, key, type, next_state, 885 true, false)); 886 } 887 888 /* 889 * Check for existence of RRSIG (zsk), or a good RRSIG state. 890 * See equations what are good RRSIG states. 891 * 892 */ 893 static bool 894 keymgr_have_rrsig(dns_dnsseckeylist_t *keyring, dns_dnsseckey_t *key, int type, 895 dst_key_state_t next_state) { 896 dst_key_state_t states[11][4] = { 897 /* DNSKEY, ZRRSIG, KRRSIG, DS */ 898 { OMNIPRESENT, OMNIPRESENT, NA, NA }, /* (3f) */ 899 { UNRETENTIVE, OMNIPRESENT, NA, NA }, /* (3g)p */ 900 { RUMOURED, OMNIPRESENT, NA, NA }, /* (3g)s */ 901 { OMNIPRESENT, UNRETENTIVE, NA, NA }, /* (3h)p */ 902 { OMNIPRESENT, RUMOURED, NA, NA }, /* (3h)s */ 903 }; 904 dst_key_state_t na[4] = { NA, NA, NA, NA }; /* successor n/a */ 905 906 return ( 907 /* 908 * If all DS records are hidden than this rule can be ignored. 909 */ 910 keymgr_ds_hidden_or_chained(keyring, key, type, next_state, 911 true, true) || 912 /* 913 * Equation (3f): 914 * There is a key with the same algorithm with its DNSKEY and 915 * ZRRSIG records in OMNIPRESENT state. 916 */ 917 keymgr_key_exists_with_state(keyring, key, type, next_state, 918 states[0], na, false, true) || 919 /* 920 * Equation (3g): 921 * There are two or more keys with OMNIPRESENT ZRRSIG 922 * records and the DNSKEY records get swapped. These keys 923 * must be in a successor relation. 924 */ 925 keymgr_key_exists_with_state(keyring, key, type, next_state, 926 states[1], states[2], true, 927 true) || 928 /* 929 * Equation (3h): 930 * There are two or more keys with an OMNIPRESENT DNSKEY 931 * and the ZRRSIG records get swapped. These keys must be in 932 * a successor relation. 933 */ 934 keymgr_key_exists_with_state(keyring, key, type, next_state, 935 states[3], states[4], true, 936 true) || 937 /* 938 * Equation (3i): 939 * If no DNSKEYs are published, the state of the signatures is 940 * irrelevant. In case a DNSKEY is published however, there 941 * must be a path that can be validated from there. 942 */ 943 keymgr_dnskey_hidden_or_chained(keyring, key, type, next_state, 944 true)); 945 } 946 947 /* 948 * Check if a transition in the state machine is allowed by the policy. 949 * This means when we do rollovers, we want to follow the rules of the 950 * 1. Pre-publish rollover method (in case of a ZSK) 951 * - First introduce the DNSKEY record. 952 * - Only if the DNSKEY record is OMNIPRESENT, introduce ZRRSIG records. 953 * 954 * 2. Double-KSK rollover method (in case of a KSK) 955 * - First introduce the DNSKEY record, as well as the KRRSIG records. 956 * - Only if the DNSKEY record is OMNIPRESENT, suggest to introduce the DS. 957 * 958 */ 959 static bool 960 keymgr_policy_approval(dns_dnsseckeylist_t *keyring, dns_dnsseckey_t *key, 961 int type, dst_key_state_t next) { 962 dst_key_state_t dnskeystate = HIDDEN; 963 dst_key_state_t ksk_present[4] = { OMNIPRESENT, NA, OMNIPRESENT, 964 OMNIPRESENT }; 965 dst_key_state_t ds_rumoured[4] = { OMNIPRESENT, NA, OMNIPRESENT, 966 RUMOURED }; 967 dst_key_state_t ds_retired[4] = { OMNIPRESENT, NA, OMNIPRESENT, 968 UNRETENTIVE }; 969 dst_key_state_t ksk_rumoured[4] = { RUMOURED, NA, NA, OMNIPRESENT }; 970 dst_key_state_t ksk_retired[4] = { UNRETENTIVE, NA, NA, OMNIPRESENT }; 971 dst_key_state_t na[4] = { NA, NA, NA, NA }; /* successor n/a */ 972 973 if (next != RUMOURED) { 974 /* 975 * Local policy only adds an extra barrier on transitions to 976 * the RUMOURED state. 977 */ 978 return (true); 979 } 980 981 switch (type) { 982 case DST_KEY_DNSKEY: 983 /* No restrictions. */ 984 return (true); 985 case DST_KEY_ZRRSIG: 986 /* Make sure the DNSKEY record is OMNIPRESENT. */ 987 (void)dst_key_getstate(key->key, DST_KEY_DNSKEY, &dnskeystate); 988 if (dnskeystate == OMNIPRESENT) { 989 return (true); 990 } 991 /* 992 * Or are we introducing a new key for this algorithm? Because 993 * in that case allow publishing the RRSIG records before the 994 * DNSKEY. 995 */ 996 return (!(keymgr_key_exists_with_state(keyring, key, type, next, 997 ksk_present, na, false, 998 true) || 999 keymgr_key_exists_with_state(keyring, key, type, next, 1000 ds_retired, ds_rumoured, 1001 true, true) || 1002 keymgr_key_exists_with_state( 1003 keyring, key, type, next, ksk_retired, 1004 ksk_rumoured, true, true))); 1005 case DST_KEY_KRRSIG: 1006 /* Only introduce if the DNSKEY is also introduced. */ 1007 (void)dst_key_getstate(key->key, DST_KEY_DNSKEY, &dnskeystate); 1008 return (dnskeystate != HIDDEN); 1009 case DST_KEY_DS: 1010 /* Make sure the DNSKEY record is OMNIPRESENT. */ 1011 (void)dst_key_getstate(key->key, DST_KEY_DNSKEY, &dnskeystate); 1012 return (dnskeystate == OMNIPRESENT); 1013 default: 1014 return (false); 1015 } 1016 } 1017 1018 /* 1019 * Check if a transition in the state machine is DNSSEC safe. 1020 * This implements Equation(1) of "Flexible and Robust Key Rollover". 1021 * 1022 */ 1023 static bool 1024 keymgr_transition_allowed(dns_dnsseckeylist_t *keyring, dns_dnsseckey_t *key, 1025 int type, dst_key_state_t next_state) { 1026 /* Debug logging. */ 1027 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(1))) { 1028 bool rule1a, rule1b, rule2a, rule2b, rule3a, rule3b; 1029 char keystr[DST_KEY_FORMATSIZE]; 1030 dst_key_format(key->key, keystr, sizeof(keystr)); 1031 rule1a = keymgr_have_ds(keyring, key, type, NA); 1032 rule1b = keymgr_have_ds(keyring, key, type, next_state); 1033 rule2a = keymgr_have_dnskey(keyring, key, type, NA); 1034 rule2b = keymgr_have_dnskey(keyring, key, type, next_state); 1035 rule3a = keymgr_have_rrsig(keyring, key, type, NA); 1036 rule3b = keymgr_have_rrsig(keyring, key, type, next_state); 1037 isc_log_write( 1038 dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_DNSSEC, 1039 ISC_LOG_DEBUG(1), 1040 "keymgr: dnssec evaluation of %s %s record %s: " 1041 "rule1=(~%s or %s) rule2=(~%s or %s) " 1042 "rule3=(~%s or %s)", 1043 keymgr_keyrole(key->key), keystr, keystatetags[type], 1044 rule1a ? "true" : "false", rule1b ? "true" : "false", 1045 rule2a ? "true" : "false", rule2b ? "true" : "false", 1046 rule3a ? "true" : "false", rule3b ? "true" : "false"); 1047 } 1048 1049 return ( 1050 /* 1051 * Rule 1: There must be a DS at all times. 1052 * First check the current situation: if the rule check fails, 1053 * we allow the transition to attempt to move us out of the 1054 * invalid state. If the rule check passes, also check if 1055 * the next state is also still a valid situation. 1056 */ 1057 (!keymgr_have_ds(keyring, key, type, NA) || 1058 keymgr_have_ds(keyring, key, type, next_state)) && 1059 /* 1060 * Rule 2: There must be a DNSKEY at all times. Again, first 1061 * check the current situation, then assess the next state. 1062 */ 1063 (!keymgr_have_dnskey(keyring, key, type, NA) || 1064 keymgr_have_dnskey(keyring, key, type, next_state)) && 1065 /* 1066 * Rule 3: There must be RRSIG records at all times. Again, 1067 * first check the current situation, then assess the next 1068 * state. 1069 */ 1070 (!keymgr_have_rrsig(keyring, key, type, NA) || 1071 keymgr_have_rrsig(keyring, key, type, next_state))); 1072 } 1073 1074 /* 1075 * Calculate the time when it is safe to do the next transition. 1076 * 1077 */ 1078 static void 1079 keymgr_transition_time(dns_dnsseckey_t *key, int type, 1080 dst_key_state_t next_state, dns_kasp_t *kasp, 1081 isc_stdtime_t now, isc_stdtime_t *when) { 1082 isc_result_t ret; 1083 isc_stdtime_t lastchange, nexttime = now; 1084 1085 /* 1086 * No need to wait if we move things into an uncertain state. 1087 */ 1088 if (next_state == RUMOURED || next_state == UNRETENTIVE) { 1089 *when = now; 1090 return; 1091 } 1092 1093 ret = dst_key_gettime(key->key, keystatetimes[type], &lastchange); 1094 if (ret != ISC_R_SUCCESS) { 1095 /* No last change, for safety purposes let's set it to now. */ 1096 dst_key_settime(key->key, keystatetimes[type], now); 1097 lastchange = now; 1098 } 1099 1100 switch (type) { 1101 case DST_KEY_DNSKEY: 1102 case DST_KEY_KRRSIG: 1103 switch (next_state) { 1104 case OMNIPRESENT: 1105 /* 1106 * RFC 7583: The publication interval (Ipub) is the 1107 * amount of time that must elapse after the 1108 * publication of a DNSKEY (plus RRSIG (KSK)) before 1109 * it can be assumed that any resolvers that have the 1110 * relevant RRset cached have a copy of the new 1111 * information. This is the sum of the propagation 1112 * delay (Dprp) and the DNSKEY TTL (TTLkey). This 1113 * translates to zone-propagation-delay + dnskey-ttl. 1114 * We will also add the publish-safety interval. 1115 */ 1116 nexttime = lastchange + dst_key_getttl(key->key) + 1117 dns_kasp_zonepropagationdelay(kasp) + 1118 dns_kasp_publishsafety(kasp); 1119 break; 1120 case HIDDEN: 1121 /* 1122 * Same as OMNIPRESENT but without the publish-safety 1123 * interval. 1124 */ 1125 nexttime = lastchange + dst_key_getttl(key->key) + 1126 dns_kasp_zonepropagationdelay(kasp); 1127 break; 1128 default: 1129 nexttime = now; 1130 break; 1131 } 1132 break; 1133 case DST_KEY_ZRRSIG: 1134 switch (next_state) { 1135 case OMNIPRESENT: 1136 case HIDDEN: 1137 /* 1138 * RFC 7583: The retire interval (Iret) is the amount 1139 * of time that must elapse after a DNSKEY or 1140 * associated data enters the retire state for any 1141 * dependent information (RRSIG ZSK) to be purged from 1142 * validating resolver caches. This is defined as: 1143 * 1144 * Iret = Dsgn + Dprp + TTLsig 1145 * 1146 * Where Dsgn is the Dsgn is the delay needed to 1147 * ensure that all existing RRsets have been re-signed 1148 * with the new key, Dprp is the propagation delay and 1149 * TTLsig is the maximum TTL of all zone RRSIG 1150 * records. This translates to: 1151 * 1152 * Dsgn + zone-propagation-delay + max-zone-ttl. 1153 * 1154 * We will also add the retire-safety interval. 1155 */ 1156 nexttime = lastchange + dns_kasp_zonemaxttl(kasp) + 1157 dns_kasp_zonepropagationdelay(kasp) + 1158 dns_kasp_retiresafety(kasp); 1159 /* 1160 * Only add the sign delay Dsgn if there is an actual 1161 * predecessor or successor key. 1162 */ 1163 uint32_t tag; 1164 ret = dst_key_getnum(key->key, DST_NUM_PREDECESSOR, 1165 &tag); 1166 if (ret != ISC_R_SUCCESS) { 1167 ret = dst_key_getnum(key->key, 1168 DST_NUM_SUCCESSOR, &tag); 1169 } 1170 if (ret == ISC_R_SUCCESS) { 1171 nexttime += dns_kasp_signdelay(kasp); 1172 } 1173 break; 1174 default: 1175 nexttime = now; 1176 break; 1177 } 1178 break; 1179 case DST_KEY_DS: 1180 switch (next_state) { 1181 case OMNIPRESENT: 1182 case HIDDEN: 1183 /* 1184 * RFC 7583: The successor DS record is published in 1185 * the parent zone and after the registration delay 1186 * (Dreg), the time taken after the DS record has been 1187 * submitted to the parent zone manager for it to be 1188 * placed in the zone. Key N (the predecessor) must 1189 * remain in the zone until any caches that contain a 1190 * copy of the DS RRset have a copy containing the new 1191 * DS record. This interval is the retire interval 1192 * (Iret), given by: 1193 * 1194 * Iret = DprpP + TTLds 1195 * 1196 * So we need to wait Dreg + Iret before the DS becomes 1197 * OMNIPRESENT. This translates to: 1198 * 1199 * parent-registration-delay + 1200 * parent-propagation-delay + parent-ds-ttl. 1201 * 1202 * We will also add the retire-safety interval. 1203 */ 1204 nexttime = lastchange + dns_kasp_dsttl(kasp) + 1205 dns_kasp_parentregistrationdelay(kasp) + 1206 dns_kasp_parentpropagationdelay(kasp) + 1207 dns_kasp_retiresafety(kasp); 1208 break; 1209 default: 1210 nexttime = now; 1211 break; 1212 } 1213 break; 1214 default: 1215 INSIST(0); 1216 ISC_UNREACHABLE(); 1217 break; 1218 } 1219 1220 *when = nexttime; 1221 } 1222 1223 /* 1224 * Update keys. 1225 * This implements Algorithm (1) of "Flexible and Robust Key Rollover". 1226 * 1227 */ 1228 static isc_result_t 1229 keymgr_update(dns_dnsseckeylist_t *keyring, dns_kasp_t *kasp, isc_stdtime_t now, 1230 isc_stdtime_t *nexttime) { 1231 bool changed; 1232 1233 /* Repeat until nothing changed. */ 1234 transition: 1235 changed = false; 1236 1237 /* For all keys in the zone. */ 1238 for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); dkey != NULL; 1239 dkey = ISC_LIST_NEXT(dkey, link)) 1240 { 1241 char keystr[DST_KEY_FORMATSIZE]; 1242 dst_key_format(dkey->key, keystr, sizeof(keystr)); 1243 1244 /* For all records related to this key. */ 1245 for (int i = 0; i < NUM_KEYSTATES; i++) { 1246 isc_result_t ret; 1247 isc_stdtime_t when; 1248 dst_key_state_t state, next_state; 1249 1250 ret = dst_key_getstate(dkey->key, i, &state); 1251 if (ret == ISC_R_NOTFOUND) { 1252 /* 1253 * This record type is not applicable for this 1254 * key, continue to the next record type. 1255 */ 1256 continue; 1257 } 1258 1259 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, 1260 DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), 1261 "keymgr: examine %s %s type %s " 1262 "in state %s", 1263 keymgr_keyrole(dkey->key), keystr, 1264 keystatetags[i], keystatestrings[state]); 1265 1266 /* Get the desired next state. */ 1267 next_state = keymgr_desiredstate(dkey, state); 1268 if (state == next_state) { 1269 /* 1270 * This record is in a stable state. 1271 * No change needed, continue with the next 1272 * record type. 1273 */ 1274 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, 1275 DNS_LOGMODULE_DNSSEC, 1276 ISC_LOG_DEBUG(1), 1277 "keymgr: %s %s type %s in " 1278 "stable state %s", 1279 keymgr_keyrole(dkey->key), keystr, 1280 keystatetags[i], 1281 keystatestrings[state]); 1282 continue; 1283 } 1284 1285 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, 1286 DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), 1287 "keymgr: can we transition %s %s type %s " 1288 "state %s to state %s?", 1289 keymgr_keyrole(dkey->key), keystr, 1290 keystatetags[i], keystatestrings[state], 1291 keystatestrings[next_state]); 1292 1293 /* Is the transition allowed according to policy? */ 1294 if (!keymgr_policy_approval(keyring, dkey, i, 1295 next_state)) { 1296 /* No, please respect rollover methods. */ 1297 isc_log_write( 1298 dns_lctx, DNS_LOGCATEGORY_DNSSEC, 1299 DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), 1300 "keymgr: policy says no to %s %s type " 1301 "%s " 1302 "state %s to state %s", 1303 keymgr_keyrole(dkey->key), keystr, 1304 keystatetags[i], keystatestrings[state], 1305 keystatestrings[next_state]); 1306 1307 continue; 1308 } 1309 1310 /* Is the transition DNSSEC safe? */ 1311 if (!keymgr_transition_allowed(keyring, dkey, i, 1312 next_state)) { 1313 /* No, this would make the zone bogus. */ 1314 isc_log_write( 1315 dns_lctx, DNS_LOGCATEGORY_DNSSEC, 1316 DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), 1317 "keymgr: dnssec says no to %s %s type " 1318 "%s " 1319 "state %s to state %s", 1320 keymgr_keyrole(dkey->key), keystr, 1321 keystatetags[i], keystatestrings[state], 1322 keystatestrings[next_state]); 1323 continue; 1324 } 1325 1326 /* Is it time to make the transition? */ 1327 when = now; 1328 keymgr_transition_time(dkey, i, next_state, kasp, now, 1329 &when); 1330 if (when > now) { 1331 /* Not yet. */ 1332 isc_log_write( 1333 dns_lctx, DNS_LOGCATEGORY_DNSSEC, 1334 DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), 1335 "keymgr: time says no to %s %s type %s " 1336 "state %s to state %s (wait %u " 1337 "seconds)", 1338 keymgr_keyrole(dkey->key), keystr, 1339 keystatetags[i], keystatestrings[state], 1340 keystatestrings[next_state], 1341 when - now); 1342 if (*nexttime == 0 || *nexttime > when) { 1343 *nexttime = when; 1344 } 1345 continue; 1346 } 1347 1348 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, 1349 DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), 1350 "keymgr: transition %s %s type %s " 1351 "state %s to state %s!", 1352 keymgr_keyrole(dkey->key), keystr, 1353 keystatetags[i], keystatestrings[state], 1354 keystatestrings[next_state]); 1355 1356 /* It is safe to make the transition. */ 1357 dst_key_setstate(dkey->key, i, next_state); 1358 dst_key_settime(dkey->key, keystatetimes[i], now); 1359 changed = true; 1360 } 1361 } 1362 1363 /* We changed something, continue processing. */ 1364 if (changed) { 1365 goto transition; 1366 } 1367 1368 return (ISC_R_SUCCESS); 1369 } 1370 1371 /* 1372 * See if this key needs to be initialized with properties. A key created 1373 * and derived from a dnssec-policy will have the required metadata available, 1374 * otherwise these may be missing and need to be initialized. The key states 1375 * will be initialized according to existing timing metadata. 1376 * 1377 */ 1378 static void 1379 keymgr_key_init(dns_dnsseckey_t *key, dns_kasp_t *kasp, isc_stdtime_t now) { 1380 bool ksk, zsk; 1381 isc_result_t ret; 1382 isc_stdtime_t active = 0, pub = 0, syncpub = 0; 1383 dst_key_state_t dnskey_state = HIDDEN; 1384 dst_key_state_t ds_state = HIDDEN; 1385 dst_key_state_t zrrsig_state = HIDDEN; 1386 1387 REQUIRE(key != NULL); 1388 REQUIRE(key->key != NULL); 1389 1390 /* Initialize role. */ 1391 ret = dst_key_getbool(key->key, DST_BOOL_KSK, &ksk); 1392 if (ret != ISC_R_SUCCESS) { 1393 ksk = ((dst_key_flags(key->key) & DNS_KEYFLAG_KSK) != 0); 1394 dst_key_setbool(key->key, DST_BOOL_KSK, ksk); 1395 } 1396 ret = dst_key_getbool(key->key, DST_BOOL_ZSK, &zsk); 1397 if (ret != ISC_R_SUCCESS) { 1398 zsk = ((dst_key_flags(key->key) & DNS_KEYFLAG_KSK) == 0); 1399 dst_key_setbool(key->key, DST_BOOL_ZSK, zsk); 1400 } 1401 1402 /* Get time metadata. */ 1403 ret = dst_key_gettime(key->key, DST_TIME_ACTIVATE, &active); 1404 if (active <= now && ret == ISC_R_SUCCESS) { 1405 dns_ttl_t key_ttl = dst_key_getttl(key->key); 1406 key_ttl += dns_kasp_zonepropagationdelay(kasp); 1407 if ((active + key_ttl) <= now) { 1408 dnskey_state = OMNIPRESENT; 1409 } else { 1410 dnskey_state = RUMOURED; 1411 } 1412 } 1413 ret = dst_key_gettime(key->key, DST_TIME_PUBLISH, &pub); 1414 if (pub <= now && ret == ISC_R_SUCCESS) { 1415 dns_ttl_t zone_ttl = dns_kasp_zonemaxttl(kasp); 1416 zone_ttl += dns_kasp_zonepropagationdelay(kasp); 1417 if ((pub + zone_ttl) <= now) { 1418 zrrsig_state = OMNIPRESENT; 1419 } else { 1420 zrrsig_state = RUMOURED; 1421 } 1422 } 1423 ret = dst_key_gettime(key->key, DST_TIME_SYNCPUBLISH, &syncpub); 1424 if (syncpub <= now && ret == ISC_R_SUCCESS) { 1425 dns_ttl_t ds_ttl = dns_kasp_dsttl(kasp); 1426 ds_ttl += dns_kasp_parentregistrationdelay(kasp); 1427 ds_ttl += dns_kasp_parentpropagationdelay(kasp); 1428 if ((syncpub + ds_ttl) <= now) { 1429 ds_state = OMNIPRESENT; 1430 } else { 1431 ds_state = RUMOURED; 1432 } 1433 } 1434 1435 /* Set key states for all keys that do not have them. */ 1436 INITIALIZE_STATE(key->key, DST_KEY_DNSKEY, DST_TIME_DNSKEY, 1437 dnskey_state, now); 1438 if (ksk) { 1439 INITIALIZE_STATE(key->key, DST_KEY_KRRSIG, DST_TIME_KRRSIG, 1440 dnskey_state, now); 1441 INITIALIZE_STATE(key->key, DST_KEY_DS, DST_TIME_DS, ds_state, 1442 now); 1443 } 1444 if (zsk) { 1445 INITIALIZE_STATE(key->key, DST_KEY_ZRRSIG, DST_TIME_ZRRSIG, 1446 zrrsig_state, now); 1447 } 1448 } 1449 1450 static isc_result_t 1451 keymgr_key_rollover(dns_kasp_key_t *kaspkey, dns_dnsseckey_t *active_key, 1452 dns_dnsseckeylist_t *keyring, dns_dnsseckeylist_t *newkeys, 1453 const dns_name_t *origin, dns_rdataclass_t rdclass, 1454 dns_kasp_t *kasp, uint32_t lifetime, isc_stdtime_t now, 1455 isc_stdtime_t *nexttime, isc_mem_t *mctx) { 1456 char keystr[DST_KEY_FORMATSIZE]; 1457 isc_stdtime_t retire = 0, active = 0, prepub = 0; 1458 dns_dnsseckey_t *new_key = NULL; 1459 dns_dnsseckey_t *candidate = NULL; 1460 dst_key_t *dst_key = NULL; 1461 1462 /* Do we need to create a successor for the active key? */ 1463 if (active_key != NULL) { 1464 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(1))) { 1465 dst_key_format(active_key->key, keystr, sizeof(keystr)); 1466 isc_log_write( 1467 dns_lctx, DNS_LOGCATEGORY_DNSSEC, 1468 DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), 1469 "keymgr: DNSKEY %s (%s) is active in policy %s", 1470 keystr, keymgr_keyrole(active_key->key), 1471 dns_kasp_getname(kasp)); 1472 } 1473 1474 /* 1475 * Calculate when the successor needs to be published 1476 * in the zone. 1477 */ 1478 prepub = keymgr_prepublication_time(active_key, kasp, lifetime, 1479 now); 1480 if (prepub == 0 || prepub > now) { 1481 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(1))) { 1482 dst_key_format(active_key->key, keystr, 1483 sizeof(keystr)); 1484 isc_log_write( 1485 dns_lctx, DNS_LOGCATEGORY_DNSSEC, 1486 DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), 1487 "keymgr: new successor needed for " 1488 "DNSKEY %s (%s) (policy %s) in %u " 1489 "seconds", 1490 keystr, keymgr_keyrole(active_key->key), 1491 dns_kasp_getname(kasp), (prepub - now)); 1492 } 1493 1494 /* No need to start rollover now. */ 1495 if (*nexttime == 0 || prepub < *nexttime) { 1496 *nexttime = prepub; 1497 } 1498 return (ISC_R_SUCCESS); 1499 } 1500 1501 if (keymgr_key_has_successor(active_key, keyring)) { 1502 /* Key already has successor. */ 1503 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(1))) { 1504 dst_key_format(active_key->key, keystr, 1505 sizeof(keystr)); 1506 isc_log_write( 1507 dns_lctx, DNS_LOGCATEGORY_DNSSEC, 1508 DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), 1509 "keymgr: key DNSKEY %s (%s) (policy " 1510 "%s) already has successor", 1511 keystr, keymgr_keyrole(active_key->key), 1512 dns_kasp_getname(kasp)); 1513 } 1514 return (ISC_R_SUCCESS); 1515 } 1516 1517 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(1))) { 1518 dst_key_format(active_key->key, keystr, sizeof(keystr)); 1519 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, 1520 DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), 1521 "keymgr: need successor for DNSKEY %s " 1522 "(%s) (policy %s)", 1523 keystr, keymgr_keyrole(active_key->key), 1524 dns_kasp_getname(kasp)); 1525 } 1526 } else if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(1))) { 1527 char namestr[DNS_NAME_FORMATSIZE]; 1528 dns_name_format(origin, namestr, sizeof(namestr)); 1529 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, 1530 DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), 1531 "keymgr: no active key found for %s (policy %s)", 1532 namestr, dns_kasp_getname(kasp)); 1533 } 1534 1535 /* It is time to do key rollover, we need a new key. */ 1536 1537 /* 1538 * Check if there is a key available in pool because keys 1539 * may have been pregenerated with dnssec-keygen. 1540 */ 1541 for (candidate = ISC_LIST_HEAD(*keyring); candidate != NULL; 1542 candidate = ISC_LIST_NEXT(candidate, link)) 1543 { 1544 if (keymgr_dnsseckey_kaspkey_match(candidate, kaspkey) && 1545 dst_key_is_unused(candidate->key)) 1546 { 1547 /* Found a candidate in keyring. */ 1548 break; 1549 } 1550 } 1551 1552 if (candidate == NULL) { 1553 /* No key available in keyring, create a new one. */ 1554 isc_result_t result = keymgr_createkey(kaspkey, origin, rdclass, 1555 mctx, keyring, &dst_key); 1556 if (result != ISC_R_SUCCESS) { 1557 return (result); 1558 } 1559 dst_key_setttl(dst_key, dns_kasp_dnskeyttl(kasp)); 1560 dst_key_settime(dst_key, DST_TIME_CREATED, now); 1561 result = dns_dnsseckey_create(mctx, &dst_key, &new_key); 1562 if (result != ISC_R_SUCCESS) { 1563 return (result); 1564 } 1565 keymgr_key_init(new_key, kasp, now); 1566 } else { 1567 new_key = candidate; 1568 } 1569 dst_key_setnum(new_key->key, DST_NUM_LIFETIME, lifetime); 1570 1571 /* Got a key. */ 1572 if (active_key == NULL) { 1573 /* 1574 * If there is no active key found yet for this kasp 1575 * key configuration, immediately make this key active. 1576 */ 1577 dst_key_settime(new_key->key, DST_TIME_PUBLISH, now); 1578 dst_key_settime(new_key->key, DST_TIME_ACTIVATE, now); 1579 keymgr_settime_syncpublish(new_key, kasp, true); 1580 active = now; 1581 } else { 1582 /* 1583 * This is a successor. Mark the relationship. 1584 */ 1585 isc_stdtime_t created; 1586 (void)dst_key_gettime(new_key->key, DST_TIME_CREATED, &created); 1587 1588 dst_key_setnum(new_key->key, DST_NUM_PREDECESSOR, 1589 dst_key_id(active_key->key)); 1590 dst_key_setnum(active_key->key, DST_NUM_SUCCESSOR, 1591 dst_key_id(new_key->key)); 1592 (void)dst_key_gettime(active_key->key, DST_TIME_INACTIVE, 1593 &retire); 1594 active = retire; 1595 1596 /* 1597 * If prepublication time and/or retire time are 1598 * in the past (before the new key was created), use 1599 * creation time as published and active time, 1600 * effectively immediately making the key active. 1601 */ 1602 if (prepub < created) { 1603 active += (created - prepub); 1604 prepub = created; 1605 } 1606 if (active < created) { 1607 active = created; 1608 } 1609 dst_key_settime(new_key->key, DST_TIME_PUBLISH, prepub); 1610 dst_key_settime(new_key->key, DST_TIME_ACTIVATE, active); 1611 keymgr_settime_syncpublish(new_key, kasp, false); 1612 1613 /* 1614 * Retire predecessor. 1615 */ 1616 dst_key_setstate(active_key->key, DST_KEY_GOAL, HIDDEN); 1617 } 1618 1619 /* This key wants to be present. */ 1620 dst_key_setstate(new_key->key, DST_KEY_GOAL, OMNIPRESENT); 1621 1622 /* Do we need to set retire time? */ 1623 if (lifetime > 0) { 1624 dst_key_settime(new_key->key, DST_TIME_INACTIVE, 1625 (active + lifetime)); 1626 keymgr_settime_remove(new_key, kasp); 1627 } 1628 1629 /* Append dnsseckey to list of new keys. */ 1630 dns_dnssec_get_hints(new_key, now); 1631 new_key->source = dns_keysource_repository; 1632 INSIST(!new_key->legacy); 1633 if (candidate == NULL) { 1634 ISC_LIST_APPEND(*newkeys, new_key, link); 1635 } 1636 1637 /* Logging. */ 1638 dst_key_format(new_key->key, keystr, sizeof(keystr)); 1639 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_DNSSEC, 1640 ISC_LOG_INFO, "keymgr: DNSKEY %s (%s) %s for policy %s", 1641 keystr, keymgr_keyrole(new_key->key), 1642 (candidate != NULL) ? "selected" : "created", 1643 dns_kasp_getname(kasp)); 1644 return (ISC_R_SUCCESS); 1645 } 1646 1647 /* 1648 * Examine 'keys' and match 'kasp' policy. 1649 * 1650 */ 1651 isc_result_t 1652 dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass, 1653 const char *directory, isc_mem_t *mctx, 1654 dns_dnsseckeylist_t *keyring, dns_kasp_t *kasp, 1655 isc_stdtime_t now, isc_stdtime_t *nexttime) { 1656 isc_result_t result = ISC_R_SUCCESS; 1657 dns_dnsseckeylist_t newkeys; 1658 dns_kasp_key_t *kkey; 1659 dns_dnsseckey_t *newkey = NULL; 1660 isc_dir_t dir; 1661 bool dir_open = false; 1662 int options = (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC | DST_TYPE_STATE); 1663 char keystr[DST_KEY_FORMATSIZE]; 1664 1665 REQUIRE(DNS_KASP_VALID(kasp)); 1666 REQUIRE(keyring != NULL); 1667 1668 ISC_LIST_INIT(newkeys); 1669 1670 isc_dir_init(&dir); 1671 if (directory == NULL) { 1672 directory = "."; 1673 } 1674 1675 RETERR(isc_dir_open(&dir, directory)); 1676 dir_open = true; 1677 1678 *nexttime = 0; 1679 1680 /* Debug logging: what keys are available in the keyring? */ 1681 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(1))) { 1682 if (ISC_LIST_EMPTY(*keyring)) { 1683 char namebuf[DNS_NAME_FORMATSIZE]; 1684 dns_name_format(origin, namebuf, sizeof(namebuf)); 1685 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, 1686 DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), 1687 "keymgr: keyring empty (zone %s policy " 1688 "%s)", 1689 namebuf, dns_kasp_getname(kasp)); 1690 } 1691 1692 for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); 1693 dkey != NULL; dkey = ISC_LIST_NEXT(dkey, link)) 1694 { 1695 dst_key_format(dkey->key, keystr, sizeof(keystr)); 1696 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, 1697 DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), 1698 "keymgr: keyring: dnskey %s (policy %s)", 1699 keystr, dns_kasp_getname(kasp)); 1700 } 1701 } 1702 1703 /* Do we need to remove keys? */ 1704 for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); dkey != NULL; 1705 dkey = ISC_LIST_NEXT(dkey, link)) 1706 { 1707 bool found_match = false; 1708 1709 keymgr_key_init(dkey, kasp, now); 1710 1711 for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL; 1712 kkey = ISC_LIST_NEXT(kkey, link)) 1713 { 1714 if (keymgr_dnsseckey_kaspkey_match(dkey, kkey)) { 1715 found_match = true; 1716 break; 1717 } 1718 } 1719 1720 /* No match, so retire unwanted retire key. */ 1721 if (!found_match) { 1722 keymgr_key_retire(dkey, kasp, now); 1723 } 1724 } 1725 1726 /* Create keys according to the policy, if come in short. */ 1727 for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL; 1728 kkey = ISC_LIST_NEXT(kkey, link)) 1729 { 1730 uint32_t lifetime = dns_kasp_key_lifetime(kkey); 1731 dns_dnsseckey_t *active_key = NULL; 1732 1733 /* Do we have keys available for this kasp key? */ 1734 for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); 1735 dkey != NULL; dkey = ISC_LIST_NEXT(dkey, link)) 1736 { 1737 if (keymgr_dnsseckey_kaspkey_match(dkey, kkey)) { 1738 /* Found a match. */ 1739 dst_key_format(dkey->key, keystr, 1740 sizeof(keystr)); 1741 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, 1742 DNS_LOGMODULE_DNSSEC, 1743 ISC_LOG_DEBUG(1), 1744 "keymgr: DNSKEY %s (%s) matches " 1745 "policy %s", 1746 keystr, keymgr_keyrole(dkey->key), 1747 dns_kasp_getname(kasp)); 1748 1749 /* Initialize lifetime if not set. */ 1750 uint32_t l; 1751 if (dst_key_getnum(dkey->key, DST_NUM_LIFETIME, 1752 &l) != ISC_R_SUCCESS) { 1753 dst_key_setnum(dkey->key, 1754 DST_NUM_LIFETIME, 1755 lifetime); 1756 } 1757 1758 if (active_key) { 1759 /* We already have an active key that 1760 * matches the kasp policy. 1761 */ 1762 if (!dst_key_is_unused(dkey->key) && 1763 (dst_key_goal(dkey->key) == 1764 OMNIPRESENT) && 1765 !keymgr_key_is_successor( 1766 dkey->key, 1767 active_key->key) && 1768 !keymgr_key_is_successor( 1769 active_key->key, dkey->key)) 1770 { 1771 /* 1772 * Multiple signing keys match 1773 * the kasp key configuration. 1774 * Retire excess keys in use. 1775 */ 1776 keymgr_key_retire(dkey, kasp, 1777 now); 1778 } 1779 continue; 1780 } 1781 1782 /* 1783 * This is possibly an active key created 1784 * outside dnssec-policy. Initialize goal, 1785 * if not set. 1786 */ 1787 dst_key_state_t goal; 1788 if (dst_key_getstate(dkey->key, DST_KEY_GOAL, 1789 &goal) != ISC_R_SUCCESS) { 1790 dst_key_setstate(dkey->key, 1791 DST_KEY_GOAL, 1792 OMNIPRESENT); 1793 } 1794 1795 /* 1796 * Save the matched key only if it is active 1797 * or desires to be active. 1798 */ 1799 if (dst_key_goal(dkey->key) == OMNIPRESENT || 1800 dst_key_is_active(dkey->key, now)) { 1801 active_key = dkey; 1802 } 1803 } 1804 } 1805 1806 /* See if this key requires a rollover. */ 1807 RETERR(keymgr_key_rollover(kkey, active_key, keyring, &newkeys, 1808 origin, rdclass, kasp, lifetime, now, 1809 nexttime, mctx)); 1810 } 1811 1812 /* Walked all kasp key configurations. Append new keys. */ 1813 if (!ISC_LIST_EMPTY(newkeys)) { 1814 ISC_LIST_APPENDLIST(*keyring, newkeys, link); 1815 } 1816 1817 /* Read to update key states. */ 1818 keymgr_update(keyring, kasp, now, nexttime); 1819 1820 /* Store key states and update hints. */ 1821 for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); dkey != NULL; 1822 dkey = ISC_LIST_NEXT(dkey, link)) 1823 { 1824 dns_dnssec_get_hints(dkey, now); 1825 RETERR(dst_key_tofile(dkey->key, options, directory)); 1826 } 1827 1828 result = ISC_R_SUCCESS; 1829 1830 failure: 1831 if (dir_open) { 1832 isc_dir_close(&dir); 1833 } 1834 1835 if (result != ISC_R_SUCCESS) { 1836 while ((newkey = ISC_LIST_HEAD(newkeys)) != NULL) { 1837 ISC_LIST_UNLINK(newkeys, newkey, link); 1838 INSIST(newkey->key != NULL); 1839 dst_key_free(&newkey->key); 1840 dns_dnsseckey_destroy(mctx, &newkey); 1841 } 1842 } 1843 1844 return (result); 1845 } 1846 1847 static void 1848 keytime_status(dst_key_t *key, isc_stdtime_t now, isc_buffer_t *buf, 1849 const char *pre, int ks, int kt) { 1850 char timestr[26]; /* Minimal buf as per ctime_r() spec. */ 1851 isc_result_t ret; 1852 isc_stdtime_t when = 0; 1853 dst_key_state_t state; 1854 1855 isc_buffer_printf(buf, "%s", pre); 1856 (void)dst_key_getstate(key, ks, &state); 1857 ret = dst_key_gettime(key, kt, &when); 1858 if (state == RUMOURED || state == OMNIPRESENT) { 1859 isc_buffer_printf(buf, "yes - since "); 1860 } else if (now < when) { 1861 isc_buffer_printf(buf, "no - scheduled "); 1862 } else { 1863 isc_buffer_printf(buf, "no\n"); 1864 return; 1865 } 1866 if (ret == ISC_R_SUCCESS) { 1867 isc_stdtime_tostring(when, timestr, sizeof(timestr)); 1868 isc_buffer_printf(buf, "%s\n", timestr); 1869 } 1870 } 1871 1872 static void 1873 rollover_status(dns_dnsseckey_t *dkey, dns_kasp_t *kasp, isc_stdtime_t now, 1874 isc_buffer_t *buf, bool zsk) { 1875 char timestr[26]; /* Minimal buf as per ctime_r() spec. */ 1876 isc_result_t ret = ISC_R_SUCCESS; 1877 isc_stdtime_t active_time = 0; 1878 dst_key_state_t state = NA, goal = NA; 1879 int rrsig, active, retire; 1880 dst_key_t *key = dkey->key; 1881 1882 if (zsk) { 1883 rrsig = DST_KEY_ZRRSIG; 1884 active = DST_TIME_ACTIVATE; 1885 retire = DST_TIME_INACTIVE; 1886 } else { 1887 rrsig = DST_KEY_KRRSIG; 1888 active = DST_TIME_PUBLISH; 1889 retire = DST_TIME_DELETE; 1890 } 1891 1892 isc_buffer_printf(buf, "\n"); 1893 1894 (void)dst_key_getstate(key, DST_KEY_GOAL, &goal); 1895 (void)dst_key_getstate(key, rrsig, &state); 1896 (void)dst_key_gettime(key, active, &active_time); 1897 if (active_time == 0) { 1898 // only interested in keys that were once active. 1899 return; 1900 } 1901 1902 if (goal == HIDDEN && (state == UNRETENTIVE || state == HIDDEN)) { 1903 isc_stdtime_t remove_time = 0; 1904 // is the key removed yet? 1905 state = NA; 1906 (void)dst_key_getstate(key, DST_KEY_DNSKEY, &state); 1907 if (state == RUMOURED || state == OMNIPRESENT) { 1908 ret = dst_key_gettime(key, DST_TIME_DELETE, 1909 &remove_time); 1910 if (ret == ISC_R_SUCCESS) { 1911 isc_buffer_printf(buf, " Key is retired, will " 1912 "be removed on "); 1913 isc_stdtime_tostring(remove_time, timestr, 1914 sizeof(timestr)); 1915 isc_buffer_printf(buf, "%s", timestr); 1916 } 1917 } else { 1918 isc_buffer_printf( 1919 buf, " Key has been removed from the zone"); 1920 } 1921 } else { 1922 isc_stdtime_t retire_time = 0; 1923 uint32_t lifetime = 0; 1924 (void)dst_key_getnum(key, DST_NUM_LIFETIME, &lifetime); 1925 ret = dst_key_gettime(key, retire, &retire_time); 1926 if (ret == ISC_R_SUCCESS) { 1927 if (now < retire_time) { 1928 if (goal == OMNIPRESENT) { 1929 isc_buffer_printf(buf, 1930 " Next rollover " 1931 "scheduled on "); 1932 retire_time = keymgr_prepublication_time( 1933 dkey, kasp, lifetime, now); 1934 } else { 1935 isc_buffer_printf( 1936 buf, " Key will retire on "); 1937 } 1938 } else { 1939 isc_buffer_printf(buf, 1940 " Rollover is due since "); 1941 } 1942 isc_stdtime_tostring(retire_time, timestr, 1943 sizeof(timestr)); 1944 isc_buffer_printf(buf, "%s", timestr); 1945 } else { 1946 isc_buffer_printf(buf, " No rollover scheduled"); 1947 } 1948 } 1949 isc_buffer_printf(buf, "\n"); 1950 } 1951 1952 static void 1953 keystate_status(dst_key_t *key, isc_buffer_t *buf, const char *pre, int ks) { 1954 dst_key_state_t state = NA; 1955 1956 (void)dst_key_getstate(key, ks, &state); 1957 switch (state) { 1958 case HIDDEN: 1959 isc_buffer_printf(buf, " - %shidden\n", pre); 1960 break; 1961 case RUMOURED: 1962 isc_buffer_printf(buf, " - %srumoured\n", pre); 1963 break; 1964 case OMNIPRESENT: 1965 isc_buffer_printf(buf, " - %somnipresent\n", pre); 1966 break; 1967 case UNRETENTIVE: 1968 isc_buffer_printf(buf, " - %sunretentive\n", pre); 1969 break; 1970 case NA: 1971 default: 1972 /* print nothing */ 1973 break; 1974 } 1975 } 1976 1977 void 1978 dns_keymgr_status(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring, 1979 isc_stdtime_t now, char *out, size_t out_len) { 1980 isc_buffer_t buf; 1981 char timestr[26]; /* Minimal buf as per ctime_r() spec. */ 1982 1983 REQUIRE(DNS_KASP_VALID(kasp)); 1984 REQUIRE(keyring != NULL); 1985 REQUIRE(out != NULL); 1986 1987 isc_buffer_init(&buf, out, out_len); 1988 1989 // policy name 1990 isc_buffer_printf(&buf, "dnssec-policy: %s\n", dns_kasp_getname(kasp)); 1991 isc_buffer_printf(&buf, "current time: "); 1992 isc_stdtime_tostring(now, timestr, sizeof(timestr)); 1993 isc_buffer_printf(&buf, "%s\n", timestr); 1994 1995 for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); dkey != NULL; 1996 dkey = ISC_LIST_NEXT(dkey, link)) 1997 { 1998 char algstr[DNS_NAME_FORMATSIZE]; 1999 bool ksk = false, zsk = false; 2000 2001 if (dst_key_is_unused(dkey->key)) { 2002 continue; 2003 } 2004 2005 // key data 2006 dst_key_getbool(dkey->key, DST_BOOL_KSK, &ksk); 2007 dst_key_getbool(dkey->key, DST_BOOL_ZSK, &zsk); 2008 dns_secalg_format((dns_secalg_t)dst_key_alg(dkey->key), algstr, 2009 sizeof(algstr)); 2010 isc_buffer_printf(&buf, "\nkey: %d (%s), %s\n", 2011 dst_key_id(dkey->key), algstr, 2012 keymgr_keyrole(dkey->key)); 2013 2014 // publish status 2015 keytime_status(dkey->key, now, &buf, 2016 " published: ", DST_KEY_DNSKEY, 2017 DST_TIME_PUBLISH); 2018 2019 // signing status 2020 if (ksk) { 2021 keytime_status(dkey->key, now, &buf, 2022 " key signing: ", DST_KEY_KRRSIG, 2023 DST_TIME_PUBLISH); 2024 } 2025 if (zsk) { 2026 keytime_status(dkey->key, now, &buf, 2027 " zone signing: ", DST_KEY_ZRRSIG, 2028 DST_TIME_ACTIVATE); 2029 } 2030 2031 // rollover status 2032 rollover_status(dkey, kasp, now, &buf, zsk); 2033 2034 // key states 2035 keystate_status(dkey->key, &buf, 2036 "goal: ", DST_KEY_GOAL); 2037 keystate_status(dkey->key, &buf, 2038 "dnskey: ", DST_KEY_DNSKEY); 2039 keystate_status(dkey->key, &buf, 2040 "ds: ", DST_KEY_DS); 2041 keystate_status(dkey->key, &buf, 2042 "zone rrsig: ", DST_KEY_ZRRSIG); 2043 keystate_status(dkey->key, &buf, 2044 "key rrsig: ", DST_KEY_KRRSIG); 2045 } 2046 } 2047