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