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