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