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