xref: /dragonfly/contrib/ldns/drill/securetrace.c (revision ec1c3f3a)
1 /*
2  * securechasetrace.c
3  * Where all the hard work concerning secure tracing is done
4  *
5  * (c) 2005, 2006 NLnet Labs
6  *
7  * See the file LICENSE for the license
8  *
9  */
10 
11 #include "drill.h"
12 #include <ldns/ldns.h>
13 
14 #define SELF "[S]"  /* self sig ok */
15 #define TRUST "[T]" /* chain from parent */
16 #define BOGUS "[B]" /* bogus */
17 #define UNSIGNED "[U]" /* no relevant dnssec data found */
18 
19 #if 0
20 /* See if there is a key/ds in trusted that matches
21  * a ds in *ds.
22  */
23 static ldns_rr_list *
24 ds_key_match(ldns_rr_list *ds, ldns_rr_list *trusted)
25 {
26 	size_t i, j;
27 	bool match;
28 	ldns_rr *rr_i, *rr_j;
29 	ldns_rr_list *keys;
30 
31 	if (!trusted || !ds) {
32 		return NULL;
33 	}
34 
35 	match = false;
36 	keys = ldns_rr_list_new();
37 	if (!keys) {
38 		return NULL;
39 	}
40 
41 	if (!ds || !trusted) {
42 		return NULL;
43 	}
44 
45 	for (i = 0; i < ldns_rr_list_rr_count(trusted); i++) {
46 		rr_i = ldns_rr_list_rr(trusted, i);
47 		for (j = 0; j < ldns_rr_list_rr_count(ds); j++) {
48 
49 			rr_j = ldns_rr_list_rr(ds, j);
50 			if (ldns_rr_compare_ds(rr_i, rr_j)) {
51 				match = true;
52 				/* only allow unique RRs to match */
53 				ldns_rr_set_push_rr(keys, rr_i);
54 			}
55 		}
56 	}
57 	if (match) {
58 		return keys;
59 	} else {
60 		return NULL;
61 	}
62 }
63 #endif
64 
65 static ldns_pkt *
66 get_dnssec_pkt(ldns_resolver *r, ldns_rdf *name, ldns_rr_type t)
67 {
68 	ldns_pkt *p = NULL;
69 	p = ldns_resolver_query(r, name, t, LDNS_RR_CLASS_IN, 0);
70 	if (!p) {
71 		return NULL;
72 	} else {
73 		if (verbosity >= 5) {
74 			ldns_pkt_print(stdout, p);
75 		}
76 		return p;
77 	}
78 }
79 
80 #ifdef HAVE_SSL
81 /*
82  * retrieve keys for this zone
83  */
84 static ldns_pkt_type
85 get_key(ldns_pkt *p, ldns_rdf *apexname, ldns_rr_list **rrlist, ldns_rr_list **opt_sig)
86 {
87 	return get_dnssec_rr(p, apexname, LDNS_RR_TYPE_DNSKEY, rrlist, opt_sig);
88 }
89 
90 /*
91  * check to see if we can find a DS rrset here which we can then follow
92  */
93 static ldns_pkt_type
94 get_ds(ldns_pkt *p, ldns_rdf *ownername, ldns_rr_list **rrlist, ldns_rr_list **opt_sig)
95 {
96 	return get_dnssec_rr(p, ownername, LDNS_RR_TYPE_DS, rrlist, opt_sig);
97 }
98 #endif /* HAVE_SSL */
99 
100 static void
101 remove_resolver_nameservers(ldns_resolver *res)
102 {
103 	ldns_rdf *pop;
104 
105 	/* remove the old nameserver from the resolver */
106 	while((pop = ldns_resolver_pop_nameserver(res))) {
107 		ldns_rdf_deep_free(pop);
108 	}
109 
110 }
111 
112 /*ldns_pkt **/
113 #ifdef HAVE_SSL
114 int
115 do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
116                 ldns_rr_class c, ldns_rr_list *trusted_keys, ldns_rdf *start_name
117                )
118 {
119 	ldns_resolver *res;
120 	ldns_pkt *p, *local_p;
121 	ldns_rr_list *new_nss;
122 	ldns_rr_list *ns_addr;
123 	ldns_rdf *pop;
124 	ldns_rdf **labels = NULL;
125 	ldns_status status, st;
126 	ssize_t i;
127 	size_t j;
128 	size_t k;
129 	size_t l;
130 	uint8_t labels_count = 0;
131 
132 	/* dnssec */
133 	ldns_rr_list *key_list;
134 	ldns_rr_list *key_sig_list;
135 	ldns_rr_list *ds_list;
136 	ldns_rr_list *ds_sig_list;
137 	ldns_rr_list *correct_key_list;
138 	ldns_rr_list *trusted_ds_rrs;
139 	bool new_keys_trusted = false;
140 	ldns_rr_list *current_correct_keys = NULL;
141 	ldns_rr_list *dataset;
142 
143 	ldns_rr_list *nsec_rrs = NULL;
144 	ldns_rr_list *nsec_rr_sigs = NULL;
145 
146 	/* empty non-terminal check */
147 	bool ent;
148 	ldns_rr  *nsecrr;      /* The nsec that proofs the non-terminal */
149 	ldns_rdf *hashed_name; /* The query hashed with nsec3 params */
150 	ldns_rdf *label0;      /* The first label of an nsec3 owner name */
151 
152 	/* glue handling */
153 	ldns_rr_list *new_ns_addr;
154 	ldns_rr_list *old_ns_addr;
155 	ldns_rr *ns_rr;
156 
157 	int result = 0;
158 
159 	/* printing niceness */
160 	const ldns_rr_descriptor *descriptor;
161 
162 	descriptor = ldns_rr_descript(t);
163 
164 	new_nss = NULL;
165 	ns_addr = NULL;
166 	key_list = NULL;
167 	ds_list = NULL;
168 
169 	p = NULL;
170 	local_p = NULL;
171 	res = ldns_resolver_new();
172 	key_sig_list = NULL;
173 	ds_sig_list = NULL;
174 
175 	if (!res) {
176 		error("Memory allocation failed");
177 		result = -1;
178 		return result;
179 	}
180 
181 	correct_key_list = ldns_rr_list_new();
182 	if (!correct_key_list) {
183 		error("Memory allocation failed");
184 		result = -1;
185 		return result;
186 	}
187 
188 	trusted_ds_rrs = ldns_rr_list_new();
189 	if (!trusted_ds_rrs) {
190 		error("Memory allocation failed");
191 		result = -1;
192 		return result;
193 	}
194         /* Add all preset trusted DS signatures to the list of trusted DS RRs. */
195         for (j = 0; j < ldns_rr_list_rr_count(trusted_keys); j++) {
196             ldns_rr* one_rr = ldns_rr_list_rr(trusted_keys, j);
197             if (ldns_rr_get_type(one_rr)  == LDNS_RR_TYPE_DS) {
198                 ldns_rr_list_push_rr(trusted_ds_rrs, ldns_rr_clone(one_rr));
199             }
200         }
201 
202 	/* transfer some properties of local_res to res */
203 	ldns_resolver_set_ip6(res,
204 			ldns_resolver_ip6(local_res));
205 	ldns_resolver_set_port(res,
206 			ldns_resolver_port(local_res));
207 	ldns_resolver_set_debug(res,
208 			ldns_resolver_debug(local_res));
209 	ldns_resolver_set_fail(res,
210 			ldns_resolver_fail(local_res));
211 	ldns_resolver_set_usevc(res,
212 			ldns_resolver_usevc(local_res));
213 	ldns_resolver_set_random(res,
214 			ldns_resolver_random(local_res));
215 	ldns_resolver_set_source(res,
216 			ldns_resolver_source(local_res));
217 	ldns_resolver_set_recursive(local_res, true);
218 
219 	ldns_resolver_set_recursive(res, false);
220 	ldns_resolver_set_dnssec_cd(res, false);
221 	ldns_resolver_set_dnssec(res, true);
222 
223 	/* setup the root nameserver in the new resolver */
224 	status = ldns_resolver_push_nameserver_rr_list(res, global_dns_root);
225 	if (status != LDNS_STATUS_OK) {
226 		printf("ERRRRR: %s\n", ldns_get_errorstr_by_id(status));
227 		ldns_rr_list_print(stdout, global_dns_root);
228 		result = status;
229 		goto done;
230 	}
231 	labels_count = ldns_dname_label_count(name);
232 	if (start_name) {
233 		if (ldns_dname_is_subdomain(name, start_name)) {
234 			labels_count -= ldns_dname_label_count(start_name);
235 		} else {
236 			fprintf(stderr, "Error; ");
237 			ldns_rdf_print(stderr, name);
238 			fprintf(stderr, " is not a subdomain of ");
239 			ldns_rdf_print(stderr, start_name);
240 			fprintf(stderr, "\n");
241 			goto done;
242 		}
243 	}
244 	labels = LDNS_CALLOC(ldns_rdf*, labels_count + 2);
245 	if (!labels) {
246 		goto done;
247 	}
248 	labels[0] = ldns_dname_new_frm_str(LDNS_ROOT_LABEL_STR);
249 	labels[1] = ldns_rdf_clone(name);
250 	for(i = 2 ; i < (ssize_t)labels_count + 2; i++) {
251 		labels[i] = ldns_dname_left_chop(labels[i - 1]);
252 	}
253 
254 	/* get the nameserver for the label
255 	 * ask: dnskey and ds for the label
256 	 */
257 	for(i = (ssize_t)labels_count + 1; i > 0; i--) {
258 		status = ldns_resolver_send(&local_p, res, labels[i], LDNS_RR_TYPE_NS, c, 0);
259 		if (status != LDNS_STATUS_OK) {
260 			fprintf(stderr, "Error sending query: %s\n", ldns_get_errorstr_by_id(status));
261 			result = status;
262 			goto done;
263 		}
264 
265 		/* TODO: handle status */
266 
267 		if (verbosity >= 5) {
268 			ldns_pkt_print(stdout, local_p);
269 		}
270 
271 		new_nss = ldns_pkt_rr_list_by_type(local_p,
272 					LDNS_RR_TYPE_NS, LDNS_SECTION_ANSWER);
273  		if (!new_nss) {
274 			/* if it's a delegation, servers put them in the auth section */
275 			new_nss = ldns_pkt_rr_list_by_type(local_p,
276 					LDNS_RR_TYPE_NS, LDNS_SECTION_AUTHORITY);
277 		}
278 
279 		/* if this is the final step there might not be nameserver records
280 		   of course if the data is in the apex, there are, so cover both
281 		   cases */
282 		if (new_nss || i > 1) {
283 			for(j = 0; j < ldns_rr_list_rr_count(new_nss); j++) {
284 				ns_rr = ldns_rr_list_rr(new_nss, j);
285 				pop = ldns_rr_rdf(ns_rr, 0);
286 				if (!pop) {
287 					printf("nopo\n");
288 					break;
289 				}
290 				/* retrieve it's addresses */
291 				/* trust glue? */
292 				new_ns_addr = NULL;
293 				if (ldns_dname_is_subdomain(pop, labels[i])) {
294 					new_ns_addr = ldns_pkt_rr_list_by_name_and_type(local_p, pop, LDNS_RR_TYPE_A, LDNS_SECTION_ADDITIONAL);
295 				}
296 				if (!new_ns_addr || ldns_rr_list_rr_count(new_ns_addr) == 0) {
297 					new_ns_addr = ldns_get_rr_list_addr_by_name(res, pop, c, 0);
298 				}
299 				if (!new_ns_addr || ldns_rr_list_rr_count(new_ns_addr) == 0) {
300 					new_ns_addr = ldns_get_rr_list_addr_by_name(local_res, pop, c, 0);
301 				}
302 
303 				if (new_ns_addr) {
304 					old_ns_addr = ns_addr;
305 					ns_addr = ldns_rr_list_cat_clone(ns_addr, new_ns_addr);
306 					ldns_rr_list_deep_free(old_ns_addr);
307 				}
308 				ldns_rr_list_deep_free(new_ns_addr);
309 			}
310 			ldns_rr_list_deep_free(new_nss);
311 
312 			if (ns_addr) {
313 				remove_resolver_nameservers(res);
314 
315 				if (ldns_resolver_push_nameserver_rr_list(res, ns_addr) !=
316 						LDNS_STATUS_OK) {
317 					error("Error adding new nameservers");
318 					ldns_pkt_free(local_p);
319 					goto done;
320 				}
321 				ldns_rr_list_deep_free(ns_addr);
322 			} else {
323 				status = ldns_verify_denial(local_p, labels[i], LDNS_RR_TYPE_NS, &nsec_rrs, &nsec_rr_sigs);
324 
325 				/* verify the nsec3 themselves*/
326 				if (verbosity >= 4) {
327 					printf("NSEC(3) Records to verify:\n");
328 					ldns_rr_list_print(stdout, nsec_rrs);
329 					printf("With signatures:\n");
330 					ldns_rr_list_print(stdout, nsec_rr_sigs);
331 					printf("correct keys:\n");
332 					ldns_rr_list_print(stdout, correct_key_list);
333 				}
334 
335 				if (status == LDNS_STATUS_OK) {
336 					if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, trusted_keys, NULL)) == LDNS_STATUS_OK) {
337 						fprintf(stdout, "%s ", TRUST);
338 						fprintf(stdout, "Existence denied: ");
339 						ldns_rdf_print(stdout, labels[i]);
340 	/*
341 						if (descriptor && descriptor->_name) {
342 							printf(" %s", descriptor->_name);
343 						} else {
344 							printf(" TYPE%u", t);
345 						}
346 	*/					fprintf(stdout, " NS\n");
347 					} else if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, correct_key_list, NULL)) == LDNS_STATUS_OK) {
348 						fprintf(stdout, "%s ", SELF);
349 						fprintf(stdout, "Existence denied: ");
350 						ldns_rdf_print(stdout, labels[i]);
351 	/*
352 						if (descriptor && descriptor->_name) {
353 							printf(" %s", descriptor->_name);
354 						} else {
355 							printf(" TYPE%u", t);
356 						}
357 	*/
358 						fprintf(stdout, " NS\n");
359 					} else {
360 						fprintf(stdout, "%s ", BOGUS);
361 						result = 1;
362 						printf(";; Error verifying denial of existence for name ");
363 						ldns_rdf_print(stdout, labels[i]);
364 	/*
365 						printf(" type ");
366 						if (descriptor && descriptor->_name) {
367 							printf("%s", descriptor->_name);
368 						} else {
369 							printf("TYPE%u", t);
370 						}
371 	*/					printf("NS: %s\n", ldns_get_errorstr_by_id(st));
372 					}
373 				} else {
374 					fprintf(stdout, "%s ", BOGUS);
375 					result = 1;
376 					printf(";; Error verifying denial of existence for name ");
377 					ldns_rdf_print(stdout, labels[i]);
378 					printf("NS: %s\n", ldns_get_errorstr_by_id(status));
379 				}
380 
381 				/* there might be an empty non-terminal, in which case we need to continue */
382 				ent = false;
383 				for (j = 0; j < ldns_rr_list_rr_count(nsec_rrs); j++) {
384 					nsecrr = ldns_rr_list_rr(nsec_rrs, j);
385 					/* For NSEC when the next name is a subdomain of the question */
386 					if (ldns_rr_get_type(nsecrr) == LDNS_RR_TYPE_NSEC &&
387 							ldns_dname_is_subdomain(ldns_rr_rdf(nsecrr, 0), labels[i])) {
388 						ent = true;
389 
390 					/* For NSEC3, the hash matches the name and the type bitmap is empty*/
391 					} else if (ldns_rr_get_type(nsecrr) == LDNS_RR_TYPE_NSEC3) {
392 						hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsecrr, labels[i]);
393 						label0 = ldns_dname_label(ldns_rr_owner(nsecrr), 0);
394 						if (hashed_name && label0 &&
395 								ldns_dname_compare(hashed_name, label0) == 0 &&
396 								ldns_nsec3_bitmap(nsecrr) == NULL) {
397 							ent = true;
398 						}
399 						if (label0) {
400 							LDNS_FREE(label0);
401 						}
402 						if (hashed_name) {
403 							LDNS_FREE(hashed_name);
404 						}
405 					}
406 				}
407 				if (!ent) {
408 					ldns_rr_list_deep_free(nsec_rrs);
409 					ldns_rr_list_deep_free(nsec_rr_sigs);
410 					ldns_pkt_free(local_p);
411 					goto done;
412 				} else {
413 					printf(";; There is an empty non-terminal here, continue\n");
414 					continue;
415 				}
416 			}
417 
418 			if (ldns_resolver_nameserver_count(res) == 0) {
419 				error("No nameservers found for this node");
420 				goto done;
421 			}
422 		}
423 		ldns_pkt_free(local_p);
424 
425 		fprintf(stdout, ";; Domain: ");
426 		ldns_rdf_print(stdout, labels[i]);
427 		fprintf(stdout, "\n");
428 
429 		/* retrieve keys for current domain, and verify them
430 		   if they match an already trusted DS, or if one of the
431 		   keys used to sign these is trusted, add the keys to
432 		   the trusted list */
433 		p = get_dnssec_pkt(res, labels[i], LDNS_RR_TYPE_DNSKEY);
434 		(void) get_key(p, labels[i], &key_list, &key_sig_list);
435 		if (key_sig_list) {
436 			if (key_list) {
437 				current_correct_keys = ldns_rr_list_new();
438 				if ((st = ldns_verify(key_list, key_sig_list, key_list, current_correct_keys)) ==
439 						LDNS_STATUS_OK) {
440 					/* add all signed keys (don't just add current_correct, you'd miss
441 					 * the zsk's then */
442 					for (j = 0; j < ldns_rr_list_rr_count(key_list); j++) {
443 						ldns_rr_list_push_rr(correct_key_list, ldns_rr_clone(ldns_rr_list_rr(key_list, j)));
444 					}
445 
446 					/* check whether these keys were signed
447 					 * by a trusted keys. if so, these
448 					 * keys are also trusted */
449 					new_keys_trusted = false;
450 					for (k = 0; k < ldns_rr_list_rr_count(current_correct_keys); k++) {
451 						for (j = 0; j < ldns_rr_list_rr_count(trusted_ds_rrs); j++) {
452 							if (ldns_rr_compare_ds(ldns_rr_list_rr(current_correct_keys, k),
453 								    ldns_rr_list_rr(trusted_ds_rrs, j))) {
454 								new_keys_trusted = true;
455 							}
456 						}
457 					}
458 
459 					/* also all keys are trusted if one of the current correct keys is trusted */
460 					for (k = 0; k < ldns_rr_list_rr_count(current_correct_keys); k++) {
461 						for (j = 0; j < ldns_rr_list_rr_count(trusted_keys); j++) {
462 							if (ldns_rr_compare(ldns_rr_list_rr(current_correct_keys, k),
463 								            ldns_rr_list_rr(trusted_keys, j)) == 0) {
464 								            new_keys_trusted = true;
465 							}
466 						}
467 					}
468 
469 
470 					if (new_keys_trusted) {
471 						ldns_rr_list_push_rr_list(trusted_keys, key_list);
472 						print_rr_list_abbr(stdout, key_list, TRUST);
473 						ldns_rr_list_free(key_list);
474 						key_list = NULL;
475 					} else {
476 						if (verbosity >= 2) {
477 							printf(";; Signature ok but no chain to a trusted key or ds record\n");
478 						}
479 						print_rr_list_abbr(stdout, key_list, SELF);
480 						ldns_rr_list_deep_free(key_list);
481 						key_list = NULL;
482 					}
483 				} else {
484 					print_rr_list_abbr(stdout, key_list, BOGUS);
485 					result = 2;
486 					ldns_rr_list_deep_free(key_list);
487 					key_list = NULL;
488 				}
489 				ldns_rr_list_free(current_correct_keys);
490 				current_correct_keys = NULL;
491 			} else {
492 				printf(";; No DNSKEY record found for ");
493 				ldns_rdf_print(stdout, labels[i]);
494 				printf("\n");
495 			}
496 		}
497 
498 		ldns_pkt_free(p);
499 		ldns_rr_list_deep_free(key_sig_list);
500 		key_sig_list = NULL;
501 
502 		/* check the DS records for the next child domain */
503 		if (i > 1) {
504 			p = get_dnssec_pkt(res, labels[i-1], LDNS_RR_TYPE_DS);
505 			(void) get_ds(p, labels[i-1], &ds_list, &ds_sig_list);
506 			if (!ds_list) {
507 				ldns_rr_list_deep_free(ds_sig_list);
508 				(void) get_dnssec_rr( p, labels[i-1]
509 				                    , LDNS_RR_TYPE_CNAME
510 				                    , &ds_list, &ds_sig_list);
511 				if (ds_list) {
512 					st = ldns_verify( ds_list, ds_sig_list
513 					                , correct_key_list
514 					                , current_correct_keys);
515 
516 					if (st == LDNS_STATUS_OK) {
517 						printf(";; No DS record found "
518 						       "for ");
519 						ldns_rdf_print(stdout,
520 							labels[i-1]);
521 						printf(", but valid CNAME");
522 					} else {
523 						printf(BOGUS " Unable to verify "
524 						       "denial of existence for ");
525 						ldns_rdf_print(stdout,
526 							labels[i-1]);
527 						printf(", because of BOGUS CNAME");
528 					}
529 					printf("\n");
530 					ldns_rr_list_deep_free(ds_sig_list);
531 					ldns_pkt_free(p);
532 					ldns_rr_list_deep_free(ds_list);
533 					ds_list = NULL;
534 					ds_sig_list = NULL;
535 					p = NULL;
536 				} else {
537 					ldns_rr_list_deep_free(ds_sig_list);
538 					ldns_pkt_free(p);
539 					p = get_dnssec_pkt(res, name,
540 							LDNS_RR_TYPE_DNSKEY);
541 					(void) get_ds(p, NULL
542 					             , &ds_list, &ds_sig_list);
543 				}
544 			}
545 			if (ds_sig_list) {
546 				if (ds_list) {
547 					if (verbosity >= 4) {
548 						printf("VERIFYING:\n");
549 						printf("DS LIST:\n");
550 						ldns_rr_list_print(stdout, ds_list);
551 						printf("SIGS:\n");
552 						ldns_rr_list_print(stdout, ds_sig_list);
553 						printf("KEYS:\n");
554 						ldns_rr_list_print(stdout, correct_key_list);
555 					}
556 
557 					current_correct_keys = ldns_rr_list_new();
558 
559 					if ((st = ldns_verify(ds_list, ds_sig_list, correct_key_list, current_correct_keys)) ==
560 							LDNS_STATUS_OK) {
561 						/* if the ds is signed by a trusted key and a key from correct keys
562 						   matches that ds, add that key to the trusted keys */
563 						new_keys_trusted = false;
564 						if (verbosity >= 2) {
565 							printf("Checking if signing key is trusted:\n");
566 						}
567 						for (j = 0; j < ldns_rr_list_rr_count(current_correct_keys); j++) {
568 							if (verbosity >= 2) {
569 								printf("New key: ");
570 								ldns_rr_print(stdout, ldns_rr_list_rr(current_correct_keys, j));
571 							}
572 							for (k = 0; k < ldns_rr_list_rr_count(trusted_keys); k++) {
573 								if (verbosity >= 2) {
574 									printf("\tTrusted key: ");
575 									ldns_rr_print(stdout, ldns_rr_list_rr(trusted_keys, k));
576 								}
577 								if (ldns_rr_compare(ldns_rr_list_rr(current_correct_keys, j),
578 								    ldns_rr_list_rr(trusted_keys, k)) == 0) {
579 								    	if (verbosity >= 2) {
580 								    		printf("Key is now trusted!\n");
581 									}
582 									for (l = 0; l < ldns_rr_list_rr_count(ds_list); l++) {
583 										ldns_rr_list_push_rr(trusted_ds_rrs, ldns_rr_clone(ldns_rr_list_rr(ds_list, l)));
584 										new_keys_trusted = true;
585 									}
586 								}
587 							}
588 						}
589 						if (new_keys_trusted) {
590 							print_rr_list_abbr(stdout, ds_list, TRUST);
591 						} else {
592 							print_rr_list_abbr(stdout, ds_list, SELF);
593 						}
594 					} else {
595 						result = 3;
596 						print_rr_list_abbr(stdout, ds_list, BOGUS);
597 					}
598 
599 					ldns_rr_list_free(current_correct_keys);
600 					current_correct_keys = NULL;
601 				} else {
602 					/* wait apparently there were no keys either, go back to the ds packet */
603 					ldns_pkt_free(p);
604 					ldns_rr_list_deep_free(ds_sig_list);
605 					p = get_dnssec_pkt(res, labels[i-1], LDNS_RR_TYPE_DS);
606 					(void) get_ds(p, labels[i-1], &ds_list, &ds_sig_list);
607 
608 					status = ldns_verify_denial(p, labels[i-1], LDNS_RR_TYPE_DS, &nsec_rrs, &nsec_rr_sigs);
609 
610 					if (verbosity >= 4) {
611 						printf("NSEC(3) Records to verify:\n");
612 						ldns_rr_list_print(stdout, nsec_rrs);
613 						printf("With signatures:\n");
614 						ldns_rr_list_print(stdout, nsec_rr_sigs);
615 						printf("correct keys:\n");
616 						ldns_rr_list_print(stdout, correct_key_list);
617 					}
618 
619 					if (status == LDNS_STATUS_OK) {
620 						if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, trusted_keys, NULL)) == LDNS_STATUS_OK) {
621 							fprintf(stdout, "%s ", TRUST);
622 							fprintf(stdout, "Existence denied: ");
623 							ldns_rdf_print(stdout, labels[i-1]);
624 							printf(" DS");
625 							fprintf(stdout, "\n");
626 						} else if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, correct_key_list, NULL)) == LDNS_STATUS_OK) {
627 							fprintf(stdout, "%s ", SELF);
628 							fprintf(stdout, "Existence denied: ");
629 							ldns_rdf_print(stdout, labels[i-1]);
630 							printf(" DS");
631 							fprintf(stdout, "\n");
632 						} else {
633 							result = 4;
634 							fprintf(stdout, "%s ", BOGUS);
635 							printf("Error verifying denial of existence for ");
636 							ldns_rdf_print(stdout, labels[i-1]);
637 							printf(" DS");
638 							printf(": %s\n", ldns_get_errorstr_by_id(st));
639 						}
640 
641 
642 					} else {
643 						if (status == LDNS_STATUS_CRYPTO_NO_RRSIG) {
644 							printf(";; No DS for ");
645 							ldns_rdf_print(stdout, labels[i - 1]);
646 						} else {
647 							printf(BOGUS " Unable to verify denial of existence for ");
648 							ldns_rdf_print(stdout, labels[i - 1]);
649 							printf(" DS: %s\n", ldns_get_errorstr_by_id(status));
650 						}
651 					}
652 					if (verbosity >= 2) {
653 						printf(";; No ds record for delegation\n");
654 					}
655 				}
656 			}
657 			ldns_rr_list_deep_free(ds_list);
658 			ldns_pkt_free(p);
659 		} else {
660 			/* if this is the last label, just verify the data and stop */
661 			p = get_dnssec_pkt(res, labels[i], t);
662 			(void) get_dnssec_rr(p, labels[i], t, &dataset, &key_sig_list);
663 			if (dataset && ldns_rr_list_rr_count(dataset) > 0) {
664 				if (key_sig_list && ldns_rr_list_rr_count(key_sig_list) > 0) {
665 
666 					/* If this is a wildcard, you must be able to deny exact match */
667 					if ((st = ldns_verify(dataset, key_sig_list, trusted_keys, NULL)) == LDNS_STATUS_OK) {
668 						fprintf(stdout, "%s ", TRUST);
669 						ldns_rr_list_print(stdout, dataset);
670 					} else if ((st = ldns_verify(dataset, key_sig_list, correct_key_list, NULL)) == LDNS_STATUS_OK) {
671 						fprintf(stdout, "%s ", SELF);
672 						ldns_rr_list_print(stdout, dataset);
673 					} else {
674 						result = 5;
675 						fprintf(stdout, "%s ", BOGUS);
676 						ldns_rr_list_print(stdout, dataset);
677 						printf(";; Error: %s\n", ldns_get_errorstr_by_id(st));
678 					}
679 				} else {
680 					fprintf(stdout, "%s ", UNSIGNED);
681 					ldns_rr_list_print(stdout, dataset);
682 				}
683 				ldns_rr_list_deep_free(dataset);
684 			} else {
685 				status = ldns_verify_denial(p, name, t, &nsec_rrs, &nsec_rr_sigs);
686 				if (status == LDNS_STATUS_OK) {
687 					/* verify the nsec3 themselves*/
688 					if (verbosity >= 5) {
689 						printf("NSEC(3) Records to verify:\n");
690 						ldns_rr_list_print(stdout, nsec_rrs);
691 						printf("With signatures:\n");
692 						ldns_rr_list_print(stdout, nsec_rr_sigs);
693 						printf("correct keys:\n");
694 						ldns_rr_list_print(stdout, correct_key_list);
695 /*
696 						printf("trusted keys at %p:\n", trusted_keys);
697 						ldns_rr_list_print(stdout, trusted_keys);
698 */					}
699 
700 					if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, trusted_keys, NULL)) == LDNS_STATUS_OK) {
701 						fprintf(stdout, "%s ", TRUST);
702 						fprintf(stdout, "Existence denied: ");
703 						ldns_rdf_print(stdout, name);
704 						if (descriptor && descriptor->_name) {
705 							printf(" %s", descriptor->_name);
706 						} else {
707 							printf(" TYPE%u", t);
708 						}
709 						fprintf(stdout, "\n");
710 					} else if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, correct_key_list, NULL)) == LDNS_STATUS_OK) {
711 						fprintf(stdout, "%s ", SELF);
712 						fprintf(stdout, "Existence denied: ");
713 						ldns_rdf_print(stdout, name);
714 						if (descriptor && descriptor->_name) {
715 							printf(" %s", descriptor->_name);
716 						} else {
717 							printf(" TYPE%u", t);
718 						}
719 						fprintf(stdout, "\n");
720 					} else {
721 						result = 6;
722 						fprintf(stdout, "%s ", BOGUS);
723 						printf("Error verifying denial of existence for ");
724 						ldns_rdf_print(stdout, name);
725 						printf(" type ");
726 						if (descriptor && descriptor->_name) {
727 							printf("%s", descriptor->_name);
728 						} else {
729 							printf("TYPE%u", t);
730 						}
731 						printf(": %s\n", ldns_get_errorstr_by_id(st));
732 					}
733 
734 					ldns_rr_list_deep_free(nsec_rrs);
735 					ldns_rr_list_deep_free(nsec_rr_sigs);
736 				} else {
737 /*
738 */
739 					if (status == LDNS_STATUS_CRYPTO_NO_RRSIG) {
740 						printf("%s ", UNSIGNED);
741 						printf("No data found for: ");
742 						ldns_rdf_print(stdout, name);
743 						printf(" type ");
744 						if (descriptor && descriptor->_name) {
745 							printf("%s", descriptor->_name);
746 						} else {
747 							printf("TYPE%u", t);
748 						}
749 						printf("\n");
750 					} else {
751 						printf(BOGUS " Unable to verify denial of existence for ");
752 						ldns_rdf_print(stdout, name);
753 						printf(" type ");
754 						if (descriptor && descriptor->_name) {
755 							printf("%s", descriptor->_name);
756 						} else {
757 							printf("TYPE%u", t);
758 						}
759 						printf("\n");
760 					}
761 
762 				}
763 			}
764 			ldns_pkt_free(p);
765 		}
766 
767 		new_nss = NULL;
768 		ns_addr = NULL;
769 		ldns_rr_list_deep_free(key_list);
770 		key_list = NULL;
771 		ldns_rr_list_deep_free(key_sig_list);
772 		key_sig_list = NULL;
773 		ds_list = NULL;
774 		ldns_rr_list_deep_free(ds_sig_list);
775 		ds_sig_list = NULL;
776 	}
777 	printf(";;" SELF " self sig OK; " BOGUS " bogus; " TRUST " trusted; " UNSIGNED " unsigned\n");
778 	/* verbose mode?
779 	printf("Trusted keys:\n");
780 	ldns_rr_list_print(stdout, trusted_keys);
781 	printf("trusted dss:\n");
782 	ldns_rr_list_print(stdout, trusted_ds_rrs);
783 	*/
784 
785 	done:
786 	ldns_rr_list_deep_free(trusted_ds_rrs);
787 	ldns_rr_list_deep_free(correct_key_list);
788 	ldns_resolver_deep_free(res);
789 	if (labels) {
790 		for(i = 0 ; i < (ssize_t)labels_count + 2; i++) {
791 			ldns_rdf_deep_free(labels[i]);
792 		}
793 		LDNS_FREE(labels);
794 	}
795 	return result;
796 }
797 #endif /* HAVE_SSL */
798