Deleted Added
full compact
val_utils.h (256281) val_utils.h (269257)
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
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.
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE 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"
45struct query_info;
46struct reply_info;
47struct val_env;
48struct module_env;
49struct ub_packed_rrset_key;
50struct key_entry_key;
51struct regional;
52struct val_anchors;
53struct rrset_cache;
54struct sock_list;
55
56/**
57 * Response classifications for the validator. The different types of proofs.
58 */
59enum 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 */
92enum 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 */
110void 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 */
125enum 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 */
138enum 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 */
157enum 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 */
177enum 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 */
205struct 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 */
233struct 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 */
248int 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 */
267int 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 */
277int 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 */
294void 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 */
305void 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 */
315void 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 */
327void 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 */
337size_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 */
345void 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 */
353const 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 */
365void 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 */
374int 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 */
381int 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 */
400struct 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 */
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"
45struct query_info;
46struct reply_info;
47struct val_env;
48struct module_env;
49struct ub_packed_rrset_key;
50struct key_entry_key;
51struct regional;
52struct val_anchors;
53struct rrset_cache;
54struct sock_list;
55
56/**
57 * Response classifications for the validator. The different types of proofs.
58 */
59enum 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 */
92enum 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 */
110void 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 */
125enum 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 */
138enum 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 */
157enum 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 */
177enum 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 */
205struct 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 */
233struct 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 */
248int 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 */
267int 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 */
277int 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 */
294void 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 */
305void 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 */
315void 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 */
327void 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 */
337size_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 */
345void 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 */
353const 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 */
365void 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 */
374int 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 */
381int 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 */
400struct 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 */