1/* $NetBSD: keytable.h,v 1.8 2024/02/21 22:52:10 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 52ISC_LANG_BEGINDECLS 53 54typedef void (*dns_keytable_callback_t)(const dns_name_t *name, void *fn_arg); 55 56isc_result_t 57dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep); 58/*%< 59 * Create a keytable. 60 * 61 * Requires: 62 * 63 *\li 'mctx' is a valid memory context. 64 * 65 *\li keytablep != NULL && *keytablep == NULL 66 * 67 * Ensures: 68 * 69 *\li On success, *keytablep is a valid, empty key table. 70 * 71 * Returns: 72 * 73 *\li ISC_R_SUCCESS 74 * 75 *\li Any other result indicates failure. 76 */ 77 78void 79dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp); 80/*%< 81 * Attach *targetp to source. 82 * 83 * Requires: 84 * 85 *\li 'source' is a valid keytable. 86 * 87 *\li 'targetp' points to a NULL dns_keytable_t *. 88 * 89 * Ensures: 90 * 91 *\li *targetp is attached to source. 92 */ 93 94void 95dns_keytable_detach(dns_keytable_t **keytablep); 96/*%< 97 * Detach *keytablep from its keytable. 98 * 99 * Requires: 100 * 101 *\li 'keytablep' points to a valid keytable. 102 * 103 * Ensures: 104 * 105 *\li *keytablep is NULL. 106 * 107 *\li If '*keytablep' is the last reference to the keytable, 108 * all resources used by the keytable will be freed 109 */ 110 111isc_result_t 112dns_keytable_add(dns_keytable_t *keytable, bool managed, bool initial, 113 dns_name_t *name, dns_rdata_ds_t *ds, 114 dns_keytable_callback_t callback, void *callback_arg); 115/*%< 116 * Add a key to 'keytable'. The keynode associated with 'name' 117 * is updated with the DS specified in 'ds'. 118 * 119 * The value of keynode->managed is set to 'managed', and the 120 * value of keynode->initial is set to 'initial'. (Note: 'initial' 121 * should only be used when adding managed-keys from configuration. 122 * This indicates the key is in "initializing" state, and has not yet 123 * been confirmed with a key refresh query. Once a key refresh query 124 * has validated, we update the keynode with initial == false.) 125 * 126 * Notes: 127 * 128 *\li If the key already exists in the table, adding it again 129 * has no effect and ISC_R_SUCCESS is returned. 130 * 131 * Requires: 132 * 133 *\li 'keytable' points to a valid keytable. 134 *\li 'ds' is not NULL. 135 *\li if 'initial' is true then 'managed' must also be true. 136 * 137 * Returns: 138 * 139 *\li ISC_R_SUCCESS 140 *\li ISC_R_EXISTS 141 * 142 *\li Any other result indicates failure. 143 */ 144 145isc_result_t 146dns_keytable_marksecure(dns_keytable_t *keytable, const dns_name_t *name); 147/*%< 148 * Add a null key to 'keytable' for name 'name'. This marks the 149 * name as a secure domain, but doesn't supply any key data to allow the 150 * domain to be validated. (Used when automated trust anchor management 151 * has gotten broken by a zone misconfiguration; for example, when the 152 * active key has been revoked but the stand-by key was still in its 30-day 153 * waiting period for validity.) 154 * 155 * Notes: 156 * 157 *\li If a key already exists in the table, ISC_R_EXISTS is 158 * returned and nothing is done. 159 * 160 * Requires: 161 * 162 *\li 'keytable' points to a valid keytable. 163 * 164 *\li keyp != NULL && *keyp is a valid dst_key_t *. 165 * 166 * Returns: 167 * 168 *\li ISC_R_SUCCESS 169 *\li ISC_R_EXISTS 170 * 171 *\li Any other result indicates failure. 172 */ 173 174isc_result_t 175dns_keytable_delete(dns_keytable_t *keytable, const dns_name_t *keyname, 176 dns_keytable_callback_t callback, void *callback_arg); 177/*%< 178 * Delete all trust anchors from 'keytable' matching name 'keyname' 179 * 180 * Requires: 181 * 182 *\li 'keytable' points to a valid keytable. 183 * 184 *\li 'name' is not NULL 185 * 186 * Returns: 187 * 188 *\li ISC_R_SUCCESS 189 * 190 *\li Any other result indicates failure. 191 */ 192 193isc_result_t 194dns_keytable_deletekey(dns_keytable_t *keytable, const dns_name_t *keyname, 195 dns_rdata_dnskey_t *dnskey); 196/*%< 197 * Remove the trust anchor matching the name 'keyname' and the DNSKEY 198 * rdata struct 'dnskey' from 'keytable'. 199 * 200 * Requires: 201 * 202 *\li 'keytable' points to a valid keytable. 203 *\li 'dnskey' is not NULL 204 * 205 * Returns: 206 * 207 *\li ISC_R_SUCCESS 208 * 209 *\li Any other result indicates failure. 210 */ 211 212isc_result_t 213dns_keytable_find(dns_keytable_t *keytable, const dns_name_t *keyname, 214 dns_keynode_t **keynodep); 215/*%< 216 * Search for the first instance of a trust anchor named 'name' in 217 * 'keytable', without regard to keyid and algorithm. 218 * 219 * Requires: 220 * 221 *\li 'keytable' is a valid keytable. 222 * 223 *\li 'name' is a valid absolute name. 224 * 225 *\li keynodep != NULL && *keynodep == NULL 226 * 227 * Returns: 228 * 229 *\li ISC_R_SUCCESS 230 *\li ISC_R_NOTFOUND 231 * 232 *\li Any other result indicates an error. 233 */ 234 235isc_result_t 236dns_keytable_finddeepestmatch(dns_keytable_t *keytable, const dns_name_t *name, 237 dns_name_t *foundname); 238/*%< 239 * Search for the deepest match of 'name' in 'keytable'. 240 * 241 * Requires: 242 * 243 *\li 'keytable' is a valid keytable. 244 * 245 *\li 'name' is a valid absolute name. 246 * 247 *\li 'foundname' is a name with a dedicated buffer. 248 * 249 * Returns: 250 * 251 *\li ISC_R_SUCCESS 252 *\li ISC_R_NOTFOUND 253 * 254 *\li Any other result indicates an error. 255 */ 256 257void 258dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep); 259/*%< 260 * Detach a keynode found via dns_keytable_find(). 261 * 262 * Requires: 263 * 264 *\li *keynodep is a valid keynode returned by a call to dns_keytable_find(). 265 * 266 * Ensures: 267 * 268 *\li *keynodep == NULL 269 */ 270 271isc_result_t 272dns_keytable_issecuredomain(dns_keytable_t *keytable, const dns_name_t *name, 273 dns_name_t *foundname, bool *wantdnssecp); 274/*%< 275 * Is 'name' at or beneath a trusted key? 276 * 277 * Requires: 278 * 279 *\li 'keytable' is a valid keytable. 280 * 281 *\li 'name' is a valid absolute name. 282 * 283 *\li 'foundanme' is NULL or is a pointer to an initialized dns_name_t 284 * 285 *\li '*wantsdnssecp' is a valid bool. 286 * 287 * Ensures: 288 * 289 *\li On success, *wantsdnssecp will be true if and only if 'name' 290 * is at or beneath a trusted key. If 'foundname' is not NULL, then 291 * it will be updated to contain the name of the closest enclosing 292 * trust anchor. 293 * 294 * Returns: 295 * 296 *\li ISC_R_SUCCESS 297 * 298 *\li Any other result is an error. 299 */ 300 301isc_result_t 302dns_keytable_dump(dns_keytable_t *keytable, FILE *fp); 303/*%< 304 * Dump the keytable on fp. 305 */ 306 307isc_result_t 308dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **buf); 309/*%< 310 * Dump the keytable to buffer at 'buf' 311 */ 312 313bool 314dns_keynode_dsset(dns_keynode_t *keynode, dns_rdataset_t *rdataset); 315/*%< 316 * Clone the DS RRset associated with 'keynode' into 'rdataset' if 317 * it exists. 'dns_rdataset_disassociate(rdataset)' needs to be 318 * called when done. 319 * 320 * Returns: 321 *\li true if there is a DS RRset. 322 *\li false if there isn't DS RRset. 323 * 324 * Requires: 325 *\li 'keynode' is valid. 326 *\li 'rdataset' is valid or NULL. 327 */ 328 329bool 330dns_keynode_managed(dns_keynode_t *keynode); 331/*%< 332 * Is this flagged as a managed key? 333 */ 334 335bool 336dns_keynode_initial(dns_keynode_t *keynode); 337/*%< 338 * Is this flagged as an initializing key? 339 */ 340 341void 342dns_keynode_trust(dns_keynode_t *keynode); 343/*%< 344 * Sets keynode->initial to false in order to mark the key as 345 * trusted: no longer an initializing key. 346 */ 347 348isc_result_t 349dns_keytable_forall(dns_keytable_t *keytable, 350 void (*func)(dns_keytable_t *, dns_keynode_t *, 351 dns_name_t *, void *), 352 void *arg); 353ISC_LANG_ENDDECLS 354