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