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