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