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 
609  uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev,
610  int *line_nr, bool *explicit_ttl);
611 
614  uint32_t default_ttl, ldns_rr_class ATTR_UNUSED(c), int* line_nr)
615 {
616  ldns_rr* cur_rr;
617  size_t i;
618 
619  ldns_rdf *my_origin = NULL;
620  ldns_rdf *my_prev = NULL;
621 
623  /* NSEC3s may occur before the names they refer to. We must remember
624  them and add them to the name later on, after the name is read.
625  We track not yet matching NSEC3s*n the todo_nsec3s list */
626  ldns_rr_list* todo_nsec3s = ldns_rr_list_new();
627  /* when reading NSEC3s, there is a chance that we encounter nsecs
628  for empty nonterminals, whose nonterminals we cannot derive yet
629  because the needed information is to be read later.
630 
631  nsec3_ents (where ent is e.n.t.; i.e. empty non terminal) will
632  hold the NSEC3s that still didn't have a matching name in the
633  zone tree, even after all names were read. They can only match
634  after the zone is equipped with all the empty non terminals. */
635  ldns_rbtree_t todo_nsec3_ents;
636  ldns_rbnode_t *new_node;
637  ldns_rr_list* todo_nsec3_rrsigs = ldns_rr_list_new();
638 
639  ldns_status status;
640 
641 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
642  ldns_zone* zone = NULL;
643 #else
644  ldns_rr *prev_rr = NULL;
645  uint32_t my_ttl = default_ttl;
646  /* RFC 1035 Section 5.1, says 'Omitted class and TTL values are default
647  * to the last explicitly stated values.'
648  */
649  bool ttl_from_TTL = false;
650  bool explicit_ttl = false;
651 #endif
652 
653  ldns_rbtree_init(&todo_nsec3_ents, ldns_dname_compare_v);
654 
655 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
656  status = ldns_zone_new_frm_fp_l(&zone, fp, origin, default_ttl, c, line_nr);
657  if (status != LDNS_STATUS_OK)
658  goto error;
659 #endif
660  if (!newzone || !todo_nsec3s || !todo_nsec3_rrsigs ) {
661  status = LDNS_STATUS_MEM_ERR;
662  goto error;
663  }
664  if (origin) {
665  if (!(my_origin = ldns_rdf_clone(origin))) {
666  status = LDNS_STATUS_MEM_ERR;
667  goto error;
668  }
669  if (!(my_prev = ldns_rdf_clone(origin))) {
670  status = LDNS_STATUS_MEM_ERR;
671  goto error;
672  }
673  }
674 
675 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
676  if (ldns_zone_soa(zone)) {
677  status = ldns_dnssec_zone_add_rr(newzone, ldns_zone_soa(zone));
678  if (status != LDNS_STATUS_OK)
679  goto error;
680  }
681  for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
682  cur_rr = ldns_rr_list_rr(ldns_zone_rrs(zone), i);
683  status = LDNS_STATUS_OK;
684 #else
685  while (!feof(fp)) {
686  /* If ttl came from $TTL line, then it should be the default.
687  * (RFC 2308 Section 4)
688  * Otherwise it "defaults to the last explicitly stated value"
689  * (RFC 1035 Section 5.1)
690  */
691  if (ttl_from_TTL)
692  my_ttl = default_ttl;
693  status = ldns_rr_new_frm_fp_l(&cur_rr, fp, &my_ttl, &my_origin,
694  &my_prev, line_nr, &explicit_ttl);
695 #endif
696  switch (status) {
697  case LDNS_STATUS_OK:
698 #ifndef FASTER_DNSSEC_ZONE_NEW_FRM_FP
699  if (explicit_ttl) {
700  if (!ttl_from_TTL) {
701  /* No $TTL, so ttl "defaults to the
702  * last explicitly stated value"
703  * (RFC 1035 Section 5.1)
704  */
705  my_ttl = ldns_rr_ttl(cur_rr);
706  }
707  /* When ttl is implicit, try to adhere to the rules as
708  * much as possible. (also for compatibility with bind)
709  * This was changed when fixing an issue with ZONEMD
710  * which hashes the TTL too.
711  */
712  } else if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SIG
713  || ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_RRSIG) {
714  if (ldns_rr_rd_count(cur_rr) >= 4
716 
717  /* SIG without explicit ttl get ttl
718  * from the original_ttl field
719  * (RFC 2535 Section 7.2)
720  *
721  * Similarly for RRSIG, but stated less
722  * specifically in the spec.
723  * (RFC 4034 Section 3)
724  */
725  ldns_rr_set_ttl(cur_rr,
727  ldns_rr_rdf(rr, 3)));
728 
729  } else if (prev_rr
730  && ldns_rr_get_type(prev_rr) == ldns_rr_get_type(cur_rr)
731  && ldns_dname_compare( ldns_rr_owner(prev_rr)
732  , ldns_rr_owner(cur_rr)) == 0)
733 
734  /* "TTLs of all RRs in an RRSet must be the same"
735  * (RFC 2881 Section 5.2)
736  */
737  ldns_rr_set_ttl(cur_rr, ldns_rr_ttl(prev_rr));
738 
739  prev_rr = cur_rr;
740 #endif
741  status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
742  if (status ==
744 
745  if (rr_is_rrsig_covering(cur_rr,
747  ldns_rr_list_push_rr(todo_nsec3_rrsigs,
748  cur_rr);
749  } else {
750  ldns_rr_list_push_rr(todo_nsec3s,
751  cur_rr);
752  }
753  status = LDNS_STATUS_OK;
754 
755  } else if (status != LDNS_STATUS_OK)
756  goto error;
757 
758  break;
759 
760  case LDNS_STATUS_SYNTAX_TTL: /* the ttl was set*/
761 #ifndef FASTER_DNSSEC_ZONE_NEW_FRM_FP
762  default_ttl = my_ttl;
763  ttl_from_TTL = true;
764 #endif
765  status = LDNS_STATUS_OK;
766  break;
767 
768 
769  case LDNS_STATUS_SYNTAX_EMPTY: /* empty line was seen */
770  case LDNS_STATUS_SYNTAX_ORIGIN: /* the origin was set*/
771  status = LDNS_STATUS_OK;
772  break;
773 
774  case LDNS_STATUS_SYNTAX_INCLUDE:/* $include not implemented */
776  break;
777 
778  default:
779  goto error;
780  }
781  }
782 
783  for (i = 0; status == LDNS_STATUS_OK &&
784  i < ldns_rr_list_rr_count(todo_nsec3s); i++) {
785  cur_rr = ldns_rr_list_rr(todo_nsec3s, i);
786  status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
788  if (!(new_node = LDNS_MALLOC(ldns_rbnode_t))) {
789  status = LDNS_STATUS_MEM_ERR;
790  break;
791  }
792  new_node->key = ldns_dname_label(ldns_rr_owner(cur_rr), 0);
793  new_node->data = cur_rr;
794  if (!ldns_rbtree_insert(&todo_nsec3_ents, new_node)) {
795  LDNS_FREE(new_node);
796  status = LDNS_STATUS_MEM_ERR;
797  break;
798  }
799  status = LDNS_STATUS_OK;
800  }
801  }
802  if (todo_nsec3_ents.count > 0)
803  (void) ldns_dnssec_zone_add_empty_nonterminals_nsec3(
804  newzone, &todo_nsec3_ents);
805  for (i = 0; status == LDNS_STATUS_OK &&
806  i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++) {
807  cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
808  status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
809  }
810  if (z) {
811  *z = newzone;
812  newzone = NULL;
813  } else {
814  ldns_dnssec_zone_free(newzone);
815  newzone = NULL;
816  }
817 
818 error:
819 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
820  if (zone) {
821  ldns_zone_free(zone);
822  }
823 #endif
824  ldns_rr_list_free(todo_nsec3_rrsigs);
825  ldns_traverse_postorder(&todo_nsec3_ents,
826  ldns_todo_nsec3_ents_node_free, NULL);
827  ldns_rr_list_free(todo_nsec3s);
828 
829  if (my_origin) {
830  ldns_rdf_deep_free(my_origin);
831  }
832  if (my_prev) {
833  ldns_rdf_deep_free(my_prev);
834  }
835  if (newzone) {
836  ldns_dnssec_zone_free(newzone);
837  }
838  return status;
839 }
840 
843  uint32_t ttl, ldns_rr_class ATTR_UNUSED(c))
844 {
845  return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
846 }
847 
848 static void
849 ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) {
850  (void) arg;
852  LDNS_FREE(node);
853 }
854 
855 static void
856 ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) {
857  (void) arg;
859  LDNS_FREE(node);
860 }
861 
862 static void
863 ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
864  (void) arg;
865  LDNS_FREE(node);
866 }
867 
868 void
870 {
871  if (zone) {
872  if (zone->hashed_names) {
874  ldns_hashed_names_node_free, NULL);
875  LDNS_FREE(zone->hashed_names);
876  }
877  if (zone->names) {
878  /* destroy all name structures within the tree */
880  ldns_dnssec_name_node_free,
881  NULL);
882  LDNS_FREE(zone->names);
883  }
884  LDNS_FREE(zone);
885  }
886 }
887 
888 void
890 {
891  if (zone) {
892  if (zone->hashed_names) {
894  ldns_hashed_names_node_free, NULL);
895  LDNS_FREE(zone->hashed_names);
896  }
897  if (zone->names) {
898  /* destroy all name structures within the tree */
900  ldns_dnssec_name_node_deep_free,
901  NULL);
902  LDNS_FREE(zone->names);
903  }
904  LDNS_FREE(zone);
905  }
906 }
907 
908 /* use for dname comparison in tree */
909 int
910 ldns_dname_compare_v(const void *a, const void *b) {
911  return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b);
912 }
913 
914 static void
915 ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
916  ldns_dnssec_name* name, ldns_rr* nsec3rr);
917 
918 static void
919 ldns_dnssec_zone_hashed_names_from_nsec3(
920  ldns_dnssec_zone* zone, ldns_rr* nsec3rr)
921 {
922  ldns_rbnode_t* current_node;
923  ldns_dnssec_name* current_name;
924 
925  assert(zone != NULL);
926  assert(nsec3rr != NULL);
927 
928  if (zone->hashed_names) {
930  ldns_hashed_names_node_free, NULL);
931  LDNS_FREE(zone->hashed_names);
932  }
933  zone->_nsec3params = nsec3rr;
934 
935  /* So this is a NSEC3 zone.
936  * Calculate hashes for all names already in the zone
937  */
939  if (zone->hashed_names == NULL) {
940  return;
941  }
942  for ( current_node = ldns_rbtree_first(zone->names)
943  ; current_node != LDNS_RBTREE_NULL
944  ; current_node = ldns_rbtree_next(current_node)
945  ) {
946  current_name = (ldns_dnssec_name *) current_node->data;
947  ldns_dnssec_name_make_hashed_name(zone, current_name, nsec3rr);
948 
949  }
950 }
951 
952 static void
953 ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
954  ldns_dnssec_name* name, ldns_rr* nsec3rr)
955 {
956  ldns_rbnode_t* new_node;
957 
958  assert(name != NULL);
959  if (! zone->_nsec3params) {
960  if (! nsec3rr) {
961  return;
962  }
963  ldns_dnssec_zone_hashed_names_from_nsec3(zone, nsec3rr);
964 
965  } else if (! nsec3rr) {
966  nsec3rr = zone->_nsec3params;
967  }
968  name->hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsec3rr, name->name);
969 
970  /* Also store in zone->hashed_names */
971  if ((new_node = LDNS_MALLOC(ldns_rbnode_t))) {
972 
973  new_node->key = name->hashed_name;
974  new_node->data = name;
975 
976  if (ldns_rbtree_insert(zone->hashed_names, new_node) == NULL) {
977 
978  LDNS_FREE(new_node);
979  }
980  }
981 }
982 
983 
984 static ldns_rbnode_t *
985 ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, ldns_rr *rr) {
986  ldns_rdf *hashed_name;
987  ldns_rbnode_t *to_return;
988 
989  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 && ! zone->_nsec3params){
990 
991  ldns_dnssec_zone_hashed_names_from_nsec3(zone, rr);
992  }
993  if (zone->hashed_names == NULL) {
994  return NULL;
995  }
996  hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
997  if (hashed_name == NULL) {
998  return NULL;
999  }
1000  to_return = ldns_rbtree_search(zone->hashed_names, hashed_name);
1001  ldns_rdf_deep_free(hashed_name);
1002  return to_return;
1003 }
1004 
1007 {
1008  ldns_status result = LDNS_STATUS_OK;
1009  ldns_dnssec_name *cur_name;
1010  ldns_rbnode_t *cur_node;
1011  ldns_rr_type type_covered = 0;
1012 
1013  if (!zone || !rr) {
1014  return LDNS_STATUS_ERR;
1015  }
1016 
1017  if (!zone->names) {
1019  if(!zone->names) return LDNS_STATUS_MEM_ERR;
1020  }
1021 
1022  /* we need the original of the hashed name if this is
1023  an NSEC3, or an RRSIG that covers an NSEC3 */
1024  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) {
1025  type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
1026  }
1027  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 ||
1028  type_covered == LDNS_RR_TYPE_NSEC3) {
1029  cur_node = ldns_dnssec_zone_find_nsec3_original(zone, rr);
1030  if (!cur_node) {
1032  }
1033  } else {
1034  cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr));
1035  }
1036  if (!cur_node) {
1037  /* add */
1038  cur_name = ldns_dnssec_name_new_frm_rr(rr);
1039  if(!cur_name) return LDNS_STATUS_MEM_ERR;
1040  cur_node = LDNS_MALLOC(ldns_rbnode_t);
1041  if(!cur_node) {
1042  ldns_dnssec_name_free(cur_name);
1043  return LDNS_STATUS_MEM_ERR;
1044  }
1045  cur_node->key = ldns_rr_owner(rr);
1046  cur_node->data = cur_name;
1047  (void)ldns_rbtree_insert(zone->names, cur_node);
1048  ldns_dnssec_name_make_hashed_name(zone, cur_name, NULL);
1049  } else {
1050  cur_name = (ldns_dnssec_name *) cur_node->data;
1051  result = ldns_dnssec_name_add_rr(cur_name, rr);
1052  }
1053  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
1054  zone->soa = cur_name;
1055  }
1056  return result;
1057 }
1058 
1059 void
1061  const ldns_rbtree_t *tree,
1062  bool print_soa)
1063 {
1064  ldns_rbnode_t *node;
1065  ldns_dnssec_name *name;
1066 
1067  node = ldns_rbtree_first(tree);
1068  while (node != LDNS_RBTREE_NULL) {
1069  name = (ldns_dnssec_name *) node->data;
1070  ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa);
1071  if ((fmt->flags & LDNS_COMMENT_LAYOUT))
1072  fprintf(out, ";\n");
1073  node = ldns_rbtree_next(node);
1074  }
1075 }
1076 
1077 void
1078 ldns_dnssec_zone_names_print(FILE *out, const ldns_rbtree_t *tree, bool print_soa)
1079 {
1081  tree, print_soa);
1082 }
1083 
1084 void
1086  const ldns_dnssec_zone *zone)
1087 {
1088  if (zone) {
1089  if (zone->soa) {
1090  if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
1091  fprintf(out, ";; Zone: ");
1093  zone->soa));
1094  fprintf(out, "\n;\n");
1095  }
1098  zone->soa,
1099  LDNS_RR_TYPE_SOA),
1100  false);
1101  if ((fmt->flags & LDNS_COMMENT_LAYOUT))
1102  fprintf(out, ";\n");
1103  }
1104 
1105  if (zone->names) {
1107  zone->names, false);
1108  }
1109  }
1110 }
1111 
1112 void
1114 {
1116 }
1117 
1118 static ldns_status
1119 ldns_dnssec_zone_add_empty_nonterminals_nsec3(
1120  ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s)
1121 {
1122  ldns_dnssec_name *new_name;
1123  ldns_rdf *cur_name;
1124  ldns_rdf *next_name;
1125  ldns_rbnode_t *cur_node, *next_node, *new_node;
1126 
1127  /* for the detection */
1128  uint16_t i, cur_label_count, next_label_count;
1129  uint16_t soa_label_count = 0;
1130  ldns_rdf *l1, *l2;
1131  int lpos;
1132 
1133  if (!zone) {
1134  return LDNS_STATUS_ERR;
1135  }
1136  if (zone->soa && zone->soa->name) {
1137  soa_label_count = ldns_dname_label_count(zone->soa->name);
1138  }
1139 
1140  cur_node = ldns_rbtree_first(zone->names);
1141  while (cur_node != LDNS_RBTREE_NULL) {
1142  next_node = ldns_rbtree_next(cur_node);
1143 
1144  /* skip glue */
1145  while (next_node != LDNS_RBTREE_NULL &&
1146  next_node->data &&
1147  ((ldns_dnssec_name *)next_node->data)->is_glue
1148  ) {
1149  next_node = ldns_rbtree_next(next_node);
1150  }
1151 
1152  if (next_node == LDNS_RBTREE_NULL) {
1153  next_node = ldns_rbtree_first(zone->names);
1154  }
1155  if (! cur_node->data || ! next_node->data) {
1156  return LDNS_STATUS_ERR;
1157  }
1158  cur_name = ((ldns_dnssec_name *)cur_node->data)->name;
1159  next_name = ((ldns_dnssec_name *)next_node->data)->name;
1160  cur_label_count = ldns_dname_label_count(cur_name);
1161  next_label_count = ldns_dname_label_count(next_name);
1162 
1163  /* Since the names are in canonical order, we can
1164  * recognize empty non-terminals by their labels;
1165  * every label after the first one on the next owner
1166  * name is a non-terminal if it either does not exist
1167  * in the current name or is different from the same
1168  * label in the current name (counting from the end)
1169  */
1170  for (i = 1; i < next_label_count - soa_label_count; i++) {
1171  lpos = (int)cur_label_count - (int)next_label_count + (int)i;
1172  if (lpos >= 0) {
1173  l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos);
1174  } else {
1175  l1 = NULL;
1176  }
1177  l2 = ldns_dname_clone_from(next_name, i);
1178 
1179  if (!l1 || ldns_dname_compare(l1, l2) != 0) {
1180  /* We have an empty nonterminal, add it to the
1181  * tree
1182  */
1183  ldns_rbnode_t *node = NULL;
1184  ldns_rdf *ent_name;
1185 
1186  if (!(ent_name = ldns_dname_clone_from(
1187  next_name, i))) {
1188 
1189  ldns_rdf_deep_free(l1);
1190  ldns_rdf_deep_free(l2);
1191  return LDNS_STATUS_MEM_ERR;
1192  }
1193 
1194  if (nsec3s && zone->_nsec3params) {
1195  ldns_rdf *ent_hashed_name;
1196 
1197  if (!(ent_hashed_name =
1199  zone->_nsec3params,
1200  ent_name))) {
1201  ldns_rdf_deep_free(l1);
1202  ldns_rdf_deep_free(l2);
1203  ldns_rdf_deep_free(ent_name);
1204  return LDNS_STATUS_MEM_ERR;
1205  }
1206  node = ldns_rbtree_search(nsec3s,
1207  ent_hashed_name);
1208  ldns_rdf_deep_free(ent_hashed_name);
1209  if (!node) {
1210  ldns_rdf_deep_free(l1);
1211  ldns_rdf_deep_free(l2);
1212  ldns_rdf_deep_free(ent_name);
1213  continue;
1214  }
1215  }
1216  new_name = ldns_dnssec_name_new();
1217  if (!new_name) {
1218  ldns_rdf_deep_free(l1);
1219  ldns_rdf_deep_free(l2);
1220  ldns_rdf_deep_free(ent_name);
1221  return LDNS_STATUS_MEM_ERR;
1222  }
1223  new_name->name = ent_name;
1224  new_name->name_alloced = true;
1225  new_node = LDNS_MALLOC(ldns_rbnode_t);
1226  if (!new_node) {
1227  ldns_rdf_deep_free(l1);
1228  ldns_rdf_deep_free(l2);
1229  ldns_dnssec_name_free(new_name);
1230  return LDNS_STATUS_MEM_ERR;
1231  }
1232  new_node->key = new_name->name;
1233  new_node->data = new_name;
1234  (void)ldns_rbtree_insert(zone->names, new_node);
1235  ldns_dnssec_name_make_hashed_name(
1236  zone, new_name, NULL);
1237  if (node)
1238  (void) ldns_dnssec_zone_add_rr(zone,
1239  (ldns_rr *)node->data);
1240  }
1241  ldns_rdf_deep_free(l1);
1242  ldns_rdf_deep_free(l2);
1243  }
1244 
1245  /* we might have inserted a new node after
1246  * the current one so we can't just use next()
1247  */
1248  if (next_node != ldns_rbtree_first(zone->names)) {
1249  cur_node = next_node;
1250  } else {
1251  cur_node = LDNS_RBTREE_NULL;
1252  }
1253  }
1254  return LDNS_STATUS_OK;
1255 }
1256 
1259 {
1260  return ldns_dnssec_zone_add_empty_nonterminals_nsec3(zone, NULL);
1261 }
1262 
1263 bool
1265 {
1266  ldns_rr* nsec3;
1267  ldns_rbnode_t* node;
1268 
1270  node = ldns_rbtree_first(zone->names);
1271  while (node != LDNS_RBTREE_NULL) {
1272  nsec3 = ((ldns_dnssec_name*)node->data)->nsec;
1273  if (nsec3 &&ldns_rr_get_type(nsec3)
1274  == LDNS_RR_TYPE_NSEC3 &&
1275  ldns_nsec3_optout(nsec3)) {
1276  return true;
1277  }
1278  node = ldns_rbtree_next(node);
1279  }
1280  }
1281  return false;
1282 }
1283 
1284 /*
1285  * Stuff for calculating and verifying zone digests
1286  */
1296 
1297 typedef struct dnssec_zone_rr_iter {
1308  uint8_t apex_labs;
1310 
1311 INLINE void
1312 dnssec_zone_rr_iter_set_state_for_next_name(dnssec_zone_rr_iter *i)
1313 {
1314  /* Make sure the i->name is "in zone" (i.e. below the apex) */
1315  if (i->apex_name) {
1316  ldns_rdf *name = (ldns_rdf *)i->node->key;
1317 
1318  while (i->name && name != i->apex_name /* not apex */
1319 
1320  && ( ldns_dname_label_count(name) != i->apex_labs
1321  || ldns_dname_compare(name, i->apex_name)) /* not apex */
1322 
1323  && !ldns_dname_is_subdomain(name, i->apex_name) /* no sub */) {
1324 
1325  /* next name */
1326  i->node = ldns_rbtree_next(i->node);
1327  if (i->node == LDNS_RBTREE_NULL)
1328  i->name = NULL;
1329  else {
1330  i->name = (ldns_dnssec_name *)i->node->data;
1331  name = (ldns_rdf *)i->node->key;
1332  }
1333  }
1334  }
1335  /* determine state */
1336  if (!i->name) {
1337  if (!i->nsec3_name)
1339  else {
1340  i->rrs = i->nsec3_name->nsec_signatures;
1342  }
1343  } else if (!i->nsec3_name) {
1344  i->rrsets = i->name->rrsets;
1346 
1348  , (ldns_rdf *)i->node->key) < 0) {
1349  i->rrs = i->nsec3_name->nsec_signatures;
1351  } else {
1352  i->rrsets = i->name->rrsets;
1354  }
1355 }
1356 
1398 static ldns_rr *
1399 dnssec_zone_rr_iter_next(dnssec_zone_rr_iter *i)
1400 {
1401  ldns_rr *nsec3;
1402 
1403  for (;;) {
1404  if (i->rrs) {
1405  ldns_rr *rr = i->rrs->rr;
1406  i->rrs = i->rrs->next;
1407  return rr;
1408  }
1409  switch (i->state) {
1411  if (i->rrsets
1412  && i->rrsets->type < LDNS_RR_TYPE_RRSIG) {
1413 
1414  i->rrs = i->rrsets->rrs;
1415  i->rrsets = i->rrsets->next;
1416  break;
1417  }
1418  i->rrsets4rrsigs = i->name->rrsets;
1419  if (i->name->nsec && ldns_rr_get_type(i->name->nsec)
1420  == LDNS_RR_TYPE_NSEC) {
1421 
1423  break;
1424  }
1426  /* fallthrough */
1427 
1429  if (i->rrsets4rrsigs) {
1430  i->rrs = i->rrsets4rrsigs->signatures;
1431  i->rrsets4rrsigs = i->rrsets4rrsigs->next;
1432  break;
1433  }
1435  /* fallthrough */
1436 
1438  if (i->rrsets) {
1439  i->rrs = i->rrsets->rrs;
1440  i->rrsets = i->rrsets->next;
1441  break;
1442  }
1443  /* next name */
1444  i->node = ldns_rbtree_next(i->node);
1445  i->name = i->node == LDNS_RBTREE_NULL ? NULL
1446  : (ldns_dnssec_name *)i->node->data;
1447 
1448  dnssec_zone_rr_iter_set_state_for_next_name(i);
1449  break;
1450 
1452  if (i->rrsets4rrsigs
1454 
1455  i->rrs = i->rrsets4rrsigs->signatures;
1456  i->rrsets4rrsigs = i->rrsets4rrsigs->next;
1457  break;
1458  }
1460  i->rrs = i->name->nsec_signatures;
1461  break;
1462 
1464  if (i->rrsets4rrsigs) {
1465  i->rrs = i->rrsets4rrsigs->signatures;
1466  i->rrsets4rrsigs = i->rrsets4rrsigs->next;
1467  break;
1468  }
1470  return i->name->nsec;
1471 
1473  nsec3 = i->nsec3_name->nsec;
1474 
1475  /* next nsec3 */
1476  do {
1477  i->nsec3_node
1479  i->nsec3_name
1480  = i->nsec3_node == LDNS_RBTREE_NULL ? NULL
1482 
1483  /* names for glue can be in the hashed_names
1484  * tree, but will not have a NSEC3
1485  */
1486  } while (i->nsec3_name && !i->nsec3_name->nsec);
1487 
1488  dnssec_zone_rr_iter_set_state_for_next_name(i);
1489  return nsec3;
1490 
1492  return NULL;
1493  }
1494  }
1495 }
1496 
1497 static ldns_rr *
1498 dnssec_zone_rr_iter_first(dnssec_zone_rr_iter *i, ldns_dnssec_zone *zone)
1499 {
1500  if (!i || !zone)
1501  return NULL;
1502 
1503  memset(i, 0, sizeof(*i));
1504  i->zone = zone;
1505  if (zone->soa && zone->soa->name) {
1506  i->apex_name = zone->soa->name;
1508  } else
1509  i->apex_name = NULL;
1510 
1511 
1512  i->node = ldns_rbtree_first(zone->names);
1513  i->name = i->node == LDNS_RBTREE_NULL ? NULL
1514  : (ldns_dnssec_name *)i->node->data;
1515 
1516  if (zone->hashed_names) {
1517  do {
1519  i->nsec3_name = i->nsec3_node == LDNS_RBTREE_NULL ?NULL
1521  } while (i->nsec3_name && !i->nsec3_name->nsec);
1522  }
1523  dnssec_zone_rr_iter_set_state_for_next_name(i);
1524  return dnssec_zone_rr_iter_next(i);
1525 }
1526 
1530  ZONEMD_SCHEME_LAST = 1
1531 };
1532 typedef enum enum_zonemd_scheme zonemd_scheme;
1533 
1538  ZONEMD_HASH_LAST = 2
1539 };
1540 typedef enum enum_zonemd_hash zonemd_hash;
1541 
1545  unsigned simple_sha384 : 1;
1546  unsigned simple_sha512 : 1;
1547  unsigned double_sha384 : 1;
1548  unsigned double_sha512 : 1;
1549 };
1550 typedef struct struct_zone_digester zone_digester;
1551 
1552 INLINE bool zone_digester_set(zone_digester *zd)
1553 { return zd && (zd->simple_sha384 || zd->simple_sha512); }
1554 
1555 INLINE void zone_digester_init(zone_digester *zd)
1556 { memset(zd, 0, sizeof(*zd)); }
1557 
1558 static ldns_status
1559 zone_digester_add(zone_digester *zd, zonemd_scheme scheme, zonemd_hash hash)
1560 {
1561  if (!zd)
1562  return LDNS_STATUS_NULL;
1563 
1564  switch (scheme) {
1565  case ZONEMD_SCHEME_SIMPLE:
1566  switch (hash) {
1567  case ZONEMD_HASH_SHA384:
1568  if (zd->double_sha384)
1570 
1571  else if (zd->simple_sha384) {
1572  zd->simple_sha384 = 0;
1573  zd->double_sha384 = 1;
1575  }
1577  zd->simple_sha384 = 1;
1578  break;
1579 
1580  case ZONEMD_HASH_SHA512:
1581  if (zd->double_sha512)
1583 
1584  else if (zd->simple_sha512) {
1585  zd->simple_sha512 = 0;
1586  zd->double_sha512 = 1;
1588  }
1590  zd->simple_sha512 = 1;
1591  break;
1592  default:
1594  }
1595  break;
1596  default:
1598  }
1599  return LDNS_STATUS_OK;
1600 }
1601 
1602 static ldns_status
1603 zone_digester_update(zone_digester *zd, ldns_rr *rr)
1604 {
1605  uint8_t data[65536];
1606  ldns_buffer buf;
1607  ldns_status st;
1608 
1609  buf._data = data;
1610  buf._position = 0;
1611  buf._limit = sizeof(data);
1612  buf._capacity = sizeof(data);
1613  buf._fixed = 1;
1614  buf._status = LDNS_STATUS_OK;
1615 
1616  if ((st = ldns_rr2buffer_wire_canonical(&buf, rr, LDNS_SECTION_ANSWER)))
1617  return st;
1618 
1619  if (zd->simple_sha384)
1620  ldns_sha384_update(&zd->sha384_CTX, data, buf._position);
1621 
1622  if (zd->simple_sha512)
1623  ldns_sha512_update(&zd->sha512_CTX, data, buf._position);
1624 
1625  return LDNS_STATUS_OK;
1626 }
1627 
1628 INLINE ldns_rr *
1629 new_zonemd(ldns_rr *soa, zonemd_hash hash)
1630 {
1631  ldns_rr *rr = NULL;
1632  uint8_t *data = NULL;
1633  ldns_rdf *rdf;
1634  size_t md_len = hash == ZONEMD_HASH_SHA384
1637 
1639  return NULL;
1640 
1641  if (!(rdf = ldns_rdf_clone(ldns_rr_owner(soa))))
1642  goto error;
1643 
1644  ldns_rr_set_owner(rr, rdf);
1646  ldns_rr_set_ttl(rr, ldns_rr_ttl(soa));
1647 
1648  if (!(rdf = ldns_rdf_clone(ldns_rr_rdf(soa, 2))))
1649  goto error;
1650  ldns_rr_set_rdf(rr, rdf, 0);
1651 
1652  if (!(rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, 1)))
1653  goto error;
1654  ldns_rr_set_rdf(rr, rdf, 1);
1655 
1656  if (!(rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, hash)))
1657  goto error;
1658  ldns_rr_set_rdf(rr, rdf, 2);
1659 
1660  if (!(data = LDNS_XMALLOC(uint8_t, md_len)))
1661  goto error;
1662 
1663  if (!(rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, md_len, data)))
1664  goto error;
1665  ldns_rr_set_rdf(rr, rdf, 3);
1666 
1667  return rr;
1668 error:
1669  if (data)
1670  LDNS_FREE(data);
1671  ldns_rr_free(rr);
1672  return NULL;
1673 }
1674 
1675 static ldns_rr_list *
1676 zone_digester_export(
1677  zone_digester *zd, ldns_rr *soa, ldns_status *ret_st)
1678 {
1680  ldns_rr_list *rr_list = NULL;
1681  ldns_rr *sha384 = NULL;
1682  ldns_rr *sha512 = NULL;
1683 
1684  if (!zd || !soa)
1685  st = LDNS_STATUS_NULL;
1686 
1687  else if (ldns_rr_get_type(soa) != LDNS_RR_TYPE_SOA
1688  || ldns_rr_rd_count(soa) < 3)
1690 
1691  else if (!(rr_list = ldns_rr_list_new()))
1692  st = LDNS_STATUS_MEM_ERR;
1693 
1694  else if (zd->simple_sha384
1695  && !(sha384 = new_zonemd(soa, ZONEMD_HASH_SHA384)))
1696  st = LDNS_STATUS_MEM_ERR;
1697 
1698  else if (zd->simple_sha512
1699  && !(sha512 = new_zonemd(soa, ZONEMD_HASH_SHA512)))
1700  st = LDNS_STATUS_MEM_ERR;
1701 
1702  else if (zd->simple_sha384
1703  && !ldns_rr_list_push_rr(rr_list, sha384))
1704  st = LDNS_STATUS_MEM_ERR;
1705 
1706  else if (zd->simple_sha512
1707  && !ldns_rr_list_push_rr(rr_list, sha512)) {
1708  if (zd->simple_sha384)
1709  sha384 = NULL; /* deleted by ldns_rr_list_deep_free */
1710  st = LDNS_STATUS_MEM_ERR;
1711 
1712  } else {
1713  if (sha384)
1715  , &zd->sha384_CTX);
1716  if (sha512)
1718  , &zd->sha512_CTX);
1719  return rr_list;
1720  }
1721  if (ret_st)
1722  *ret_st = st;
1723  if (sha384)
1724  ldns_rr_free(sha384);
1725  if (sha512)
1726  ldns_rr_free(sha512);
1727  if (rr_list)
1728  ldns_rr_list_deep_free(rr_list);
1729  return NULL;
1730 }
1731 
1732 static ldns_status
1733 ldns_digest_zone(ldns_dnssec_zone *zone, zone_digester *zd)
1734 {
1736  dnssec_zone_rr_iter rr_iter;
1737  ldns_rr *rr;
1738  ldns_rdf *apex_name; /* name of zone apex */
1739 
1740  if (!zone || !zd || !zone->soa || !zone->soa->name)
1741  return LDNS_STATUS_NULL;
1742 
1743  apex_name = zone->soa->name;
1744  for ( rr = dnssec_zone_rr_iter_first(&rr_iter, zone)
1745  ; rr && !st
1746  ; rr = dnssec_zone_rr_iter_next(&rr_iter)) {
1747  /* Skip apex ZONEMD RRs */
1749  && !ldns_dname_compare(ldns_rr_owner(rr), apex_name))
1750  continue;
1751  /* Skip RRSIGs for apex ZONEMD RRs */
1755  && !ldns_dname_compare(ldns_rr_owner(rr), apex_name))
1756  continue;
1757  st = zone_digester_update(zd, rr);
1758  }
1759  return st;
1760 }
1761 
1764 {
1765  ldns_dnssec_rrsets *zonemd, *soa;
1766  zone_digester zd;
1767  ldns_dnssec_rrs *rrs;
1768  ldns_rr *soa_rr;
1769  ldns_status st;
1772  size_t valid_zonemds;
1773 
1774  if (!zone)
1775  return LDNS_STATUS_NULL;
1776 
1777  zonemd = ldns_dnssec_zone_find_rrset(
1778  zone, zone->soa->name, LDNS_RR_TYPE_ZONEMD);
1779  if (!zonemd) {
1780  ldns_rbnode_t *nsec3_node;
1781 
1782  /* we need proof of non-existence for ZONEMD at the apex */
1783  if (zone->soa->nsec) {
1785  zone->soa->nsec),
1787  return LDNS_STATUS_NO_ZONEMD;
1788 
1789  } else if (!zone->soa->hashed_name || !zone->hashed_names)
1790  return LDNS_STATUS_NO_ZONEMD;
1791 
1792  else if (LDNS_RBTREE_NULL ==
1793  (nsec3_node = ldns_rbtree_search( zone->hashed_names
1794  , zone->soa->hashed_name)))
1795  return LDNS_STATUS_NO_ZONEMD;
1796  else {
1797  ldns_dnssec_name *nsec3
1798  = (ldns_dnssec_name *)nsec3_node->data;
1800  nsec3->nsec),
1802  return LDNS_STATUS_NO_ZONEMD;
1803  }
1804  /* ZONEMD at apex does really not exist */
1805  return LDNS_STATUS_OK;
1806  }
1808  zone, zone->soa->name, LDNS_RR_TYPE_SOA);
1809  if (!soa || !soa->rrs || !soa->rrs->rr)
1811 
1812  soa_rr = soa->rrs->rr;
1813  if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
1814  || ldns_rr_rd_count(soa_rr) < 3)
1816 
1817  zone_digester_init(&zd);
1818  for (rrs = zonemd->rrs; rrs; rrs = rrs->next) {
1819  if (!rrs->rr
1821  || ldns_rr_rd_count(rrs->rr) < 4)
1822  continue;
1823 
1824  /* serial should match SOA's serial */
1825  if (ldns_rdf2native_int32(ldns_rr_rdf(soa_rr, 2))
1826  != ldns_rdf2native_int32(ldns_rr_rdf(rrs->rr, 0)))
1827  continue;
1828 
1829  /* Add (scheme, hash) to digester */
1830  zone_digester_add(&zd,
1832  ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr, 2)));
1833  }
1834  if (!zone_digester_set(&zd))
1836 
1837  if ((st = ldns_digest_zone(zone, &zd)))
1838  return st;
1839 
1840  if (zd.simple_sha384)
1842  if (zd.simple_sha512)
1844 
1845  valid_zonemds = 0;
1846  for (rrs = zonemd->rrs; rrs; rrs = rrs->next) {
1847  if (!rrs->rr
1849  || ldns_rr_rd_count(rrs->rr) < 4)
1850  continue;
1851 
1852  /* serial should match SOA's serial */
1853  if (ldns_rdf2native_int32(ldns_rr_rdf(soa_rr, 2))
1854  != ldns_rdf2native_int32(ldns_rr_rdf(rrs->rr, 0)))
1855  continue;
1856 
1857  if (ZONEMD_SCHEME_SIMPLE !=
1859  continue;
1860 
1861  if (ZONEMD_HASH_SHA384
1862  == ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr,2))
1864  == ldns_rdf_size(ldns_rr_rdf(rrs->rr, 3))
1865  && memcmp( simple_sha384
1866  , ldns_rdf_data(ldns_rr_rdf(rrs->rr, 3))
1867  , LDNS_SHA384_DIGEST_LENGTH) == 0)
1868 
1869  valid_zonemds += 1;
1870 
1871  if (ZONEMD_HASH_SHA512
1872  == ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr,2))
1874  == ldns_rdf_size(ldns_rr_rdf(rrs->rr, 3))
1875  && memcmp( simple_sha512
1876  , ldns_rdf_data(ldns_rr_rdf(rrs->rr, 3))
1877  , LDNS_SHA512_DIGEST_LENGTH) == 0)
1878 
1879  valid_zonemds += 1;
1880  }
1881  return valid_zonemds ? LDNS_STATUS_OK : LDNS_STATUS_NO_VALID_ZONEMD;
1882 }
1883 
1884 #ifdef HAVE_SSL
1885 static ldns_status
1886 rr_list2dnssec_rrs(ldns_rr_list *rr_list, ldns_dnssec_rrs **rrs,
1887  ldns_rr_list *new_rrs)
1888 {
1889  ldns_rr *rr = NULL;
1890 
1891  if (!rr_list || !rrs)
1892  return LDNS_STATUS_NULL;
1893 
1894  if (ldns_rr_list_rr_count(rr_list) == 0)
1895  return LDNS_STATUS_OK;
1896 
1897  if (!*rrs) {
1898  if (!(*rrs = ldns_dnssec_rrs_new()))
1899  return LDNS_STATUS_MEM_ERR;
1900  (*rrs)->rr = ldns_rr_list_pop_rr(rr_list);
1901  if (new_rrs)
1902  ldns_rr_list_push_rr(new_rrs, (*rrs)->rr);
1903  }
1904  while ((rr = ldns_rr_list_pop_rr(rr_list))) {
1905  ldns_status st;
1906 
1907  if ((st = ldns_dnssec_rrs_add_rr(*rrs, rr))) {
1908  ldns_rr_list_push_rr(rr_list, rr);
1909  return st;
1910  } else if (new_rrs)
1911  ldns_rr_list_push_rr(new_rrs, rr);
1912  }
1913  return LDNS_STATUS_OK;
1914 }
1915 
1916 
1919  ldns_rr_list *new_rrs, ldns_key_list *key_list, int signflags)
1920 {
1922  zone_digester zd;
1923  ldns_rr_list *zonemd_rr_list = NULL;
1924  ldns_rr_list *zonemd_rrsigs = NULL;
1925  ldns_dnssec_rrsets *soa_rrset;
1926  ldns_rr *soa_rr = NULL;
1927  ldns_dnssec_rrsets **rrset_ref;
1928  ldns_dnssec_rrsets *zonemd_rrset;
1929 
1930  zone_digester_init(&zd);
1931  if (signflags & LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA384)
1932  zone_digester_add(&zd, ZONEMD_SCHEME_SIMPLE
1933  , ZONEMD_HASH_SHA384);
1934 
1935  if (signflags & LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA512)
1936  zone_digester_add(&zd, ZONEMD_SCHEME_SIMPLE
1937  , ZONEMD_HASH_SHA512);
1938 
1939  if ((st = ldns_digest_zone(zone, &zd)))
1940  return st;
1941 
1942  soa_rrset = ldns_dnssec_zone_find_rrset(
1943  zone, zone->soa->name, LDNS_RR_TYPE_SOA);
1944  if (!soa_rrset || !soa_rrset->rrs || !soa_rrset->rrs->rr)
1946  soa_rr = soa_rrset->rrs->rr;
1947 
1948  if (!(zonemd_rr_list = zone_digester_export(&zd, soa_rr, &st)))
1949  return st;
1950 
1951  /* - replace or add ZONEMD rrset */
1952  rrset_ref = &zone->soa->rrsets; /* scan rrsets at apex */
1953  while (*rrset_ref && (*rrset_ref)->type < LDNS_RR_TYPE_ZONEMD)
1954  rrset_ref = &(*rrset_ref)->next;
1955  if (*rrset_ref && (*rrset_ref)->type == LDNS_RR_TYPE_ZONEMD) {
1956  /* reuse zonemd rrset */
1957  zonemd_rrset = *rrset_ref;
1958  ldns_dnssec_rrs_free(zonemd_rrset->rrs);
1959  zonemd_rrset->rrs = NULL;
1960  ldns_dnssec_rrs_free(zonemd_rrset->signatures);
1961  zonemd_rrset->signatures = NULL;
1962  } else {
1963  /* insert zonemd rrset */
1964  zonemd_rrset = ldns_dnssec_rrsets_new();
1965  if (!zonemd_rrset) {
1966  ldns_rr_list_deep_free(zonemd_rr_list);
1967  return LDNS_STATUS_MEM_ERR;
1968  }
1969  zonemd_rrset->type = LDNS_RR_TYPE_ZONEMD;
1970  zonemd_rrset->next = *rrset_ref;
1971  *rrset_ref = zonemd_rrset;
1972  }
1973  if ((zonemd_rrsigs = ldns_sign_public(zonemd_rr_list, key_list)))
1974  st = rr_list2dnssec_rrs( zonemd_rrsigs
1975  , &zonemd_rrset->signatures, new_rrs);
1976  if (!st)
1977  st = rr_list2dnssec_rrs( zonemd_rr_list
1978  , &zonemd_rrset->rrs, new_rrs);
1979  ldns_rr_list_deep_free(zonemd_rr_list);
1980  ldns_rr_list_deep_free(zonemd_rrsigs);
1981  return st;
1982 }
1983 
1984 #endif /* HAVE_SSL */
1985 
#define ATTR_UNUSED(x)
Definition: common.h:72
ldns_rdf * ldns_dname_clone_from(const ldns_rdf *d, uint16_t n)
Clones the given dname from the nth label on.
Definition: dname.c:160
bool ldns_dname_is_subdomain(const ldns_rdf *sub, const ldns_rdf *parent)
test whether the name sub falls under parent (i.e.
Definition: dname.c:296
int ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2)
Compares the two dname rdf's according to the algorithm for ordering in RFC4034 Section 6.
Definition: dname.c:359
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
bool ldns_nsec_bitmap_covers_type(const ldns_rdf *bitmap, ldns_rr_type type)
Check if RR type t is enumerated and set in the RR type bitmap rdf.
Definition: dnssec.c:1393
bool ldns_nsec3_optout(const ldns_rr *nsec3_rr)
Returns true if the opt-out flag has been set in the given NSEC3 RR.
Definition: dnssec.c:1286
ldns_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)
use this function to sign with a public/private key alg return the created signatures
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:613
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:1085
struct dnssec_zone_rr_iter dnssec_zone_rr_iter
ldns_status _ldns_rr_new_frm_fp_l_internal(ldns_rr **newrr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev, int *line_nr, bool *explicit_ttl)
Definition: rr.c:725
ldns_status ldns_dnssec_zone_verify_zonemd(ldns_dnssec_zone *zone)
Definition: dnssec_zone.c:1763
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:1527
@ ZONEMD_SCHEME_SIMPLE
Definition: dnssec_zone.c:1529
@ ZONEMD_SCHEME_FIRST
Definition: dnssec_zone.c:1528
@ ZONEMD_SCHEME_LAST
Definition: dnssec_zone.c:1530
void ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_dnssec_rrsets *rrsets, bool follow)
Print the given list of rrsets to the given file descriptor.
Definition: dnssec_zone.c:302
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:1918
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:1113
void ldns_dnssec_name_deep_free(ldns_dnssec_name *name)
Frees the name structure and its rrs and rrsets.
Definition: dnssec_zone.c:389
bool 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_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
void ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_rbtree_t *tree, bool print_soa)
Prints the rbtree of ldns_dnssec_name structures to the file descriptor.
Definition: dnssec_zone.c:1060
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_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
bool 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:1264
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:1006
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:842
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:1258
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
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:869
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:1540
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:1534
@ ZONEMD_HASH_SHA512
Definition: dnssec_zone.c:1537
@ ZONEMD_HASH_LAST
Definition: dnssec_zone.c:1538
@ ZONEMD_HASH_SHA384
Definition: dnssec_zone.c:1536
@ ZONEMD_HASH_FIRST
Definition: dnssec_zone.c:1535
enum enum_zonemd_scheme zonemd_scheme
Definition: dnssec_zone.c:1532
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:889
void ldns_dnssec_rrsets_print(FILE *out, const ldns_dnssec_rrsets *rrsets, bool follow)
Print the given list of rrsets to the given file descriptor.
Definition: dnssec_zone.c:310
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
void ldns_dnssec_zone_names_print(FILE *out, const ldns_rbtree_t *tree, bool print_soa)
Prints the rbtree of ldns_dnssec_name structures to the file descriptor.
Definition: dnssec_zone.c:1078
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:910
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:1287
@ DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC
Definition: dnssec_zone.c:1291
@ DNSSEC_ZONE_RR_ITER_LT_RRSIG
Definition: dnssec_zone.c:1288
@ DNSSEC_ZONE_RR_ITER_REST
Definition: dnssec_zone.c:1290
@ DNSSEC_ZONE_RR_ITER_FINI
Definition: dnssec_zone.c:1294
@ DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC_REST
Definition: dnssec_zone.c:1292
@ DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC
Definition: dnssec_zone.c:1289
@ DNSSEC_ZONE_RR_ITER_NSEC3
Definition: dnssec_zone.c:1293
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:146
void ldns_rdf_print(FILE *output, const ldns_rdf *rdf)
Prints the data in the rdata field to the given file stream (in presentation format)
Definition: host2str.c:3386
const ldns_output_format * ldns_output_format_default
The default output format record.
Definition: host2str.c:142
void ldns_rr_print_fmt(FILE *output, const ldns_output_format *fmt, const ldns_rr *rr)
Prints the data in the resource record to the given file stream (in presentation format)
Definition: host2str.c:3398
#define LDNS_COMMENT_LAYOUT
Print mark up.
Definition: host2str.h:62
ldns_status ldns_rr2buffer_wire_canonical(ldns_buffer *buffer, 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
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
ldns_rbnode_t * ldns_rbtree_next(ldns_rbnode_t *node)
Returns next larger node in the tree.
Definition: rbtree.c:574
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
#define LDNS_RBTREE_NULL
The nullpointer, points to empty node.
Definition: rbtree.h:76
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
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
@ 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
void ldns_rr_list_free(ldns_rr_list *rr_list)
frees an rr_list structure.
Definition: rr.c:1011
ldns_rr * ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr)
returns a specific rr of an rrlist.
Definition: rr.c:990
ldns_rr * ldns_rr_list_pop_rr(ldns_rr_list *rr_list)
pops the last rr from an rrlist.
Definition: rr.c:1177
uint32_t ldns_rr_ttl(const ldns_rr *rr)
returns the ttl of an rr structure.
Definition: rr.c:931
ldns_rdf * ldns_rr_owner(const ldns_rr *rr)
returns the owner name of an rr structure.
Definition: rr.c:919
ldns_rr_type ldns_rdf2rr_type(const ldns_rdf *rd)
convert an rdf of type LDNS_RDF_TYPE_TYPE to an actual LDNS_RR_TYPE.
Definition: rr.c:2750
ldns_status ldns_rr_new_frm_fp_l(ldns_rr **newrr, 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:796
void ldns_rr_list_deep_free(ldns_rr_list *rr_list)
frees an rr_list structure and all rrs contained therein.
Definition: rr.c:1020
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:804
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
size_t ldns_rr_rd_count(const ldns_rr *rr)
returns the rd_count of an rr structure.
Definition: rr.c:937
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:840
size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
returns the number of rr's in an rr_list.
Definition: rr.c:957
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition: rr.c:943
void ldns_rr_set_ttl(ldns_rr *rr, uint32_t ttl)
sets the ttl in the rr structure.
Definition: rr.c:816
bool ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr)
pushes an rr to an rrlist.
Definition: rr.c:1132
ldns_rr_class ldns_rr_get_class(const ldns_rr *rr)
returns the class of the rr.
Definition: rr.c:949
void ldns_rr_set_class(ldns_rr *rr, ldns_rr_class rr_class)
sets the class in the rr.
Definition: rr.c:834
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
Definition: rr.c:1000
int ldns_rr_compare(const ldns_rr *rr1, const ldns_rr *rr2)
compares two rrs.
Definition: rr.c:1638
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
Definition: rr.c:909
enum ldns_enum_rr_type ldns_rr_type
Definition: rr.h:243
@ LDNS_RR_TYPE_RRSIG
DNSSEC.
Definition: rr.h:170
@ LDNS_RR_TYPE_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
enum ldns_enum_rr_class ldns_rr_class
Definition: rr.h:61
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_init(ldns_sha512_CTX *context)
Definition: sha2.c:634
void ldns_sha512_final(sha2_byte digest[64], ldns_sha512_CTX *context)
Definition: sha2.c:908
void ldns_sha384_update(ldns_sha384_CTX *context, const sha2_byte *data, size_t len)
Definition: sha2.c:957
void ldns_sha512_update(ldns_sha512_CTX *context, const sha2_byte *data, size_t len)
Definition: sha2.c:815
void ldns_sha384_final(sha2_byte digest[48], ldns_sha384_CTX *context)
Definition: sha2.c:961
void ldns_sha384_init(ldns_sha384_CTX *context)
Definition: sha2.c:948
#define LDNS_SHA512_DIGEST_LENGTH
Definition: sha2.h:69
#define LDNS_SHA384_DIGEST_LENGTH
Definition: sha2.h:66
ldns_dnssec_name * nsec3_name
Definition: dnssec_zone.c:1305
dnssec_zone_rr_iter_state state
Definition: dnssec_zone.c:1306
ldns_rdf * apex_name
Definition: dnssec_zone.c:1307
ldns_dnssec_name * name
Definition: dnssec_zone.c:1300
ldns_dnssec_rrsets * rrsets4rrsigs
Definition: dnssec_zone.c:1303
ldns_dnssec_zone * zone
Definition: dnssec_zone.c:1298
ldns_rbnode_t * nsec3_node
Definition: dnssec_zone.c:1304
ldns_rbnode_t * node
Definition: dnssec_zone.c:1299
ldns_dnssec_rrs * rrs
Definition: dnssec_zone.c:1302
ldns_dnssec_rrsets * rrsets
Definition: dnssec_zone.c:1301
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
bool 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
bool 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 * 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
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:338
Resource Record.
Definition: rr.h:310
DNS Zone.
Definition: zone.h:43
ldns_sha512_CTX sha512_CTX
Definition: dnssec_zone.c:1544
ldns_sha384_CTX sha384_CTX
Definition: dnssec_zone.c:1543
#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 default_ttl, ldns_rr_class c __attribute__((unused)), int *line_nr)
Definition: zone.c:198