1 /* $NetBSD: validator.h,v 1.14 2026/04/08 00:16:14 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 dns/validator.h 23 * 24 * \brief 25 * DNS Validator 26 * This is the BIND 9 validator, the module responsible for validating the 27 * rdatasets and negative responses (messages). It makes use of zones in 28 * the view and may fetch RRset to complete trust chains. It implements 29 * DNSSEC as specified in RFC 4033, 4034 and 4035. 30 * 31 * Correct operation is critical to preventing spoofed answers from secure 32 * zones being accepted. 33 * 34 * MP: 35 *\li The module ensures appropriate synchronization of data structures it 36 * creates and manipulates. 37 * 38 * Reliability: 39 *\li No anticipated impact. 40 * 41 * Resources: 42 *\li TBS 43 * 44 * Security: 45 *\li No anticipated impact. 46 * 47 * Standards: 48 *\li RFCs: 1034, 1035, 2181, 4033, 4034, 4035. 49 */ 50 51 #include <stdbool.h> 52 53 #include <isc/job.h> 54 #include <isc/lang.h> 55 #include <isc/refcount.h> 56 57 #include <dns/fixedname.h> 58 #include <dns/rdata.h> 59 #include <dns/rdataset.h> 60 #include <dns/rdatastruct.h> /* for dns_rdata_rrsig_t */ 61 #include <dns/resolver.h> 62 #include <dns/types.h> 63 64 #include <dst/dst.h> 65 66 #define DNS_VALIDATOR_NOQNAMEPROOF 0 67 #define DNS_VALIDATOR_NODATAPROOF 1 68 #define DNS_VALIDATOR_NOWILDCARDPROOF 2 69 #define DNS_VALIDATOR_CLOSESTENCLOSER 3 70 71 /*% 72 * A validator object represents a validation in progress. 73 * \brief 74 * Clients are strongly discouraged from using this type directly, with 75 * the exception of the 'link' field, which may be used directly for 76 * whatever purpose the client desires. 77 */ 78 struct dns_validator { 79 unsigned int magic; 80 dns_view_t *view; 81 isc_loop_t *loop; 82 uint32_t tid; 83 isc_refcount_t references; 84 85 /* Name and type of the response to be validated. */ 86 dns_name_t *name; 87 dns_rdatatype_t type; 88 89 /* 90 * Callback and argument to use to inform the caller 91 * that validation is complete. 92 */ 93 isc_job_cb cb; 94 void *arg; 95 96 /* Validation options (_DEFER, _NONTA, etc). */ 97 unsigned int options; 98 99 /* 100 * Results of a completed validation. 101 */ 102 isc_result_t result; 103 104 /* 105 * Rdata and RRSIG (if any) for positive responses. 106 */ 107 dns_rdataset_t *rdataset; 108 dns_rdataset_t *sigrdataset; 109 /* 110 * The full response. Required for negative responses. 111 * Also required for positive wildcard responses. 112 */ 113 dns_message_t *message; 114 /* 115 * Proofs to be cached. 116 */ 117 dns_name_t *proofs[4]; 118 /* 119 * Optout proof seen. 120 */ 121 bool optout; 122 /* 123 * Answer is secure. 124 */ 125 bool secure; 126 127 /* Internal validator state */ 128 atomic_bool canceling; 129 unsigned int attributes; 130 dns_fetch_t *fetch; 131 dns_validator_t *subvalidator; 132 dns_validator_t *parent; 133 dns_keytable_t *keytable; 134 dst_key_t *key; 135 dns_rdata_rrsig_t *siginfo; 136 unsigned int labels; 137 dns_rdataset_t *nxset; 138 dns_rdataset_t *keyset; 139 dns_rdataset_t *dsset; 140 dns_rdataset_t fdsset; 141 dns_rdataset_t frdataset; 142 dns_rdataset_t fsigrdataset; 143 dns_fixedname_t fname; 144 dns_fixedname_t wild; 145 dns_fixedname_t closest; 146 ISC_LINK(dns_validator_t) link; 147 bool mustbesecure; 148 unsigned int depth; 149 unsigned int authcount; 150 unsigned int authfail; 151 isc_stdtime_t start; 152 153 bool digest_sha1; 154 uint8_t unsupported_algorithm; 155 uint8_t unsupported_digest; 156 uint8_t validation_attempts; 157 dns_rdata_t rdata; 158 bool resume; 159 isc_counter_t *nvalidations; 160 isc_counter_t *nfails; 161 isc_counter_t *qc; 162 isc_counter_t *gqc; 163 fetchctx_t *parent_fetch; 164 165 dns_edectx_t edectx; 166 167 dns_edectx_t *cb_edectx; 168 }; 169 170 /*% 171 * dns_validator_create() options. 172 */ 173 /* obsolete: #define DNS_VALIDATOR_DLV 0x0001U */ 174 #define DNS_VALIDATOR_DEFER 0x0002U 175 #define DNS_VALIDATOR_NOCDFLAG 0x0004U 176 #define DNS_VALIDATOR_NONTA 0x0008U /*% Ignore NTA table */ 177 178 ISC_LANG_BEGINDECLS 179 180 isc_result_t 181 dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, 182 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, 183 dns_message_t *message, unsigned int options, 184 isc_loop_t *loop, isc_job_cb cb, void *arg, 185 isc_counter_t *nvalidations, isc_counter_t *nfails, 186 isc_counter_t *qc, isc_counter_t *gqc, fetchctx_t *parent, 187 dns_edectx_t *edectx, dns_validator_t **validatorp); 188 /*%< 189 * Start a DNSSEC validation. 190 * 191 * On success (which is guaranteed as long as the view has valid 192 * trust anchors), `validatorp` is updated to point to the new 193 * validator. The caller is responsible for detaching it. 194 * 195 * The validator will validate a response to the question given by 196 * 'name' and 'type'. 197 * 198 * To validate a positive response, the response data is 199 * given by 'rdataset' and 'sigrdataset'. If 'sigrdataset' 200 * is NULL, the data is presumed insecure and an attempt 201 * is made to prove its insecurity by finding the appropriate 202 * null key. 203 * 204 * The complete response message may be given in 'message', 205 * to make available any authority section NSECs that may be 206 * needed for validation of a response resulting from a 207 * wildcard expansion (though no such wildcard validation 208 * is implemented yet). If the complete response message 209 * is not available, 'message' is NULL. 210 * 211 * To validate a negative response, the complete negative response 212 * message is given in 'message'. The 'rdataset', and 213 * 'sigrdataset' arguments must be NULL, but the 'name' and 'type' 214 * arguments must be provided. 215 * 216 * The validation is performed in the context of 'view'. 217 * 218 * When the validation finishes, the callback function 'cb' is 219 * called, passing a dns_valstatus_t object which contains a 220 * poiner to 'arg'. The caller is responsible for freeing this 221 * object. 222 * 223 * Its 'result' field will be ISC_R_SUCCESS iff the 224 * response was successfully proven to be either secure or 225 * part of a known insecure domain. 226 */ 227 228 void 229 dns_validator_send(dns_validator_t *validator); 230 /*%< 231 * Send a deferred validation request 232 * 233 * Requires: 234 * 'validator' to points to a valid DNSSEC validator. 235 */ 236 237 void 238 dns_validator_cancel(dns_validator_t *validator); 239 /*%< 240 * Cancel a DNSSEC validation in progress. 241 * 242 * Requires: 243 *\li 'validator' points to a valid DNSSEC validator, which 244 * may or may not already have completed. 245 * 246 * Ensures: 247 *\li It the validator has not already sent its completion 248 * event, it will send it with result code ISC_R_CANCELED. 249 */ 250 251 void 252 dns_validator_shutdown(dns_validator_t *val); 253 /*%< 254 * Release the name associated with the DNSSEC validator. 255 * 256 * Requires: 257 * \li 'val' points to a valid DNSSEC validator. 258 * \li The validator must have completed and sent its completion 259 * event. 260 * 261 * Ensures: 262 *\li The name associated with the DNSSEC validator is released. 263 */ 264 265 #if DNS_VALIDATOR_TRACE 266 #define dns_validator_ref(ptr) \ 267 dns_validator__ref(ptr, __func__, __FILE__, __LINE__) 268 #define dns_validator_unref(ptr) \ 269 dns_validator__unref(ptr, __func__, __FILE__, __LINE__) 270 #define dns_validator_attach(ptr, ptrp) \ 271 dns_validator__attach(ptr, ptrp, __func__, __FILE__, __LINE__) 272 #define dns_validator_detach(ptrp) \ 273 dns_validator__detach(ptrp, __func__, __FILE__, __LINE__) 274 ISC_REFCOUNT_TRACE_DECL(dns_validator); 275 #else 276 ISC_REFCOUNT_DECL(dns_validator); 277 #endif 278 279 ISC_LANG_ENDDECLS 280