Home | History | Annotate | Line # | Download | only in dns
      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