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 initializes 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 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(HAVE_LIBRESSL)
601  ERR_load_crypto_strings();
602 #endif
603  ERR_print_errors_fp(stdout);
604  printf("\n");
605  }
606  ldns_rr_print_fmt(out, fmt,
607  tree->
608  parent_signature[i]);
609  printf("For RRset:\n");
610  ldns_rr_list_print_fmt(out, fmt,
611  tree->rrset);
612  printf("With key:\n");
613  ldns_rr_print_fmt(out, fmt,
614  tree->parents[i]->rr);
615  }
616  ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
617  tree->parents[i],
618  tabs+1,
619  extended,
620  sibmap,
621  treedepth);
622  }
623  } else {
624  print_tabs(out, tabs, sibmap, treedepth);
625  fprintf(out, "<no data>\n");
626  }
627  } else {
628  fprintf(out, "<null pointer>\n");
629  }
630 
631  if (mapset) {
632  LDNS_FREE(sibmap);
633  }
634 }
635 
636 void
639  size_t tabs,
640  bool extended)
641 {
642  ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
643  tree, tabs, extended, NULL, 0);
644 }
645 
646 void
649  size_t tabs,
650  bool extended)
651 {
653  tree, tabs, extended);
654 }
655 
656 
659  const ldns_dnssec_trust_tree *parent,
660  const ldns_rr *signature,
661  const ldns_status parent_status)
662 {
663  if (tree
664  && parent
666  /*
667  printf("Add parent for: ");
668  ldns_rr_print(stdout, tree->rr);
669  printf("parent: ");
670  ldns_rr_print(stdout, parent->rr);
671  */
672  tree->parents[tree->parent_count] =
673  (ldns_dnssec_trust_tree *) parent;
674  tree->parent_status[tree->parent_count] = parent_status;
675  tree->parent_signature[tree->parent_count] = (ldns_rr *) signature;
676  tree->parent_count++;
677  return LDNS_STATUS_OK;
678  } else {
679  return LDNS_STATUS_ERR;
680  }
681 }
682 
683 /* if rr is null, take the first from the rrset */
686  ldns_dnssec_data_chain *data_chain,
687  ldns_rr *rr,
688  time_t check_time
689  )
690 {
691  ldns_rr_list *cur_rrset;
692  ldns_rr_list *cur_sigs;
693  ldns_rr *cur_rr = NULL;
694  ldns_rr *cur_sig_rr;
695  size_t i, j;
696 
698  if(!new_tree)
699  return NULL;
700 
701  if (data_chain && data_chain->rrset) {
702  cur_rrset = data_chain->rrset;
703 
704  cur_sigs = data_chain->signatures;
705 
706  if (rr) {
707  cur_rr = rr;
708  }
709 
710  if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) {
711  cur_rr = ldns_rr_list_rr(cur_rrset, 0);
712  }
713 
714  if (cur_rr) {
715  new_tree->rr = cur_rr;
716  new_tree->rrset = cur_rrset;
717  /* there are three possibilities:
718  1 - 'normal' rrset, signed by a key
719  2 - dnskey signed by other dnskey
720  3 - dnskey proven by higher level DS
721  (data denied by nsec is a special case that can
722  occur in multiple places)
723 
724  */
725  if (cur_sigs) {
726  for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) {
727  /* find the appropriate key in the parent list */
728  cur_sig_rr = ldns_rr_list_rr(cur_sigs, i);
729 
730  if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) {
731  if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
732  ldns_rr_owner(cur_rr)))
733  {
734  /* find first that does match */
735 
736  for (j = 0;
737  j < ldns_rr_list_rr_count(cur_rrset) &&
738  ldns_dname_compare(ldns_rr_owner(cur_sig_rr),ldns_rr_owner(cur_rr)) != 0;
739  j++) {
740  cur_rr = ldns_rr_list_rr(cur_rrset, j);
741 
742  }
743  if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
744  ldns_rr_owner(cur_rr)))
745  {
746  break;
747  }
748  }
749 
750  }
751  /* option 1 */
752  if (data_chain->parent) {
754  new_tree,
755  data_chain,
756  cur_sig_rr,
757  check_time);
758  }
759 
760  /* option 2 */
762  new_tree,
763  data_chain,
764  cur_rr,
765  cur_sig_rr,
766  check_time);
767  }
768 
770  new_tree, data_chain,
771  cur_rr, check_time);
772  } else {
773  /* no signatures? maybe it's nsec data */
774 
775  /* just add every rr from parent as new parent */
777  new_tree, data_chain, check_time);
778  }
779  }
780  }
781 
782  return new_tree;
783 }
784 
787 {
788  return ldns_dnssec_derive_trust_tree_time(data_chain, rr, ldns_time(NULL));
789 }
790 
791 void
793  ldns_dnssec_trust_tree *new_tree,
794  ldns_dnssec_data_chain *data_chain,
795  ldns_rr *cur_sig_rr,
796  time_t check_time)
797 {
798  size_t i, j;
799  ldns_rr_list *cur_rrset = ldns_rr_list_clone(data_chain->rrset);
800  ldns_dnssec_trust_tree *cur_parent_tree;
801  ldns_rr *cur_parent_rr;
802  uint16_t cur_keytag;
803  ldns_rr_list *tmp_rrset = NULL;
804  ldns_status cur_status;
805 
806  cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
807 
808  for (j = 0; j < ldns_rr_list_rr_count(data_chain->parent->rrset); j++) {
809  cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
810  if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
811  if (ldns_calc_keytag(cur_parent_rr) == cur_keytag) {
812 
813  /* TODO: check wildcard nsec too */
814  if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
815  tmp_rrset = cur_rrset;
816  if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
817  == LDNS_RR_TYPE_NSEC ||
818  ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
819  == LDNS_RR_TYPE_NSEC3) {
820  /* might contain different names!
821  sort and split */
822  ldns_rr_list_sort(cur_rrset);
823  assert(tmp_rrset == cur_rrset);
824  tmp_rrset = ldns_rr_list_pop_rrset(cur_rrset);
825 
826  /* with nsecs, this might be the wrong one */
827  while (tmp_rrset &&
828  ldns_rr_list_rr_count(cur_rrset) > 0 &&
831  tmp_rrset, 0)),
832  ldns_rr_owner(cur_sig_rr)) != 0) {
833  ldns_rr_list_deep_free(tmp_rrset);
834  tmp_rrset =
835  ldns_rr_list_pop_rrset(cur_rrset);
836  }
837  }
838  cur_status = ldns_verify_rrsig_time(
839  tmp_rrset,
840  cur_sig_rr,
841  cur_parent_rr,
842  check_time);
843  if (tmp_rrset && tmp_rrset != cur_rrset
844  ) {
846  tmp_rrset);
847  tmp_rrset = NULL;
848  }
849  /* avoid dupes */
850  for (i = 0; i < new_tree->parent_count; i++) {
851  if (cur_parent_rr == new_tree->parents[i]->rr) {
852  goto done;
853  }
854  }
855 
856  cur_parent_tree =
858  data_chain->parent,
859  cur_parent_rr,
860  check_time);
861  (void)ldns_dnssec_trust_tree_add_parent(new_tree,
862  cur_parent_tree,
863  cur_sig_rr,
864  cur_status);
865  }
866  }
867  }
868  }
869  done:
870  ldns_rr_list_deep_free(cur_rrset);
871 }
872 
873 void
875  ldns_dnssec_data_chain *data_chain,
876  ldns_rr *cur_sig_rr)
877 {
879  new_tree, data_chain, cur_sig_rr, ldns_time(NULL));
880 }
881 
882 void
884  ldns_dnssec_trust_tree *new_tree,
885  ldns_dnssec_data_chain *data_chain,
886  ldns_rr *cur_rr,
887  ldns_rr *cur_sig_rr,
888  time_t check_time)
889 {
890  size_t j;
891  ldns_rr_list *cur_rrset = data_chain->rrset;
892  ldns_dnssec_trust_tree *cur_parent_tree;
893  ldns_rr *cur_parent_rr;
894  uint16_t cur_keytag;
895  ldns_status cur_status;
896 
897  cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
898 
899  for (j = 0; j < ldns_rr_list_rr_count(cur_rrset); j++) {
900  cur_parent_rr = ldns_rr_list_rr(cur_rrset, j);
901  if (cur_parent_rr != cur_rr &&
902  ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
903  if (ldns_calc_keytag(cur_parent_rr) == cur_keytag
904  ) {
905  cur_parent_tree = ldns_dnssec_trust_tree_new();
906  cur_parent_tree->rr = cur_parent_rr;
907  cur_parent_tree->rrset = cur_rrset;
908  cur_status = ldns_verify_rrsig_time(
909  cur_rrset, cur_sig_rr,
910  cur_parent_rr, check_time);
912  cur_parent_tree, cur_sig_rr, cur_status))
913  ldns_dnssec_trust_tree_free(cur_parent_tree);
914  }
915  }
916  }
917 }
918 
919 void
921  ldns_dnssec_data_chain *data_chain,
922  ldns_rr *cur_rr,
923  ldns_rr *cur_sig_rr)
924 {
926  new_tree, data_chain, cur_rr, cur_sig_rr, ldns_time(NULL));
927 }
928 
929 void
931  ldns_dnssec_trust_tree *new_tree,
932  ldns_dnssec_data_chain *data_chain,
933  ldns_rr *cur_rr,
934  time_t check_time)
935 {
936  size_t j, h;
937  ldns_rr_list *cur_rrset = data_chain->rrset;
938  ldns_dnssec_trust_tree *cur_parent_tree;
939  ldns_rr *cur_parent_rr;
940 
941  /* try the parent to see whether there are DSs there */
942  if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_DNSKEY &&
943  data_chain->parent &&
944  data_chain->parent->rrset
945  ) {
946  for (j = 0;
947  j < ldns_rr_list_rr_count(data_chain->parent->rrset);
948  j++) {
949  cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
950  if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DS) {
951  for (h = 0; h < ldns_rr_list_rr_count(cur_rrset); h++) {
952  cur_rr = ldns_rr_list_rr(cur_rrset, h);
953  if (ldns_rr_compare_ds(cur_rr, cur_parent_rr)) {
954  cur_parent_tree =
956  data_chain->parent,
957  cur_parent_rr,
958  check_time);
960  new_tree,
961  cur_parent_tree,
962  NULL,
964  } else {
965  /*ldns_rr_print(stdout, cur_parent_rr);*/
966  }
967  }
968  }
969  }
970  }
971 }
972 
973 void
975  ldns_dnssec_data_chain *data_chain,
976  ldns_rr *cur_rr)
977 {
979  new_tree, data_chain, cur_rr, ldns_time(NULL));
980 }
981 
982 void
984  ldns_dnssec_trust_tree *new_tree,
985  ldns_dnssec_data_chain *data_chain,
986  time_t check_time)
987 {
988  size_t i;
989  ldns_rr_list *cur_rrset;
990  ldns_rr *cur_parent_rr;
991  ldns_dnssec_trust_tree *cur_parent_tree;
992  ldns_status result;
993 
994  if (data_chain->parent && data_chain->parent->rrset) {
995  cur_rrset = data_chain->parent->rrset;
996  /* nsec? */
997  if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
998  if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
1001  new_tree->rr,
1002  cur_rrset,
1003  data_chain->parent->signatures,
1004  data_chain->packet_rcode,
1005  data_chain->packet_qtype,
1006  data_chain->packet_nodata);
1007  } else if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
1009  result = ldns_dnssec_verify_denial(
1010  new_tree->rr,
1011  cur_rrset,
1012  data_chain->parent->signatures);
1013  } else {
1014  /* unsigned zone, unsigned parent */
1015  result = LDNS_STATUS_OK;
1016  }
1017  } else {
1019  }
1020  for (i = 0; i < ldns_rr_list_rr_count(cur_rrset); i++) {
1021  cur_parent_rr = ldns_rr_list_rr(cur_rrset, i);
1022  cur_parent_tree =
1024  data_chain->parent,
1025  cur_parent_rr,
1026  check_time);
1027  if (ldns_dnssec_trust_tree_add_parent(new_tree,
1028  cur_parent_tree, NULL, result))
1029  ldns_dnssec_trust_tree_free(cur_parent_tree);
1030 
1031  }
1032  }
1033 }
1034 
1035 void
1037  ldns_dnssec_data_chain *data_chain)
1038 {
1040  new_tree, data_chain, ldns_time(NULL));
1041 }
1042 
1043 /*
1044  * returns OK if there is a path from tree to key with only OK
1045  * the (first) error in between otherwise
1046  * or NOT_FOUND if the key wasn't present at all
1047  */
1050  ldns_rr_list *trusted_keys)
1051 {
1052  size_t i;
1054  bool equal;
1055  ldns_status parent_result;
1056 
1057  if (tree && trusted_keys && ldns_rr_list_rr_count(trusted_keys) > 0)
1058  { if (tree->rr) {
1059  for (i = 0; i < ldns_rr_list_rr_count(trusted_keys); i++) {
1060  equal = ldns_rr_compare_ds(
1061  tree->rr,
1062  ldns_rr_list_rr(trusted_keys, i));
1063  if (equal) {
1064  result = LDNS_STATUS_OK;
1065  return result;
1066  }
1067  }
1068  }
1069  for (i = 0; i < tree->parent_count; i++) {
1070  parent_result =
1072  trusted_keys);
1073  if (parent_result != LDNS_STATUS_CRYPTO_NO_DNSKEY) {
1074  if (tree->parent_status[i] != LDNS_STATUS_OK) {
1075  result = tree->parent_status[i];
1076  } else {
1077  if (tree->rr &&
1078  ldns_rr_get_type(tree->rr)
1079  == LDNS_RR_TYPE_NSEC &&
1080  parent_result == LDNS_STATUS_OK
1081  ) {
1082  result =
1084  } else {
1085  result = parent_result;
1086  }
1087  }
1088  }
1089  }
1090  } else {
1091  result = LDNS_STATUS_ERR;
1092  }
1093 
1094  return result;
1095 }
1096 
1099  const ldns_rr_list *rrset,
1100  const ldns_rr_list *rrsig,
1101  const ldns_rr_list *keys,
1102  time_t check_time,
1103  ldns_rr_list *good_keys
1104  )
1105 {
1106  uint16_t i;
1107  ldns_status verify_result = LDNS_STATUS_ERR;
1108 
1109  if (!rrset || !rrsig || !keys) {
1110  return LDNS_STATUS_ERR;
1111  }
1112 
1113  if (ldns_rr_list_rr_count(rrset) < 1) {
1114  return LDNS_STATUS_ERR;
1115  }
1116 
1117  if (ldns_rr_list_rr_count(rrsig) < 1) {
1119  }
1120 
1121  if (ldns_rr_list_rr_count(keys) < 1) {
1122  verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1123  } else {
1124  for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1126  rrset, ldns_rr_list_rr(rrsig, i),
1127  keys, check_time, good_keys);
1128  /* try a little to get more descriptive error */
1129  if(s == LDNS_STATUS_OK) {
1130  verify_result = LDNS_STATUS_OK;
1131  } else if(verify_result == LDNS_STATUS_ERR)
1132  verify_result = s;
1133  else if(s != LDNS_STATUS_ERR && verify_result ==
1135  verify_result = s;
1136  }
1137  }
1138  return verify_result;
1139 }
1140 
1142 ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys,
1143  ldns_rr_list *good_keys)
1144 {
1145  return ldns_verify_time(rrset, rrsig, keys, ldns_time(NULL), good_keys);
1146 }
1147 
1150  const ldns_rr_list *keys, ldns_rr_list *good_keys)
1151 {
1152  uint16_t i;
1153  ldns_status verify_result = LDNS_STATUS_ERR;
1154 
1155  if (!rrset || !rrsig || !keys) {
1156  return LDNS_STATUS_ERR;
1157  }
1158 
1159  if (ldns_rr_list_rr_count(rrset) < 1) {
1160  return LDNS_STATUS_ERR;
1161  }
1162 
1163  if (ldns_rr_list_rr_count(rrsig) < 1) {
1165  }
1166 
1167  if (ldns_rr_list_rr_count(keys) < 1) {
1168  verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1169  } else {
1170  for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1172  ldns_rr_list_rr(rrsig, i), keys, good_keys);
1173 
1174  /* try a little to get more descriptive error */
1175  if (s == LDNS_STATUS_OK) {
1176  verify_result = LDNS_STATUS_OK;
1177  } else if (verify_result == LDNS_STATUS_ERR) {
1178  verify_result = s;
1179  } else if (s != LDNS_STATUS_ERR && verify_result ==
1181  verify_result = s;
1182  }
1183  }
1184  }
1185  return verify_result;
1186 }
1187 
1188 ldns_rr_list *
1190  const ldns_rdf *domain,
1191  const ldns_rr_list *keys,
1192  time_t check_time,
1193  ldns_status *status)
1194 {
1195  ldns_rr_list * trusted_keys = NULL;
1196  ldns_rr_list * ds_keys = NULL;
1197  ldns_rdf * prev_parent_domain;
1198  ldns_rdf * parent_domain;
1199  ldns_rr_list * parent_keys = NULL;
1200 
1201  if (res && domain && keys) {
1202 
1203  if ((trusted_keys = ldns_validate_domain_dnskey_time(res,
1204  domain, keys, check_time))) {
1205  *status = LDNS_STATUS_OK;
1206  } else {
1207  /* No trusted keys in this domain, we'll have to find some in the parent domain */
1209 
1210  parent_domain = ldns_dname_left_chop(domain);
1211  while (parent_domain && /* Fail if we are at the root*/
1212  ldns_rdf_size(parent_domain) > 0) {
1213 
1214  if ((parent_keys =
1216  parent_domain,
1217  keys,
1218  check_time,
1219  status))) {
1220  /* Check DS records */
1221  if ((ds_keys =
1223  domain,
1224  parent_keys,
1225  check_time))) {
1226  trusted_keys =
1228  res,
1229  domain,
1230  ds_keys,
1231  check_time,
1232  status);
1233  ldns_rr_list_deep_free(ds_keys);
1234  } else {
1235  /* No valid DS at the parent -- fail */
1237  }
1238  ldns_rr_list_deep_free(parent_keys);
1239  break;
1240  } else {
1241  parent_domain = ldns_dname_left_chop((
1242  prev_parent_domain
1243  = parent_domain
1244  ));
1245  ldns_rdf_deep_free(prev_parent_domain);
1246  }
1247  }
1248  if (parent_domain) {
1249  ldns_rdf_deep_free(parent_domain);
1250  }
1251  }
1252  }
1253  return trusted_keys;
1254 }
1255 
1256 ldns_rr_list *
1258  const ldns_rdf *domain,
1259  const ldns_rr_list *keys,
1260  ldns_status *status)
1261 {
1263  res, domain, keys, ldns_time(NULL), status);
1264 }
1265 
1266 ldns_rr_list *
1268  const ldns_resolver * res,
1269  const ldns_rdf * domain,
1270  const ldns_rr_list * keys,
1271  time_t check_time
1272  )
1273 {
1274  ldns_pkt * keypkt;
1275  ldns_rr * cur_key;
1276  uint16_t key_i; uint16_t key_j; uint16_t key_k;
1277  uint16_t sig_i; ldns_rr * cur_sig;
1278 
1279  ldns_rr_list * domain_keys = NULL;
1280  ldns_rr_list * domain_sigs = NULL;
1281  ldns_rr_list * trusted_keys = NULL;
1282 
1283  /* Fetch keys for the domain */
1284  keypkt = ldns_resolver_query(res, domain,
1286  if (keypkt) {
1287  domain_keys = ldns_pkt_rr_list_by_type(keypkt,
1290  domain_sigs = ldns_pkt_rr_list_by_type(keypkt,
1293 
1294  /* Try to validate the record using our keys */
1295  for (key_i=0; key_i< ldns_rr_list_rr_count(domain_keys); key_i++) {
1296 
1297  cur_key = ldns_rr_list_rr(domain_keys, key_i);
1298  for (key_j=0; key_j<ldns_rr_list_rr_count(keys); key_j++) {
1299  if (ldns_rr_compare_ds(ldns_rr_list_rr(keys, key_j),
1300  cur_key)) {
1301 
1302  /* Current key is trusted -- validate */
1303  trusted_keys = ldns_rr_list_new();
1304 
1305  for (sig_i=0;
1306  sig_i<ldns_rr_list_rr_count(domain_sigs);
1307  sig_i++) {
1308  cur_sig = ldns_rr_list_rr(domain_sigs, sig_i);
1309  /* Avoid non-matching sigs */
1311  ldns_rr_rrsig_keytag(cur_sig))
1312  == ldns_calc_keytag(cur_key)) {
1314  domain_keys,
1315  cur_sig,
1316  cur_key,
1317  check_time)
1318  == LDNS_STATUS_OK) {
1319 
1320  /* Push the whole rrset
1321  -- we can't do much more */
1322  for (key_k=0;
1323  key_k<ldns_rr_list_rr_count(
1324  domain_keys);
1325  key_k++) {
1327  trusted_keys,
1328  ldns_rr_clone(
1330  domain_keys,
1331  key_k)));
1332  }
1333 
1334  ldns_rr_list_deep_free(domain_keys);
1335  ldns_rr_list_deep_free(domain_sigs);
1336  ldns_pkt_free(keypkt);
1337  return trusted_keys;
1338  }
1339  }
1340  }
1341 
1342  /* Only push our trusted key */
1343  ldns_rr_list_push_rr(trusted_keys,
1344  ldns_rr_clone(cur_key));
1345  }
1346  }
1347  }
1348 
1349  ldns_rr_list_deep_free(domain_keys);
1350  ldns_rr_list_deep_free(domain_sigs);
1351  ldns_pkt_free(keypkt);
1352 
1353  } else {
1354  /* LDNS_STATUS_CRYPTO_NO_DNSKEY */
1355  }
1356 
1357  return trusted_keys;
1358 }
1359 
1360 ldns_rr_list *
1362  const ldns_rdf * domain,
1363  const ldns_rr_list * keys)
1364 {
1366  res, domain, keys, ldns_time(NULL));
1367 }
1368 
1369 ldns_rr_list *
1371  const ldns_resolver *res,
1372  const ldns_rdf * domain,
1373  const ldns_rr_list * keys,
1374  time_t check_time)
1375 {
1376  ldns_pkt * dspkt;
1377  uint16_t key_i;
1378  ldns_rr_list * rrset = NULL;
1379  ldns_rr_list * sigs = NULL;
1380  ldns_rr_list * trusted_keys = NULL;
1381 
1382  /* Fetch DS for the domain */
1383  dspkt = ldns_resolver_query(res, domain,
1385  if (dspkt) {
1386  rrset = ldns_pkt_rr_list_by_type(dspkt,
1389  sigs = ldns_pkt_rr_list_by_type(dspkt,
1392 
1393  /* Validate sigs */
1394  if (ldns_verify_time(rrset, sigs, keys, check_time, NULL)
1395  == LDNS_STATUS_OK) {
1396  trusted_keys = ldns_rr_list_new();
1397  for (key_i=0; key_i<ldns_rr_list_rr_count(rrset); key_i++) {
1398  ldns_rr_list_push_rr(trusted_keys,
1400  key_i)
1401  )
1402  );
1403  }
1404  }
1405 
1406  ldns_rr_list_deep_free(rrset);
1407  ldns_rr_list_deep_free(sigs);
1408  ldns_pkt_free(dspkt);
1409 
1410  } else {
1411  /* LDNS_STATUS_CRYPTO_NO_DS */
1412  }
1413 
1414  return trusted_keys;
1415 }
1416 
1417 ldns_rr_list *
1419  const ldns_rdf * domain,
1420  const ldns_rr_list * keys)
1421 {
1422  return ldns_validate_domain_ds_time(res, domain, keys, ldns_time(NULL));
1423 }
1424 
1427  ldns_resolver *res,
1428  ldns_rr_list *rrset,
1429  ldns_rr_list * rrsigs,
1430  time_t check_time,
1431  ldns_rr_list * validating_keys
1432  )
1433 {
1434  uint16_t sig_i; uint16_t key_i;
1435  ldns_rr * cur_sig; ldns_rr * cur_key;
1436  ldns_rr_list * trusted_keys = NULL;
1437  ldns_status result = LDNS_STATUS_ERR;
1438 
1439  if (!res || !rrset || !rrsigs) {
1440  return LDNS_STATUS_ERR;
1441  }
1442 
1443  if (ldns_rr_list_rr_count(rrset) < 1) {
1444  return LDNS_STATUS_ERR;
1445  }
1446 
1447  if (ldns_rr_list_rr_count(rrsigs) < 1) {
1449  }
1450 
1451  /* Look at each sig */
1452  for (sig_i=0; sig_i < ldns_rr_list_rr_count(rrsigs); sig_i++) {
1453 
1454  cur_sig = ldns_rr_list_rr(rrsigs, sig_i);
1455  /* Get a valid signer key and validate the sig */
1456  if ((trusted_keys = ldns_fetch_valid_domain_keys_time(
1457  res,
1458  ldns_rr_rrsig_signame(cur_sig),
1460  check_time,
1461  &result))) {
1462 
1463  for (key_i = 0;
1464  key_i < ldns_rr_list_rr_count(trusted_keys);
1465  key_i++) {
1466  cur_key = ldns_rr_list_rr(trusted_keys, key_i);
1467 
1468  if ((result = ldns_verify_rrsig_time(rrset,
1469  cur_sig,
1470  cur_key,
1471  check_time))
1472  == LDNS_STATUS_OK) {
1473  if (validating_keys) {
1474  ldns_rr_list_push_rr(validating_keys,
1475  ldns_rr_clone(cur_key));
1476  }
1477  ldns_rr_list_deep_free(trusted_keys);
1478  return LDNS_STATUS_OK;
1479  }
1480  }
1481  }
1482  }
1483 
1484  ldns_rr_list_deep_free(trusted_keys);
1485  return result;
1486 }
1487 
1490  ldns_resolver *res,
1491  ldns_rr_list *rrset,
1492  ldns_rr_list * rrsigs,
1493  ldns_rr_list * validating_keys)
1494 {
1495  return ldns_verify_trusted_time(
1496  res, rrset, rrsigs, ldns_time(NULL), validating_keys);
1497 }
1498 
1499 
1502  ldns_rr_list *nsecs,
1503  ldns_rr_list *rrsigs)
1504 {
1505  ldns_rdf *rr_name;
1506  ldns_rdf *wildcard_name = NULL;
1507  ldns_rdf *chopped_dname;
1508  ldns_rr *cur_nsec;
1509  size_t i;
1510  ldns_status result;
1511  /* needed for wildcard check on exact match */
1512  ldns_rr *rrsig;
1513  bool name_covered = false;
1514  bool type_covered = false;
1515  bool wildcard_covered = false;
1516  bool wildcard_type_covered = false;
1517  bool rr_name_is_root = false;
1518 
1519  rr_name = ldns_rr_owner(rr);
1520  rr_name_is_root = ldns_rdf_size(rr_name) == 1
1521  && *ldns_rdf_data(rr_name) == 0;
1522  if (!rr_name_is_root) {
1523  wildcard_name = ldns_dname_new_frm_str("*");
1524  chopped_dname = ldns_dname_left_chop(rr_name);
1525  result = ldns_dname_cat(wildcard_name, chopped_dname);
1526  ldns_rdf_deep_free(chopped_dname);
1527  if (result != LDNS_STATUS_OK) {
1528  return result;
1529  }
1530  }
1531 
1532  for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1533  cur_nsec = ldns_rr_list_rr(nsecs, i);
1534  if (ldns_dname_compare(rr_name, ldns_rr_owner(cur_nsec)) == 0) {
1535  /* see section 5.4 of RFC4035, if the label count of the NSEC's
1536  RRSIG is equal, then it is proven that wildcard expansion
1537  could not have been used to match the request */
1539  ldns_rr_owner(cur_nsec),
1540  ldns_rr_get_type(cur_nsec),
1541  rrsigs);
1542  if (rrsig && ldns_rdf2native_int8(ldns_rr_rrsig_labels(rrsig))
1543  == ldns_dname_label_count(rr_name)) {
1544  wildcard_covered = true;
1545  }
1546 
1548  ldns_rr_get_type(rr))) {
1549  type_covered = true;
1550  }
1551  }
1552  if (ldns_nsec_covers_name(cur_nsec, rr_name)) {
1553  name_covered = true;
1554  }
1555 
1556  if (rr_name_is_root)
1557  continue;
1558 
1559  if (ldns_dname_compare(wildcard_name,
1560  ldns_rr_owner(cur_nsec)) == 0) {
1562  ldns_rr_get_type(rr))) {
1563  wildcard_type_covered = true;
1564  }
1565  }
1566 
1567  if (ldns_nsec_covers_name(cur_nsec, wildcard_name)) {
1568  wildcard_covered = true;
1569  }
1570 
1571  }
1572 
1573  ldns_rdf_deep_free(wildcard_name);
1574 
1575  if (type_covered || !name_covered) {
1577  }
1578 
1579  if (rr_name_is_root)
1580  return LDNS_STATUS_OK;
1581 
1582  if (wildcard_type_covered || !wildcard_covered) {
1584  }
1585 
1586  return LDNS_STATUS_OK;
1587 }
1588 
1591  , ldns_rr_list *nsecs
1592  , ATTR_UNUSED(ldns_rr_list *rrsigs)
1593  , ldns_pkt_rcode packet_rcode
1594  , ldns_rr_type packet_qtype
1595  , bool packet_nodata
1596  , ldns_rr **match
1597  )
1598 {
1599  ldns_rdf *closest_encloser;
1600  ldns_rdf *wildcard;
1601  ldns_rdf *hashed_wildcard_name;
1602  bool wildcard_covered = false;
1603  ldns_rdf *zone_name;
1604  ldns_rdf *hashed_name;
1605  ldns_rdf *hashed_next_closer;
1606  size_t i;
1608 
1609  if (match) {
1610  *match = NULL;
1611  }
1612 
1613  zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
1614 
1615  /* section 8.4 */
1616  if (packet_rcode == LDNS_RCODE_NXDOMAIN) {
1617  closest_encloser = ldns_dnssec_nsec3_closest_encloser(
1618  ldns_rr_owner(rr),
1619  ldns_rr_get_type(rr),
1620  nsecs);
1621  if(!closest_encloser) {
1623  goto done;
1624  }
1625 
1626  wildcard = ldns_dname_new_frm_str("*");
1627  (void) ldns_dname_cat(wildcard, closest_encloser);
1628 
1629  for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1630  hashed_wildcard_name =
1632  wildcard
1633  );
1634  (void) ldns_dname_cat(hashed_wildcard_name, zone_name);
1635 
1636  if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
1637  hashed_wildcard_name)) {
1638  wildcard_covered = true;
1639  if (match) {
1640  *match = ldns_rr_list_rr(nsecs, i);
1641  }
1642  }
1643  ldns_rdf_deep_free(hashed_wildcard_name);
1644  }
1645 
1646  if (! wildcard_covered) {
1648  } else {
1649  result = LDNS_STATUS_OK;
1650  }
1651  ldns_rdf_deep_free(closest_encloser);
1652  ldns_rdf_deep_free(wildcard);
1653 
1654  } else if (packet_nodata && packet_qtype != LDNS_RR_TYPE_DS) {
1655  /* section 8.5 */
1656  hashed_name = ldns_nsec3_hash_name_frm_nsec3(
1657  ldns_rr_list_rr(nsecs, 0),
1658  ldns_rr_owner(rr));
1659  (void) ldns_dname_cat(hashed_name, zone_name);
1660  for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1661  if (ldns_dname_compare(hashed_name,
1662  ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
1663  == 0) {
1666  packet_qtype)
1667  &&
1670  LDNS_RR_TYPE_CNAME)) {
1671  result = LDNS_STATUS_OK;
1672  if (match) {
1673  *match = ldns_rr_list_rr(nsecs, i);
1674  }
1675  goto done;
1676  }
1677  }
1678  }
1679  ldns_rdf_deep_free(hashed_name);
1681  /* wildcard no data? section 8.7 */
1682  closest_encloser = ldns_dnssec_nsec3_closest_encloser(
1683  ldns_rr_owner(rr),
1684  ldns_rr_get_type(rr),
1685  nsecs);
1686  if(!closest_encloser) {
1687  result = LDNS_STATUS_NSEC3_ERR;
1688  goto done;
1689  }
1690  wildcard = ldns_dname_new_frm_str("*");
1691  (void) ldns_dname_cat(wildcard, closest_encloser);
1692  for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1693  hashed_wildcard_name =
1695  wildcard);
1696  (void) ldns_dname_cat(hashed_wildcard_name, zone_name);
1697 
1698  if (ldns_dname_compare(hashed_wildcard_name,
1699  ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
1700  == 0) {
1703  packet_qtype)
1704  &&
1707  LDNS_RR_TYPE_CNAME)) {
1708  result = LDNS_STATUS_OK;
1709  if (match) {
1710  *match = ldns_rr_list_rr(nsecs, i);
1711  }
1712  }
1713  }
1714  ldns_rdf_deep_free(hashed_wildcard_name);
1715  if (result == LDNS_STATUS_OK) {
1716  break;
1717  }
1718  }
1719  ldns_rdf_deep_free(closest_encloser);
1720  ldns_rdf_deep_free(wildcard);
1721  } else if (packet_nodata && packet_qtype == LDNS_RR_TYPE_DS) {
1722  /* section 8.6 */
1723  /* note: up to XXX this is the same as for 8.5 */
1724  hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs,
1725  0),
1726  ldns_rr_owner(rr)
1727  );
1728  (void) ldns_dname_cat(hashed_name, zone_name);
1729  for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1730  if (ldns_dname_compare(hashed_name,
1732  i)))
1733  == 0) {
1737  &&
1740  LDNS_RR_TYPE_CNAME)) {
1741  result = LDNS_STATUS_OK;
1742  if (match) {
1743  *match = ldns_rr_list_rr(nsecs, i);
1744  }
1745  goto done;
1746  }
1747  }
1748  }
1749 
1750  /* XXX see note above */
1752 
1753  closest_encloser = ldns_dnssec_nsec3_closest_encloser(
1754  ldns_rr_owner(rr),
1755  ldns_rr_get_type(rr),
1756  nsecs);
1757  if(!closest_encloser) {
1758  result = LDNS_STATUS_NSEC3_ERR;
1759  goto done;
1760  }
1761  /* Now check if we have a Opt-Out NSEC3 that covers the "next closer"*/
1762 
1763  if (ldns_dname_label_count(closest_encloser) + 1
1765 
1766  /* Query name *is* the "next closer". */
1767  hashed_next_closer = hashed_name;
1768  } else {
1769  ldns_rdf *next_closer;
1770 
1771  ldns_rdf_deep_free(hashed_name);
1772  /* "next closer" has less labels than the query name.
1773  * Create the name and hash it.
1774  */
1775  next_closer = ldns_dname_clone_from(
1776  ldns_rr_owner(rr),
1778  - (ldns_dname_label_count(closest_encloser) + 1)
1779  );
1780  hashed_next_closer = ldns_nsec3_hash_name_frm_nsec3(
1781  ldns_rr_list_rr(nsecs, 0),
1782  next_closer
1783  );
1784  (void) ldns_dname_cat(hashed_next_closer, zone_name);
1785  ldns_rdf_deep_free(next_closer);
1786  }
1787  /* Find the NSEC3 that covers the "next closer" */
1788  for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1789  if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
1790  hashed_next_closer) &&
1791  ldns_nsec3_optout(ldns_rr_list_rr(nsecs, i))) {
1792 
1793  result = LDNS_STATUS_OK;
1794  if (match) {
1795  *match = ldns_rr_list_rr(nsecs, i);
1796  }
1797  break;
1798  }
1799  }
1800  ldns_rdf_deep_free(hashed_next_closer);
1801  ldns_rdf_deep_free(closest_encloser);
1802  }
1803 
1804  done:
1805  ldns_rdf_deep_free(zone_name);
1806  return result;
1807 }
1808 
1811  ldns_rr_list *nsecs,
1812  ldns_rr_list *rrsigs,
1813  ldns_pkt_rcode packet_rcode,
1814  ldns_rr_type packet_qtype,
1815  bool packet_nodata)
1816 {
1818  rr, nsecs, rrsigs, packet_rcode,
1819  packet_qtype, packet_nodata, NULL
1820  );
1821 }
1822 
1823 #ifdef USE_GOST
1824 EVP_PKEY*
1825 ldns_gost2pkey_raw(const unsigned char* key, size_t keylen)
1826 {
1827  /* prefix header for X509 encoding */
1828  uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
1829  0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
1830  0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
1831  0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
1832  unsigned char encoded[37+64];
1833  const unsigned char* pp;
1834  if(keylen != 64) {
1835  /* key wrong size */
1836  return NULL;
1837  }
1838 
1839  /* create evp_key */
1840  memmove(encoded, asn, 37);
1841  memmove(encoded+37, key, 64);
1842  pp = (unsigned char*)&encoded[0];
1843 
1844  return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
1845 }
1846 
1847 static ldns_status
1848 ldns_verify_rrsig_gost_raw(const unsigned char* sig, size_t siglen,
1849  const ldns_buffer* rrset, const unsigned char* key, size_t keylen)
1850 {
1851  EVP_PKEY *evp_key;
1852  ldns_status result;
1853 
1854  (void) ldns_key_EVP_load_gost_id();
1855  evp_key = ldns_gost2pkey_raw(key, keylen);
1856  if(!evp_key) {
1857  /* could not convert key */
1858  return LDNS_STATUS_CRYPTO_BOGUS;
1859  }
1860 
1861  /* verify signature */
1862  result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset,
1863  evp_key, EVP_get_digestbyname("md_gost94"));
1864  EVP_PKEY_free(evp_key);
1865 
1866  return result;
1867 }
1868 #endif
1869 
1870 #ifdef USE_ED25519
1871 EVP_PKEY*
1872 ldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
1873 {
1874  /* ASN1 for ED25519 is 302a300506032b6570032100 <32byteskey> */
1875  uint8_t pre[] = {0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
1876  0x70, 0x03, 0x21, 0x00};
1877  int pre_len = 12;
1878  uint8_t buf[256];
1879  EVP_PKEY *evp_key;
1880  /* pp gets modified by d2i() */
1881  const unsigned char* pp = (unsigned char*)buf;
1882  if(keylen != 32 || keylen + pre_len > sizeof(buf))
1883  return NULL; /* wrong length */
1884  memmove(buf, pre, pre_len);
1885  memmove(buf+pre_len, key, keylen);
1886  evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
1887  return evp_key;
1888 }
1889 
1890 static ldns_status
1891 ldns_verify_rrsig_ed25519_raw(unsigned char* sig, size_t siglen,
1892  ldns_buffer* rrset, unsigned char* key, size_t keylen)
1893 {
1894  EVP_PKEY *evp_key;
1895  ldns_status result;
1896 
1897  evp_key = ldns_ed255192pkey_raw(key, keylen);
1898  if(!evp_key) {
1899  /* could not convert key */
1900  return LDNS_STATUS_CRYPTO_BOGUS;
1901  }
1902  result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, NULL);
1903  EVP_PKEY_free(evp_key);
1904  return result;
1905 }
1906 #endif /* USE_ED25519 */
1907 
1908 #ifdef USE_ED448
1909 EVP_PKEY*
1910 ldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
1911 {
1912  /* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
1913  uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
1914  0x71, 0x03, 0x3a, 0x00};
1915  int pre_len = 12;
1916  uint8_t buf[256];
1917  EVP_PKEY *evp_key;
1918  /* pp gets modified by d2i() */
1919  const unsigned char* pp = (unsigned char*)buf;
1920  if(keylen != 57 || keylen + pre_len > sizeof(buf))
1921  return NULL; /* wrong length */
1922  memmove(buf, pre, pre_len);
1923  memmove(buf+pre_len, key, keylen);
1924  evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
1925  return evp_key;
1926 }
1927 
1928 static ldns_status
1929 ldns_verify_rrsig_ed448_raw(unsigned char* sig, size_t siglen,
1930  ldns_buffer* rrset, unsigned char* key, size_t keylen)
1931 {
1932  EVP_PKEY *evp_key;
1933  ldns_status result;
1934 
1935  evp_key = ldns_ed4482pkey_raw(key, keylen);
1936  if(!evp_key) {
1937  /* could not convert key */
1938  return LDNS_STATUS_CRYPTO_BOGUS;
1939  }
1940  result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, NULL);
1941  EVP_PKEY_free(evp_key);
1942  return result;
1943 }
1944 #endif /* USE_ED448 */
1945 
1946 #ifdef USE_ECDSA
1947 EVP_PKEY*
1948 ldns_ecdsa2pkey_raw(const unsigned char* key, size_t keylen, uint8_t algo)
1949 {
1950  unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
1951  const unsigned char* pp = buf;
1952  EVP_PKEY *evp_key;
1953  EC_KEY *ec;
1954  /* check length, which uncompressed must be 2 bignums */
1955  if(algo == LDNS_ECDSAP256SHA256) {
1956  if(keylen != 2*256/8) return NULL;
1957  ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
1958  } else if(algo == LDNS_ECDSAP384SHA384) {
1959  if(keylen != 2*384/8) return NULL;
1960  ec = EC_KEY_new_by_curve_name(NID_secp384r1);
1961  } else ec = NULL;
1962  if(!ec) return NULL;
1963  if(keylen+1 > sizeof(buf))
1964  return NULL; /* sanity check */
1965  /* prepend the 0x02 (from docs) (or actually 0x04 from implementation
1966  * of openssl) for uncompressed data */
1967  buf[0] = POINT_CONVERSION_UNCOMPRESSED;
1968  memmove(buf+1, key, keylen);
1969  if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
1970  EC_KEY_free(ec);
1971  return NULL;
1972  }
1973  evp_key = EVP_PKEY_new();
1974  if(!evp_key) {
1975  EC_KEY_free(ec);
1976  return NULL;
1977  }
1978  if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
1979  EVP_PKEY_free(evp_key);
1980  EC_KEY_free(ec);
1981  return NULL;
1982  }
1983  return evp_key;
1984 }
1985 
1986 static ldns_status
1987 ldns_verify_rrsig_ecdsa_raw(unsigned char* sig, size_t siglen,
1988  ldns_buffer* rrset, unsigned char* key, size_t keylen, uint8_t algo)
1989 {
1990  EVP_PKEY *evp_key;
1991  ldns_status result;
1992  const EVP_MD *d;
1993 
1994  evp_key = ldns_ecdsa2pkey_raw(key, keylen, algo);
1995  if(!evp_key) {
1996  /* could not convert key */
1997  return LDNS_STATUS_CRYPTO_BOGUS;
1998  }
1999  if(algo == LDNS_ECDSAP256SHA256)
2000  d = EVP_sha256();
2001  else d = EVP_sha384(); /* LDNS_ECDSAP384SHA384 */
2002  result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, d);
2003  EVP_PKEY_free(evp_key);
2004  return result;
2005 }
2006 #endif
2007 
2010  ldns_buffer *key_buf, uint8_t algo)
2011 {
2013  (unsigned char*)ldns_buffer_begin(rawsig_buf),
2014  ldns_buffer_position(rawsig_buf),
2015  verify_buf,
2016  (unsigned char*)ldns_buffer_begin(key_buf),
2017  ldns_buffer_position(key_buf), algo);
2018 }
2019 
2021 ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
2022  ldns_buffer *verify_buf, unsigned char* key, size_t keylen,
2023  uint8_t algo)
2024 {
2025  /* check for right key */
2026  switch(algo) {
2027 #ifdef USE_DSA
2028  case LDNS_DSA:
2029  case LDNS_DSA_NSEC3:
2030  return ldns_verify_rrsig_dsa_raw(sig,
2031  siglen,
2032  verify_buf,
2033  key,
2034  keylen);
2035  break;
2036 #endif
2037  case LDNS_RSASHA1:
2038  case LDNS_RSASHA1_NSEC3:
2039  return ldns_verify_rrsig_rsasha1_raw(sig,
2040  siglen,
2041  verify_buf,
2042  key,
2043  keylen);
2044  break;
2045 #ifdef USE_SHA2
2046  case LDNS_RSASHA256:
2048  siglen,
2049  verify_buf,
2050  key,
2051  keylen);
2052  break;
2053  case LDNS_RSASHA512:
2055  siglen,
2056  verify_buf,
2057  key,
2058  keylen);
2059  break;
2060 #endif
2061 #ifdef USE_GOST
2062  case LDNS_ECC_GOST:
2063  return ldns_verify_rrsig_gost_raw(sig, siglen, verify_buf,
2064  key, keylen);
2065  break;
2066 #endif
2067 #ifdef USE_ECDSA
2068  case LDNS_ECDSAP256SHA256:
2069  case LDNS_ECDSAP384SHA384:
2070  return ldns_verify_rrsig_ecdsa_raw(sig, siglen, verify_buf,
2071  key, keylen, algo);
2072  break;
2073 #endif
2074 #ifdef USE_ED25519
2075  case LDNS_ED25519:
2076  return ldns_verify_rrsig_ed25519_raw(sig, siglen, verify_buf,
2077  key, keylen);
2078  break;
2079 #endif
2080 #ifdef USE_ED448
2081  case LDNS_ED448:
2082  return ldns_verify_rrsig_ed448_raw(sig, siglen, verify_buf,
2083  key, keylen);
2084  break;
2085 #endif
2086  case LDNS_RSAMD5:
2087  return ldns_verify_rrsig_rsamd5_raw(sig,
2088  siglen,
2089  verify_buf,
2090  key,
2091  keylen);
2092  break;
2093  default:
2094  /* do you know this alg?! */
2096  }
2097 }
2098 
2099 
2107 static void
2108 ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, const ldns_rr* rrsig)
2109 {
2110  uint32_t orig_ttl;
2111  uint16_t i;
2112  uint8_t label_count;
2113  ldns_rdf *wildcard_name;
2114  ldns_rdf *wildcard_chopped;
2115  ldns_rdf *wildcard_chopped_tmp;
2116 
2117  if ((rrsig == NULL) || ldns_rr_rd_count(rrsig) < 4) {
2118  return;
2119  }
2120 
2121  orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
2122  label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
2123 
2124  for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
2125  if (label_count <
2127  ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
2128  (void) ldns_str2rdf_dname(&wildcard_name, "*");
2129  wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(
2130  ldns_rr_list_rr(rrset_clone, i)));
2131  while (label_count < ldns_dname_label_count(wildcard_chopped)) {
2132  wildcard_chopped_tmp = ldns_dname_left_chop(
2133  wildcard_chopped);
2134  ldns_rdf_deep_free(wildcard_chopped);
2135  wildcard_chopped = wildcard_chopped_tmp;
2136  }
2137  (void) ldns_dname_cat(wildcard_name, wildcard_chopped);
2138  ldns_rdf_deep_free(wildcard_chopped);
2140  rrset_clone, i)));
2141  ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i),
2142  wildcard_name);
2143  }
2144  ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl);
2145  /* convert to lowercase */
2146  ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
2147  }
2148 }
2149 
2156 static ldns_status
2157 ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, const ldns_rr* rrsig)
2158 {
2159  uint8_t sig_algo;
2160 
2161  if (rrsig == NULL) {
2163  }
2164  if (ldns_rr_rdf(rrsig, 1) == NULL) {
2166  }
2167  sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
2168  /* check for known and implemented algo's now (otherwise
2169  * the function could return a wrong error
2170  */
2171  /* create a buffer with signature rdata */
2172  /* for some algorithms we need other data than for others... */
2173  /* (the DSA API wants DER encoding for instance) */
2174 
2175  switch(sig_algo) {
2176  case LDNS_RSAMD5:
2177  case LDNS_RSASHA1:
2178  case LDNS_RSASHA1_NSEC3:
2179 #ifdef USE_SHA2
2180  case LDNS_RSASHA256:
2181  case LDNS_RSASHA512:
2182 #endif
2183 #ifdef USE_GOST
2184  case LDNS_ECC_GOST:
2185 #endif
2186 #ifdef USE_ED25519
2187  case LDNS_ED25519:
2188 #endif
2189 #ifdef USE_ED448
2190  case LDNS_ED448:
2191 #endif
2192  if (ldns_rr_rdf(rrsig, 8) == NULL) {
2194  }
2195  if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8))
2196  != LDNS_STATUS_OK) {
2197  return LDNS_STATUS_MEM_ERR;
2198  }
2199  break;
2200 #ifdef USE_DSA
2201  case LDNS_DSA:
2202  case LDNS_DSA_NSEC3:
2203  /* EVP takes rfc2459 format, which is a tad longer than dns format */
2204  if (ldns_rr_rdf(rrsig, 8) == NULL) {
2206  }
2208  rawsig_buf, ldns_rr_rdf(rrsig, 8))
2209  != LDNS_STATUS_OK) {
2210  /*
2211  if (ldns_rdf2buffer_wire(rawsig_buf,
2212  ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
2213  */
2214  return LDNS_STATUS_MEM_ERR;
2215  }
2216  break;
2217 #endif
2218 #ifdef USE_ECDSA
2219  case LDNS_ECDSAP256SHA256:
2220  case LDNS_ECDSAP384SHA384:
2221  /* EVP produces an ASN prefix on the signature, which is
2222  * not used in the DNS */
2223  if (ldns_rr_rdf(rrsig, 8) == NULL) {
2225  }
2227  rawsig_buf, ldns_rr_rdf(rrsig, 8))
2228  != LDNS_STATUS_OK) {
2229  return LDNS_STATUS_MEM_ERR;
2230  }
2231  break;
2232 #endif
2233  case LDNS_DH:
2234  case LDNS_ECC:
2235  case LDNS_INDIRECT:
2237  default:
2239  }
2240  return LDNS_STATUS_OK;
2241 }
2242 
2249 static ldns_status
2250 ldns_rrsig_check_timestamps(const ldns_rr* rrsig, time_t now)
2251 {
2252  int32_t inception, expiration;
2253 
2254  /* check the signature time stamps */
2255  inception = (int32_t)ldns_rdf2native_time_t(
2256  ldns_rr_rrsig_inception(rrsig));
2257  expiration = (int32_t)ldns_rdf2native_time_t(
2258  ldns_rr_rrsig_expiration(rrsig));
2259 
2260  if (expiration - inception < 0) {
2261  /* bad sig, expiration before inception?? Tsssg */
2263  }
2264  if (((int32_t) now) - inception < 0) {
2265  /* bad sig, inception date has not yet come to pass */
2267  }
2268  if (expiration - ((int32_t) now) < 0) {
2269  /* bad sig, expiration date has passed */
2271  }
2272  return LDNS_STATUS_OK;
2273 }
2274 
2283 static ldns_status
2284 ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
2285  ldns_rr_list* rrset_clone, const ldns_rr* rrsig)
2286 {
2287  ldns_status result;
2288 
2289  /* canonicalize the sig */
2291 
2292  /* check if the typecovered is equal to the type checked */
2294  ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0)))
2296 
2297  /* create a buffer with b64 signature rdata */
2298  result = ldns_rrsig2rawsig_buffer(rawsig_buf, rrsig);
2299  if(result != LDNS_STATUS_OK)
2300  return result;
2301 
2302  /* use TTL from signature. Use wildcard names for wildcards */
2303  /* also canonicalizes rrset_clone */
2304  ldns_rrset_use_signature_ttl(rrset_clone, rrsig);
2305 
2306  /* sort the rrset in canonical order */
2307  ldns_rr_list_sort(rrset_clone);
2308 
2309  /* put the signature rr (without the b64) to the verify_buf */
2310  if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK)
2311  return LDNS_STATUS_MEM_ERR;
2312 
2313  /* add the rrset in verify_buf */
2314  if(ldns_rr_list2buffer_wire(verify_buf, rrset_clone)
2315  != LDNS_STATUS_OK)
2316  return LDNS_STATUS_MEM_ERR;
2317 
2318  return LDNS_STATUS_OK;
2319 }
2320 
2330 static ldns_status
2331 ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
2332  const ldns_rr* rrsig, ldns_rr* key)
2333 {
2334  uint8_t sig_algo;
2335 
2336  if (rrsig == NULL) {
2338  }
2339  if (ldns_rr_rdf(rrsig, 1) == NULL) {
2341  }
2342  sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
2343 
2344  /* before anything, check if the keytags match */
2345  if (ldns_calc_keytag(key)
2346  ==
2348  ) {
2350  ldns_status result = LDNS_STATUS_ERR;
2351 
2352  /* put the key-data in a buffer, that's the third rdf, with
2353  * the base64 encoded key data */
2354  if (ldns_rr_rdf(key, 3) == NULL) {
2355  ldns_buffer_free(key_buf);
2357  }
2358  if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3))
2359  != LDNS_STATUS_OK) {
2360  ldns_buffer_free(key_buf);
2361  /* returning is bad might screw up
2362  good keys later in the list
2363  what to do? */
2364  return LDNS_STATUS_ERR;
2365  }
2366 
2367  if (ldns_rr_rdf(key, 2) == NULL) {
2369  }
2370  else if (sig_algo == ldns_rdf2native_int8(
2371  ldns_rr_rdf(key, 2))) {
2372  result = ldns_verify_rrsig_buffers(rawsig_buf,
2373  verify_buf, key_buf, sig_algo);
2374  } else {
2375  /* No keys with the corresponding algorithm are found */
2377  }
2378 
2379  ldns_buffer_free(key_buf);
2380  return result;
2381  }
2382  else {
2383  /* No keys with the corresponding keytag are found */
2385  }
2386 }
2387 
2388 /*
2389  * to verify:
2390  * - create the wire fmt of the b64 key rdata
2391  * - create the wire fmt of the sorted rrset
2392  * - create the wire fmt of the b64 sig rdata
2393  * - create the wire fmt of the sig without the b64 rdata
2394  * - cat the sig data (without b64 rdata) to the rrset
2395  * - verify the rrset+sig, with the b64 data and the b64 key data
2396  */
2399  const ldns_rr_list *rrset,
2400  const ldns_rr *rrsig,
2401  const ldns_rr_list *keys,
2402  time_t check_time,
2403  ldns_rr_list *good_keys)
2404 {
2405  ldns_status result;
2406  ldns_rr_list *valid;
2407 
2408  if (!good_keys)
2409  valid = NULL;
2410 
2411  else if (!(valid = ldns_rr_list_new()))
2412  return LDNS_STATUS_MEM_ERR;
2413 
2414  result = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, valid);
2415  if(result != LDNS_STATUS_OK) {
2416  ldns_rr_list_free(valid);
2417  return result;
2418  }
2419 
2420  /* check timestamps last; its OK except time */
2421  result = ldns_rrsig_check_timestamps(rrsig, check_time);
2422  if(result != LDNS_STATUS_OK) {
2423  ldns_rr_list_free(valid);
2424  return result;
2425  }
2426 
2427  ldns_rr_list_cat(good_keys, valid);
2428  ldns_rr_list_free(valid);
2429  return LDNS_STATUS_OK;
2430 }
2431 
2432 /*
2433  * to verify:
2434  * - create the wire fmt of the b64 key rdata
2435  * - create the wire fmt of the sorted rrset
2436  * - create the wire fmt of the b64 sig rdata
2437  * - create the wire fmt of the sig without the b64 rdata
2438  * - cat the sig data (without b64 rdata) to the rrset
2439  * - verify the rrset+sig, with the b64 data and the b64 key data
2440  */
2443  ldns_rr *rrsig,
2444  const ldns_rr_list *keys,
2445  ldns_rr_list *good_keys)
2446 {
2448  rrset, rrsig, keys, ldns_time(NULL), good_keys);
2449 }
2450 
2453  const ldns_rr *rrsig,
2454  const ldns_rr_list *keys,
2455  ldns_rr_list *good_keys)
2456 {
2457  ldns_buffer *rawsig_buf;
2458  ldns_buffer *verify_buf;
2459  uint16_t i;
2460  ldns_status result, status;
2461  ldns_rr_list *rrset_clone;
2462  ldns_rr_list *validkeys;
2463 
2464  if (!rrset) {
2465  return LDNS_STATUS_ERR;
2466  }
2467 
2468  validkeys = ldns_rr_list_new();
2469  if (!validkeys) {
2470  return LDNS_STATUS_MEM_ERR;
2471  }
2472 
2473  /* clone the rrset so that we can fiddle with it */
2474  rrset_clone = ldns_rr_list_clone(rrset);
2475 
2476  /* create the buffers which will certainly hold the raw data */
2477  rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2478  verify_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2479 
2480  result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
2481  rrset_clone, rrsig);
2482  if(result != LDNS_STATUS_OK) {
2483  ldns_buffer_free(verify_buf);
2484  ldns_buffer_free(rawsig_buf);
2485  ldns_rr_list_deep_free(rrset_clone);
2486  ldns_rr_list_free(validkeys);
2487  return result;
2488  }
2489 
2491  for(i = 0; i < ldns_rr_list_rr_count(keys); i++) {
2492  status = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
2493  rrsig, ldns_rr_list_rr(keys, i));
2494  if (status == LDNS_STATUS_OK) {
2495  /* one of the keys has matched, don't break
2496  * here, instead put the 'winning' key in
2497  * the validkey list and return the list
2498  * later */
2499  if (!ldns_rr_list_push_rr(validkeys,
2500  ldns_rr_list_rr(keys,i))) {
2501  /* couldn't push the key?? */
2502  ldns_buffer_free(rawsig_buf);
2503  ldns_buffer_free(verify_buf);
2504  ldns_rr_list_deep_free(rrset_clone);
2505  ldns_rr_list_free(validkeys);
2506  return LDNS_STATUS_MEM_ERR;
2507  }
2508 
2509  result = status;
2510  }
2511 
2513  result = status;
2514  }
2515  }
2516 
2517  /* no longer needed */
2518  ldns_rr_list_deep_free(rrset_clone);
2519  ldns_buffer_free(rawsig_buf);
2520  ldns_buffer_free(verify_buf);
2521 
2522  if (ldns_rr_list_rr_count(validkeys) == 0) {
2523  /* no keys were added, return last error */
2524  ldns_rr_list_free(validkeys);
2525  return result;
2526  }
2527 
2528  /* do not check timestamps */
2529 
2530  ldns_rr_list_cat(good_keys, validkeys);
2531  ldns_rr_list_free(validkeys);
2532  return LDNS_STATUS_OK;
2533 }
2534 
2537  ldns_rr_list *rrset,
2538  ldns_rr *rrsig,
2539  ldns_rr *key,
2540  time_t check_time)
2541 {
2542  ldns_buffer *rawsig_buf;
2543  ldns_buffer *verify_buf;
2544  ldns_status result;
2545  ldns_rr_list *rrset_clone;
2546 
2547  if (!rrset) {
2548  return LDNS_STATUS_NO_DATA;
2549  }
2550  /* clone the rrset so that we can fiddle with it */
2551  rrset_clone = ldns_rr_list_clone(rrset);
2552  /* create the buffers which will certainly hold the raw data */
2553  rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2554  verify_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2555 
2556  result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
2557  rrset_clone, rrsig);
2558  if(result != LDNS_STATUS_OK) {
2559  ldns_rr_list_deep_free(rrset_clone);
2560  ldns_buffer_free(rawsig_buf);
2561  ldns_buffer_free(verify_buf);
2562  return result;
2563  }
2564  result = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
2565  rrsig, key);
2566  /* no longer needed */
2567  ldns_rr_list_deep_free(rrset_clone);
2568  ldns_buffer_free(rawsig_buf);
2569  ldns_buffer_free(verify_buf);
2570 
2571  /* check timestamp last, apart from time its OK */
2572  if(result == LDNS_STATUS_OK)
2573  result = ldns_rrsig_check_timestamps(rrsig, check_time);
2574 
2575  return result;
2576 }
2577 
2580 {
2581  return ldns_verify_rrsig_time(rrset, rrsig, key, ldns_time(NULL));
2582 }
2583 
2584 
2587  ldns_buffer *rrset,
2588  EVP_PKEY *key,
2589  const EVP_MD *digest_type)
2590 {
2592  (unsigned char*)ldns_buffer_begin(sig),
2593  ldns_buffer_position(sig),
2594  rrset,
2595  key,
2596  digest_type);
2597 }
2598 
2600 ldns_verify_rrsig_evp_raw(const unsigned char *sig, size_t siglen,
2601  const ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
2602 {
2603  EVP_MD_CTX *ctx;
2604  int res;
2605 
2606 #ifdef HAVE_EVP_MD_CTX_NEW
2607  ctx = EVP_MD_CTX_new();
2608 #else
2609  ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx));
2610  if(ctx) EVP_MD_CTX_init(ctx);
2611 #endif
2612  if(!ctx)
2613  return LDNS_STATUS_MEM_ERR;
2614 
2615 #if defined(USE_ED25519) || defined(USE_ED448)
2616  if(!digest_type) {
2617  res = EVP_DigestVerifyInit(ctx, NULL, digest_type, NULL, key);
2618  if(res == 1) {
2619  res = EVP_DigestVerify(ctx, sig, siglen,
2620  ldns_buffer_begin(rrset),
2621  ldns_buffer_position(rrset));
2622  }
2623  } else {
2624 #else
2625  res = 0;
2626  if(digest_type) {
2627 #endif
2628  EVP_VerifyInit(ctx, digest_type);
2629  EVP_VerifyUpdate(ctx,
2630  ldns_buffer_begin(rrset),
2631  ldns_buffer_position(rrset));
2632  res = EVP_VerifyFinal(ctx, sig, (unsigned int) siglen, key);
2633  }
2634 
2635  EVP_MD_CTX_destroy(ctx);
2636 
2637  if (res == 1) {
2638  return LDNS_STATUS_OK;
2639 
2640  } else if (res == 0) {
2641  return LDNS_STATUS_CRYPTO_BOGUS;
2642  }
2643  /* TODO how to communicate internal SSL error?
2644  let caller use ssl's get_error() */
2645  return LDNS_STATUS_SSL_ERR;
2646 }
2647 
2650 {
2652  (unsigned char*) ldns_buffer_begin(sig),
2653  ldns_buffer_position(sig),
2654  rrset,
2655  (unsigned char*) ldns_buffer_begin(key),
2656  ldns_buffer_position(key));
2657 }
2658 
2661 {
2663  (unsigned char*)ldns_buffer_begin(sig),
2664  ldns_buffer_position(sig),
2665  rrset,
2666  (unsigned char*) ldns_buffer_begin(key),
2667  ldns_buffer_position(key));
2668 }
2669 
2672 {
2674  (unsigned char*)ldns_buffer_begin(sig),
2675  ldns_buffer_position(sig),
2676  rrset,
2677  (unsigned char*) ldns_buffer_begin(key),
2678  ldns_buffer_position(key));
2679 }
2680 
2682 ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
2683  ldns_buffer* rrset, unsigned char* key, size_t keylen)
2684 {
2685 #ifdef USE_DSA
2686  EVP_PKEY *evp_key;
2687  ldns_status result;
2688 
2689  evp_key = EVP_PKEY_new();
2690  if (EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen))) {
2691  result = ldns_verify_rrsig_evp_raw(sig,
2692  siglen,
2693  rrset,
2694  evp_key,
2695 # ifdef HAVE_EVP_DSS1
2696  EVP_dss1()
2697 # else
2698  EVP_sha1()
2699 # endif
2700  );
2701  } else {
2702  result = LDNS_STATUS_SSL_ERR;
2703  }
2704  EVP_PKEY_free(evp_key);
2705  return result;
2706 #else
2707  (void)sig; (void)siglen; (void)rrset; (void)key; (void)keylen;
2709 #endif
2710 }
2711 
2713 ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen,
2714  ldns_buffer* rrset, unsigned char* key, size_t keylen)
2715 {
2716  EVP_PKEY *evp_key;
2717  ldns_status result;
2718 
2719  evp_key = EVP_PKEY_new();
2720  if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2721  result = ldns_verify_rrsig_evp_raw(sig,
2722  siglen,
2723  rrset,
2724  evp_key,
2725  EVP_sha1());
2726  } else {
2727  result = LDNS_STATUS_SSL_ERR;
2728  }
2729  EVP_PKEY_free(evp_key);
2730 
2731  return result;
2732 }
2733 
2736  size_t siglen,
2737  ldns_buffer* rrset,
2738  unsigned char* key,
2739  size_t keylen)
2740 {
2741 #ifdef USE_SHA2
2742  EVP_PKEY *evp_key;
2743  ldns_status result;
2744 
2745  evp_key = EVP_PKEY_new();
2746  if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2747  result = ldns_verify_rrsig_evp_raw(sig,
2748  siglen,
2749  rrset,
2750  evp_key,
2751  EVP_sha256());
2752  } else {
2753  result = LDNS_STATUS_SSL_ERR;
2754  }
2755  EVP_PKEY_free(evp_key);
2756 
2757  return result;
2758 #else
2759  /* touch these to prevent compiler warnings */
2760  (void) sig;
2761  (void) siglen;
2762  (void) rrset;
2763  (void) key;
2764  (void) keylen;
2766 #endif
2767 }
2768 
2771  size_t siglen,
2772  ldns_buffer* rrset,
2773  unsigned char* key,
2774  size_t keylen)
2775 {
2776 #ifdef USE_SHA2
2777  EVP_PKEY *evp_key;
2778  ldns_status result;
2779 
2780  evp_key = EVP_PKEY_new();
2781  if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2782  result = ldns_verify_rrsig_evp_raw(sig,
2783  siglen,
2784  rrset,
2785  evp_key,
2786  EVP_sha512());
2787  } else {
2788  result = LDNS_STATUS_SSL_ERR;
2789  }
2790  EVP_PKEY_free(evp_key);
2791 
2792  return result;
2793 #else
2794  /* touch these to prevent compiler warnings */
2795  (void) sig;
2796  (void) siglen;
2797  (void) rrset;
2798  (void) key;
2799  (void) keylen;
2801 #endif
2802 }
2803 
2804 
2806 ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
2807  size_t siglen,
2808  ldns_buffer* rrset,
2809  unsigned char* key,
2810  size_t keylen)
2811 {
2812  EVP_PKEY *evp_key;
2813  ldns_status result;
2814 
2815  evp_key = EVP_PKEY_new();
2816  if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2817  result = ldns_verify_rrsig_evp_raw(sig,
2818  siglen,
2819  rrset,
2820  evp_key,
2821  EVP_md5());
2822  } else {
2823  result = LDNS_STATUS_SSL_ERR;
2824  }
2825  EVP_PKEY_free(evp_key);
2826 
2827  return result;
2828 }
2829 
2830 #endif
void ldns_buffer_free(ldns_buffer *buffer)
frees the buffer.
Definition: buffer.c:137
ldns_buffer * ldns_buffer_new(size_t capacity)
creates a new buffer with the specified capacity.
Definition: buffer.c:16
#define ATTR_UNUSED(x)
Definition: common.h:72
ldns_rdf * ldns_dname_clone_from(const ldns_rdf *d, uint16_t n)
Clones the given dname from the nth label on.
Definition: dname.c:160
bool ldns_dname_is_subdomain(const ldns_rdf *sub, const ldns_rdf *parent)
test whether the name sub falls under parent (i.e.
Definition: dname.c:296
int ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2)
Compares the two dname rdf's according to the algorithm for ordering in RFC4034 Section 6.
Definition: dname.c:359
void ldns_dname2canonical(const ldns_rdf *rd)
Put a dname into canonical fmt - ie.
Definition: dname.c:280
ldns_rdf * ldns_dname_left_chop(const ldns_rdf *d)
chop one label off the left side of a dname.
Definition: dname.c:189
uint8_t ldns_dname_label_count(const ldns_rdf *r)
count the number of labels inside a LDNS_RDF_DNAME type rdf.
Definition: dname.c:214
ldns_status ldns_dname_cat(ldns_rdf *rd1, const ldns_rdf *rd2)
concatenates rd2 after rd1 (rd2 is copied, rd1 is modified)
Definition: dname.c:90
ldns_rdf * ldns_dname_new_frm_str(const char *str)
creates a new dname rdf from a string.
Definition: dname.c:268
ldns_rdf * ldns_nsec_get_bitmap(const ldns_rr *nsec)
Returns the rdata field that contains the bitmap of the covered types of the given NSEC record.
Definition: dnssec.c:89
bool ldns_dnssec_pkt_has_rrsigs(const ldns_pkt *pkt)
Checks whether the packet contains rrsigs.
Definition: dnssec.c:204
ldns_status ldns_convert_ecdsa_rrsig_rdf2asn1(ldns_buffer *target_buffer, const ldns_rdf *sig_rdf)
Converts the RRSIG signature RDF (from DNS) to a buffer with the signature in ASN1 format as openssl ...
Definition: dnssec.c:1907
ldns_rr * ldns_dnssec_get_rrsig_for_name_and_type(const ldns_rdf *name, const ldns_rr_type type, const ldns_rr_list *rrs)
Returns the first RRSIG rr that corresponds to the rrset with the given name and type.
Definition: dnssec.c:34
RSA * ldns_key_buf2rsa_raw(const unsigned char *key, size_t len)
Like ldns_key_buf2rsa, but uses raw buffer.
Definition: dnssec.c:421
uint16_t ldns_calc_keytag(const ldns_rr *key)
calculates a keytag of a key for use in DNSSEC.
Definition: dnssec.c:277
bool ldns_nsec_bitmap_covers_type(const ldns_rdf *bitmap, ldns_rr_type type)
Check if RR type t is enumerated and set in the RR type bitmap rdf.
Definition: dnssec.c:1393
bool ldns_nsec3_optout(const ldns_rr *nsec3_rr)
Returns true if the opt-out flag has been set in the given NSEC3 RR.
Definition: dnssec.c:1286
ldns_status ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer, const ldns_rdf *sig_rdf)
Converts the RRSIG signature RDF (in rfc2536 format) to a buffer with the signature in rfc2459 format...
Definition: dnssec.c:1807
ldns_rr_list * ldns_dnssec_pkt_get_rrsigs_for_name_and_type(const ldns_pkt *pkt, const ldns_rdf *name, ldns_rr_type type)
Returns a ldns_rr_list containing the signatures covering the given name and type.
Definition: dnssec.c:223
ldns_rdf * ldns_nsec3_bitmap(const ldns_rr *nsec3_rr)
Returns the bitmap specifying the covered types of the given NSEC3 RR.
Definition: dnssec.c:1358
DSA * ldns_key_buf2dsa_raw(const unsigned char *key, size_t len)
Like ldns_key_buf2dsa, but uses raw buffer.
Definition: dnssec.c:344
ldns_rdf * ldns_nsec3_hash_name_frm_nsec3(const ldns_rr *nsec, const ldns_rdf *name)
Calculates the hashed name using the parameters of the given NSEC3 RR.
Definition: dnssec.c:1368
ldns_rdf * ldns_dnssec_nsec3_closest_encloser(const ldns_rdf *qname, ldns_rr_type qtype __attribute__((unused)), const ldns_rr_list *nsec3s)
Definition: dnssec.c:102
ldns_rr_list * ldns_dnssec_pkt_get_rrsigs_for_type(const ldns_pkt *pkt, ldns_rr_type type)
Returns a ldns_rr_list containing the signatures covering the given type.
Definition: dnssec.c:250
bool ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name)
Checks coverage of NSEC(3) RR name span Remember that nsec and name must both be in canonical form (i...
Definition: dnssec.c:1508
EVP_PKEY * ldns_gost2pkey_raw(const unsigned char *key, size_t keylen)
Converts a holding buffer with key material to EVP PKEY in openssl.
ldns_status ldns_verify_rrsig_buffers_raw(unsigned char *sig, size_t siglen, ldns_buffer *verify_buf, unsigned char *key, size_t keylen, uint8_t algo)
Like ldns_verify_rrsig_buffers, but uses raw data.
void ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain)
Prints the dnssec_data_chain to the given file stream.
Definition: dnssec_verify.c:91
EVP_PKEY * ldns_ed255192pkey_raw(const unsigned char *key, size_t keylen)
Converts a holding buffer with key material to EVP PKEY in openssl.
ldns_dnssec_trust_tree * ldns_dnssec_trust_tree_new(void)
Creates a new (empty) dnssec_trust_tree structure.
ldns_rr_list * ldns_fetch_valid_domain_keys_time(const ldns_resolver *res, const ldns_rdf *domain, const ldns_rr_list *keys, time_t check_time, ldns_status *status)
Tries to build an authentication chain from the given keys down to the queried domain.
void ldns_dnssec_derive_trust_tree_dnskey_rrset_time(ldns_dnssec_trust_tree *new_tree, ldns_dnssec_data_chain *data_chain, ldns_rr *cur_rr, ldns_rr *cur_sig_rr, time_t check_time)
Sub function for derive_trust_tree that is used for DNSKEY rrsets.
ldns_status ldns_verify_rrsig_keylist_time(const ldns_rr_list *rrset, const ldns_rr *rrsig, const ldns_rr_list *keys, time_t check_time, ldns_rr_list *good_keys)
Verifies an rrsig.
ldns_status ldns_verify_notime(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys, ldns_rr_list *good_keys)
Verifies a list of signatures for one rrset, but disregard the time.
ldns_status ldns_verify_rrsig_keylist(ldns_rr_list *rrset, ldns_rr *rrsig, const ldns_rr_list *keys, ldns_rr_list *good_keys)
Verifies an rrsig.
ldns_rr_list * ldns_validate_domain_dnskey(const ldns_resolver *res, const ldns_rdf *domain, const ldns_rr_list *keys)
Validates the DNSKEY RRset for the given domain using the provided trusted keys.
ldns_status ldns_verify_rrsig_rsasha256_raw(unsigned char *sig, size_t siglen, ldns_buffer *rrset, unsigned char *key, size_t keylen)
Like ldns_verify_rrsig_rsasha256, but uses raw signature and key data.
ldns_dnssec_data_chain * ldns_dnssec_data_chain_new(void)
Creates a new dnssec_chain structure.
Definition: dnssec_verify.c:19
ldns_dnssec_trust_tree * ldns_dnssec_derive_trust_tree_time(ldns_dnssec_data_chain *data_chain, ldns_rr *rr, time_t check_time)
Generates a dnssec_trust_tree for the given rr from the given data_chain.
ldns_status ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
verifies a buffer with signature data (RSASHA1) for a buffer with rrset data with a buffer with key d...
void ldns_dnssec_derive_trust_tree_dnskey_rrset(ldns_dnssec_trust_tree *new_tree, ldns_dnssec_data_chain *data_chain, ldns_rr *cur_rr, ldns_rr *cur_sig_rr)
Sub function for derive_trust_tree that is used for DNSKEY rrsets.
ldns_status ldns_verify_rrsig_keylist_notime(const ldns_rr_list *rrset, const ldns_rr *rrsig, const ldns_rr_list *keys, ldns_rr_list *good_keys)
Verifies an rrsig.
ldns_status ldns_dnssec_verify_denial(ldns_rr *rr, ldns_rr_list *nsecs, ldns_rr_list *rrsigs)
denial is not just a river in egypt
ldns_status ldns_dnssec_verify_denial_nsec3_match(ldns_rr *rr, ldns_rr_list *nsecs, ldns_rr_list *rrsigs __attribute__((unused)), ldns_pkt_rcode packet_rcode, ldns_rr_type packet_qtype, bool packet_nodata, ldns_rr **match)
ldns_status ldns_verify_rrsig_dsa_raw(unsigned char *sig, size_t siglen, ldns_buffer *rrset, unsigned char *key, size_t keylen)
Like ldns_verify_rrsig_dsa, but uses raw signature and key data.
ldns_status ldns_verify_trusted(ldns_resolver *res, ldns_rr_list *rrset, ldns_rr_list *rrsigs, ldns_rr_list *validating_keys)
Verifies a list of signatures for one RRset using a valid trust path.
ldns_status ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
verifies a buffer with signature data (RSAMD5) for a buffer with rrset data with a buffer with key da...
ldns_status ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf, ldns_buffer *key_buf, uint8_t algo)
Verifies the already processed data in the buffers This function should probably not be used directly...
ldns_status ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
verify an rrsig with 1 key
void ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree *new_tree, ldns_dnssec_data_chain *data_chain)
Sub function for derive_trust_tree that is used when there are no signatures.
void ldns_dnssec_derive_trust_tree_no_sig_time(ldns_dnssec_trust_tree *new_tree, ldns_dnssec_data_chain *data_chain, time_t check_time)
Sub function for derive_trust_tree that is used when there are no signatures.
EVP_PKEY * ldns_ed4482pkey_raw(const unsigned char *key, size_t keylen)
Converts a holding buffer with key material to EVP PKEY in openssl.
void ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain)
Frees a dnssec_data_chain structure, and all data contained therein.
Definition: dnssec_verify.c:45
ldns_dnssec_trust_tree * ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr)
Generates a dnssec_trust_tree for the given rr from the given data_chain.
ldns_status ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree, ldns_rr_list *trusted_keys)
Returns OK if there is a trusted path in the tree to one of the DNSKEY or DS RRs in the given list.
ldns_status ldns_verify_rrsig_rsasha1_raw(unsigned char *sig, size_t siglen, ldns_buffer *rrset, unsigned char *key, size_t keylen)
Like ldns_verify_rrsig_rsasha1, but uses raw signature and key data.
ldns_status ldns_verify_rrsig_rsasha512_raw(unsigned char *sig, size_t siglen, ldns_buffer *rrset, unsigned char *key, size_t keylen)
Like ldns_verify_rrsig_rsasha512, but uses raw signature and key data.
ldns_status ldns_verify_trusted_time(ldns_resolver *res, ldns_rr_list *rrset, ldns_rr_list *rrsigs, time_t check_time, ldns_rr_list *validating_keys)
Verifies a list of signatures for one RRset using a valid trust path.
ldns_dnssec_data_chain * ldns_dnssec_build_data_chain(ldns_resolver *res, uint16_t qflags, const ldns_rr_list *rrset, const ldns_pkt *pkt, ldns_rr *orig_rr)
Build an ldns_dnssec_data_chain, which contains all DNSSEC data that is needed to derive the trust tr...
void ldns_dnssec_trust_tree_print_fmt(FILE *out, const ldns_output_format *fmt, ldns_dnssec_trust_tree *tree, size_t tabs, bool extended)
Prints the dnssec_trust_tree structure to the given file stream.
ldns_status ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
verifies a buffer with signature data (DSA) for a buffer with rrset data with a buffer with key data.
ldns_status ldns_dnssec_verify_denial_nsec3(ldns_rr *rr, ldns_rr_list *nsecs, ldns_rr_list *rrsigs, ldns_pkt_rcode packet_rcode, ldns_rr_type packet_qtype, bool packet_nodata)
Denial of existence using NSEC3 records Since NSEC3 is a bit more complicated than normal denial,...
void ldns_dnssec_trust_tree_print(FILE *out, ldns_dnssec_trust_tree *tree, size_t tabs, bool extended)
Prints the dnssec_trust_tree structure to the given file stream.
ldns_status ldns_verify_rrsig_rsamd5_raw(unsigned char *sig, size_t siglen, ldns_buffer *rrset, unsigned char *key, size_t keylen)
Like ldns_verify_rrsig_rsamd5, but uses raw signature and key data.
ldns_rr_list * ldns_fetch_valid_domain_keys(const ldns_resolver *res, const ldns_rdf *domain, const ldns_rr_list *keys, ldns_status *status)
Tries to build an authentication chain from the given keys down to the queried domain.
void ldns_dnssec_data_chain_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_dnssec_data_chain *chain)
Prints the dnssec_data_chain to the given file stream.
Definition: dnssec_verify.c:56
ldns_status ldns_verify_rrsig_evp_raw(const unsigned char *sig, size_t siglen, const ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
Like ldns_verify_rrsig_evp, but uses raw signature data.
ldns_rr_list * ldns_validate_domain_dnskey_time(const ldns_resolver *res, const ldns_rdf *domain, const ldns_rr_list *keys, time_t check_time)
Validates the DNSKEY RRset for the given domain using the provided trusted keys.
void ldns_dnssec_data_chain_free(ldns_dnssec_data_chain *chain)
Frees a dnssec_data_chain structure.
Definition: dnssec_verify.c:39
ldns_status ldns_verify_rrsig_time(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key, time_t check_time)
verify an rrsig with 1 key
ldns_rr_list * ldns_validate_domain_ds_time(const ldns_resolver *res, const ldns_rdf *domain, const ldns_rr_list *keys, time_t check_time)
Validates the DS RRset for the given domain using the provided trusted keys.
ldns_rr_list * ldns_validate_domain_ds(const ldns_resolver *res, const ldns_rdf *domain, const ldns_rr_list *keys)
Validates the DS RRset for the given domain using the provided trusted keys.
ldns_status ldns_verify_time(const ldns_rr_list *rrset, const ldns_rr_list *rrsig, const ldns_rr_list *keys, time_t check_time, ldns_rr_list *good_keys)
Verifies a list of signatures for one rrset.
void ldns_dnssec_derive_trust_tree_ds_rrset(ldns_dnssec_trust_tree *new_tree, ldns_dnssec_data_chain *data_chain, ldns_rr *cur_rr)
Sub function for derive_trust_tree that is used for DS rrsets.
ldns_status ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys, ldns_rr_list *good_keys)
Verifies a list of signatures for one rrset.
void ldns_dnssec_derive_trust_tree_normal_rrset(ldns_dnssec_trust_tree *new_tree, ldns_dnssec_data_chain *data_chain, ldns_rr *cur_sig_rr)
Sub function for derive_trust_tree that is used for a 'normal' rrset.
EVP_PKEY * ldns_ecdsa2pkey_raw(const unsigned char *key, size_t keylen, uint8_t algo)
Converts a holding buffer with key material to EVP PKEY in openssl.
ldns_status ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree, const ldns_dnssec_trust_tree *parent, const ldns_rr *signature, const ldns_status parent_status)
Adds a trust tree as a parent for the given trust tree.
size_t ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree)
returns the depth of the trust tree
void ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree)
Frees the dnssec_trust_tree recursively.
ldns_status ldns_verify_rrsig_evp(ldns_buffer *sig, ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
verifies a buffer with signature data for a buffer with rrset data with an EVP_PKEY
void ldns_dnssec_derive_trust_tree_normal_rrset_time(ldns_dnssec_trust_tree *new_tree, ldns_dnssec_data_chain *data_chain, ldns_rr *cur_sig_rr, time_t check_time)
Sub function for derive_trust_tree that is used for a 'normal' rrset.
void ldns_dnssec_derive_trust_tree_ds_rrset_time(ldns_dnssec_trust_tree *new_tree, ldns_dnssec_data_chain *data_chain, ldns_rr *cur_rr, time_t check_time)
Sub function for derive_trust_tree that is used for DS rrsets.
#define LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS
dnssec_verify
Definition: dnssec_verify.h:6
const char * ldns_get_errorstr_by_id(ldns_status err)
look up a descriptive text by each error.
Definition: error.c:191
@ LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY
Definition: error.h:56
@ LDNS_STATUS_NO_DATA
Definition: error.h:77
@ LDNS_STATUS_CRYPTO_NO_RRSIG
Definition: error.h:54
@ LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR
Definition: error.h:67
@ LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL
Definition: error.h:53
@ LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED
Definition: error.h:100
@ LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION
Definition: error.h:66
@ LDNS_STATUS_CRYPTO_NO_DNSKEY
Definition: error.h:55
@ LDNS_STATUS_SSL_ERR
Definition: error.h:36
@ LDNS_STATUS_CRYPTO_NO_TRUSTED_DS
Definition: error.h:58
@ LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED
Definition: error.h:99
@ LDNS_STATUS_CRYPTO_BOGUS
Definition: error.h:61
@ LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY
Definition: error.h:59
@ LDNS_STATUS_NSEC3_ERR
Definition: error.h:69
@ LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED
Definition: error.h:63
@ LDNS_STATUS_ERR
Definition: error.h:37
@ LDNS_STATUS_MEM_ERR
Definition: error.h:34
@ LDNS_STATUS_DNSSEC_EXISTENCE_DENIED
Definition: error.h:98
@ LDNS_STATUS_CRYPTO_SIG_EXPIRED
Definition: error.h:62
@ LDNS_STATUS_CRYPTO_UNKNOWN_ALGO
Definition: error.h:52
@ LDNS_STATUS_OK
Definition: error.h:26
@ LDNS_STATUS_MISSING_RDATA_FIELDS_KEY
Definition: error.h:103
@ LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG
Definition: error.h:102
enum ldns_enum_status ldns_status
Definition: error.h:146
void ldns_rr_list_print_fmt(FILE *output, const ldns_output_format *fmt, const ldns_rr_list *lst)
print a rr_list to output
Definition: host2str.c:3436
ldns_lookup_table ldns_rcodes[]
Response codes.
Definition: host2str.c:109
void ldns_rdf_print(FILE *output, const ldns_rdf *rdf)
Prints the data in the rdata field to the given file stream (in presentation format)
Definition: host2str.c:3386
const ldns_output_format * ldns_output_format_default
The default output format record.
Definition: host2str.c:142
void ldns_rr_print_fmt(FILE *output, const ldns_output_format *fmt, const ldns_rr *rr)
Prints the data in the resource record to the given file stream (in presentation format)
Definition: host2str.c:3398
ldns_status ldns_rdf2buffer_wire(ldns_buffer *buffer, const ldns_rdf *rdf)
Copies the rdata data to the buffer in wire format.
Definition: host2wire.c:109
ldns_status ldns_rr_list2buffer_wire(ldns_buffer *buffer, const ldns_rr_list *rr_list)
Copies the rr_list data to the buffer in wire format.
Definition: host2wire.c:156
ldns_status ldns_rrsig2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
Converts a rrsig to wireformat BUT EXCLUDE the rrsig rdata This is needed in DNSSEC verification.
Definition: host2wire.c:294
int ldns_key_EVP_load_gost_id(void)
Get the PKEY id for GOST, loads GOST into openssl as a side effect.
@ LDNS_ED448
Definition: keys.h:59
@ LDNS_RSAMD5
Definition: keys.h:46
@ LDNS_ECDSAP384SHA384
Definition: keys.h:57
@ LDNS_RSASHA1_NSEC3
Definition: keys.h:52
@ LDNS_DSA_NSEC3
Definition: keys.h:51
@ LDNS_DSA
Definition: keys.h:48
@ LDNS_ECDSAP256SHA256
Definition: keys.h:56
@ LDNS_ECC_GOST
Definition: keys.h:55
@ LDNS_DH
Definition: keys.h:47
@ LDNS_INDIRECT
Definition: keys.h:60
@ LDNS_ECC
Definition: keys.h:49
@ LDNS_RSASHA1
Definition: keys.h:50
@ LDNS_RSASHA512
Definition: keys.h:54
@ LDNS_RSASHA256
Definition: keys.h:53
@ LDNS_ED25519
Definition: keys.h:58
Including this file will include all ldns files, and define some lookup tables.
void ldns_pkt_free(ldns_pkt *packet)
frees the packet structure and all data that it contains.
Definition: packet.c:895
uint16_t ldns_pkt_ancount(const ldns_pkt *packet)
Return the packet's an count.
Definition: packet.c:106
ldns_rr_list * ldns_pkt_rr_list_by_name_and_type(const ldns_pkt *packet, const ldns_rdf *ownername, ldns_rr_type type, ldns_pkt_section sec)
return all the rr with a specific type and type from a packet.
Definition: packet.c:340
ldns_pkt_rcode ldns_pkt_get_rcode(const ldns_pkt *packet)
Return the packet's response code.
Definition: packet.c:94
ldns_rr_list * ldns_pkt_rr_list_by_type(const ldns_pkt *packet, ldns_rr_type type, ldns_pkt_section sec)
return all the rr with a specific type from a packet.
Definition: packet.c:304
#define LDNS_MAX_PACKETLEN
Definition: packet.h:24
enum ldns_enum_pkt_rcode ldns_pkt_rcode
Definition: packet.h:69
@ LDNS_SECTION_ANSWER
Definition: packet.h:279
@ LDNS_SECTION_ANY_NOQUESTION
used to get all non-question rrs from a packet
Definition: packet.h:285
#define LDNS_RD
Definition: packet.h:30
@ LDNS_RCODE_NXDOMAIN
Definition: packet.h:60
void ldns_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
Definition: rdata.c:230
uint32_t ldns_rdf2native_int32(const ldns_rdf *rd)
returns the native uint32_t representation from the rdf.
Definition: rdata.c:98
uint16_t ldns_rdf2native_int16(const ldns_rdf *rd)
returns the native uint16_t representation from the rdf.
Definition: rdata.c:84
uint8_t ldns_rdf2native_int8(const ldns_rdf *rd)
returns the native uint8_t representation from the rdf.
Definition: rdata.c:70
size_t ldns_rdf_size(const ldns_rdf *rd)
returns the size of the rdf.
Definition: rdata.c:24
time_t ldns_rdf2native_time_t(const ldns_rdf *rd)
returns the native time_t representation from the rdf.
Definition: rdata.c:112
uint8_t * ldns_rdf_data(const ldns_rdf *rd)
returns the data of the rdf.
Definition: rdata.c:38
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
Definition: rdata.c:222
ldns_pkt * ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags)
Send a query to a nameserver.
Definition: resolver.c:1164
ldns_rr_list * ldns_resolver_dnssec_anchors(const ldns_resolver *r)
Get the resolver's DNSSEC anchors.
Definition: resolver.c:132
void ldns_rr_list_free(ldns_rr_list *rr_list)
frees an rr_list structure.
Definition: rr.c:1011
ldns_rr * ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr)
returns a specific rr of an rrlist.
Definition: rr.c:990
ldns_rdf * ldns_rr_owner(const ldns_rr *rr)
returns the owner name of an rr structure.
Definition: rr.c:919
ldns_rr_type ldns_rdf2rr_type(const ldns_rdf *rd)
convert an rdf of type LDNS_RDF_TYPE_TYPE to an actual LDNS_RR_TYPE.
Definition: rr.c:2750
void ldns_rr_list_deep_free(ldns_rr_list *rr_list)
frees an rr_list structure and all rrs contained therein.
Definition: rr.c:1020
const ldns_rr_descriptor * ldns_rr_descript(uint16_t type)
returns the resource record descriptor for the given rr type.
Definition: rr.c:2632
void ldns_rr_set_owner(ldns_rr *rr, ldns_rdf *owner)
sets the owner in the rr structure.
Definition: rr.c:804
ldns_rr_list * ldns_rr_list_pop_rrset(ldns_rr_list *rr_list)
pops the first rrset from the list, the list must be sorted, so that all rr's from each rrset are nex...
Definition: rr.c:1348
void ldns_rr_list_sort(ldns_rr_list *unsorted)
sorts an rr_list (canonical wire format).
Definition: rr.c:1516
void ldns_rr2canonical(ldns_rr *rr)
converts each dname in a rr to its canonical form.
Definition: rr.c:1781
size_t ldns_rr_rd_count(const ldns_rr *rr)
returns the rd_count of an rr structure.
Definition: rr.c:937
size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
returns the number of rr's in an rr_list.
Definition: rr.c:957
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition: rr.c:943
void ldns_rr_set_ttl(ldns_rr *rr, uint32_t ttl)
sets the ttl in the rr structure.
Definition: rr.c:816
bool ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr)
pushes an rr to an rrlist.
Definition: rr.c:1132
ldns_rr_class ldns_rr_get_class(const ldns_rr *rr)
returns the class of the rr.
Definition: rr.c:949
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
Definition: rr.c:1000
bool ldns_rr_list_cat(ldns_rr_list *left, const ldns_rr_list *right)
concatenates two ldns_rr_lists together.
Definition: rr.c:1036
bool ldns_rr_compare_ds(const ldns_rr *orr1, const ldns_rr *orr2)
returns true of the given rr's are equal.
Definition: rr.c:1710
ldns_rr * ldns_rr_clone(const ldns_rr *rr)
clones a rr and all its data
Definition: rr.c:1400
ldns_rr_list * ldns_rr_list_clone(const ldns_rr_list *rrlist)
clones an rrlist.
Definition: rr.c:1431
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
Definition: rr.c:909
enum ldns_enum_rr_type ldns_rr_type
Definition: rr.h:243
@ LDNS_RR_TYPE_RRSIG
DNSSEC.
Definition: rr.h:170
@ LDNS_RR_TYPE_DNSKEY
Definition: rr.h:172
@ LDNS_RR_TYPE_NSEC
Definition: rr.h:171
@ LDNS_RR_TYPE_DS
RFC4034, RFC3658.
Definition: rr.h:164
@ LDNS_RR_TYPE_CNAME
the canonical name for an alias
Definition: rr.h:88
@ LDNS_RR_TYPE_NSEC3
Definition: rr.h:176
@ LDNS_RR_TYPE_NS
an authoritative name server
Definition: rr.h:82
enum ldns_enum_rr_class ldns_rr_class
Definition: rr.h:61
@ LDNS_RR_CLASS_IN
the Internet
Definition: rr.h:47
ldns_rdf * ldns_rr_rrsig_inception(const ldns_rr *r)
returns the inception time of a LDNS_RR_TYPE_RRSIG RR
Definition: rr_functions.c:171
ldns_rdf * ldns_rr_rrsig_expiration(const ldns_rr *r)
returns the expiration time of a LDNS_RR_TYPE_RRSIG RR
Definition: rr_functions.c:159
ldns_rdf * ldns_rr_rrsig_keytag(const ldns_rr *r)
returns the keytag of a LDNS_RR_TYPE_RRSIG RR
Definition: rr_functions.c:183
ldns_rdf * ldns_rr_rrsig_labels(const ldns_rr *r)
returns the number of labels of a LDNS_RR_TYPE_RRSIG RR
Definition: rr_functions.c:135
ldns_rdf * ldns_rr_rrsig_typecovered(const ldns_rr *r)
returns the type covered of a LDNS_RR_TYPE_RRSIG rr
Definition: rr_functions.c:111
ldns_rdf * ldns_rr_rrsig_signame(const ldns_rr *r)
returns the signers name of a LDNS_RR_TYPE_RRSIG RR
Definition: rr_functions.c:195
ldns_status ldns_str2rdf_dname(ldns_rdf **d, const char *str)
convert a dname string into wireformat
Definition: str2host.c:311
ldns_dnssec_data_chain * parent
Definition: dnssec_verify.h:25
ldns_dnssec_trust_tree * parents[10]
ldns_rr * parent_signature[10]
for debugging, add signatures too (you might want those if they contain errors)
implementation of buffers to ease operations
Definition: buffer.h:51
A general purpose lookup table.
Definition: util.h:156
const char * name
Definition: util.h:158
Output format specifier.
Definition: host2str.h:89
DNS packet.
Definition: packet.h:235
Resource record data field.
Definition: rdata.h:197
DNS stub resolver structure.
Definition: resolver.h:60
Contains all information about resource record types.
Definition: rr.h:351
const char * _name
Textual name of the RR type.
Definition: rr.h:355
List or Set of Resource Records.
Definition: rr.h:338
Resource Record.
Definition: rr.h:310
ldns_lookup_table * ldns_lookup_by_id(ldns_lookup_table *table, int id)
Definition: util.c:41
#define LDNS_FREE(ptr)
Definition: util.h:60
#define LDNS_CALLOC(type, count)
Definition: util.h:53
#define LDNS_XMALLOC(type, count)
Definition: util.h:51