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