1 /*	$NetBSD: keytable.h,v 1.4 2014/12/10 04:37:58 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2004, 2005, 2007, 2009, 2010  Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (C) 2000, 2001  Internet Software Consortium.
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /* Id: keytable.h,v 1.23 2010/06/25 03:24:05 marka Exp  */
21 
22 #ifndef DNS_KEYTABLE_H
23 #define DNS_KEYTABLE_H 1
24 
25 /*****
26  ***** Module Info
27  *****/
28 
29 /*! \file
30  * \brief
31  * The keytable module provides services for storing and retrieving DNSSEC
32  * trusted keys, as well as the ability to find the deepest matching key
33  * for a given domain name.
34  *
35  * MP:
36  *\li	The module ensures appropriate synchronization of data structures it
37  *	creates and manipulates.
38  *
39  * Resources:
40  *\li	TBS
41  *
42  * Security:
43  *\li	No anticipated impact.
44  */
45 
46 #include <isc/lang.h>
47 #include <isc/magic.h>
48 #include <isc/refcount.h>
49 #include <isc/rwlock.h>
50 #include <isc/stdtime.h>
51 
52 #include <dns/types.h>
53 
54 #include <dst/dst.h>
55 
56 ISC_LANG_BEGINDECLS
57 
58 struct dns_keytable {
59 	/* Unlocked. */
60 	unsigned int		magic;
61 	isc_mem_t		*mctx;
62 	isc_mutex_t		lock;
63 	isc_rwlock_t		rwlock;
64 	/* Locked by lock. */
65 	isc_uint32_t		active_nodes;
66 	/* Locked by rwlock. */
67 	isc_uint32_t		references;
68 	dns_rbt_t		*table;
69 };
70 
71 #define KEYTABLE_MAGIC			ISC_MAGIC('K', 'T', 'b', 'l')
72 #define VALID_KEYTABLE(kt)	 	ISC_MAGIC_VALID(kt, KEYTABLE_MAGIC)
73 
74 struct dns_keynode {
75 	unsigned int		magic;
76 	isc_refcount_t		refcount;
77 	dst_key_t *		key;
78 	isc_boolean_t           managed;
79 	struct dns_keynode *	next;
80 };
81 
82 #define KEYNODE_MAGIC			ISC_MAGIC('K', 'N', 'o', 'd')
83 #define VALID_KEYNODE(kn)	 	ISC_MAGIC_VALID(kn, KEYNODE_MAGIC)
84 
85 isc_result_t
86 dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep);
87 /*%<
88  * Create a keytable.
89  *
90  * Requires:
91  *
92  *\li	'mctx' is a valid memory context.
93  *
94  *\li	keytablep != NULL && *keytablep == NULL
95  *
96  * Ensures:
97  *
98  *\li	On success, *keytablep is a valid, empty key table.
99  *
100  * Returns:
101  *
102  *\li	ISC_R_SUCCESS
103  *
104  *\li	Any other result indicates failure.
105  */
106 
107 
108 void
109 dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp);
110 /*%<
111  * Attach *targetp to source.
112  *
113  * Requires:
114  *
115  *\li	'source' is a valid keytable.
116  *
117  *\li	'targetp' points to a NULL dns_keytable_t *.
118  *
119  * Ensures:
120  *
121  *\li	*targetp is attached to source.
122  */
123 
124 void
125 dns_keytable_detach(dns_keytable_t **keytablep);
126 /*%<
127  * Detach *keytablep from its keytable.
128  *
129  * Requires:
130  *
131  *\li	'keytablep' points to a valid keytable.
132  *
133  * Ensures:
134  *
135  *\li	*keytablep is NULL.
136  *
137  *\li	If '*keytablep' is the last reference to the keytable,
138  *		all resources used by the keytable will be freed
139  */
140 
141 isc_result_t
142 dns_keytable_add(dns_keytable_t *keytable, isc_boolean_t managed,
143 		 dst_key_t **keyp);
144 /*%<
145  * Add '*keyp' to 'keytable' (using the name in '*keyp').
146  * The value of keynode->managed is set to 'managed'
147  *
148  * Notes:
149  *
150  *\li	Ownership of *keyp is transferred to the keytable.
151  *\li   If the key already exists in the table, ISC_R_EXISTS is
152  *      returned and the new key is freed.
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  * Ensures:
161  *
162  *\li	On success, *keyp == NULL
163  *
164  * Returns:
165  *
166  *\li	ISC_R_SUCCESS
167  *\li	ISC_R_EXISTS
168  *
169  *\li	Any other result indicates failure.
170  */
171 
172 isc_result_t
173 dns_keytable_marksecure(dns_keytable_t *keytable, dns_name_t *name);
174 /*%<
175  * Add a null key to 'keytable' for name 'name'.  This marks the
176  * name as a secure domain, but doesn't supply any key data to allow the
177  * domain to be validated.  (Used when automated trust anchor management
178  * has gotten broken by a zone misconfiguration; for example, when the
179  * active key has been revoked but the stand-by key was still in its 30-day
180  * waiting period for validity.)
181  *
182  * Notes:
183  *
184  *\li   If a key already exists in the table, ISC_R_EXISTS is
185  *      returned and nothing is done.
186  *
187  * Requires:
188  *
189  *\li	'keytable' points to a valid keytable.
190  *
191  *\li	keyp != NULL && *keyp is a valid dst_key_t *.
192  *
193  * Returns:
194  *
195  *\li	ISC_R_SUCCESS
196  *\li	ISC_R_EXISTS
197  *
198  *\li	Any other result indicates failure.
199  */
200 
201 isc_result_t
202 dns_keytable_delete(dns_keytable_t *keytable, dns_name_t *keyname);
203 /*%<
204  * Delete node(s) from 'keytable' matching name 'keyname'
205  *
206  * Requires:
207  *
208  *\li	'keytable' points to a valid keytable.
209  *
210  *\li	'name' is not NULL
211  *
212  * Returns:
213  *
214  *\li	ISC_R_SUCCESS
215  *
216  *\li	Any other result indicates failure.
217  */
218 
219 isc_result_t
220 dns_keytable_deletekeynode(dns_keytable_t *keytable, dst_key_t *dstkey);
221 /*%<
222  * Delete node(s) from 'keytable' containing copies of the key pointed
223  * to by 'dstkey'
224  *
225  * Requires:
226  *
227  *\li	'keytable' points to a valid keytable.
228  *\li	'dstkey' is not NULL
229  *
230  * Returns:
231  *
232  *\li	ISC_R_SUCCESS
233  *
234  *\li	Any other result indicates failure.
235  */
236 
237 isc_result_t
238 dns_keytable_find(dns_keytable_t *keytable, dns_name_t *keyname,
239 		  dns_keynode_t **keynodep);
240 /*%<
241  * Search for the first instance of a key named 'name' in 'keytable',
242  * without regard to keyid and algorithm.  Use dns_keytable_nextkeynode()
243  * to find subsequent instances.
244  *
245  * Requires:
246  *
247  *\li	'keytable' is a valid keytable.
248  *
249  *\li	'name' is a valid absolute name.
250  *
251  *\li	keynodep != NULL && *keynodep == NULL
252  *
253  * Returns:
254  *
255  *\li	ISC_R_SUCCESS
256  *\li	ISC_R_NOTFOUND
257  *
258  *\li	Any other result indicates an error.
259  */
260 
261 isc_result_t
262 dns_keytable_nextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
263 			 dns_keynode_t **nextnodep);
264 /*%<
265  * Return for the next key after 'keynode' in 'keytable', without regard to
266  * keyid and algorithm.
267  *
268  * Requires:
269  *
270  *\li	'keytable' is a valid keytable.
271  *
272  *\li	'keynode' is a valid keynode.
273  *
274  *\li	nextnodep != NULL && *nextnodep == NULL
275  *
276  * Returns:
277  *
278  *\li	ISC_R_SUCCESS
279  *\li	ISC_R_NOTFOUND
280  *
281  *\li	Any other result indicates an error.
282  */
283 
284 isc_result_t
285 dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name,
286 			 dns_secalg_t algorithm, dns_keytag_t tag,
287 			 dns_keynode_t **keynodep);
288 /*%<
289  * Search for a key named 'name', matching 'algorithm' and 'tag' in
290  * 'keytable'.  This finds the first instance which matches.  Use
291  * dns_keytable_findnextkeynode() to find other instances.
292  *
293  * Requires:
294  *
295  *\li	'keytable' is a valid keytable.
296  *
297  *\li	'name' is a valid absolute name.
298  *
299  *\li	keynodep != NULL && *keynodep == NULL
300  *
301  * Returns:
302  *
303  *\li	ISC_R_SUCCESS
304  *\li	DNS_R_PARTIALMATCH	the name existed in the keytable.
305  *\li	ISC_R_NOTFOUND
306  *
307  *\li	Any other result indicates an error.
308  */
309 
310 isc_result_t
311 dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
312 					     dns_keynode_t **nextnodep);
313 /*%<
314  * Search for the next key with the same properties as 'keynode' in
315  * 'keytable' as found by dns_keytable_findkeynode().
316  *
317  * Requires:
318  *
319  *\li	'keytable' is a valid keytable.
320  *
321  *\li	'keynode' is a valid keynode.
322  *
323  *\li	nextnodep != NULL && *nextnodep == NULL
324  *
325  * Returns:
326  *
327  *\li	ISC_R_SUCCESS
328  *\li	ISC_R_NOTFOUND
329  *
330  *\li	Any other result indicates an error.
331  */
332 
333 isc_result_t
334 dns_keytable_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name,
335 			      dns_name_t *foundname);
336 /*%<
337  * Search for the deepest match of 'name' in 'keytable'.
338  *
339  * Requires:
340  *
341  *\li	'keytable' is a valid keytable.
342  *
343  *\li	'name' is a valid absolute name.
344  *
345  *\li	'foundname' is a name with a dedicated buffer.
346  *
347  * Returns:
348  *
349  *\li	ISC_R_SUCCESS
350  *\li	ISC_R_NOTFOUND
351  *
352  *\li	Any other result indicates an error.
353  */
354 
355 void
356 dns_keytable_attachkeynode(dns_keytable_t *keytable, dns_keynode_t *source,
357 			   dns_keynode_t **target);
358 /*%<
359  * Attach a keynode and and increment the active_nodes counter in a
360  * corresponding keytable.
361  *
362  * Requires:
363  *
364  *\li	'keytable' is a valid keytable.
365  *
366  *\li	'source' is a valid keynode.
367  *
368  *\li	'target' is not null and '*target' is null.
369  */
370 
371 void
372 dns_keytable_detachkeynode(dns_keytable_t *keytable,
373 			   dns_keynode_t **keynodep);
374 /*%<
375  * Give back a keynode found via dns_keytable_findkeynode().
376  *
377  * Requires:
378  *
379  *\li	'keytable' is a valid keytable.
380  *
381  *\li	*keynodep is a valid keynode returned by a call to
382  *	dns_keytable_findkeynode().
383  *
384  * Ensures:
385  *
386  *\li	*keynodep == NULL
387  */
388 
389 isc_result_t
390 dns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name,
391 			    isc_boolean_t *wantdnssecp);
392 /*%<
393  * Is 'name' at or beneath a trusted key?
394  *
395  * Requires:
396  *
397  *\li	'keytable' is a valid keytable.
398  *
399  *\li	'name' is a valid absolute name.
400  *
401  *\li	'*wantsdnssecp' is a valid isc_boolean_t.
402  *
403  * Ensures:
404  *
405  *\li	On success, *wantsdnssecp will be ISC_TRUE if and only if 'name'
406  *	is at or beneath a trusted key.
407  *
408  * Returns:
409  *
410  *\li	ISC_R_SUCCESS
411  *
412  *\li	Any other result is an error.
413  */
414 
415 isc_result_t
416 dns_keytable_dump(dns_keytable_t *keytable, FILE *fp);
417 /*%<
418  * Dump the keytable on fp.
419  */
420 
421 dst_key_t *
422 dns_keynode_key(dns_keynode_t *keynode);
423 /*%<
424  * Get the DST key associated with keynode.
425  */
426 
427 isc_boolean_t
428 dns_keynode_managed(dns_keynode_t *keynode);
429 /*%<
430  * Is this flagged as a managed key?
431  */
432 
433 isc_result_t
434 dns_keynode_create(isc_mem_t *mctx, dns_keynode_t **target);
435 /*%<
436  * Allocate space for a keynode
437  */
438 
439 void
440 dns_keynode_attach(dns_keynode_t *source, dns_keynode_t **target);
441 /*%<
442  * Attach keynode 'source' to '*target'
443  */
444 
445 void
446 dns_keynode_detach(isc_mem_t *mctx, dns_keynode_t **target);
447 /*%<
448  * Detach a single keynode, without touching any keynodes that
449  * may be pointed to by its 'next' pointer
450  */
451 
452 void
453 dns_keynode_detachall(isc_mem_t *mctx, dns_keynode_t **target);
454 /*%<
455  * Detach a keynode and all its succesors.
456  */
457 ISC_LANG_ENDDECLS
458 
459 #endif /* DNS_KEYTABLE_H */
460