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