1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * SPDX-License-Identifier: MPL-2.0
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 https://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 #ifndef DNS_KEYTABLE_H
15 #define DNS_KEYTABLE_H 1
16 
17 /*****
18 ***** Module Info
19 *****/
20 
21 /*! \file
22  * \brief
23  * The keytable module provides services for storing and retrieving DNSSEC
24  * trusted keys, as well as the ability to find the deepest matching key
25  * for a given domain name.
26  *
27  * MP:
28  *\li	The module ensures appropriate synchronization of data structures it
29  *	creates and manipulates.
30  *
31  * Resources:
32  *\li	TBS
33  *
34  * Security:
35  *\li	No anticipated impact.
36  */
37 
38 #include <stdbool.h>
39 
40 #include <isc/lang.h>
41 #include <isc/magic.h>
42 #include <isc/refcount.h>
43 #include <isc/rwlock.h>
44 #include <isc/stdtime.h>
45 
46 #include <dns/rdatastruct.h>
47 #include <dns/types.h>
48 
49 #include <dst/dst.h>
50 
51 ISC_LANG_BEGINDECLS
52 
53 isc_result_t
54 dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep);
55 /*%<
56  * Create a keytable.
57  *
58  * Requires:
59  *
60  *\li	'mctx' is a valid memory context.
61  *
62  *\li	keytablep != NULL && *keytablep == NULL
63  *
64  * Ensures:
65  *
66  *\li	On success, *keytablep is a valid, empty key table.
67  *
68  * Returns:
69  *
70  *\li	ISC_R_SUCCESS
71  *
72  *\li	Any other result indicates failure.
73  */
74 
75 void
76 dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp);
77 /*%<
78  * Attach *targetp to source.
79  *
80  * Requires:
81  *
82  *\li	'source' is a valid keytable.
83  *
84  *\li	'targetp' points to a NULL dns_keytable_t *.
85  *
86  * Ensures:
87  *
88  *\li	*targetp is attached to source.
89  */
90 
91 void
92 dns_keytable_detach(dns_keytable_t **keytablep);
93 /*%<
94  * Detach *keytablep from its keytable.
95  *
96  * Requires:
97  *
98  *\li	'keytablep' points to a valid keytable.
99  *
100  * Ensures:
101  *
102  *\li	*keytablep is NULL.
103  *
104  *\li	If '*keytablep' is the last reference to the keytable,
105  *		all resources used by the keytable will be freed
106  */
107 
108 isc_result_t
109 dns_keytable_add(dns_keytable_t *keytable, bool managed, bool initial,
110 		 dns_name_t *name, dns_rdata_ds_t *ds);
111 /*%<
112  * Add a key to 'keytable'. The keynode associated with 'name'
113  * is updated with the DS specified in 'ds'.
114  *
115  * The value of keynode->managed is set to 'managed', and the
116  * value of keynode->initial is set to 'initial'. (Note: 'initial'
117  * should only be used when adding managed-keys from configuration.
118  * This indicates the key is in "initializing" state, and has not yet
119  * been confirmed with a key refresh query.  Once a key refresh query
120  * has validated, we update the keynode with initial == false.)
121  *
122  * Notes:
123  *
124  *\li   If the key already exists in the table, adding it again
125  *      has no effect and ISC_R_SUCCESS is returned.
126  *
127  * Requires:
128  *
129  *\li	'keytable' points to a valid keytable.
130  *\li	'ds' is not NULL.
131  *\li	if 'initial' is true then 'managed' must also be true.
132  *
133  * Returns:
134  *
135  *\li	ISC_R_SUCCESS
136  *\li	ISC_R_EXISTS
137  *
138  *\li	Any other result indicates failure.
139  */
140 
141 isc_result_t
142 dns_keytable_marksecure(dns_keytable_t *keytable, const dns_name_t *name);
143 /*%<
144  * Add a null key to 'keytable' for name 'name'.  This marks the
145  * name as a secure domain, but doesn't supply any key data to allow the
146  * domain to be validated.  (Used when automated trust anchor management
147  * has gotten broken by a zone misconfiguration; for example, when the
148  * active key has been revoked but the stand-by key was still in its 30-day
149  * waiting period for validity.)
150  *
151  * Notes:
152  *
153  *\li   If a key already exists in the table, ISC_R_EXISTS is
154  *      returned and nothing is done.
155  *
156  * Requires:
157  *
158  *\li	'keytable' points to a valid keytable.
159  *
160  *\li	keyp != NULL && *keyp is a valid dst_key_t *.
161  *
162  * Returns:
163  *
164  *\li	ISC_R_SUCCESS
165  *\li	ISC_R_EXISTS
166  *
167  *\li	Any other result indicates failure.
168  */
169 
170 isc_result_t
171 dns_keytable_delete(dns_keytable_t *keytable, const dns_name_t *keyname);
172 /*%<
173  * Delete all trust anchors from 'keytable' matching name 'keyname'
174  *
175  * Requires:
176  *
177  *\li	'keytable' points to a valid keytable.
178  *
179  *\li	'name' is not NULL
180  *
181  * Returns:
182  *
183  *\li	ISC_R_SUCCESS
184  *
185  *\li	Any other result indicates failure.
186  */
187 
188 isc_result_t
189 dns_keytable_deletekey(dns_keytable_t *keytable, const dns_name_t *keyname,
190 		       dns_rdata_dnskey_t *dnskey);
191 /*%<
192  * Remove the trust anchor matching the name 'keyname' and the DNSKEY
193  * rdata struct 'dnskey' from 'keytable'.
194  *
195  * Requires:
196  *
197  *\li	'keytable' points to a valid keytable.
198  *\li	'dnskey' is not NULL
199  *
200  * Returns:
201  *
202  *\li	ISC_R_SUCCESS
203  *
204  *\li	Any other result indicates failure.
205  */
206 
207 isc_result_t
208 dns_keytable_find(dns_keytable_t *keytable, const dns_name_t *keyname,
209 		  dns_keynode_t **keynodep);
210 /*%<
211  * Search for the first instance of a trust anchor named 'name' in
212  * 'keytable', without regard to keyid and algorithm.
213  *
214  * Requires:
215  *
216  *\li	'keytable' is a valid keytable.
217  *
218  *\li	'name' is a valid absolute name.
219  *
220  *\li	keynodep != NULL && *keynodep == NULL
221  *
222  * Returns:
223  *
224  *\li	ISC_R_SUCCESS
225  *\li	ISC_R_NOTFOUND
226  *
227  *\li	Any other result indicates an error.
228  */
229 
230 isc_result_t
231 dns_keytable_finddeepestmatch(dns_keytable_t *keytable, const dns_name_t *name,
232 			      dns_name_t *foundname);
233 /*%<
234  * Search for the deepest match of 'name' in 'keytable'.
235  *
236  * Requires:
237  *
238  *\li	'keytable' is a valid keytable.
239  *
240  *\li	'name' is a valid absolute name.
241  *
242  *\li	'foundname' is a name with a dedicated buffer.
243  *
244  * Returns:
245  *
246  *\li	ISC_R_SUCCESS
247  *\li	ISC_R_NOTFOUND
248  *
249  *\li	Any other result indicates an error.
250  */
251 
252 void
253 dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep);
254 /*%<
255  * Detach a keynode found via dns_keytable_find().
256  *
257  * Requires:
258  *
259  *\li	*keynodep is a valid keynode returned by a call to dns_keytable_find().
260  *
261  * Ensures:
262  *
263  *\li	*keynodep == NULL
264  */
265 
266 isc_result_t
267 dns_keytable_issecuredomain(dns_keytable_t *keytable, const dns_name_t *name,
268 			    dns_name_t *foundname, bool *wantdnssecp);
269 /*%<
270  * Is 'name' at or beneath a trusted key?
271  *
272  * Requires:
273  *
274  *\li	'keytable' is a valid keytable.
275  *
276  *\li	'name' is a valid absolute name.
277  *
278  *\li	'foundanme' is NULL or is a pointer to an initialized dns_name_t
279  *
280  *\li	'*wantsdnssecp' is a valid bool.
281  *
282  * Ensures:
283  *
284  *\li	On success, *wantsdnssecp will be true if and only if 'name'
285  *	is at or beneath a trusted key.  If 'foundname' is not NULL, then
286  *	it will be updated to contain the name of the closest enclosing
287  *	trust anchor.
288  *
289  * Returns:
290  *
291  *\li	ISC_R_SUCCESS
292  *
293  *\li	Any other result is an error.
294  */
295 
296 isc_result_t
297 dns_keytable_dump(dns_keytable_t *keytable, FILE *fp);
298 /*%<
299  * Dump the keytable on fp.
300  */
301 
302 isc_result_t
303 dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **buf);
304 /*%<
305  * Dump the keytable to buffer at 'buf'
306  */
307 
308 bool
309 dns_keynode_dsset(dns_keynode_t *keynode, dns_rdataset_t *rdataset);
310 /*%<
311  * Clone the DS RRset associated with 'keynode' into 'rdataset' if
312  * it exists.  'dns_rdataset_disassociate(rdataset)' needs to be
313  * called when done.
314  *
315  * Returns:
316  *\li	true if there is a DS RRset.
317  *\li	false if there isn't DS RRset.
318  *
319  * Requires:
320  *\li	'keynode' is valid.
321  *\li	'rdataset' is valid or NULL.
322  */
323 
324 bool
325 dns_keynode_managed(dns_keynode_t *keynode);
326 /*%<
327  * Is this flagged as a managed key?
328  */
329 
330 bool
331 dns_keynode_initial(dns_keynode_t *keynode);
332 /*%<
333  * Is this flagged as an initializing key?
334  */
335 
336 void
337 dns_keynode_trust(dns_keynode_t *keynode);
338 /*%<
339  * Sets keynode->initial to false in order to mark the key as
340  * trusted: no longer an initializing key.
341  */
342 
343 isc_result_t
344 dns_keytable_forall(dns_keytable_t *keytable,
345 		    void (*func)(dns_keytable_t *, dns_keynode_t *,
346 				 dns_name_t *, void *),
347 		    void *arg);
348 ISC_LANG_ENDDECLS
349 
350 #endif /* DNS_KEYTABLE_H */
351