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