ldns  1.7.0
dnssec_verify.c
Go to the documentation of this file.
1 #include <ldns/config.h>
2 
3 #include <ldns/ldns.h>
4 
5 #include <strings.h>
6 #include <time.h>
7 
8 #ifdef HAVE_SSL
9 /* this entire file is rather useless when you don't have
10  * crypto...
11  */
12 #include <openssl/ssl.h>
13 #include <openssl/evp.h>
14 #include <openssl/rand.h>
15 #include <openssl/err.h>
16 #include <openssl/md5.h>
17 
20 {
22  if(!nc) return NULL;
23  /*
24  * not needed anymore because CALLOC initalizes everything to zero.
25 
26  nc->rrset = NULL;
27  nc->parent_type = 0;
28  nc->parent = NULL;
29  nc->signatures = NULL;
30  nc->packet_rcode = 0;
31  nc->packet_qtype = 0;
32  nc->packet_nodata = false;
33 
34  */
35  return nc;
36 }
37 
38 void
40 {
41  LDNS_FREE(chain);
42 }
43 
44 void
46 {
49  if (chain->parent) {
51  }
52  LDNS_FREE(chain);
53 }
54 
55 void
57  const ldns_dnssec_data_chain *chain)
58 {
59  ldns_lookup_table *rcode;
60  const ldns_rr_descriptor *rr_descriptor;
61  if (chain) {
62  ldns_dnssec_data_chain_print_fmt(out, fmt, chain->parent);
63  if (ldns_rr_list_rr_count(chain->rrset) > 0) {
65  (int) chain->packet_rcode);
66  if (rcode) {
67  fprintf(out, ";; rcode: %s\n", rcode->name);
68  }
69 
70  rr_descriptor = ldns_rr_descript(chain->packet_qtype);
71  if (rr_descriptor && rr_descriptor->_name) {
72  fprintf(out, ";; qtype: %s\n", rr_descriptor->_name);
73  } else if (chain->packet_qtype != 0) {
74  fprintf(out, "TYPE%u",
75  chain->packet_qtype);
76  }
77  if (chain->packet_nodata) {
78  fprintf(out, ";; NODATA response\n");
79  }
80  fprintf(out, "rrset:\n");
81  ldns_rr_list_print_fmt(out, fmt, chain->rrset);
82  fprintf(out, "sigs:\n");
83  ldns_rr_list_print_fmt(out, fmt, chain->signatures);
84  fprintf(out, "---\n");
85  } else {
86  fprintf(out, "<no data>\n");
87  }
88  }
89 }
90 void
92 {
94  out, ldns_output_format_default, chain);
95 }
96 
97 
98 static void
99 ldns_dnssec_build_data_chain_dnskey(ldns_resolver *res,
100  uint16_t qflags,
101  const ldns_pkt *pkt,
102  ldns_rr_list *signatures,
103  ldns_dnssec_data_chain *new_chain,
104  ldns_rdf *key_name,
105  ldns_rr_class c) {
106  ldns_rr_list *keys;
107  ldns_pkt *my_pkt;
108  if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
109  new_chain->signatures = ldns_rr_list_clone(signatures);
110  new_chain->parent_type = 0;
111 
113  pkt,
114  key_name,
117  );
118  if (!keys) {
119  my_pkt = ldns_resolver_query(res,
120  key_name,
122  c,
123  qflags);
124  if (my_pkt) {
126  my_pkt,
127  key_name,
130  );
131  new_chain->parent = ldns_dnssec_build_data_chain(res,
132  qflags,
133  keys,
134  my_pkt,
135  NULL);
137  ldns_pkt_free(my_pkt);
138  }
139  } else {
140  new_chain->parent = ldns_dnssec_build_data_chain(res,
141  qflags,
142  keys,
143  pkt,
144  NULL);
146  }
148  }
149 }
150 
151 static void
152 ldns_dnssec_build_data_chain_other(ldns_resolver *res,
153  uint16_t qflags,
154  ldns_dnssec_data_chain *new_chain,
155  ldns_rdf *key_name,
156  ldns_rr_class c,
157  ldns_rr_list *dss)
158 {
159  /* 'self-signed', parent is a DS */
160 
161  /* okay, either we have other keys signing the current one,
162  * or the current
163  * one should have a DS record in the parent zone.
164  * How do we find this out? Try both?
165  *
166  * request DNSKEYS for current zone,
167  * add all signatures to current level
168  */
169  ldns_pkt *my_pkt;
170  ldns_rr_list *signatures2;
171 
172  new_chain->parent_type = 1;
173 
174  my_pkt = ldns_resolver_query(res,
175  key_name,
177  c,
178  qflags);
179  if (my_pkt) {
181  key_name,
184  );
185  if (dss) {
186  new_chain->parent = ldns_dnssec_build_data_chain(res,
187  qflags,
188  dss,
189  my_pkt,
190  NULL);
191  new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
193  }
194  ldns_pkt_free(my_pkt);
195  }
196 
197  my_pkt = ldns_resolver_query(res,
198  key_name,
200  c,
201  qflags);
202  if (my_pkt) {
203  signatures2 = ldns_pkt_rr_list_by_name_and_type(my_pkt,
204  key_name,
207  if (signatures2) {
208  if (new_chain->signatures) {
209  printf("There were already sigs!\n");
211  printf("replacing the old sigs\n");
212  }
213  new_chain->signatures = signatures2;
214  }
215  ldns_pkt_free(my_pkt);
216  }
217 }
218 
219 static ldns_dnssec_data_chain *
220 ldns_dnssec_build_data_chain_nokeyname(ldns_resolver *res,
221  uint16_t qflags,
222  ldns_rr *orig_rr,
223  const ldns_rr_list *rrset,
224  ldns_dnssec_data_chain *new_chain)
225 {
226  ldns_rdf *possible_parent_name;
227  ldns_pkt *my_pkt;
228  /* apparently we were not able to find a signing key, so
229  we assume the chain ends here
230  */
231  /* try parents for auth denial of DS */
232  if (orig_rr) {
233  possible_parent_name = ldns_rr_owner(orig_rr);
234  } else if (rrset && ldns_rr_list_rr_count(rrset) > 0) {
235  possible_parent_name = ldns_rr_owner(ldns_rr_list_rr(rrset, 0));
236  } else {
237  /* no information to go on, give up */
238  return new_chain;
239  }
240 
241  my_pkt = ldns_resolver_query(res,
242  possible_parent_name,
245  qflags);
246  if (!my_pkt) {
247  return new_chain;
248  }
249 
250  if (ldns_pkt_ancount(my_pkt) > 0) {
251  /* add error, no sigs but DS in parent */
252  /*ldns_pkt_print(stdout, my_pkt);*/
253  ldns_pkt_free(my_pkt);
254  } else {
255  /* are there signatures? */
256  new_chain->parent = ldns_dnssec_build_data_chain(res,
257  qflags,
258  NULL,
259  my_pkt,
260  NULL);
261 
262  new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
263 
264  }
265  return new_chain;
266 }
267 
268 
271  uint16_t qflags,
272  const ldns_rr_list *rrset,
273  const ldns_pkt *pkt,
274  ldns_rr *orig_rr)
275 {
276  ldns_rr_list *signatures = NULL;
277  ldns_rr_list *dss = NULL;
278 
279  ldns_rr_list *my_rrset;
280 
281  ldns_pkt *my_pkt;
282 
283  ldns_rdf *name = NULL, *key_name = NULL;
284  ldns_rr_type type = 0;
285  ldns_rr_class c = 0;
286 
287  bool other_rrset = false;
288 
290 
291  assert(pkt != NULL);
292 
293  if (!ldns_dnssec_pkt_has_rrsigs(pkt)) {
294  /* hmm. no dnssec data in the packet. go up to try and deny
295  * DS? */
296  return new_chain;
297  }
298 
299  if (orig_rr) {
300  new_chain->rrset = ldns_rr_list_new();
301  ldns_rr_list_push_rr(new_chain->rrset, orig_rr);
302  new_chain->parent = ldns_dnssec_build_data_chain(res,
303  qflags,
304  rrset,
305  pkt,
306  NULL);
307  new_chain->packet_rcode = ldns_pkt_get_rcode(pkt);
308  new_chain->packet_qtype = ldns_rr_get_type(orig_rr);
309  if (ldns_pkt_ancount(pkt) == 0) {
310  new_chain->packet_nodata = true;
311  }
312  return new_chain;
313  }
314 
315  if (!rrset || ldns_rr_list_rr_count(rrset) < 1) {
316  /* hmm, no data, do we have denial? only works if pkt was given,
317  otherwise caller has to do the check himself */
318  new_chain->packet_nodata = true;
319  if (pkt) {
320  my_rrset = ldns_pkt_rr_list_by_type(pkt,
323  );
324  if (my_rrset) {
325  if (ldns_rr_list_rr_count(my_rrset) > 0) {
326  type = LDNS_RR_TYPE_NSEC;
327  other_rrset = true;
328  } else {
329  ldns_rr_list_deep_free(my_rrset);
330  my_rrset = NULL;
331  }
332  } else {
333  /* nothing, try nsec3 */
334  my_rrset = ldns_pkt_rr_list_by_type(pkt,
337  if (my_rrset) {
338  if (ldns_rr_list_rr_count(my_rrset) > 0) {
339  type = LDNS_RR_TYPE_NSEC3;
340  other_rrset = true;
341  } else {
342  ldns_rr_list_deep_free(my_rrset);
343  my_rrset = NULL;
344  }
345  } else {
346  /* nothing, stop */
347  /* try parent zone? for denied insecure? */
348  return new_chain;
349  }
350  }
351  } else {
352  return new_chain;
353  }
354  } else {
355  my_rrset = (ldns_rr_list *) rrset;
356  }
357 
358  if (my_rrset && ldns_rr_list_rr_count(my_rrset) > 0) {
359  new_chain->rrset = ldns_rr_list_clone(my_rrset);
360  name = ldns_rr_owner(ldns_rr_list_rr(my_rrset, 0));
361  type = ldns_rr_get_type(ldns_rr_list_rr(my_rrset, 0));
362  c = ldns_rr_get_class(ldns_rr_list_rr(my_rrset, 0));
363  }
364 
365  if (other_rrset) {
366  ldns_rr_list_deep_free(my_rrset);
367  }
368 
369  /* normally there will only be 1 signature 'set'
370  but there can be more than 1 denial (wildcards)
371  so check for NSEC
372  */
373  if (type == LDNS_RR_TYPE_NSEC || type == LDNS_RR_TYPE_NSEC3) {
374  /* just throw in all signatures, the tree builder must sort
375  this out */
376  if (pkt) {
377  signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
378  } else {
379  my_pkt = ldns_resolver_query(res, name, type, c, qflags);
380  if (my_pkt) {
381  signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
382  ldns_pkt_free(my_pkt);
383  }
384  }
385  } else {
386  if (pkt) {
387  signatures =
389  name,
390  type);
391  }
392  if (!signatures) {
393  my_pkt = ldns_resolver_query(res, name, type, c, qflags);
394  if (my_pkt) {
395  signatures =
397  name,
398  type);
399  ldns_pkt_free(my_pkt);
400  }
401  }
402  }
403 
404  if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
405  key_name = ldns_rr_rdf(ldns_rr_list_rr(signatures, 0), 7);
406  }
407  if (!key_name) {
408  if (signatures) {
409  ldns_rr_list_deep_free(signatures);
410  }
411  return ldns_dnssec_build_data_chain_nokeyname(res,
412  qflags,
413  orig_rr,
414  rrset,
415  new_chain);
416  }
417  if (type != LDNS_RR_TYPE_DNSKEY) {
418  if (type != LDNS_RR_TYPE_DS ||
419  ldns_dname_is_subdomain(name, key_name)) {
420  ldns_dnssec_build_data_chain_dnskey(res,
421  qflags,
422  pkt,
423  signatures,
424  new_chain,
425  key_name,
426  c
427  );
428  }
429  } else {
430  ldns_dnssec_build_data_chain_other(res,
431  qflags,
432  new_chain,
433  key_name,
434  c,
435  dss
436  );
437  }
438  if (signatures) {
439  ldns_rr_list_deep_free(signatures);
440  }
441  return new_chain;
442 }
443 
446 {
448  1);
449  if(!new_tree) return NULL;
450  new_tree->rr = NULL;
451  new_tree->rrset = NULL;
452  new_tree->parent_count = 0;
453 
454  return new_tree;
455 }
456 
457 void
459 {
460  size_t i;
461  if (tree) {
462  for (i = 0; i < tree->parent_count; i++) {
464  }
465  }
466  LDNS_FREE(tree);
467 }
468 
469 size_t
471 {
472  size_t result = 0;
473  size_t parent = 0;
474  size_t i;
475 
476  for (i = 0; i < tree->parent_count; i++) {
477  parent = ldns_dnssec_trust_tree_depth(tree->parents[i]);
478  if (parent > result) {
479  result = parent;
480  }
481  }
482  return 1 + result;
483 }
484 
485 /* TODO ldns_ */
486 static void
487 print_tabs(FILE *out, size_t nr, uint8_t *map, size_t treedepth)
488 {
489  size_t i;
490  for (i = 0; i < nr; i++) {
491  if (i == nr - 1) {
492  fprintf(out, "|---");
493  } else if (map && i < treedepth && map[i] == 1) {
494  fprintf(out, "| ");
495  } else {
496  fprintf(out, " ");
497  }
498  }
499 }
500 
501 static void
502 ldns_dnssec_trust_tree_print_sm_fmt(FILE *out,
503  const ldns_output_format *fmt,
505  size_t tabs,
506  bool extended,
507  uint8_t *sibmap,
508  size_t treedepth)
509 {
510  size_t i;
511  const ldns_rr_descriptor *descriptor;
512  bool mapset = false;
513 
514  if (!sibmap) {
515  treedepth = ldns_dnssec_trust_tree_depth(tree);
516  sibmap = LDNS_XMALLOC(uint8_t, treedepth);
517  if(!sibmap)
518  return; /* mem err */
519  memset(sibmap, 0, treedepth);
520  mapset = true;
521  }
522 
523  if (tree) {
524  if (tree->rr) {
525  print_tabs(out, tabs, sibmap, treedepth);
526  ldns_rdf_print(out, ldns_rr_owner(tree->rr));
527  descriptor = ldns_rr_descript(ldns_rr_get_type(tree->rr));
528 
529  if (descriptor->_name) {
530  fprintf(out, " (%s", descriptor->_name);
531  } else {
532  fprintf(out, " (TYPE%d",
533  ldns_rr_get_type(tree->rr));
534  }
535  if (tabs > 0) {
536  if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DNSKEY) {
537  fprintf(out, " keytag: %u",
538  (unsigned int) ldns_calc_keytag(tree->rr));
539  fprintf(out, " alg: ");
540  ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
541  fprintf(out, " flags: ");
542  ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
543  } else if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DS) {
544  fprintf(out, " keytag: ");
545  ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
546  fprintf(out, " digest type: ");
547  ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
548  }
549  if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NSEC) {
550  fprintf(out, " ");
551  ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
552  fprintf(out, " ");
553  ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 1));
554  }
555  }
556 
557  fprintf(out, ")\n");
558  for (i = 0; i < tree->parent_count; i++) {
559  if (tree->parent_count > 1 && i < tree->parent_count - 1) {
560  sibmap[tabs] = 1;
561  } else {
562  sibmap[tabs] = 0;
563  }
564  /* only print errors */
565  if (ldns_rr_get_type(tree->parents[i]->rr) ==
567  ldns_rr_get_type(tree->parents[i]->rr) ==
569  if (tree->parent_status[i] == LDNS_STATUS_OK) {
570  print_tabs(out, tabs + 1, sibmap, treedepth);
571  if (tabs == 0 &&
572  ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS &&
573  ldns_rr_rd_count(tree->rr) > 0) {
574  fprintf(out, "Existence of DS is denied by:\n");
575  } else {
576  fprintf(out, "Existence is denied by:\n");
577  }
578  } else {
579  /* NS records aren't signed */
580  if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS) {
581  fprintf(out, "Existence of DS is denied by:\n");
582  } else {
583  print_tabs(out, tabs + 1, sibmap, treedepth);
584  fprintf(out,
585  "Error in denial of existence: %s\n",
587  tree->parent_status[i]));
588  }
589  }
590  } else
591  if (tree->parent_status[i] != LDNS_STATUS_OK) {
592  print_tabs(out, tabs + 1, sibmap, treedepth);
593  fprintf(out,
594  "%s:\n",
596  tree->parent_status[i]));
597  if (tree->parent_status[i]
598  == LDNS_STATUS_SSL_ERR) {
599  printf("; SSL Error: ");
600  ERR_load_crypto_strings();
601  ERR_print_errors_fp(stdout);
602  printf("\n");
603  }
604  ldns_rr_print_fmt(out, fmt,
605  tree->
606  parent_signature[i]);
607  printf("For RRset:\n");
608  ldns_rr_list_print_fmt(out, fmt,
609  tree->rrset);
610  printf("With key:\n");
611  ldns_rr_print_fmt(out, fmt,
612  tree->parents[i]->rr);
613  }
614  ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
615  tree->parents[i],
616  tabs+1,
617  extended,
618  sibmap,
619  treedepth);
620  }
621  } else {
622  print_tabs(out, tabs, sibmap, treedepth);
623  fprintf(out, "<no data>\n");
624  }
625  } else {
626  fprintf(out, "<null pointer>\n");
627  }
628 
629  if (mapset) {
630  LDNS_FREE(sibmap);
631  }
632 }
633 
634 void
637  size_t tabs,
638  bool extended)
639 {
640  ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
641  tree, tabs, extended, NULL, 0);
642 }
643 
644 void
647  size_t tabs,
648  bool extended)
649 {
651  tree, tabs, extended);
652 }
653 
654 
657  const ldns_dnssec_trust_tree *parent,
658  const ldns_rr *signature,
659  const ldns_status parent_status)
660 {
661  if (tree
662  && parent
664  /*
665  printf("Add parent for: ");
666  ldns_rr_print(stdout, tree->rr);
667  printf("parent: ");
668  ldns_rr_print(stdout, parent->rr);
669  */
670  tree->parents[tree->parent_count] =
671  (ldns_dnssec_trust_tree *) parent;
672  tree->parent_status[tree->parent_count] = parent_status;
673  tree->parent_signature[tree->parent_count] = (ldns_rr *) signature;
674  tree->parent_count++;
675  return LDNS_STATUS_OK;
676  } else {
677  return LDNS_STATUS_ERR;
678  }
679 }
680 
681 /* if rr is null, take the first from the rrset */
684  ldns_dnssec_data_chain *data_chain,
685  ldns_rr *rr,
686  time_t check_time
687  )
688 {
689  ldns_rr_list *cur_rrset;
690  ldns_rr_list *cur_sigs;
691  ldns_rr *cur_rr = NULL;
692  ldns_rr *cur_sig_rr;
693  size_t i, j;
694 
696  if(!new_tree)
697  return NULL;
698 
699  if (data_chain && data_chain->rrset) {
700  cur_rrset = data_chain->rrset;
701 
702  cur_sigs = data_chain->signatures;
703 
704  if (rr) {
705  cur_rr = rr;
706  }
707 
708  if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) {
709  cur_rr = ldns_rr_list_rr(cur_rrset, 0);
710  }
711 
712  if (cur_rr) {
713  new_tree->rr = cur_rr;
714  new_tree->rrset = cur_rrset;
715  /* there are three possibilities:
716  1 - 'normal' rrset, signed by a key
717  2 - dnskey signed by other dnskey
718  3 - dnskey proven by higher level DS
719  (data denied by nsec is a special case that can
720  occur in multiple places)
721 
722  */
723  if (cur_sigs) {
724  for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) {
725  /* find the appropriate key in the parent list */
726  cur_sig_rr = ldns_rr_list_rr(cur_sigs, i);
727 
728  if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) {
729  if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
730  ldns_rr_owner(cur_rr)))
731  {
732  /* find first that does match */
733 
734  for (j = 0;
735  j < ldns_rr_list_rr_count(cur_rrset) &&
736  ldns_dname_compare(ldns_rr_owner(cur_sig_rr),ldns_rr_owner(cur_rr)) != 0;
737  j++) {
738  cur_rr = ldns_rr_list_rr(cur_rrset, j);
739 
740  }
741  if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
742  ldns_rr_owner(cur_rr)))
743  {
744  break;
745  }
746  }
747 
748  }
749  /* option 1 */
750  if (data_chain->parent) {
752  new_tree,
753  data_chain,
754  cur_sig_rr,
755  check_time);
756  }
757 
758  /* option 2 */
760  new_tree,
761  data_chain,
762  cur_rr,
763  cur_sig_rr,
764  check_time);
765  }
766 
768  new_tree, data_chain,
769  cur_rr, check_time);
770  } else {
771  /* no signatures? maybe it's nsec data */
772 
773  /* just add every rr from parent as new parent */
775  new_tree, data_chain, check_time);
776  }
777  }
778  }
779 
780  return new_tree;
781 }
782 
785 {
786  return ldns_dnssec_derive_trust_tree_time(data_chain, rr, ldns_time(NULL));
787 }
788 
789 void
791  ldns_dnssec_trust_tree *new_tree,
792  ldns_dnssec_data_chain *data_chain,
793  ldns_rr *cur_sig_rr,
794  time_t check_time)
795 {
796  size_t i, j;
797  ldns_rr_list *cur_rrset = ldns_rr_list_clone(data_chain->rrset);
798  ldns_dnssec_trust_tree *cur_parent_tree;
799  ldns_rr *cur_parent_rr;
800  uint16_t cur_keytag;
801  ldns_rr_list *tmp_rrset = NULL;
802  ldns_status cur_status;
803 
804  cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
805 
806  for (j = 0; j < ldns_rr_list_rr_count(data_chain->parent->rrset); j++) {
807  cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
808  if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
809  if (ldns_calc_keytag(cur_parent_rr) == cur_keytag) {
810 
811  /* TODO: check wildcard nsec too */
812  if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
813  tmp_rrset = cur_rrset;
814  if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
815  == LDNS_RR_TYPE_NSEC ||
816  ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
817  == LDNS_RR_TYPE_NSEC3) {
818  /* might contain different names!
819  sort and split */
820  ldns_rr_list_sort(cur_rrset);
821  assert(tmp_rrset == cur_rrset);
822  tmp_rrset = ldns_rr_list_pop_rrset(cur_rrset);
823 
824  /* with nsecs, this might be the wrong one */
825  while (tmp_rrset &&
826  ldns_rr_list_rr_count(cur_rrset) > 0 &&
829  tmp_rrset, 0)),
830  ldns_rr_owner(cur_sig_rr)) != 0) {
831  ldns_rr_list_deep_free(tmp_rrset);
832  tmp_rrset =
833  ldns_rr_list_pop_rrset(cur_rrset);
834  }
835  }
836  cur_status = ldns_verify_rrsig_time(
837  tmp_rrset,
838  cur_sig_rr,
839  cur_parent_rr,
840  check_time);
841  if (tmp_rrset && tmp_rrset != cur_rrset
842  ) {
844  tmp_rrset);
845  tmp_rrset = NULL;
846  }
847  /* avoid dupes */
848  for (i = 0; i < new_tree->parent_count; i++) {
849  if (cur_parent_rr == new_tree->parents[i]->rr) {
850  goto done;
851  }
852  }
853 
854  cur_parent_tree =
856  data_chain->parent,
857  cur_parent_rr,
858  check_time);
859  (void)ldns_dnssec_trust_tree_add_parent(new_tree,
860  cur_parent_tree,
861  cur_sig_rr,
862  cur_status);
863  }
864  }
865  }
866  }
867  done:
868  ldns_rr_list_deep_free(cur_rrset);
869 }
870 
871 void
873  ldns_dnssec_data_chain *data_chain,
874  ldns_rr *cur_sig_rr)
875 {
877  new_tree, data_chain, cur_sig_rr, ldns_time(NULL));
878 }
879 
880 void
882  ldns_dnssec_trust_tree *new_tree,
883  ldns_dnssec_data_chain *data_chain,
884  ldns_rr *cur_rr,
885  ldns_rr *cur_sig_rr,
886  time_t check_time)
887 {
888  size_t j;
889  ldns_rr_list *cur_rrset = data_chain->rrset;
890  ldns_dnssec_trust_tree *cur_parent_tree;
891  ldns_rr *cur_parent_rr;
892  uint16_t cur_keytag;
893  ldns_status cur_status;
894 
895  cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
896 
897  for (j = 0; j < ldns_rr_list_rr_count(cur_rrset); j++) {
898  cur_parent_rr = ldns_rr_list_rr(cur_rrset, j);
899  if (cur_parent_rr != cur_rr &&
900  ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
901  if (ldns_calc_keytag(cur_parent_rr) == cur_keytag
902  ) {
903  cur_parent_tree = ldns_dnssec_trust_tree_new();
904  cur_parent_tree->rr = cur_parent_rr;
905  cur_parent_tree->rrset = cur_rrset;
906  cur_status = ldns_verify_rrsig_time(
907  cur_rrset, cur_sig_rr,
908  cur_parent_rr, check_time);
910  cur_parent_tree, cur_sig_rr, cur_status))
911  ldns_dnssec_trust_tree_free(cur_parent_tree);
912  }
913  }
914  }
915 }
916 
917 void
919  ldns_dnssec_data_chain *data_chain,
920  ldns_rr *cur_rr,
921  ldns_rr *cur_sig_rr)
922 {
924  new_tree, data_chain, cur_rr, cur_sig_rr, ldns_time(NULL));
925 }
926 
927 void
929  ldns_dnssec_trust_tree *new_tree,
930  ldns_dnssec_data_chain *data_chain,
931  ldns_rr *cur_rr,
932  time_t check_time)
933 {
934  size_t j, h;
935  ldns_rr_list *cur_rrset = data_chain->rrset;
936  ldns_dnssec_trust_tree *cur_parent_tree;
937  ldns_rr *cur_parent_rr;
938 
939  /* try the parent to see whether there are DSs there */
940  if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_DNSKEY &&
941  data_chain->parent &&
942  data_chain->parent->rrset
943  ) {
944  for (j = 0;
945  j < ldns_rr_list_rr_count(data_chain->parent->rrset);
946  j++) {
947  cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
948  if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DS) {
949  for (h = 0; h < ldns_rr_list_rr_count(cur_rrset); h++) {
950  cur_rr = ldns_rr_list_rr(cur_rrset, h);
951  if (ldns_rr_compare_ds(cur_rr, cur_parent_rr)) {
952  cur_parent_tree =
954  data_chain->parent,
955  cur_parent_rr,
956  check_time);
958  new_tree,
959  cur_parent_tree,
960  NULL,
962  } else {
963  /*ldns_rr_print(stdout, cur_parent_rr);*/
964  }
965  }
966  }
967  }
968  }
969 }
970 
971 void
973  ldns_dnssec_data_chain *data_chain,
974  ldns_rr *cur_rr)
975 {
977  new_tree, data_chain, cur_rr, ldns_time(NULL));
978 }
979 
980 void
982  ldns_dnssec_trust_tree *new_tree,
983  ldns_dnssec_data_chain *data_chain,
984  time_t check_time)
985 {
986  size_t i;
987  ldns_rr_list *cur_rrset;
988  ldns_rr *cur_parent_rr;
989  ldns_dnssec_trust_tree *cur_parent_tree;
990  ldns_status result;
991 
992  if (data_chain->parent && data_chain->parent->rrset) {
993  cur_rrset = data_chain->parent->rrset;
994  /* nsec? */
995  if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
996  if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
999  new_tree->rr,
1000  cur_rrset,
1001  data_chain->parent->signatures,
1002  data_chain->packet_rcode,
1003  data_chain->packet_qtype,
1004  data_chain->packet_nodata);
1005  } else if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
1007  result = ldns_dnssec_verify_denial(
1008  new_tree->rr,
1009  cur_rrset,
1010  data_chain->parent->signatures);
1011  } else {
1012  /* unsigned zone, unsigned parent */
1013  result = LDNS_STATUS_OK;
1014  }
1015  } else {
1017  }
1018  for (i = 0; i < ldns_rr_list_rr_count(cur_rrset); i++) {
1019  cur_parent_rr = ldns_rr_list_rr(cur_rrset, i);
1020  cur_parent_tree =
1022  data_chain->parent,
1023  cur_parent_rr,
1024  check_time);
1025  if (ldns_dnssec_trust_tree_add_parent(new_tree,
1026  cur_parent_tree, NULL, result))
1027  ldns_dnssec_trust_tree_free(cur_parent_tree);
1028 
1029  }
1030  }
1031 }
1032 
1033 void
1035  ldns_dnssec_data_chain *data_chain)
1036 {
1038  new_tree, data_chain, ldns_time(NULL));
1039 }
1040 
1041 /*
1042  * returns OK if there is a path from tree to key with only OK
1043  * the (first) error in between otherwise
1044  * or NOT_FOUND if the key wasn't present at all
1045  */
1048  ldns_rr_list *trusted_keys)
1049 {
1050  size_t i;
1052  bool equal;
1053  ldns_status parent_result;
1054 
1055  if (tree && trusted_keys && ldns_rr_list_rr_count(trusted_keys) > 0)
1056  { if (tree->rr) {
1057  for (i = 0; i < ldns_rr_list_rr_count(trusted_keys); i++) {
1058  equal = ldns_rr_compare_ds(
1059  tree->rr,
1060  ldns_rr_list_rr(trusted_keys, i));
1061  if (equal) {
1062  result = LDNS_STATUS_OK;
1063  return result;
1064  }
1065  }
1066  }
1067  for (i = 0; i < tree->parent_count; i++) {
1068  parent_result =
1070  trusted_keys);
1071  if (parent_result != LDNS_STATUS_CRYPTO_NO_DNSKEY) {
1072  if (tree->parent_status[i] != LDNS_STATUS_OK) {
1073  result = tree->parent_status[i];
1074  } else {
1075  if (tree->rr &&
1076  ldns_rr_get_type(tree->rr)
1077  == LDNS_RR_TYPE_NSEC &&
1078  parent_result == LDNS_STATUS_OK
1079  ) {
1080  result =
1082  } else {
1083  result = parent_result;
1084  }
1085  }
1086  }
1087  }
1088  } else {
1089  result = LDNS_STATUS_ERR;
1090  }
1091 
1092  return result;
1093 }
1094 
1097  const ldns_rr_list *rrset,
1098  const ldns_rr_list *rrsig,
1099  const ldns_rr_list *keys,
1100  time_t check_time,
1101  ldns_rr_list *good_keys
1102  )
1103 {
1104  uint16_t i;
1105  ldns_status verify_result = LDNS_STATUS_ERR;
1106 
1107  if (!rrset || !rrsig || !keys) {
1108  return LDNS_STATUS_ERR;
1109  }
1110 
1111  if (ldns_rr_list_rr_count(rrset) < 1) {
1112  return LDNS_STATUS_ERR;
1113  }
1114 
1115  if (ldns_rr_list_rr_count(rrsig) < 1) {
1117  }
1118 
1119  if (ldns_rr_list_rr_count(keys) < 1) {
1120  verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1121  } else {
1122  for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1124  rrset, ldns_rr_list_rr(rrsig, i),
1125  keys, check_time, good_keys);
1126  /* try a little to get more descriptive error */
1127  if(s == LDNS_STATUS_OK) {
1128  verify_result = LDNS_STATUS_OK;
1129  } else if(verify_result == LDNS_STATUS_ERR)
1130  verify_result = s;
1131  else if(s != LDNS_STATUS_ERR && verify_result ==
1133  verify_result = s;
1134  }
1135  }
1136  return verify_result;
1137 }
1138