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