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