ldns  1.9.2
dnssec_zone.c
Go to the documentation of this file.
1 /*
2  * special zone file structures and functions for better dnssec handling
3  */
4 
5 #include <ldns/config.h>
6 
7 #include <ldns/ldns.h>
8 
11 {
12  ldns_dnssec_rrs *new_rrs;
13  new_rrs = LDNS_MALLOC(ldns_dnssec_rrs);
14  if(!new_rrs) return NULL;
15  new_rrs->rr = NULL;
16  new_rrs->next = NULL;
17  return new_rrs;
18 }
19 
20 INLINE void
21 ldns_dnssec_rrs_free_internal(ldns_dnssec_rrs *rrs, int deep)
22 {
23  ldns_dnssec_rrs *next;
24  while (rrs) {
25  next = rrs->next;
26  if (deep) {
27  ldns_rr_free(rrs->rr);
28  }
29  LDNS_FREE(rrs);
30  rrs = next;
31  }
32 }
33 
34 void
36 {
37  ldns_dnssec_rrs_free_internal(rrs, 0);
38 }
39 
40 void
42 {
43  ldns_dnssec_rrs_free_internal(rrs, 1);
44 }
45 
48 {
49  int cmp;
50  ldns_dnssec_rrs *new_rrs;
51  if (!rrs || !rr) {
52  return LDNS_STATUS_ERR;
53  }
54 
55  /* this could be done more efficiently; name and type should already
56  be equal */
57  cmp = ldns_rr_compare(rrs->rr, rr);
58  if (cmp < 0) {
59  if (rrs->next) {
60  return ldns_dnssec_rrs_add_rr(rrs->next, rr);
61  } else {
62  new_rrs = ldns_dnssec_rrs_new();
63  new_rrs->rr = rr;
64  rrs->next = new_rrs;
65  }
66  } else if (cmp > 0) {
67  /* put the current old rr in the new next, put the new
68  rr in the current container */
69  new_rrs = ldns_dnssec_rrs_new();
70  new_rrs->rr = rrs->rr;
71  new_rrs->next = rrs->next;
72  rrs->rr = rr;
73  rrs->next = new_rrs;
74  } else
75  return LDNS_STATUS_EQUAL_RR;
76 
77  return LDNS_STATUS_OK;
78 }
79 
80 void
82  const ldns_dnssec_rrs *rrs)
83 {
84  if (!rrs) {
85  if ((fmt->flags & LDNS_COMMENT_LAYOUT))
86  fprintf(out, "; <void>");
87  } else {
88  if (rrs->rr) {
89  ldns_rr_print_fmt(out, fmt, rrs->rr);
90  }
91  if (rrs->next) {
92  ldns_dnssec_rrs_print_fmt(out, fmt, rrs->next);
93  }
94  }
95 }
96 
97 void
98 ldns_dnssec_rrs_print(FILE *out, const ldns_dnssec_rrs *rrs)
99 {
101 }
102 
103 
106 {
107  ldns_dnssec_rrsets *new_rrsets;
108  new_rrsets = LDNS_MALLOC(ldns_dnssec_rrsets);
109  if(!new_rrsets) return NULL;
110  new_rrsets->rrs = NULL;
111  new_rrsets->type = 0;
112  new_rrsets->signatures = NULL;
113  new_rrsets->next = NULL;
114  return new_rrsets;
115 }
116 
117 INLINE void
118 ldns_dnssec_rrsets_free_internal(ldns_dnssec_rrsets *rrsets, int deep)
119 {
120  if (rrsets) {
121  if (rrsets->rrs) {
122  ldns_dnssec_rrs_free_internal(rrsets->rrs, deep);
123  }
124  if (rrsets->next) {
125  ldns_dnssec_rrsets_free_internal(rrsets->next, deep);
126  }
127  if (rrsets->signatures) {
128  ldns_dnssec_rrs_free_internal(rrsets->signatures, deep);
129  }
130  LDNS_FREE(rrsets);
131  }
132 }
133 
134 void
136 {
137  ldns_dnssec_rrsets_free_internal(rrsets, 0);
138 }
139 
140 void
142 {
143  ldns_dnssec_rrsets_free_internal(rrsets, 1);
144 }
145 
148 {
149  if (rrsets) {
150  return rrsets->type;
151  } else {
152  return 0;
153  }
154 }
155 
158  ldns_rr_type type)
159 {
160  if (rrsets) {
161  rrsets->type = type;
162  return LDNS_STATUS_OK;
163  }
164  return LDNS_STATUS_ERR;
165 }
166 
167 static ldns_dnssec_rrsets *
168 ldns_dnssec_rrsets_new_frm_rr(ldns_rr *rr)
169 {
170  ldns_dnssec_rrsets *new_rrsets;
171  ldns_rr_type rr_type;
172  bool rrsig;
173 
174  new_rrsets = ldns_dnssec_rrsets_new();
175  rr_type = ldns_rr_get_type(rr);
176  if (rr_type == LDNS_RR_TYPE_RRSIG) {
177  rrsig = true;
179  } else {
180  rrsig = false;
181  }
182  if (!rrsig) {
183  new_rrsets->rrs = ldns_dnssec_rrs_new();
184  new_rrsets->rrs->rr = rr;
185  } else {
186  new_rrsets->signatures = ldns_dnssec_rrs_new();
187  new_rrsets->signatures->rr = rr;
188  }
189  new_rrsets->type = rr_type;
190  return new_rrsets;
191 }
192 
195 {
196  ldns_dnssec_rrsets *new_rrsets;
197  ldns_rr_type rr_type;
198  bool rrsig = false;
199  ldns_status result = LDNS_STATUS_OK;
200 
201  if (!rrsets || !rr) {
202  return LDNS_STATUS_ERR;
203  }
204 
205  rr_type = ldns_rr_get_type(rr);
206 
207  if (rr_type == LDNS_RR_TYPE_RRSIG) {
208  rrsig = true;
210  }
211 
212  if (!rrsets->rrs && rrsets->type == 0 && !rrsets->signatures) {
213  if (!rrsig) {
214  rrsets->rrs = ldns_dnssec_rrs_new();
215  rrsets->rrs->rr = rr;
216  rrsets->type = rr_type;
217  } else {
218  rrsets->signatures = ldns_dnssec_rrs_new();
219  rrsets->signatures->rr = rr;
220  rrsets->type = rr_type;
221  }
222  return LDNS_STATUS_OK;
223  }
224 
225  if (rr_type > ldns_dnssec_rrsets_type(rrsets)) {
226  if (rrsets->next) {
227  result = ldns_dnssec_rrsets_add_rr(rrsets->next, rr);
228  } else {
229  new_rrsets = ldns_dnssec_rrsets_new_frm_rr(rr);
230  rrsets->next = new_rrsets;
231  }
232  } else if (rr_type < ldns_dnssec_rrsets_type(rrsets)) {
233  /* move the current one into the new next,
234  replace field of current with data from new rr */
235  new_rrsets = ldns_dnssec_rrsets_new();
236  new_rrsets->rrs = rrsets->rrs;
237  new_rrsets->type = rrsets->type;
238  new_rrsets->signatures = rrsets->signatures;
239  new_rrsets->next = rrsets->next;
240  if (!rrsig) {
241  rrsets->rrs = ldns_dnssec_rrs_new();
242  rrsets->rrs->rr = rr;
243  rrsets->signatures = NULL;
244  } else {
245  rrsets->rrs = NULL;
246  rrsets->signatures = ldns_dnssec_rrs_new();
247  rrsets->signatures->rr = rr;
248  }
249  rrsets->type = rr_type;
250  rrsets->next = new_rrsets;
251  } else {
252  /* equal, add to current rrsets */
253  if (rrsig) {
254  if (rrsets->signatures) {
255  result = ldns_dnssec_rrs_add_rr(rrsets->signatures, rr);
256  } else {
257  rrsets->signatures = ldns_dnssec_rrs_new();
258  rrsets->signatures->rr = rr;
259  }
260  } else {
261  if (rrsets->rrs) {
262  result = ldns_dnssec_rrs_add_rr(rrsets->rrs, rr);
263  } else {
264  rrsets->rrs = ldns_dnssec_rrs_new();
265  rrsets->rrs->rr = rr;
266  }
267  }
268  }
269 
270  return result;
271 }
272 
273 static void
274 ldns_dnssec_rrsets_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
275  const ldns_dnssec_rrsets *rrsets,
276  bool follow,
277  bool show_soa)
278 {
279  if (!rrsets) {
280  if ((fmt->flags & LDNS_COMMENT_LAYOUT))
281  fprintf(out, "; <void>\n");
282  } else {
283  if (rrsets->rrs &&
284  (show_soa ||
286  )
287  ) {
288  ldns_dnssec_rrs_print_fmt(out, fmt, rrsets->rrs);
289  if (rrsets->signatures) {
290  ldns_dnssec_rrs_print_fmt(out, fmt,
291  rrsets->signatures);
292  }
293  }
294  if (follow && rrsets->next) {
295  ldns_dnssec_rrsets_print_soa_fmt(out, fmt,
296  rrsets->next, follow, show_soa);
297  }
298  }
299 }
300 
301 
302 void
304  const ldns_dnssec_rrsets *rrsets,
305  bool follow)
306 {
307  ldns_dnssec_rrsets_print_soa_fmt(out, fmt, rrsets, follow, true);
308 }
309 
310 void
311 ldns_dnssec_rrsets_print(FILE *out, const ldns_dnssec_rrsets *rrsets, bool follow)
312 {
314  rrsets, follow);
315 }
316 
319 {
320  ldns_dnssec_name *new_name;
321 
322  new_name = LDNS_CALLOC(ldns_dnssec_name, 1);
323  if (!new_name) {
324  return NULL;
325  }
326  /*
327  * not needed anymore because CALLOC initializes everything to zero.
328 
329  new_name->name = NULL;
330  new_name->rrsets = NULL;
331  new_name->name_alloced = false;
332  new_name->nsec = NULL;
333  new_name->nsec_signatures = NULL;
334 
335  new_name->is_glue = false;
336  new_name->hashed_name = NULL;
337 
338  */
339  return new_name;
340 }
341 
344 {
346 
347  new_name->name = ldns_rr_owner(rr);
348  if(ldns_dnssec_name_add_rr(new_name, rr) != LDNS_STATUS_OK) {
349  ldns_dnssec_name_free(new_name);
350  return NULL;
351  }
352 
353  return new_name;
354 }
355 
356 INLINE void
357 ldns_dnssec_name_free_internal(ldns_dnssec_name *name,
358  int deep)
359 {
360  if (name) {
361  if (name->name_alloced) {
362  ldns_rdf_deep_free(name->name);
363  }
364  if (name->rrsets) {
365  ldns_dnssec_rrsets_free_internal(name->rrsets, deep);
366  }
367  if (name->nsec && deep) {
368  ldns_rr_free(name->nsec);
369  }
370  if (name->nsec_signatures) {
371  ldns_dnssec_rrs_free_internal(name->nsec_signatures, deep);
372  }
373  if (name->hashed_name) {
374  /* Hashed name is always allocated when signing,
375  * so always deep free
376  */
378  }
379  LDNS_FREE(name);
380  }
381 }
382 
383 void
385 {
386  ldns_dnssec_name_free_internal(name, 0);
387 }
388 
389 void
391 {
392  ldns_dnssec_name_free_internal(name, 1);
393 }
394 
395 ldns_rdf *
397 {
398  if (name) {
399  return name->name;
400  }
401  return NULL;
402 }
403 
404 bool
406 {
407  if (name) {
408  return name->is_glue;
409  }
410  return false;
411 }
412 
413 void
415  ldns_rdf *dname)
416 {
417  if (rrset && dname) {
418  rrset->name = dname;
419  }
420 }
421 
422 
423 void
425 {
426  if (rrset && nsec) {
427  rrset->nsec = nsec;
428  }
429 }
430 
431 int
432 ldns_dnssec_name_cmp(const void *a, const void *b)
433 {
436 
437  if (na && nb) {
440  } else if (na) {
441  return 1;
442  } else if (nb) {
443  return -1;
444  } else {
445  return 0;
446  }
447 }
448 
451  ldns_rr *rr)
452 {
453  ldns_status result = LDNS_STATUS_OK;
454  ldns_rr_type rr_type;
455  ldns_rr_type typecovered = 0;
456 
457  /* special handling for NSEC3 and NSECX covering RRSIGS */
458 
459  if (!name || !rr) {
460  return LDNS_STATUS_ERR;
461  }
462 
463  rr_type = ldns_rr_get_type(rr);
464 
465  if (rr_type == LDNS_RR_TYPE_RRSIG) {
466  typecovered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
467  }
468 
469  if (rr_type == LDNS_RR_TYPE_NSEC ||
470  rr_type == LDNS_RR_TYPE_NSEC3) {
471  /* XX check if is already set (and error?) */
472  name->nsec = rr;
473  } else if (typecovered == LDNS_RR_TYPE_NSEC ||
474  typecovered == LDNS_RR_TYPE_NSEC3) {
475  if (name->nsec_signatures) {
476  result = ldns_dnssec_rrs_add_rr(name->nsec_signatures, rr);
477  } else {
479  name->nsec_signatures->rr = rr;
480  }
481  } else {
482  /* it's a 'normal' RR, add it to the right rrset */
483  if (name->rrsets) {
484  result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr);
485  } else {
486  name->rrsets = ldns_dnssec_rrsets_new();
487  result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr);
488  }
489  }
490  return result;
491 }
492 
495  ldns_rr_type type) {
496  ldns_dnssec_rrsets *result;
497 
498  result = name->rrsets;
499  while (result) {
500  if (result->type == type) {
501  return result;
502  } else {
503  result = result->next;
504  }
505  }
506  return NULL;
507 }
508 
511  const ldns_rdf *dname,
512  ldns_rr_type type)
513 {
514  ldns_rbnode_t *node;
515 
516  if (!zone || !dname || !zone->names) {
517  return NULL;
518  }
519 
520  node = ldns_rbtree_search(zone->names, dname);
521  if (node) {
523  type);
524  } else {
525  return NULL;
526  }
527 }
528 
529 static void
530 ldns_dnssec_name_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
531  const ldns_dnssec_name *name,
532  bool show_soa)
533 {
534  if (name) {
535  if(name->rrsets) {
536  ldns_dnssec_rrsets_print_soa_fmt(out, fmt,
537  name->rrsets, true, show_soa);
538  } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
539  fprintf(out, ";; Empty nonterminal: ");
540  ldns_rdf_print(out, name->name);
541  fprintf(out, "\n");
542  }
543  if(name->nsec) {
544  ldns_rr_print_fmt(out, fmt, name->nsec);
545  }
546  if (name->nsec_signatures) {
547  ldns_dnssec_rrs_print_fmt(out, fmt,
548  name->nsec_signatures);
549  }
550  } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
551  fprintf(out, "; <void>\n");
552  }
553 }
554 
555 
556 void
558  const ldns_dnssec_name *name)
559 {
560  ldns_dnssec_name_print_soa_fmt(out, fmt, name, true);
561 }
562 
563 void
565 {
567 }
568 
569 
572 {
574  if(!zone) return NULL;
575  zone->soa = NULL;
576  zone->names = NULL;
577  zone->hashed_names = NULL;
578  zone->_nsec3params = NULL;
579 
580  return zone;
581 }
582 
583 static bool
584 rr_is_rrsig_covering(ldns_rr* rr, ldns_rr_type t)
585 {
588 }
589 
590 /* When the zone is first read into an list and then inserted into an
591  * ldns_dnssec_zone (rbtree) the nodes of the rbtree are allocated close (next)
592  * to each other. Because ldns-verify-zone (the only program that uses this
593  * function) uses the rbtree mostly for sequential walking, this results
594  * in a speed increase (of 15% on linux) because we have less CPU-cache misses.
595  */
596 #define FASTER_DNSSEC_ZONE_NEW_FRM_FP 1 /* Because of L2 cache efficiency */
597 
598 static ldns_status
599 ldns_dnssec_zone_add_empty_nonterminals_nsec3(
600  ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s);
601 
602 static void
603 ldns_todo_nsec3_ents_node_free(ldns_rbnode_t *node, void *arg) {
604  (void) arg;
605  ldns_rdf_deep_free((ldns_rdf *)node->key);
606  LDNS_FREE(node);
607 }
608 
611  uint32_t default_ttl, ldns_rr_class ATTR_UNUSED(c), int* line_nr)
612 {
613  ldns_rr* cur_rr;
614  size_t i;
615 
616  ldns_rdf *my_origin = NULL;
617  ldns_rdf *my_prev = NULL;
618 
620  /* NSEC3s may occur before the names they refer to. We must remember
621  them and add them to the name later on, after the name is read.
622  We track not yet matching NSEC3s*n the todo_nsec3s list */
623  ldns_rr_list* todo_nsec3s = ldns_rr_list_new();
624  /* when reading NSEC3s, there is a chance that we encounter nsecs
625  for empty nonterminals, whose nonterminals we cannot derive yet
626  because the needed information is to be read later.
627 
628  nsec3_ents (where ent is e.n.t.; i.e. empty non terminal) will
629  hold the NSEC3s that still didn't have a matching name in the
630  zone tree, even after all names were read. They can only match
631  after the zone is equipped with all the empty non terminals. */
632  ldns_rbtree_t todo_nsec3_ents;
633  ldns_rbnode_t *new_node;
634  ldns_rr_list* todo_nsec3_rrsigs = ldns_rr_list_new();
635 
636  ldns_status status;
637 
638 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
639  ldns_zone* zone = NULL;
640 #else
641  ldns_rr *prev_rr = NULL;
642  uint32_t my_ttl = default_ttl;
643  /* RFC 1035 Section 5.1, says 'Omitted class and TTL values are default
644  * to the last explicitly stated values.'
645  */
646  bool ttl_from_TTL = false;
647  bool explicit_ttl = false;
648 #endif
649 
650  ldns_rbtree_init(&todo_nsec3_ents, ldns_dname_compare_v);
651 
652 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
653  status = ldns_zone_new_frm_fp_l(&zone, fp, origin, default_ttl, c, line_nr);
654  if (status != LDNS_STATUS_OK)
655  goto error;
656 #endif
657  if (!newzone || !todo_nsec3s || !todo_nsec3_rrsigs ) {
658  status = LDNS_STATUS_MEM_ERR;
659  goto error;
660  }
661  if (origin) {
662  if (!(my_origin = ldns_rdf_clone(origin))) {
663  status = LDNS_STATUS_MEM_ERR;
664  goto error;
665  }
666  if (!(my_prev = ldns_rdf_clone(origin))) {
667  status = LDNS_STATUS_MEM_ERR;
668  goto error;
669  }
670  }
671 
672 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
673  if (ldns_zone_soa(zone)) {
674  status = ldns_dnssec_zone_add_rr(newzone, ldns_zone_soa(zone));
675  if (status != LDNS_STATUS_OK)
676  goto error;
677  }
678  for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
679  cur_rr = ldns_rr_list_rr(ldns_zone_rrs(zone), i);
680  status = LDNS_STATUS_OK;
681 #else
682  while (!feof(fp)) {
683  /* If ttl came from $TTL line, then it should be the default.
684  * (RFC 2308 Section 4)
685  * Otherwise it "defaults to the last explicitly stated value"
686  * (RFC 1035 Section 5.1)
687  */
688  if (ttl_from_TTL)
689  my_ttl = default_ttl;
690  status = ldns_rr_new_frm_fp_l(&cur_rr, fp, &my_ttl, &my_origin,
691  &my_prev, line_nr, &explicit_ttl);
692 #endif
693  switch (status) {
694  case LDNS_STATUS_OK:
695 #ifndef FASTER_DNSSEC_ZONE_NEW_FRM_FP
696  if (explicit_ttl) {
697  if (!ttl_from_TTL) {
698  /* No $TTL, so ttl "defaults to the
699  * last explicitly stated value"
700  * (RFC 1035 Section 5.1)
701  */
702  my_ttl = ldns_rr_ttl(cur_rr);
703  }
704  /* When ttl is implicit, try to adhere to the rules as
705  * much as possible. (also for compatibility with bind)
706  * This was changed when fixing an issue with ZONEMD
707  * which hashes the TTL too.
708  */
709  } else if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SIG
710  || ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_RRSIG) {
711  if (ldns_rr_rd_count(cur_rr) >= 4
713 
714  /* SIG without explicit ttl get ttl
715  * from the original_ttl field
716  * (RFC 2535 Section 7.2)
717  *
718  * Similarly for RRSIG, but stated less
719  * specifically in the spec.
720  * (RFC 4034 Section 3)
721  */
722  ldns_rr_set_ttl(cur_rr,
724  ldns_rr_rdf(rr, 3)));
725 
726  } else if (prev_rr
727  && ldns_rr_get_type(prev_rr) == ldns_rr_get_type(cur_rr)
728  && ldns_dname_compare( ldns_rr_owner(prev_rr)
729  , ldns_rr_owner(cur_rr)) == 0)
730 
731  /* "TTLs of all RRs in an RRSet must be the same"
732  * (RFC 2881 Section 5.2)
733  */
734  ldns_rr_set_ttl(cur_rr, ldns_rr_ttl(prev_rr));
735 
736 #endif
737  status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
738  switch(status) {
740  if (rr_is_rrsig_covering(cur_rr,
742  ldns_rr_list_push_rr(todo_nsec3_rrsigs,
743  cur_rr);
744  } else {
745  ldns_rr_list_push_rr(todo_nsec3s,
746  cur_rr);
747  }
748  status = LDNS_STATUS_OK;
749  break;
751  ldns_rr_free(cur_rr);
752 #ifndef FASTER_DNSSEC_ZONE_NEW_FRM_FP
753  cur_rr = prev_rr;
754 #else
755  cur_rr = NULL;
756 #endif
757  status = LDNS_STATUS_OK;
758  break;
759  case LDNS_STATUS_OK:
760  break;
761  default:
762  goto error;
763  }
764 #ifndef FASTER_DNSSEC_ZONE_NEW_FRM_FP
765  prev_rr = cur_rr;
766 #endif
767  break;
768 
769  case LDNS_STATUS_SYNTAX_TTL: /* the ttl was set*/
770 #ifndef FASTER_DNSSEC_ZONE_NEW_FRM_FP
771  default_ttl = my_ttl;
772  ttl_from_TTL = true;
773 #endif
774  status = LDNS_STATUS_OK;
775  break;
776 
777 
778  case LDNS_STATUS_SYNTAX_EMPTY: /* empty line was seen */
779  case LDNS_STATUS_SYNTAX_ORIGIN: /* the origin was set*/
780  status = LDNS_STATUS_OK;
781  break;
782 
783  case LDNS_STATUS_SYNTAX_INCLUDE:/* $include not implemented */
785  break;
786 
787  default:
788  goto error;
789  }
790  }
791 
792  for (i = 0; status == LDNS_STATUS_OK &&
793  i < ldns_rr_list_rr_count(todo_nsec3s); i++) {
794  cur_rr = ldns_rr_list_rr(todo_nsec3s, i);
795  status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
797  if (!(new_node = LDNS_MALLOC(ldns_rbnode_t))) {
798  status = LDNS_STATUS_MEM_ERR;
799  break;
800  }
801  new_node->key = ldns_dname_label(ldns_rr_owner(cur_rr), 0);
802  new_node->data = cur_rr;
803  if (!ldns_rbtree_insert(&todo_nsec3_ents, new_node)) {
804  LDNS_FREE(new_node);
805  status = LDNS_STATUS_MEM_ERR;
806  break;
807  }
808  status = LDNS_STATUS_OK;
809  }
810  }
811  if (todo_nsec3_ents.count > 0)
812  (void) ldns_dnssec_zone_add_empty_nonterminals_nsec3(
813  newzone, &todo_nsec3_ents);
814  for (i = 0; status == LDNS_STATUS_OK &&
815  i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++) {
816  cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
817  status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
818  }
819  if (z) {
820  *z = newzone;
821  newzone = NULL;
822  } else {
823  ldns_dnssec_zone_free(newzone);
824  newzone = NULL;
825  }
826 
827 error:
828 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
829  if (zone) {
830  ldns_zone_free(zone);
831  }
832 #endif
833  ldns_rr_list_free(todo_nsec3_rrsigs);
834  ldns_traverse_postorder(&todo_nsec3_ents,
835  ldns_todo_nsec3_ents_node_free, NULL);
836  ldns_rr_list_free(todo_nsec3s);
837 
838  if (my_origin) {
839  ldns_rdf_deep_free(my_origin);
840  }
841  if (my_prev) {
842  ldns_rdf_deep_free(my_prev);
843  }
844  if (newzone) {
845  ldns_dnssec_zone_free(newzone);
846  }
847  return status;
848 }
849 
852  uint32_t ttl, ldns_rr_class ATTR_UNUSED(c))
853 {
854  return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
855 }
856 
857 static void
858 ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) {
859  (void) arg;
861  LDNS_FREE(node);
862 }
863 
864 static void
865 ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) {
866  (void) arg;
868  LDNS_FREE(node);
869 }
870 
871 static void
872 ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
873  (void) arg;
874  LDNS_FREE(node);
875 }
876 
877 void
879 {
880  if (zone) {
881  if (zone->hashed_names) {
883  ldns_hashed_names_node_free, NULL);
884  LDNS_FREE(zone->hashed_names);
885  }
886  if (zone->names) {
887  /* destroy all name structures within the tree */
889  ldns_dnssec_name_node_free,
890  NULL);
891  LDNS_FREE(zone->names);
892  }
893  LDNS_FREE(zone);
894  }
895 }
896 
897 void
899 {
900  if (zone) {
901  if (zone->hashed_names) {
903  ldns_hashed_names_node_free, NULL);
904  LDNS_FREE(zone->hashed_names);
905  }
906  if (zone->names) {
907  /* destroy all name structures within the tree */
909  ldns_dnssec_name_node_deep_free,
910  NULL);
911  LDNS_FREE(zone->names);
912  }
913  LDNS_FREE(zone);
914  }
915 }
916 
917 /* use for dname comparison in tree */
918 int
919 ldns_dname_compare_v(const void *a, const void *b) {
920  return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b);
921 }
922 
923 static void
924 ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
925  ldns_dnssec_name* name, ldns_rr* nsec3rr);
926 
927 static void
928 ldns_dnssec_zone_hashed_names_from_nsec3(
929  ldns_dnssec_zone* zone, ldns_rr* nsec3rr)
930 {
931  ldns_rbnode_t* current_node;
932  ldns_dnssec_name* current_name;
933 
934  assert(zone != NULL);
935  assert(nsec3rr != NULL);
936 
937  if (zone->hashed_names) {
939  ldns_hashed_names_node_free, NULL);
940  LDNS_FREE(zone->hashed_names);
941  }
942  zone->_nsec3params = nsec3rr;
943 
944  /* So this is a NSEC3 zone.
945  * Calculate hashes for all names already in the zone
946  */
948  if (zone->hashed_names == NULL) {
949  return;
950  }
951  for ( current_node = ldns_rbtree_first(zone->names)
952  ; current_node != LDNS_RBTREE_NULL
953  ; current_node = ldns_rbtree_next(current_node)
954  ) {
955  current_name = (ldns_dnssec_name *) current_node->data;
956  ldns_dnssec_name_make_hashed_name(zone, current_name, nsec3rr);
957 
958  }
959 }
960 
961 static void
962 ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
963  ldns_dnssec_name* name, ldns_rr* nsec3rr)
964 {
965  ldns_rbnode_t* new_node;
966 
967  assert(name != NULL);
968  if (! zone->_nsec3params) {
969  if (! nsec3rr) {
970  return;
971  }
972  ldns_dnssec_zone_hashed_names_from_nsec3(zone, nsec3rr);
973 
974  } else if (! nsec3rr) {
975  nsec3rr = zone->_nsec3params;
976  }
977  name->hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsec3rr, name->name);
978 
979  /* Also store in zone->hashed_names */
980  if ((new_node = LDNS_MALLOC(ldns_rbnode_t))) {
981 
982  new_node->key = name->hashed_name;
983  new_node->data = name;
984 
985  if (ldns_rbtree_insert(zone->hashed_names, new_node) == NULL) {
986 
987  LDNS_FREE(new_node);
988  }
989  }
990 }
991 
992 
993 static ldns_rbnode_t *
994 ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, ldns_rr *rr) {
995  ldns_rdf *hashed_name;
996  ldns_rbnode_t *to_return;
997 
998  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 && ! zone->_nsec3params){
999 
1000  ldns_dnssec_zone_hashed_names_from_nsec3(zone, rr);
1001  }
1002  if (zone->hashed_names == NULL) {
1003  return NULL;
1004  }
1005  hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
1006  if (hashed_name == NULL) {
1007  return NULL;
1008  }
1009  to_return = ldns_rbtree_search(zone->hashed_names, hashed_name);
1010  ldns_rdf_deep_free(hashed_name);
1011  return to_return;
1012 }
1013 
1016 {
1017  ldns_status result = LDNS_STATUS_OK;
1018  ldns_dnssec_name *cur_name;
1019  ldns_rbnode_t *cur_node;
1020  ldns_rr_type type_covered = 0;
1021 
1022  if (!zone || !rr) {
1023  return LDNS_STATUS_ERR;
1024  }
1025 
1026  if (!zone->names) {
1028  if(!zone->names) return LDNS_STATUS_MEM_ERR;
1029  }
1030 
1031  /* we need the original of the hashed name if this is
1032  an NSEC3, or an RRSIG that covers an NSEC3 */
1033  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) {
1034  type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
1035  }
1036  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 ||
1037  type_covered == LDNS_RR_TYPE_NSEC3) {
1038  cur_node = ldns_dnssec_zone_find_nsec3_original(zone, rr);
1039  if (!cur_node) {
1041  }
1042  } else {
1043  cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr));
1044  }
1045  if (!cur_node) {
1046  /* add */
1047  cur_name = ldns_dnssec_name_new_frm_rr(rr);
1048  if(!cur_name) return LDNS_STATUS_MEM_ERR;
1049  cur_node = LDNS_MALLOC(ldns_rbnode_t);
1050  if(!cur_node) {
1051  ldns_dnssec_name_free(cur_name);
1052  return LDNS_STATUS_MEM_ERR;
1053  }
1054  cur_node->key = ldns_rr_owner(rr);
1055  cur_node->data = cur_name;
1056  (void)ldns_rbtree_insert(zone->names, cur_node);
1057  ldns_dnssec_name_make_hashed_name(zone, cur_name, NULL);
1058  } else {
1059  cur_name = (ldns_dnssec_name *) cur_node->data;
1060  result = ldns_dnssec_name_add_rr(cur_name, rr);
1061  }
1062  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
1063  zone->soa = cur_name;
1064  }
1065  return result;
1066 }
1067 
1068 void
1070  const ldns_rbtree_t *tree,
1071  bool print_soa)
1072 {
1073  ldns_rbnode_t *node;
1074  ldns_dnssec_name *name;
1075 
1076  node = ldns_rbtree_first(tree);
1077  while (node != LDNS_RBTREE_NULL) {
1078  name = (ldns_dnssec_name *) node->data;
1079  ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa);
1080  if ((fmt->flags & LDNS_COMMENT_LAYOUT))
1081  fprintf(out, ";\n");
1082  node = ldns_rbtree_next(node);
1083  }
1084 }
1085 
1086 void
1087 ldns_dnssec_zone_names_print(FILE *out, const ldns_rbtree_t *tree, bool print_soa)
1088 {
1090  tree, print_soa);
1091 }
1092 
1093 void
1095  const ldns_dnssec_zone *zone)
1096 {
1097  if (zone) {
1098  if (zone->soa) {
1099  if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
1100  fprintf(out, ";; Zone: ");
1102  zone->soa));
1103  fprintf(out, "\n;\n");
1104  }
1107  zone->soa,
1108  LDNS_RR_TYPE_SOA),
1109  false);
1110  if ((fmt->flags & LDNS_COMMENT_LAYOUT))
1111  fprintf(out, ";\n");
1112  }
1113 
1114  if (zone->names) {
1116  zone->names, false);
1117  }
1118  }
1119 }
1120 
1121 void
1123 {
1125 }
1126 
1127 static ldns_status
1128 ldns_dnssec_zone_add_empty_nonterminals_nsec3(
1129  ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s)
1130 {
1131  ldns_dnssec_name *new_name;
1132  ldns_rdf *cur_name;
1133  ldns_rdf *next_name;
1134  ldns_rbnode_t *cur_node, *next_node, *new_node;
1135 
1136  /* for the detection */
1137  uint16_t i, cur_label_count, next_label_count;
1138  uint16_t soa_label_count = 0;
1139  ldns_rdf *l1, *l2;
1140  int lpos;
1141 
1142  if (!zone) {
1143  return LDNS_STATUS_ERR;
1144  }
1145  if (zone->soa && zone->soa->name) {
1146  soa_label_count = ldns_dname_label_count(zone->soa->name);
1147  }
1148 
1149  cur_node = ldns_rbtree_first(zone->names);
1150  while (cur_node != LDNS_RBTREE_NULL) {
1151  next_node = ldns_rbtree_next(cur_node);
1152 
1153  /* skip glue */
1154  while (next_node != LDNS_RBTREE_NULL &&
1155  next_node->data &&
1156  ((ldns_dnssec_name *)next_node->data)->is_glue
1157  ) {
1158  next_node = ldns_rbtree_next(next_node);
1159  }
1160 
1161  if (next_node == LDNS_RBTREE_NULL) {
1162  next_node = ldns_rbtree_first(zone->names);
1163  }
1164  if (! cur_node->data || ! next_node->data) {
1165  return LDNS_STATUS_ERR;
1166  }
1167  cur_name = ((ldns_dnssec_name *)cur_node->data)->name;
1168  next_name = ((ldns_dnssec_name *)next_node->data)->name;
1169  cur_label_count = ldns_dname_label_count(cur_name);
1170  next_label_count = ldns_dname_label_count(next_name);
1171 
1172  /* Since the names are in canonical order, we can
1173  * recognize empty non-terminals by their labels;
1174  * every label after the first one on the next owner
1175  * name is a non-terminal if it either does not exist
1176  * in the current name or is different from the same
1177  * label in the current name (counting from the end)
1178  */
1179  for (i = 1; i < next_label_count - soa_label_count; i++) {
1180  lpos = (int)cur_label_count - (int)next_label_count + (int)i;
1181  if (lpos >= 0) {
1182  l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos);
1183  } else {
1184  l1 = NULL;
1185  }
1186  l2 = ldns_dname_clone_from(next_name, i);
1187 
1188  if (!l1 || ldns_dname_compare(l1, l2) != 0) {
1189  /* We have an empty nonterminal, add it to the
1190  * tree
1191  */
1192  ldns_rbnode_t *node = NULL;
1193  ldns_rdf *ent_name;
1194 
1195  if (!(ent_name = ldns_dname_clone_from(
1196  next_name, i))) {
1197 
1198  ldns_rdf_deep_free(l1);
1199  ldns_rdf_deep_free(l2);
1200  return LDNS_STATUS_MEM_ERR;
1201  }
1202 
1203  if (nsec3s && zone->_nsec3params) {
1204  ldns_rdf *ent_hashed_name;
1205 
1206  if (!(ent_hashed_name =
1208  zone->_nsec3params,
1209  ent_name))) {
1210  ldns_rdf_deep_free(l1);
1211  ldns_rdf_deep_free(l2);
1212  ldns_rdf_deep_free(ent_name);
1213  return LDNS_STATUS_MEM_ERR;
1214  }
1215  node = ldns_rbtree_search(nsec3s,
1216  ent_hashed_name);
1217  ldns_rdf_deep_free(ent_hashed_name);
1218  if (!node) {
1219  ldns_rdf_deep_free(l1);
1220  ldns_rdf_deep_free(l2);
1221  ldns_rdf_deep_free(ent_name);
1222  continue;
1223  }
1224  }
1225  new_name = ldns_dnssec_name_new();
1226  if (!new_name) {
1227  ldns_rdf_deep_free(l1);
1228  ldns_rdf_deep_free(l2);
1229  ldns_rdf_deep_free(ent_name);
1230  return LDNS_STATUS_MEM_ERR;
1231  }
1232  new_name->name = ent_name;
1233  new_name->name_alloced = true;
1234  new_node = LDNS_MALLOC(ldns_rbnode_t);
1235  if (!new_node) {
1236  ldns_rdf_deep_free(l1);
1237  ldns_rdf_deep_free(l2);
1238  ldns_dnssec_name_free(new_name);
1239  return LDNS_STATUS_MEM_ERR;
1240  }
1241  new_node->key = new_name->name;
1242  new_node->data = new_name;
1243  (void)ldns_rbtree_insert(zone->names, new_node);
1244  ldns_dnssec_name_make_hashed_name(
1245  zone, new_name, NULL);
1246  if (node)
1247  (void) ldns_dnssec_zone_add_rr(zone,
1248  (ldns_rr *)node->data);
1249  }
1250  ldns_rdf_deep_free(l1);
1251  ldns_rdf_deep_free(l2);
1252  }
1253 
1254  /* we might have inserted a new node after
1255  * the current one so we can't just use next()
1256  */
1257  if (next_node != ldns_rbtree_first(zone->names)) {
1258  cur_node = next_node;
1259  } else {
1260  cur_node = LDNS_RBTREE_NULL;
1261  }
1262  }
1263  return LDNS_STATUS_OK;
1264 }
1265 
1268 {
1269  return ldns_dnssec_zone_add_empty_nonterminals_nsec3(zone, NULL);
1270 }
1271 
1272 bool
1274 {
1275  ldns_rr* nsec3;
1276  ldns_rbnode_t* node;
1277 
1279  node = ldns_rbtree_first(zone->names);
1280  while (node != LDNS_RBTREE_NULL) {
1281  nsec3 = ((ldns_dnssec_name*)node->data)->nsec;
1282  if (nsec3 &&ldns_rr_get_type(nsec3)
1283  == LDNS_RR_TYPE_NSEC3 &&
1284  ldns_nsec3_optout(nsec3)) {
1285  return true;
1286  }
1287  node = ldns_rbtree_next(node);
1288  }
1289  }
1290  return false;
1291 }
1292 
1293 /*
1294  * Stuff for calculating and verifying zone digests
1295  */
1305 
1306 typedef struct dnssec_zone_rr_iter {
1317  uint8_t apex_labs;
1319 
1320 INLINE void
1321 dnssec_zone_rr_iter_set_state_for_next_name(dnssec_zone_rr_iter *i)
1322 {
1323  /* Make sure the i->name is "in zone" (i.e. below the apex) */
1324  if (i->apex_name) {
1325  ldns_rdf *name = (ldns_rdf *)i->node->key;
1326 
1327  while (i->name && name != i->apex_name /* not apex */
1328 
1329  && ( ldns_dname_label_count(name) != i->apex_labs
1330  || ldns_dname_compare(name, i->apex_name)) /* not apex */
1331 
1332  && !ldns_dname_is_subdomain(name, i->apex_name) /* no sub */) {
1333 
1334  /* next name */
1335  i->node = ldns_rbtree_next(i->node);
1336  if (i->node == LDNS_RBTREE_NULL)
1337  i->name = NULL;
1338  else {
1339  i->name = (ldns_dnssec_name *)i->node->data;
1340  name = (ldns_rdf *)i->node->key;
1341  }
1342  }
1343  }
1344  /* determine state */
1345  if (!i->name) {
1346  if (!i->nsec3_name)
1348  else {
1349  i->rrs = i->nsec3_name->nsec_signatures;
1351  }
1352  } else if (!i->nsec3_name) {
1353  i->rrsets = i->name->rrsets;
1355 
1357  , (ldns_rdf *)i->node->key) < 0) {
1358  i->rrs = i->nsec3_name->nsec_signatures;
1360  } else {
1361  i->rrsets = i->name->rrsets;
1363  }
1364 }
1365 
1407 static ldns_rr *
1408 dnssec_zone_rr_iter_next(dnssec_zone_rr_iter *i)
1409 {
1410  ldns_rr *nsec3;
1411 
1412  for (;;) {
1413  if (i->rrs) {
1414  ldns_rr *rr = i->rrs->rr;
1415  i->rrs = i->rrs->next;
1416  return rr;
1417  }
1418  switch (i->state) {
1420  if (i->rrsets
1421  && i->rrsets->type < LDNS_RR_TYPE_RRSIG) {
1422 
1423  i->rrs = i->rrsets->rrs;
1424  i->rrsets = i->rrsets->next;
1425  break;
1426  }
1427  i->rrsets4rrsigs = i->name->rrsets;
1428  if (i->name->nsec && ldns_rr_get_type(i->name->nsec)
1429  == LDNS_RR_TYPE_NSEC) {
1430 
1432  break;
1433  }
1435  /* fallthrough */
1436 
1438  if (i->rrsets4rrsigs) {
1439  i->rrs = i->rrsets4rrsigs->signatures;
1440  i->rrsets4rrsigs = i->rrsets4rrsigs->next;
1441  break;
1442  }
1444  /* fallthrough */
1445 
1447  if (i->rrsets) {
1448  i->rrs = i->rrsets->rrs;
1449  i->rrsets = i->rrsets->next;
1450  break;
1451  }
1452  /* next name */
1453  i->node = ldns_rbtree_next(i->node);
1454  i->name = i->node == LDNS_RBTREE_NULL ? NULL
1455  : (ldns_dnssec_name *)i->node->data;
1456 
1457  dnssec_zone_rr_iter_set_state_for_next_name(i);
1458  break;
1459 
1461  if (i->rrsets4rrsigs
1463 
1464  i->rrs = i->rrsets4rrsigs->signatures;
1465  i->rrsets4rrsigs = i->rrsets4rrsigs->next;
1466  break;
1467  }
1469  i->rrs = i->name->nsec_signatures;
1470  break;
1471 
1473  if (i->rrsets4rrsigs) {
1474  i->rrs = i->rrsets4rrsigs->signatures;
1475  i->rrsets4rrsigs = i->rrsets4rrsigs->next;
1476  break;
1477  }
1479  return i->name->nsec;
1480 
1482  nsec3 = i->nsec3_name->nsec;
1483 
1484  /* next nsec3 */
1485  do {
1486  i->nsec3_node
1488  i->nsec3_name
1489  = i->nsec3_node == LDNS_RBTREE_NULL ? NULL
1491 
1492  /* names for glue can be in the hashed_names
1493  * tree, but will not have a NSEC3
1494  */
1495  } while (i->nsec3_name && !i->nsec3_name->nsec);
1496 
1497  dnssec_zone_rr_iter_set_state_for_next_name(i);
1498  return nsec3;
1499 
1501  return NULL;
1502  }
1503  }
1504 }
1505 
1506 static ldns_rr *
1507 dnssec_zone_rr_iter_first(dnssec_zone_rr_iter *i, ldns_dnssec_zone *zone)
1508 {
1509  if (!i || !zone)
1510  return NULL;
1511 
1512  memset(i, 0, sizeof(*i));
1513  i->zone = zone;
1514  if (zone->soa && zone->soa->name) {
1515  i->apex_name = zone->soa->name;
1517  } else
1518  i->apex_name = NULL;
1519 
1520 
1521  i->node = ldns_rbtree_first(zone->names);
1522  i->name = i->node == LDNS_RBTREE_NULL ? NULL
1523  : (ldns_dnssec_name *)i->node->data;
1524 
1525  if (zone->hashed_names) {
1527  i->nsec3_name = i->nsec3_node == LDNS_RBTREE_NULL ? NULL
1529  /* While there is no NSEC3 RR present at this hashed name,
1530  * skip to the next hashed name.
1531  */
1532  while (i->nsec3_name && !i->nsec3_name->nsec) {
1533  /* next nsec3 */
1535  i->nsec3_name = i->nsec3_node == LDNS_RBTREE_NULL ? NULL
1537  }
1538  }
1539  dnssec_zone_rr_iter_set_state_for_next_name(i);
1540  return dnssec_zone_rr_iter_next(i);
1541 }
1542 
1546  ZONEMD_SCHEME_LAST = 1
1547 };
1548 typedef enum enum_zonemd_scheme zonemd_scheme;
1549 
1554  ZONEMD_HASH_LAST = 2
1555 };
1556 typedef enum enum_zonemd_hash zonemd_hash;
1557 
1561  unsigned simple_sha384 : 1;
1562  unsigned simple_sha512 : 1;
1563  unsigned double_sha384 : 1;
1564  unsigned double_sha512 : 1;
1565 };
1566 typedef struct struct_zone_digester zone_digester;
1567 
1568 INLINE bool zone_digester_set(zone_digester *zd)
1569 { return zd && (zd->simple_sha384 || zd->simple_sha512); }
1570 
1571 INLINE void zone_digester_init(zone_digester *zd)
1572 { memset(zd, 0, sizeof(*zd)); }
1573 
1574 static ldns_status
1575 zone_digester_add(zone_digester *zd, zonemd_scheme scheme, zonemd_hash hash)
1576 {
1577  if (!zd)
1578  return LDNS_STATUS_NULL;
1579 
1580  switch (scheme) {
1581  case ZONEMD_SCHEME_SIMPLE:
1582  switch (hash) {
1583  case ZONEMD_HASH_SHA384:
1584  if (zd->double_sha384)
1586 
1587  else if (zd->simple_sha384) {
1588  zd->simple_sha384 = 0;
1589  zd->double_sha384 = 1;
1591  }
1593  zd->simple_sha384 = 1;
1594  break;
1595 
1596  case ZONEMD_HASH_SHA512:
1597  if (zd->double_sha512)
1599 
1600  else if (zd->simple_sha512) {
1601  zd->simple_sha512 = 0;
1602  zd->double_sha512 = 1;
1604  }
1606  zd->simple_sha512 = 1;
1607  break;
1608  default:
1610  }
1611  break;
1612  default:
1614  }
1615  return LDNS_STATUS_OK;
1616 }
1617 
1618 static ldns_status
1619 zone_digester_update(zone_digester *zd, ldns_rr *rr)
1620 {
1621  uint8_t data[65536];
1622  ldns_buffer buf;
1623  ldns_status st;
1624 
1625  buf._data = data;
1626  buf._position = 0;
1627  buf._limit = sizeof(data);
1628  buf._capacity = sizeof(data);
1629  buf._fixed = 1;
1630  buf._status = LDNS_STATUS_OK;
1631 
1632  if ((st = ldns_rr2buffer_wire_canonical(&buf, rr, LDNS_SECTION_ANSWER)))
1633  return st;
1634 
1635  if (zd->simple_sha384)
1636  ldns_sha384_update(&zd->sha384_CTX, data, buf._position);
1637 
1638  if (zd->simple_sha512)
1639  ldns_sha512_update(&zd->sha512_CTX, data, buf._position);
1640 
1641  return LDNS_STATUS_OK;
1642 }
1643 
1644 INLINE ldns_rr *
1645 new_zonemd(ldns_rr *soa, zonemd_hash hash)
1646 {
1647  ldns_rr *rr = NULL;
1648  uint8_t *data = NULL;
1649  ldns_rdf *rdf;
1650  size_t md_len = hash == ZONEMD_HASH_SHA384
1653 
1655  return NULL;
1656 
1657  if (!(rdf = ldns_rdf_clone(ldns_rr_owner(soa))))
1658  goto error;
1659 
1660  ldns_rr_set_owner(rr, rdf);
1662  ldns_rr_set_ttl(rr, ldns_rr_ttl(soa));
1663 
1664  if (!(rdf = ldns_rdf_clone(ldns_rr_rdf(soa, 2))))
1665  goto error;
1666  ldns_rr_set_rdf(rr, rdf, 0);
1667 
1668  if (!(rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, 1)))
1669  goto error;
1670  ldns_rr_set_rdf(rr, rdf, 1);
1671 
1672  if (!(rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, hash)))
1673  goto error;
1674  ldns_rr_set_rdf(rr, rdf, 2);
1675 
1676  if (!(data = LDNS_XMALLOC(uint8_t, md_len)))
1677  goto error;
1678 
1679  if (!(rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, md_len, data)))
1680  goto error;
1681  ldns_rr_set_rdf(rr, rdf, 3);
1682 
1683  return rr;
1684 error:
1685  if (data)
1686  LDNS_FREE(data);
1687  ldns_rr_free(rr);
1688  return NULL;
1689 }
1690 
1691 static ldns_rr_list *
1692 zone_digester_export(
1693  zone_digester *zd, ldns_rr *soa, ldns_status *ret_st)
1694 {
1696  ldns_rr_list *rr_list = NULL;
1697  ldns_rr *sha384 = NULL;
1698  ldns_rr *sha512 = NULL;
1699 
1700  if (!zd || !soa)
1701  st = LDNS_STATUS_NULL;
1702 
1703  else if (ldns_rr_get_type(soa) != LDNS_RR_TYPE_SOA
1704  || ldns_rr_rd_count(soa) < 3)
1706 
1707  else if (!(rr_list = ldns_rr_list_new()))
1708  st = LDNS_STATUS_MEM_ERR;
1709 
1710  else if (zd->simple_sha384
1711  && !(sha384 = new_zonemd(soa, ZONEMD_HASH_SHA384)))
1712  st = LDNS_STATUS_MEM_ERR;
1713 
1714  else if (zd->simple_sha512
1715  && !(sha512 = new_zonemd(soa, ZONEMD_HASH_SHA512)))
1716  st = LDNS_STATUS_MEM_ERR;
1717 
1718  else if (zd->simple_sha384
1719  && !ldns_rr_list_push_rr(rr_list, sha384))
1720  st = LDNS_STATUS_MEM_ERR;
1721 
1722  else if (zd->simple_sha512
1723  && !ldns_rr_list_push_rr(rr_list, sha512)) {
1724  if (zd->simple_sha384)
1725  sha384 = NULL; /* deleted by ldns_rr_list_deep_free */
1726  st = LDNS_STATUS_MEM_ERR;
1727 
1728  } else {
1729  if (sha384)
1731  , &zd->sha384_CTX);
1732  if (sha512)
1734  , &zd->sha512_CTX);
1735  return rr_list;
1736  }
1737  if (ret_st)
1738  *ret_st = st;
1739  if (sha384)
1740  ldns_rr_free(sha384);
1741  if (sha512)
1742  ldns_rr_free(sha512);
1743  if (rr_list)
1744  ldns_rr_list_deep_free(rr_list);
1745  return NULL;
1746 }
1747 
1748 static ldns_status
1749 ldns_digest_zone(ldns_dnssec_zone *zone, zone_digester *zd)
1750 {
1752  dnssec_zone_rr_iter rr_iter;
1753  ldns_rr *rr;
1754  ldns_rdf *apex_name; /* name of zone apex */
1755 
1756  if (!zone || !zd || !zone->soa || !zone->soa->name)
1757  return LDNS_STATUS_NULL;
1758 
1759  apex_name = zone->soa->name;
1760  for ( rr = dnssec_zone_rr_iter_first(&rr_iter, zone)
1761  ; rr && !st
1762  ; rr = dnssec_zone_rr_iter_next(&rr_iter)) {
1763  /* Skip apex ZONEMD RRs */
1765  && !ldns_dname_compare(ldns_rr_owner(rr), apex_name))
1766  continue;
1767  /* Skip RRSIGs for apex ZONEMD RRs */
1771  && !ldns_dname_compare(ldns_rr_owner(rr), apex_name))
1772  continue;
1773  st = zone_digester_update(zd, rr);
1774  }
1775  return st;
1776 }
1777 
1780 {
1781  ldns_dnssec_rrsets *zonemd, *soa;
1782  zone_digester zd;
1783  ldns_dnssec_rrs *rrs;
1784  ldns_rr *soa_rr;
1785  ldns_status st;
1788  size_t valid_zonemds;
1789 
1790  if (!zone)
1791  return LDNS_STATUS_NULL;
1792 
1793  zonemd = ldns_dnssec_zone_find_rrset(
1794  zone, zone->soa->name, LDNS_RR_TYPE_ZONEMD);
1795  if (!zonemd) {
1796  ldns_rbnode_t *nsec3_node;
1797 
1798  /* we need proof of non-existence for ZONEMD at the apex */
1799  if (zone->soa->nsec) {
1801  zone->soa->nsec),
1803  return LDNS_STATUS_NO_ZONEMD;
1804 
1805  } else if (!zone->soa->hashed_name || !zone->hashed_names)
1806  return LDNS_STATUS_NO_ZONEMD;
1807 
1808  else if (LDNS_RBTREE_NULL ==
1809  (nsec3_node = ldns_rbtree_search( zone->hashed_names
1810  , zone->soa->hashed_name)))
1811  return LDNS_STATUS_NO_ZONEMD;
1812  else {
1813  ldns_dnssec_name *nsec3
1814  = (ldns_dnssec_name *)nsec3_node->data;
1816  nsec3->nsec),
1818  return LDNS_STATUS_NO_ZONEMD;
1819  }
1820  /* ZONEMD at apex does really not exist */
1821  return LDNS_STATUS_OK;
1822  }
1824  zone, zone->soa->name, LDNS_RR_TYPE_SOA);
1825  if (!soa || !soa->rrs || !soa->rrs->rr)
1827 
1828  soa_rr = soa->rrs->rr;
1829  if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
1830  || ldns_rr_rd_count(soa_rr) < 3)
1832 
1833  zone_digester_init(&zd);
1834  for (rrs = zonemd->rrs; rrs; rrs = rrs->next) {
1835  if (!rrs->rr
1837  || ldns_rr_rd_count(rrs->rr) < 4)
1838  continue;
1839 
1840  /* serial should match SOA's serial */
1841  if (ldns_rdf2native_int32(ldns_rr_rdf(soa_rr, 2))
1842  != ldns_rdf2native_int32(ldns_rr_rdf(rrs->rr, 0)))
1843  continue;
1844 
1845  /* Add (scheme, hash) to digester */
1846  zone_digester_add(&zd,
1848  ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr, 2)));
1849  }
1850  if (!zone_digester_set(&zd))
1852 
1853  if ((st = ldns_digest_zone(zone, &zd)))
1854  return st;
1855 
1856  if (zd.simple_sha384)
1858  if (zd.simple_sha512)
1860 
1861  valid_zonemds = 0;
1862  for (rrs = zonemd->rrs; rrs; rrs = rrs->next) {
1863  if (!rrs->rr
1865  || ldns_rr_rd_count(rrs->rr) < 4)
1866  continue;
1867 
1868  /* serial should match SOA's serial */
1869  if (ldns_rdf2native_int32(ldns_rr_rdf(soa_rr, 2))
1870  != ldns_rdf2native_int32(ldns_rr_rdf(rrs->rr, 0)))
1871  continue;
1872 
1873  if (ZONEMD_SCHEME_SIMPLE !=
1875  continue;
1876 
1877  if (ZONEMD_HASH_SHA384
1878  == ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr,2))
1880  == ldns_rdf_size(ldns_rr_rdf(rrs->rr, 3))
1881  && memcmp( simple_sha384
1882  , ldns_rdf_data(ldns_rr_rdf(rrs->rr, 3))
1883  , LDNS_SHA384_DIGEST_LENGTH) == 0)
1884 
1885  valid_zonemds += 1;
1886 
1887  if (ZONEMD_HASH_SHA512
1888  == ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr,2))
1890  == ldns_rdf_size(ldns_rr_rdf(rrs->rr, 3))
1891  && memcmp( simple_sha512
1892  , ldns_rdf_data(ldns_rr_rdf(rrs->rr, 3))
1893  , LDNS_SHA512_DIGEST_LENGTH) == 0)
1894 
1895  valid_zonemds += 1;
1896  }
1897  return valid_zonemds ? LDNS_STATUS_OK : LDNS_STATUS_NO_VALID_ZONEMD;
1898 }
1899 
1900 #ifdef HAVE_SSL
1901 static ldns_status
1902 rr_list2dnssec_rrs(ldns_rr_list *rr_list, ldns_dnssec_rrs **rrs,
1903  ldns_rr_list *new_rrs)
1904 {
1905  ldns_rr *rr = NULL;
1906 
1907  if (!rr_list || !rrs)
1908  return LDNS_STATUS_NULL;
1909 
1910  if (ldns_rr_list_rr_count(rr_list) == 0)
1911  return LDNS_STATUS_OK;
1912 
1913  if (!*rrs) {
1914  if (!(*rrs = ldns_dnssec_rrs_new()))
1915  return LDNS_STATUS_MEM_ERR;
1916  (*rrs)->rr = ldns_rr_list_pop_rr(rr_list);
1917  if (new_rrs)
1918  ldns_rr_list_push_rr(new_rrs, (*rrs)->rr);
1919  }
1920  while ((rr = ldns_rr_list_pop_rr(rr_list))) {
1921  ldns_status st;
1922 
1923  if ((st = ldns_dnssec_rrs_add_rr(*rrs, rr))) {
1924  ldns_rr_list_push_rr(rr_list, rr);
1925  return st;
1926  } else if (new_rrs)
1927  ldns_rr_list_push_rr(new_rrs, rr);
1928  }
1929  return LDNS_STATUS_OK;
1930 }
1931 
1932 
1935  ldns_rr_list *new_rrs, ldns_key_list *key_list, int signflags);
1938  ldns_rr_list *new_rrs, ldns_key_list *key_list, int signflags)
1939 {
1941  zone_digester zd;
1942  ldns_rr_list *zonemd_rr_list = NULL;
1943  ldns_rr_list *zonemd_rrsigs = NULL;
1944  ldns_dnssec_rrsets *soa_rrset;
1945  ldns_rr *soa_rr = NULL;
1946  ldns_dnssec_rrsets **rrset_ref;
1947  ldns_dnssec_rrsets *zonemd_rrset;
1948 
1949  zone_digester_init(&zd);
1950  if (signflags & LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA384)
1951  zone_digester_add(&zd, ZONEMD_SCHEME_SIMPLE
1952  , ZONEMD_HASH_SHA384);
1953 
1954  if (signflags & LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA512)
1955  zone_digester_add(&zd, ZONEMD_SCHEME_SIMPLE
1956  , ZONEMD_HASH_SHA512);
1957 
1958  if ((st = ldns_digest_zone(zone, &zd)))
1959  return st;
1960 
1961  soa_rrset = ldns_dnssec_zone_find_rrset(
1962  zone, zone->soa->name, LDNS_RR_TYPE_SOA);
1963  if (!soa_rrset || !soa_rrset->rrs || !soa_rrset->rrs->rr)
1965  soa_rr = soa_rrset->rrs->rr;
1966 
1967  if (!(zonemd_rr_list = zone_digester_export(&zd, soa_rr, &st)))
1968  return st;
1969 
1970  /* - replace or add ZONEMD rrset */
1971  rrset_ref = &zone->soa->rrsets; /* scan rrsets at apex */
1972  while (*rrset_ref && (*rrset_ref)->type < LDNS_RR_TYPE_ZONEMD)
1973  rrset_ref = &(*rrset_ref)->next;
1974  if (*rrset_ref && (*rrset_ref)->type == LDNS_RR_TYPE_ZONEMD) {
1975  /* reuse zonemd rrset */
1976  zonemd_rrset = *rrset_ref;
1977  ldns_dnssec_rrs_free(zonemd_rrset->rrs);
1978  zonemd_rrset->rrs = NULL;
1979  ldns_dnssec_rrs_free(zonemd_rrset->signatures);
1980  zonemd_rrset->signatures = NULL;
1981  } else {
1982  /* insert zonemd rrset */
1983  zonemd_rrset = ldns_dnssec_rrsets_new();
1984  if (!zonemd_rrset) {
1985  ldns_rr_list_deep_free(zonemd_rr_list);
1986  return LDNS_STATUS_MEM_ERR;
1987  }
1988  zonemd_rrset->type = LDNS_RR_TYPE_ZONEMD;
1989  zonemd_rrset->next = *rrset_ref;
1990  *rrset_ref = zonemd_rrset;
1991  }
1992  if ((zonemd_rrsigs = ldns_sign_public(zonemd_rr_list, key_list)))
1993  st = rr_list2dnssec_rrs( zonemd_rrsigs
1994  , &zonemd_rrset->signatures, new_rrs);
1995  if (!st)
1996  st = rr_list2dnssec_rrs( zonemd_rr_list
1997  , &zonemd_rrset->rrs, new_rrs);
1998  ldns_rr_list_deep_free(zonemd_rr_list);
1999  ldns_rr_list_deep_free(zonemd_rrsigs);
2000  return st;
2001 }
2002 
2003 #endif /* HAVE_SSL */
2004 
#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
signed char 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
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_rdf * ldns_dname_label(const ldns_rdf *rdf, uint8_t labelpos)
look inside the rdf and if it is an LDNS_RDF_TYPE_DNAME try and retrieve a specific label.
Definition: dname.c:560
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
signed char 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:1395
signed char 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:1288
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:1370
ldns_rr_list * ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
Sign an rrset.
Definition: dnssec_sign.c:227
#define LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA384
Definition: dnssec_sign.h:18
#define LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA512
Definition: dnssec_sign.h:19
ldns_status ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone **z, FILE *fp, const ldns_rdf *origin, uint32_t default_ttl, ldns_rr_class c __attribute__((unused)), int *line_nr)
Definition: dnssec_zone.c:610
void ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets)
Frees the list of rrsets and their rrs, but not the ldns_rr records in the sets.
Definition: dnssec_zone.c:135
void ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_dnssec_zone *zone)
Prints the complete zone to the given file descriptor.
Definition: dnssec_zone.c:1094
struct dnssec_zone_rr_iter dnssec_zone_rr_iter
void ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_rbtree_t *tree, signed char print_soa)
Prints the rbtree of ldns_dnssec_name structures to the file descriptor.
Definition: dnssec_zone.c:1069
ldns_status ldns_dnssec_zone_verify_zonemd(ldns_dnssec_zone *zone)
Definition: dnssec_zone.c:1779
ldns_dnssec_rrsets * ldns_dnssec_zone_find_rrset(const ldns_dnssec_zone *zone, const ldns_rdf *dname, ldns_rr_type type)
Find the RRset with the given name and type in the zone.
Definition: dnssec_zone.c:510
enum_zonemd_scheme
Definition: dnssec_zone.c:1543
@ ZONEMD_SCHEME_SIMPLE
Definition: dnssec_zone.c:1545
@ ZONEMD_SCHEME_FIRST
Definition: dnssec_zone.c:1544
@ ZONEMD_SCHEME_LAST
Definition: dnssec_zone.c:1546
void ldns_dnssec_name_set_nsec(ldns_dnssec_name *rrset, ldns_rr *nsec)
Sets the NSEC(3) RR of the given dnssec_name structure.
Definition: dnssec_zone.c:424
void ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs)
Frees the list of rrs, and the individual ldns_rr records contained in the list.
Definition: dnssec_zone.c:41
void ldns_dnssec_name_set_name(ldns_dnssec_name *rrset, ldns_rdf *dname)
Sets the domain name of the given dnssec_name structure.
Definition: dnssec_zone.c:414
ldns_status ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr)
Adds an RR to the list of RRs.
Definition: dnssec_zone.c:47
ldns_status dnssec_zone_equip_zonemd(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int signflags)
Definition: dnssec_zone.c:1937
void ldns_dnssec_zone_print(FILE *out, const ldns_dnssec_zone *zone)
Prints the complete zone to the given file descriptor.
Definition: dnssec_zone.c:1122
void ldns_dnssec_name_deep_free(ldns_dnssec_name *name)
Frees the name structure and its rrs and rrsets.
Definition: dnssec_zone.c:390
void ldns_dnssec_rrsets_print(FILE *out, const ldns_dnssec_rrsets *rrsets, signed char follow)
Print the given list of rrsets to the given file descriptor.
Definition: dnssec_zone.c:311
void ldns_dnssec_name_free(ldns_dnssec_name *name)
Frees the name structure and its rrs and rrsets.
Definition: dnssec_zone.c:384
ldns_dnssec_name * ldns_dnssec_name_new(void)
Create a new data structure for a dnssec name.
Definition: dnssec_zone.c:318
ldns_status ldns_dnssec_name_add_rr(ldns_dnssec_name *name, ldns_rr *rr)
Inserts the given rr at the right place in the current dnssec_name No checking is done whether the na...
Definition: dnssec_zone.c:450
void ldns_dnssec_zone_names_print(FILE *out, const ldns_rbtree_t *tree, signed char print_soa)
Prints the rbtree of ldns_dnssec_name structures to the file descriptor.
Definition: dnssec_zone.c:1087
void ldns_dnssec_rrs_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_dnssec_rrs *rrs)
Prints the given rrs to the file descriptor.
Definition: dnssec_zone.c:81
ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
Adds the given RR to the zone.
Definition: dnssec_zone.c:1015
ldns_status ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr)
Add an ldns_rr to the corresponding RRset in the given list of RRsets.
Definition: dnssec_zone.c:194
void ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs)
Frees the list of rrs, but not the individual ldns_rr records contained in the list.
Definition: dnssec_zone.c:35
ldns_dnssec_name * ldns_dnssec_name_new_frm_rr(ldns_rr *rr)
Create a new data structure for a dnssec name for the given RR.
Definition: dnssec_zone.c:343
ldns_status ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone **z, FILE *fp, const ldns_rdf *origin, uint32_t ttl, ldns_rr_class c __attribute__((unused)))
Definition: dnssec_zone.c:851
ldns_dnssec_rrsets * ldns_dnssec_rrsets_new(void)
Creates a new list (entry) of RRsets.
Definition: dnssec_zone.c:105
ldns_status ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
Adds explicit dnssec_name structures for the empty nonterminals in this zone.
Definition: dnssec_zone.c:1267
ldns_rdf * ldns_dnssec_name_name(const ldns_dnssec_name *name)
Returns the domain name of the given dnssec_name structure.
Definition: dnssec_zone.c:396
signed char ldns_dnssec_name_is_glue(const ldns_dnssec_name *name)
Returns if dnssec_name structure is marked as glue.
Definition: dnssec_zone.c:405
void ldns_dnssec_zone_free(ldns_dnssec_zone *zone)
Frees the given zone structure, and its rbtree of dnssec_names Individual ldns_rr RRs within those na...
Definition: dnssec_zone.c:878
signed char ldns_dnssec_zone_is_nsec3_optout(const ldns_dnssec_zone *zone)
If a NSEC3PARAM is available in the apex, walks the zone and returns true on the first optout nsec3.
Definition: dnssec_zone.c:1273
void ldns_dnssec_rrs_print(FILE *out, const ldns_dnssec_rrs *rrs)
Prints the given rrs to the file descriptor.
Definition: dnssec_zone.c:98
enum enum_zonemd_hash zonemd_hash
Definition: dnssec_zone.c:1556
void ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets)
Frees the list of rrsets and their rrs, and the ldns_rr records in the sets.
Definition: dnssec_zone.c:141
void ldns_dnssec_name_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_dnssec_name *name)
Prints the RRs in the dnssec name structure to the given file descriptor.
Definition: dnssec_zone.c:557
ldns_dnssec_rrs * ldns_dnssec_rrs_new(void)
Creates a new entry for 1 pointer to an rr and 1 pointer to the next rrs.
Definition: dnssec_zone.c:10
enum_zonemd_hash
Definition: dnssec_zone.c:1550
@ ZONEMD_HASH_SHA512
Definition: dnssec_zone.c:1553
@ ZONEMD_HASH_LAST
Definition: dnssec_zone.c:1554
@ ZONEMD_HASH_SHA384
Definition: dnssec_zone.c:1552
@ ZONEMD_HASH_FIRST
Definition: dnssec_zone.c:1551
enum enum_zonemd_scheme zonemd_scheme
Definition: dnssec_zone.c:1548
void ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone)
Frees the given zone structure, and its rbtree of dnssec_names Individual ldns_rr RRs within those na...
Definition: dnssec_zone.c:898
void ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_dnssec_rrsets *rrsets, signed char follow)
Print the given list of rrsets to the given file descriptor.
Definition: dnssec_zone.c:303
ldns_dnssec_rrsets * ldns_dnssec_name_find_rrset(const ldns_dnssec_name *name, ldns_rr_type type)
Find the RRset with the given type in within this name structure.
Definition: dnssec_zone.c:494
ldns_status ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets, ldns_rr_type type)
Sets the RR type of the rrset (that is head of the given list)
Definition: dnssec_zone.c:157
void ldns_dnssec_name_print(FILE *out, const ldns_dnssec_name *name)
Prints the RRs in the dnssec name structure to the given file descriptor.
Definition: dnssec_zone.c:564
int ldns_dname_compare_v(const void *a, const void *b)
Given in dnssec_zone.c, also used in dnssec_sign.c:w.
Definition: dnssec_zone.c:919
int ldns_dnssec_name_cmp(const void *a, const void *b)
Compares the domain names of the two arguments in their canonical ordering.
Definition: dnssec_zone.c:432
dnssec_zone_rr_iter_state
Definition: dnssec_zone.c:1296
@ DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC
Definition: dnssec_zone.c:1300
@ DNSSEC_ZONE_RR_ITER_LT_RRSIG
Definition: dnssec_zone.c:1297
@ DNSSEC_ZONE_RR_ITER_REST
Definition: dnssec_zone.c:1299
@ DNSSEC_ZONE_RR_ITER_FINI
Definition: dnssec_zone.c:1303
@ DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC_REST
Definition: dnssec_zone.c:1301
@ DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC
Definition: dnssec_zone.c:1298
@ DNSSEC_ZONE_RR_ITER_NSEC3
Definition: dnssec_zone.c:1302
ldns_dnssec_zone * ldns_dnssec_zone_new(void)
Creates a new dnssec_zone structure.
Definition: dnssec_zone.c:571
ldns_rr_type ldns_dnssec_rrsets_type(const ldns_dnssec_rrsets *rrsets)
Returns the rr type of the rrset (that is head of the given list)
Definition: dnssec_zone.c:147
@ LDNS_STATUS_EQUAL_RR
Definition: error.h:147
@ LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND
Definition: error.h:101
@ LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL
Definition: error.h:82
@ LDNS_STATUS_ZONEMD_UNKNOWN_SCHEME
Definition: error.h:134
@ LDNS_STATUS_ZONEMD_DOUBLE_OCCURRENCE
Definition: error.h:133
@ LDNS_STATUS_NULL
Definition: error.h:51
@ LDNS_STATUS_ERR
Definition: error.h:37
@ LDNS_STATUS_MEM_ERR
Definition: error.h:34
@ LDNS_STATUS_SYNTAX_TTL
Definition: error.h:88
@ LDNS_STATUS_NO_ZONEMD
Definition: error.h:137
@ LDNS_STATUS_ZONEMD_UNKNOWN_HASH
Definition: error.h:135
@ LDNS_STATUS_OK
Definition: error.h:26
@ LDNS_STATUS_SYNTAX_EMPTY
Definition: error.h:91
@ LDNS_STATUS_ZONEMD_INVALID_SOA
Definition: error.h:136
@ LDNS_STATUS_NO_VALID_ZONEMD
Definition: error.h:138
@ LDNS_STATUS_SYNTAX_INCLUDE
Definition: error.h:90
@ LDNS_STATUS_SYNTAX_ORIGIN
Definition: error.h:89
enum ldns_enum_status ldns_status
Definition: error.h:152
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:3454
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:3466
#define LDNS_COMMENT_LAYOUT
Print mark up.
Definition: host2str.h:62
ldns_status ldns_rr2buffer_wire_canonical(ldns_buffer *output, const ldns_rr *rr, int section)
Copies the rr data to the buffer in wire format, in canonical format according to RFC3597 (every dnam...
Definition: host2wire.c:171
Including this file will include all ldns files, and define some lookup tables.
@ LDNS_SECTION_ANSWER
Definition: packet.h:279
ldns_rbtree_t * ldns_rbtree_create(int(*cmpf)(const void *, const void *))
Create new tree (malloced) with given key compare function.
Definition: rbtree.c:80
ldns_rbnode_t * ldns_rbtree_next(ldns_rbnode_t *rbtree)
Returns next larger node in the tree.
Definition: rbtree.c:574
void ldns_traverse_postorder(ldns_rbtree_t *tree, void(*func)(ldns_rbnode_t *, void *), void *arg)
Call function for all elements in the redblack tree, such that leaf elements are called before parent...
Definition: rbtree.c:666
ldns_rbnode_t * ldns_rbtree_first(const ldns_rbtree_t *rbtree)
Returns first (smallest) node in the tree.
Definition: rbtree.c:548
#define LDNS_RBTREE_NULL
The nullpointer, points to empty node.
Definition: rbtree.h:76
ldns_rbnode_t * ldns_rbtree_search(ldns_rbtree_t *rbtree, const void *key)
Find key in tree.
Definition: rbtree.c:294
void ldns_rbtree_init(ldns_rbtree_t *rbtree, int(*cmpf)(const void *, const void *))
Init a new tree (malloced by caller) with given key compare function.
Definition: rbtree.c:97
ldns_rbnode_t * ldns_rbtree_insert(ldns_rbtree_t *rbtree, ldns_rbnode_t *data)
Insert data into the tree.
Definition: rbtree.c:242
ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd)
returns the type of the rdf.
Definition: rdata.c:31
ldns_rdf * ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value)
returns the rdf containing the native uint8_t repr.
Definition: rdata.c:126
void ldns_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
Definition: rdata.c:230
ldns_rdf * ldns_rdf_new(ldns_rdf_type type, size_t size, void *data)
allocates a new rdf structure and fills it.
Definition: rdata.c:179
uint32_t ldns_rdf2native_int32(const ldns_rdf *rd)
returns the native uint32_t representation from the rdf.
Definition: rdata.c:98
uint8_t ldns_rdf2native_int8(const ldns_rdf *rd)
returns the native uint8_t representation from the rdf.
Definition: rdata.c:70
@ LDNS_RDF_TYPE_INT32
32 bits
Definition: rdata.h:56
@ LDNS_RDF_TYPE_HEX
hex string
Definition: rdata.h:72
@ LDNS_RDF_TYPE_INT8
8 bits
Definition: rdata.h:52
size_t ldns_rdf_size(const ldns_rdf *rd)
returns the size of the rdf.
Definition: rdata.c:24
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
void ldns_rr_list_free(ldns_rr_list *rr_list)
frees an rr_list structure.
Definition: rr.c:1009
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:988
ldns_rr * ldns_rr_list_pop_rr(ldns_rr_list *rr_list)
pops the last rr from an rrlist.
Definition: rr.c:1175
uint32_t ldns_rr_ttl(const ldns_rr *rr)
returns the ttl of an rr structure.
Definition: rr.c:929
ldns_rdf * ldns_rr_owner(const ldns_rr *rr)
returns the owner name of an rr structure.
Definition: rr.c:917
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:2855
void ldns_rr_list_deep_free(ldns_rr_list *rr_list)
frees an rr_list structure and all rrs contained therein.
Definition: rr.c:1018
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
Definition: rr.c:81
void ldns_rr_set_owner(ldns_rr *rr, ldns_rdf *owner)
sets the owner in the rr structure.
Definition: rr.c:802
ldns_rr * ldns_rr_new_frm_type(ldns_rr_type t)
creates a new rr structure, based on the given type.
Definition: rr.c:48
enum ldns_enum_rr_type ldns_rr_type
Definition: rr.h:260
@ LDNS_RR_TYPE_RRSIG
DNSSEC.
Definition: rr.h:170
@ LDNS_RR_TYPE_ZONEMD
Definition: rr.h:194
@ LDNS_RR_TYPE_SOA
marks the start of a zone of authority
Definition: rr.h:90
@ LDNS_RR_TYPE_NSEC
Definition: rr.h:171
@ LDNS_RR_TYPE_NSEC3PARAM
Definition: rr.h:177
@ LDNS_RR_TYPE_SIG
2535typecode
Definition: rr.h:126
@ LDNS_RR_TYPE_NSEC3
Definition: rr.h:176
signed char ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr)
pushes an rr to an rrlist.
Definition: rr.c:1130
size_t ldns_rr_rd_count(const ldns_rr *rr)
returns the rd_count of an rr structure.
Definition: rr.c:935
ldns_rdf * ldns_rr_set_rdf(ldns_rr *rr, const ldns_rdf *f, size_t position)
sets a rdf member, it will be set on the position given.
Definition: rr.c:838
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:955
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition: rr.c:941
void ldns_rr_set_ttl(ldns_rr *rr, uint32_t ttl)
sets the ttl in the rr structure.
Definition: rr.c:814
ldns_rr_class ldns_rr_get_class(const ldns_rr *rr)
returns the class of the rr.
Definition: rr.c:947
enum ldns_enum_rr_class ldns_rr_class
Definition: rr.h:61
void ldns_rr_set_class(ldns_rr *rr, ldns_rr_class rr_class)
sets the class in the rr.
Definition: rr.c:832
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
Definition: rr.c:998
ldns_status ldns_rr_new_frm_fp_l(ldns_rr **rr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev, int *line_nr)
creates a new rr from a file containing a string.
Definition: rr.c:794
int ldns_rr_compare(const ldns_rr *rr1, const ldns_rr *rr2)
compares two rrs.
Definition: rr.c:1676
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
Definition: rr.c:907
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
void ldns_sha512_update(ldns_sha512_CTX *, const uint8_t *, size_t)
Definition: sha2.c:819
void ldns_sha384_init(ldns_sha384_CTX *)
Definition: sha2.c:952
void ldns_sha512_init(ldns_sha512_CTX *)
Definition: sha2.c:635
#define LDNS_SHA512_DIGEST_LENGTH
Definition: sha2.h:69
void ldns_sha512_final(uint8_t[64], ldns_sha512_CTX *)
Definition: sha2.c:912
#define LDNS_SHA384_DIGEST_LENGTH
Definition: sha2.h:66
void ldns_sha384_update(ldns_sha384_CTX *, const uint8_t *, size_t)
Definition: sha2.c:961
void ldns_sha384_final(uint8_t[48], ldns_sha384_CTX *)
Definition: sha2.c:965
ldns_dnssec_name * nsec3_name
Definition: dnssec_zone.c:1314
dnssec_zone_rr_iter_state state
Definition: dnssec_zone.c:1315
ldns_rdf * apex_name
Definition: dnssec_zone.c:1316
ldns_dnssec_name * name
Definition: dnssec_zone.c:1309
ldns_dnssec_rrsets * rrsets4rrsigs
Definition: dnssec_zone.c:1312
ldns_dnssec_zone * zone
Definition: dnssec_zone.c:1307
ldns_rbnode_t * nsec3_node
Definition: dnssec_zone.c:1313
ldns_rbnode_t * node
Definition: dnssec_zone.c:1308
ldns_dnssec_rrs * rrs
Definition: dnssec_zone.c:1311
ldns_dnssec_rrsets * rrsets
Definition: dnssec_zone.c:1310
The rbnode_t struct definition.
Definition: rbtree.h:60
const void * data
pointer to data
Definition: rbtree.h:70
const void * key
pointer to sorting key
Definition: rbtree.h:68
definition for tree struct
Definition: rbtree.h:83
size_t count
The number of the nodes in the tree.
Definition: rbtree.h:88
implementation of buffers to ease operations
Definition: buffer.h:51
size_t _capacity
The amount of data the buffer can contain.
Definition: buffer.h:59
unsigned _fixed
If the buffer is fixed it cannot be resized.
Definition: buffer.h:65
size_t _position
The current position used for reading/writing.
Definition: buffer.h:53
ldns_status _status
The current state of the buffer.
Definition: buffer.h:70
uint8_t * _data
The data contained in the buffer.
Definition: buffer.h:62
size_t _limit
The read/write limit.
Definition: buffer.h:56
ldns_dnssec_rrs * nsec_signatures
signatures for the NSEC record
Definition: dnssec_zone.h:71
ldns_rr * nsec
NSEC pointing to the next name (or NSEC3 pointing to the next NSEC3)
Definition: dnssec_zone.h:67
signed char name_alloced
Usually, the name is a pointer to the owner name of the first rr for this name, but sometimes there i...
Definition: dnssec_zone.h:59
ldns_rdf * hashed_name
pointer to store the hashed name (only used when in an NSEC3 zone
Definition: dnssec_zone.h:85
ldns_dnssec_rrsets * rrsets
The rrsets for this name.
Definition: dnssec_zone.h:63
signed char is_glue
Unlike what the name is_glue suggests, this field is set to true by ldns_dnssec_zone_mark_glue() or l...
Definition: dnssec_zone.h:81
ldns_rdf * name
pointer to a dname containing the name.
Definition: dnssec_zone.h:51
ldns_dnssec_rrs * next
Definition: dnssec_zone.h:25
ldns_dnssec_rrs * rrs
Definition: dnssec_zone.h:34
ldns_dnssec_rrs * signatures
Definition: dnssec_zone.h:36
ldns_dnssec_rrsets * next
Definition: dnssec_zone.h:37
Structure containing a dnssec zone.
Definition: dnssec_zone.h:91
ldns_rbtree_t * hashed_names
tree of ldns_dnssec_names by nsec3 hashes (when applicable)
Definition: dnssec_zone.h:97
ldns_rbtree_t * names
tree of ldns_dnssec_names
Definition: dnssec_zone.h:95
ldns_rr * _nsec3params
points to the first added NSEC3 rr whose parameters will be assumed for all subsequent NSEC3 rr's and...
Definition: dnssec_zone.h:102
ldns_dnssec_name * soa
points to the name containing the SOA RR
Definition: dnssec_zone.h:93
Same as rr_list, but now for keys.
Definition: keys.h:173
Output format specifier.
Definition: host2str.h:89
int flags
Specification of how RR's should be formatted in text.
Definition: host2str.h:91
Resource record data field.
Definition: rdata.h:203
List or Set of Resource Records.
Definition: rr.h:355
Resource Record.
Definition: rr.h:327
DNS Zone.
Definition: zone.h:43
ldns_sha512_CTX sha512_CTX
Definition: dnssec_zone.c:1560
ldns_sha384_CTX sha384_CTX
Definition: dnssec_zone.c:1559
#define INLINE
splint static inline workaround
Definition: util.h:42
#define LDNS_FREE(ptr)
Definition: util.h:60
#define LDNS_CALLOC(type, count)
Definition: util.h:53
#define LDNS_MALLOC(type)
Memory management macros.
Definition: util.h:49
#define LDNS_XMALLOC(type, count)
Definition: util.h:51
ldns_rr_list * ldns_zone_rrs(const ldns_zone *z)
Get a list of a zone's content.
Definition: zone.c:35
ldns_rr * ldns_zone_soa(const ldns_zone *z)
Return the soa record of a zone.
Definition: zone.c:17
void ldns_zone_free(ldns_zone *zone)
Frees the allocated memory for the zone, and the rr_list structure in it.
Definition: zone.c:369
ldns_status ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, const ldns_rdf *origin, uint32_t ttl, ldns_rr_class c, int *line_nr)
Create a new zone from a file, keep track of the line numbering.