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