]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/unbound/validator/val_utils.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / unbound / validator / val_utils.h
1 /*
2  * validator/val_utils.h - validator utility functions.
3  *
4  * Copyright (c) 2007, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  * 
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  * 
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  * 
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  * 
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 /**
37  * \file
38  *
39  * This file contains helper functions for the validator module.
40  */
41
42 #ifndef VALIDATOR_VAL_UTILS_H
43 #define VALIDATOR_VAL_UTILS_H
44 #include "util/data/packed_rrset.h"
45 struct query_info;
46 struct reply_info;
47 struct val_env;
48 struct module_env;
49 struct ub_packed_rrset_key;
50 struct key_entry_key;
51 struct regional;
52 struct val_anchors;
53 struct rrset_cache;
54 struct sock_list;
55
56 /**
57  * Response classifications for the validator. The different types of proofs.
58  */
59 enum val_classification {
60         /** Not subtyped yet. */
61         VAL_CLASS_UNTYPED = 0,
62         /** Not a recognized subtype. */
63         VAL_CLASS_UNKNOWN,
64         /** A positive, direct, response */
65         VAL_CLASS_POSITIVE,
66         /** A positive response, with a CNAME/DNAME chain. */
67         VAL_CLASS_CNAME,
68         /** A NOERROR/NODATA response. */
69         VAL_CLASS_NODATA,
70         /** A NXDOMAIN response. */
71         VAL_CLASS_NAMEERROR,
72         /** A CNAME/DNAME chain, and the offset is at the end of it,
73          * but there is no answer here, it can be NAMERROR or NODATA. */
74         VAL_CLASS_CNAMENOANSWER,
75         /** A referral, from cache with a nonRD query. */
76         VAL_CLASS_REFERRAL,
77         /** A response to a qtype=ANY query. */
78         VAL_CLASS_ANY
79 };
80
81 /**
82  * Given a response, classify ANSWER responses into a subtype.
83  * @param query_flags: query flags for the original query.
84  * @param origqinf: query info. The original query name.
85  * @param qinf: query info. The chased query name.
86  * @param rep: response. The original response.
87  * @param skip: offset into the original response answer section.
88  * @return A subtype, all values possible except UNTYPED .
89  *      Once CNAME type is returned you can increase skip.
90  *      Then, another CNAME type, CNAME_NOANSWER or POSITIVE are possible.
91  */
92 enum val_classification val_classify_response(uint16_t query_flags,
93         struct query_info* origqinf, struct query_info* qinf, 
94         struct reply_info* rep, size_t skip);
95
96 /**
97  * Given a response, determine the name of the "signer". This is primarily
98  * to determine if the response is, in fact, signed at all, and, if so, what
99  * is the name of the most pertinent keyset.
100  *
101  * @param subtype: the type from classify.
102  * @param qinf: query, the chased query name.
103  * @param rep: response to that, original response.
104  * @param cname_skip: how many answer rrsets have been skipped due to CNAME
105  *      chains being chased around.
106  * @param signer_name:  signer name, if the response is signed 
107  *      (even partially), or null if the response isn't signed.
108  * @param signer_len: length of signer_name of 0 if signer_name is NULL.
109  */
110 void val_find_signer(enum val_classification subtype, 
111         struct query_info* qinf, struct reply_info* rep,
112         size_t cname_skip, uint8_t** signer_name, size_t* signer_len);
113
114 /**
115  * Verify RRset with keys
116  * @param env: module environment (scratch buffer)
117  * @param ve: validator environment (verification settings)
118  * @param rrset: what to verify
119  * @param keys: dnskey rrset to verify with.
120  * @param sigalg: if nonNULL provide downgrade protection otherwise one
121  *   algorithm is enough.  Algo list is constructed in here.
122  * @param reason: reason of failure. Fixed string or alloced in scratch.
123  * @return security status of verification.
124  */
125 enum sec_status val_verify_rrset(struct module_env* env, struct val_env* ve,
126         struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys,
127         uint8_t* sigalg, char** reason);
128
129 /**
130  * Verify RRset with keys from a keyset.
131  * @param env: module environment (scratch buffer)
132  * @param ve: validator environment (verification settings)
133  * @param rrset: what to verify
134  * @param kkey: key_entry to verify with.
135  * @param reason: reason of failure. Fixed string or alloced in scratch.
136  * @return security status of verification.
137  */
138 enum sec_status val_verify_rrset_entry(struct module_env* env, 
139         struct val_env* ve, struct ub_packed_rrset_key* rrset, 
140         struct key_entry_key* kkey, char** reason);
141
142 /**
143  * Verify DNSKEYs with DS rrset. Like val_verify_new_DNSKEYs but
144  * returns a sec_status instead of a key_entry.
145  * @param env: module environment (scratch buffer)
146  * @param ve: validator environment (verification settings)
147  * @param dnskey_rrset: DNSKEY rrset to verify
148  * @param ds_rrset: DS rrset to verify with.
149  * @param sigalg: if nonNULL provide downgrade protection otherwise one
150  *   algorithm is enough.  The list of signalled algorithms is returned,
151  *   must have enough space for ALGO_NEEDS_MAX+1.
152  * @param reason: reason of failure. Fixed string or alloced in scratch.
153  * @return: sec_status_secure if a DS matches.
154  *     sec_status_insecure if end of trust (i.e., unknown algorithms).
155  *     sec_status_bogus if it fails.
156  */
157 enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env, 
158         struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset, 
159         struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason);
160
161 /**
162  * Verify DNSKEYs with DS and DNSKEY rrset.  Like val_verify_DNSKEY_with_DS
163  * but for a trust anchor.
164  * @param env: module environment (scratch buffer)
165  * @param ve: validator environment (verification settings)
166  * @param dnskey_rrset: DNSKEY rrset to verify
167  * @param ta_ds: DS rrset to verify with.
168  * @param ta_dnskey: DNSKEY rrset to verify with.
169  * @param sigalg: if nonNULL provide downgrade protection otherwise one
170  *   algorithm is enough.  The list of signalled algorithms is returned,
171  *   must have enough space for ALGO_NEEDS_MAX+1.
172  * @param reason: reason of failure. Fixed string or alloced in scratch.
173  * @return: sec_status_secure if a DS matches.
174  *     sec_status_insecure if end of trust (i.e., unknown algorithms).
175  *     sec_status_bogus if it fails.
176  */
177 enum sec_status val_verify_DNSKEY_with_TA(struct module_env* env, 
178         struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset, 
179         struct ub_packed_rrset_key* ta_ds,
180         struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason);
181
182 /**
183  * Verify new DNSKEYs with DS rrset. The DS contains hash values that should
184  * match the DNSKEY keys.
185  * match the DS to a DNSKEY and verify the DNSKEY rrset with that key.
186  *
187  * @param region: where to allocate key entry result.
188  * @param env: module environment (scratch buffer)
189  * @param ve: validator environment (verification settings)
190  * @param dnskey_rrset: DNSKEY rrset to verify
191  * @param ds_rrset: DS rrset to verify with.
192  * @param downprot: if true provide downgrade protection otherwise one
193  *   algorithm is enough.
194  * @param reason: reason of failure. Fixed string or alloced in scratch.
195  * @return a KeyEntry. This will either contain the now trusted
196  *         dnskey_rrset, a "null" key entry indicating that this DS
197  *         rrset/DNSKEY pair indicate an secure end to the island of trust
198  *         (i.e., unknown algorithms), or a "bad" KeyEntry if the dnskey
199  *         rrset fails to verify. Note that the "null" response should
200  *         generally only occur in a private algorithm scenario: normally
201  *         this sort of thing is checked before fetching the matching DNSKEY
202  *         rrset.
203  *         if downprot is set, a key entry with an algo list is made.
204  */
205 struct key_entry_key* val_verify_new_DNSKEYs(struct regional* region, 
206         struct module_env* env, struct val_env* ve, 
207         struct ub_packed_rrset_key* dnskey_rrset, 
208         struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason);
209
210
211 /**
212  * Verify rrset with trust anchor: DS and DNSKEY rrset.
213  *
214  * @param region: where to allocate key entry result.
215  * @param env: module environment (scratch buffer)
216  * @param ve: validator environment (verification settings)
217  * @param dnskey_rrset: DNSKEY rrset to verify
218  * @param ta_ds_rrset: DS rrset to verify with.
219  * @param ta_dnskey_rrset: the DNSKEY rrset to verify with.
220  * @param downprot: if true provide downgrade protection otherwise one
221  *   algorithm is enough.
222  * @param reason: reason of failure. Fixed string or alloced in scratch.
223  * @return a KeyEntry. This will either contain the now trusted
224  *         dnskey_rrset, a "null" key entry indicating that this DS
225  *         rrset/DNSKEY pair indicate an secure end to the island of trust
226  *         (i.e., unknown algorithms), or a "bad" KeyEntry if the dnskey
227  *         rrset fails to verify. Note that the "null" response should
228  *         generally only occur in a private algorithm scenario: normally
229  *         this sort of thing is checked before fetching the matching DNSKEY
230  *         rrset.
231  *         if downprot is set, a key entry with an algo list is made.
232  */
233 struct key_entry_key* val_verify_new_DNSKEYs_with_ta(struct regional* region, 
234         struct module_env* env, struct val_env* ve, 
235         struct ub_packed_rrset_key* dnskey_rrset, 
236         struct ub_packed_rrset_key* ta_ds_rrset, 
237         struct ub_packed_rrset_key* ta_dnskey_rrset,
238         int downprot, char** reason);
239
240 /**
241  * Determine if DS rrset is usable for validator or not.
242  * Returns true if the algorithms for key and DShash are supported,
243  * for at least one RR.
244  *
245  * @param ds_rrset: the newly received DS rrset.
246  * @return true or false if not usable.
247  */
248 int val_dsset_isusable(struct ub_packed_rrset_key* ds_rrset);
249
250 /**
251  * Determine by looking at a signed RRset whether or not the RRset name was
252  * the result of a wildcard expansion. If so, return the name of the
253  * generating wildcard.
254  * 
255  * @param rrset The rrset to chedck.
256  * @param wc: the wildcard name, if the rrset was synthesized from a wildcard.
257  *         unchanged if not.  The wildcard name, without "*." in front, is 
258  *         returned. This is a pointer into the rrset owner name.
259  * @return false if the signatures are inconsistent in indicating the 
260  *      wildcard status; possible spoofing of wildcard response for other
261  *      responses is being tried. We lost the status which rrsig was verified
262  *      after the verification routine finished, so we simply check if
263  *      the signatures are consistent; inserting a fake signature is a denial
264  *      of service; but in that you could also have removed the real 
265  *      signature anyway.
266  */
267 int val_rrset_wildcard(struct ub_packed_rrset_key* rrset, uint8_t** wc);
268
269 /**
270  * Chase the cname to the next query name.
271  * @param qchase: the current query name, updated to next target.
272  * @param rep: original message reply to look at CNAMEs.
273  * @param cname_skip: the skip into the answer section. Updated to skip
274  *      DNAME and CNAME to the next part of the answer.
275  * @return false on error (bad rdata).
276  */
277 int val_chase_cname(struct query_info* qchase, struct reply_info* rep,
278         size_t* cname_skip);
279
280 /**
281  * Fill up the chased reply with the content from the original reply;
282  * as pointers to those rrsets. Select the part after the cname_skip into
283  * the answer section, NS and AR sections that are signed with same signer.
284  *
285  * @param chase: chased reply, filled up.
286  * @param orig: original reply.
287  * @param cname_skip: which part of the answer section to skip.
288  *      The skipped part contains CNAME(and DNAME)s that have been chased.
289  * @param name: the signer name to look for.
290  * @param len: length of name.
291  * @param signer: signer name or NULL if an unsigned RRset is considered.
292  *      If NULL, rrsets with the lookup name are copied over.
293  */
294 void val_fill_reply(struct reply_info* chase, struct reply_info* orig, 
295         size_t cname_skip, uint8_t* name, size_t len, uint8_t* signer);
296
297 /**
298  * Remove all unsigned or non-secure status rrsets from NS and AR sections.
299  * So that unsigned data does not get let through to clients, when we have
300  * found the data to be secure.
301  *
302  * @param ve: validator environment with cleaning options.
303  * @param rep: reply to dump all nonsecure stuff out of.
304  */
305 void val_check_nonsecure(struct val_env* ve, struct reply_info* rep);
306
307 /**
308  * Mark all unchecked rrset entries not below a trust anchor as indeterminate.
309  * Only security==unchecked rrsets are updated.
310  * @param rep: the reply with rrsets.
311  * @param anchors: the trust anchors.
312  * @param r: rrset cache to store updated security status into.
313  * @param env: module environment
314  */
315 void val_mark_indeterminate(struct reply_info* rep, 
316         struct val_anchors* anchors, struct rrset_cache* r, 
317         struct module_env* env);
318
319 /**
320  * Mark all unchecked rrset entries below a NULL key entry as insecure.
321  * Only security==unchecked rrsets are updated.
322  * @param rep: the reply with rrsets.
323  * @param kname: end of secure space name.
324  * @param r: rrset cache to store updated security status into.
325  * @param env: module environment
326  */
327 void val_mark_insecure(struct reply_info* rep, uint8_t* kname,
328         struct rrset_cache* r, struct module_env* env);
329
330 /**
331  * Find next unchecked rrset position, return it for skip.
332  * @param rep: the original reply to look into.
333  * @param skip: the skip now.
334  * @return new skip, which may be at the rep->rrset_count position to signal
335  *      there are no unchecked items.
336  */
337 size_t val_next_unchecked(struct reply_info* rep, size_t skip);
338
339 /**
340  * Find the signer name for an RRset.
341  * @param rrset: the rrset.
342  * @param sname: signer name is returned or NULL if not signed.
343  * @param slen: length of sname (or 0).
344  */
345 void val_find_rrset_signer(struct ub_packed_rrset_key* rrset, uint8_t** sname,
346         size_t* slen);
347
348 /**
349  * Get string to denote the classification result.
350  * @param subtype: from classification function.
351  * @return static string to describe the classification.
352  */
353 const char* val_classification_to_string(enum val_classification subtype);
354
355 /**
356  * Add existing list to blacklist.
357  * @param blacklist: the blacklist with result
358  * @param region: the region where blacklist is allocated.
359  *      Allocation failures are logged.
360  * @param origin: origin list to add, if NULL, a cache-entry is added to
361  *   the blacklist to stop cache from being used.
362  * @param cross: if true this is a cross-qstate copy, and the 'origin'
363  *   list is not allocated in the same region as the blacklist.
364  */
365 void val_blacklist(struct sock_list** blacklist, struct regional* region,
366         struct sock_list* origin, int cross);
367
368 /**
369  * check if has dnssec info, and if it has signed nsecs. gives error reason.
370  * @param rep: reply to check.
371  * @param reason: returned on fail.
372  * @return false if message has no signed nsecs.  Can not prove negatives.
373  */
374 int val_has_signed_nsecs(struct reply_info* rep, char** reason);
375
376 /**
377  * Return algo number for favorite (best) algorithm that we support in DS.
378  * @param ds_rrset: the DSes in this rrset are inspected and best algo chosen.
379  * @return algo number or 0 if none supported. 0 is unused as algo number.
380  */
381 int val_favorite_ds_algo(struct ub_packed_rrset_key* ds_rrset);
382
383 /**
384  * Find DS denial message in cache.  Saves new qstate allocation and allows
385  * the validator to use partial content which is not enough to construct a
386  * message for network (or user) consumption.  Without SOA for example,
387  * which is a common occurence in the unbound code since the referrals contain
388  * NSEC/NSEC3 rrs without the SOA element, thus do not allow synthesis of a
389  * full negative reply, but do allow synthesis of sufficient proof.
390  * @param env: query env with caches and time.
391  * @param nm: name of DS record sought.
392  * @param nmlen: length of name.
393  * @param c: class of DS RR.
394  * @param region: where to allocate result.
395  * @param topname: name of the key that is currently in use, that will get
396  *      used to validate the result, and thus no higher entries from the
397  *      negative cache need to be examined.
398  * @return a dns_msg on success. NULL on failure.
399  */
400 struct dns_msg* val_find_DS(struct module_env* env, uint8_t* nm, size_t nmlen,
401         uint16_t c, struct regional* region, uint8_t* topname);
402
403 #endif /* VALIDATOR_VAL_UTILS_H */