1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
7  *
8  * See the COPYRIGHT file distributed with this work for additional
9  * information regarding copyright ownership.
10  */
11 
12 /*! \file */
13 
14 #include <string.h>
15 
16 #include <isc/assertions.h>
17 #include <isc/buffer.h>
18 #include <isc/file.h>
19 #include <isc/hex.h>
20 #include <isc/log.h>
21 #include <isc/mem.h>
22 #include <isc/util.h>
23 
24 #include <dns/kasp.h>
25 #include <dns/keyvalues.h>
26 #include <dns/log.h>
27 
28 isc_result_t
dns_kasp_create(isc_mem_t * mctx,const char * name,dns_kasp_t ** kaspp)29 dns_kasp_create(isc_mem_t *mctx, const char *name, dns_kasp_t **kaspp) {
30 	dns_kasp_t *kasp;
31 
32 	REQUIRE(name != NULL);
33 	REQUIRE(kaspp != NULL && *kaspp == NULL);
34 
35 	kasp = isc_mem_get(mctx, sizeof(*kasp));
36 	kasp->mctx = NULL;
37 	isc_mem_attach(mctx, &kasp->mctx);
38 
39 	kasp->name = isc_mem_strdup(mctx, name);
40 	isc_mutex_init(&kasp->lock);
41 	kasp->frozen = false;
42 
43 	isc_refcount_init(&kasp->references, 1);
44 
45 	ISC_LINK_INIT(kasp, link);
46 
47 	kasp->signatures_refresh = DNS_KASP_SIG_REFRESH;
48 	kasp->signatures_validity = DNS_KASP_SIG_VALIDITY;
49 	kasp->signatures_validity_dnskey = DNS_KASP_SIG_VALIDITY_DNSKEY;
50 
51 	ISC_LIST_INIT(kasp->keys);
52 
53 	kasp->dnskey_ttl = DNS_KASP_KEY_TTL;
54 	kasp->publish_safety = DNS_KASP_PUBLISH_SAFETY;
55 	kasp->retire_safety = DNS_KASP_RETIRE_SAFETY;
56 	kasp->purge_keys = DNS_KASP_PURGE_KEYS;
57 
58 	kasp->zone_max_ttl = DNS_KASP_ZONE_MAXTTL;
59 	kasp->zone_propagation_delay = DNS_KASP_ZONE_PROPDELAY;
60 
61 	kasp->parent_ds_ttl = DNS_KASP_DS_TTL;
62 	kasp->parent_propagation_delay = DNS_KASP_PARENT_PROPDELAY;
63 
64 	kasp->nsec3 = false;
65 
66 	kasp->magic = DNS_KASP_MAGIC;
67 	*kaspp = kasp;
68 
69 	return (ISC_R_SUCCESS);
70 }
71 
72 void
dns_kasp_attach(dns_kasp_t * source,dns_kasp_t ** targetp)73 dns_kasp_attach(dns_kasp_t *source, dns_kasp_t **targetp) {
74 	REQUIRE(DNS_KASP_VALID(source));
75 	REQUIRE(targetp != NULL && *targetp == NULL);
76 
77 	isc_refcount_increment(&source->references);
78 	*targetp = source;
79 }
80 
81 static inline void
destroy(dns_kasp_t * kasp)82 destroy(dns_kasp_t *kasp) {
83 	dns_kasp_key_t *key;
84 	dns_kasp_key_t *key_next;
85 
86 	REQUIRE(!ISC_LINK_LINKED(kasp, link));
87 
88 	for (key = ISC_LIST_HEAD(kasp->keys); key != NULL; key = key_next) {
89 		key_next = ISC_LIST_NEXT(key, link);
90 		ISC_LIST_UNLINK(kasp->keys, key, link);
91 		dns_kasp_key_destroy(key);
92 	}
93 	INSIST(ISC_LIST_EMPTY(kasp->keys));
94 
95 	isc_mutex_destroy(&kasp->lock);
96 	isc_mem_free(kasp->mctx, kasp->name);
97 	isc_mem_putanddetach(&kasp->mctx, kasp, sizeof(*kasp));
98 }
99 
100 void
dns_kasp_detach(dns_kasp_t ** kaspp)101 dns_kasp_detach(dns_kasp_t **kaspp) {
102 	REQUIRE(kaspp != NULL && DNS_KASP_VALID(*kaspp));
103 
104 	dns_kasp_t *kasp = *kaspp;
105 	*kaspp = NULL;
106 
107 	if (isc_refcount_decrement(&kasp->references) == 1) {
108 		destroy(kasp);
109 	}
110 }
111 
112 const char *
dns_kasp_getname(dns_kasp_t * kasp)113 dns_kasp_getname(dns_kasp_t *kasp) {
114 	REQUIRE(DNS_KASP_VALID(kasp));
115 
116 	return (kasp->name);
117 }
118 
119 void
dns_kasp_freeze(dns_kasp_t * kasp)120 dns_kasp_freeze(dns_kasp_t *kasp) {
121 	REQUIRE(DNS_KASP_VALID(kasp));
122 	REQUIRE(!kasp->frozen);
123 
124 	kasp->frozen = true;
125 }
126 
127 void
dns_kasp_thaw(dns_kasp_t * kasp)128 dns_kasp_thaw(dns_kasp_t *kasp) {
129 	REQUIRE(DNS_KASP_VALID(kasp));
130 	REQUIRE(kasp->frozen);
131 
132 	kasp->frozen = false;
133 }
134 
135 uint32_t
dns_kasp_signdelay(dns_kasp_t * kasp)136 dns_kasp_signdelay(dns_kasp_t *kasp) {
137 	REQUIRE(DNS_KASP_VALID(kasp));
138 	REQUIRE(kasp->frozen);
139 
140 	return (kasp->signatures_validity - kasp->signatures_refresh);
141 }
142 
143 uint32_t
dns_kasp_sigrefresh(dns_kasp_t * kasp)144 dns_kasp_sigrefresh(dns_kasp_t *kasp) {
145 	REQUIRE(DNS_KASP_VALID(kasp));
146 	REQUIRE(kasp->frozen);
147 
148 	return (kasp->signatures_refresh);
149 }
150 
151 void
dns_kasp_setsigrefresh(dns_kasp_t * kasp,uint32_t value)152 dns_kasp_setsigrefresh(dns_kasp_t *kasp, uint32_t value) {
153 	REQUIRE(DNS_KASP_VALID(kasp));
154 	REQUIRE(!kasp->frozen);
155 
156 	kasp->signatures_refresh = value;
157 }
158 
159 uint32_t
dns_kasp_sigvalidity(dns_kasp_t * kasp)160 dns_kasp_sigvalidity(dns_kasp_t *kasp) {
161 	REQUIRE(DNS_KASP_VALID(kasp));
162 	REQUIRE(kasp->frozen);
163 
164 	return (kasp->signatures_validity);
165 }
166 
167 void
dns_kasp_setsigvalidity(dns_kasp_t * kasp,uint32_t value)168 dns_kasp_setsigvalidity(dns_kasp_t *kasp, uint32_t value) {
169 	REQUIRE(DNS_KASP_VALID(kasp));
170 	REQUIRE(!kasp->frozen);
171 
172 	kasp->signatures_validity = value;
173 }
174 
175 uint32_t
dns_kasp_sigvalidity_dnskey(dns_kasp_t * kasp)176 dns_kasp_sigvalidity_dnskey(dns_kasp_t *kasp) {
177 	REQUIRE(DNS_KASP_VALID(kasp));
178 	REQUIRE(kasp->frozen);
179 
180 	return (kasp->signatures_validity_dnskey);
181 }
182 
183 void
dns_kasp_setsigvalidity_dnskey(dns_kasp_t * kasp,uint32_t value)184 dns_kasp_setsigvalidity_dnskey(dns_kasp_t *kasp, uint32_t value) {
185 	REQUIRE(DNS_KASP_VALID(kasp));
186 	REQUIRE(!kasp->frozen);
187 
188 	kasp->signatures_validity_dnskey = value;
189 }
190 
191 dns_ttl_t
dns_kasp_dnskeyttl(dns_kasp_t * kasp)192 dns_kasp_dnskeyttl(dns_kasp_t *kasp) {
193 	REQUIRE(DNS_KASP_VALID(kasp));
194 	REQUIRE(kasp->frozen);
195 
196 	return (kasp->dnskey_ttl);
197 }
198 
199 void
dns_kasp_setdnskeyttl(dns_kasp_t * kasp,dns_ttl_t ttl)200 dns_kasp_setdnskeyttl(dns_kasp_t *kasp, dns_ttl_t ttl) {
201 	REQUIRE(DNS_KASP_VALID(kasp));
202 	REQUIRE(!kasp->frozen);
203 
204 	kasp->dnskey_ttl = ttl;
205 }
206 
207 uint32_t
dns_kasp_purgekeys(dns_kasp_t * kasp)208 dns_kasp_purgekeys(dns_kasp_t *kasp) {
209 	REQUIRE(DNS_KASP_VALID(kasp));
210 	REQUIRE(kasp->frozen);
211 
212 	return (kasp->purge_keys);
213 }
214 
215 void
dns_kasp_setpurgekeys(dns_kasp_t * kasp,uint32_t value)216 dns_kasp_setpurgekeys(dns_kasp_t *kasp, uint32_t value) {
217 	REQUIRE(DNS_KASP_VALID(kasp));
218 	REQUIRE(!kasp->frozen);
219 
220 	kasp->purge_keys = value;
221 }
222 
223 uint32_t
dns_kasp_publishsafety(dns_kasp_t * kasp)224 dns_kasp_publishsafety(dns_kasp_t *kasp) {
225 	REQUIRE(DNS_KASP_VALID(kasp));
226 	REQUIRE(kasp->frozen);
227 
228 	return (kasp->publish_safety);
229 }
230 
231 void
dns_kasp_setpublishsafety(dns_kasp_t * kasp,uint32_t value)232 dns_kasp_setpublishsafety(dns_kasp_t *kasp, uint32_t value) {
233 	REQUIRE(DNS_KASP_VALID(kasp));
234 	REQUIRE(!kasp->frozen);
235 
236 	kasp->publish_safety = value;
237 }
238 
239 uint32_t
dns_kasp_retiresafety(dns_kasp_t * kasp)240 dns_kasp_retiresafety(dns_kasp_t *kasp) {
241 	REQUIRE(DNS_KASP_VALID(kasp));
242 	REQUIRE(kasp->frozen);
243 
244 	return (kasp->retire_safety);
245 }
246 
247 void
dns_kasp_setretiresafety(dns_kasp_t * kasp,uint32_t value)248 dns_kasp_setretiresafety(dns_kasp_t *kasp, uint32_t value) {
249 	REQUIRE(DNS_KASP_VALID(kasp));
250 	REQUIRE(!kasp->frozen);
251 
252 	kasp->retire_safety = value;
253 }
254 
255 dns_ttl_t
dns_kasp_zonemaxttl(dns_kasp_t * kasp)256 dns_kasp_zonemaxttl(dns_kasp_t *kasp) {
257 	REQUIRE(DNS_KASP_VALID(kasp));
258 	REQUIRE(kasp->frozen);
259 
260 	return (kasp->zone_max_ttl);
261 }
262 
263 void
dns_kasp_setzonemaxttl(dns_kasp_t * kasp,dns_ttl_t ttl)264 dns_kasp_setzonemaxttl(dns_kasp_t *kasp, dns_ttl_t ttl) {
265 	REQUIRE(DNS_KASP_VALID(kasp));
266 	REQUIRE(!kasp->frozen);
267 
268 	kasp->zone_max_ttl = ttl;
269 }
270 
271 uint32_t
dns_kasp_zonepropagationdelay(dns_kasp_t * kasp)272 dns_kasp_zonepropagationdelay(dns_kasp_t *kasp) {
273 	REQUIRE(DNS_KASP_VALID(kasp));
274 	REQUIRE(kasp->frozen);
275 
276 	return (kasp->zone_propagation_delay);
277 }
278 
279 void
dns_kasp_setzonepropagationdelay(dns_kasp_t * kasp,uint32_t value)280 dns_kasp_setzonepropagationdelay(dns_kasp_t *kasp, uint32_t value) {
281 	REQUIRE(DNS_KASP_VALID(kasp));
282 	REQUIRE(!kasp->frozen);
283 
284 	kasp->zone_propagation_delay = value;
285 }
286 
287 dns_ttl_t
dns_kasp_dsttl(dns_kasp_t * kasp)288 dns_kasp_dsttl(dns_kasp_t *kasp) {
289 	REQUIRE(DNS_KASP_VALID(kasp));
290 	REQUIRE(kasp->frozen);
291 
292 	return (kasp->parent_ds_ttl);
293 }
294 
295 void
dns_kasp_setdsttl(dns_kasp_t * kasp,dns_ttl_t ttl)296 dns_kasp_setdsttl(dns_kasp_t *kasp, dns_ttl_t ttl) {
297 	REQUIRE(DNS_KASP_VALID(kasp));
298 	REQUIRE(!kasp->frozen);
299 
300 	kasp->parent_ds_ttl = ttl;
301 }
302 
303 uint32_t
dns_kasp_parentpropagationdelay(dns_kasp_t * kasp)304 dns_kasp_parentpropagationdelay(dns_kasp_t *kasp) {
305 	REQUIRE(DNS_KASP_VALID(kasp));
306 	REQUIRE(kasp->frozen);
307 
308 	return (kasp->parent_propagation_delay);
309 }
310 
311 void
dns_kasp_setparentpropagationdelay(dns_kasp_t * kasp,uint32_t value)312 dns_kasp_setparentpropagationdelay(dns_kasp_t *kasp, uint32_t value) {
313 	REQUIRE(DNS_KASP_VALID(kasp));
314 	REQUIRE(!kasp->frozen);
315 
316 	kasp->parent_propagation_delay = value;
317 }
318 
319 isc_result_t
dns_kasplist_find(dns_kasplist_t * list,const char * name,dns_kasp_t ** kaspp)320 dns_kasplist_find(dns_kasplist_t *list, const char *name, dns_kasp_t **kaspp) {
321 	dns_kasp_t *kasp = NULL;
322 
323 	REQUIRE(kaspp != NULL && *kaspp == NULL);
324 
325 	if (list == NULL) {
326 		return (ISC_R_NOTFOUND);
327 	}
328 
329 	for (kasp = ISC_LIST_HEAD(*list); kasp != NULL;
330 	     kasp = ISC_LIST_NEXT(kasp, link))
331 	{
332 		if (strcmp(kasp->name, name) == 0) {
333 			break;
334 		}
335 	}
336 
337 	if (kasp == NULL) {
338 		return (ISC_R_NOTFOUND);
339 	}
340 
341 	dns_kasp_attach(kasp, kaspp);
342 	return (ISC_R_SUCCESS);
343 }
344 
345 dns_kasp_keylist_t
dns_kasp_keys(dns_kasp_t * kasp)346 dns_kasp_keys(dns_kasp_t *kasp) {
347 	REQUIRE(DNS_KASP_VALID(kasp));
348 	REQUIRE(kasp->frozen);
349 
350 	return (kasp->keys);
351 }
352 
353 bool
dns_kasp_keylist_empty(dns_kasp_t * kasp)354 dns_kasp_keylist_empty(dns_kasp_t *kasp) {
355 	REQUIRE(DNS_KASP_VALID(kasp));
356 
357 	return (ISC_LIST_EMPTY(kasp->keys));
358 }
359 
360 void
dns_kasp_addkey(dns_kasp_t * kasp,dns_kasp_key_t * key)361 dns_kasp_addkey(dns_kasp_t *kasp, dns_kasp_key_t *key) {
362 	REQUIRE(DNS_KASP_VALID(kasp));
363 	REQUIRE(!kasp->frozen);
364 	REQUIRE(key != NULL);
365 
366 	ISC_LIST_APPEND(kasp->keys, key, link);
367 }
368 
369 isc_result_t
dns_kasp_key_create(dns_kasp_t * kasp,dns_kasp_key_t ** keyp)370 dns_kasp_key_create(dns_kasp_t *kasp, dns_kasp_key_t **keyp) {
371 	dns_kasp_key_t *key;
372 
373 	REQUIRE(DNS_KASP_VALID(kasp));
374 	REQUIRE(keyp != NULL && *keyp == NULL);
375 
376 	key = isc_mem_get(kasp->mctx, sizeof(*key));
377 	key->mctx = NULL;
378 	isc_mem_attach(kasp->mctx, &key->mctx);
379 
380 	ISC_LINK_INIT(key, link);
381 
382 	key->lifetime = 0;
383 	key->algorithm = 0;
384 	key->length = -1;
385 	key->role = 0;
386 	*keyp = key;
387 	return (ISC_R_SUCCESS);
388 }
389 
390 void
dns_kasp_key_destroy(dns_kasp_key_t * key)391 dns_kasp_key_destroy(dns_kasp_key_t *key) {
392 	REQUIRE(key != NULL);
393 
394 	isc_mem_putanddetach(&key->mctx, key, sizeof(*key));
395 }
396 
397 uint32_t
dns_kasp_key_algorithm(dns_kasp_key_t * key)398 dns_kasp_key_algorithm(dns_kasp_key_t *key) {
399 	REQUIRE(key != NULL);
400 
401 	return (key->algorithm);
402 }
403 
404 unsigned int
dns_kasp_key_size(dns_kasp_key_t * key)405 dns_kasp_key_size(dns_kasp_key_t *key) {
406 	unsigned int size = 0;
407 	unsigned int min = 0;
408 
409 	REQUIRE(key != NULL);
410 
411 	switch (key->algorithm) {
412 	case DNS_KEYALG_RSASHA1:
413 	case DNS_KEYALG_NSEC3RSASHA1:
414 	case DNS_KEYALG_RSASHA256:
415 	case DNS_KEYALG_RSASHA512:
416 		min = (key->algorithm == DNS_KEYALG_RSASHA512) ? 1024 : 512;
417 		if (key->length > -1) {
418 			size = (unsigned int)key->length;
419 			if (size < min) {
420 				size = min;
421 			}
422 			if (size > 4096) {
423 				size = 4096;
424 			}
425 		} else {
426 			size = 2048;
427 		}
428 		break;
429 	case DNS_KEYALG_ECDSA256:
430 		size = 256;
431 		break;
432 	case DNS_KEYALG_ECDSA384:
433 		size = 384;
434 		break;
435 	case DNS_KEYALG_ED25519:
436 		size = 256;
437 		break;
438 	case DNS_KEYALG_ED448:
439 		size = 456;
440 		break;
441 	default:
442 		/* unsupported */
443 		break;
444 	}
445 	return (size);
446 }
447 
448 uint32_t
dns_kasp_key_lifetime(dns_kasp_key_t * key)449 dns_kasp_key_lifetime(dns_kasp_key_t *key) {
450 	REQUIRE(key != NULL);
451 
452 	return (key->lifetime);
453 }
454 
455 bool
dns_kasp_key_ksk(dns_kasp_key_t * key)456 dns_kasp_key_ksk(dns_kasp_key_t *key) {
457 	REQUIRE(key != NULL);
458 
459 	return (key->role & DNS_KASP_KEY_ROLE_KSK);
460 }
461 
462 bool
dns_kasp_key_zsk(dns_kasp_key_t * key)463 dns_kasp_key_zsk(dns_kasp_key_t *key) {
464 	REQUIRE(key != NULL);
465 
466 	return (key->role & DNS_KASP_KEY_ROLE_ZSK);
467 }
468 
469 uint8_t
dns_kasp_nsec3iter(dns_kasp_t * kasp)470 dns_kasp_nsec3iter(dns_kasp_t *kasp) {
471 	REQUIRE(kasp != NULL);
472 	REQUIRE(kasp->frozen);
473 	REQUIRE(kasp->nsec3);
474 
475 	return (kasp->nsec3param.iterations);
476 }
477 
478 uint8_t
dns_kasp_nsec3flags(dns_kasp_t * kasp)479 dns_kasp_nsec3flags(dns_kasp_t *kasp) {
480 	REQUIRE(kasp != NULL);
481 	REQUIRE(kasp->frozen);
482 	REQUIRE(kasp->nsec3);
483 
484 	if (kasp->nsec3param.optout) {
485 		return (0x01);
486 	}
487 	return (0x00);
488 }
489 
490 uint8_t
dns_kasp_nsec3saltlen(dns_kasp_t * kasp)491 dns_kasp_nsec3saltlen(dns_kasp_t *kasp) {
492 	REQUIRE(kasp != NULL);
493 	REQUIRE(kasp->frozen);
494 	REQUIRE(kasp->nsec3);
495 
496 	return (kasp->nsec3param.saltlen);
497 }
498 
499 bool
dns_kasp_nsec3(dns_kasp_t * kasp)500 dns_kasp_nsec3(dns_kasp_t *kasp) {
501 	REQUIRE(kasp != NULL);
502 	REQUIRE(kasp->frozen);
503 
504 	return kasp->nsec3;
505 }
506 
507 void
dns_kasp_setnsec3(dns_kasp_t * kasp,bool nsec3)508 dns_kasp_setnsec3(dns_kasp_t *kasp, bool nsec3) {
509 	REQUIRE(kasp != NULL);
510 	REQUIRE(!kasp->frozen);
511 
512 	kasp->nsec3 = nsec3;
513 }
514 
515 void
dns_kasp_setnsec3param(dns_kasp_t * kasp,uint8_t iter,bool optout,uint8_t saltlen)516 dns_kasp_setnsec3param(dns_kasp_t *kasp, uint8_t iter, bool optout,
517 		       uint8_t saltlen) {
518 	REQUIRE(kasp != NULL);
519 	REQUIRE(!kasp->frozen);
520 	REQUIRE(kasp->nsec3);
521 
522 	kasp->nsec3param.iterations = iter;
523 	kasp->nsec3param.optout = optout;
524 	kasp->nsec3param.saltlen = saltlen;
525 }
526