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