00001 /* 00002 * Copyright (C) 2004, 2005, 2007, 2009, 2010, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") 00003 * Copyright (C) 2000, 2001 Internet Software Consortium. 00004 * 00005 * Permission to use, copy, modify, and/or distribute this software for any 00006 * purpose with or without fee is hereby granted, provided that the above 00007 * copyright notice and this permission notice appear in all copies. 00008 * 00009 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 00010 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 00011 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 00012 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 00013 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 00014 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00015 * PERFORMANCE OF THIS SOFTWARE. 00016 */ 00017 00018 /* $Id: keytable.h,v 1.23 2010/06/25 03:24:05 marka Exp $ */ 00019 00020 #ifndef DNS_KEYTABLE_H 00021 #define DNS_KEYTABLE_H 1 00022 00023 /***** 00024 ***** Module Info 00025 *****/ 00026 00027 /*! \file 00028 * \brief 00029 * The keytable module provides services for storing and retrieving DNSSEC 00030 * trusted keys, as well as the ability to find the deepest matching key 00031 * for a given domain name. 00032 * 00033 * MP: 00034 *\li The module ensures appropriate synchronization of data structures it 00035 * creates and manipulates. 00036 * 00037 * Resources: 00038 *\li TBS 00039 * 00040 * Security: 00041 *\li No anticipated impact. 00042 */ 00043 00044 #include <isc/lang.h> 00045 #include <isc/magic.h> 00046 #include <isc/refcount.h> 00047 #include <isc/rwlock.h> 00048 #include <isc/stdtime.h> 00049 00050 #include <dns/types.h> 00051 00052 #include <dst/dst.h> 00053 00054 ISC_LANG_BEGINDECLS 00055 00056 struct dns_keytable { 00057 /* Unlocked. */ 00058 unsigned int magic; 00059 isc_mem_t *mctx; 00060 isc_mutex_t lock; 00061 isc_rwlock_t rwlock; 00062 /* Locked by lock. */ 00063 isc_uint32_t active_nodes; 00064 /* Locked by rwlock. */ 00065 isc_uint32_t references; 00066 dns_rbt_t *table; 00067 }; 00068 00069 #define KEYTABLE_MAGIC ISC_MAGIC('K', 'T', 'b', 'l') 00070 #define VALID_KEYTABLE(kt) ISC_MAGIC_VALID(kt, KEYTABLE_MAGIC) 00071 00072 struct dns_keynode { 00073 unsigned int magic; 00074 isc_refcount_t refcount; 00075 dst_key_t * key; 00076 isc_boolean_t managed; 00077 struct dns_keynode * next; 00078 }; 00079 00080 #define KEYNODE_MAGIC ISC_MAGIC('K', 'N', 'o', 'd') 00081 #define VALID_KEYNODE(kn) ISC_MAGIC_VALID(kn, KEYNODE_MAGIC) 00082 00083 isc_result_t 00084 dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep); 00085 /*%< 00086 * Create a keytable. 00087 * 00088 * Requires: 00089 * 00090 *\li 'mctx' is a valid memory context. 00091 * 00092 *\li keytablep != NULL && *keytablep == NULL 00093 * 00094 * Ensures: 00095 * 00096 *\li On success, *keytablep is a valid, empty key table. 00097 * 00098 * Returns: 00099 * 00100 *\li ISC_R_SUCCESS 00101 * 00102 *\li Any other result indicates failure. 00103 */ 00104 00105 00106 void 00107 dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp); 00108 /*%< 00109 * Attach *targetp to source. 00110 * 00111 * Requires: 00112 * 00113 *\li 'source' is a valid keytable. 00114 * 00115 *\li 'targetp' points to a NULL dns_keytable_t *. 00116 * 00117 * Ensures: 00118 * 00119 *\li *targetp is attached to source. 00120 */ 00121 00122 void 00123 dns_keytable_detach(dns_keytable_t **keytablep); 00124 /*%< 00125 * Detach *keytablep from its keytable. 00126 * 00127 * Requires: 00128 * 00129 *\li 'keytablep' points to a valid keytable. 00130 * 00131 * Ensures: 00132 * 00133 *\li *keytablep is NULL. 00134 * 00135 *\li If '*keytablep' is the last reference to the keytable, 00136 * all resources used by the keytable will be freed 00137 */ 00138 00139 isc_result_t 00140 dns_keytable_add(dns_keytable_t *keytable, isc_boolean_t managed, 00141 dst_key_t **keyp); 00142 /*%< 00143 * Add '*keyp' to 'keytable' (using the name in '*keyp'). 00144 * The value of keynode->managed is set to 'managed' 00145 * 00146 * Notes: 00147 * 00148 *\li Ownership of *keyp is transferred to the keytable. 00149 *\li If the key already exists in the table, ISC_R_EXISTS is 00150 * returned and the new key is freed. 00151 * 00152 * Requires: 00153 * 00154 *\li 'keytable' points to a valid keytable. 00155 * 00156 *\li keyp != NULL && *keyp is a valid dst_key_t *. 00157 * 00158 * Ensures: 00159 * 00160 *\li On success, *keyp == NULL 00161 * 00162 * Returns: 00163 * 00164 *\li ISC_R_SUCCESS 00165 *\li ISC_R_EXISTS 00166 * 00167 *\li Any other result indicates failure. 00168 */ 00169 00170 isc_result_t 00171 dns_keytable_marksecure(dns_keytable_t *keytable, dns_name_t *name); 00172 /*%< 00173 * Add a null key to 'keytable' for name 'name'. This marks the 00174 * name as a secure domain, but doesn't supply any key data to allow the 00175 * domain to be validated. (Used when automated trust anchor management 00176 * has gotten broken by a zone misconfiguration; for example, when the 00177 * active key has been revoked but the stand-by key was still in its 30-day 00178 * waiting period for validity.) 00179 * 00180 * Notes: 00181 * 00182 *\li If a key already exists in the table, ISC_R_EXISTS is 00183 * returned and nothing is done. 00184 * 00185 * Requires: 00186 * 00187 *\li 'keytable' points to a valid keytable. 00188 * 00189 *\li keyp != NULL && *keyp is a valid dst_key_t *. 00190 * 00191 * Returns: 00192 * 00193 *\li ISC_R_SUCCESS 00194 *\li ISC_R_EXISTS 00195 * 00196 *\li Any other result indicates failure. 00197 */ 00198 00199 isc_result_t 00200 dns_keytable_delete(dns_keytable_t *keytable, dns_name_t *keyname); 00201 /*%< 00202 * Delete node(s) from 'keytable' matching name 'keyname' 00203 * 00204 * Requires: 00205 * 00206 *\li 'keytable' points to a valid keytable. 00207 * 00208 *\li 'name' is not NULL 00209 * 00210 * Returns: 00211 * 00212 *\li ISC_R_SUCCESS 00213 * 00214 *\li Any other result indicates failure. 00215 */ 00216 00217 isc_result_t 00218 dns_keytable_deletekeynode(dns_keytable_t *keytable, dst_key_t *dstkey); 00219 /*%< 00220 * Delete node(s) from 'keytable' containing copies of the key pointed 00221 * to by 'dstkey' 00222 * 00223 * Requires: 00224 * 00225 *\li 'keytable' points to a valid keytable. 00226 *\li 'dstkey' is not NULL 00227 * 00228 * Returns: 00229 * 00230 *\li ISC_R_SUCCESS 00231 * 00232 *\li Any other result indicates failure. 00233 */ 00234 00235 isc_result_t 00236 dns_keytable_find(dns_keytable_t *keytable, dns_name_t *keyname, 00237 dns_keynode_t **keynodep); 00238 /*%< 00239 * Search for the first instance of a key named 'name' in 'keytable', 00240 * without regard to keyid and algorithm. Use dns_keytable_nextkeynode() 00241 * to find subsequent instances. 00242 * 00243 * Requires: 00244 * 00245 *\li 'keytable' is a valid keytable. 00246 * 00247 *\li 'name' is a valid absolute name. 00248 * 00249 *\li keynodep != NULL && *keynodep == NULL 00250 * 00251 * Returns: 00252 * 00253 *\li ISC_R_SUCCESS 00254 *\li ISC_R_NOTFOUND 00255 * 00256 *\li Any other result indicates an error. 00257 */ 00258 00259 isc_result_t 00260 dns_keytable_nextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode, 00261 dns_keynode_t **nextnodep); 00262 /*%< 00263 * Return for the next key after 'keynode' in 'keytable', without regard to 00264 * keyid and algorithm. 00265 * 00266 * Requires: 00267 * 00268 *\li 'keytable' is a valid keytable. 00269 * 00270 *\li 'keynode' is a valid keynode. 00271 * 00272 *\li nextnodep != NULL && *nextnodep == NULL 00273 * 00274 * Returns: 00275 * 00276 *\li ISC_R_SUCCESS 00277 *\li ISC_R_NOTFOUND 00278 * 00279 *\li Any other result indicates an error. 00280 */ 00281 00282 isc_result_t 00283 dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name, 00284 dns_secalg_t algorithm, dns_keytag_t tag, 00285 dns_keynode_t **keynodep); 00286 /*%< 00287 * Search for a key named 'name', matching 'algorithm' and 'tag' in 00288 * 'keytable'. This finds the first instance which matches. Use 00289 * dns_keytable_findnextkeynode() to find other instances. 00290 * 00291 * Requires: 00292 * 00293 *\li 'keytable' is a valid keytable. 00294 * 00295 *\li 'name' is a valid absolute name. 00296 * 00297 *\li keynodep != NULL && *keynodep == NULL 00298 * 00299 * Returns: 00300 * 00301 *\li ISC_R_SUCCESS 00302 *\li DNS_R_PARTIALMATCH the name existed in the keytable. 00303 *\li ISC_R_NOTFOUND 00304 * 00305 *\li Any other result indicates an error. 00306 */ 00307 00308 isc_result_t 00309 dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode, 00310 dns_keynode_t **nextnodep); 00311 /*%< 00312 * Search for the next key with the same properties as 'keynode' in 00313 * 'keytable' as found by dns_keytable_findkeynode(). 00314 * 00315 * Requires: 00316 * 00317 *\li 'keytable' is a valid keytable. 00318 * 00319 *\li 'keynode' is a valid keynode. 00320 * 00321 *\li nextnodep != NULL && *nextnodep == NULL 00322 * 00323 * Returns: 00324 * 00325 *\li ISC_R_SUCCESS 00326 *\li ISC_R_NOTFOUND 00327 * 00328 *\li Any other result indicates an error. 00329 */ 00330 00331 isc_result_t 00332 dns_keytable_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name, 00333 dns_name_t *foundname); 00334 /*%< 00335 * Search for the deepest match of 'name' in 'keytable'. 00336 * 00337 * Requires: 00338 * 00339 *\li 'keytable' is a valid keytable. 00340 * 00341 *\li 'name' is a valid absolute name. 00342 * 00343 *\li 'foundname' is a name with a dedicated buffer. 00344 * 00345 * Returns: 00346 * 00347 *\li ISC_R_SUCCESS 00348 *\li ISC_R_NOTFOUND 00349 * 00350 *\li Any other result indicates an error. 00351 */ 00352 00353 void 00354 dns_keytable_attachkeynode(dns_keytable_t *keytable, dns_keynode_t *source, 00355 dns_keynode_t **target); 00356 /*%< 00357 * Attach a keynode and and increment the active_nodes counter in a 00358 * corresponding keytable. 00359 * 00360 * Requires: 00361 * 00362 *\li 'keytable' is a valid keytable. 00363 * 00364 *\li 'source' is a valid keynode. 00365 * 00366 *\li 'target' is not null and '*target' is null. 00367 */ 00368 00369 void 00370 dns_keytable_detachkeynode(dns_keytable_t *keytable, 00371 dns_keynode_t **keynodep); 00372 /*%< 00373 * Give back a keynode found via dns_keytable_findkeynode(). 00374 * 00375 * Requires: 00376 * 00377 *\li 'keytable' is a valid keytable. 00378 * 00379 *\li *keynodep is a valid keynode returned by a call to 00380 * dns_keytable_findkeynode(). 00381 * 00382 * Ensures: 00383 * 00384 *\li *keynodep == NULL 00385 */ 00386 00387 isc_result_t 00388 dns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name, 00389 dns_name_t *foundname, isc_boolean_t *wantdnssecp); 00390 /*%< 00391 * Is 'name' at or beneath a trusted key? 00392 * 00393 * Requires: 00394 * 00395 *\li 'keytable' is a valid keytable. 00396 * 00397 *\li 'name' is a valid absolute name. 00398 * 00399 *\li 'foundanme' is NULL or is a pointer to an initialized dns_name_t 00400 * 00401 *\li '*wantsdnssecp' is a valid isc_boolean_t. 00402 00403 * Ensures: 00404 * 00405 *\li On success, *wantsdnssecp will be ISC_TRUE if and only if 'name' 00406 * is at or beneath a trusted key. If 'foundname' is not NULL, then 00407 * it will be updated to contain the name of the closest enclosing 00408 * trust anchor. 00409 * 00410 * Returns: 00411 * 00412 *\li ISC_R_SUCCESS 00413 * 00414 *\li Any other result is an error. 00415 */ 00416 00417 isc_result_t 00418 dns_keytable_dump(dns_keytable_t *keytable, FILE *fp); 00419 /*%< 00420 * Dump the keytable on fp. 00421 */ 00422 00423 isc_result_t 00424 dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **buf); 00425 /*%< 00426 * Dump the keytable to buffer at 'buf' 00427 */ 00428 00429 dst_key_t * 00430 dns_keynode_key(dns_keynode_t *keynode); 00431 /*%< 00432 * Get the DST key associated with keynode. 00433 */ 00434 00435 isc_boolean_t 00436 dns_keynode_managed(dns_keynode_t *keynode); 00437 /*%< 00438 * Is this flagged as a managed key? 00439 */ 00440 00441 isc_result_t 00442 dns_keynode_create(isc_mem_t *mctx, dns_keynode_t **target); 00443 /*%< 00444 * Allocate space for a keynode 00445 */ 00446 00447 void 00448 dns_keynode_attach(dns_keynode_t *source, dns_keynode_t **target); 00449 /*%< 00450 * Attach keynode 'source' to '*target' 00451 */ 00452 00453 void 00454 dns_keynode_detach(isc_mem_t *mctx, dns_keynode_t **target); 00455 /*%< 00456 * Detach a single keynode, without touching any keynodes that 00457 * may be pointed to by its 'next' pointer 00458 */ 00459 00460 void 00461 dns_keynode_detachall(isc_mem_t *mctx, dns_keynode_t **target); 00462 /*%< 00463 * Detach a keynode and all its succesors. 00464 */ 00465 ISC_LANG_ENDDECLS 00466 00467 #endif /* DNS_KEYTABLE_H */