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