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