1/* $NetBSD: keytable.h,v 1.2.6.1 2012/06/05 21:14:55 bouyer 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 56ISC_LANG_BEGINDECLS 57 58struct 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 74struct 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 85isc_result_t 86dns_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 108void 109dns_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 124void 125dns_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 141isc_result_t 142dns_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 172isc_result_t 173dns_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 201isc_result_t 202dns_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 219isc_result_t 220dns_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 237isc_result_t 238dns_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 261isc_result_t 262dns_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 284isc_result_t 285dns_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 310isc_result_t 311dns_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 333isc_result_t 334dns_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 355void 356dns_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 371void 372dns_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 389isc_result_t 390dns_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 415isc_result_t 416dns_keytable_dump(dns_keytable_t *keytable, FILE *fp); 417/*%< 418 * Dump the keytable on fp. 419 */ 420 421dst_key_t * 422dns_keynode_key(dns_keynode_t *keynode); 423/*%< 424 * Get the DST key associated with keynode. 425 */ 426 427isc_boolean_t 428dns_keynode_managed(dns_keynode_t *keynode); 429/*%< 430 * Is this flagged as a managed key? 431 */ 432 433isc_result_t 434dns_keynode_create(isc_mem_t *mctx, dns_keynode_t **target); 435/*%< 436 * Allocate space for a keynode 437 */ 438 439void 440dns_keynode_attach(dns_keynode_t *source, dns_keynode_t **target); 441/*%< 442 * Attach keynode 'source' to '*target' 443 */ 444 445void 446dns_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 452void 453dns_keynode_detachall(isc_mem_t *mctx, dns_keynode_t **target); 454/*%< 455 * Detach a keynode and all its succesors. 456 */ 457ISC_LANG_ENDDECLS 458 459#endif /* DNS_KEYTABLE_H */ 460