xref: /freebsd/contrib/ldns/drill/securetrace.c (revision 5afab0e5e56fe90a378fb57249600e7924e1cab2)
17b5038d7SDag-Erling Smørgrav /*
27b5038d7SDag-Erling Smørgrav  * securechasetrace.c
37b5038d7SDag-Erling Smørgrav  * Where all the hard work concerning secure tracing is done
47b5038d7SDag-Erling Smørgrav  *
57b5038d7SDag-Erling Smørgrav  * (c) 2005, 2006 NLnet Labs
67b5038d7SDag-Erling Smørgrav  *
77b5038d7SDag-Erling Smørgrav  * See the file LICENSE for the license
87b5038d7SDag-Erling Smørgrav  *
97b5038d7SDag-Erling Smørgrav  */
107b5038d7SDag-Erling Smørgrav 
117b5038d7SDag-Erling Smørgrav #include "drill.h"
127b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h>
137b5038d7SDag-Erling Smørgrav 
147b5038d7SDag-Erling Smørgrav #define SELF "[S]"  /* self sig ok */
157b5038d7SDag-Erling Smørgrav #define TRUST "[T]" /* chain from parent */
167b5038d7SDag-Erling Smørgrav #define BOGUS "[B]" /* bogus */
177b5038d7SDag-Erling Smørgrav #define UNSIGNED "[U]" /* no relevant dnssec data found */
187b5038d7SDag-Erling Smørgrav 
197b5038d7SDag-Erling Smørgrav #if 0
207b5038d7SDag-Erling Smørgrav /* See if there is a key/ds in trusted that matches
217b5038d7SDag-Erling Smørgrav  * a ds in *ds.
227b5038d7SDag-Erling Smørgrav  */
237b5038d7SDag-Erling Smørgrav static ldns_rr_list *
247b5038d7SDag-Erling Smørgrav ds_key_match(ldns_rr_list *ds, ldns_rr_list *trusted)
257b5038d7SDag-Erling Smørgrav {
267b5038d7SDag-Erling Smørgrav 	size_t i, j;
277b5038d7SDag-Erling Smørgrav 	bool match;
287b5038d7SDag-Erling Smørgrav 	ldns_rr *rr_i, *rr_j;
297b5038d7SDag-Erling Smørgrav 	ldns_rr_list *keys;
307b5038d7SDag-Erling Smørgrav 
317b5038d7SDag-Erling Smørgrav 	if (!trusted || !ds) {
327b5038d7SDag-Erling Smørgrav 		return NULL;
337b5038d7SDag-Erling Smørgrav 	}
347b5038d7SDag-Erling Smørgrav 
357b5038d7SDag-Erling Smørgrav 	match = false;
367b5038d7SDag-Erling Smørgrav 	keys = ldns_rr_list_new();
377b5038d7SDag-Erling Smørgrav 	if (!keys) {
387b5038d7SDag-Erling Smørgrav 		return NULL;
397b5038d7SDag-Erling Smørgrav 	}
407b5038d7SDag-Erling Smørgrav 
417b5038d7SDag-Erling Smørgrav 	if (!ds || !trusted) {
427b5038d7SDag-Erling Smørgrav 		return NULL;
437b5038d7SDag-Erling Smørgrav 	}
447b5038d7SDag-Erling Smørgrav 
457b5038d7SDag-Erling Smørgrav 	for (i = 0; i < ldns_rr_list_rr_count(trusted); i++) {
467b5038d7SDag-Erling Smørgrav 		rr_i = ldns_rr_list_rr(trusted, i);
477b5038d7SDag-Erling Smørgrav 		for (j = 0; j < ldns_rr_list_rr_count(ds); j++) {
487b5038d7SDag-Erling Smørgrav 
497b5038d7SDag-Erling Smørgrav 			rr_j = ldns_rr_list_rr(ds, j);
507b5038d7SDag-Erling Smørgrav 			if (ldns_rr_compare_ds(rr_i, rr_j)) {
517b5038d7SDag-Erling Smørgrav 				match = true;
527b5038d7SDag-Erling Smørgrav 				/* only allow unique RRs to match */
537b5038d7SDag-Erling Smørgrav 				ldns_rr_set_push_rr(keys, rr_i);
547b5038d7SDag-Erling Smørgrav 			}
557b5038d7SDag-Erling Smørgrav 		}
567b5038d7SDag-Erling Smørgrav 	}
577b5038d7SDag-Erling Smørgrav 	if (match) {
587b5038d7SDag-Erling Smørgrav 		return keys;
597b5038d7SDag-Erling Smørgrav 	} else {
607b5038d7SDag-Erling Smørgrav 		return NULL;
617b5038d7SDag-Erling Smørgrav 	}
627b5038d7SDag-Erling Smørgrav }
637b5038d7SDag-Erling Smørgrav #endif
647b5038d7SDag-Erling Smørgrav 
65986ba33cSDag-Erling Smørgrav static ldns_pkt *
get_dnssec_pkt(ldns_resolver * r,ldns_rdf * name,ldns_rr_type t)667b5038d7SDag-Erling Smørgrav get_dnssec_pkt(ldns_resolver *r, ldns_rdf *name, ldns_rr_type t)
677b5038d7SDag-Erling Smørgrav {
687b5038d7SDag-Erling Smørgrav 	ldns_pkt *p = NULL;
697b5038d7SDag-Erling Smørgrav 	p = ldns_resolver_query(r, name, t, LDNS_RR_CLASS_IN, 0);
707b5038d7SDag-Erling Smørgrav 	if (!p) {
717b5038d7SDag-Erling Smørgrav 		return NULL;
727b5038d7SDag-Erling Smørgrav 	} else {
737b5038d7SDag-Erling Smørgrav 		if (verbosity >= 5) {
747b5038d7SDag-Erling Smørgrav 			ldns_pkt_print(stdout, p);
757b5038d7SDag-Erling Smørgrav 		}
767b5038d7SDag-Erling Smørgrav 		return p;
777b5038d7SDag-Erling Smørgrav 	}
787b5038d7SDag-Erling Smørgrav }
797b5038d7SDag-Erling Smørgrav 
807b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
817b5038d7SDag-Erling Smørgrav /*
827b5038d7SDag-Erling Smørgrav  * retrieve keys for this zone
837b5038d7SDag-Erling Smørgrav  */
847b5038d7SDag-Erling Smørgrav static ldns_pkt_type
get_key(ldns_pkt * p,ldns_rdf * apexname,ldns_rr_list ** rrlist,ldns_rr_list ** opt_sig)857b5038d7SDag-Erling Smørgrav get_key(ldns_pkt *p, ldns_rdf *apexname, ldns_rr_list **rrlist, ldns_rr_list **opt_sig)
867b5038d7SDag-Erling Smørgrav {
877b5038d7SDag-Erling Smørgrav 	return get_dnssec_rr(p, apexname, LDNS_RR_TYPE_DNSKEY, rrlist, opt_sig);
887b5038d7SDag-Erling Smørgrav }
897b5038d7SDag-Erling Smørgrav 
907b5038d7SDag-Erling Smørgrav /*
917b5038d7SDag-Erling Smørgrav  * check to see if we can find a DS rrset here which we can then follow
927b5038d7SDag-Erling Smørgrav  */
937b5038d7SDag-Erling Smørgrav static ldns_pkt_type
get_ds(ldns_pkt * p,ldns_rdf * ownername,ldns_rr_list ** rrlist,ldns_rr_list ** opt_sig)947b5038d7SDag-Erling Smørgrav get_ds(ldns_pkt *p, ldns_rdf *ownername, ldns_rr_list **rrlist, ldns_rr_list **opt_sig)
957b5038d7SDag-Erling Smørgrav {
967b5038d7SDag-Erling Smørgrav 	return get_dnssec_rr(p, ownername, LDNS_RR_TYPE_DS, rrlist, opt_sig);
977b5038d7SDag-Erling Smørgrav }
987b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
997b5038d7SDag-Erling Smørgrav 
100986ba33cSDag-Erling Smørgrav static void
remove_resolver_nameservers(ldns_resolver * res)1017b5038d7SDag-Erling Smørgrav remove_resolver_nameservers(ldns_resolver *res)
1027b5038d7SDag-Erling Smørgrav {
1037b5038d7SDag-Erling Smørgrav 	ldns_rdf *pop;
1047b5038d7SDag-Erling Smørgrav 
1057b5038d7SDag-Erling Smørgrav 	/* remove the old nameserver from the resolver */
1067b5038d7SDag-Erling Smørgrav 	while((pop = ldns_resolver_pop_nameserver(res))) {
1077b5038d7SDag-Erling Smørgrav 		ldns_rdf_deep_free(pop);
1087b5038d7SDag-Erling Smørgrav 	}
1097b5038d7SDag-Erling Smørgrav 
1107b5038d7SDag-Erling Smørgrav }
1117b5038d7SDag-Erling Smørgrav 
1127b5038d7SDag-Erling Smørgrav /*ldns_pkt **/
1137b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
1147b5038d7SDag-Erling Smørgrav int
do_secure_trace(ldns_resolver * local_res,ldns_rdf * name,ldns_rr_type t,ldns_rr_class c,ldns_rr_list * trusted_keys,ldns_rdf * start_name)1157b5038d7SDag-Erling Smørgrav do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
1167b5038d7SDag-Erling Smørgrav                 ldns_rr_class c, ldns_rr_list *trusted_keys, ldns_rdf *start_name
1177b5038d7SDag-Erling Smørgrav                )
1187b5038d7SDag-Erling Smørgrav {
1197b5038d7SDag-Erling Smørgrav 	ldns_resolver *res;
1207b5038d7SDag-Erling Smørgrav 	ldns_pkt *p, *local_p;
1217b5038d7SDag-Erling Smørgrav 	ldns_rr_list *new_nss;
1227b5038d7SDag-Erling Smørgrav 	ldns_rr_list *ns_addr;
1237b5038d7SDag-Erling Smørgrav 	ldns_rdf *pop;
1247b5038d7SDag-Erling Smørgrav 	ldns_rdf **labels = NULL;
1257b5038d7SDag-Erling Smørgrav 	ldns_status status, st;
1267b5038d7SDag-Erling Smørgrav 	ssize_t i;
1277b5038d7SDag-Erling Smørgrav 	size_t j;
1287b5038d7SDag-Erling Smørgrav 	size_t k;
1297b5038d7SDag-Erling Smørgrav 	size_t l;
13017d15b25SDag-Erling Smørgrav 	uint8_t labels_count = 0;
1317b5038d7SDag-Erling Smørgrav 
1327b5038d7SDag-Erling Smørgrav 	/* dnssec */
1337b5038d7SDag-Erling Smørgrav 	ldns_rr_list *key_list;
1347b5038d7SDag-Erling Smørgrav 	ldns_rr_list *key_sig_list;
1357b5038d7SDag-Erling Smørgrav 	ldns_rr_list *ds_list;
1367b5038d7SDag-Erling Smørgrav 	ldns_rr_list *ds_sig_list;
1377b5038d7SDag-Erling Smørgrav 	ldns_rr_list *correct_key_list;
1387b5038d7SDag-Erling Smørgrav 	ldns_rr_list *trusted_ds_rrs;
1397b5038d7SDag-Erling Smørgrav 	bool new_keys_trusted = false;
140*5afab0e5SDag-Erling Smørgrav 	ldns_rr_list *current_correct_keys = NULL;
1417b5038d7SDag-Erling Smørgrav 	ldns_rr_list *dataset;
1427b5038d7SDag-Erling Smørgrav 
1437b5038d7SDag-Erling Smørgrav 	ldns_rr_list *nsec_rrs = NULL;
1447b5038d7SDag-Erling Smørgrav 	ldns_rr_list *nsec_rr_sigs = NULL;
1457b5038d7SDag-Erling Smørgrav 
1467b5038d7SDag-Erling Smørgrav 	/* empty non-terminal check */
1477b5038d7SDag-Erling Smørgrav 	bool ent;
14817d15b25SDag-Erling Smørgrav 	ldns_rr  *nsecrr;      /* The nsec that proofs the non-terminal */
14917d15b25SDag-Erling Smørgrav 	ldns_rdf *hashed_name; /* The query hashed with nsec3 params */
15017d15b25SDag-Erling Smørgrav 	ldns_rdf *label0;      /* The first label of an nsec3 owner name */
1517b5038d7SDag-Erling Smørgrav 
1527b5038d7SDag-Erling Smørgrav 	/* glue handling */
1537b5038d7SDag-Erling Smørgrav 	ldns_rr_list *new_ns_addr;
1547b5038d7SDag-Erling Smørgrav 	ldns_rr_list *old_ns_addr;
1557b5038d7SDag-Erling Smørgrav 	ldns_rr *ns_rr;
1567b5038d7SDag-Erling Smørgrav 
1577b5038d7SDag-Erling Smørgrav 	int result = 0;
1587b5038d7SDag-Erling Smørgrav 
1597b5038d7SDag-Erling Smørgrav 	/* printing niceness */
1607b5038d7SDag-Erling Smørgrav 	const ldns_rr_descriptor *descriptor;
1617b5038d7SDag-Erling Smørgrav 
1627b5038d7SDag-Erling Smørgrav 	descriptor = ldns_rr_descript(t);
1637b5038d7SDag-Erling Smørgrav 
1647b5038d7SDag-Erling Smørgrav 	new_nss = NULL;
1657b5038d7SDag-Erling Smørgrav 	ns_addr = NULL;
1667b5038d7SDag-Erling Smørgrav 	key_list = NULL;
1677b5038d7SDag-Erling Smørgrav 	ds_list = NULL;
1687b5038d7SDag-Erling Smørgrav 
1697b5038d7SDag-Erling Smørgrav 	p = NULL;
1707b5038d7SDag-Erling Smørgrav 	local_p = NULL;
1717b5038d7SDag-Erling Smørgrav 	res = ldns_resolver_new();
1727b5038d7SDag-Erling Smørgrav 	key_sig_list = NULL;
1737b5038d7SDag-Erling Smørgrav 	ds_sig_list = NULL;
1747b5038d7SDag-Erling Smørgrav 
1757b5038d7SDag-Erling Smørgrav 	if (!res) {
1767b5038d7SDag-Erling Smørgrav 		error("Memory allocation failed");
1777b5038d7SDag-Erling Smørgrav 		result = -1;
1787b5038d7SDag-Erling Smørgrav 		return result;
1797b5038d7SDag-Erling Smørgrav 	}
1807b5038d7SDag-Erling Smørgrav 
1817b5038d7SDag-Erling Smørgrav 	correct_key_list = ldns_rr_list_new();
1827b5038d7SDag-Erling Smørgrav 	if (!correct_key_list) {
1837b5038d7SDag-Erling Smørgrav 		error("Memory allocation failed");
1847b5038d7SDag-Erling Smørgrav 		result = -1;
1857b5038d7SDag-Erling Smørgrav 		return result;
1867b5038d7SDag-Erling Smørgrav 	}
1877b5038d7SDag-Erling Smørgrav 
1887b5038d7SDag-Erling Smørgrav 	trusted_ds_rrs = ldns_rr_list_new();
1897b5038d7SDag-Erling Smørgrav 	if (!trusted_ds_rrs) {
1907b5038d7SDag-Erling Smørgrav 		error("Memory allocation failed");
1917b5038d7SDag-Erling Smørgrav 		result = -1;
1927b5038d7SDag-Erling Smørgrav 		return result;
1937b5038d7SDag-Erling Smørgrav 	}
1947b5038d7SDag-Erling Smørgrav         /* Add all preset trusted DS signatures to the list of trusted DS RRs. */
1957b5038d7SDag-Erling Smørgrav         for (j = 0; j < ldns_rr_list_rr_count(trusted_keys); j++) {
1967b5038d7SDag-Erling Smørgrav             ldns_rr* one_rr = ldns_rr_list_rr(trusted_keys, j);
1977b5038d7SDag-Erling Smørgrav             if (ldns_rr_get_type(one_rr)  == LDNS_RR_TYPE_DS) {
1987b5038d7SDag-Erling Smørgrav                 ldns_rr_list_push_rr(trusted_ds_rrs, ldns_rr_clone(one_rr));
1997b5038d7SDag-Erling Smørgrav             }
2007b5038d7SDag-Erling Smørgrav         }
2017b5038d7SDag-Erling Smørgrav 
2027b5038d7SDag-Erling Smørgrav 	/* transfer some properties of local_res to res */
2037b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_ip6(res,
2047b5038d7SDag-Erling Smørgrav 			ldns_resolver_ip6(local_res));
2057b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_port(res,
2067b5038d7SDag-Erling Smørgrav 			ldns_resolver_port(local_res));
2077b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_debug(res,
2087b5038d7SDag-Erling Smørgrav 			ldns_resolver_debug(local_res));
2097b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_fail(res,
2107b5038d7SDag-Erling Smørgrav 			ldns_resolver_fail(local_res));
2117b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_usevc(res,
2127b5038d7SDag-Erling Smørgrav 			ldns_resolver_usevc(local_res));
2137b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_random(res,
2147b5038d7SDag-Erling Smørgrav 			ldns_resolver_random(local_res));
21517d15b25SDag-Erling Smørgrav 	ldns_resolver_set_source(res,
21617d15b25SDag-Erling Smørgrav 			ldns_resolver_source(local_res));
2177b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_recursive(local_res, true);
2187b5038d7SDag-Erling Smørgrav 
2197b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_recursive(res, false);
2207b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_dnssec_cd(res, false);
2217b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_dnssec(res, true);
2227b5038d7SDag-Erling Smørgrav 
2237b5038d7SDag-Erling Smørgrav 	/* setup the root nameserver in the new resolver */
2247b5038d7SDag-Erling Smørgrav 	status = ldns_resolver_push_nameserver_rr_list(res, global_dns_root);
2257b5038d7SDag-Erling Smørgrav 	if (status != LDNS_STATUS_OK) {
2267b5038d7SDag-Erling Smørgrav 		printf("ERRRRR: %s\n", ldns_get_errorstr_by_id(status));
2277b5038d7SDag-Erling Smørgrav 		ldns_rr_list_print(stdout, global_dns_root);
2282787e39aSDag-Erling Smørgrav 		result = status;
2292787e39aSDag-Erling Smørgrav 		goto done;
2307b5038d7SDag-Erling Smørgrav 	}
2317b5038d7SDag-Erling Smørgrav 	labels_count = ldns_dname_label_count(name);
2327b5038d7SDag-Erling Smørgrav 	if (start_name) {
2337b5038d7SDag-Erling Smørgrav 		if (ldns_dname_is_subdomain(name, start_name)) {
2347b5038d7SDag-Erling Smørgrav 			labels_count -= ldns_dname_label_count(start_name);
2357b5038d7SDag-Erling Smørgrav 		} else {
2367b5038d7SDag-Erling Smørgrav 			fprintf(stderr, "Error; ");
2377b5038d7SDag-Erling Smørgrav 			ldns_rdf_print(stderr, name);
2387b5038d7SDag-Erling Smørgrav 			fprintf(stderr, " is not a subdomain of ");
2397b5038d7SDag-Erling Smørgrav 			ldns_rdf_print(stderr, start_name);
2407b5038d7SDag-Erling Smørgrav 			fprintf(stderr, "\n");
2417b5038d7SDag-Erling Smørgrav 			goto done;
2427b5038d7SDag-Erling Smørgrav 		}
2437b5038d7SDag-Erling Smørgrav 	}
244*5afab0e5SDag-Erling Smørgrav 	labels = LDNS_CALLOC(ldns_rdf*, labels_count + 2);
2457b5038d7SDag-Erling Smørgrav 	if (!labels) {
2467b5038d7SDag-Erling Smørgrav 		goto done;
2477b5038d7SDag-Erling Smørgrav 	}
2487b5038d7SDag-Erling Smørgrav 	labels[0] = ldns_dname_new_frm_str(LDNS_ROOT_LABEL_STR);
2497b5038d7SDag-Erling Smørgrav 	labels[1] = ldns_rdf_clone(name);
2507b5038d7SDag-Erling Smørgrav 	for(i = 2 ; i < (ssize_t)labels_count + 2; i++) {
2517b5038d7SDag-Erling Smørgrav 		labels[i] = ldns_dname_left_chop(labels[i - 1]);
2527b5038d7SDag-Erling Smørgrav 	}
2537b5038d7SDag-Erling Smørgrav 
2547b5038d7SDag-Erling Smørgrav 	/* get the nameserver for the label
2557b5038d7SDag-Erling Smørgrav 	 * ask: dnskey and ds for the label
2567b5038d7SDag-Erling Smørgrav 	 */
2577b5038d7SDag-Erling Smørgrav 	for(i = (ssize_t)labels_count + 1; i > 0; i--) {
2587b5038d7SDag-Erling Smørgrav 		status = ldns_resolver_send(&local_p, res, labels[i], LDNS_RR_TYPE_NS, c, 0);
259*5afab0e5SDag-Erling Smørgrav 		if (status != LDNS_STATUS_OK) {
260*5afab0e5SDag-Erling Smørgrav 			fprintf(stderr, "Error sending query: %s\n", ldns_get_errorstr_by_id(status));
261*5afab0e5SDag-Erling Smørgrav 			result = status;
262*5afab0e5SDag-Erling Smørgrav 			goto done;
263*5afab0e5SDag-Erling Smørgrav 		}
264*5afab0e5SDag-Erling Smørgrav 
265*5afab0e5SDag-Erling Smørgrav 		/* TODO: handle status */
2667b5038d7SDag-Erling Smørgrav 
2677b5038d7SDag-Erling Smørgrav 		if (verbosity >= 5) {
2687b5038d7SDag-Erling Smørgrav 			ldns_pkt_print(stdout, local_p);
2697b5038d7SDag-Erling Smørgrav 		}
2707b5038d7SDag-Erling Smørgrav 
2717b5038d7SDag-Erling Smørgrav 		new_nss = ldns_pkt_rr_list_by_type(local_p,
2727b5038d7SDag-Erling Smørgrav 					LDNS_RR_TYPE_NS, LDNS_SECTION_ANSWER);
2737b5038d7SDag-Erling Smørgrav  		if (!new_nss) {
2747b5038d7SDag-Erling Smørgrav 			/* if it's a delegation, servers put them in the auth section */
2757b5038d7SDag-Erling Smørgrav 			new_nss = ldns_pkt_rr_list_by_type(local_p,
2767b5038d7SDag-Erling Smørgrav 					LDNS_RR_TYPE_NS, LDNS_SECTION_AUTHORITY);
2777b5038d7SDag-Erling Smørgrav 		}
2787b5038d7SDag-Erling Smørgrav 
2797b5038d7SDag-Erling Smørgrav 		/* if this is the final step there might not be nameserver records
2807b5038d7SDag-Erling Smørgrav 		   of course if the data is in the apex, there are, so cover both
2817b5038d7SDag-Erling Smørgrav 		   cases */
2827b5038d7SDag-Erling Smørgrav 		if (new_nss || i > 1) {
2837b5038d7SDag-Erling Smørgrav 			for(j = 0; j < ldns_rr_list_rr_count(new_nss); j++) {
2847b5038d7SDag-Erling Smørgrav 				ns_rr = ldns_rr_list_rr(new_nss, j);
2857b5038d7SDag-Erling Smørgrav 				pop = ldns_rr_rdf(ns_rr, 0);
2867b5038d7SDag-Erling Smørgrav 				if (!pop) {
2877b5038d7SDag-Erling Smørgrav 					printf("nopo\n");
2887b5038d7SDag-Erling Smørgrav 					break;
2897b5038d7SDag-Erling Smørgrav 				}
2907b5038d7SDag-Erling Smørgrav 				/* retrieve it's addresses */
2917b5038d7SDag-Erling Smørgrav 				/* trust glue? */
2927b5038d7SDag-Erling Smørgrav 				new_ns_addr = NULL;
2937b5038d7SDag-Erling Smørgrav 				if (ldns_dname_is_subdomain(pop, labels[i])) {
2947b5038d7SDag-Erling Smørgrav 					new_ns_addr = ldns_pkt_rr_list_by_name_and_type(local_p, pop, LDNS_RR_TYPE_A, LDNS_SECTION_ADDITIONAL);
2957b5038d7SDag-Erling Smørgrav 				}
2967b5038d7SDag-Erling Smørgrav 				if (!new_ns_addr || ldns_rr_list_rr_count(new_ns_addr) == 0) {
2977b5038d7SDag-Erling Smørgrav 					new_ns_addr = ldns_get_rr_list_addr_by_name(res, pop, c, 0);
2987b5038d7SDag-Erling Smørgrav 				}
2997b5038d7SDag-Erling Smørgrav 				if (!new_ns_addr || ldns_rr_list_rr_count(new_ns_addr) == 0) {
3007b5038d7SDag-Erling Smørgrav 					new_ns_addr = ldns_get_rr_list_addr_by_name(local_res, pop, c, 0);
3017b5038d7SDag-Erling Smørgrav 				}
3027b5038d7SDag-Erling Smørgrav 
3037b5038d7SDag-Erling Smørgrav 				if (new_ns_addr) {
3047b5038d7SDag-Erling Smørgrav 					old_ns_addr = ns_addr;
3057b5038d7SDag-Erling Smørgrav 					ns_addr = ldns_rr_list_cat_clone(ns_addr, new_ns_addr);
3067b5038d7SDag-Erling Smørgrav 					ldns_rr_list_deep_free(old_ns_addr);
3077b5038d7SDag-Erling Smørgrav 				}
3087b5038d7SDag-Erling Smørgrav 				ldns_rr_list_deep_free(new_ns_addr);
3097b5038d7SDag-Erling Smørgrav 			}
3107b5038d7SDag-Erling Smørgrav 			ldns_rr_list_deep_free(new_nss);
3117b5038d7SDag-Erling Smørgrav 
3127b5038d7SDag-Erling Smørgrav 			if (ns_addr) {
3137b5038d7SDag-Erling Smørgrav 				remove_resolver_nameservers(res);
3147b5038d7SDag-Erling Smørgrav 
3157b5038d7SDag-Erling Smørgrav 				if (ldns_resolver_push_nameserver_rr_list(res, ns_addr) !=
3167b5038d7SDag-Erling Smørgrav 						LDNS_STATUS_OK) {
3177b5038d7SDag-Erling Smørgrav 					error("Error adding new nameservers");
3187b5038d7SDag-Erling Smørgrav 					ldns_pkt_free(local_p);
3197b5038d7SDag-Erling Smørgrav 					goto done;
3207b5038d7SDag-Erling Smørgrav 				}
3217b5038d7SDag-Erling Smørgrav 				ldns_rr_list_deep_free(ns_addr);
3227b5038d7SDag-Erling Smørgrav 			} else {
3237b5038d7SDag-Erling Smørgrav 				status = ldns_verify_denial(local_p, labels[i], LDNS_RR_TYPE_NS, &nsec_rrs, &nsec_rr_sigs);
3247b5038d7SDag-Erling Smørgrav 
3257b5038d7SDag-Erling Smørgrav 				/* verify the nsec3 themselves*/
3267b5038d7SDag-Erling Smørgrav 				if (verbosity >= 4) {
3277b5038d7SDag-Erling Smørgrav 					printf("NSEC(3) Records to verify:\n");
3287b5038d7SDag-Erling Smørgrav 					ldns_rr_list_print(stdout, nsec_rrs);
3297b5038d7SDag-Erling Smørgrav 					printf("With signatures:\n");
3307b5038d7SDag-Erling Smørgrav 					ldns_rr_list_print(stdout, nsec_rr_sigs);
3317b5038d7SDag-Erling Smørgrav 					printf("correct keys:\n");
3327b5038d7SDag-Erling Smørgrav 					ldns_rr_list_print(stdout, correct_key_list);
3337b5038d7SDag-Erling Smørgrav 				}
3347b5038d7SDag-Erling Smørgrav 
3357b5038d7SDag-Erling Smørgrav 				if (status == LDNS_STATUS_OK) {
3367b5038d7SDag-Erling Smørgrav 					if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, trusted_keys, NULL)) == LDNS_STATUS_OK) {
3377b5038d7SDag-Erling Smørgrav 						fprintf(stdout, "%s ", TRUST);
3387b5038d7SDag-Erling Smørgrav 						fprintf(stdout, "Existence denied: ");
3397b5038d7SDag-Erling Smørgrav 						ldns_rdf_print(stdout, labels[i]);
3407b5038d7SDag-Erling Smørgrav 	/*
3417b5038d7SDag-Erling Smørgrav 						if (descriptor && descriptor->_name) {
3427b5038d7SDag-Erling Smørgrav 							printf(" %s", descriptor->_name);
3437b5038d7SDag-Erling Smørgrav 						} else {
3447b5038d7SDag-Erling Smørgrav 							printf(" TYPE%u", t);
3457b5038d7SDag-Erling Smørgrav 						}
3467b5038d7SDag-Erling Smørgrav 	*/					fprintf(stdout, " NS\n");
3477b5038d7SDag-Erling Smørgrav 					} else if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, correct_key_list, NULL)) == LDNS_STATUS_OK) {
3487b5038d7SDag-Erling Smørgrav 						fprintf(stdout, "%s ", SELF);
3497b5038d7SDag-Erling Smørgrav 						fprintf(stdout, "Existence denied: ");
3507b5038d7SDag-Erling Smørgrav 						ldns_rdf_print(stdout, labels[i]);
3517b5038d7SDag-Erling Smørgrav 	/*
3527b5038d7SDag-Erling Smørgrav 						if (descriptor && descriptor->_name) {
3537b5038d7SDag-Erling Smørgrav 							printf(" %s", descriptor->_name);
3547b5038d7SDag-Erling Smørgrav 						} else {
3557b5038d7SDag-Erling Smørgrav 							printf(" TYPE%u", t);
3567b5038d7SDag-Erling Smørgrav 						}
3577b5038d7SDag-Erling Smørgrav 	*/
3587b5038d7SDag-Erling Smørgrav 						fprintf(stdout, " NS\n");
3597b5038d7SDag-Erling Smørgrav 					} else {
3607b5038d7SDag-Erling Smørgrav 						fprintf(stdout, "%s ", BOGUS);
3617b5038d7SDag-Erling Smørgrav 						result = 1;
3627b5038d7SDag-Erling Smørgrav 						printf(";; Error verifying denial of existence for name ");
3637b5038d7SDag-Erling Smørgrav 						ldns_rdf_print(stdout, labels[i]);
3647b5038d7SDag-Erling Smørgrav 	/*
3657b5038d7SDag-Erling Smørgrav 						printf(" type ");
3667b5038d7SDag-Erling Smørgrav 						if (descriptor && descriptor->_name) {
3677b5038d7SDag-Erling Smørgrav 							printf("%s", descriptor->_name);
3687b5038d7SDag-Erling Smørgrav 						} else {
3697b5038d7SDag-Erling Smørgrav 							printf("TYPE%u", t);
3707b5038d7SDag-Erling Smørgrav 						}
3717b5038d7SDag-Erling Smørgrav 	*/					printf("NS: %s\n", ldns_get_errorstr_by_id(st));
3727b5038d7SDag-Erling Smørgrav 					}
3737b5038d7SDag-Erling Smørgrav 				} else {
3747b5038d7SDag-Erling Smørgrav 					fprintf(stdout, "%s ", BOGUS);
3757b5038d7SDag-Erling Smørgrav 					result = 1;
3767b5038d7SDag-Erling Smørgrav 					printf(";; Error verifying denial of existence for name ");
3777b5038d7SDag-Erling Smørgrav 					ldns_rdf_print(stdout, labels[i]);
3787b5038d7SDag-Erling Smørgrav 					printf("NS: %s\n", ldns_get_errorstr_by_id(status));
3797b5038d7SDag-Erling Smørgrav 				}
3807b5038d7SDag-Erling Smørgrav 
3817b5038d7SDag-Erling Smørgrav 				/* there might be an empty non-terminal, in which case we need to continue */
3827b5038d7SDag-Erling Smørgrav 				ent = false;
3837b5038d7SDag-Erling Smørgrav 				for (j = 0; j < ldns_rr_list_rr_count(nsec_rrs); j++) {
38417d15b25SDag-Erling Smørgrav 					nsecrr = ldns_rr_list_rr(nsec_rrs, j);
38517d15b25SDag-Erling Smørgrav 					/* For NSEC when the next name is a subdomain of the question */
38617d15b25SDag-Erling Smørgrav 					if (ldns_rr_get_type(nsecrr) == LDNS_RR_TYPE_NSEC &&
38717d15b25SDag-Erling Smørgrav 							ldns_dname_is_subdomain(ldns_rr_rdf(nsecrr, 0), labels[i])) {
3887b5038d7SDag-Erling Smørgrav 						ent = true;
38917d15b25SDag-Erling Smørgrav 
39017d15b25SDag-Erling Smørgrav 					/* For NSEC3, the hash matches the name and the type bitmap is empty*/
39117d15b25SDag-Erling Smørgrav 					} else if (ldns_rr_get_type(nsecrr) == LDNS_RR_TYPE_NSEC3) {
39217d15b25SDag-Erling Smørgrav 						hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsecrr, labels[i]);
39317d15b25SDag-Erling Smørgrav 						label0 = ldns_dname_label(ldns_rr_owner(nsecrr), 0);
39417d15b25SDag-Erling Smørgrav 						if (hashed_name && label0 &&
39517d15b25SDag-Erling Smørgrav 								ldns_dname_compare(hashed_name, label0) == 0 &&
39617d15b25SDag-Erling Smørgrav 								ldns_nsec3_bitmap(nsecrr) == NULL) {
39717d15b25SDag-Erling Smørgrav 							ent = true;
39817d15b25SDag-Erling Smørgrav 						}
39917d15b25SDag-Erling Smørgrav 						if (label0) {
40017d15b25SDag-Erling Smørgrav 							LDNS_FREE(label0);
40117d15b25SDag-Erling Smørgrav 						}
40217d15b25SDag-Erling Smørgrav 						if (hashed_name) {
40317d15b25SDag-Erling Smørgrav 							LDNS_FREE(hashed_name);
40417d15b25SDag-Erling Smørgrav 						}
4057b5038d7SDag-Erling Smørgrav 					}
4067b5038d7SDag-Erling Smørgrav 				}
4077b5038d7SDag-Erling Smørgrav 				if (!ent) {
4087b5038d7SDag-Erling Smørgrav 					ldns_rr_list_deep_free(nsec_rrs);
4097b5038d7SDag-Erling Smørgrav 					ldns_rr_list_deep_free(nsec_rr_sigs);
4107b5038d7SDag-Erling Smørgrav 					ldns_pkt_free(local_p);
4117b5038d7SDag-Erling Smørgrav 					goto done;
4127b5038d7SDag-Erling Smørgrav 				} else {
4137b5038d7SDag-Erling Smørgrav 					printf(";; There is an empty non-terminal here, continue\n");
4147b5038d7SDag-Erling Smørgrav 					continue;
4157b5038d7SDag-Erling Smørgrav 				}
4167b5038d7SDag-Erling Smørgrav 			}
4177b5038d7SDag-Erling Smørgrav 
4187b5038d7SDag-Erling Smørgrav 			if (ldns_resolver_nameserver_count(res) == 0) {
4197b5038d7SDag-Erling Smørgrav 				error("No nameservers found for this node");
4207b5038d7SDag-Erling Smørgrav 				goto done;
4217b5038d7SDag-Erling Smørgrav 			}
4227b5038d7SDag-Erling Smørgrav 		}
4237b5038d7SDag-Erling Smørgrav 		ldns_pkt_free(local_p);
4247b5038d7SDag-Erling Smørgrav 
4257b5038d7SDag-Erling Smørgrav 		fprintf(stdout, ";; Domain: ");
4267b5038d7SDag-Erling Smørgrav 		ldns_rdf_print(stdout, labels[i]);
4277b5038d7SDag-Erling Smørgrav 		fprintf(stdout, "\n");
4287b5038d7SDag-Erling Smørgrav 
4297b5038d7SDag-Erling Smørgrav 		/* retrieve keys for current domain, and verify them
4307b5038d7SDag-Erling Smørgrav 		   if they match an already trusted DS, or if one of the
4317b5038d7SDag-Erling Smørgrav 		   keys used to sign these is trusted, add the keys to
4327b5038d7SDag-Erling Smørgrav 		   the trusted list */
4337b5038d7SDag-Erling Smørgrav 		p = get_dnssec_pkt(res, labels[i], LDNS_RR_TYPE_DNSKEY);
4347b5038d7SDag-Erling Smørgrav 		(void) get_key(p, labels[i], &key_list, &key_sig_list);
4357b5038d7SDag-Erling Smørgrav 		if (key_sig_list) {
4367b5038d7SDag-Erling Smørgrav 			if (key_list) {
4377b5038d7SDag-Erling Smørgrav 				current_correct_keys = ldns_rr_list_new();
4387b5038d7SDag-Erling Smørgrav 				if ((st = ldns_verify(key_list, key_sig_list, key_list, current_correct_keys)) ==
4397b5038d7SDag-Erling Smørgrav 						LDNS_STATUS_OK) {
4407b5038d7SDag-Erling Smørgrav 					/* add all signed keys (don't just add current_correct, you'd miss
4417b5038d7SDag-Erling Smørgrav 					 * the zsk's then */
4427b5038d7SDag-Erling Smørgrav 					for (j = 0; j < ldns_rr_list_rr_count(key_list); j++) {
4437b5038d7SDag-Erling Smørgrav 						ldns_rr_list_push_rr(correct_key_list, ldns_rr_clone(ldns_rr_list_rr(key_list, j)));
4447b5038d7SDag-Erling Smørgrav 					}
4457b5038d7SDag-Erling Smørgrav 
4467b5038d7SDag-Erling Smørgrav 					/* check whether these keys were signed
4477b5038d7SDag-Erling Smørgrav 					 * by a trusted keys. if so, these
4487b5038d7SDag-Erling Smørgrav 					 * keys are also trusted */
4497b5038d7SDag-Erling Smørgrav 					new_keys_trusted = false;
4507b5038d7SDag-Erling Smørgrav 					for (k = 0; k < ldns_rr_list_rr_count(current_correct_keys); k++) {
4517b5038d7SDag-Erling Smørgrav 						for (j = 0; j < ldns_rr_list_rr_count(trusted_ds_rrs); j++) {
4527b5038d7SDag-Erling Smørgrav 							if (ldns_rr_compare_ds(ldns_rr_list_rr(current_correct_keys, k),
4537b5038d7SDag-Erling Smørgrav 								    ldns_rr_list_rr(trusted_ds_rrs, j))) {
4547b5038d7SDag-Erling Smørgrav 								new_keys_trusted = true;
4557b5038d7SDag-Erling Smørgrav 							}
4567b5038d7SDag-Erling Smørgrav 						}
4577b5038d7SDag-Erling Smørgrav 					}
4587b5038d7SDag-Erling Smørgrav 
4597b5038d7SDag-Erling Smørgrav 					/* also all keys are trusted if one of the current correct keys is trusted */
4607b5038d7SDag-Erling Smørgrav 					for (k = 0; k < ldns_rr_list_rr_count(current_correct_keys); k++) {
4617b5038d7SDag-Erling Smørgrav 						for (j = 0; j < ldns_rr_list_rr_count(trusted_keys); j++) {
4627b5038d7SDag-Erling Smørgrav 							if (ldns_rr_compare(ldns_rr_list_rr(current_correct_keys, k),
4637b5038d7SDag-Erling Smørgrav 								            ldns_rr_list_rr(trusted_keys, j)) == 0) {
4647b5038d7SDag-Erling Smørgrav 								            new_keys_trusted = true;
4657b5038d7SDag-Erling Smørgrav 							}
4667b5038d7SDag-Erling Smørgrav 						}
4677b5038d7SDag-Erling Smørgrav 					}
4687b5038d7SDag-Erling Smørgrav 
4697b5038d7SDag-Erling Smørgrav 
4707b5038d7SDag-Erling Smørgrav 					if (new_keys_trusted) {
4717b5038d7SDag-Erling Smørgrav 						ldns_rr_list_push_rr_list(trusted_keys, key_list);
4727b5038d7SDag-Erling Smørgrav 						print_rr_list_abbr(stdout, key_list, TRUST);
4737b5038d7SDag-Erling Smørgrav 						ldns_rr_list_free(key_list);
4747b5038d7SDag-Erling Smørgrav 						key_list = NULL;
4757b5038d7SDag-Erling Smørgrav 					} else {
4767b5038d7SDag-Erling Smørgrav 						if (verbosity >= 2) {
4777b5038d7SDag-Erling Smørgrav 							printf(";; Signature ok but no chain to a trusted key or ds record\n");
4787b5038d7SDag-Erling Smørgrav 						}
4797b5038d7SDag-Erling Smørgrav 						print_rr_list_abbr(stdout, key_list, SELF);
4807b5038d7SDag-Erling Smørgrav 						ldns_rr_list_deep_free(key_list);
4817b5038d7SDag-Erling Smørgrav 						key_list = NULL;
4827b5038d7SDag-Erling Smørgrav 					}
4837b5038d7SDag-Erling Smørgrav 				} else {
4847b5038d7SDag-Erling Smørgrav 					print_rr_list_abbr(stdout, key_list, BOGUS);
4857b5038d7SDag-Erling Smørgrav 					result = 2;
4867b5038d7SDag-Erling Smørgrav 					ldns_rr_list_deep_free(key_list);
4877b5038d7SDag-Erling Smørgrav 					key_list = NULL;
4887b5038d7SDag-Erling Smørgrav 				}
4897b5038d7SDag-Erling Smørgrav 				ldns_rr_list_free(current_correct_keys);
4907b5038d7SDag-Erling Smørgrav 				current_correct_keys = NULL;
4917b5038d7SDag-Erling Smørgrav 			} else {
4927b5038d7SDag-Erling Smørgrav 				printf(";; No DNSKEY record found for ");
4937b5038d7SDag-Erling Smørgrav 				ldns_rdf_print(stdout, labels[i]);
4947b5038d7SDag-Erling Smørgrav 				printf("\n");
4957b5038d7SDag-Erling Smørgrav 			}
4967b5038d7SDag-Erling Smørgrav 		}
4977b5038d7SDag-Erling Smørgrav 
4987b5038d7SDag-Erling Smørgrav 		ldns_pkt_free(p);
4997b5038d7SDag-Erling Smørgrav 		ldns_rr_list_deep_free(key_sig_list);
5007b5038d7SDag-Erling Smørgrav 		key_sig_list = NULL;
5017b5038d7SDag-Erling Smørgrav 
5027b5038d7SDag-Erling Smørgrav 		/* check the DS records for the next child domain */
5037b5038d7SDag-Erling Smørgrav 		if (i > 1) {
5047b5038d7SDag-Erling Smørgrav 			p = get_dnssec_pkt(res, labels[i-1], LDNS_RR_TYPE_DS);
5057b5038d7SDag-Erling Smørgrav 			(void) get_ds(p, labels[i-1], &ds_list, &ds_sig_list);
5067b5038d7SDag-Erling Smørgrav 			if (!ds_list) {
5077b5038d7SDag-Erling Smørgrav 				ldns_rr_list_deep_free(ds_sig_list);
508*5afab0e5SDag-Erling Smørgrav 				(void) get_dnssec_rr( p, labels[i-1]
509*5afab0e5SDag-Erling Smørgrav 				                    , LDNS_RR_TYPE_CNAME
510*5afab0e5SDag-Erling Smørgrav 				                    , &ds_list, &ds_sig_list);
511*5afab0e5SDag-Erling Smørgrav 				if (ds_list) {
512*5afab0e5SDag-Erling Smørgrav 					st = ldns_verify( ds_list, ds_sig_list
513*5afab0e5SDag-Erling Smørgrav 					                , correct_key_list
514*5afab0e5SDag-Erling Smørgrav 					                , current_correct_keys);
515*5afab0e5SDag-Erling Smørgrav 
516*5afab0e5SDag-Erling Smørgrav 					if (st == LDNS_STATUS_OK) {
517*5afab0e5SDag-Erling Smørgrav 						printf(";; No DS record found "
518*5afab0e5SDag-Erling Smørgrav 						       "for ");
519*5afab0e5SDag-Erling Smørgrav 						ldns_rdf_print(stdout,
520*5afab0e5SDag-Erling Smørgrav 							labels[i-1]);
521*5afab0e5SDag-Erling Smørgrav 						printf(", but valid CNAME");
522*5afab0e5SDag-Erling Smørgrav 					} else {
523*5afab0e5SDag-Erling Smørgrav 						printf(BOGUS " Unable to verify "
524*5afab0e5SDag-Erling Smørgrav 						       "denial of existence for ");
525*5afab0e5SDag-Erling Smørgrav 						ldns_rdf_print(stdout,
526*5afab0e5SDag-Erling Smørgrav 							labels[i-1]);
527*5afab0e5SDag-Erling Smørgrav 						printf(", because of BOGUS CNAME");
5287b5038d7SDag-Erling Smørgrav 					}
529*5afab0e5SDag-Erling Smørgrav 					printf("\n");
530*5afab0e5SDag-Erling Smørgrav 					ldns_rr_list_deep_free(ds_sig_list);
531*5afab0e5SDag-Erling Smørgrav 					ldns_pkt_free(p);
532*5afab0e5SDag-Erling Smørgrav 					ldns_rr_list_deep_free(ds_list);
533*5afab0e5SDag-Erling Smørgrav 					ds_list = NULL;
534*5afab0e5SDag-Erling Smørgrav 					ds_sig_list = NULL;
535*5afab0e5SDag-Erling Smørgrav 					p = NULL;
536*5afab0e5SDag-Erling Smørgrav 				} else {
537*5afab0e5SDag-Erling Smørgrav 					ldns_rr_list_deep_free(ds_sig_list);
538*5afab0e5SDag-Erling Smørgrav 					ldns_pkt_free(p);
539*5afab0e5SDag-Erling Smørgrav 					p = get_dnssec_pkt(res, name,
540*5afab0e5SDag-Erling Smørgrav 							LDNS_RR_TYPE_DNSKEY);
541*5afab0e5SDag-Erling Smørgrav 					(void) get_ds(p, NULL
542*5afab0e5SDag-Erling Smørgrav 					             , &ds_list, &ds_sig_list);
543*5afab0e5SDag-Erling Smørgrav 				}
5447b5038d7SDag-Erling Smørgrav 			}
5457b5038d7SDag-Erling Smørgrav 			if (ds_sig_list) {
5467b5038d7SDag-Erling Smørgrav 				if (ds_list) {
5477b5038d7SDag-Erling Smørgrav 					if (verbosity >= 4) {
5487b5038d7SDag-Erling Smørgrav 						printf("VERIFYING:\n");
5497b5038d7SDag-Erling Smørgrav 						printf("DS LIST:\n");
5507b5038d7SDag-Erling Smørgrav 						ldns_rr_list_print(stdout, ds_list);
5517b5038d7SDag-Erling Smørgrav 						printf("SIGS:\n");
5527b5038d7SDag-Erling Smørgrav 						ldns_rr_list_print(stdout, ds_sig_list);
5537b5038d7SDag-Erling Smørgrav 						printf("KEYS:\n");
5547b5038d7SDag-Erling Smørgrav 						ldns_rr_list_print(stdout, correct_key_list);
5557b5038d7SDag-Erling Smørgrav 					}
5567b5038d7SDag-Erling Smørgrav 
5577b5038d7SDag-Erling Smørgrav 					current_correct_keys = ldns_rr_list_new();
5587b5038d7SDag-Erling Smørgrav 
5597b5038d7SDag-Erling Smørgrav 					if ((st = ldns_verify(ds_list, ds_sig_list, correct_key_list, current_correct_keys)) ==
5607b5038d7SDag-Erling Smørgrav 							LDNS_STATUS_OK) {
5617b5038d7SDag-Erling Smørgrav 						/* if the ds is signed by a trusted key and a key from correct keys
5627b5038d7SDag-Erling Smørgrav 						   matches that ds, add that key to the trusted keys */
5637b5038d7SDag-Erling Smørgrav 						new_keys_trusted = false;
5647b5038d7SDag-Erling Smørgrav 						if (verbosity >= 2) {
5657b5038d7SDag-Erling Smørgrav 							printf("Checking if signing key is trusted:\n");
5667b5038d7SDag-Erling Smørgrav 						}
5677b5038d7SDag-Erling Smørgrav 						for (j = 0; j < ldns_rr_list_rr_count(current_correct_keys); j++) {
5687b5038d7SDag-Erling Smørgrav 							if (verbosity >= 2) {
5697b5038d7SDag-Erling Smørgrav 								printf("New key: ");
5707b5038d7SDag-Erling Smørgrav 								ldns_rr_print(stdout, ldns_rr_list_rr(current_correct_keys, j));
5717b5038d7SDag-Erling Smørgrav 							}
5727b5038d7SDag-Erling Smørgrav 							for (k = 0; k < ldns_rr_list_rr_count(trusted_keys); k++) {
5737b5038d7SDag-Erling Smørgrav 								if (verbosity >= 2) {
5747b5038d7SDag-Erling Smørgrav 									printf("\tTrusted key: ");
5757b5038d7SDag-Erling Smørgrav 									ldns_rr_print(stdout, ldns_rr_list_rr(trusted_keys, k));
5767b5038d7SDag-Erling Smørgrav 								}
5777b5038d7SDag-Erling Smørgrav 								if (ldns_rr_compare(ldns_rr_list_rr(current_correct_keys, j),
5787b5038d7SDag-Erling Smørgrav 								    ldns_rr_list_rr(trusted_keys, k)) == 0) {
5797b5038d7SDag-Erling Smørgrav 								    	if (verbosity >= 2) {
5807b5038d7SDag-Erling Smørgrav 								    		printf("Key is now trusted!\n");
5817b5038d7SDag-Erling Smørgrav 									}
5827b5038d7SDag-Erling Smørgrav 									for (l = 0; l < ldns_rr_list_rr_count(ds_list); l++) {
5837b5038d7SDag-Erling Smørgrav 										ldns_rr_list_push_rr(trusted_ds_rrs, ldns_rr_clone(ldns_rr_list_rr(ds_list, l)));
5847b5038d7SDag-Erling Smørgrav 										new_keys_trusted = true;
5857b5038d7SDag-Erling Smørgrav 									}
5867b5038d7SDag-Erling Smørgrav 								}
5877b5038d7SDag-Erling Smørgrav 							}
5887b5038d7SDag-Erling Smørgrav 						}
5897b5038d7SDag-Erling Smørgrav 						if (new_keys_trusted) {
5907b5038d7SDag-Erling Smørgrav 							print_rr_list_abbr(stdout, ds_list, TRUST);
5917b5038d7SDag-Erling Smørgrav 						} else {
5927b5038d7SDag-Erling Smørgrav 							print_rr_list_abbr(stdout, ds_list, SELF);
5937b5038d7SDag-Erling Smørgrav 						}
5947b5038d7SDag-Erling Smørgrav 					} else {
5957b5038d7SDag-Erling Smørgrav 						result = 3;
5967b5038d7SDag-Erling Smørgrav 						print_rr_list_abbr(stdout, ds_list, BOGUS);
5977b5038d7SDag-Erling Smørgrav 					}
5987b5038d7SDag-Erling Smørgrav 
5997b5038d7SDag-Erling Smørgrav 					ldns_rr_list_free(current_correct_keys);
6007b5038d7SDag-Erling Smørgrav 					current_correct_keys = NULL;
6017b5038d7SDag-Erling Smørgrav 				} else {
6027b5038d7SDag-Erling Smørgrav 					/* wait apparently there were no keys either, go back to the ds packet */
6037b5038d7SDag-Erling Smørgrav 					ldns_pkt_free(p);
6047b5038d7SDag-Erling Smørgrav 					ldns_rr_list_deep_free(ds_sig_list);
6057b5038d7SDag-Erling Smørgrav 					p = get_dnssec_pkt(res, labels[i-1], LDNS_RR_TYPE_DS);
6067b5038d7SDag-Erling Smørgrav 					(void) get_ds(p, labels[i-1], &ds_list, &ds_sig_list);
6077b5038d7SDag-Erling Smørgrav 
6087b5038d7SDag-Erling Smørgrav 					status = ldns_verify_denial(p, labels[i-1], LDNS_RR_TYPE_DS, &nsec_rrs, &nsec_rr_sigs);
6097b5038d7SDag-Erling Smørgrav 
6107b5038d7SDag-Erling Smørgrav 					if (verbosity >= 4) {
6117b5038d7SDag-Erling Smørgrav 						printf("NSEC(3) Records to verify:\n");
6127b5038d7SDag-Erling Smørgrav 						ldns_rr_list_print(stdout, nsec_rrs);
6137b5038d7SDag-Erling Smørgrav 						printf("With signatures:\n");
6147b5038d7SDag-Erling Smørgrav 						ldns_rr_list_print(stdout, nsec_rr_sigs);
6157b5038d7SDag-Erling Smørgrav 						printf("correct keys:\n");
6167b5038d7SDag-Erling Smørgrav 						ldns_rr_list_print(stdout, correct_key_list);
6177b5038d7SDag-Erling Smørgrav 					}
6187b5038d7SDag-Erling Smørgrav 
6197b5038d7SDag-Erling Smørgrav 					if (status == LDNS_STATUS_OK) {
6207b5038d7SDag-Erling Smørgrav 						if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, trusted_keys, NULL)) == LDNS_STATUS_OK) {
6217b5038d7SDag-Erling Smørgrav 							fprintf(stdout, "%s ", TRUST);
6227b5038d7SDag-Erling Smørgrav 							fprintf(stdout, "Existence denied: ");
6237b5038d7SDag-Erling Smørgrav 							ldns_rdf_print(stdout, labels[i-1]);
6247b5038d7SDag-Erling Smørgrav 							printf(" DS");
6257b5038d7SDag-Erling Smørgrav 							fprintf(stdout, "\n");
6267b5038d7SDag-Erling Smørgrav 						} else if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, correct_key_list, NULL)) == LDNS_STATUS_OK) {
6277b5038d7SDag-Erling Smørgrav 							fprintf(stdout, "%s ", SELF);
6287b5038d7SDag-Erling Smørgrav 							fprintf(stdout, "Existence denied: ");
6297b5038d7SDag-Erling Smørgrav 							ldns_rdf_print(stdout, labels[i-1]);
6307b5038d7SDag-Erling Smørgrav 							printf(" DS");
6317b5038d7SDag-Erling Smørgrav 							fprintf(stdout, "\n");
6327b5038d7SDag-Erling Smørgrav 						} else {
6337b5038d7SDag-Erling Smørgrav 							result = 4;
6347b5038d7SDag-Erling Smørgrav 							fprintf(stdout, "%s ", BOGUS);
6357b5038d7SDag-Erling Smørgrav 							printf("Error verifying denial of existence for ");
6367b5038d7SDag-Erling Smørgrav 							ldns_rdf_print(stdout, labels[i-1]);
6377b5038d7SDag-Erling Smørgrav 							printf(" DS");
6387b5038d7SDag-Erling Smørgrav 							printf(": %s\n", ldns_get_errorstr_by_id(st));
6397b5038d7SDag-Erling Smørgrav 						}
6407b5038d7SDag-Erling Smørgrav 
6417b5038d7SDag-Erling Smørgrav 
6427b5038d7SDag-Erling Smørgrav 					} else {
6437b5038d7SDag-Erling Smørgrav 						if (status == LDNS_STATUS_CRYPTO_NO_RRSIG) {
6447b5038d7SDag-Erling Smørgrav 							printf(";; No DS for ");
6457b5038d7SDag-Erling Smørgrav 							ldns_rdf_print(stdout, labels[i - 1]);
6467b5038d7SDag-Erling Smørgrav 						} else {
647*5afab0e5SDag-Erling Smørgrav 							printf(BOGUS " Unable to verify denial of existence for ");
6487b5038d7SDag-Erling Smørgrav 							ldns_rdf_print(stdout, labels[i - 1]);
6497b5038d7SDag-Erling Smørgrav 							printf(" DS: %s\n", ldns_get_errorstr_by_id(status));
6507b5038d7SDag-Erling Smørgrav 						}
6517b5038d7SDag-Erling Smørgrav 					}
6527b5038d7SDag-Erling Smørgrav 					if (verbosity >= 2) {
6537b5038d7SDag-Erling Smørgrav 						printf(";; No ds record for delegation\n");
6547b5038d7SDag-Erling Smørgrav 					}
6557b5038d7SDag-Erling Smørgrav 				}
6567b5038d7SDag-Erling Smørgrav 			}
6577b5038d7SDag-Erling Smørgrav 			ldns_rr_list_deep_free(ds_list);
6587b5038d7SDag-Erling Smørgrav 			ldns_pkt_free(p);
6597b5038d7SDag-Erling Smørgrav 		} else {
6607b5038d7SDag-Erling Smørgrav 			/* if this is the last label, just verify the data and stop */
6617b5038d7SDag-Erling Smørgrav 			p = get_dnssec_pkt(res, labels[i], t);
6627b5038d7SDag-Erling Smørgrav 			(void) get_dnssec_rr(p, labels[i], t, &dataset, &key_sig_list);
6637b5038d7SDag-Erling Smørgrav 			if (dataset && ldns_rr_list_rr_count(dataset) > 0) {
6647b5038d7SDag-Erling Smørgrav 				if (key_sig_list && ldns_rr_list_rr_count(key_sig_list) > 0) {
6657b5038d7SDag-Erling Smørgrav 
6667b5038d7SDag-Erling Smørgrav 					/* If this is a wildcard, you must be able to deny exact match */
6677b5038d7SDag-Erling Smørgrav 					if ((st = ldns_verify(dataset, key_sig_list, trusted_keys, NULL)) == LDNS_STATUS_OK) {
6687b5038d7SDag-Erling Smørgrav 						fprintf(stdout, "%s ", TRUST);
6697b5038d7SDag-Erling Smørgrav 						ldns_rr_list_print(stdout, dataset);
6707b5038d7SDag-Erling Smørgrav 					} else if ((st = ldns_verify(dataset, key_sig_list, correct_key_list, NULL)) == LDNS_STATUS_OK) {
6717b5038d7SDag-Erling Smørgrav 						fprintf(stdout, "%s ", SELF);
6727b5038d7SDag-Erling Smørgrav 						ldns_rr_list_print(stdout, dataset);
6737b5038d7SDag-Erling Smørgrav 					} else {
6747b5038d7SDag-Erling Smørgrav 						result = 5;
6757b5038d7SDag-Erling Smørgrav 						fprintf(stdout, "%s ", BOGUS);
6767b5038d7SDag-Erling Smørgrav 						ldns_rr_list_print(stdout, dataset);
6777b5038d7SDag-Erling Smørgrav 						printf(";; Error: %s\n", ldns_get_errorstr_by_id(st));
6787b5038d7SDag-Erling Smørgrav 					}
6797b5038d7SDag-Erling Smørgrav 				} else {
6807b5038d7SDag-Erling Smørgrav 					fprintf(stdout, "%s ", UNSIGNED);
6817b5038d7SDag-Erling Smørgrav 					ldns_rr_list_print(stdout, dataset);
6827b5038d7SDag-Erling Smørgrav 				}
6837b5038d7SDag-Erling Smørgrav 				ldns_rr_list_deep_free(dataset);
6847b5038d7SDag-Erling Smørgrav 			} else {
6857b5038d7SDag-Erling Smørgrav 				status = ldns_verify_denial(p, name, t, &nsec_rrs, &nsec_rr_sigs);
6867b5038d7SDag-Erling Smørgrav 				if (status == LDNS_STATUS_OK) {
6877b5038d7SDag-Erling Smørgrav 					/* verify the nsec3 themselves*/
6887b5038d7SDag-Erling Smørgrav 					if (verbosity >= 5) {
6897b5038d7SDag-Erling Smørgrav 						printf("NSEC(3) Records to verify:\n");
6907b5038d7SDag-Erling Smørgrav 						ldns_rr_list_print(stdout, nsec_rrs);
6917b5038d7SDag-Erling Smørgrav 						printf("With signatures:\n");
6927b5038d7SDag-Erling Smørgrav 						ldns_rr_list_print(stdout, nsec_rr_sigs);
6937b5038d7SDag-Erling Smørgrav 						printf("correct keys:\n");
6947b5038d7SDag-Erling Smørgrav 						ldns_rr_list_print(stdout, correct_key_list);
6957b5038d7SDag-Erling Smørgrav /*
6967b5038d7SDag-Erling Smørgrav 						printf("trusted keys at %p:\n", trusted_keys);
6977b5038d7SDag-Erling Smørgrav 						ldns_rr_list_print(stdout, trusted_keys);
6987b5038d7SDag-Erling Smørgrav */					}
6997b5038d7SDag-Erling Smørgrav 
7007b5038d7SDag-Erling Smørgrav 					if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, trusted_keys, NULL)) == LDNS_STATUS_OK) {
7017b5038d7SDag-Erling Smørgrav 						fprintf(stdout, "%s ", TRUST);
7027b5038d7SDag-Erling Smørgrav 						fprintf(stdout, "Existence denied: ");
7037b5038d7SDag-Erling Smørgrav 						ldns_rdf_print(stdout, name);
7047b5038d7SDag-Erling Smørgrav 						if (descriptor && descriptor->_name) {
7057b5038d7SDag-Erling Smørgrav 							printf(" %s", descriptor->_name);
7067b5038d7SDag-Erling Smørgrav 						} else {
7077b5038d7SDag-Erling Smørgrav 							printf(" TYPE%u", t);
7087b5038d7SDag-Erling Smørgrav 						}
7097b5038d7SDag-Erling Smørgrav 						fprintf(stdout, "\n");
7107b5038d7SDag-Erling Smørgrav 					} else if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, correct_key_list, NULL)) == LDNS_STATUS_OK) {
7117b5038d7SDag-Erling Smørgrav 						fprintf(stdout, "%s ", SELF);
7127b5038d7SDag-Erling Smørgrav 						fprintf(stdout, "Existence denied: ");
7137b5038d7SDag-Erling Smørgrav 						ldns_rdf_print(stdout, name);
7147b5038d7SDag-Erling Smørgrav 						if (descriptor && descriptor->_name) {
7157b5038d7SDag-Erling Smørgrav 							printf(" %s", descriptor->_name);
7167b5038d7SDag-Erling Smørgrav 						} else {
7177b5038d7SDag-Erling Smørgrav 							printf(" TYPE%u", t);
7187b5038d7SDag-Erling Smørgrav 						}
7197b5038d7SDag-Erling Smørgrav 						fprintf(stdout, "\n");
7207b5038d7SDag-Erling Smørgrav 					} else {
7217b5038d7SDag-Erling Smørgrav 						result = 6;
7227b5038d7SDag-Erling Smørgrav 						fprintf(stdout, "%s ", BOGUS);
7237b5038d7SDag-Erling Smørgrav 						printf("Error verifying denial of existence for ");
7247b5038d7SDag-Erling Smørgrav 						ldns_rdf_print(stdout, name);
7257b5038d7SDag-Erling Smørgrav 						printf(" type ");
7267b5038d7SDag-Erling Smørgrav 						if (descriptor && descriptor->_name) {
7277b5038d7SDag-Erling Smørgrav 							printf("%s", descriptor->_name);
7287b5038d7SDag-Erling Smørgrav 						} else {
7297b5038d7SDag-Erling Smørgrav 							printf("TYPE%u", t);
7307b5038d7SDag-Erling Smørgrav 						}
7317b5038d7SDag-Erling Smørgrav 						printf(": %s\n", ldns_get_errorstr_by_id(st));
7327b5038d7SDag-Erling Smørgrav 					}
7337b5038d7SDag-Erling Smørgrav 
7347b5038d7SDag-Erling Smørgrav 					ldns_rr_list_deep_free(nsec_rrs);
7357b5038d7SDag-Erling Smørgrav 					ldns_rr_list_deep_free(nsec_rr_sigs);
7367b5038d7SDag-Erling Smørgrav 				} else {
7377b5038d7SDag-Erling Smørgrav /*
7387b5038d7SDag-Erling Smørgrav */
7397b5038d7SDag-Erling Smørgrav 					if (status == LDNS_STATUS_CRYPTO_NO_RRSIG) {
7407b5038d7SDag-Erling Smørgrav 						printf("%s ", UNSIGNED);
7417b5038d7SDag-Erling Smørgrav 						printf("No data found for: ");
7427b5038d7SDag-Erling Smørgrav 						ldns_rdf_print(stdout, name);
7437b5038d7SDag-Erling Smørgrav 						printf(" type ");
7447b5038d7SDag-Erling Smørgrav 						if (descriptor && descriptor->_name) {
7457b5038d7SDag-Erling Smørgrav 							printf("%s", descriptor->_name);
7467b5038d7SDag-Erling Smørgrav 						} else {
7477b5038d7SDag-Erling Smørgrav 							printf("TYPE%u", t);
7487b5038d7SDag-Erling Smørgrav 						}
7497b5038d7SDag-Erling Smørgrav 						printf("\n");
7507b5038d7SDag-Erling Smørgrav 					} else {
751*5afab0e5SDag-Erling Smørgrav 						printf(BOGUS " Unable to verify denial of existence for ");
7527b5038d7SDag-Erling Smørgrav 						ldns_rdf_print(stdout, name);
7537b5038d7SDag-Erling Smørgrav 						printf(" type ");
7547b5038d7SDag-Erling Smørgrav 						if (descriptor && descriptor->_name) {
7557b5038d7SDag-Erling Smørgrav 							printf("%s", descriptor->_name);
7567b5038d7SDag-Erling Smørgrav 						} else {
7577b5038d7SDag-Erling Smørgrav 							printf("TYPE%u", t);
7587b5038d7SDag-Erling Smørgrav 						}
7597b5038d7SDag-Erling Smørgrav 						printf("\n");
7607b5038d7SDag-Erling Smørgrav 					}
7617b5038d7SDag-Erling Smørgrav 
7627b5038d7SDag-Erling Smørgrav 				}
7637b5038d7SDag-Erling Smørgrav 			}
7647b5038d7SDag-Erling Smørgrav 			ldns_pkt_free(p);
7657b5038d7SDag-Erling Smørgrav 		}
7667b5038d7SDag-Erling Smørgrav 
7677b5038d7SDag-Erling Smørgrav 		new_nss = NULL;
7687b5038d7SDag-Erling Smørgrav 		ns_addr = NULL;
7697b5038d7SDag-Erling Smørgrav 		ldns_rr_list_deep_free(key_list);
7707b5038d7SDag-Erling Smørgrav 		key_list = NULL;
7717b5038d7SDag-Erling Smørgrav 		ldns_rr_list_deep_free(key_sig_list);
7727b5038d7SDag-Erling Smørgrav 		key_sig_list = NULL;
7737b5038d7SDag-Erling Smørgrav 		ds_list = NULL;
7747b5038d7SDag-Erling Smørgrav 		ldns_rr_list_deep_free(ds_sig_list);
7757b5038d7SDag-Erling Smørgrav 		ds_sig_list = NULL;
7767b5038d7SDag-Erling Smørgrav 	}
777*5afab0e5SDag-Erling Smørgrav 	printf(";;" SELF " self sig OK; " BOGUS " bogus; " TRUST " trusted; " UNSIGNED " unsigned\n");
7787b5038d7SDag-Erling Smørgrav 	/* verbose mode?
7797b5038d7SDag-Erling Smørgrav 	printf("Trusted keys:\n");
7807b5038d7SDag-Erling Smørgrav 	ldns_rr_list_print(stdout, trusted_keys);
7817b5038d7SDag-Erling Smørgrav 	printf("trusted dss:\n");
7827b5038d7SDag-Erling Smørgrav 	ldns_rr_list_print(stdout, trusted_ds_rrs);
7837b5038d7SDag-Erling Smørgrav 	*/
7847b5038d7SDag-Erling Smørgrav 
7857b5038d7SDag-Erling Smørgrav 	done:
7867b5038d7SDag-Erling Smørgrav 	ldns_rr_list_deep_free(trusted_ds_rrs);
7877b5038d7SDag-Erling Smørgrav 	ldns_rr_list_deep_free(correct_key_list);
7887b5038d7SDag-Erling Smørgrav 	ldns_resolver_deep_free(res);
7897b5038d7SDag-Erling Smørgrav 	if (labels) {
7907b5038d7SDag-Erling Smørgrav 		for(i = 0 ; i < (ssize_t)labels_count + 2; i++) {
7917b5038d7SDag-Erling Smørgrav 			ldns_rdf_deep_free(labels[i]);
7927b5038d7SDag-Erling Smørgrav 		}
7937b5038d7SDag-Erling Smørgrav 		LDNS_FREE(labels);
7947b5038d7SDag-Erling Smørgrav 	}
7957b5038d7SDag-Erling Smørgrav 	return result;
7967b5038d7SDag-Erling Smørgrav }
7977b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
798