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