xref: /netbsd-src/external/mpl/bind/dist/lib/dns/kasp.c (revision 154bfe8e089c1a0a4e9ed8414f08d3da90949162)
1 /*	$NetBSD: kasp.c,v 1.2 2020/05/24 19:46:23 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 <string.h>
17 
18 #include <isc/assertions.h>
19 #include <isc/file.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
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 
57 	kasp->zone_max_ttl = DNS_KASP_ZONE_MAXTTL;
58 	kasp->zone_propagation_delay = DNS_KASP_ZONE_PROPDELAY;
59 
60 	kasp->parent_ds_ttl = DNS_KASP_DS_TTL;
61 	kasp->parent_propagation_delay = DNS_KASP_PARENT_PROPDELAY;
62 	kasp->parent_registration_delay = DNS_KASP_PARENT_REGDELAY;
63 
64 	/* TODO: The rest of the KASP configuration */
65 
66 	kasp->magic = DNS_KASP_MAGIC;
67 	*kaspp = kasp;
68 
69 	return (ISC_R_SUCCESS);
70 }
71 
72 void
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
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
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 *
113 dns_kasp_getname(dns_kasp_t *kasp) {
114 	REQUIRE(DNS_KASP_VALID(kasp));
115 
116 	return (kasp->name);
117 }
118 
119 void
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
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
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
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
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
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
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
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
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 = value;
189 }
190 
191 dns_ttl_t
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
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
208 dns_kasp_publishsafety(dns_kasp_t *kasp) {
209 	REQUIRE(DNS_KASP_VALID(kasp));
210 	REQUIRE(kasp->frozen);
211 
212 	return (kasp->publish_safety);
213 }
214 
215 void
216 dns_kasp_setpublishsafety(dns_kasp_t *kasp, uint32_t value) {
217 	REQUIRE(DNS_KASP_VALID(kasp));
218 	REQUIRE(!kasp->frozen);
219 
220 	kasp->publish_safety = value;
221 }
222 
223 uint32_t
224 dns_kasp_retiresafety(dns_kasp_t *kasp) {
225 	REQUIRE(DNS_KASP_VALID(kasp));
226 	REQUIRE(kasp->frozen);
227 
228 	return (kasp->retire_safety);
229 }
230 
231 void
232 dns_kasp_setretiresafety(dns_kasp_t *kasp, uint32_t value) {
233 	REQUIRE(DNS_KASP_VALID(kasp));
234 	REQUIRE(!kasp->frozen);
235 
236 	kasp->retire_safety = value;
237 }
238 
239 dns_ttl_t
240 dns_kasp_zonemaxttl(dns_kasp_t *kasp) {
241 	REQUIRE(DNS_KASP_VALID(kasp));
242 	REQUIRE(kasp->frozen);
243 
244 	return (kasp->zone_max_ttl);
245 }
246 
247 void
248 dns_kasp_setzonemaxttl(dns_kasp_t *kasp, dns_ttl_t ttl) {
249 	REQUIRE(DNS_KASP_VALID(kasp));
250 	REQUIRE(!kasp->frozen);
251 
252 	kasp->zone_max_ttl = ttl;
253 }
254 
255 uint32_t
256 dns_kasp_zonepropagationdelay(dns_kasp_t *kasp) {
257 	REQUIRE(DNS_KASP_VALID(kasp));
258 	REQUIRE(kasp->frozen);
259 
260 	return (kasp->zone_propagation_delay);
261 }
262 
263 void
264 dns_kasp_setzonepropagationdelay(dns_kasp_t *kasp, uint32_t value) {
265 	REQUIRE(DNS_KASP_VALID(kasp));
266 	REQUIRE(!kasp->frozen);
267 
268 	kasp->zone_propagation_delay = value;
269 }
270 
271 dns_ttl_t
272 dns_kasp_dsttl(dns_kasp_t *kasp) {
273 	REQUIRE(DNS_KASP_VALID(kasp));
274 	REQUIRE(kasp->frozen);
275 
276 	return (kasp->parent_ds_ttl);
277 }
278 
279 void
280 dns_kasp_setdsttl(dns_kasp_t *kasp, dns_ttl_t ttl) {
281 	REQUIRE(DNS_KASP_VALID(kasp));
282 	REQUIRE(!kasp->frozen);
283 
284 	kasp->parent_ds_ttl = ttl;
285 }
286 
287 uint32_t
288 dns_kasp_parentpropagationdelay(dns_kasp_t *kasp) {
289 	REQUIRE(DNS_KASP_VALID(kasp));
290 	REQUIRE(kasp->frozen);
291 
292 	return (kasp->parent_propagation_delay);
293 }
294 
295 void
296 dns_kasp_setparentpropagationdelay(dns_kasp_t *kasp, uint32_t value) {
297 	REQUIRE(DNS_KASP_VALID(kasp));
298 	REQUIRE(!kasp->frozen);
299 
300 	kasp->parent_propagation_delay = value;
301 }
302 
303 uint32_t
304 dns_kasp_parentregistrationdelay(dns_kasp_t *kasp) {
305 	REQUIRE(DNS_KASP_VALID(kasp));
306 	REQUIRE(kasp->frozen);
307 
308 	return (kasp->parent_registration_delay);
309 }
310 
311 void
312 dns_kasp_setparentregistrationdelay(dns_kasp_t *kasp, uint32_t value) {
313 	REQUIRE(DNS_KASP_VALID(kasp));
314 	REQUIRE(!kasp->frozen);
315 
316 	kasp->parent_registration_delay = value;
317 }
318 
319 isc_result_t
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
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
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
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
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
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
398 dns_kasp_key_algorithm(dns_kasp_key_t *key) {
399 	REQUIRE(key != NULL);
400 
401 	return (key->algorithm);
402 }
403 
404 unsigned int
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 = 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 = 32;
437 		break;
438 	case DNS_KEYALG_ED448:
439 		size = 57;
440 		break;
441 	default:
442 		/* unsupported */
443 		break;
444 	}
445 	return (size);
446 }
447 
448 uint32_t
449 dns_kasp_key_lifetime(dns_kasp_key_t *key) {
450 	REQUIRE(key != NULL);
451 
452 	return (key->lifetime);
453 }
454 
455 bool
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
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