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