1 /**
2  *
3  * /brief functions for DNSSEC
4  *
5  * In this file, the "dnssec_return_validation_chain" extension is implemented
6  * (with the _getdns_get_validation_chain() function)
7  * Also the function getdns_validate_dnssec is implemented.
8  * DNSSEC validation as a stub combines those two functionalities, by first
9  * fetching all the records that are necessary to be able to validate a
10  * request (i.e. the "dnssec_return_validation_chain" extension) and then
11  * performing DNSSEC validation for a request with those support records
12  * (and a trust anchor of course).
13  */
14 
15 /*
16  * Copyright (c) 2013, NLnet Labs, Verisign, Inc.
17  * All rights reserved.
18  *
19  * Redistribution and use in source and binary forms, with or without
20  * modification, are permitted provided that the following conditions are met:
21  * * Redistributions of source code must retain the above copyright
22  *   notice, this list of conditions and the following disclaimer.
23  * * Redistributions in binary form must reproduce the above copyright
24  *   notice, this list of conditions and the following disclaimer in the
25  *   documentation and/or other materials provided with the distribution.
26  * * Neither the names of the copyright holders nor the
27  *   names of its contributors may be used to endorse or promote products
28  *   derived from this software without specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
31  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33  * DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
34  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  */
41 
42 /*
43  * From the API:
44  *
45  * The "dnssec_return_validation_chain" extension as explained in section 3.1:
46  *
47  *	Applications that want to do their own validation will want to have the
48  *	DNSSEC-related records for a particular response. Use the
49  *	dnssec_return_validation_chain extension. The extension's value
50  *	(an int) is set to GETDNS_EXTENSION_TRUE to cause a set of additional
51  *	DNSSEC-related records needed for validation to be returned in the
52  *	response object. This set comes as validation_chain (a list) at the top
53  *	level of the response object. This list includes all resource record
54  *	dicts for all the resource records (DS, DNSKEY and their RRSIGs) that
55  *	are needed to perform the validation from the root up.
56  *
57  *
58  * The getdns_validate_dnssec() function as explained in section 7:
59  *
60  *	If an application wants the API do perform DNSSEC validation without
61  *	using the extensions, it can use the getdns_validate_dnssec() helper
62  *	function.
63  *
64  *	getdns_return_t
65  *	getdns_validate_dnssec(
66  *		getdns_list     *record_to_validate,
67  *		getdns_list     *bundle_of_support_records,
68  *		getdns_list     *trust_anchor_records
69  *	);
70  *
71  *	The record_to_validate is the resource record being validated together
72  *	with the associated signatures. The API will use the resource records
73  *	in bundle_of_support_records to construct the validation chain and the
74  *	DNSKEY or DS records in trust_anchor_records as trust anchors. The
75  * 	function returns one of GETDNS_DNSSEC_SECURE, GETDNS_DNSSEC_BOGUS,
76  *	GETDNS_DNSSEC_INDETERMINATE, or GETDNS_DNSSEC_INSECURE.
77  */
78 
79 /* Outline of operations in this file
80  * ==================================
81  *
82  * Data structure to represent the delegation/referral hierarchy
83  * -------------------------------------------------------------
84  * Both the "dnssec_return_validation_chain" extension, and the
85  * getdns_validate_dnssec() function use the same structs to represent the
86  * involved pieces of the DNS in a hierarchical manner.
87  *
88  * However, the tree is not represented from the root, but from the RRsets that
89  * need to be validated.  The RRset to validate is a member of the chain_head
90  * struct for this.  The chain_head struct has a "next" member to form a linked
91  * list of RRsets to validate.
92  *
93  * The chain_head struct also has a "parent" member to a linked list of
94  * chain_node structs (linked with the "parent" member of those chain_nodes).
95  * For each label in the name of the rrset in a chain_head, is a chain_node,
96  * all the way to the root.  The last chain_node is thus always the root, for
97  * every chain_head.
98  *
99  * The construction functions for this datastructure make sure there is always
100  * a single chain_node representing the same name.  They also make sure space
101  * for chain_head + the number of extra chain_nodes needed is allocated in a
102  * single region, so that on destruction one only has to free the chain_heads.
103  *
104  * A chain_node contains two RRset members, "dnskey" and "ds" which represent
105  * the potential client side DNSKEYs and the parent side DS records of a
106  * potential zonecut at this point.  Whether or not there is an actual zone
107  * cut is determined separately.  With the "dnssec_return_validation_chain"
108  * extension by scheduling queries, and with the getdns_validation_dnssec()
109  * function by provisioning the support records at the chain nodes.
110  *
111  * In the construction functions a chain_head is created for every RRset in
112  * the answer and authority section of a given packet (except for synthesized
113  * CNAMEs).  Furthermore, if the queries for name/class/type is not in the
114  * packet, a chain_head for the non-existent rrset is created too, to that
115  * it will be evaluated for non-existence later in the validation process.
116  *
117  * The chain_head and chain_node structs are defined in section:
118  * "Validation Chain Data Structs".  The functions to construct the hierarchy
119  * are defined in section "Validation Chain Construction".  When the
120  * construction functions are called for the purpose of the
121  * "dnssec_return_validation_chain" extension, queries to provision the
122  * chain_nodes are scheduled.  Function theretofore are in section:
123  * "Schedule Queries to Provision Validation Chain"
124  *
125  *
126  * _getdns_rrset
127  * ------------
128  * RRsets used in the structure described above are represented by the
129  * _getdns_rrset struct.  They consist of name/rr_class and rr_type members
130  * plus a reference to the wireformat packet that should contain the RRset.
131  *
132  * The actual RR's in the rrset and the signatures are only accessed via
133  * iterators; substantiated with the rrtype_iter struct to iterate over RRs
134  * in a _getdns_rrset, and the rrsig_iter to iterate over the RRSIGs covering
135  * the RRs in the _getdns_rrset.
136  *
137  * The _getdns_rrsets are already equipped with name/rr_class and rr_type when
138  * constructing the linked list of chain_nodes up to the root for a chain_head.
139  * They are substantiated with the wireformat packets that are returned with
140  * the queries that were sheduled in the context of the
141  * "dnssec_return_validation_chain" extension.
142  *
143  * Note that the NSEC(3) RRsets proving the non-existance of a _getdns_rrset
144  * can be found by processing that _getdns_rrset, as it contains the pointer
145  * to the wireformat data that should either contain the RRset or the proof
146  * of non-existance.
147  *
148  * The getdns_validate_dnssec() function, after it constructed the chain_heads
149  * hierarchy, creates an artificial packet for the support records and equips
150  * all the ds and dnskey _getdns_rrsets on the chain_nodes with this packet.
151  *
152  * The _getdns_rrset + support function and data types are defined in section:
153  * "_getdns_rrset + Support Iterators"
154  *
155  *
156  * Validation
157  * ----------
158  * Validation of a constructed chain is done by the
159  * chain_set_netreq_dnssec_status() function when validating in stub mode.
160  * And with the chain_validate_dnssec() function when using the
161  * getdns_validate_dnssec() function.  They are the same, except that
162  * chain_set_netreq_dnssec_status() evaluates DNSSEC status per network
163  * request and chain_validate_dnssec() does it for the whole chain.
164  *
165  * They both evaluate the DNSSEC status for each head in turn.  The worst
166  * DNSSEC status determines the status of all heads evaluated.  Where
167  * INSECURE is worse than SECURE, and BOGUS is worse than INSECURE.
168  *
169  * For each head, the closest (most labels still a parent of the head's name)
170  * trust anchor is tried.  Without fitting trust anchors, DNSSEC_INDETERMINATE
171  * is returned.
172  *
173  * Security status for a head (with a specific trust anchor) is evaluated by
174  * first finding a authenticated keyset from the parent chain_nodes, and then
175  * evaluating the rrset of the head (existent or not) with that keyset.
176  *
177  * Functions that implement DNSSEC validation are in section:
178  * "DNSSEC Validation".
179  *
180  * Many functions are of key verification boolean return type; e.g.
181  * key_proves_nonexistance(), ds_authenticates_keys(), a_key_signed_rrset()
182  * These will return the keytag identifying the key that was used to
183  * authenticate + 0x10000 to allow keytag 0.
184  *
185  * These returned keytag's are used later with function
186  * append_rrs2val_chain_list() to return a "dnssec_validation_chain" that
187  * enumerates a single RRSIG per RRset.  This can be found in section:
188  * "dnssec_return_validation_chain Extension".
189  */
190 
191 #include "config.h"
192 #include "debug.h"
193 #include <sys/types.h>
194 #include <sys/stat.h>
195 #include <unistd.h>
196 #include <ctype.h>
197 #include "getdns/getdns.h"
198 #include "context.h"
199 #include "util-internal.h"
200 #include "types-internal.h"
201 #include "dnssec.h"
202 #include "rr-dict.h"
203 #include "gldns/str2wire.h"
204 #include "gldns/wire2str.h"
205 #include "gldns/keyraw.h"
206 #include "gldns/parseutil.h"
207 #include "general.h"
208 #include "dict.h"
209 #include "list.h"
210 #include "util/val_secalgo.h"
211 #include "anchor.h"
212 #include "tls.h"
213 
214 #define SIGNATURE_VERIFIED         0x10000
215 #define NSEC3_ITERATION_COUNT_HIGH 0x20000
216 #define NO_SUPPORTED_ALGORITHMS    0x40000
217 
218 /*******************  Frequently Used Utility Functions  *********************
219  *****************************************************************************/
220 
_dname_len(const uint8_t * name)221 static inline size_t _dname_len(const uint8_t *name)
222 {
223 	const uint8_t *p;
224 	for (p = name; *p; p += *p + 1)
225 		/* pass */
226 		;
227 	return p - name + 1;
228 }
229 
_dname_label_count(const uint8_t * name)230 static inline size_t _dname_label_count(const uint8_t *name)
231 {
232 	size_t c;
233 	for (c = 0; *name; name += *name + 1, c++)
234 		/* pass */
235 		;
236 	return c;
237 }
238 
_dname_equal(const uint8_t * left,const uint8_t * right)239 static inline int _dname_equal(const uint8_t *left, const uint8_t *right)
240 {
241 	return _getdns_dname_equal(left, right);
242 }
243 
_dname_is_parent(const uint8_t * const parent,const uint8_t * subdomain)244 static int _dname_is_parent(
245     const uint8_t * const parent, const uint8_t *subdomain)
246 {
247 	if (*parent == 0)
248 		return 1;
249 
250 	else while (*subdomain) {
251 		if (_dname_equal(parent, subdomain))
252 			return 1;
253 
254 		subdomain += *subdomain + 1;
255 	}
256 	return 0;
257 }
258 
_dname_label_copy(uint8_t * dst,const uint8_t * src,size_t dst_len)259 static uint8_t *_dname_label_copy(uint8_t *dst, const uint8_t *src, size_t dst_len)
260 {
261 	uint8_t *r = dst, i;
262 
263 	if (!src || (size_t)*src + 1 > dst_len)
264 		return NULL;
265 
266 	for (i = (*dst++ = *src++); i ; i--)
267 		*dst++ = tolower(*src++);
268 
269 	return r;
270 }
271 
272 
273 /* Fills the array pointed to by labels (of at least 128 uint8_t * pointers)
274  * with pointers to labels in given dname in reversed order.  So that
275  * labels[0] will point to the root.
276  * labels[1] will point to the tld etc.
277  * A pointer just past the last assigned array element will be returned.
278  *
279  * So if dname would be "www.getdnsapi.net"
280  * labels[0] will be "."
281  * labels[1] will be "net."
282  * labels[2] will be "getdnsapi.net."
283  * labels[3] will be "www.getdnsapi.net."
284  * The returned value will be &labels[4]
285  */
reverse_labels(const uint8_t * dname,const uint8_t ** labels)286 static const uint8_t **reverse_labels(
287     const uint8_t *dname, const uint8_t **labels)
288 {
289 	if (*dname)
290 		labels = reverse_labels(dname + *dname + 1, labels);
291 	*labels = dname;
292 	return labels + 1;
293 }
294 
dname_shared_parent(const uint8_t * left,const uint8_t * right)295 static const uint8_t *dname_shared_parent(
296     const uint8_t *left, const uint8_t *right)
297 {
298 	const uint8_t *llabels[128], *rlabels[128], **last_llabel, **last_rlabel,
299 		**llabel, **rlabel, *l, *r;
300 	uint8_t sz;
301 
302 	last_llabel = reverse_labels(left, llabels);
303 	last_rlabel = reverse_labels(right, rlabels);
304 
305 	/* Always at least one label (the root) */
306 	assert(last_llabel > llabels);
307 	assert(last_rlabel > rlabels);
308 	assert(*llabels[0] == 0);
309 	assert(*rlabels[0] == 0);
310 
311 	for ( llabel = &llabels[1], rlabel = &rlabels[1]
312 	    ; llabel < last_llabel
313 	    ; llabel++, rlabel++ ) {
314 
315 		sz = **llabel;
316 		if (   rlabel == last_rlabel
317 		    || **llabel != **rlabel)
318 			return llabel[-1];
319 
320 		for (l = *llabel+1, r = *rlabel+1; sz; l++, r++, sz-- )
321 			if (*l != *r && tolower((unsigned char)*l) !=
322 					tolower((unsigned char)*r))
323 				return llabel[-1];
324 	}
325 	return llabel[-1];
326 }
327 
dname_compare(const uint8_t * left,const uint8_t * right)328 static int dname_compare(const uint8_t *left, const uint8_t *right)
329 {
330 	const uint8_t *llabels[128], *rlabels[128], **last_llabel, **last_rlabel,
331 		**llabel, **rlabel, *l, *r;
332 	uint8_t lsz, rsz;
333 
334 	last_llabel = reverse_labels(left, llabels);
335 	last_rlabel = reverse_labels(right, rlabels);
336 
337 	for ( llabel = llabels, rlabel = rlabels
338 	    ; llabel < last_llabel
339 	    ; llabel++, rlabel++ ) {
340 
341 		if (rlabel == last_rlabel)
342 			return 1;
343 
344 		for ( l = *llabel, lsz = *l++, r = *rlabel, rsz = *r++
345 		    ; lsz; l++, r++, lsz--, rsz-- ) {
346 
347 			/* No compression pointers here */
348 			assert(lsz <= 63);
349 			assert(rsz <= 63);
350 
351 			if (!rsz)
352 				return 1;
353 			if (*l != *r && tolower((unsigned char)*l) !=
354 					tolower((unsigned char)*r)) {
355 				if (tolower((unsigned char)*l) <
356 				    tolower((unsigned char)*r))
357 					return -1;
358 				return 1;
359 			}
360 		}
361 		if (rsz)
362 			return -1;
363 	}
364 	return rlabel == last_rlabel ? 0 : -1;
365 }
366 
bitmap_has_type(_getdns_rdf_iter * bitmap,uint16_t rr_type)367 static int bitmap_has_type(_getdns_rdf_iter *bitmap, uint16_t rr_type)
368 {
369 	const uint8_t *dptr, *dend;
370 	uint8_t window  = rr_type >> 8;
371 	uint8_t subtype = rr_type & 0xFF;
372 
373 	if (!bitmap || (dptr = bitmap->pos) == (dend = bitmap->nxt))
374 		return 0;
375 
376 	/* Type Bitmap = ( Window Block # | Bitmap Length | Bitmap ) +
377 	 *                 dptr[0]          dptr[1]         dptr[2:]
378 	 */
379 	while (dptr < dend && dptr[0] <= window) {
380 		if (dptr[0] == window && subtype / 8 < dptr[1] &&
381 		    dptr + dptr[1] + 2 <= dend)
382 			return dptr[2 + subtype / 8] & (0x80 >> (subtype % 8));
383 		dptr += dptr[1] + 2; /* next window */
384 	}
385 	return 0;
386 }
387 
388 #if defined(SEC_DEBUG) && SEC_DEBUG
debug_sec_print_rr(const char * msg,_getdns_rr_iter * rr)389 static inline void debug_sec_print_rr(const char *msg, _getdns_rr_iter *rr)
390 {
391 	char str_spc[8192], *str = str_spc;
392 	size_t str_len = sizeof(str_spc);
393 	const uint8_t *data = rr->pos;
394 	size_t data_len = rr->nxt - rr->pos;
395 
396 	if (!rr || !rr->pos) {
397 		DEBUG_SEC("%s<nil>\n", msg);
398 		return;
399 	}
400 	(void) gldns_wire2str_rr_scan(
401 	    (UNCONST_UINT8_p *) &data, &data_len, &str, &str_len,
402 	    (UNCONST_UINT8_p) rr->pkt, rr->pkt_end - rr->pkt);
403 	DEBUG_SEC("%s%s", msg, str_spc);
404 }
debug_sec_print_dname(const char * msg,const uint8_t * label)405 static inline void debug_sec_print_dname(const char *msg, const uint8_t *label)
406 {
407 	char str[1024];
408 
409 	if (label && gldns_wire2str_dname_buf(
410 	    (UNCONST_UINT8_p)label, 256, str, sizeof(str)))
411 		DEBUG_SEC("%s%s\n", msg, str);
412 	else
413 		DEBUG_SEC("%s<nil>\n", msg);
414 }
415 #else
416 #define debug_sec_print_rr(...) DEBUG_OFF(__VA_ARGS__)
417 #define debug_sec_print_dname(...) DEBUG_OFF(__VA_ARGS__)
418 #define debug_sec_print_pkt(...) DEBUG_OFF(__VA_ARGS__)
419 #endif
420 
421 
422 /*******************  _getdns_rrset + Support Iterators  **********************
423  *****************************************************************************/
424 
425 
426 #if defined(SEC_DEBUG) && SEC_DEBUG
debug_sec_print_rrset(const char * msg,_getdns_rrset * rrset)427 static void debug_sec_print_rrset(const char *msg, _getdns_rrset *rrset)
428 {
429 	char owner[1024];
430 	char buf_space[2048];
431 	gldns_buffer buf;
432 	_getdns_rrtype_iter *rr, rr_space;
433 	_getdns_rrsig_iter  *rrsig, rrsig_space;
434 	size_t i;
435 
436 	if (!rrset) {
437 		DEBUG_SEC("<nil>");
438 		return;
439 	}
440 	gldns_buffer_init_frm_data(&buf, buf_space, sizeof(buf_space));
441 	if (gldns_wire2str_dname_buf(
442 	    (UNCONST_UINT8_p)rrset->name, 256, owner, sizeof(owner)))
443 		gldns_buffer_printf(&buf, "%s ", owner);
444 	else	gldns_buffer_printf(&buf, "<nil> ");
445 
446 	switch (rrset->rr_class) {
447 	case GETDNS_RRCLASS_IN	: gldns_buffer_printf(&buf, "IN ")  ; break;
448 	case GETDNS_RRCLASS_CH	: gldns_buffer_printf(&buf, "CH ")  ; break;
449 	case GETDNS_RRCLASS_HS	: gldns_buffer_printf(&buf, "HS ")  ; break;
450 	case GETDNS_RRCLASS_NONE: gldns_buffer_printf(&buf, "NONE "); break;
451 	case GETDNS_RRCLASS_ANY	: gldns_buffer_printf(&buf, "ANY ") ; break;
452 	default			: gldns_buffer_printf(&buf, "CLASS%d "
453 						          , rrset->rr_class);
454 				  break;
455 	}
456 	gldns_buffer_printf(&buf, "%s", _getdns_rr_type_name(rrset->rr_type));
457 
458 	gldns_buffer_printf(&buf, ", rrs:");
459 	for ( rr = _getdns_rrtype_iter_init(&rr_space, rrset), i = 1
460 	    ; rr
461 	    ; rr = _getdns_rrtype_iter_next(rr), i++)
462 		gldns_buffer_printf(&buf, " %d", (int)i);
463 
464 	gldns_buffer_printf(&buf, ", rrsigs:");
465 	for ( rrsig = _getdns_rrsig_iter_init(&rrsig_space, rrset), i = 1
466 	    ; rrsig
467 	    ; rrsig = _getdns_rrsig_iter_next(rrsig), i++)
468 		gldns_buffer_printf(&buf, " %d", (int)i);
469 
470 	DEBUG_SEC("%s%s\n", msg, buf_space);
471 }
472 #else
473 #define debug_sec_print_rrset(...) DEBUG_OFF(__VA_ARGS__)
474 #endif
475 
476 
477 /*********************  Validation Chain Data Structs  ***********************
478  *****************************************************************************/
479 
480 typedef struct chain_head chain_head;
481 typedef struct chain_node chain_node;
482 
483 struct chain_head {
484 	struct mem_funcs  my_mf;
485 
486 	size_t              lock;
487 
488 	chain_head         *next;
489 	chain_node         *parent;
490 	size_t              node_count; /* Number of nodes attached directly
491 	                                 * to this head.  For cleaning.  */
492 	_getdns_rrset       rrset;
493 	getdns_network_req *netreq;
494 	int                 signer;
495 
496 	uint8_t             name_spc[];
497 };
498 
499 struct chain_node {
500 	chain_node  *parent;
501 
502 	size_t              lock;
503 
504 	_getdns_rrset       dnskey;
505 	getdns_network_req *dnskey_req;
506 	int                 dnskey_signer;
507 
508 	_getdns_rrset       ds;
509 	getdns_network_req *ds_req;
510 	int                 ds_signer;
511 
512 	chain_head  *chains;
513 };
514 
515 /*********************  Validation Chain Construction  ***********************
516  *****************************************************************************/
517 
518 /* When construction is done in the context of stub validation, the requests
519  * to equip the chain nodes with their RR sets are done alongside construction.
520  * Hence they need to be enumerated before the construction functions.
521  */
522 static void val_chain_sched(chain_head *head, const uint8_t *dname);
523 static void val_chain_sched_ds(chain_head *head, const uint8_t *dname);
524 static void val_chain_sched_signer(chain_head *head, _getdns_rrsig_iter *rrsig);
525 
add_rrset2val_chain(const struct mem_funcs * mf,chain_head ** chain_p,_getdns_rrset * rrset,getdns_network_req * netreq)526 static chain_head *add_rrset2val_chain(const struct mem_funcs *mf,
527     chain_head **chain_p, _getdns_rrset *rrset, getdns_network_req *netreq)
528 {
529 	chain_head *head;
530 	const uint8_t *labels[128], **last_label, **label;
531 
532 	ssize_t     max_labels; /* max labels in common */
533 	chain_head *max_head;
534 	chain_node *max_node;
535 
536 	size_t      dname_len, head_sz, node_count, n;
537 	const uint8_t *dname;
538 	uint8_t    *region;
539 	chain_node *node;
540 
541 	last_label = reverse_labels(rrset->name, labels);
542 
543 	/* Try to find a chain with the most overlapping labels.
544 	 * max_labels will be the number of labels in common from the root
545 	 *            (so at least one; the root)
546 	 * max_head   will be the head of the chain with max # labels in common
547 	 */
548 	max_head = NULL;
549 	max_labels = 0;
550 	for (head = *chain_p; head; head = head->next) {
551 		/* Also, try to prevent adding double rrsets */
552 		if (   rrset->rr_class == head->rrset.rr_class
553 		    && rrset->rr_type  == head->rrset.rr_type
554 		    && _dname_equal(rrset->name, head->rrset.name)) {
555 
556 			if (rrset->pkt == head->rrset.pkt &&
557 			    rrset->pkt_len == head->rrset.pkt_len)
558 				return NULL;
559 			else {
560 				/* Anticipate resubmissions due to
561 				 * roadblock avoidance */
562 				head->rrset.pkt = rrset->pkt;
563 				head->rrset.pkt_len = rrset->pkt_len;
564 				return head;
565 			}
566 		}
567 
568 		if (   rrset->rr_class == head->rrset.rr_class
569 		    && rrset->rr_type  == head->rrset.rr_type
570 		    && rrset->pkt      != head->rrset.pkt
571 		    && _dname_equal(rrset->name, head->rrset.name)) {
572 			return NULL;
573 		}
574 		for (label = labels; label < last_label; label++) {
575 			if (! _dname_is_parent(*label, head->rrset.name))
576 				break;
577 		}
578 		if ((ssize_t)(label - labels) > max_labels) {
579 			max_labels = label - labels;
580 			max_head = head;
581 		}
582 	}
583 	/* Chain found.  Now set max_node to the point in the chain where nodes
584 	 *               will be common.
585 	 */
586 	if (max_head) {
587 		for ( node = max_head->parent, n = 0
588 		    ; node
589 		    ; node = node->parent, n++);
590 
591 		for ( n -= max_labels, node = max_head->parent
592 		    ; n && node
593 		    ; n--, node = node->parent);
594 
595 		max_node = node;
596 	} else
597 		max_node = NULL;
598 
599 	/* node_count is the amount of nodes to still allocate.
600 	 * the last one's parent has to hook into the max_node.
601 	 */
602 	dname_len = *labels - last_label[-1] + 1;
603 	head_sz = (sizeof(chain_head) + dname_len + 7) / 8 * 8;
604 	node_count = last_label - labels - max_labels;
605 	DEBUG_SEC( "%"PRIsz" labels in common. %"PRIsz" labels to allocate\n"
606 	         , max_labels, node_count);
607 
608 	if (! (region = GETDNS_XMALLOC(*mf, uint8_t, head_sz +
609 	    node_count * sizeof(chain_node))))
610 		return NULL;
611 
612 	/* Append the head on the linked list of heads */
613 	for (head = *chain_p; head && head->next; head = head->next)
614 		;
615 	if  (head)
616 		head = head->next = (chain_head *)region;
617 	else
618 		head = *chain_p   = (chain_head *)region;
619 
620 	head->my_mf = *mf;
621 	head->lock = 1;
622 	head->next = NULL;
623 	head->rrset.name = head->name_spc;
624 	memcpy(head->name_spc, rrset->name, dname_len);
625 	head->rrset.rr_class = rrset->rr_class;
626 	head->rrset.rr_type = rrset->rr_type;
627 	head->rrset.pkt = rrset->pkt;
628 	head->rrset.pkt_len = rrset->pkt_len;
629 	head->rrset.sections = rrset->sections;
630 	head->netreq = netreq;
631 	head->signer = -1;
632 	head->node_count = node_count;
633 
634 	if (!node_count) {
635 		/* When this head has no nodes of itself, it must have found
636 		 * another head which has nodes for its labels (i.e. max_head)
637 		 */
638 		assert(max_head != NULL);
639 
640 		head->parent = max_head->parent;
641 		return head;
642 	}
643 
644 	/* Initialize the nodes */
645 
646 	for ( head->parent = node = (chain_node *)(region + head_sz),
647 	      dname = head->rrset.name
648 	    ; node_count
649 	    ; node_count--, node = node->parent =&node[1], dname += *dname + 1) {
650 
651 		node->lock            = 0;
652 		node->ds.name         = dname;
653 		node->dnskey.name     = dname;
654 		node->ds.rr_class     = head->rrset.rr_class;
655 		node->dnskey.rr_class = head->rrset.rr_class;
656 		node->ds.rr_type      = GETDNS_RRTYPE_DS;
657 		node->dnskey.rr_type  = GETDNS_RRTYPE_DNSKEY;
658 		node->ds.pkt          = NULL;
659 		node->ds.pkt_len      = 0;
660 		node->ds.sections     = head->rrset.sections;
661 		node->dnskey.pkt      = NULL;
662 		node->dnskey.pkt_len  = 0;
663 		node->dnskey.sections = head->rrset.sections;
664 		node->ds_req          = NULL;
665 		node->dnskey_req      = NULL;
666 		node->ds_signer       = -1;
667 		node->dnskey_signer   = -1;
668 
669 		node->chains          = *chain_p;
670 	}
671 	/* On the first chain, max_node == NULL.
672 	 * Schedule a root DNSKEY query, we always need that.
673 	 */
674 	if (!(node[-1].parent = max_node))
675 		val_chain_sched(head, (uint8_t *)"\0");
676 
677 	/* For an NSEC or NSEC3 query, stop at that.  If it is valid it will
678 	 * have a signature which will be chased.
679 	 */
680 	if (head->rrset.rr_type == GETDNS_RRTYPE_NSEC ||
681 	    head->rrset.rr_type == GETDNS_RRTYPE_NSEC3)
682 		return head;
683 
684 	/* Otherwise, schedule key lookups for the tld and sld too. */
685 	if (!max_node) {
686 		if (head->node_count > 1)
687 			val_chain_sched(head, node[-2].ds.name);
688 		if (head->node_count > 2)
689 			val_chain_sched(head, node[-3].ds.name);
690 	} else if ((max_labels == 1 || max_labels == 2) && head->node_count > 0)
691 		val_chain_sched(head, node[-1].ds.name);
692 	if (max_labels == 1 && head->node_count > 1)
693 		val_chain_sched(head, node[-2].ds.name);
694 
695 	return head;
696 }
697 
is_synthesized_cname(_getdns_rrset * cname)698 static int is_synthesized_cname(_getdns_rrset *cname)
699 {
700 	_getdns_rrset_iter *i, i_spc;
701 	_getdns_rrset *dname;
702 	_getdns_rrtype_iter rr_spc, *rr;
703 	_getdns_rdf_iter rdf_spc, *rdf;
704 	_getdns_rrtype_iter drr_spc, *drr;
705 	_getdns_rdf_iter drdf_spc, *drdf;
706 	uint8_t cname_rdata_spc[256],
707 	        dname_rdata_spc[256],
708 		synth_name[256],
709 	       *synth_name_end = synth_name + sizeof(synth_name) - 1, *s;
710 	const uint8_t *cname_rdata, *dname_rdata, *c;
711 	size_t cname_rdata_len = sizeof(cname_rdata_spc),
712 	       dname_rdata_len = sizeof(dname_rdata_len),
713 	       cname_labels, dname_labels;
714 
715 	/* Synthesized CNAMEs don't have RRSIGs */
716 	if (   cname->rr_type != GETDNS_RRTYPE_CNAME
717 	    || _getdns_rrset_has_rrsigs(cname))
718 		return 0;
719 
720 	/* Get canonical name rdata field */
721 	if (   !(rr = _getdns_rrtype_iter_init(&rr_spc, cname))
722 	    || !(rdf = _getdns_rdf_iter_init(&rdf_spc, &rr->rr_i))
723 	    || !(cname_rdata = _getdns_rdf_if_or_as_decompressed(
724 			    rdf, cname_rdata_spc, &cname_rdata_len)))
725 		return 0;
726 
727 	/* Find a matching DNAME */
728 	for ( i = _getdns_rrset_iter_init(&i_spc, cname->pkt, cname->pkt_len
729 	                                        , SECTION_ANSWER)
730 	    ; i
731 	    ; i = _getdns_rrset_iter_next(i)) {
732 
733 		dname = _getdns_rrset_iter_value(i);
734 		if (   dname->rr_type != GETDNS_RRTYPE_DNAME
735 		    /* DNAME->owner is parent of CNAME->owner */
736 		    || !_dname_is_parent(dname->name, cname->name))
737 			continue;
738 
739 
740 		dname_labels = _dname_label_count(dname->name);
741 		cname_labels = _dname_label_count(cname->name);
742 
743 		/* Synthesize the canonical name.
744 		 * First copy labels(cname) - labels(dname) labels from
745 		 * CNAME's owner name, then append DNAME rdata field.
746 		 * If it matches CNAME's rdata field then it was synthesized
747 		 * with this DNAME.
748 		 */
749 		cname_labels -= dname_labels;
750 		for ( c = cname->name, s = synth_name
751 		    ; cname_labels && s +  *c + 1 < synth_name_end
752 		    ; cname_labels--, c += *c + 1, s += *s + 1 ) {
753 
754 			memcpy(s, c, *c + 1);
755 		}
756 		if (cname_labels)
757 			continue;
758 
759 		/* Get DNAME's rdata field */
760 		if (   !(drr = _getdns_rrtype_iter_init(&drr_spc, dname))
761 		    || !(drdf=_getdns_rdf_iter_init(&drdf_spc,&drr->rr_i))
762 		    || !(dname_rdata = _getdns_rdf_if_or_as_decompressed(
763 				    drdf, dname_rdata_spc, &dname_rdata_len)))
764 			continue;
765 
766 		if (s + _dname_len(dname_rdata) > synth_name_end)
767 			continue;
768 
769 		memcpy(s, dname_rdata, _dname_len(dname_rdata));
770 		debug_sec_print_dname("Synthesized name: ", synth_name);
771 		debug_sec_print_dname("  Canonical name: ", cname_rdata);
772 		if (_dname_equal(synth_name, cname_rdata))
773 			return 1;
774 	}
775 	return 0;
776 }
777 
778 /* Create the validation chain structure for the given packet.
779  * When netreq is set, queries will be scheduled for the DS
780  * and DNSKEY RR's for the nodes on the validation chain.
781  *
782  * Scheduling is as follows.
783  * If the RRset has a signature, signer name is followed to schedule DS/DNSKEY.
784  * Otherwise, if the RRSET is a SOA, owner name is followed to schedule DS
785  * Otherwise, if the RRset is a CNAME, a SOA query is scheduled for the parent
786  * Otherwise, a SOA query is scheduled for the owner name.
787  *
788  * When a SOA query was successful, a query for DS will follow for that
789  * owner name.
790  */
add_pkt2val_chain(const struct mem_funcs * mf,chain_head ** chain_p,uint8_t * pkt,size_t pkt_len,getdns_network_req * netreq)791 static void add_pkt2val_chain(const struct mem_funcs *mf,
792     chain_head **chain_p, uint8_t *pkt, size_t pkt_len,
793     getdns_network_req *netreq)
794 {
795 	_getdns_rrset_iter *i, i_spc;
796 	_getdns_rrset *rrset;
797 	_getdns_rrsig_iter *rrsig, rrsig_spc;
798 	size_t n_rrsigs;
799 	chain_head *head;
800 
801 	assert(pkt);
802 	assert(pkt_len >= GLDNS_HEADER_SIZE);
803 
804 	/* For all things with signatures, create a chain */
805 
806 	/* For all things without signature, find SOA (zonecut) and query DS */
807 
808 	for ( i = _getdns_rrset_iter_init(&i_spc, pkt, pkt_len
809 	                                        , SECTION_NO_ADDITIONAL)
810 	    ; i
811 	    ; i = _getdns_rrset_iter_next(i)) {
812 
813 		rrset = _getdns_rrset_iter_value(i);
814 		debug_sec_print_rrset("rrset: ", rrset);
815 
816 		/* Schedule validation for everything, except from DNAME
817 		 * synthesized CNAME's
818 		 */
819 		if (is_synthesized_cname(rrset))
820 			continue;
821 
822 		if (!(rrsig = _getdns_rrsig_iter_init(&rrsig_spc, rrset))
823 		    && _getdns_rr_iter_section(&i->rr_i) != SECTION_ANSWER)
824 			continue; /* No sigs in authority section is okayish */
825 
826 		if (!(head = add_rrset2val_chain(mf, chain_p, rrset, netreq)))
827 			continue;
828 
829 		for ( n_rrsigs = 0; rrsig
830 		    ; rrsig = _getdns_rrsig_iter_next(rrsig), n_rrsigs++) {
831 
832 			/* Signature, so lookup DS/DNSKEY at signer's name */
833 			val_chain_sched_signer(head, rrsig);
834 		}
835 		if (n_rrsigs)
836 			continue;
837 
838 		/* No signatures found for this RRset */
839 		if (rrset->rr_type == GETDNS_RRTYPE_SOA)
840 			val_chain_sched_ds(head, rrset->name);
841 		else if (rrset->rr_type == GETDNS_RRTYPE_CNAME)
842 			val_chain_sched_ds(head, rrset->name + *rrset->name + 1);
843 		else
844 			val_chain_sched_ds(head, rrset->name);
845 	}
846 }
847 
848 /* For NOERROR/NODATA or NXDOMAIN responses add extra rrset to
849  * the validation chain so the denial of existence will be
850  * checked eventually.
851  * But only if we know the question of course...
852  */
add_question2val_chain(const struct mem_funcs * mf,chain_head ** chain_p,uint8_t * pkt,size_t pkt_len,const uint8_t * qname,uint16_t qtype,uint16_t qclass,getdns_network_req * netreq)853 static void add_question2val_chain(const struct mem_funcs *mf,
854     chain_head **chain_p, uint8_t *pkt, size_t pkt_len,
855     const uint8_t *qname, uint16_t qtype, uint16_t qclass,
856     getdns_network_req *netreq)
857 {
858 	_getdns_rrset_iter *i, i_spc;
859 	_getdns_rrset *rrset;
860 	_getdns_rrsig_iter rrsig_spc;
861 	size_t n_soas;
862 
863 	_getdns_rrset_spc q_rrset;
864 	chain_head *head;
865 
866 	assert(pkt);
867 	assert(pkt_len >= GLDNS_HEADER_SIZE);
868 	assert(qname);
869 
870 	/* First find the canonical name for the question */
871 	q_rrset.rrset.name     = qname;
872 	q_rrset.rrset.rr_type  = qtype;
873 	q_rrset.rrset.rr_class = qclass;
874 	q_rrset.rrset.pkt      = pkt;
875 	q_rrset.rrset.pkt_len  = pkt_len;
876 	q_rrset.rrset.sections = SECTION_ANSWER;
877 
878 	if (_getdns_initialized_rrset_answer(&q_rrset))
879 		return;
880 
881 	/* No answer for the question.  Add a head for this rrset
882 	 * anyway, to validate proof of non-existance, or to find
883 	 * proof that the packet is insecure.
884 	 */
885 	debug_sec_print_rrset("Adding NX rrset: ", &q_rrset.rrset);
886 	head = add_rrset2val_chain(mf, chain_p, &q_rrset.rrset, netreq);
887 
888 	/* Insecure SOA indicating a zonecut in the authority section?
889 	 * Then schedule a DS query at the zonecut for insecure proof.
890 	 */
891 	n_soas = 0;
892 	for ( i = _getdns_rrset_iter_init(&i_spc, pkt, pkt_len
893 	                                        , SECTION_AUTHORITY)
894 	    ; i ; i = _getdns_rrset_iter_next(i)) {
895 		rrset = _getdns_rrset_iter_value(i);
896 		debug_sec_print_rrset("rrset: ", rrset);
897 
898 		if (rrset->rr_type != GETDNS_RRTYPE_SOA)
899 			continue;
900 
901 		n_soas += 1;
902 
903 		if (_getdns_rrsig_iter_init(&rrsig_spc, rrset))
904 			continue;
905 
906 		val_chain_sched_ds(head, rrset->name);
907 	}
908 	/* No answer and no SOA indicating a zonecut? Find zonecut */
909 	if (n_soas == 0)
910 		val_chain_sched_ds(head, q_rrset.rrset.name);
911 }
912 
913 
914 /*************  Schedule Queries to Provision Validation Chain ***************
915  *****************************************************************************/
916 
CD_extension(getdns_dns_req * dnsreq)917 static getdns_dict *CD_extension(getdns_dns_req *dnsreq)
918 {
919 #ifdef DNSSEC_ROADBLOCK_AVOIDANCE
920 	return !dnsreq->dnssec_roadblock_avoidance
921 	     ? dnssec_ok_checking_disabled
922 	     : !dnsreq->avoid_dnssec_roadblocks
923 	     ? dnssec_ok_checking_disabled_roadblock_avoidance
924 	     : dnssec_ok_checking_disabled_avoid_roadblocks;
925 #else
926 	(void)dnsreq;
927 	return dnssec_ok_checking_disabled;
928 #endif
929 }
930 
931 static void check_chain_complete(chain_head *chain);
932 
_dnskey_query(const chain_node * node)933 static chain_head *_dnskey_query(const chain_node *node)
934 {
935 	chain_head *head;
936 
937 	for (head = node->chains; head; head = head->next)
938 		if (head->rrset.rr_type == GETDNS_RRTYPE_DNSKEY &&
939 		    head->parent == node)
940 			return head;
941 	return NULL;
942 }
943 
944 static void val_chain_node_cb(getdns_dns_req *dnsreq);
val_chain_sched_node(chain_node * node)945 static void val_chain_sched_node(chain_node *node)
946 {
947 	getdns_context *context;
948 	getdns_eventloop *loop;
949 	char  name[1024];
950 
951 	context = node->chains->netreq->owner->context;
952 	loop    = node->chains->netreq->owner->loop;
953 
954 	if (!gldns_wire2str_dname_buf(
955 	    (UNCONST_UINT8_p)node->ds.name, 256, name, sizeof(name)))
956 		return;
957 
958 	DEBUG_SEC("schedule DS & DNSKEY lookup for %s\n", name);
959 
960 	node->lock++;
961 	if (! node->dnskey_req) {
962 		chain_head *head;
963 
964 		/* Reuse the DNSKEY query if this node is scheduled in the
965 		 * context of validating a DNSKEY query, because libunbound
966 		 * does not callback from a callback for the same query.
967 		 */
968 
969 		if ((head = _dnskey_query(node))) {
970 			DEBUG_SEC("Found DNSKEY head: %p\n", (void *)head);
971 			node->dnskey_req     = head->netreq;
972 			node->dnskey.pkt     = head->netreq->response;
973 			node->dnskey.pkt_len = head->netreq->response_len;
974 
975 		} else if (_getdns_general_loop(
976 		    context, loop, name, GETDNS_RRTYPE_DNSKEY,
977 		    CD_extension(node->chains->netreq->owner),
978 		    node, &node->dnskey_req, NULL, val_chain_node_cb))
979 
980 			node->dnskey_req     = NULL;
981 	}
982 	if (! node->ds_req && node->parent /* not root */ &&
983 	    _getdns_general_loop(context, loop, name, GETDNS_RRTYPE_DS,
984 	    CD_extension(node->chains->netreq->owner),
985 	    node, &node->ds_req, NULL, val_chain_node_cb))
986 
987 		node->ds_req = NULL;
988 
989 	if (node->lock) node->lock--;
990 }
991 
val_chain_sched(chain_head * head,const uint8_t * dname)992 static void val_chain_sched(chain_head *head, const uint8_t *dname)
993 {
994 	chain_node *node;
995 
996 	if (!head->netreq)
997 		return;
998 
999 	for ( node = head->parent
1000 	    ; node && !_dname_equal(dname, node->ds.name)
1001 	    ; node = node->parent);
1002 	if (node)
1003 		val_chain_sched_node(node);
1004 }
1005 
val_chain_sched_ds_node(chain_node * node)1006 static void val_chain_sched_ds_node(chain_node *node)
1007 {
1008 	getdns_context *context;
1009 	getdns_eventloop *loop;
1010 	char  name[1024];
1011 
1012 	context = node->chains->netreq->owner->context;
1013 	loop    = node->chains->netreq->owner->loop;
1014 
1015 	if (!gldns_wire2str_dname_buf(
1016 	    (UNCONST_UINT8_p)node->ds.name, 256, name, sizeof(name)))
1017 
1018 		return;
1019 
1020 	DEBUG_SEC("schedule DS lookup for %s\n", name);
1021 
1022 	node->lock++;
1023 	if (! node->ds_req && node->parent /* not root */ &&
1024 	    _getdns_general_loop(context, loop, name, GETDNS_RRTYPE_DS,
1025 	    CD_extension(node->chains->netreq->owner),
1026 	    node, &node->ds_req, NULL, val_chain_node_cb))
1027 
1028 		node->ds_req = NULL;
1029 
1030 	if (node->lock) node->lock--;
1031 }
1032 
val_chain_sched_ds(chain_head * head,const uint8_t * dname)1033 static void val_chain_sched_ds(chain_head *head, const uint8_t *dname)
1034 {
1035 	chain_node *node;
1036 
1037 	if (!head->netreq)
1038 		return;
1039 
1040 	for ( node = head->parent
1041 	    ; node && !_dname_equal(dname, node->ds.name)
1042 	    ; node = node->parent);
1043 	if (node)
1044 		val_chain_sched_ds_node(node);
1045 }
1046 
val_chain_sched_signer_node(chain_node * node,_getdns_rrsig_iter * rrsig)1047 static void val_chain_sched_signer_node(chain_node *node, _getdns_rrsig_iter *rrsig)
1048 {
1049 	_getdns_rdf_iter rdf_spc, *rdf;
1050 	uint8_t  signer_spc[256];
1051 	const uint8_t *signer;
1052 	size_t   signer_len;
1053 
1054 	if (!(rdf = _getdns_rdf_iter_init_at(&rdf_spc, &rrsig->rr_i, 7)))
1055 		return;
1056 
1057 	if (!(signer = _getdns_rdf_if_or_as_decompressed(
1058 	    rdf, signer_spc, &signer_len)))
1059 		return;
1060 
1061 	while (node && !_dname_equal(signer, node->ds.name))
1062 		node = node->parent;
1063 	if (node)
1064 		val_chain_sched_node(node);
1065 }
1066 
val_chain_sched_signer(chain_head * head,_getdns_rrsig_iter * rrsig)1067 static void val_chain_sched_signer(chain_head *head, _getdns_rrsig_iter *rrsig)
1068 {
1069 	if (!head->netreq)
1070 		return;
1071 
1072 	val_chain_sched_signer_node(head->parent, rrsig);
1073 }
1074 
1075 /* Cancel all DS and DNSKEY for subdomains of parent_dname,
1076  * and also the DNSKEY query at the parent_dname
1077  */
cancel_requests_for_subdomains_of(chain_head * head,const uint8_t * parent_dname)1078 static void cancel_requests_for_subdomains_of(
1079     chain_head *head, const uint8_t *parent_dname)
1080 {
1081 	chain_head *next;
1082 	chain_node *node;
1083 	size_t      node_count;
1084 
1085 	while (head) {
1086 		next = head->next;
1087 
1088 		if (!_dname_is_parent(parent_dname, head->rrset.name)) {
1089 			head = next;
1090 			continue;
1091 		}
1092 		for ( node_count = head->node_count, node = head->parent
1093 		    ; node_count
1094 		    ; node_count--, node = node->parent ) {
1095 
1096 			if (!_getdns_netreq_finished(node->dnskey_req)) {
1097 				_getdns_context_cancel_request(
1098 				    node->dnskey_req->owner);
1099 				node->dnskey_req = NULL;
1100 			}
1101 
1102 			if (_dname_equal(parent_dname, node->ds.name))
1103 				break;
1104 
1105 			if (!_getdns_netreq_finished(node->ds_req)) {
1106 				_getdns_context_cancel_request(
1107 				    node->ds_req->owner);
1108 				node->ds_req = NULL;
1109 			}
1110 		}
1111 		head = next;
1112 	}
1113 
1114 }
1115 
1116 static int nsec3_matches_name(_getdns_rrset *nsec3, const uint8_t *name);
1117 static int nsec3_covers_name(
1118     _getdns_rrset *nsec3, const uint8_t *name, int *opt_out);
1119 
insecure_delegation(_getdns_rrset * ds_rrset)1120 static int insecure_delegation(_getdns_rrset *ds_rrset)
1121 {
1122 	_getdns_rrset        nsec_rrset;
1123 	_getdns_rrtype_iter *rr, rr_spc;
1124 	_getdns_rrsig_iter   rrsig_spc;
1125 	_getdns_rdf_iter     bitmap_spc, *bitmap;
1126 	_getdns_rrset_iter  *i, i_spc;
1127 
1128 	/* For NSEC, an insecure delegation is a NODATA proof for DS */
1129 	nsec_rrset = *ds_rrset;
1130 	nsec_rrset.rr_type = GETDNS_RRTYPE_NSEC;
1131 	if (!_getdns_rrsig_iter_init(&rrsig_spc, &nsec_rrset))
1132 		; /* pass */
1133 	else for ( rr = _getdns_rrtype_iter_init(&rr_spc, &nsec_rrset)
1134 	         ; rr ; rr = _getdns_rrtype_iter_next(rr)) {
1135 
1136 		if ((bitmap = _getdns_rdf_iter_init_at( &bitmap_spc
1137 		                                      , &rr->rr_i, 1))
1138 		    &&  bitmap_has_type(bitmap, GETDNS_RRTYPE_NS)
1139 		    && !bitmap_has_type(bitmap, GETDNS_RRTYPE_DS)
1140 		    && _getdns_rrsig_iter_init(&rrsig_spc, &nsec_rrset))
1141 			return 1;
1142 	}
1143 
1144 	/* For NSEC3 it is either a NODATA proof with a delegation,
1145            or a NSEC3 opt-out coverage  */
1146 	for ( i = _getdns_rrset_iter_init(&i_spc, ds_rrset->pkt
1147 	                                        , ds_rrset->pkt_len
1148 	                                        , SECTION_NO_ADDITIONAL)
1149 	    ; i ; i = _getdns_rrset_iter_next(i)) {
1150 		_getdns_rrset *nsec3_rrset = _getdns_rrset_iter_value(i);
1151 		int opt_out;
1152 
1153 		if (  !nsec3_rrset
1154 		    || nsec3_rrset->rr_type != GETDNS_RRTYPE_NSEC3
1155 		    ||!(rr = _getdns_rrtype_iter_init(&rr_spc, nsec3_rrset)))
1156 			continue;
1157 
1158 		if (!nsec3_covers_name(nsec3_rrset, ds_rrset->name, &opt_out))
1159 			continue;
1160 
1161 		if (nsec3_matches_name(nsec3_rrset, ds_rrset->name)) {
1162 			bitmap = _getdns_rdf_iter_init_at( &bitmap_spc
1163 			                                 , &rr->rr_i, 5);
1164 			return  bitmap
1165 			    &&  bitmap_has_type(bitmap, GETDNS_RRTYPE_NS)
1166 			    && !bitmap_has_type(bitmap, GETDNS_RRTYPE_DS);
1167 		}
1168 		else if (opt_out)
1169 			return 1;
1170 	}
1171 	return 0;
1172 }
1173 
val_chain_node_cb(getdns_dns_req * dnsreq)1174 static void val_chain_node_cb(getdns_dns_req *dnsreq)
1175 {
1176 	chain_node *node = (chain_node *)dnsreq->user_pointer;
1177 	getdns_network_req *netreq = dnsreq->netreqs[0];
1178 	_getdns_rrset_iter *i, i_spc;
1179 	_getdns_rrset *rrset;
1180 	_getdns_rrsig_iter  *rrsig, rrsig_spc;
1181 	size_t n_signers;
1182 
1183 	switch (netreq->request_type) {
1184 	case GETDNS_RRTYPE_DS    : node->ds.pkt     = netreq->response;
1185 	                           node->ds.pkt_len = netreq->response_len;
1186 	                           break;
1187 	case GETDNS_RRTYPE_DNSKEY: node->dnskey.pkt     = netreq->response;
1188 	                           node->dnskey.pkt_len = netreq->response_len;
1189 		                   /* fallthrough */
1190 	default                  : check_chain_complete(node->chains);
1191 				   return;
1192 	}
1193 	node->lock++;
1194 	n_signers = 0;
1195 	for ( i = _getdns_rrset_iter_init(&i_spc, netreq->response
1196 	                                        , netreq->response_len
1197 	                                        , SECTION_NO_ADDITIONAL)
1198 	    ; i
1199 	    ; i = _getdns_rrset_iter_next(i)) {
1200 
1201 		rrset = _getdns_rrset_iter_value(i);
1202 
1203 		if (rrset->rr_type != GETDNS_RRTYPE_DS     &&
1204 		    rrset->rr_type != GETDNS_RRTYPE_NSEC   &&
1205 		    rrset->rr_type != GETDNS_RRTYPE_NSEC3)
1206 			continue;
1207 
1208 		for ( rrsig = _getdns_rrsig_iter_init(&rrsig_spc, rrset)
1209 		    ; rrsig; rrsig = _getdns_rrsig_iter_next(rrsig)) {
1210 
1211 			val_chain_sched_signer_node(node, rrsig);
1212 			n_signers++;
1213 		}
1214 	}
1215 	if (netreq->request_type != GETDNS_RRTYPE_DS)
1216 		; /* pass */
1217 	else if (n_signers) {
1218 		_getdns_rrtype_iter ds_spc;
1219 
1220 		if (_getdns_rrtype_iter_init(&ds_spc, &node->ds))
1221 			; /* pass */
1222 
1223 		else if (insecure_delegation(&node->ds)) {
1224 			debug_sec_print_rrset("Insecure delegation. "
1225 			    "Canceling requests below ", &node->ds);
1226 			cancel_requests_for_subdomains_of(
1227 			    node->chains, node->ds.name);
1228 		} else {
1229 			debug_sec_print_rrset("No DS at ", &node->ds);
1230 		}
1231 	} else {
1232 		/* No signed DS and no signed proof of non-existance.
1233 		 * Search further up the tree...
1234 		 */
1235 		val_chain_sched_ds_node(node->parent);
1236 	}
1237 	if (node->lock) node->lock--;
1238 	check_chain_complete(node->chains);
1239 }
1240 
1241 
1242 /***************************  DNSSEC Validation  *****************************
1243  *****************************************************************************/
1244 
1245 
1246 /* Returns whether a key in set dnskey is used to sign rrset.
1247  * Only keytag and signer name is compared.  The signature is not verified.
1248  */
key_matches_signer(_getdns_rrset * dnskey,_getdns_rrset * rrset)1249 static int key_matches_signer(_getdns_rrset *dnskey, _getdns_rrset *rrset)
1250 {
1251 	_getdns_rrtype_iter rr_spc, *rr;
1252 	_getdns_rrsig_iter rrsig_spc, *rrsig;
1253 	uint16_t keytag;
1254 	_getdns_rdf_iter rdf_spc, *rdf;
1255 	uint8_t signer_spc[256];
1256 	const uint8_t *signer;
1257 	size_t signer_len = sizeof(signer_spc);
1258 
1259 	assert(dnskey->rr_type == GETDNS_RRTYPE_DNSKEY);
1260 
1261 
1262 	for ( rr = _getdns_rrtype_iter_init(&rr_spc, dnskey)
1263 	    ; rr ; rr = _getdns_rrtype_iter_next(rr) ) {
1264 
1265 
1266 		/* Enough space to at least read algorithm field? */
1267 		if (rr->rr_i.nxt < rr->rr_i.rr_type + 14)
1268 			continue;
1269 
1270 		/* Then we have at least 4 bytes to calculate keytag */
1271 		keytag = gldns_calc_keytag_raw(
1272 		    (UNCONST_UINT8_p)rr->rr_i.rr_type + 10,
1273 		    rr->rr_i.nxt - rr->rr_i.rr_type - 10);
1274 
1275 		for ( rrsig = _getdns_rrsig_iter_init(&rrsig_spc, rrset)
1276 		    ; rrsig ; rrsig = _getdns_rrsig_iter_next(rrsig) ) {
1277 
1278 			if (/* Space for keytag & signer in rrsig rdata? */
1279 			       rrsig->rr_i.nxt >= rrsig->rr_i.rr_type + 28
1280 
1281 			    /* Does Algorithm match */
1282 			    && rrsig->rr_i.rr_type[12] == rr->rr_i.rr_type[13]
1283 
1284 			    /* Does the keytag match? */
1285 			    && gldns_read_uint16(rrsig->rr_i.rr_type + 26)
1286 					    == keytag
1287 
1288 			    /* Does the signer name match? */
1289 			    && (rdf = _getdns_rdf_iter_init_at(
1290 					    &rdf_spc, &rrsig->rr_i, 7))
1291 
1292 			    && (signer = _getdns_rdf_if_or_as_decompressed(
1293 					    rdf, signer_spc, &signer_len))
1294 
1295 			    && _dname_equal(dnskey->name, signer))
1296 
1297 				return keytag;
1298 		}
1299 	}
1300 	return 0;
1301 }
1302 
_rr_uncompressed_rdata_size(_getdns_rrtype_iter * rr)1303 static size_t _rr_uncompressed_rdata_size(_getdns_rrtype_iter *rr)
1304 {
1305 	_getdns_rdf_iter *rdf, rdf_spc;
1306 	uint8_t decompressed[256];
1307 	size_t sz = 0, decompressed_sz;
1308 
1309 	for ( rdf = _getdns_rdf_iter_init(&rdf_spc, &rr->rr_i)
1310 	    ; rdf
1311 	    ; rdf = _getdns_rdf_iter_next(rdf)) {
1312 
1313 		if ((rdf->rdd_pos->type & GETDNS_RDF_N_C) == GETDNS_RDF_N_C) {
1314 			decompressed_sz = sizeof(decompressed);
1315 			if (_getdns_rdf_if_or_as_decompressed(
1316 			    rdf, decompressed, &decompressed_sz))
1317 				sz += decompressed_sz;
1318 		} else
1319 			sz += rdf->nxt - rdf->pos;
1320 	}
1321 	return sz;
1322 }
1323 
_rr_rdata_size(_getdns_rrtype_iter * rr)1324 static size_t _rr_rdata_size(_getdns_rrtype_iter *rr)
1325 {
1326 	const _getdns_rr_def *rr_def;
1327 	size_t i;
1328 
1329 	rr_def = _getdns_rr_def_lookup(gldns_read_uint16(rr->rr_i.rr_type));
1330 
1331 	for (i = 0; i < rr_def->n_rdata_fields; i++)
1332 		if ((rr_def->rdata[i].type & GETDNS_RDF_N_C) == GETDNS_RDF_N_C)
1333 			return _rr_uncompressed_rdata_size(rr);
1334 
1335 	/* assert(gldns_read_uint16(rr->rr_type+8) == rr->nxt-rr->rr_type-10);
1336 	 */
1337 	return rr->rr_i.nxt - rr->rr_i.rr_type - 10;
1338 }
1339 
1340 /* Iterate byte by byte over rdata canonicalizing dname's */
1341 typedef struct canon_rdata_iter {
1342 	_getdns_rdf_iter  rdf_spc;
1343 	_getdns_rdf_iter *rdf;
1344 	uint8_t           cdname[256]; /* Canonical dname */
1345 	const uint8_t    *pos;
1346 	size_t            len;
1347 } canon_rdata_iter;
1348 
canon_rdata_iter_field_init(canon_rdata_iter * i)1349 static inline void canon_rdata_iter_field_init(canon_rdata_iter *i)
1350 {
1351 	for (;;) {
1352 		if ((i->rdf->rdd_pos->type & GETDNS_RDF_N) == GETDNS_RDF_N) {
1353 			i->len = sizeof(i->cdname);
1354 			if ((i->pos = _getdns_rdf_if_or_as_decompressed(
1355 			    i->rdf, i->cdname, &i->len))) {
1356 				_dname_canonicalize(i->pos, i->cdname);
1357 				i->pos = i->cdname;
1358 			}
1359 		} else {
1360 			i->pos = i->rdf->pos;
1361 			i->len = i->rdf->nxt - i->rdf->pos;
1362 		}
1363 		if (i->len || !(i->rdf = _getdns_rdf_iter_next(i->rdf)))
1364 			return;
1365 	}
1366 }
1367 
canon_rdata_iter_init(canon_rdata_iter * i,_getdns_rr_iter * rr)1368 static inline void canon_rdata_iter_init(canon_rdata_iter*i,_getdns_rr_iter*rr)
1369 {
1370 	if ((i->rdf = _getdns_rdf_iter_init(&i->rdf_spc, rr)))
1371 		canon_rdata_iter_field_init(i);
1372 }
1373 
canon_rdata_iter_data(canon_rdata_iter * i)1374 static inline int canon_rdata_iter_data(canon_rdata_iter *i)
1375 {
1376 	return i->rdf != NULL;
1377 }
1378 
canon_rdata_iter_byte(canon_rdata_iter * i)1379 static inline uint8_t canon_rdata_iter_byte(canon_rdata_iter *i)
1380 {
1381 	return *i->pos;
1382 }
1383 
canon_rdata_iter_next(canon_rdata_iter * i)1384 static inline void canon_rdata_iter_next(canon_rdata_iter *i)
1385 {
1386 	if (--i->len == 0 && (i->rdf = _getdns_rdf_iter_next(i->rdf)))
1387 		canon_rdata_iter_field_init(i);
1388 	else
1389 		i->pos++;
1390 }
1391 
_rr_iter_rdata_cmp(const void * a,const void * b)1392 static int _rr_iter_rdata_cmp(const void *a, const void *b)
1393 {
1394 	_getdns_rr_iter *x = (_getdns_rr_iter *)a;
1395 	_getdns_rr_iter *y = (_getdns_rr_iter *)b;
1396 
1397 	uint16_t rr_type = gldns_read_uint16(x->rr_type);
1398 	size_t x_rdata_len, y_rdata_len;
1399 	int r;
1400 
1401 	canon_rdata_iter p, q;
1402 
1403 	assert(rr_type == gldns_read_uint16(y->rr_type));
1404 
1405 	if (!_dnssec_rdata_to_canonicalize(rr_type)) {
1406 		/* Memory compare of rdata */
1407 		x_rdata_len = x->nxt - x->rr_type - 10;
1408 		y_rdata_len = y->nxt - y->rr_type - 10;
1409 		if ((r = memcmp(x->rr_type + 10, y->rr_type + 10,
1410 		    x_rdata_len < y_rdata_len ? x_rdata_len : y_rdata_len)))
1411 			return r;
1412 		return x_rdata_len < y_rdata_len ? -1 :
1413 		       x_rdata_len > y_rdata_len ?  1 : 0;
1414 	}
1415 	for ( canon_rdata_iter_init(&p, x), canon_rdata_iter_init(&q, y)
1416 	    ; canon_rdata_iter_data(&p)  && canon_rdata_iter_data(&q)
1417 	    ; canon_rdata_iter_next(&p)   , canon_rdata_iter_next(&q) ) {
1418 
1419 		if (canon_rdata_iter_byte(&p) != canon_rdata_iter_byte(&q))
1420 			return canon_rdata_iter_byte(&p) >
1421 			       canon_rdata_iter_byte(&q) ? 1 : -1;
1422 	}
1423 	return canon_rdata_iter_data(&p) ?  1
1424 	     : canon_rdata_iter_data(&q) ? -1 : 0;
1425 }
1426 
1427 /* Verifies the signature rrsig for rrset rrset with key key.
1428  * When the rrset was a wildcard expansion (rrsig labels < labels owner name),
1429  * nc_name will be set to the next closer (within rrset->name).
1430  */
1431 #define VAL_RRSET_SPC_SZ 256
_getdns_verify_rrsig(const struct mem_funcs * mf,_getdns_rrset * rrset,_getdns_rrsig_iter * rrsig,_getdns_rrtype_iter * key,const uint8_t ** nc_name)1432 static int _getdns_verify_rrsig(const struct mem_funcs *mf,
1433     _getdns_rrset *rrset, _getdns_rrsig_iter *rrsig, _getdns_rrtype_iter *key,
1434     const uint8_t **nc_name)
1435 {
1436 	int r;
1437 	int to_skip;
1438 	_getdns_rr_iter  val_rrset_spc[VAL_RRSET_SPC_SZ];
1439 	_getdns_rr_iter *val_rrset = val_rrset_spc;
1440 	_getdns_rrtype_iter rr_spc, *rr;
1441 	size_t n_rrs, i, valbuf_sz, owner_len;
1442 	_getdns_rdf_iter *signer, signer_spc, *rdf, rdf_spc;
1443 	uint8_t valbuf_spc[4096], *valbuf_buf = valbuf_spc;
1444 	uint8_t cdname_spc[256], owner[256];
1445 	const uint8_t *cdname, *owner_offset;
1446 	size_t cdname_len, pos;
1447 	uint32_t orig_ttl;
1448 	gldns_buffer valbuf;
1449 	char *reason;
1450 
1451 	/* nc_name should already have been initialized by the parent! */
1452 	assert(nc_name);
1453 	assert(!*nc_name);
1454 
1455 	if (!(signer = _getdns_rdf_iter_init_at(&signer_spc, &rrsig->rr_i, 7)))
1456 		return 0;
1457 	valbuf_sz = signer->nxt - rrsig->rr_i.rr_type - 10;
1458 
1459 	/* We were able to get the signer,
1460 	 * so the labels rdata field is definitely readable
1461 	 */
1462 	assert(rrsig->rr_i.rr_type + 14 <= rrsig->rr_i.nxt);
1463 
1464 	/* If the number of labels in the owner is larger than  "labels" rdata
1465 	 * field, then this is a wildcard expansion.
1466 	 */
1467 	if (_dname_label_count(rrset->name) > (size_t)rrsig->rr_i.rr_type[13]) {
1468 
1469 		/* This is a valid wildcard expansion.  Calculate and return the
1470 		 * "Next closer" name, because we need another NSEC to cover it.
1471 		 * (except for rrsigs for NSECs, but those are dealt with later)
1472 		 */
1473 		to_skip = (int)_dname_label_count(rrset->name)
1474 			- (int)rrsig->rr_i.rr_type[13];
1475 
1476 		for ( owner_offset = rrset->name
1477 		    ; to_skip > 0
1478 		    ; owner_offset += *owner_offset + 1, to_skip--);
1479 
1480 		if ((owner_len = _dname_len(owner_offset) + 2) > 255)
1481 			return 0;
1482 
1483 		owner[0] = 1; owner[1] = '*';
1484 		(void) memcpy(owner + 2, owner_offset, owner_len - 2);
1485 
1486 	} else if ((owner_len = _dname_len(rrset->name)) > 255)
1487 		return 0;
1488 	else
1489 		(void) memcpy(owner, rrset->name, owner_len);
1490 
1491 	_dname_canonicalize2(owner);
1492 
1493 	for (;;) {
1494 		for ( rr = _getdns_rrtype_iter_init(&rr_spc, rrset), n_rrs = 0
1495 		    ; rr
1496 		    ; rr = _getdns_rrtype_iter_next(rr), n_rrs++) {
1497 
1498 			if (val_rrset == val_rrset_spc) {
1499 				valbuf_sz += owner_len
1500 				          +  2 /* type */
1501 				          +  2 /* class */
1502 				          +  4 /* Orig TTL */
1503 					  +  2 /* Rdata len */
1504 				          +  _rr_rdata_size(rr);
1505 				if (n_rrs < VAL_RRSET_SPC_SZ)
1506 					val_rrset[n_rrs] = rr->rr_i;
1507 			} else
1508 				val_rrset[n_rrs] = rr->rr_i;
1509 		}
1510 		/* Did everything fit? Then break */
1511 		if (val_rrset != val_rrset_spc || n_rrs <= VAL_RRSET_SPC_SZ)
1512 			break;
1513 
1514 		/* More space needed for val_rrset */
1515 		val_rrset = GETDNS_XMALLOC(*mf, _getdns_rr_iter, n_rrs);
1516 	}
1517 	DEBUG_SEC( "sizes: %"PRIsz" rrs, %"PRIsz" bytes for validation buffer\n"
1518 	         , n_rrs, valbuf_sz);
1519 
1520 	qsort(val_rrset, n_rrs, sizeof(_getdns_rr_iter), _rr_iter_rdata_cmp);
1521 
1522 	if (valbuf_sz >= sizeof(valbuf_spc))
1523 		valbuf_buf = GETDNS_XMALLOC(*mf, uint8_t, valbuf_sz);
1524 
1525 	gldns_buffer_init_frm_data(&valbuf, valbuf_buf, valbuf_sz);
1526 	gldns_buffer_write(&valbuf,
1527 	    rrsig->rr_i.rr_type + 10, signer->nxt - rrsig->rr_i.rr_type - 10);
1528 	_dname_canonicalize2(gldns_buffer_at(&valbuf, 18));
1529 
1530 	orig_ttl = gldns_read_uint32(rrsig->rr_i.rr_type + 14);
1531 
1532 	if (!_dnssec_rdata_to_canonicalize(rrset->rr_type))
1533 		for (i = 0; i < n_rrs; i++) {
1534 			/* Get rid of doubles */
1535 			if (i && !_rr_iter_rdata_cmp(
1536 			    &val_rrset[i], &val_rrset[i-1]))
1537 				continue;
1538 
1539 			gldns_buffer_write(&valbuf, owner, owner_len);
1540 			gldns_buffer_write_u16(&valbuf, rrset->rr_type);
1541 			gldns_buffer_write_u16(&valbuf, rrset->rr_class);
1542 			gldns_buffer_write_u32(&valbuf, orig_ttl);
1543 			gldns_buffer_write(&valbuf, val_rrset[i].rr_type + 8,
1544 			    val_rrset[i].nxt - val_rrset[i].rr_type - 8);
1545 		}
1546 	else for (i = 0; i < n_rrs; i++) {
1547 		if (i && !_rr_iter_rdata_cmp(&val_rrset[i], &val_rrset[i-1]))
1548 			continue;
1549 		gldns_buffer_write(&valbuf, owner, owner_len);
1550 		gldns_buffer_write_u16(&valbuf, rrset->rr_type);
1551 		gldns_buffer_write_u16(&valbuf, rrset->rr_class);
1552 		gldns_buffer_write_u32(&valbuf, orig_ttl);
1553 		pos = gldns_buffer_position(&valbuf);
1554 		gldns_buffer_skip(&valbuf, 2);
1555 		for ( rdf = _getdns_rdf_iter_init(&rdf_spc, &val_rrset[i])
1556 		    ; rdf
1557 		    ; rdf = _getdns_rdf_iter_next(rdf) ) {
1558 			if (!(rdf->rdd_pos->type & GETDNS_RDF_N)) {
1559 				gldns_buffer_write(
1560 				    &valbuf, rdf->pos, rdf->nxt - rdf->pos);
1561 				continue;
1562 			}
1563 			cdname_len = sizeof(cdname);
1564 			if (!(cdname = _getdns_rdf_if_or_as_decompressed(
1565 			    rdf, cdname_spc, &cdname_len)))
1566 				continue;
1567 			gldns_buffer_write(&valbuf, cdname, cdname_len);
1568 			_dname_canonicalize2(
1569 			    gldns_buffer_current(&valbuf) - cdname_len);
1570 		}
1571 		gldns_buffer_write_u16_at(&valbuf, pos,
1572 		    (uint16_t)(gldns_buffer_position(&valbuf) - pos - 2));
1573 	}
1574 	DEBUG_SEC( "written to valbuf: %"PRIsz" bytes\n"
1575 	         , gldns_buffer_position(&valbuf));
1576 	assert(gldns_buffer_position(&valbuf) <= valbuf_sz);
1577 
1578 	gldns_buffer_flip(&valbuf);
1579 	r = _getdns_verify_canonrrset(&valbuf, key->rr_i.rr_type[13],
1580 	    (UNCONST_UINT8_p)signer->nxt, rrsig->rr_i.nxt - signer->nxt,
1581 	    (UNCONST_UINT8_p)key->rr_i.rr_type+14,
1582 	    key->rr_i.nxt - key->rr_i.rr_type-14,
1583 	    &reason);
1584 
1585 #if defined(SEC_DEBUG) && SEC_DEBUG
1586 	if (r == 0) {
1587 		DEBUG_SEC("verification failed: %s\n", reason);
1588 		debug_sec_print_dname("verification failed for: ", owner);
1589 		debug_sec_print_rrset("verification failed for rrset: ", rrset);
1590 		debug_sec_print_rr("verification failed sig: ", &rrsig->rr_i);
1591 		debug_sec_print_rr("verification failed key: ", &key->rr_i);
1592 	}
1593 #endif
1594 	if (val_rrset != val_rrset_spc)
1595 		GETDNS_FREE(*mf, val_rrset);
1596 	if (valbuf_buf != valbuf_spc)
1597 		GETDNS_FREE(*mf, valbuf_buf);
1598 	if (!r)
1599 		return 0;
1600 
1601 	/* Verification has already been done, so the labels rdata field is
1602 	 * definitely readable
1603 	 */
1604 	assert(rrsig->rr_i.rr_type + 14 <= rrsig->rr_i.nxt);
1605 
1606 	/* If the number of labels in the owner name mathes the "labels" rdata
1607 	 * field, then this was not a wildcard expansion, and everything is
1608 	 * good.
1609 	 */
1610 	if ((size_t)rrsig->rr_i.rr_type[13] == _dname_label_count(rrset->name))
1611 		return 1;
1612 
1613 	/* This is a valid wildcard expansion.  Calculate and return the
1614 	 * "Next closer" name, because we need another NSEC to cover it.
1615 	 * (except for rrsigs for NSECs, but those are dealt with later)
1616 	 */
1617 	to_skip = (int)_dname_label_count(rrset->name)
1618 		- (int)rrsig->rr_i.rr_type[13] - 1;
1619 
1620 	for ( *nc_name = rrset->name
1621 	    ; to_skip > 0
1622 	    ; *nc_name += **nc_name + 1, to_skip--);
1623 
1624 	return 1;
1625 }
1626 
1627 /* Calculates NSEC3 hash for name, and stores that into label */
_getdns_nsec3_hash_label(uint8_t * label,size_t label_len,const uint8_t * name,uint8_t algorithm,uint16_t iterations,const uint8_t * salt)1628 static uint8_t *_getdns_nsec3_hash_label(uint8_t *label, size_t label_len,
1629     const uint8_t *name, uint8_t algorithm,
1630     uint16_t iterations, const uint8_t *salt)
1631 {
1632 	uint8_t buf[512], *dst, *eob;
1633 	const uint8_t *src;
1634 	uint8_t md[SHA_DIGEST_LENGTH + 256];
1635 
1636 	assert(SHA_DIGEST_LENGTH + 256 < sizeof(buf));
1637 
1638 	if (algorithm != GLDNS_SHA1)
1639 		return NULL;
1640 
1641 	for ( src = name, dst = buf, eob = buf + sizeof(buf)
1642 	    ; *src && dst + *src < eob
1643 	    ;  src += *src + 1, dst += *dst + 1 )
1644 		_dname_label_copy(dst, src, eob - dst);
1645 
1646 	if (*src || dst + *salt >= eob)
1647 		return NULL;
1648 	*dst++ = 0;
1649 	(void)memcpy(dst, salt + 1, *salt);
1650 	dst += *salt;
1651 
1652 	_getdns_tls_sha1(buf, dst - buf, md);
1653 	if (iterations) {
1654 		(void)memcpy(buf + SHA_DIGEST_LENGTH, salt + 1, *salt);
1655 		while (iterations--) {
1656 			(void)memcpy(buf, md, SHA_DIGEST_LENGTH);
1657 			_getdns_tls_sha1(buf, SHA_DIGEST_LENGTH + *salt, md);
1658 		}
1659 	}
1660 	*label = gldns_b32_ntop_extended_hex(
1661 	    md, SHA_DIGEST_LENGTH, (char *)label + 1, label_len - 1);
1662 
1663 	return label;
1664 }
1665 
name2nsec3_label(_getdns_rrset * nsec3,const uint8_t * name,uint8_t * label,size_t label_len)1666 static uint8_t *name2nsec3_label(
1667     _getdns_rrset *nsec3, const uint8_t *name, uint8_t *label, size_t label_len)
1668 {
1669 	_getdns_rrsig_iter rrsig_spc, *rrsig;
1670 	_getdns_rdf_iter rdf_spc, *rdf;
1671 	uint8_t signer_spc[256];
1672 	const uint8_t *signer;
1673 	size_t signer_len = sizeof(signer_spc);
1674 	_getdns_rrtype_iter rr_spc, *rr;
1675 
1676 	if (/* With the "first" signature */
1677 	       (rrsig = _getdns_rrsig_iter_init(&rrsig_spc, nsec3))
1678 
1679 	    /* Access the signer name rdata field (7th) */
1680 	    && (rdf = _getdns_rdf_iter_init_at(
1681 			    &rdf_spc, &rrsig->rr_i, 7))
1682 
1683 	    /* Verify & decompress */
1684 	    && (signer = _getdns_rdf_if_or_as_decompressed(
1685 			    rdf, signer_spc, &signer_len))
1686 
1687 	    /* signer of the NSEC3 is direct parent for this NSEC3? */
1688 	    && _dname_equal(
1689 		    signer, nsec3->name + *nsec3->name + 1)
1690 
1691 	    /* signer of the NSEC3 is parent of name? */
1692 	    && _dname_is_parent(signer, name)
1693 
1694 	    /* Initialize rr for getting NSEC3 rdata fields */
1695 	    && (rr = _getdns_rrtype_iter_init(&rr_spc, nsec3))
1696 
1697 	    /* Check for available space to get rdata fields */
1698 	    && rr->rr_i.rr_type + 15 <= rr->rr_i.nxt
1699 	    && rr->rr_i.rr_type + 14 + rr->rr_i.rr_type[14] <= rr->rr_i.nxt)
1700 
1701 		/* Get the hashed label */
1702 		return _getdns_nsec3_hash_label(label, label_len, name,
1703 			    rr->rr_i.rr_type[10],
1704 			    gldns_read_uint16(rr->rr_i.rr_type + 12),
1705 			    rr->rr_i.rr_type + 14);
1706 	return NULL;
1707 }
1708 
1709 
nsec3_iteration_count_high(_getdns_rrtype_iter * dnskey,_getdns_rrset * nsec3)1710 static int nsec3_iteration_count_high(_getdns_rrtype_iter *dnskey, _getdns_rrset *nsec3)
1711 {
1712 	_getdns_rrtype_iter rr_spc, *rr;
1713 	size_t bits;
1714 
1715 	/* No NSEC3, then iteration count is not too high */
1716 	if (nsec3->rr_type != GETDNS_RRTYPE_NSEC3)
1717 		return 0;
1718 
1719 	/* Enough space to at least read algorithm field?
1720 	 * Without key data iteration count is definitely too high.
1721 	 */
1722 	if (dnskey->rr_i.nxt < dnskey->rr_i.rr_type + 14)
1723 		return 1;
1724 
1725 	if (/* Initialize rr for getting NSEC3 rdata fields */
1726 	      !(rr = _getdns_rrtype_iter_init(&rr_spc, nsec3))
1727 
1728 	    /* Check for available space to get rdata fields */
1729 	    || rr->rr_i.rr_type + 14 > rr->rr_i.nxt)
1730 		return 1;
1731 
1732 	bits = gldns_rr_dnskey_key_size_raw(dnskey->rr_i.rr_type + 10,
1733 	    dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10,
1734 	    dnskey->rr_i.rr_type[13]);
1735 
1736 	if (bits > 2048)
1737 		return gldns_read_uint16(rr->rr_i.rr_type + 12) > 2500;
1738 	else if (bits > 1024)
1739 		return gldns_read_uint16(rr->rr_i.rr_type + 12) > 500;
1740 	else
1741 		return gldns_read_uint16(rr->rr_i.rr_type + 12) > 150;
1742 }
1743 
check_dates(time_t now,int32_t skew,int32_t exp,int32_t inc)1744 static int check_dates(time_t now, int32_t skew, int32_t exp, int32_t inc)
1745 {
1746 	return (exp - inc > 0) && (inc - now < skew) && (now - exp < skew);
1747 }
1748 
1749 /* Returns whether dnskey signed rrset.  If the rrset was a valid wildcard
1750  * expansion, nc_name will point to the next closer part of the name in rrset.
1751  */
dnskey_signed_rrset(const struct mem_funcs * mf,time_t now,uint32_t skew,_getdns_rrtype_iter * dnskey,_getdns_rrset * rrset,const uint8_t ** nc_name)1752 static int dnskey_signed_rrset(const struct mem_funcs *mf, time_t now,
1753     uint32_t skew, _getdns_rrtype_iter *dnskey, _getdns_rrset *rrset,
1754     const uint8_t **nc_name)
1755 {
1756 	_getdns_rrsig_iter rrsig_spc, *rrsig;
1757 	_getdns_rdf_iter rdf_spc, *rdf;
1758 	uint8_t signer_spc[256];
1759 	const uint8_t *signer;
1760 	size_t signer_len = sizeof(signer_spc);
1761 	uint16_t keytag;
1762 
1763 	assert(dnskey->rrset->rr_type == GETDNS_RRTYPE_DNSKEY);
1764 	assert(nc_name);
1765 
1766 	*nc_name = NULL;
1767 
1768 	/* Enough space to at least read algorithm field? */
1769 	if (dnskey->rr_i.nxt < dnskey->rr_i.rr_type + 14)
1770 		return 0;
1771 
1772 	/* Then we have at least 4 bytes to calculate keytag */
1773 	keytag = gldns_calc_keytag_raw((UNCONST_UINT8_p)dnskey->rr_i.rr_type + 10,
1774 			dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10);
1775 
1776 	for ( rrsig = _getdns_rrsig_iter_init(&rrsig_spc, rrset)
1777 	    ; rrsig ; rrsig = _getdns_rrsig_iter_next(rrsig) ) {
1778 
1779 		if (/* Space for keytag & signer in rrsig rdata? */
1780 		        rrsig->rr_i.nxt >= rrsig->rr_i.rr_type + 28
1781 
1782 		    /* Does Algorithm match */
1783 		    && rrsig->rr_i.rr_type[12] == dnskey->rr_i.rr_type[13]
1784 
1785 		    /* Does the keytag match? */
1786 		    && gldns_read_uint16(rrsig->rr_i.rr_type + 26) == keytag
1787 
1788 		    /* Signature still (or already) valid? */
1789 		    && check_dates(now, skew,
1790 			    gldns_read_uint32(rrsig->rr_i.rr_type + 18),
1791 			    gldns_read_uint32(rrsig->rr_i.rr_type + 22))
1792 
1793 		    /* Does the signer name match? */
1794 		    && (rdf = _getdns_rdf_iter_init_at(
1795 				    &rdf_spc, &rrsig->rr_i, 7))
1796 
1797 		    && (signer = _getdns_rdf_if_or_as_decompressed(
1798 				    rdf, signer_spc, &signer_len))
1799 
1800 		    && _dname_equal(dnskey->rrset->name, signer)
1801 
1802 		    /* Does the signature verify? */
1803 		    && _getdns_verify_rrsig(mf, rrset,rrsig,dnskey,nc_name)) {
1804 
1805 			debug_sec_print_rr("key ", &dnskey->rr_i);
1806 			debug_sec_print_rrset("signed ", rrset);
1807 
1808 			/* Signal insecurity by too high nsec3 iteration
1809 			 * count with NSEC3_ITERATION_COUNT_HIGH
1810 			 * bit in return value.
1811 			 */
1812 			return ( nsec3_iteration_count_high(dnskey, rrset)
1813 			       ? NSEC3_ITERATION_COUNT_HIGH
1814 			       : SIGNATURE_VERIFIED
1815 			       ) | keytag;
1816 		}
1817 	}
1818 	return 0;
1819 }
1820 
1821 /* Returns whether a dnskey for keyset signed a non wildcard rrset. */
a_key_signed_rrset_no_wc(const struct mem_funcs * mf,time_t now,uint32_t skew,_getdns_rrset * keyset,_getdns_rrset * rrset)1822 static int a_key_signed_rrset_no_wc(const struct mem_funcs *mf, time_t now,
1823     uint32_t skew, _getdns_rrset *keyset, _getdns_rrset *rrset)
1824 {
1825 	_getdns_rrtype_iter dnskey_spc, *dnskey;
1826 	const uint8_t *nc_name; /* Initialized by dnskey_signed_rrset() */
1827 	int keytag;
1828 
1829 	assert(keyset->rr_type == GETDNS_RRTYPE_DNSKEY);
1830 
1831 	for ( dnskey = _getdns_rrtype_iter_init(&dnskey_spc, keyset)
1832 	    ; dnskey ; dnskey = _getdns_rrtype_iter_next(dnskey) ) {
1833 
1834 		if (!(keytag = dnskey_signed_rrset(mf, now, skew,
1835 		    dnskey, rrset, &nc_name)))
1836 			continue;
1837 
1838 		if (!nc_name) /* Not a wildcard, then success! */
1839 			return keytag;
1840 
1841  		/* Not a wildcard expansion, but the wildcard name itself. */
1842 		if (rrset->rr_type == GETDNS_RRTYPE_NSEC &&
1843 		    rrset->name[0] == 1 && rrset->name[1] == '*' &&
1844 		    nc_name == rrset->name)
1845 			return keytag;
1846 	}
1847 	return 0;
1848 }
1849 
1850 static int find_nsec_covering_name(const struct mem_funcs *mf,
1851     time_t now, uint32_t skew, _getdns_rrset *dnskey,
1852     _getdns_rrset *rrset, const uint8_t *name, int *opt_out);
1853 
1854 /* Returns whether a dnskey for keyset signed rrset. */
a_key_signed_rrset(const struct mem_funcs * mf,time_t now,uint32_t skew,_getdns_rrset * keyset,_getdns_rrset * rrset)1855 static int a_key_signed_rrset(const struct mem_funcs *mf, time_t now,
1856     uint32_t skew, _getdns_rrset *keyset, _getdns_rrset *rrset)
1857 {
1858 	_getdns_rrtype_iter dnskey_spc, *dnskey;
1859 	const uint8_t *nc_name; /* Initialized by dnskey_signed_rrset() */
1860 
1861 	int keytag;
1862 
1863 	assert(keyset->rr_type == GETDNS_RRTYPE_DNSKEY);
1864 
1865 	for ( dnskey = _getdns_rrtype_iter_init(&dnskey_spc, keyset)
1866 	    ; dnskey ; dnskey = _getdns_rrtype_iter_next(dnskey) ) {
1867 
1868 		if (!(keytag = dnskey_signed_rrset(mf, now, skew,
1869 		    dnskey, rrset, &nc_name)))
1870 			continue;
1871 
1872 		if (!nc_name) /* Not a wildcard, then success! */
1873 			return keytag;
1874 
1875 		/* Wildcard RRSIG for a NSEC on the wildcard.
1876 		 * There is no more specific!
1877 		 */
1878 		if (rrset->rr_type == GETDNS_RRTYPE_NSEC &&
1879 		    rrset->name[0] == 1 && rrset->name[1] == '*' &&
1880 		    nc_name == rrset->name)
1881 			return keytag;
1882 
1883 		debug_sec_print_rrset("wildcard expanded to: ", rrset);
1884 		debug_sec_print_dname("Find NSEC covering the more sepecific: "
1885 				, nc_name);
1886 
1887 		if (find_nsec_covering_name(
1888 		    mf, now, skew, keyset, rrset, nc_name, NULL))
1889 			return keytag;
1890 	}
1891 	return 0;
1892 }
1893 
1894 /* Returns whether a DS in ds_set matches a dnskey in dnskey_set which in turn
1895  * signed the dnskey set.
1896  */
ds_authenticates_keys(const struct mem_funcs * mf,time_t now,uint32_t skew,_getdns_rrset * ds_set,_getdns_rrset * dnskey_set)1897 static int ds_authenticates_keys(const struct mem_funcs *mf,
1898     time_t now, uint32_t skew, _getdns_rrset *ds_set, _getdns_rrset *dnskey_set)
1899 {
1900 	_getdns_rrtype_iter dnskey_spc, *dnskey;
1901 	_getdns_rrtype_iter ds_spc, *ds;
1902 	uint16_t keytag;
1903 	const uint8_t *nc_name; /* Initialized by dnskey_signed_rrset() */
1904 	size_t valid_dsses = 0, supported_dsses = 0;
1905 	uint8_t max_supported_digest = 0;
1906 	int max_supported_result = 0;
1907 	unsigned char digest_spc[256], *digest;
1908 	unsigned char digest_buf_spc[2048], *digest_buf;
1909 	size_t digest_len, digest_buf_len, dnskey_owner_len;
1910 
1911 	assert(ds_set->rr_type == GETDNS_RRTYPE_DS);
1912 	assert(dnskey_set->rr_type == GETDNS_RRTYPE_DNSKEY);
1913 
1914 	/* The ds_set is already authenticated! */
1915 
1916 	if (!_dname_equal(ds_set->name, dnskey_set->name))
1917 		return 0;
1918 
1919 	debug_sec_print_rrset("ds_authenticates_keys DS: ", ds_set);
1920 	debug_sec_print_rrset("ds_authenticates_keys DNSKEY: ", dnskey_set);
1921 
1922 	if ((dnskey_owner_len = _dname_len(dnskey_set->name)) >= 255)
1923 		return 0;
1924 
1925 	(void) memcpy(digest_buf_spc, dnskey_set->name, dnskey_owner_len);
1926 	_dname_canonicalize2(digest_buf_spc);
1927 
1928 	for ( dnskey = _getdns_rrtype_iter_init(&dnskey_spc, dnskey_set)
1929 	    ; dnskey ; dnskey = _getdns_rrtype_iter_next(dnskey)) {
1930 
1931 		/* Enough space to at least read algorithm field? */
1932 		if (dnskey->rr_i.nxt < dnskey->rr_i.rr_type + 14)
1933 			continue;
1934 
1935 		keytag = gldns_calc_keytag_raw(
1936 		    (UNCONST_UINT8_p) dnskey->rr_i.rr_type + 10,
1937 		    dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10);
1938 
1939 		for ( ds = _getdns_rrtype_iter_init(&ds_spc, ds_set)
1940 		    ; ds ; ds = _getdns_rrtype_iter_next(ds)) {
1941 
1942 			if (/* Space for keytag, algorithm & digest type? */
1943 			       ds->rr_i.nxt < ds->rr_i.rr_type + 14
1944 
1945 			    /* Does algorithm match? */
1946 			    || ds->rr_i.rr_type[12] != dnskey->rr_i.rr_type[13]
1947 
1948 			    /* Does the keytag match? */
1949 			    || gldns_read_uint16(ds->rr_i.rr_type+10)!=keytag)
1950 
1951 				continue;
1952 
1953 			valid_dsses++;
1954 
1955 			if (/* Algorithm is not RSAMD5 (deprecated) */
1956 			       ds->rr_i.rr_type[12] == GLDNS_RSAMD5
1957 
1958 			    /* Algorithm is supported */
1959 			    || !_getdns_dnskey_algo_id_is_supported(
1960 				    ds->rr_i.rr_type[12])
1961 
1962 			    /* Digest is supported */
1963 			    || !(digest_len = _getdns_ds_digest_size_supported(
1964 				    ds->rr_i.rr_type[13])))
1965 
1966 				continue;
1967 
1968 			digest = digest_len <= sizeof(digest_spc) ? digest_spc
1969 			    : GETDNS_XMALLOC(*mf, unsigned char, digest_len);
1970 
1971 			digest_buf_len = dnskey->rr_i.nxt
1972 			               - dnskey->rr_i.rr_type - 10
1973 			               + dnskey_owner_len;
1974 			digest_buf = digest_buf_len <= sizeof(digest_buf_spc)
1975 			    ? digest_buf_spc
1976 			    : GETDNS_XMALLOC(*mf, unsigned char, digest_buf_len);
1977 
1978 			if (digest_buf != digest_buf_spc)
1979 				(void) memcpy(digest_buf,
1980 				    digest_buf_spc, dnskey_owner_len);
1981 
1982 			(void) memcpy(digest_buf + dnskey_owner_len,
1983 			    dnskey->rr_i.rr_type + 10,
1984 			    dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10);
1985 
1986 			if (!_getdns_secalgo_ds_digest(ds->rr_i.rr_type[13],
1987 			    digest_buf, digest_buf_len, digest)) {
1988 
1989 				if (digest != digest_spc)
1990 					GETDNS_FREE(*mf, digest);
1991 				if (digest_buf != digest_buf_spc)
1992 					GETDNS_FREE(*mf, digest_buf);
1993 				continue;
1994 			}
1995 			supported_dsses++;
1996 
1997 			/* The result of the best digest type counts!
1998 			 * We'll assume higher is better for now.
1999 			 * So, continue with next DS if...
2000 			 */
2001 			if (/* we already had a better digest earlier */
2002 			       ds->rr_i.rr_type[13] < max_supported_digest
2003 
2004 			    /* or we had the same digest and it already gave
2005 			     * a match  (to a key in dnskey_set which
2006 			     *           authenticated the dnskey_set).
2007 			     */
2008 			    || (   ds->rr_i.rr_type[13] == max_supported_digest
2009 				&& max_supported_result)) {
2010 				if (digest != digest_spc)
2011 					GETDNS_FREE(*mf, digest);
2012 				if (digest_buf != digest_buf_spc)
2013 					GETDNS_FREE(*mf, digest_buf);
2014 
2015 				DEBUG_SEC("Better DS available\n");
2016 				continue;
2017 			}
2018 			max_supported_digest = ds->rr_i.rr_type[13];
2019 			max_supported_result = 0;
2020 
2021 			if ((int)digest_len != ds->rr_i.nxt - ds->rr_i.rr_type-14
2022 			    || memcmp(digest, ds->rr_i.rr_type+14, digest_len) != 0) {
2023 				if (digest != digest_spc)
2024 					GETDNS_FREE(*mf, digest);
2025 				if (digest_buf != digest_buf_spc)
2026 					GETDNS_FREE(*mf, digest_buf);
2027 
2028 				DEBUG_SEC("HASH length mismatch %"PRIsz" != %"PRIsz"\n",
2029 					digest_len, ds->rr_i.nxt - ds->rr_i.rr_type-14);
2030 				continue;
2031 			}
2032 			/* Match! */
2033 			if (digest != digest_spc)
2034 				GETDNS_FREE(*mf, digest);
2035 			if (digest_buf != digest_buf_spc)
2036 				GETDNS_FREE(*mf, digest_buf);
2037 
2038 			if (!dnskey_signed_rrset(mf, now, skew,
2039 			    dnskey, dnskey_set, &nc_name)
2040 			    || nc_name /* No DNSKEY's on wildcards! */) {
2041 
2042 				debug_sec_print_rrset("keyset did not "
2043 				    "authenticate: ", dnskey_set);
2044 				continue;
2045 			}
2046 			debug_sec_print_rrset(
2047 			    "keyset authenticated: ", dnskey_set);
2048 			max_supported_result = SIGNATURE_VERIFIED | keytag;
2049 		}
2050 	}
2051 	DEBUG_SEC("valid_dsses: %"PRIsz", supported_dsses: %"PRIsz"\n",
2052 			valid_dsses, supported_dsses);
2053 	if (valid_dsses && !supported_dsses)
2054 		return NO_SUPPORTED_ALGORITHMS;
2055 	else
2056 		return max_supported_result;
2057 }
2058 
nsec_covers_name(_getdns_rrset * nsec,const uint8_t * name,const uint8_t ** ce_name)2059 static int nsec_covers_name(
2060     _getdns_rrset *nsec, const uint8_t *name, const uint8_t **ce_name)
2061 {
2062 	uint8_t owner_spc[256], next_spc[256];
2063 	const uint8_t *owner, *next;
2064 	size_t owner_len = sizeof(owner_spc), next_len = sizeof(next_spc);
2065 
2066 	_getdns_rrtype_iter rr_spc, *rr;
2067 	_getdns_rdf_iter rdf_spc, *rdf;
2068 	int nsec_cmp;
2069 	const uint8_t *common1, *common2;
2070 
2071 	if (/* Get owner and next, nicely decompressed */
2072 	       !(rr = _getdns_rrtype_iter_init(&rr_spc, nsec))
2073 	    || !(rdf = _getdns_rdf_iter_init(&rdf_spc, &rr->rr_i))
2074 	    || !(owner = _getdns_owner_if_or_as_decompressed(
2075 			    &rr->rr_i, owner_spc, &owner_len))
2076 	    || !(next = _getdns_rdf_if_or_as_decompressed(
2077 			    rdf, next_spc, &next_len)))
2078 		return 0;
2079 
2080 	debug_sec_print_dname("nsec owner: ", owner);
2081 	debug_sec_print_dname("name      : ", name);
2082 	debug_sec_print_dname("nsec next : ", next);
2083 
2084 	if (ce_name) {
2085 		common1 = dname_shared_parent(name, owner);
2086 		common2 = dname_shared_parent(name, next);
2087 		*ce_name = _dname_label_count(common1)
2088 		         > _dname_label_count(common2) ? common1 : common2;
2089 		debug_sec_print_dname("nsec closest encloser: ", *ce_name);
2090 	}
2091 
2092 	nsec_cmp = dname_compare(owner, next);
2093 	if (nsec_cmp < 0) {
2094 		/* Regular NSEC
2095 		 * >= so it can match the wildcard
2096 		 * (for wildcard NODATA proofs).
2097 		 */
2098 		return dname_compare(name, owner) >= 0
2099 		    && dname_compare(name, next)  <  0;
2100 
2101 	} else if (nsec_cmp > 0) {
2102 		/* The wrap around nsec.  So NSEC->nxt == zone.name.
2103 		 * qname must be a subdomain of that.
2104 		 */
2105 		return dname_compare(name, owner) >= 0
2106 		    && _dname_is_parent(next, name) && dname_compare(next, name);
2107 
2108 	} else {
2109 		/* This nsec is the only nsec.
2110 		 * zone.name NSEC zone.name, disproves everything else,
2111 		 * but only for subdomains of that zone.
2112 		 * (also no zone.name == qname of course)
2113 		 */
2114 		return _dname_is_parent(owner, name) && dname_compare(owner, name);
2115 	}
2116 }
2117 
nsec3_matches_name(_getdns_rrset * nsec3,const uint8_t * name)2118 static int nsec3_matches_name(_getdns_rrset *nsec3, const uint8_t *name)
2119 {
2120 	uint8_t label[64], owner[64];
2121 
2122 	if (name2nsec3_label(nsec3, name, label, sizeof(label))
2123 	    && _dname_label_copy(owner, nsec3->name, sizeof(owner)))
2124 
2125 		return *nsec3->name == label[0] /* Labels same size? */
2126 		    && memcmp(owner + 1, label + 1, label[0]) == 0;
2127 
2128 	return 0;
2129 }
2130 
nsec3_covers_name(_getdns_rrset * nsec3,const uint8_t * name,int * opt_out)2131 static int nsec3_covers_name(
2132     _getdns_rrset *nsec3, const uint8_t *name, int *opt_out)
2133 {
2134 	uint8_t label[65], next[65], owner[65];
2135 	_getdns_rrtype_iter rr_spc, *rr;
2136 	_getdns_rdf_iter rdf_spc, *rdf;
2137 	int nsz = 0, nsec_cmp;
2138 
2139 	if (!name2nsec3_label(nsec3, name, label, sizeof(label)-1))
2140 		return 0;
2141 
2142 	label[label[0]+1] = 0;
2143 
2144 	if (   !(rr = _getdns_rrtype_iter_init(&rr_spc, nsec3))
2145 	    || !(rdf = _getdns_rdf_iter_init_at(&rdf_spc, &rr->rr_i, 4))
2146 	    || rdf->pos + *rdf->pos + 1 > rdf->nxt
2147 	    || (nsz = gldns_b32_ntop_extended_hex(rdf->pos + 1, *rdf->pos,
2148 		    (char *)next + 1, sizeof(next)-2)) < 0
2149 	    || *nsec3->name > sizeof(owner) - 2
2150 	    || !_dname_label_copy(owner, nsec3->name, sizeof(owner)-1)) {
2151 
2152 		DEBUG_SEC("Error getting NSEC3 owner & next labels\n");
2153 		return 0;
2154 	}
2155 	owner[owner[0]+1] = 0;
2156 	next[(next[0] = (uint8_t)nsz)+1] = 0;
2157 
2158 	if (opt_out)
2159 		*opt_out = (rr->rr_i.rr_type[11] & 1) != 0;
2160 
2161 	debug_sec_print_dname("NSEC3 for: ", name);
2162 	debug_sec_print_dname("       is: ", label);
2163 	debug_sec_print_dname("inbetween: ", owner);
2164 	debug_sec_print_dname("      and: ", next);
2165 
2166 	nsec_cmp = dname_compare(owner, next);
2167 	if (nsec_cmp >= 0) {
2168 		/* The wrap around and apex-only nsec case */
2169 		return dname_compare(label, owner) > 0
2170 		    || dname_compare(label, next) < 0;
2171 	} else {
2172 		assert(nsec_cmp < 0);
2173 		/* The normal case
2174 		 * >= so it can match the wildcard
2175 		 * (for wildcard NODATA proofs).
2176 		 */
2177 		return dname_compare(label, owner) >= 0
2178 		    && dname_compare(label, next)  <  0;
2179 	}
2180 }
2181 
find_nsec_covering_name(const struct mem_funcs * mf,time_t now,uint32_t skew,_getdns_rrset * dnskey,_getdns_rrset * rrset,const uint8_t * name,int * opt_out)2182 static int find_nsec_covering_name(const struct mem_funcs *mf, time_t now,
2183     uint32_t skew, _getdns_rrset *dnskey,
2184     _getdns_rrset *rrset, const uint8_t *name, int *opt_out)
2185 {
2186 	_getdns_rrset_iter i_spc, *i;
2187 	_getdns_rrset *n;
2188 	_getdns_rrtype_iter nsec_spc, *nsec_rr;
2189 	_getdns_rdf_iter bitmap_spc, *bitmap;
2190 	int keytag;
2191 
2192 	if (opt_out)
2193 		*opt_out = 0;
2194 
2195 	for ( i = _getdns_rrset_iter_init(&i_spc, rrset->pkt, rrset->pkt_len
2196 	                                        , SECTION_NO_ADDITIONAL)
2197 	    ; i ; i = _getdns_rrset_iter_next(i)) {
2198 
2199 		if ((n = _getdns_rrset_iter_value(i))
2200 		    && n->rr_type == GETDNS_RRTYPE_NSEC3
2201 
2202 		    /* Get the bitmap rdata field */
2203 		    && (nsec_rr = _getdns_rrtype_iter_init(&nsec_spc, n))
2204 		    && (bitmap = _getdns_rdf_iter_init_at(
2205 				    &bitmap_spc, &nsec_rr->rr_i, 5))
2206 
2207 		    && (keytag = a_key_signed_rrset_no_wc(
2208 				    mf, now, skew, dnskey, n))
2209 		    && (   keytag & NSEC3_ITERATION_COUNT_HIGH
2210 
2211 		        || (   nsec3_covers_name(n, name, opt_out)
2212 			    /* NSEC should cover, but not match name...
2213 			     * Unless it is wildcard match, but then we have to
2214 			     * check that rrset->rr_type is not enlisted,
2215 			     * because otherwise it should have matched the
2216 			     * wildcard.
2217 			     *
2218 			     * Also no CNAME... cause that should have matched too.
2219 			     */
2220 
2221 		            && (    !nsec3_matches_name(n, name)
2222 		                || (   name[0] == 1 && name[1] == (uint8_t)'*'
2223 		                    && !bitmap_has_type(bitmap, rrset->rr_type)
2224 		                    && !bitmap_has_type(bitmap,
2225 					    GETDNS_RRTYPE_CNAME)
2226 		                   )
2227 		               )
2228 		           )
2229 		       )
2230 		    ) {
2231 
2232 			debug_sec_print_rrset("NSEC3:   ", n);
2233 			debug_sec_print_dname("covered: ", name);
2234 
2235 			return keytag;
2236 		}
2237 		if ((n = _getdns_rrset_iter_value(i))
2238 		    && n->rr_type == GETDNS_RRTYPE_NSEC
2239 		    && nsec_covers_name(n, name, NULL)
2240 
2241 		    /* Get the bitmap rdata field */
2242 		    && (nsec_rr = _getdns_rrtype_iter_init(&nsec_spc, n))
2243 		    && (bitmap = _getdns_rdf_iter_init_at(
2244 				    &bitmap_spc, &nsec_rr->rr_i, 1))
2245 
2246 		    /* NSEC should cover, but not match name...
2247 		     * Unless it is wildcard match, but then we have to check
2248 		     * that rrset->rr_type is not enlisted, because otherwise
2249 		     * it should have matched the wildcard.
2250 		     *
2251 		     * Also no CNAME... cause that should have matched too.
2252 		     */
2253 		    && (    !_dname_equal(n->name, name)
2254 		        || (   name[0] == 1 && name[1] == (uint8_t)'*'
2255 		            && !bitmap_has_type(bitmap, rrset->rr_type)
2256 		            && !bitmap_has_type(bitmap, GETDNS_RRTYPE_CNAME)
2257 		           )
2258 		       )
2259 
2260 		    /* When qname is a subdomain of the NSEC owner, make
2261 		     * sure there is no DNAME, and no delegation point
2262 		     * there.
2263 		     */
2264 		    && (   !_dname_is_parent(n->name, name)
2265 		        || (   !bitmap_has_type(bitmap, GETDNS_RRTYPE_DNAME)
2266 		            && (   !bitmap_has_type(bitmap, GETDNS_RRTYPE_NS)
2267 		                ||  bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA)
2268 		               )
2269 		           )
2270 		       )
2271 
2272 		    && (keytag = a_key_signed_rrset_no_wc(
2273 					    mf, now, skew, dnskey, n))) {
2274 
2275 			debug_sec_print_rrset("NSEC:   ", n);
2276 			debug_sec_print_dname("covered: ", name);
2277 
2278 			return keytag;
2279 		}
2280 	}
2281 	return 0;
2282 }
2283 
nsec3_find_next_closer(const struct mem_funcs * mf,time_t now,uint32_t skew,_getdns_rrset * dnskey,_getdns_rrset * rrset,const uint8_t * nc_name,int * opt_out)2284 static int nsec3_find_next_closer(
2285     const struct mem_funcs *mf, time_t now, uint32_t skew,
2286     _getdns_rrset *dnskey, _getdns_rrset *rrset,
2287     const uint8_t *nc_name, int *opt_out)
2288 {
2289 	uint8_t wc_name[256] = { 1, (uint8_t)'*' };
2290 	int my_opt_out, keytag;
2291 
2292 	if (opt_out)
2293 		*opt_out = 0;
2294 
2295 	if (!(keytag = find_nsec_covering_name(
2296 	    mf, now, skew, dnskey, rrset, nc_name, &my_opt_out))) {
2297 		/* TODO: At least google doesn't return next_closer on wildcard
2298 		 * nodata for DS query.  And in fact returns even bogus for,
2299 		 * for example bladiebla.xavier.nlnet.nl DS.
2300 		 */
2301 		return 0;
2302 	}
2303 	if (opt_out)
2304 		*opt_out = my_opt_out;
2305 
2306 	/* Wild card not needed on a "covering" NODATA response,
2307 	 * because of opt-out?
2308 	 *
2309 	 * We check for opt-out bit, because rcode is unreliable...
2310 	 * ... the checked packet might be artificially constructed
2311 	 * (if we came here via getdns_validate_dnssec) in which case
2312 	 * rcode is always NOERROR.
2313 	 */
2314 	if (my_opt_out || keytag & NSEC3_ITERATION_COUNT_HIGH)
2315 		return keytag;
2316 
2317 	nc_name += *nc_name + 1;
2318 	if (_dname_len(nc_name) > sizeof(wc_name) - 2)
2319 		return 0;
2320 	else
2321 		(void) memcpy(wc_name + 2, nc_name, _dname_len(nc_name));
2322 
2323 	return find_nsec_covering_name(
2324 	    mf, now, skew, dnskey, rrset, wc_name, opt_out);
2325 }
2326 
2327 /*
2328  * Does a key from keyset dnskey prove the nonexistence of the (name, type)
2329  * tuple in rrset?
2330  *
2331  * On success returns the keytag + SIGNATURE_VERIFIED (0x10000) of the key
2332  * that signed the proof.
2333  * Or in case there were NSEC3's with too high iteration count for the
2334  * verifying key: it returns keytag + NSEC3_ITERATION_COUNT_HIGH (0x20000)
2335  */
key_proves_nonexistance(const struct mem_funcs * mf,time_t now,uint32_t skew,_getdns_rrset * keyset,_getdns_rrset * rrset,int * opt_out)2336 static int key_proves_nonexistance(
2337     const struct mem_funcs *mf, time_t now, uint32_t skew,
2338     _getdns_rrset *keyset, _getdns_rrset *rrset, int *opt_out)
2339 {
2340 	_getdns_rrset nsec_rrset, *cover, *ce;
2341 	_getdns_rrtype_iter nsec_spc, *nsec_rr;
2342 	_getdns_rdf_iter bitmap_spc, *bitmap;
2343 	_getdns_rrset_iter i_spc, *i;
2344 	const uint8_t *ce_name, *nc_name;
2345 	uint8_t wc_name[256] = { 1, (uint8_t)'*' };
2346 	int keytag;
2347 
2348 	assert(keyset->rr_type == GETDNS_RRTYPE_DNSKEY);
2349 
2350 	debug_sec_print_rrset("Commencing NX proof for: ", rrset);
2351 	if (opt_out)
2352 		*opt_out = 0;
2353 
2354 	/* The NSEC NODATA case
2355 	 * ====================
2356 	 * NSEC has same ownername as the rrset to deny.
2357 	 * Only the rr_type is missing from the bitmap.
2358 	 */
2359 	nsec_rrset = *rrset;
2360 	nsec_rrset.rr_type = GETDNS_RRTYPE_NSEC;
2361 	nsec_rrset.sections = SECTION_NO_ADDITIONAL;
2362 
2363 	if (/* A NSEC RR exists at the owner name of rrset */
2364 	      (nsec_rr = _getdns_rrtype_iter_init(&nsec_spc, &nsec_rrset))
2365 
2366 	    /* Get the bitmap rdata field */
2367 	    && (bitmap = _getdns_rdf_iter_init_at(
2368 			    &bitmap_spc, &nsec_rr->rr_i, 1))
2369 
2370 	    /* At least the rr_type of rrset should be missing from it */
2371 	    && !bitmap_has_type(bitmap, rrset->rr_type)
2372 
2373 	    /* If the name is a CNAME, then we should have gotten the CNAME,
2374 	     * So no CNAME bit either.
2375 	     */
2376 	    && !bitmap_has_type(bitmap, GETDNS_RRTYPE_CNAME)
2377 
2378 	    /* In case of a DS query, make sure we have the parent side NSEC
2379 	     * and not the child (so no SOA).
2380 	     * Except for the root that is checked by itself.
2381 	     */
2382 	    && (    rrset->rr_type != GETDNS_RRTYPE_DS
2383 	        || !bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA)
2384 		|| *rrset->name == 0
2385 	       )
2386 
2387 	    /* If not a DS query, then make sure the NSEC does not contain NS,
2388 	     * or if it does, then also contains SOA, otherwise we have a parent
2389 	     * side delegation point NSEC where we should have gotten a child
2390 	     * side NSEC!
2391 	     */
2392 	    && (    rrset->rr_type == GETDNS_RRTYPE_DS
2393 		|| !bitmap_has_type(bitmap, GETDNS_RRTYPE_NS)
2394 		||  bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA))
2395 
2396 	    /* And a valid signature please */
2397 	    && (keytag = a_key_signed_rrset_no_wc(
2398 				    mf, now, skew, keyset, &nsec_rrset))) {
2399 
2400 		/* Flag an insecure delegation via opt_out.
2401 		 * See usage of key_proves_nonexistance() from
2402 		 * chain_node_get_trusted_keys() for explanation.
2403 		 */
2404 		if (opt_out && rrset->rr_type == GETDNS_RRTYPE_DS)
2405 			*opt_out =  bitmap_has_type(bitmap, GETDNS_RRTYPE_NS)
2406 			        && !bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA);
2407 
2408 		debug_sec_print_rrset("NSEC NODATA proof for: ", rrset);
2409 		return keytag;
2410 	}
2411 	/* More NSEC NODATA cases
2412 	 * ======================
2413 	 * There are a few NSEC NODATA cases where qname doesn't match
2414 	 * NSEC->name:
2415 	 *
2416 	 * - An empty non terminal (ENT) will result in a NSEC covering the
2417 	 *   qname, where qname > NSEC->name and ce(qname) is parent of NXT.
2418 	 *   This case is handled below after the covering NSEC is found.
2419 	 *
2420 	 * - Or a wildcard match without the type.  The wildcard owner name
2421 	 *   match has special handing in the find_nsec_covering_name function.
2422 	 *   We still expect a NSEC covering the name though.
2423 	 */
2424 
2425 	/* The NSEC Name error case
2426 	 * ========================
2427 	 * - First find the NSEC that covers the owner name.
2428 	 */
2429 	for ( i = _getdns_rrset_iter_init(&i_spc, rrset->pkt, rrset->pkt_len
2430 	                                        , SECTION_NO_ADDITIONAL)
2431 	    ; i ; i = _getdns_rrset_iter_next(i)) {
2432 
2433 		cover = _getdns_rrset_iter_value(i);
2434 
2435 		if (/* Is cover an NSEC rrset? */
2436 		       cover->rr_type != GETDNS_RRTYPE_NSEC
2437 
2438 		    /* Does it cover the name */
2439 		    || !nsec_covers_name(cover, rrset->name, &ce_name)
2440 
2441 		    /* But not a match (because that would be NODATA case) */
2442 		    || _dname_equal(cover->name, rrset->name)
2443 
2444 		    /* Get the bitmap rdata field */
2445 		    || !(nsec_rr = _getdns_rrtype_iter_init(&nsec_spc, cover))
2446 		    || !(bitmap = _getdns_rdf_iter_init_at(
2447 				    &bitmap_spc, &nsec_rr->rr_i, 1))
2448 
2449 		    /* When qname is a subdomain of the NSEC owner, make
2450 		     * sure there is no DNAME, and no delegation point
2451 		     * there.
2452 		     */
2453 		    || (   _dname_is_parent(cover->name, rrset->name)
2454 		        && (   bitmap_has_type(bitmap, GETDNS_RRTYPE_DNAME)
2455 		            || (    bitmap_has_type(bitmap, GETDNS_RRTYPE_NS)
2456 		                && !bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA)
2457 		               )
2458 		           )
2459 		       )
2460 
2461 		    /* And a valid signature please (as always) */
2462 		    || !(keytag = a_key_signed_rrset_no_wc(
2463 					    mf, now, skew, keyset, cover)))
2464 			continue;
2465 
2466 		/* We could have found a NSEC covering an Empty Non Terminal.
2467 		 * In that case no NSEC covering the wildcard is needed.
2468 		 * Because it was actually a NODATA proof.
2469 		 *
2470 		 * Empty NON terminals can be identified, by
2471 		 * qname > NSEC->name && NSEC->nxt is subdomain of qname.
2472 		 *
2473 		 * nsec_covers_name() will set ce_name to qname when NSEC->nxt
2474 		 * is a subdomain of qname.
2475 		 */
2476 		if (   dname_compare(rrset->name, cover->name) > 0
2477 		    && dname_compare(rrset->name, ce_name) == 0) {
2478 
2479 			debug_sec_print_dname("Empty Non Terminal: ", ce_name);
2480 			return keytag;
2481 		}
2482 
2483 		debug_sec_print_dname("Closest Encloser: ", ce_name);
2484 
2485 		if (_dname_len(ce_name) > sizeof(wc_name) - 2)
2486 			return 0;
2487 		else
2488 			(void) memcpy(wc_name+2, ce_name, _dname_len(ce_name));
2489 
2490 		debug_sec_print_dname("        Wildcard: ", wc_name);
2491 
2492 		return find_nsec_covering_name(
2493 		    mf, now, skew, keyset, rrset, wc_name, NULL);
2494 	}
2495 
2496 	/* The NSEC3 NODATA case
2497 	 * =====================
2498 	 * NSEC3 has same (hashed) ownername as the rrset to deny.
2499 	 */
2500 	for ( i = _getdns_rrset_iter_init(&i_spc, rrset->pkt, rrset->pkt_len
2501 	                                        , SECTION_NO_ADDITIONAL)
2502 	    ; i ; i = _getdns_rrset_iter_next(i)) {
2503 
2504 		/* ce is potentially the NSEC3 that matches complete qname
2505 		 * (so is also the closest encloser)
2506 		 */
2507 		ce = _getdns_rrset_iter_value(i);
2508 		if (    ce->rr_type == GETDNS_RRTYPE_NSEC3
2509 
2510 		    /* A NSEC3 RR exists at the owner name of rrset
2511 		     * (this is always true)
2512 		     */
2513 		    && (nsec_rr = _getdns_rrtype_iter_init(&nsec_spc, ce))
2514 
2515 		    /* Get the bitmap rdata field */
2516 		    && (bitmap = _getdns_rdf_iter_init_at(
2517 				    &bitmap_spc, &nsec_rr->rr_i, 5))
2518 
2519 		    /* At least the rr_type of rrset should be missing */
2520 		    && !bitmap_has_type(bitmap, rrset->rr_type)
2521 
2522 		    /* If the name is a CNAME, then we should have gotten it,
2523 		     * So no CNAME bit either.
2524 		     */
2525 		    && !bitmap_has_type(bitmap, GETDNS_RRTYPE_CNAME)
2526 
2527 		    /* In case of a DS query, make sure we have the parent side
2528 		     * NSEC and not the child (so no SOA).
2529 		     * (except for the root...)
2530 		     */
2531 		    && (    rrset->rr_type != GETDNS_RRTYPE_DS
2532 			|| !bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA)
2533 		        || *rrset->name == 0
2534 		       )
2535 
2536 		    /* If not a DS query, then make sure the NSEC does not
2537 		     * contain NS, or if it does, then also contains SOA,
2538 		     * otherwise we have a parent side delegation point NSEC
2539 		     * where we should have gotten a child side NSEC!
2540 		     */
2541 		    && (    rrset->rr_type == GETDNS_RRTYPE_DS
2542 			|| !bitmap_has_type(bitmap, GETDNS_RRTYPE_NS)
2543 			||  bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA))
2544 
2545 		    /* It must have a valid signature */
2546 		    && (keytag = a_key_signed_rrset_no_wc(
2547 					    mf, now, skew, keyset, ce))
2548 
2549 		    /* The qname must match the NSEC3 */
2550 		    && (   keytag & NSEC3_ITERATION_COUNT_HIGH
2551 		        || nsec3_matches_name(ce, rrset->name))) {
2552 
2553 			/* Flag an insecure delegation via opt_out.
2554 			 * See usage of key_proves_nonexistance() from
2555 			 * chain_node_get_trusted_keys() for explanation.
2556 			 */
2557 			if (opt_out && rrset->rr_type == GETDNS_RRTYPE_DS)
2558 				*opt_out =
2559 				    bitmap_has_type(bitmap, GETDNS_RRTYPE_NS)
2560 				&& !bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA);
2561 
2562 			debug_sec_print_rrset("NSEC3 No Data for: ", rrset);
2563 			return keytag;
2564 		}
2565 	}
2566 	/* More NSEC3 NODATA cases
2567 	 * ======================
2568 	 * There are a few NSEC NODATA cases where qname doesn't match
2569 	 * NSEC->name:
2570 	 *
2571 	 * - NSEC3 ownername match for qtype == NSEC3 (TODO?)
2572 	 * - Wildcard NODATA (wildcard owner name match has special handing
2573 	 *                    find_nsec_covering_name())
2574 	 */
2575 
2576 	/* The NSEC3 Name error case
2577 	 * ========================+
2578 	 * First find the closest encloser.
2579 	 */
2580 	if (*rrset->name)
2581 	for ( nc_name = rrset->name, ce_name = rrset->name + *rrset->name + 1
2582 	    ; *ce_name ; nc_name = ce_name, ce_name += *ce_name + 1) {
2583 
2584 		for ( i = _getdns_rrset_iter_init(&i_spc, rrset->pkt, rrset->pkt_len
2585 		                                        , SECTION_NO_ADDITIONAL)
2586 		    ; i ; i = _getdns_rrset_iter_next(i)) {
2587 
2588 			if (   !(ce = _getdns_rrset_iter_value(i))
2589 			    || ce->rr_type != GETDNS_RRTYPE_NSEC3
2590 
2591 			    /* Get the bitmap rdata field */
2592 			    || !(nsec_rr = _getdns_rrtype_iter_init(&nsec_spc, ce))
2593 			    || !(bitmap = _getdns_rdf_iter_init_at(
2594 					    &bitmap_spc, &nsec_rr->rr_i, 1))
2595 
2596 			    /* No DNAME or delegation point at the closest
2597 			     * encloser.
2598 			     *
2599 			     * TODO: Ask Wouter
2600 			     * Unbound val_nsec3:1024 finishes insecurely
2601 			     * here (instead of bogus) when DS is also missing.
2602 			     * Should we not have followed the delegation then
2603 			     * too?
2604 			     * The NSEC could come from a parent zone!
2605 			     *
2606 			     */
2607 			    || bitmap_has_type(bitmap, GETDNS_RRTYPE_DNAME)
2608 			    || (    bitmap_has_type(bitmap, GETDNS_RRTYPE_NS)
2609 			        && !bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA)
2610 			       )
2611 
2612 			    || !(keytag = a_key_signed_rrset_no_wc(
2613 						    mf, now, skew, keyset, ce))
2614 			    || (   !(keytag & NSEC3_ITERATION_COUNT_HIGH)
2615 			        && !nsec3_matches_name(ce, ce_name)))
2616 				continue;
2617 
2618 			debug_sec_print_rrset("Closest Encloser: ", ce);
2619 			debug_sec_print_dname("Closest Encloser: ", ce_name);
2620 			debug_sec_print_dname("     Next closer: ", nc_name);
2621 
2622 			if (    keytag & NSEC3_ITERATION_COUNT_HIGH
2623 			    || (keytag = nsec3_find_next_closer(mf, now, skew,
2624 					    keyset, rrset, nc_name, opt_out)))
2625 
2626 				return keytag;
2627 		}
2628 	}
2629 	return 0;
2630 }
2631 
2632 /* Ascend up to the root along chain_nodes.  Try to find a keyset
2633  * authenticated by a key in ta rrset (trust anchor).  When we found one,
2634  * descend back down, authenticating more specific keysets along the chain.
2635  *
2636  * The most specific keyset is returned in keys.  Also a DNSSEC status is
2637  * returned.  BOGUS if no keyset could be found.  INSECURE if the
2638  * non-existence of a DS along the path is proofed, and SECURE otherwise.
2639  */
chain_node_get_trusted_keys(const struct mem_funcs * mf,time_t now,uint32_t skew,chain_node * node,_getdns_rrset * ta,_getdns_rrset ** keys)2640 static int chain_node_get_trusted_keys(
2641     const struct mem_funcs *mf, time_t now, uint32_t skew,
2642     chain_node *node, _getdns_rrset *ta, _getdns_rrset **keys)
2643 {
2644 	int s, keytag;
2645 	int opt_out;
2646 
2647 	/* Ascend up to the root */
2648 	if (! node)
2649 		return GETDNS_DNSSEC_BOGUS;
2650 
2651 	else if (ta->rr_type == GETDNS_RRTYPE_DS) {
2652 
2653 		if ((keytag = ds_authenticates_keys(
2654 		    mf, now, skew, ta, &node->dnskey))) {
2655 			*keys = &node->dnskey;
2656 			node->dnskey_signer = keytag;
2657 			return keytag & NO_SUPPORTED_ALGORITHMS
2658 			     ? GETDNS_DNSSEC_INSECURE
2659 			     : GETDNS_DNSSEC_SECURE;
2660 		}
2661 
2662 	} else if (ta->rr_type == GETDNS_RRTYPE_DNSKEY) {
2663 
2664 		/* ta is KSK */
2665 		if ((keytag = a_key_signed_rrset_no_wc(
2666 		    mf, now, skew, ta, &node->dnskey))) {
2667 			*keys = &node->dnskey;
2668 			node->dnskey_signer = keytag;
2669 			return GETDNS_DNSSEC_SECURE;
2670 		}
2671 		/* ta is the DNSKEY for this name? */
2672 		if (_dname_equal(ta->name, node->dnskey.name)) {
2673 			*keys = ta;
2674 			return GETDNS_DNSSEC_SECURE;
2675 		}
2676 		/* ta is parent's ZSK proving insecurity below this node? */
2677 		if ((keytag = key_proves_nonexistance(
2678 		    mf, now, skew, ta, &node->ds, &opt_out))) {
2679 			node->ds_signer = keytag;
2680 
2681 			/* When the proof is in an opt_out span, result will
2682 			 * be INSECURE regardless the purpose of the searched
2683 			 * for key.
2684 			 *
2685 			 * Otherwise, INSECURE only when this is a zonecut.
2686 			 * i.e. a NODATA proof, with the NS bit and no SOA bit.
2687 			 *
2688 			 * key_proves_nonexistance() will set opt_out also for
2689 			 * these conditions.
2690 			 */
2691 			if (opt_out)
2692 				return GETDNS_DNSSEC_INSECURE;
2693 
2694 			/* If this is not an insecurity proof,
2695 			 * continue searching one label up.
2696 			 */
2697 
2698 		/* ta is parent's ZSK authenticating DS? */
2699 		} else if ((keytag = a_key_signed_rrset_no_wc(
2700 					mf, now, skew, ta, &node->ds))) {
2701 			node->ds_signer = keytag;
2702 			/* DS should authenticate the DNSKEY rrset now */
2703 			if ((keytag = ds_authenticates_keys(
2704 			    mf, now, skew, &node->ds, &node->dnskey))) {
2705 				*keys = &node->dnskey;
2706 				node->dnskey_signer = keytag;
2707 				return keytag & NO_SUPPORTED_ALGORITHMS
2708 				     ? GETDNS_DNSSEC_INSECURE
2709 				     : GETDNS_DNSSEC_SECURE;
2710 			}
2711 			/* DS without DNSKEY rrset == BOGUS */
2712 			return GETDNS_DNSSEC_BOGUS;
2713 		}
2714 	} else
2715 		return GETDNS_DNSSEC_BOGUS;
2716 
2717 	s = chain_node_get_trusted_keys(mf, now, skew, node->parent, ta, keys);
2718 	/* Set dnssec status on root DNSKEY request (for TA management) */
2719 	if (!node->parent && node->dnskey_req &&
2720 	     node->dnskey.name && *node->dnskey.name == 0)
2721 		node->dnskey_req->dnssec_status = s;
2722 
2723 	if (s != GETDNS_DNSSEC_SECURE)
2724 		return s;
2725 
2726 	/* keys is an authenticated dnskey rrset always now (i.e. ZSK) */
2727 	ta = *keys;
2728 	/* Back down to the head */
2729 	/*************************/
2730 	if ((keytag = key_proves_nonexistance(
2731 	    mf, now, skew, ta, &node->ds, &opt_out))) {
2732 		node->ds_signer = keytag;
2733 
2734 		/* When the proof is in an opt_out span, result will be
2735 		 * INSECURE regardless the purpose of the searched for key.
2736 		 *
2737 		 * Otherwise, INSECURE only when this is a zonecut.
2738 		 * i.e. a NODATA proof, with the NS bit, but no SOA bit.
2739 		 *
2740 		 * key_proves_nonexistance() will set opt_out also for these
2741 		 * conditions. (NODATA of DS with NS bit and wihout SOA bit)
2742 		 */
2743 		return opt_out ? GETDNS_DNSSEC_INSECURE
2744 		               : GETDNS_DNSSEC_SECURE;
2745 	}
2746 	if (key_matches_signer(ta, &node->ds)) {
2747 
2748 		if ((node->ds_signer = a_key_signed_rrset_no_wc(
2749 						mf, now, skew, ta, &node->ds))
2750 		   && (keytag = ds_authenticates_keys(
2751 				mf, now, skew, &node->ds, &node->dnskey))){
2752 
2753 			*keys = &node->dnskey;
2754 			node->dnskey_signer = keytag;
2755 			return keytag & NO_SUPPORTED_ALGORITHMS
2756 			     ? GETDNS_DNSSEC_INSECURE
2757 			     : GETDNS_DNSSEC_SECURE;
2758 		}
2759 		return GETDNS_DNSSEC_BOGUS;
2760 	}
2761 	/* If we are on a zone cut, we must return BOGUS, because there should
2762 	 * have been a more specific DS set.  We can be sure of a zone cut if
2763 	 * a request for the DSset was sent (because they are done only for
2764 	 * signer names and when there was a SOA) or if we do have a DS,
2765 	 * but not signed with a current trusted key.
2766 	 *
2767 	 * For the getdns_validate_dnssec case, we must make sure to insert
2768 	 * an empty DS for this name in the validation chain... so it can
2769 	 * be used for the support_records parameter.
2770 	 */
2771 	if (node->ds_req || _getdns_rrset_has_rrs(&node->ds))
2772 		return GETDNS_DNSSEC_BOGUS;
2773 
2774 	/* Not at a zone cut, the trusted keyset must be authenticating
2775 	 * something below (closer to head) this node.
2776 	 */
2777 	return GETDNS_DNSSEC_SECURE;
2778 }
2779 
2780 /* The DNSSEC status of the rrset of head is evaluated with trust anchor ta.
2781  * For this first a secure keyset is looked up, with which the keyset is
2782  * evaluated.
2783  */
chain_head_validate_with_ta(const struct mem_funcs * mf,time_t now,uint32_t skew,chain_head * head,_getdns_rrset * ta)2784 static int chain_head_validate_with_ta(const struct mem_funcs *mf,
2785     time_t now, uint32_t skew, chain_head *head, _getdns_rrset *ta)
2786 {
2787 	_getdns_rrset *keys;
2788 	int s, keytag, opt_out;
2789 
2790 	_getdns_rrtype_iter nsec_spc, *nsec_rr;
2791 	_getdns_rdf_iter bitmap_spc, *bitmap;
2792 	chain_node *parent;
2793 
2794 	debug_sec_print_rrset("Validating ", &head->rrset);
2795 	debug_sec_print_rrset("\twith trust anchor ", ta);
2796 
2797 	/* A DS is never at the apex */
2798 	if (   head->rrset.rr_type == GETDNS_RRTYPE_DS
2799 	    && head->parent->parent)
2800 		parent = head->parent->parent;
2801 
2802 	/* Only at the apex, a NSEC is signed with a DNSKEY with the same
2803 	 * owner name.  All other are signed by the parent domain or higher.
2804 	 * Besides a shortcut, choosing to search for a trusted key from the
2805 	 * parent is essential for NSECs at a delagation point! (which would
2806 	 * otherwise turn out BOGUS).
2807 	 */
2808 	else if (head->rrset.rr_type == GETDNS_RRTYPE_NSEC
2809 	    &&  head->parent->parent
2810 	    && (nsec_rr = _getdns_rrtype_iter_init(&nsec_spc, &head->rrset))
2811 	    && (bitmap = _getdns_rdf_iter_init_at(
2812 			    &bitmap_spc, &nsec_rr->rr_i, 1))
2813 	    && !bitmap_has_type(bitmap, GETDNS_RRTYPE_SOA))
2814 		parent = head->parent->parent;
2815 
2816 	/* NSEC3 is always signed by the parent domain!
2817 	 * ( the ownername of the NSEC3 itself is not in the original zone!
2818 	 *   so a search for a trusted key at that name gives either INSECURE
2819 	 *   (with opt-out) or BOGUS! )
2820 	 */
2821 	else if (head->rrset.rr_type == GETDNS_RRTYPE_NSEC3
2822 	    && head->parent->parent)
2823 		parent = head->parent->parent;
2824 	else
2825 		parent = head->parent;
2826 
2827 	if ((s = chain_node_get_trusted_keys(
2828 	    mf, now, skew, parent, ta, &keys)) != GETDNS_DNSSEC_SECURE) {
2829 		debug_sec_print_rrset("Could not get trusted keys "
2830 		                      "for validating ", &head->rrset);
2831 		DEBUG_SEC("\tstatus: %d\n", (int)s);
2832 		return s;
2833 	}
2834 	debug_sec_print_rrset("Validating ", &head->rrset);
2835 	debug_sec_print_rrset("\twith keys ", keys);
2836 
2837 	if (_getdns_rrset_has_rrs(&head->rrset)) {
2838 		if ((keytag = a_key_signed_rrset(
2839 		    mf, now, skew, keys, &head->rrset))) {
2840 			DEBUG_SEC("Key %d proved\n", (int)keytag);
2841 			debug_sec_print_rrset("\tSECURE: ", &head->rrset);
2842 			head->signer = keytag;
2843 			return GETDNS_DNSSEC_SECURE;
2844 
2845 		} else if (!_getdns_rrset_has_rrsigs(&head->rrset)
2846 				&& (keytag = key_proves_nonexistance(mf, now,
2847 					skew, keys, &head->rrset, &opt_out))
2848 				&& opt_out) {
2849 
2850 			DEBUG_SEC("Key %d proved (optout)\n", (int)keytag);
2851 			debug_sec_print_rrset("\tINSECURE: ", &head->rrset);
2852 			head->signer = keytag;
2853 			return GETDNS_DNSSEC_INSECURE;
2854 		}
2855 	} else if ((keytag = key_proves_nonexistance(mf, now, skew,
2856 					keys, &head->rrset, &opt_out))) {
2857 		DEBUG_SEC("Key %d proved (NX)\n", (int)keytag);
2858 		debug_sec_print_rrset("\tSECURE: ", &head->rrset);
2859 		head->signer = keytag;
2860 		return opt_out || (keytag & NSEC3_ITERATION_COUNT_HIGH)
2861 		     ? GETDNS_DNSSEC_INSECURE : GETDNS_DNSSEC_SECURE;
2862 	}
2863 	debug_sec_print_rrset("BOGUS: ", &head->rrset);
2864 	debug_sec_print_rrset("\twith trust anchor: ", ta);
2865 	return GETDNS_DNSSEC_BOGUS;
2866 }
2867 
2868 /* The DNSSEC status of the rrset in head is evaluated by trying the trust
2869  * anchors in tas in turn.  The best outcome counts.
2870  */
chain_head_validate(const struct mem_funcs * mf,time_t now,uint32_t skew,chain_head * head,_getdns_rrset_iter * tas)2871 static int chain_head_validate(const struct mem_funcs *mf, time_t now,
2872     uint32_t skew, chain_head *head, _getdns_rrset_iter *tas)
2873 {
2874 	_getdns_rrset_iter *i;
2875 	_getdns_rrset *ta, dnskey_ta, ds_ta;
2876 	_getdns_rrset_iter closest_ta;
2877 	int closest_labels, s = GETDNS_DNSSEC_INDETERMINATE;
2878 	size_t ta_labels, supported_algorithms;
2879 	_getdns_rrtype_iter rr_spc, *rr;
2880 
2881 	/* Find the TA closest to the head's RRset name */
2882 	closest_labels = -1;
2883 	for (i = _getdns_rrset_iter_rewind(tas); i ;i = _getdns_rrset_iter_next(i)) {
2884 		ta = _getdns_rrset_iter_value(i);
2885 
2886 		if ((ta->rr_type == GETDNS_RRTYPE_DNSKEY ||
2887 		     ta->rr_type == GETDNS_RRTYPE_DS)
2888 		    && _dname_is_parent(ta->name, head->rrset.name)
2889 		    && (int)(ta_labels = _dname_label_count(ta->name))
2890 		                       > closest_labels ) {
2891 
2892 			closest_labels = (int)ta_labels;
2893 			closest_ta = *i;
2894 			if (i->rrset.name == i->name_spc)
2895 				closest_ta.rrset.name = closest_ta.name_spc;
2896 		}
2897 	}
2898 	DEBUG_SEC("closest labels for TA: %d\n", closest_labels);
2899 	if (closest_labels == -1)
2900 		return GETDNS_DNSSEC_INDETERMINATE;
2901 
2902 	ta = _getdns_rrset_iter_value(&closest_ta);
2903 	dnskey_ta = *ta;
2904 	dnskey_ta.rr_type = GETDNS_RRTYPE_DNSKEY;
2905 	ds_ta = *ta;
2906 	ds_ta.rr_type = GETDNS_RRTYPE_DS;
2907 
2908 	if (!_getdns_rrset_has_rrs(&dnskey_ta))
2909 		return chain_head_validate_with_ta(mf,now,skew,head,&ds_ta);
2910 
2911 	/* Does the selected DNSKEY set have supported algorithms? */
2912 	supported_algorithms = 0;
2913 	for ( rr = _getdns_rrtype_iter_init(&rr_spc, ta)
2914 	    ; rr; rr = _getdns_rrtype_iter_next(rr)) {
2915 
2916 		if (   rr->rr_i.rr_type + 14 <= rr->rr_i.nxt
2917 		    && _getdns_dnskey_algo_id_is_supported(
2918 			    rr->rr_i.rr_type[13]))
2919 
2920 			supported_algorithms++;
2921 	}
2922 	if (!supported_algorithms) {
2923 		if (_getdns_rrset_has_rrs(&ds_ta))
2924 			return chain_head_validate_with_ta(
2925 			    mf, now, skew, head, &ds_ta);
2926 
2927 		return GETDNS_DNSSEC_INSECURE;
2928 	}
2929 	s = chain_head_validate_with_ta(mf, now, skew, head, &dnskey_ta);
2930 	if (_getdns_rrset_has_rrs(&ds_ta)) {
2931 		switch (chain_head_validate_with_ta(mf,now,skew,head,&ds_ta)) {
2932 		case GETDNS_DNSSEC_SECURE  : s = GETDNS_DNSSEC_SECURE;
2933 		                             /* fallthrough */
2934 		case GETDNS_DNSSEC_INSECURE: if (s != GETDNS_DNSSEC_SECURE)
2935 						     s = GETDNS_DNSSEC_INSECURE;
2936 					     break;
2937 		case GETDNS_DNSSEC_BOGUS   : if (s != GETDNS_DNSSEC_SECURE &&
2938 						 s != GETDNS_DNSSEC_INSECURE)
2939 						     s = GETDNS_DNSSEC_BOGUS;
2940 					     break;
2941 		default                    : break;
2942 		}
2943 	}
2944 	return s;
2945 }
2946 
2947 /* The DNSSEC status of the network requests which constructed the chain is
2948  * evaluated by processing each head in turn.  The worst outcome per network request
2949  * is the dnssec status for that network request.
2950  */
2951 #ifdef STUB_NATIVE_DNSSEC
chain_set_netreq_dnssec_status(chain_head * chain,_getdns_rrset_iter * tas)2952 static void chain_set_netreq_dnssec_status(chain_head *chain, _getdns_rrset_iter *tas)
2953 {
2954 	chain_head *head;
2955 
2956 	/* The netreq status is the worst for any head */
2957 	for (head = chain; head; head = head->next) {
2958 		if (!head->netreq)
2959 			continue;
2960 
2961 		switch (chain_head_validate(priv_getdns_context_mf(
2962 		    head->netreq->owner->context), time(NULL),
2963 		    head->netreq->owner->context->dnssec_allowed_skew,
2964 		    head, tas)) {
2965 
2966 		case GETDNS_DNSSEC_SECURE:
2967 			if (head->netreq->dnssec_status ==
2968 			    GETDNS_DNSSEC_INDETERMINATE)
2969 				head->netreq->dnssec_status =
2970 				    GETDNS_DNSSEC_SECURE;
2971 			break;
2972 
2973 		case GETDNS_DNSSEC_INSECURE:
2974 			if (head->netreq->dnssec_status != GETDNS_DNSSEC_BOGUS)
2975 				head->netreq->dnssec_status =
2976 					GETDNS_DNSSEC_INSECURE;
2977 			break;
2978 
2979 		case GETDNS_DNSSEC_BOGUS :
2980 			head->netreq->dnssec_status = GETDNS_DNSSEC_BOGUS;
2981 			break;
2982 
2983 		default:
2984 			break;
2985 		}
2986 	}
2987 }
2988 
chain_clear_netreq_dnssec_status(chain_head * chain)2989 static void chain_clear_netreq_dnssec_status(chain_head *chain)
2990 {
2991 	chain_head *head;
2992 	size_t      node_count;
2993 	chain_node *node;
2994 
2995 	/* The netreq status is the worst for any head */
2996 	for (head = chain; head; head = head->next) {
2997 		if (!head->netreq)
2998 			continue;
2999 
3000 		head->netreq->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
3001 		for ( node_count = head->node_count, node = head->parent
3002 		    ; node && node_count ; node_count--, node = node->parent ) {
3003 
3004 			node->ds_signer = -1;
3005 			node->dnskey_signer = -1;
3006 
3007 			if ( ! node->parent && node->dnskey_req
3008 			    && node->dnskey.name && !*node->dnskey.name) {
3009 				node->dnskey_req->dnssec_status =
3010 				    GETDNS_DNSSEC_INDETERMINATE;
3011 			}
3012 		}
3013 	}
3014 }
3015 #endif
3016 
3017 /* The DNSSEC status of all heads for a chain structure is evaluated by
3018  * processing each head in turn.  The worst outcome is the dnssec status for
3019  * the whole.
3020  */
chain_validate_dnssec(const struct mem_funcs * mf,time_t now,uint32_t skew,chain_head * chain,_getdns_rrset_iter * tas)3021 static int chain_validate_dnssec(const struct mem_funcs *mf,
3022     time_t now, uint32_t skew, chain_head *chain, _getdns_rrset_iter *tas)
3023 {
3024 	int s = GETDNS_DNSSEC_INDETERMINATE, t;
3025 	chain_head *head;
3026 
3027 	/* The netreq status is the worst for any head */
3028 	for (head = chain; head; head = head->next) {
3029 		t = chain_head_validate(mf, now, skew, head, tas);
3030 		switch (t) {
3031 		case GETDNS_DNSSEC_SECURE:
3032 			if (s == GETDNS_DNSSEC_INDETERMINATE)
3033 				s = GETDNS_DNSSEC_SECURE;
3034 			break;
3035 
3036 		case GETDNS_DNSSEC_INSECURE:
3037 			if (s != GETDNS_DNSSEC_BOGUS)
3038 				s = GETDNS_DNSSEC_INSECURE;
3039 			break;
3040 
3041 		case GETDNS_DNSSEC_BOGUS :
3042 			s = GETDNS_DNSSEC_BOGUS;
3043 			break;
3044 
3045 		default:
3046 			break;
3047 		}
3048 	}
3049 	DEBUG_SEC("chain_validate_dnssec() returning %d\n", s);
3050 	return s;
3051 }
3052 
3053 
3054 /****************  dnssec_return_validation_chain Extension ******************
3055  *****************************************************************************/
3056 
count_outstanding_requests(chain_head * head)3057 static size_t count_outstanding_requests(chain_head *head)
3058 {
3059 	size_t count;
3060 	chain_node *node;
3061 
3062 	if (!head)
3063 		return 0;
3064 
3065 	for ( node = head->parent, count = head->lock
3066 	    ; node
3067 	    ; node = node->parent) {
3068 
3069 		count += node->lock;
3070 
3071 		if (!_getdns_netreq_finished(node->dnskey_req))
3072 			count++;
3073 
3074 		if (!_getdns_netreq_finished(node->ds_req))
3075 			count++;
3076 	}
3077 	return count + count_outstanding_requests(head->next);
3078 }
3079 
rrset_in_list(_getdns_rrset * rrset,getdns_list * list)3080 static int rrset_in_list(_getdns_rrset *rrset, getdns_list *list)
3081 {
3082 	size_t          i;
3083 	getdns_dict    *rr_dict;
3084 	uint32_t        rr_type;
3085 	uint32_t        rr_class;
3086 	getdns_bindata *name;
3087 
3088 	for (i = 0; !getdns_list_get_dict(list, i, &rr_dict); i++) {
3089 		if (!getdns_dict_get_int(rr_dict, "type", &rr_type) &&
3090 		    rrset->rr_type == rr_type &&
3091 		    !getdns_dict_get_int(rr_dict, "class", &rr_class) &&
3092 		    rrset->rr_class == rr_class &&
3093 		    !getdns_dict_get_bindata(rr_dict, "name", &name) &&
3094 		    dname_compare(rrset->name, name->data) == 0)
3095 			return 1;
3096 	}
3097 	return 0;
3098 }
3099 
append_rrset2val_chain_list(getdns_list * val_chain_list,_getdns_rrset * rrset,int signer)3100 static void append_rrset2val_chain_list(
3101     getdns_list *val_chain_list, _getdns_rrset *rrset, int signer)
3102 {
3103 	_getdns_rr_iter  val_rrset_spc[VAL_RRSET_SPC_SZ];
3104 	_getdns_rr_iter *val_rrset = val_rrset_spc;
3105 	_getdns_rrtype_iter rr_spc, *rr;
3106 	size_t n_rrs, i;
3107 	uint32_t orig_ttl;
3108 	getdns_dict *rr_dict;
3109 	_getdns_rrsig_iter  *rrsig, rrsig_spc;
3110 
3111 	assert(val_chain_list && rrset);
3112 
3113 	if (signer < 0)
3114 		return;
3115 
3116 	for ( rrsig = _getdns_rrsig_iter_init(&rrsig_spc, rrset)
3117 	    ; rrsig &&
3118 	      (   rrsig->rr_i.nxt < rrsig->rr_i.rr_type + 28
3119 	       || gldns_read_uint16(rrsig->rr_i.rr_type + 26)
3120 	          != (signer & 0xFFFF))
3121 	    ; rrsig = _getdns_rrsig_iter_next(rrsig))
3122 		; /* pass */
3123 
3124 	if (!rrsig)
3125 		return;
3126 
3127 	/* keytag was already read, so orig_ttl should cause no problem */
3128 	assert(rrsig->rr_i.nxt >= rrsig->rr_i.rr_type + 18);
3129 
3130 	orig_ttl = gldns_read_uint32(rrsig->rr_i.rr_type + 14);
3131 
3132 	for (;;) {
3133 		for ( rr = _getdns_rrtype_iter_init(&rr_spc, rrset), n_rrs = 0
3134 		    ; rr
3135 		    ; rr = _getdns_rrtype_iter_next(rr), n_rrs++) {
3136 
3137 			if (n_rrs < VAL_RRSET_SPC_SZ ||
3138 			    val_rrset != val_rrset_spc)
3139 				val_rrset[n_rrs] = rr->rr_i;
3140 		}
3141 		/* Did everything fit? Then break */
3142 		if (val_rrset != val_rrset_spc || n_rrs <= VAL_RRSET_SPC_SZ)
3143 			break;
3144 
3145 		/* More space needed for val_rrset */
3146 		val_rrset = GETDNS_XMALLOC(
3147 		    val_chain_list->mf, _getdns_rr_iter, n_rrs);
3148 	}
3149 	qsort(val_rrset, n_rrs, sizeof(_getdns_rr_iter), _rr_iter_rdata_cmp);
3150 	for (i = 0; i < n_rrs; i++) {
3151 		/* Get rid of doubles */
3152 		if (i && !_rr_iter_rdata_cmp(&val_rrset[i], &val_rrset[i-1]))
3153 			continue;
3154 
3155 		if (!(rr_dict =  _getdns_rr_iter2rr_dict_canonical(
3156 		    &val_chain_list->mf, &val_rrset[i], &orig_ttl)))
3157 			continue;
3158 
3159 		if (_getdns_list_append_this_dict(val_chain_list, rr_dict))
3160 			getdns_dict_destroy(rr_dict);
3161 	}
3162 	if ((rr_dict =  _getdns_rr_iter2rr_dict_canonical(
3163 	    &val_chain_list->mf, &rrsig->rr_i, &orig_ttl)) &&
3164 	    _getdns_list_append_this_dict(val_chain_list, rr_dict))
3165 		getdns_dict_destroy(rr_dict);
3166 
3167 	/* Append the other RRSIGs, which were not used for validation too,
3168 	 * because other validators might not have the same algorithm support.
3169 	 */
3170 	for ( rrsig = _getdns_rrsig_iter_init(&rrsig_spc, rrset)
3171 	    ; rrsig
3172 	    ; rrsig = _getdns_rrsig_iter_next(rrsig)) {
3173 
3174 		if (rrsig->rr_i.nxt < rrsig->rr_i.rr_type + 28)
3175 			continue;
3176 
3177 		if (gldns_read_uint16(rrsig->rr_i.rr_type + 26)
3178 		    == (signer & 0xFFFF))
3179 			continue;
3180 
3181 		orig_ttl = gldns_read_uint32(rrsig->rr_i.rr_type + 14);
3182 		if ((rr_dict =  _getdns_rr_iter2rr_dict_canonical(
3183 		    &val_chain_list->mf, &rrsig->rr_i, &orig_ttl)) &&
3184 		    _getdns_list_append_this_dict(val_chain_list, rr_dict))
3185 			getdns_dict_destroy(rr_dict);
3186 	}
3187 	if (val_rrset != val_rrset_spc)
3188 		GETDNS_FREE(val_chain_list->mf, val_rrset);
3189 }
3190 
append_rrs2val_chain_list(getdns_context * ctxt,getdns_list * val_chain_list,getdns_network_req * netreq,int signer)3191 static void append_rrs2val_chain_list(getdns_context *ctxt,
3192     getdns_list *val_chain_list, getdns_network_req *netreq, int signer)
3193 {
3194 	_getdns_rrset_iter *i, i_spc;
3195 	_getdns_rrset *rrset;
3196 	_getdns_rrtype_iter *rr, rr_spc;
3197 	_getdns_rrsig_iter  *rrsig, rrsig_spc;
3198 	getdns_dict *rr_dict;
3199 
3200 	for ( i = _getdns_rrset_iter_init(&i_spc, netreq->response
3201 	                                        , netreq->response_len
3202 	                                        , SECTION_NO_ADDITIONAL)
3203 	    ; i
3204 	    ; i = _getdns_rrset_iter_next(i)) {
3205 
3206 		rrset = _getdns_rrset_iter_value(i);
3207 
3208 		if (rrset->rr_type == GETDNS_RRTYPE_NSEC   ||
3209 		    rrset->rr_type == GETDNS_RRTYPE_NSEC3) {
3210 
3211 			if (rrset_in_list(rrset, val_chain_list))
3212 				continue;
3213 
3214 		} else if (rrset->rr_type != GETDNS_RRTYPE_DNSKEY &&
3215 		           rrset->rr_type != GETDNS_RRTYPE_DS)
3216 			continue;
3217 
3218 		if (signer > 0) {
3219 			/* We have a signer!  Return RRset in canonical
3220 			 * form and order with only the RRSIG that signed
3221 			 * the RRset.
3222 			 */
3223 			append_rrset2val_chain_list(
3224 			   val_chain_list, rrset, signer);
3225 			continue;
3226 		}
3227 		for ( rr = _getdns_rrtype_iter_init(&rr_spc, rrset)
3228 		    ; rr; rr = _getdns_rrtype_iter_next(rr)) {
3229 
3230 			if (!(rr_dict = _getdns_rr_iter2rr_dict(
3231 			    &ctxt->mf, &rr->rr_i)))
3232 				continue;
3233 
3234 			if (_getdns_list_append_this_dict(val_chain_list, rr_dict))
3235 				getdns_dict_destroy(rr_dict);
3236 		}
3237 		for ( rrsig = _getdns_rrsig_iter_init(&rrsig_spc, rrset)
3238 		    ; rrsig; rrsig = _getdns_rrsig_iter_next(rrsig)) {
3239 
3240 			if (!(rr_dict = _getdns_rr_iter2rr_dict(
3241 						&ctxt->mf, &rrsig->rr_i)))
3242 				continue;
3243 
3244 			if (_getdns_list_append_this_dict(val_chain_list, rr_dict))
3245 				getdns_dict_destroy(rr_dict);
3246 		}
3247 	}
3248 }
3249 
append_empty_ds2val_chain_list(getdns_context * context,getdns_list * val_chain_list,_getdns_rrset * ds)3250 static void append_empty_ds2val_chain_list(
3251     getdns_context *context, getdns_list *val_chain_list, _getdns_rrset *ds)
3252 {
3253 	getdns_dict *rr_dict;
3254 	getdns_bindata bindata;
3255 	getdns_dict *rdata_dict;
3256 
3257 	if (!(rr_dict = getdns_dict_create_with_context(context)))
3258 		return;
3259 
3260 	bindata.size = _dname_len(ds->name);
3261 	bindata.data = (UNCONST_UINT8_p)ds->name;
3262 	(void) getdns_dict_set_bindata(rr_dict, "name", &bindata);
3263 	(void) getdns_dict_set_int(rr_dict, "class", ds->rr_class);
3264 	(void) getdns_dict_set_int(rr_dict, "type", ds->rr_type);
3265 	(void) getdns_dict_set_int(rr_dict, "ttl", 0);
3266 
3267 	if (!(rdata_dict = getdns_dict_create_with_context(context))) {
3268 		getdns_dict_destroy(rr_dict);
3269 		return;
3270 	}
3271 	bindata.size = 0;
3272 	bindata.data = NULL;
3273 	(void) getdns_dict_set_bindata(rdata_dict, "rdata_raw", &bindata);
3274 	getdns_dict_destroy(rdata_dict);
3275 
3276 	if (_getdns_list_append_this_dict(val_chain_list, rr_dict))
3277 		getdns_dict_destroy(rr_dict);
3278 }
_to_the_root(chain_node * node)3279 static inline chain_node *_to_the_root(chain_node *node)
3280 {
3281 	while (node->parent) node = node->parent;
3282 	return node;
3283 }
3284 
_getdns_bogus(getdns_dns_req * dnsreq)3285 int _getdns_bogus(getdns_dns_req *dnsreq)
3286 {
3287 	getdns_network_req **netreq_p, *netreq;
3288 
3289 	for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p) ; netreq_p++) {
3290 		if (netreq->dnssec_status == GETDNS_DNSSEC_BOGUS)
3291 			return 1;
3292 	}
3293 	return 0;
3294 }
3295 
check_chain_complete(chain_head * chain)3296 static void check_chain_complete(chain_head *chain)
3297 {
3298 	getdns_dns_req *dnsreq;
3299 	getdns_context *context;
3300 	size_t o, node_count;
3301 	chain_head *head, *next, *same_chain;
3302 	chain_node *node;
3303 	getdns_list *val_chain_list;
3304 	getdns_dict *response_dict;
3305 	_getdns_rrset_iter tas_iter;
3306 
3307 	if ((o = count_outstanding_requests(chain)) > 0) {
3308 		DEBUG_SEC("%"PRIsz" outstanding requests\n", o);
3309 		return;
3310 	}
3311 	DEBUG_SEC("Chain done!\n");
3312 	dnsreq = chain->netreq->owner;
3313 	context = dnsreq->context;
3314 
3315 	if (dnsreq->waiting_for_ta) {
3316 		getdns_dns_req **d;
3317 
3318 		for (d = &context->ta_notify; *d; d = &(*d)->ta_notify) {
3319 			if (*d == dnsreq) {
3320 				*d = dnsreq->ta_notify;
3321 				dnsreq->ta_notify = NULL;
3322 				break;
3323 			}
3324 		}
3325 
3326 	} else {
3327 		if (context->trust_anchors_source == GETDNS_TASRC_FETCHING) {
3328 			dnsreq->waiting_for_ta = 1;
3329 			dnsreq->ta_notify = context->ta_notify;
3330 			context->ta_notify = dnsreq;
3331 			return;
3332 		}
3333 	}
3334 #ifdef STUB_NATIVE_DNSSEC
3335 	if (context->trust_anchors)
3336 
3337 		chain_set_netreq_dnssec_status(chain,_getdns_rrset_iter_init(&tas_iter,
3338 		    context->trust_anchors, context->trust_anchors_len,
3339 		    SECTION_ANSWER));
3340 #else
3341 	if (context->trust_anchors)
3342 
3343 		(void) chain_validate_dnssec(priv_getdns_context_mf(context),
3344 		    time(NULL), context->dnssec_allowed_skew,
3345 		    chain, _getdns_rrset_iter_init( &tas_iter
3346 		                          , context->trust_anchors
3347 		                          , context->trust_anchors_len
3348 		                          , SECTION_ANSWER));
3349 #endif
3350 	if (context->trust_anchors_source == GETDNS_TASRC_XML) {
3351 		if ((head = chain) && (node = _to_the_root(head->parent)) &&
3352 		    node->dnskey.name && *node->dnskey.name == 0)
3353 			_getdns_context_update_root_ksk(context,&node->dnskey);
3354 
3355 	} else if (_getdns_bogus(dnsreq)) {
3356 		_getdns_rrsig_iter rrsig_spc;
3357 
3358 		if ((head = chain) && (node = _to_the_root(head->parent))
3359  		    /* The root DNSKEY rrset */
3360 		    && node->dnskey.name && *node->dnskey.name == 0
3361 		    /* We queried it and had a response */
3362 		    && node->dnskey_req
3363 		    /* The response was bogus */
3364 		    && node->dnskey_req->dnssec_status == GETDNS_DNSSEC_BOGUS
3365 		    /* The response was bogus, but not because it has no rrsigs */
3366 		    && _getdns_rrsig_iter_init(&rrsig_spc, &node->dnskey)
3367 		    ){
3368 
3369 			_getdns_log( &context->log
3370 				   , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_NOTICE
3371 				   , "root DNSKEY set was bogus!\n");
3372 			if (!dnsreq->waiting_for_ta) {
3373 				uint64_t now_ms = 0;
3374 
3375 				dnsreq->waiting_for_ta = 1;
3376 				_getdns_context_equip_with_anchor(
3377 				    context, &now_ms);
3378 
3379 				if (context->trust_anchors_source
3380 				    == GETDNS_TASRC_XML) {
3381 					chain_clear_netreq_dnssec_status(chain);
3382 					check_chain_complete(chain);
3383 					return;
3384 				}
3385 				if (context->trust_anchors_source ==
3386 						GETDNS_TASRC_FAILED
3387 				&& 0 == _getdns_ms_until_expiry2(
3388 				    context->trust_anchors_backoff_expiry,
3389 				    &now_ms)) {
3390 					context->trust_anchors_source =
3391 					    GETDNS_TASRC_NONE;
3392 				}
3393 				if (context->trust_anchors_source
3394 				!=  GETDNS_TASRC_FAILED) {
3395 					_getdns_start_fetching_ta(
3396 					    context,  dnsreq->loop, &now_ms);
3397 				}
3398 				if (dnsreq->waiting_for_ta &&
3399 				    context->trust_anchors_source
3400 				    == GETDNS_TASRC_FETCHING) {
3401 
3402 					chain_clear_netreq_dnssec_status(chain);
3403 					dnsreq->ta_notify = context->ta_notify;
3404 					context->ta_notify = dnsreq;
3405 					return;
3406 				}
3407 			}
3408 		}
3409 	}
3410 
3411 #ifdef DNSSEC_ROADBLOCK_AVOIDANCE
3412 	if (    dnsreq->dnssec_roadblock_avoidance
3413 	    && !dnsreq->avoid_dnssec_roadblocks
3414 	    &&  _getdns_bogus(dnsreq)) {
3415 
3416 		getdns_network_req **netreq_p, *netreq;
3417 		uint64_t now_ms = 0;
3418 
3419 		dnsreq->avoid_dnssec_roadblocks = 1;
3420 		dnsreq->chain->lock += 1;
3421 
3422 		for ( netreq_p = dnsreq->netreqs
3423 		    ; (netreq = *netreq_p)
3424 		    ; netreq_p++) {
3425 
3426 			_getdns_netreq_change_state(netreq, NET_REQ_NOT_SENT);
3427 			netreq->dnssec_status =
3428 				GETDNS_DNSSEC_INDETERMINATE;
3429 			netreq->owner = dnsreq;
3430 			(void) _getdns_submit_netreq(netreq, &now_ms);
3431 		}
3432 		if (!dnsreq->dnssec_return_validation_chain)
3433 			return;
3434 
3435 		for ( head = chain; head ; head = next ) {
3436 			next = head->next;
3437 			for ( node_count = head->node_count
3438 			    , node = head->parent
3439 			    ; node_count
3440 			    ; node_count--, node = node->parent ) {
3441 
3442 				if (node->dnskey_req) {
3443 					_getdns_netreq_change_state(
3444 					    node->dnskey_req,
3445 					    NET_REQ_NOT_SENT);
3446 					node->dnskey_req->owner->
3447 					    avoid_dnssec_roadblocks = 1;
3448 					(void) _getdns_submit_netreq(
3449 					    node->dnskey_req, &now_ms);
3450 				}
3451 				if (node->ds_req) {
3452 					_getdns_netreq_change_state(
3453 					    node->ds_req, NET_REQ_NOT_SENT);
3454 					node->ds_req->owner->
3455 					    avoid_dnssec_roadblocks = 1;
3456 					(void) _getdns_submit_netreq(
3457 					    node->ds_req, &now_ms);
3458 				}
3459 			}
3460 		}
3461 		return;
3462 	}
3463 #endif
3464 	dnsreq->waiting_for_ta = 0;
3465 	val_chain_list = dnsreq->dnssec_return_validation_chain
3466 		? getdns_list_create_with_context(context) : NULL;
3467 
3468 	/* Walk chain to add values to val_chain_list.  We do not cleanup yet.
3469 	 * The chain will eventually be freed when the dns request is descheduled
3470 	 * with getdns_context_clear_outbound_request().
3471 	 */
3472 	for ( head = chain; head ; head = next ) {
3473 		next = head->next;
3474 		if (dnsreq->dnssec_return_full_validation_chain &&
3475 		    head->node_count && head->signer > 0) {
3476 
3477 			append_rrset2val_chain_list(
3478 			    val_chain_list, &head->rrset, head->signer);
3479 
3480 			for ( same_chain = next
3481 			    ; same_chain && same_chain->signer == head->signer
3482 			    ; same_chain = same_chain->next) {
3483 				append_rrset2val_chain_list(val_chain_list,
3484 				    &same_chain->rrset, same_chain->signer);
3485 				same_chain->signer = -1;
3486 			}
3487 		}
3488 		for ( node_count = head->node_count, node = head->parent
3489 		    ; node_count
3490 		    ; node_count--, node = node->parent ) {
3491 
3492 			if (node->dnskey_req) {
3493 				if (val_chain_list)
3494 					append_rrs2val_chain_list(
3495 					    context, val_chain_list,
3496 					    node->dnskey_req,
3497 					    node->dnskey_signer);
3498 			}
3499 			if (node->ds_req) {
3500 				if (val_chain_list)
3501 					append_rrs2val_chain_list(
3502 					    context, val_chain_list,
3503 					    node->ds_req, node->ds_signer);
3504 
3505 				if (val_chain_list && node->ds_signer == -1 &&
3506 				    !_getdns_rrset_has_rrs(&node->ds)) {
3507 					/* Add empty DS, to prevent less
3508 					 * specific to be able to authenticate
3509 					 * below a zone cut (closer to head)
3510 					 */
3511 					append_empty_ds2val_chain_list(
3512 					    context, val_chain_list,
3513 					    &node->ds);
3514 				}
3515 			}
3516 		}
3517 	}
3518 
3519 	response_dict = _getdns_create_getdns_response(dnsreq);
3520 	if (val_chain_list) {
3521 		if (_getdns_dict_set_this_list(
3522 		    response_dict, "validation_chain", val_chain_list))
3523 			getdns_list_destroy(val_chain_list);
3524 	}
3525 
3526 	/* Final user callback */
3527 	dnsreq->validating = 0;
3528 	_getdns_call_user_callback(dnsreq, response_dict);
3529 }
3530 
_getdns_ta_notify_dnsreqs(getdns_context * context)3531 void _getdns_ta_notify_dnsreqs(getdns_context *context)
3532 {
3533 	getdns_dns_req **dnsreq_p, *dnsreq = NULL;
3534 	uint64_t now_ms = 0;
3535 
3536 	assert(context);
3537 
3538 	if (context->trust_anchors_source == GETDNS_TASRC_NONE ||
3539 	    context->trust_anchors_source == GETDNS_TASRC_FETCHING)
3540 		return;
3541 
3542 	dnsreq_p = &context->ta_notify;
3543 	while ((dnsreq = *dnsreq_p)) {
3544 		assert(dnsreq->waiting_for_ta);
3545 
3546 		if (dnsreq->chain)
3547 			check_chain_complete(dnsreq->chain);
3548 		else {
3549 			getdns_network_req *netreq, **netreq_p;
3550 			int r = GETDNS_RETURN_GOOD;
3551 
3552 			(void) _getdns_context_prepare_for_resolution(context);
3553 
3554 			*dnsreq_p = dnsreq->ta_notify;
3555 			for ( netreq_p = dnsreq->netreqs
3556 			    ; !r && (netreq = *netreq_p)
3557 			    ; netreq_p++ ) {
3558 
3559 				if (!(r = _getdns_submit_netreq(netreq, &now_ms)))
3560 					continue;
3561 				if (r == DNS_REQ_FINISHED)
3562 					break;
3563 				_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
3564 			}
3565 		}
3566 		assert(*dnsreq_p != dnsreq);
3567 	}
3568 }
3569 
_getdns_validation_chain_timeout(getdns_dns_req * dnsreq)3570 void _getdns_validation_chain_timeout(getdns_dns_req *dnsreq)
3571 {
3572 	cancel_requests_for_subdomains_of(dnsreq->chain, (uint8_t *)"\0");
3573 	dnsreq->request_timed_out = 1;
3574 	check_chain_complete(dnsreq->chain);
3575 }
3576 
_getdns_cancel_validation_chain(getdns_dns_req * dnsreq)3577 void _getdns_cancel_validation_chain(getdns_dns_req *dnsreq)
3578 {
3579 	chain_head *head, *next;
3580 	chain_node *node;
3581 	size_t      node_count;
3582 
3583 	/* Clear nodes under direct DNSKEY queries.
3584 	 * They share the DNSKEY lookup netreq, but _dnskey_query() can not
3585 	 * be used because we're free'ing the heads.
3586 	 */
3587 	for (head = dnsreq->chain; head; head = head->next) {
3588 		if (  head->rrset.rr_type == GETDNS_RRTYPE_DNSKEY
3589 		   && head->node_count
3590 		   && head->netreq == head->parent->dnskey_req)
3591 			head->parent->dnskey_req = NULL;
3592 	}
3593 	head = dnsreq->chain;
3594 	dnsreq->chain = NULL;
3595 	while (head) {
3596 		next = head->next;
3597 
3598 		for ( node_count = head->node_count, node = head->parent
3599 		    ; node_count
3600 		    ; node_count--, node = node->parent ) {
3601 
3602 			if (node->dnskey_req)
3603 				_getdns_context_cancel_request(
3604 				    node->dnskey_req->owner);
3605 
3606 			if (node->ds_req)
3607 				_getdns_context_cancel_request(
3608 				    node->ds_req->owner);
3609 		}
3610 		GETDNS_FREE(head->my_mf, head);
3611 		head = next;
3612 	}
3613 }
3614 
_getdns_get_validation_chain(getdns_dns_req * dnsreq)3615 void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
3616 {
3617 	getdns_network_req *netreq, **netreq_p;
3618 	chain_head *chain = NULL, *chain_p;
3619 
3620 	if (dnsreq->avoid_dnssec_roadblocks) {
3621 		chain = dnsreq->chain;
3622 
3623 	} else if (dnsreq->validating)
3624 		return;
3625 	dnsreq->validating = 1;
3626 
3627 	if (dnsreq->avoid_dnssec_roadblocks && chain->lock == 0)
3628 		; /* pass */
3629 
3630 	else for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p) ; netreq_p++) {
3631 		if (!  netreq->response
3632 		    || netreq->response_len < GLDNS_HEADER_SIZE
3633 		    || ( GLDNS_RCODE_WIRE(netreq->response)
3634 			 != GETDNS_RCODE_NOERROR &&
3635 			 GLDNS_RCODE_WIRE(netreq->response)
3636 			 != GETDNS_RCODE_NXDOMAIN) ) {
3637 
3638 			netreq->dnssec_status = GETDNS_DNSSEC_INSECURE;
3639 			continue;
3640 
3641 		} else if (netreq->unbound_id != -1)
3642 			netreq->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
3643 
3644 		add_pkt2val_chain( &dnsreq->my_mf, &chain
3645 		                 , netreq->response, netreq->response_len
3646 				 , netreq
3647 		                 );
3648 		add_question2val_chain( &dnsreq->my_mf, &chain
3649 		                      , netreq->response, netreq->response_len
3650 		                      , netreq->owner->name
3651 		                      , netreq->request_type
3652 		                      , netreq->owner->request_class
3653 				      , netreq
3654 		                      );
3655 	}
3656 	if (chain) {
3657 		for (chain_p = chain; chain_p; chain_p = chain_p->next) {
3658 			if (chain_p->lock) chain_p->lock--;
3659 		}
3660 		dnsreq->chain = chain;
3661 		if (dnsreq->avoid_dnssec_roadblocks && chain->lock)
3662 			chain->lock -= 1;
3663 
3664 		check_chain_complete(chain);
3665 	} else {
3666 		dnsreq->validating = 0;
3667 		_getdns_call_user_callback(dnsreq,
3668 		    _getdns_create_getdns_response(dnsreq));
3669 	}
3670 }
3671 
3672 
3673 /*******************  getdns_validate_dnssec() Function  *********************
3674  *****************************************************************************/
3675 
3676 
wire_validate_dnssec(const struct mem_funcs * mf,time_t now,uint32_t skew,uint8_t * to_val,size_t to_val_len,uint8_t * support,size_t support_len,uint8_t * tas,size_t tas_len)3677 static int wire_validate_dnssec(const struct mem_funcs *mf,
3678     time_t now, uint32_t skew, uint8_t *to_val, size_t to_val_len,
3679     uint8_t *support, size_t support_len, uint8_t *tas, size_t tas_len)
3680 {
3681 	chain_head *chain, *head, *next_head;
3682 	chain_node *node;
3683 
3684 	uint8_t qname_spc[256];
3685 	const uint8_t *qname = NULL;
3686 	size_t qname_len = sizeof(qname_spc);
3687 	uint16_t qtype = 0, qclass = GETDNS_RRCLASS_IN;
3688 
3689 	_getdns_rr_iter rr_spc, *rr;
3690 	_getdns_rrset_iter tas_iter;
3691 
3692 	int s;
3693 
3694 
3695 	if (to_val_len < GLDNS_HEADER_SIZE)
3696 		return GETDNS_RETURN_GENERIC_ERROR;
3697 
3698 #if defined(SEC_DEBUG) && SEC_DEBUG
3699 	char *str = gldns_wire2str_pkt(to_val, to_val_len);
3700 	DEBUG_SEC("to validate: %s\n", str);
3701 	free(str);
3702 #endif
3703 
3704 	if (GLDNS_RCODE_WIRE(to_val) != GETDNS_RCODE_NOERROR &&
3705 	    GLDNS_RCODE_WIRE(to_val) != GETDNS_RCODE_NXDOMAIN)
3706 		return GETDNS_DNSSEC_INSECURE;
3707 
3708 	if (GLDNS_QDCOUNT(to_val) == 0 && GLDNS_ANCOUNT(to_val) == 0)
3709 		return GETDNS_RETURN_GENERIC_ERROR;
3710 
3711 	chain = NULL;
3712 	/* First create a chain (head + nodes) for each rr in the answer and
3713 	 * authority section of the fake to_val packet.
3714 	 */
3715 	add_pkt2val_chain(mf, &chain, to_val, to_val_len, NULL);
3716 
3717 	/* For each question in the question section add a chain head.
3718 	 */
3719 	if (   (rr = _getdns_rr_iter_init(&rr_spc, to_val, to_val_len))
3720 	    && _getdns_rr_iter_section(rr) == SECTION_QUESTION
3721 	    && (qname = _getdns_owner_if_or_as_decompressed(
3722 			    rr, qname_spc, &qname_len))
3723 	    && rr->nxt >= rr->rr_type + 4) {
3724 
3725 		qtype = gldns_read_uint16(rr->rr_type);
3726 		qclass = gldns_read_uint16(rr->rr_type + 2);
3727 
3728 		add_question2val_chain(mf, &chain, to_val, to_val_len,
3729 		    qname, qtype, qclass, NULL);
3730 	}
3731 
3732 	/* Now equip the nodes with the support records wireformat */
3733 	for (head = chain; head; head = head->next) {
3734 		for (node = head->parent; node; node = node->parent) {
3735 
3736 			node->dnskey.pkt = support;
3737 			node->dnskey.pkt_len = support_len;
3738 			node->ds.pkt = support;
3739 			node->ds.pkt_len = support_len;
3740 		}
3741 	}
3742 	s = chain_validate_dnssec(mf, now, skew, chain,
3743 	    _getdns_rrset_iter_init(
3744 		    &tas_iter, tas, tas_len, SECTION_ANSWER));
3745 
3746 	/* Cleanup the chain */
3747 	for (head = chain; head; head = next_head) {
3748 		next_head = head->next;
3749 		GETDNS_FREE(*mf, head);
3750 	}
3751 	return s;
3752 }
3753 
3754 /*
3755  * getdns_validate_dnssec
3756  *
3757  */
3758 getdns_return_t
getdns_validate_dnssec2(const getdns_list * records_to_validate,const getdns_list * support_records,const getdns_list * trust_anchors,time_t now,uint32_t skew)3759 getdns_validate_dnssec2(const getdns_list *records_to_validate,
3760     const getdns_list *support_records,
3761     const getdns_list *trust_anchors,
3762     time_t now, uint32_t skew)
3763 {
3764 	uint8_t to_val_buf[4096], *to_val,
3765 		support_buf[4096], *support,
3766 		tas_buf[4096], *tas;
3767 
3768 	size_t to_val_len = sizeof(to_val_buf),
3769 	       support_len = sizeof(support_buf),
3770 	       tas_len = sizeof(tas_buf);
3771 
3772 	int r = GETDNS_RETURN_MEMORY_ERROR;
3773 	const struct mem_funcs *mf;
3774 
3775 	size_t i;
3776 	getdns_dict *reply;
3777 
3778 #if defined(SEC_DEBUG) && SEC_DEBUG
3779 	fflush(stdout);
3780 #endif
3781 
3782 	if (!records_to_validate || !trust_anchors)
3783 		return GETDNS_RETURN_INVALID_PARAMETER;
3784 	mf = &records_to_validate->mf;
3785 
3786 	/* First convert everything to wire format
3787 	 */
3788 
3789 	if (!support_records)
3790 		(void) memset((support = support_buf), 0, GLDNS_HEADER_SIZE);
3791 
3792 	else if (!(support = _getdns_list2wire(support_records,
3793 	    support_buf, &support_len, mf)))
3794 		return GETDNS_RETURN_MEMORY_ERROR;
3795 
3796 	if (!(tas = _getdns_list2wire(trust_anchors,
3797 	    tas_buf, &tas_len, mf)))
3798 		goto exit_free_support;
3799 
3800 	if (!(to_val = _getdns_list2wire(records_to_validate,
3801 	    to_val_buf, &to_val_len, mf)))
3802 		goto exit_free_tas;
3803 
3804 	if ((r = wire_validate_dnssec(mf, now, skew, to_val, to_val_len,
3805 	    support,support_len, tas,tas_len)) != GETDNS_RETURN_GENERIC_ERROR)
3806 		goto exit_free_to_val;
3807 
3808 	for (i = 0; !getdns_list_get_dict(records_to_validate,i,&reply); i++) {
3809 
3810 		DEBUG_SEC("REPLY %"PRIsz", r: %d\n", i, r);
3811 		if (to_val != to_val_buf)
3812 			GETDNS_FREE(*mf, to_val);
3813 		to_val_len = sizeof(to_val_buf);
3814 
3815 		if (!(to_val = _getdns_reply2wire(
3816 		    reply, to_val_buf, &to_val_len, mf)))
3817 			continue;
3818 
3819 		r = GETDNS_DNSSEC_INDETERMINATE;
3820 		switch (wire_validate_dnssec(mf, now, skew,
3821 		    to_val, to_val_len, support, support_len, tas, tas_len)) {
3822 		case GETDNS_DNSSEC_SECURE:
3823 			if (r == GETDNS_DNSSEC_INDETERMINATE)
3824 				r = GETDNS_DNSSEC_SECURE;
3825 			break;
3826 		case GETDNS_DNSSEC_INSECURE:
3827 			if (r != GETDNS_DNSSEC_BOGUS)
3828 				r = GETDNS_DNSSEC_INSECURE;
3829 			break;
3830 		case GETDNS_DNSSEC_BOGUS:
3831 			r = GETDNS_DNSSEC_BOGUS;
3832 			break;
3833 		default:
3834 			break;
3835 		}
3836 	}
3837 	DEBUG_SEC("REPLY %"PRIsz", r: %d\n", i, r);
3838 
3839 exit_free_to_val:
3840 	if (to_val != to_val_buf)
3841 		GETDNS_FREE(*mf, to_val);
3842 exit_free_tas:
3843 	if (tas != tas_buf)
3844 		GETDNS_FREE(*mf, tas);
3845 exit_free_support:
3846 	if (support != support_buf)
3847 		GETDNS_FREE(*mf, support);
3848 
3849 	return r;
3850 }
3851 
3852 
3853 getdns_return_t
getdns_validate_dnssec(const getdns_list * records_to_validate,const getdns_list * support_records,const getdns_list * trust_anchors)3854 getdns_validate_dnssec(const getdns_list *records_to_validate,
3855     const getdns_list *support_records,
3856     const getdns_list *trust_anchors)
3857 {
3858 	return getdns_validate_dnssec2(records_to_validate, support_records,
3859 	    trust_anchors, time(NULL), 0);
3860 }
3861 
3862 /******************  getdns_root_trust_anchor() Function  ********************
3863  *****************************************************************************/
3864 
3865 uint16_t
_getdns_parse_ta_file(time_t * ta_mtime,gldns_buffer * gbuf)3866 _getdns_parse_ta_file(time_t *ta_mtime, gldns_buffer *gbuf)
3867 {
3868 
3869 	struct gldns_file_parse_state pst;
3870 	struct stat st;
3871 	uint8_t rr[8192]; /* Reasonable size for a single DNSKEY or DS RR */
3872 	size_t len, dname_len;
3873 	FILE *in;
3874 	uint16_t ta_count = 0;
3875 	size_t pkt_start;
3876 
3877 	if (stat(TRUST_ANCHOR_FILE, &st) != 0)
3878 		return 0;
3879 
3880 	if (ta_mtime)
3881 		*ta_mtime = st.st_mtime;
3882 
3883 	if (!(in = fopen(TRUST_ANCHOR_FILE, "r")))
3884 		return 0;
3885 
3886 	memset(&pst, 0, sizeof(pst));
3887 	pst.default_ttl = 3600;
3888 	pst.lineno = 1;
3889 
3890 	pkt_start = gldns_buffer_position(gbuf);
3891 	/* Empty header */
3892 	gldns_buffer_write_u32(gbuf, 0);
3893 	gldns_buffer_write_u32(gbuf, 0);
3894 	gldns_buffer_write_u32(gbuf, 0);
3895 
3896 	while (!feof(in)) {
3897 		len = sizeof(rr);
3898 		dname_len = 0;
3899 		if (gldns_fp2wire_rr_buf(in, rr, &len, &dname_len, &pst))
3900 			break;
3901 		if (len == 0)  /* empty, $TTL, $ORIGIN */
3902 			continue;
3903 		if (gldns_wirerr_get_type(rr, len, dname_len)
3904 		    != GLDNS_RR_TYPE_DS &&
3905 		    gldns_wirerr_get_type(rr, len, dname_len)
3906 		    != GLDNS_RR_TYPE_DNSKEY)
3907 			continue;
3908 
3909 		gldns_buffer_write(gbuf, rr, len);
3910 		ta_count++;
3911 	}
3912 	fclose(in);
3913 	gldns_buffer_write_u16_at(gbuf, pkt_start+GLDNS_ANCOUNT_OFF, ta_count);
3914 
3915 	return ta_count;
3916 }
3917 
3918 getdns_list *
getdns_root_trust_anchor(time_t * utc_date_of_anchor)3919 getdns_root_trust_anchor(time_t *utc_date_of_anchor)
3920 {
3921 	gldns_buffer *gbuf;
3922 	getdns_list *ta_rrs;
3923 
3924 	if (!(ta_rrs = getdns_list_create()))
3925 		return NULL;
3926 
3927 	if (!(gbuf = gldns_buffer_new(4096)))
3928 		goto error_free_ta_rrs;
3929 
3930 	if (!_getdns_parse_ta_file(utc_date_of_anchor, gbuf))
3931 		goto error_free_gbuf;
3932 
3933 	_getdns_wire2list( gldns_buffer_begin(gbuf)
3934 	                 , gldns_buffer_position(gbuf), ta_rrs);
3935 
3936 	gldns_buffer_free(gbuf);
3937 	return ta_rrs;
3938 
3939 error_free_gbuf:
3940 	gldns_buffer_free(gbuf);
3941 error_free_ta_rrs:
3942 	getdns_list_destroy(ta_rrs);
3943 	return NULL;
3944 }
3945 
3946 /* dnssec.c */
3947