1 /*	$NetBSD: validator.h,v 1.7 2022/09/23 12:15:30 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 #ifndef DNS_VALIDATOR_H
17 #define DNS_VALIDATOR_H 1
18 
19 /*****
20 ***** Module Info
21 *****/
22 
23 /*! \file dns/validator.h
24  *
25  * \brief
26  * DNS Validator
27  * This is the BIND 9 validator, the module responsible for validating the
28  * rdatasets and negative responses (messages).  It makes use of zones in
29  * the view and may fetch RRset to complete trust chains.  It implements
30  * DNSSEC as specified in RFC 4033, 4034 and 4035.
31  *
32  * Correct operation is critical to preventing spoofed answers from secure
33  * zones being accepted.
34  *
35  * MP:
36  *\li	The module ensures appropriate synchronization of data structures it
37  *	creates and manipulates.
38  *
39  * Reliability:
40  *\li	No anticipated impact.
41  *
42  * Resources:
43  *\li	TBS
44  *
45  * Security:
46  *\li	No anticipated impact.
47  *
48  * Standards:
49  *\li	RFCs:	1034, 1035, 2181, 4033, 4034, 4035.
50  */
51 
52 #include <stdbool.h>
53 
54 #include <isc/event.h>
55 #include <isc/lang.h>
56 #include <isc/mutex.h>
57 
58 #include <dns/fixedname.h>
59 #include <dns/rdataset.h>
60 #include <dns/rdatastruct.h> /* for dns_rdata_rrsig_t */
61 #include <dns/types.h>
62 
63 #include <dst/dst.h>
64 
65 /*%
66  * A dns_validatorevent_t is sent when a 'validation' completes.
67  * \brief
68  * 'name', 'rdataset', 'sigrdataset', and 'message' are the values that were
69  * supplied when dns_validator_create() was called.  They are returned to the
70  * caller so that they may be freed.
71  *
72  * If the RESULT is ISC_R_SUCCESS and the answer is secure then
73  * proofs[] will contain the names of the NSEC records that hold the
74  * various proofs.  Note the same name may appear multiple times.
75  */
76 typedef struct dns_validatorevent {
77 	ISC_EVENT_COMMON(struct dns_validatorevent);
78 	dns_validator_t *validator;
79 	isc_result_t	 result;
80 	/*
81 	 * Name and type of the response to be validated.
82 	 */
83 	dns_name_t     *name;
84 	dns_rdatatype_t type;
85 	/*
86 	 * Rdata and RRSIG (if any) for positive responses.
87 	 */
88 	dns_rdataset_t *rdataset;
89 	dns_rdataset_t *sigrdataset;
90 	/*
91 	 * The full response.  Required for negative responses.
92 	 * Also required for positive wildcard responses.
93 	 */
94 	dns_message_t *message;
95 	/*
96 	 * Proofs to be cached.
97 	 */
98 	dns_name_t *proofs[4];
99 	/*
100 	 * Optout proof seen.
101 	 */
102 	bool optout;
103 	/*
104 	 * Answer is secure.
105 	 */
106 	bool secure;
107 } dns_validatorevent_t;
108 
109 #define DNS_VALIDATOR_NOQNAMEPROOF    0
110 #define DNS_VALIDATOR_NODATAPROOF     1
111 #define DNS_VALIDATOR_NOWILDCARDPROOF 2
112 #define DNS_VALIDATOR_CLOSESTENCLOSER 3
113 
114 /*%
115  * A validator object represents a validation in progress.
116  * \brief
117  * Clients are strongly discouraged from using this type directly, with
118  * the exception of the 'link' field, which may be used directly for
119  * whatever purpose the client desires.
120  */
121 struct dns_validator {
122 	/* Unlocked. */
123 	unsigned int magic;
124 	isc_mutex_t  lock;
125 	dns_view_t  *view;
126 	/* Locked by lock. */
127 	unsigned int	      options;
128 	unsigned int	      attributes;
129 	dns_validatorevent_t *event;
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 	isc_task_t	     *task;
137 	isc_taskaction_t      action;
138 	void		     *arg;
139 	unsigned int	      labels;
140 	dns_rdataset_t	     *currentset;
141 	dns_rdataset_t	     *keyset;
142 	dns_rdataset_t	     *dsset;
143 	dns_rdataset_t	      fdsset;
144 	dns_rdataset_t	      frdataset;
145 	dns_rdataset_t	      fsigrdataset;
146 	dns_fixedname_t	      fname;
147 	dns_fixedname_t	      wild;
148 	dns_fixedname_t	      closest;
149 	ISC_LINK(dns_validator_t) link;
150 	bool	      mustbesecure;
151 	unsigned int  depth;
152 	unsigned int  authcount;
153 	unsigned int  authfail;
154 	isc_stdtime_t start;
155 };
156 
157 /*%
158  * dns_validator_create() options.
159  */
160 /* obsolete: #define DNS_VALIDATOR_DLV	0x0001U */
161 #define DNS_VALIDATOR_DEFER    0x0002U
162 #define DNS_VALIDATOR_NOCDFLAG 0x0004U
163 #define DNS_VALIDATOR_NONTA    0x0008U /*% Ignore NTA table */
164 
165 ISC_LANG_BEGINDECLS
166 
167 isc_result_t
168 dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
169 		     dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
170 		     dns_message_t *message, unsigned int options,
171 		     isc_task_t *task, isc_taskaction_t action, void *arg,
172 		     dns_validator_t **validatorp);
173 /*%<
174  * Start a DNSSEC validation.
175  *
176  * This validates a response to the question given by
177  * 'name' and 'type'.
178  *
179  * To validate a positive response, the response data is
180  * given by 'rdataset' and 'sigrdataset'.  If 'sigrdataset'
181  * is NULL, the data is presumed insecure and an attempt
182  * is made to prove its insecurity by finding the appropriate
183  * null key.
184  *
185  * The complete response message may be given in 'message',
186  * to make available any authority section NSECs that may be
187  * needed for validation of a response resulting from a
188  * wildcard expansion (though no such wildcard validation
189  * is implemented yet).  If the complete response message
190  * is not available, 'message' is NULL.
191  *
192  * To validate a negative response, the complete negative response
193  * message is given in 'message'.  The 'rdataset', and
194  * 'sigrdataset' arguments must be NULL, but the 'name' and 'type'
195  * arguments must be provided.
196  *
197  * The validation is performed in the context of 'view'.
198  *
199  * When the validation finishes, a dns_validatorevent_t with
200  * the given 'action' and 'arg' are sent to 'task'.
201  * Its 'result' field will be ISC_R_SUCCESS iff the
202  * response was successfully proven to be either secure or
203  * part of a known insecure domain.
204  */
205 
206 void
207 dns_validator_send(dns_validator_t *validator);
208 /*%<
209  * Send a deferred validation request
210  *
211  * Requires:
212  *	'validator' to points to a valid DNSSEC validator.
213  */
214 
215 void
216 dns_validator_cancel(dns_validator_t *validator);
217 /*%<
218  * Cancel a DNSSEC validation in progress.
219  *
220  * Requires:
221  *\li	'validator' points to a valid DNSSEC validator, which
222  *	may or may not already have completed.
223  *
224  * Ensures:
225  *\li	It the validator has not already sent its completion
226  *	event, it will send it with result code ISC_R_CANCELED.
227  */
228 
229 void
230 dns_validator_destroy(dns_validator_t **validatorp);
231 /*%<
232  * Destroy a DNSSEC validator.
233  *
234  * Requires:
235  *\li	'*validatorp' points to a valid DNSSEC validator.
236  * \li	The validator must have completed and sent its completion
237  * 	event.
238  *
239  * Ensures:
240  *\li	All resources used by the validator are freed.
241  */
242 
243 ISC_LANG_ENDDECLS
244 
245 #endif /* DNS_VALIDATOR_H */
246