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