1 /* $NetBSD: keytable.h,v 1.9 2025/01/26 16:25:27 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 #pragma once 17 18 /***** 19 ***** Module Info 20 *****/ 21 22 /*! \file 23 * \brief 24 * The keytable module provides services for storing and retrieving DNSSEC 25 * trusted keys, as well as the ability to find the deepest matching key 26 * for a given domain name. 27 * 28 * MP: 29 *\li The module ensures appropriate synchronization of data structures it 30 * creates and manipulates. 31 * 32 * Resources: 33 *\li TBS 34 * 35 * Security: 36 *\li No anticipated impact. 37 */ 38 39 #include <stdbool.h> 40 41 #include <isc/lang.h> 42 #include <isc/magic.h> 43 #include <isc/refcount.h> 44 #include <isc/rwlock.h> 45 #include <isc/stdtime.h> 46 47 #include <dns/rdatastruct.h> 48 #include <dns/types.h> 49 50 #include <dst/dst.h> 51 52 ISC_LANG_BEGINDECLS 53 54 typedef void (*dns_keytable_callback_t)(const dns_name_t *name, void *fn_arg); 55 56 void 57 dns_keytable_create(dns_view_t *view, dns_keytable_t **keytablep); 58 /*%< 59 * Create a keytable. 60 * 61 * Requires: 62 * 63 *\li 'view' is a valid memory context. 64 *\li keytablep != NULL && *keytablep == NULL 65 */ 66 67 isc_result_t 68 dns_keytable_add(dns_keytable_t *keytable, bool managed, bool initial, 69 dns_name_t *name, dns_rdata_ds_t *ds, 70 dns_keytable_callback_t callback, void *callback_arg); 71 /*%< 72 * Add a key to 'keytable'. The keynode associated with 'name' 73 * is updated with the DS specified in 'ds'. 74 * 75 * The value of keynode->managed is set to 'managed', and the 76 * value of keynode->initial is set to 'initial'. (Note: 'initial' 77 * should only be used when adding managed-keys from configuration. 78 * This indicates the key is in "initializing" state, and has not yet 79 * been confirmed with a key refresh query. Once a key refresh query 80 * has validated, we update the keynode with initial == false.) 81 * 82 * Notes: 83 * 84 *\li If the key already exists in the table, adding it again 85 * has no effect and ISC_R_SUCCESS is returned. 86 * 87 * Requires: 88 * 89 *\li 'keytable' points to a valid keytable. 90 *\li 'ds' is not NULL. 91 *\li if 'initial' is true then 'managed' must also be true. 92 * 93 * Returns: 94 * 95 *\li ISC_R_SUCCESS 96 *\li ISC_R_EXISTS 97 * 98 *\li Any other result indicates failure. 99 */ 100 101 isc_result_t 102 dns_keytable_marksecure(dns_keytable_t *keytable, const dns_name_t *name); 103 /*%< 104 * Add a null key to 'keytable' for name 'name'. This marks the 105 * name as a secure domain, but doesn't supply any key data to allow the 106 * domain to be validated. (Used when automated trust anchor management 107 * has gotten broken by a zone misconfiguration; for example, when the 108 * active key has been revoked but the stand-by key was still in its 30-day 109 * waiting period for validity.) 110 * 111 * Notes: 112 * 113 *\li If a key already exists in the table, ISC_R_EXISTS is 114 * returned and nothing is done. 115 * 116 * Requires: 117 * 118 *\li 'keytable' points to a valid keytable. 119 * 120 *\li keyp != NULL && *keyp is a valid dst_key_t *. 121 * 122 * Returns: 123 * 124 *\li ISC_R_SUCCESS 125 *\li ISC_R_EXISTS 126 * 127 *\li Any other result indicates failure. 128 */ 129 130 isc_result_t 131 dns_keytable_delete(dns_keytable_t *keytable, const dns_name_t *keyname, 132 dns_keytable_callback_t callback, void *callback_arg); 133 /*%< 134 * Delete all trust anchors from 'keytable' matching name 'keyname' 135 * 136 * Requires: 137 * 138 *\li 'keytable' points to a valid keytable. 139 * 140 *\li 'name' is not NULL 141 * 142 * Returns: 143 * 144 *\li ISC_R_SUCCESS 145 * 146 *\li Any other result indicates failure. 147 */ 148 149 isc_result_t 150 dns_keytable_deletekey(dns_keytable_t *keytable, const dns_name_t *keyname, 151 dns_rdata_dnskey_t *dnskey); 152 /*%< 153 * Remove the trust anchor matching the name 'keyname' and the DNSKEY 154 * rdata struct 'dnskey' from 'keytable'. 155 * 156 * Requires: 157 * 158 *\li 'keytable' points to a valid keytable. 159 *\li 'dnskey' is not NULL 160 * 161 * Returns: 162 * 163 *\li ISC_R_SUCCESS 164 * 165 *\li Any other result indicates failure. 166 */ 167 168 isc_result_t 169 dns_keytable_find(dns_keytable_t *keytable, const dns_name_t *keyname, 170 dns_keynode_t **keynodep); 171 /*%< 172 * Search for the first instance of a trust anchor named 'name' in 173 * 'keytable', without regard to keyid and algorithm. 174 * 175 * Requires: 176 * 177 *\li 'keytable' is a valid keytable. 178 * 179 *\li 'name' is a valid absolute name. 180 * 181 *\li keynodep != NULL && *keynodep == NULL 182 * 183 * Returns: 184 * 185 *\li ISC_R_SUCCESS 186 *\li ISC_R_NOTFOUND 187 * 188 *\li Any other result indicates an error. 189 */ 190 191 isc_result_t 192 dns_keytable_finddeepestmatch(dns_keytable_t *keytable, const dns_name_t *name, 193 dns_name_t *foundname); 194 /*%< 195 * Search for the deepest match of 'name' in 'keytable'. 196 * 197 * Requires: 198 * 199 *\li 'keytable' is a valid keytable. 200 * 201 *\li 'name' is a valid absolute name. 202 * 203 *\li 'foundname' is a name with a dedicated buffer. 204 * 205 * Returns: 206 * 207 *\li ISC_R_SUCCESS 208 *\li ISC_R_NOTFOUND 209 * 210 *\li Any other result indicates an error. 211 */ 212 213 isc_result_t 214 dns_keytable_issecuredomain(dns_keytable_t *keytable, const dns_name_t *name, 215 dns_name_t *foundname, bool *wantdnssecp); 216 /*%< 217 * Is 'name' at or beneath a trusted key? 218 * 219 * Requires: 220 * 221 *\li 'keytable' is a valid keytable. 222 * 223 *\li 'name' is a valid absolute name. 224 * 225 *\li 'foundanme' is NULL or is a pointer to an initialized dns_name_t 226 * 227 *\li '*wantsdnssecp' is a valid bool. 228 * 229 * Ensures: 230 * 231 *\li On success, *wantsdnssecp will be true if and only if 'name' 232 * is at or beneath a trusted key. If 'foundname' is not NULL, then 233 * it will be updated to contain the name of the closest enclosing 234 * trust anchor. 235 * 236 * Returns: 237 * 238 *\li ISC_R_SUCCESS 239 * 240 *\li Any other result is an error. 241 */ 242 243 isc_result_t 244 dns_keytable_dump(dns_keytable_t *keytable, FILE *fp); 245 /*%< 246 * Dump the keytable on fp. 247 */ 248 249 isc_result_t 250 dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **buf); 251 /*%< 252 * Dump the keytable to buffer at 'buf' 253 */ 254 255 bool 256 dns_keynode_dsset(dns_keynode_t *keynode, dns_rdataset_t *rdataset); 257 /*%< 258 * Clone the DS RRset associated with 'keynode' into 'rdataset' if 259 * it exists. 'dns_rdataset_disassociate(rdataset)' needs to be 260 * called when done. 261 * 262 * Returns: 263 *\li true if there is a DS RRset. 264 *\li false if there isn't DS RRset. 265 * 266 * Requires: 267 *\li 'keynode' is valid. 268 *\li 'rdataset' is valid or NULL. 269 */ 270 271 bool 272 dns_keynode_managed(dns_keynode_t *keynode); 273 /*%< 274 * Is this flagged as a managed key? 275 */ 276 277 bool 278 dns_keynode_initial(dns_keynode_t *keynode); 279 /*%< 280 * Is this flagged as an initializing key? 281 */ 282 283 void 284 dns_keynode_trust(dns_keynode_t *keynode); 285 /*%< 286 * Sets keynode->initial to false in order to mark the key as 287 * trusted: no longer an initializing key. 288 */ 289 290 void 291 dns_keytable_forall(dns_keytable_t *keytable, 292 void (*func)(dns_keytable_t *, dns_keynode_t *, 293 dns_name_t *, void *), 294 void *arg); 295 /*%< 296 * Call 'func' on each keynode in 'keytable'. 297 */ 298 299 ISC_REFCOUNT_DECL(dns_keytable); 300 ISC_REFCOUNT_DECL(dns_keynode); 301 ISC_LANG_ENDDECLS 302