xref: /dragonfly/contrib/ldns/dnssec_verify.c (revision c37c9ab3)
1 #include <ldns/config.h>
2 
3 #include <ldns/ldns.h>
4 
5 #include <strings.h>
6 #include <time.h>
7 
8 #ifdef HAVE_SSL
9 /* this entire file is rather useless when you don't have
10  * crypto...
11  */
12 #include <openssl/ssl.h>
13 #include <openssl/evp.h>
14 #include <openssl/rand.h>
15 #include <openssl/err.h>
16 #include <openssl/md5.h>
17 
18 ldns_dnssec_data_chain *
19 ldns_dnssec_data_chain_new(void)
20 {
21 	ldns_dnssec_data_chain *nc = LDNS_CALLOC(ldns_dnssec_data_chain, 1);
22         if(!nc) return NULL;
23 	/*
24 	 * not needed anymore because CALLOC initalizes everything to zero.
25 
26 	nc->rrset = NULL;
27 	nc->parent_type = 0;
28 	nc->parent = NULL;
29 	nc->signatures = NULL;
30 	nc->packet_rcode = 0;
31 	nc->packet_qtype = 0;
32 	nc->packet_nodata = false;
33 
34 	 */
35 	return nc;
36 }
37 
38 void
39 ldns_dnssec_data_chain_free(ldns_dnssec_data_chain *chain)
40 {
41 	LDNS_FREE(chain);
42 }
43 
44 void
45 ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain)
46 {
47 	ldns_rr_list_deep_free(chain->rrset);
48 	ldns_rr_list_deep_free(chain->signatures);
49 	if (chain->parent) {
50 		ldns_dnssec_data_chain_deep_free(chain->parent);
51 	}
52 	LDNS_FREE(chain);
53 }
54 
55 void
56 ldns_dnssec_data_chain_print_fmt(FILE *out, const ldns_output_format *fmt,
57 		const ldns_dnssec_data_chain *chain)
58 {
59 	ldns_lookup_table *rcode;
60 	const ldns_rr_descriptor *rr_descriptor;
61 	if (chain) {
62 		ldns_dnssec_data_chain_print_fmt(out, fmt, chain->parent);
63 		if (ldns_rr_list_rr_count(chain->rrset) > 0) {
64 			rcode = ldns_lookup_by_id(ldns_rcodes,
65 								 (int) chain->packet_rcode);
66 			if (rcode) {
67 				fprintf(out, ";; rcode: %s\n", rcode->name);
68 			}
69 
70 			rr_descriptor = ldns_rr_descript(chain->packet_qtype);
71 			if (rr_descriptor && rr_descriptor->_name) {
72 				fprintf(out, ";; qtype: %s\n", rr_descriptor->_name);
73 			} else if (chain->packet_qtype != 0) {
74 				fprintf(out, "TYPE%u",
75 					   chain->packet_qtype);
76 			}
77 			if (chain->packet_nodata) {
78 				fprintf(out, ";; NODATA response\n");
79 			}
80 			fprintf(out, "rrset:\n");
81 			ldns_rr_list_print_fmt(out, fmt, chain->rrset);
82 			fprintf(out, "sigs:\n");
83 			ldns_rr_list_print_fmt(out, fmt, chain->signatures);
84 			fprintf(out, "---\n");
85 		} else {
86 			fprintf(out, "<no data>\n");
87 		}
88 	}
89 }
90 void
91 ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain)
92 {
93 	ldns_dnssec_data_chain_print_fmt(
94 			out, ldns_output_format_default, chain);
95 }
96 
97 
98 static void
99 ldns_dnssec_build_data_chain_dnskey(ldns_resolver *res,
100 					    uint16_t qflags,
101 					    const ldns_pkt *pkt,
102 					    ldns_rr_list *signatures,
103 						ldns_dnssec_data_chain *new_chain,
104 						ldns_rdf *key_name,
105 						ldns_rr_class c) {
106 	ldns_rr_list *keys;
107 	ldns_pkt *my_pkt;
108 	if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
109 		new_chain->signatures = ldns_rr_list_clone(signatures);
110 		new_chain->parent_type = 0;
111 
112 		keys = ldns_pkt_rr_list_by_name_and_type(
113 				  pkt,
114 				 key_name,
115 				 LDNS_RR_TYPE_DNSKEY,
116 				 LDNS_SECTION_ANY_NOQUESTION
117 			  );
118 		if (!keys) {
119 			my_pkt = ldns_resolver_query(res,
120 									key_name,
121 									LDNS_RR_TYPE_DNSKEY,
122 									c,
123 									qflags);
124 			if (my_pkt) {
125 			keys = ldns_pkt_rr_list_by_name_and_type(
126 					  my_pkt,
127 					 key_name,
128 					 LDNS_RR_TYPE_DNSKEY,
129 					 LDNS_SECTION_ANY_NOQUESTION
130 				  );
131 			new_chain->parent = ldns_dnssec_build_data_chain(res,
132 													qflags,
133 													keys,
134 													my_pkt,
135 													NULL);
136 			new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
137 			ldns_pkt_free(my_pkt);
138 			}
139 		} else {
140 			new_chain->parent = ldns_dnssec_build_data_chain(res,
141 													qflags,
142 													keys,
143 													pkt,
144 													NULL);
145 			new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
146 		}
147 		ldns_rr_list_deep_free(keys);
148 	}
149 }
150 
151 static void
152 ldns_dnssec_build_data_chain_other(ldns_resolver *res,
153 					    uint16_t qflags,
154 						ldns_dnssec_data_chain *new_chain,
155 						ldns_rdf *key_name,
156 						ldns_rr_class c,
157 						ldns_rr_list *dss)
158 {
159 	/* 'self-signed', parent is a DS */
160 
161 	/* okay, either we have other keys signing the current one,
162 	 * or the current
163 	 * one should have a DS record in the parent zone.
164 	 * How do we find this out? Try both?
165 	 *
166 	 * request DNSKEYS for current zone,
167 	 * add all signatures to current level
168 	 */
169 	ldns_pkt *my_pkt;
170 	ldns_rr_list *signatures2;
171 
172 	new_chain->parent_type = 1;
173 
174 	my_pkt = ldns_resolver_query(res,
175 							key_name,
176 							LDNS_RR_TYPE_DS,
177 							c,
178 							qflags);
179 	if (my_pkt) {
180 	dss = ldns_pkt_rr_list_by_name_and_type(my_pkt,
181 									key_name,
182 									LDNS_RR_TYPE_DS,
183 									LDNS_SECTION_ANY_NOQUESTION
184 									);
185 	if (dss) {
186 		new_chain->parent = ldns_dnssec_build_data_chain(res,
187 												qflags,
188 												dss,
189 												my_pkt,
190 												NULL);
191 		new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
192 		ldns_rr_list_deep_free(dss);
193 	}
194 	ldns_pkt_free(my_pkt);
195 	}
196 
197 	my_pkt = ldns_resolver_query(res,
198 							key_name,
199 							LDNS_RR_TYPE_DNSKEY,
200 							c,
201 							qflags);
202 	if (my_pkt) {
203 	signatures2 = ldns_pkt_rr_list_by_name_and_type(my_pkt,
204 										   key_name,
205 										   LDNS_RR_TYPE_RRSIG,
206 										   LDNS_SECTION_ANSWER);
207 	if (signatures2) {
208 		if (new_chain->signatures) {
209 			printf("There were already sigs!\n");
210 			ldns_rr_list_deep_free(new_chain->signatures);
211 			printf("replacing the old sigs\n");
212 		}
213 		new_chain->signatures = signatures2;
214 	}
215 	ldns_pkt_free(my_pkt);
216 	}
217 }
218 
219 static ldns_dnssec_data_chain *
220 ldns_dnssec_build_data_chain_nokeyname(ldns_resolver *res,
221                                        uint16_t qflags,
222                                        ldns_rr *orig_rr,
223                                        const ldns_rr_list *rrset,
224                                        ldns_dnssec_data_chain *new_chain)
225 {
226 	ldns_rdf *possible_parent_name;
227 	ldns_pkt *my_pkt;
228 	/* apparently we were not able to find a signing key, so
229 	   we assume the chain ends here
230 	*/
231 	/* try parents for auth denial of DS */
232 	if (orig_rr) {
233 		possible_parent_name = ldns_rr_owner(orig_rr);
234 	} else if (rrset && ldns_rr_list_rr_count(rrset) > 0) {
235 		possible_parent_name = ldns_rr_owner(ldns_rr_list_rr(rrset, 0));
236 	} else {
237 		/* no information to go on, give up */
238 		return new_chain;
239 	}
240 
241 	my_pkt = ldns_resolver_query(res,
242 	              possible_parent_name,
243 	              LDNS_RR_TYPE_DS,
244 	              LDNS_RR_CLASS_IN,
245 	              qflags);
246 	if (!my_pkt) {
247 		return new_chain;
248 	}
249 
250 	if (ldns_pkt_ancount(my_pkt) > 0) {
251 		/* add error, no sigs but DS in parent */
252 		/*ldns_pkt_print(stdout, my_pkt);*/
253 		ldns_pkt_free(my_pkt);
254 	} else {
255 		/* are there signatures? */
256 		new_chain->parent =  ldns_dnssec_build_data_chain(res,
257 		                          qflags,
258 		                          NULL,
259 		                          my_pkt,
260 		                          NULL);
261 
262 		new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
263 
264 	}
265 	return new_chain;
266 }
267 
268 
269 ldns_dnssec_data_chain *
270 ldns_dnssec_build_data_chain(ldns_resolver *res,
271 					    uint16_t qflags,
272 					    const ldns_rr_list *rrset,
273 					    const ldns_pkt *pkt,
274 					    ldns_rr *orig_rr)
275 {
276 	ldns_rr_list *signatures = NULL;
277 	ldns_rr_list *dss = NULL;
278 
279 	ldns_rr_list *my_rrset;
280 
281 	ldns_pkt *my_pkt;
282 
283 	ldns_rdf *name = NULL, *key_name = NULL;
284 	ldns_rr_type type = 0;
285 	ldns_rr_class c = 0;
286 
287 	bool other_rrset = false;
288 
289 	ldns_dnssec_data_chain *new_chain = ldns_dnssec_data_chain_new();
290 
291 	assert(pkt != NULL);
292 
293 	if (!ldns_dnssec_pkt_has_rrsigs(pkt)) {
294 		/* hmm. no dnssec data in the packet. go up to try and deny
295 		 * DS? */
296 		return new_chain;
297 	}
298 
299 	if (orig_rr) {
300 		new_chain->rrset = ldns_rr_list_new();
301 		ldns_rr_list_push_rr(new_chain->rrset, orig_rr);
302 		new_chain->parent = ldns_dnssec_build_data_chain(res,
303 											    qflags,
304 											    rrset,
305 											    pkt,
306 											    NULL);
307 		new_chain->packet_rcode = ldns_pkt_get_rcode(pkt);
308 		new_chain->packet_qtype = ldns_rr_get_type(orig_rr);
309 		if (ldns_pkt_ancount(pkt) == 0) {
310 			new_chain->packet_nodata = true;
311 		}
312 		return new_chain;
313 	}
314 
315 	if (!rrset || ldns_rr_list_rr_count(rrset) < 1) {
316 		/* hmm, no data, do we have denial? only works if pkt was given,
317 		   otherwise caller has to do the check himself */
318 		new_chain->packet_nodata = true;
319 		if (pkt) {
320 			my_rrset = ldns_pkt_rr_list_by_type(pkt,
321 										 LDNS_RR_TYPE_NSEC,
322 										 LDNS_SECTION_ANY_NOQUESTION
323 										 );
324 			if (my_rrset) {
325 				if (ldns_rr_list_rr_count(my_rrset) > 0) {
326 					type = LDNS_RR_TYPE_NSEC;
327 					other_rrset = true;
328 				} else {
329 					ldns_rr_list_deep_free(my_rrset);
330 					my_rrset = NULL;
331 				}
332 			} else {
333 				/* nothing, try nsec3 */
334 				my_rrset = ldns_pkt_rr_list_by_type(pkt,
335 						     LDNS_RR_TYPE_NSEC3,
336 							LDNS_SECTION_ANY_NOQUESTION);
337 				if (my_rrset) {
338 					if (ldns_rr_list_rr_count(my_rrset) > 0) {
339 						type = LDNS_RR_TYPE_NSEC3;
340 						other_rrset = true;
341 					} else {
342 						ldns_rr_list_deep_free(my_rrset);
343 						my_rrset = NULL;
344 					}
345 				} else {
346 					/* nothing, stop */
347 					/* try parent zone? for denied insecure? */
348 					return new_chain;
349 				}
350 			}
351 		} else {
352 			return new_chain;
353 		}
354 	} else {
355 		my_rrset = (ldns_rr_list *) rrset;
356 	}
357 
358 	if (my_rrset && ldns_rr_list_rr_count(my_rrset) > 0) {
359 		new_chain->rrset = ldns_rr_list_clone(my_rrset);
360 		name = ldns_rr_owner(ldns_rr_list_rr(my_rrset, 0));
361 		type = ldns_rr_get_type(ldns_rr_list_rr(my_rrset, 0));
362 		c = ldns_rr_get_class(ldns_rr_list_rr(my_rrset, 0));
363 	}
364 
365 	if (other_rrset) {
366 		ldns_rr_list_deep_free(my_rrset);
367 	}
368 
369 	/* normally there will only be 1 signature 'set'
370 	   but there can be more than 1 denial (wildcards)
371 	   so check for NSEC
372 	*/
373 	if (type == LDNS_RR_TYPE_NSEC || type == LDNS_RR_TYPE_NSEC3) {
374 		/* just throw in all signatures, the tree builder must sort
375 		   this out */
376 		if (pkt) {
377 			signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
378 		} else {
379 			my_pkt = ldns_resolver_query(res, name, type, c, qflags);
380 			if (my_pkt) {
381 			signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
382 			ldns_pkt_free(my_pkt);
383 			}
384 		}
385 	} else {
386 		if (pkt) {
387 			signatures =
388 				ldns_dnssec_pkt_get_rrsigs_for_name_and_type(pkt,
389 													name,
390 													type);
391 		}
392 		if (!signatures) {
393 			my_pkt = ldns_resolver_query(res, name, type, c, qflags);
394 			if (my_pkt) {
395 			signatures =
396 				ldns_dnssec_pkt_get_rrsigs_for_name_and_type(my_pkt,
397 													name,
398 													type);
399 			ldns_pkt_free(my_pkt);
400 			}
401 		}
402 	}
403 
404 	if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
405 		key_name = ldns_rr_rdf(ldns_rr_list_rr(signatures, 0), 7);
406 	}
407 	if (!key_name) {
408 		if (signatures) {
409 			ldns_rr_list_deep_free(signatures);
410 		}
411 		return ldns_dnssec_build_data_chain_nokeyname(res,
412 		                                              qflags,
413 		                                              orig_rr,
414 		                                              rrset,
415 		                                              new_chain);
416 	}
417 	if (type != LDNS_RR_TYPE_DNSKEY) {
418 		if (type != LDNS_RR_TYPE_DS ||
419 				ldns_dname_is_subdomain(name, key_name)) {
420 			ldns_dnssec_build_data_chain_dnskey(res,
421 			                                    qflags,
422 			                                    pkt,
423 			                                    signatures,
424 			                                    new_chain,
425 			                                    key_name,
426 			                                    c
427 			                                   );
428 		}
429 	} else {
430 		ldns_dnssec_build_data_chain_other(res,
431 		                                   qflags,
432 		                                   new_chain,
433 		                                   key_name,
434 		                                   c,
435 		                                   dss
436 		                                  );
437 	}
438 	if (signatures) {
439 		ldns_rr_list_deep_free(signatures);
440 	}
441 	return new_chain;
442 }
443 
444 ldns_dnssec_trust_tree *
445 ldns_dnssec_trust_tree_new(void)
446 {
447 	ldns_dnssec_trust_tree *new_tree = LDNS_XMALLOC(ldns_dnssec_trust_tree,
448 										   1);
449         if(!new_tree) return NULL;
450 	new_tree->rr = NULL;
451 	new_tree->rrset = NULL;
452 	new_tree->parent_count = 0;
453 
454 	return new_tree;
455 }
456 
457 void
458 ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree)
459 {
460 	size_t i;
461 	if (tree) {
462 		for (i = 0; i < tree->parent_count; i++) {
463 			ldns_dnssec_trust_tree_free(tree->parents[i]);
464 		}
465 	}
466 	LDNS_FREE(tree);
467 }
468 
469 size_t
470 ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree)
471 {
472 	size_t result = 0;
473 	size_t parent = 0;
474 	size_t i;
475 
476 	for (i = 0; i < tree->parent_count; i++) {
477 		parent = ldns_dnssec_trust_tree_depth(tree->parents[i]);
478 		if (parent > result) {
479 			result = parent;
480 		}
481 	}
482 	return 1 + result;
483 }
484 
485 /* TODO ldns_ */
486 static void
487 print_tabs(FILE *out, size_t nr, uint8_t *map, size_t treedepth)
488 {
489 	size_t i;
490 	for (i = 0; i < nr; i++) {
491 		if (i == nr - 1) {
492 			fprintf(out, "|---");
493 		} else if (map && i < treedepth && map[i] == 1) {
494 			fprintf(out, "|   ");
495 		} else {
496 			fprintf(out, "    ");
497 		}
498 	}
499 }
500 
501 static void
502 ldns_dnssec_trust_tree_print_sm_fmt(FILE *out,
503 		const ldns_output_format *fmt,
504 		ldns_dnssec_trust_tree *tree,
505 		size_t tabs,
506 		bool extended,
507 		uint8_t *sibmap,
508 		size_t treedepth)
509 {
510 	size_t i;
511 	const ldns_rr_descriptor *descriptor;
512 	bool mapset = false;
513 
514 	if (!sibmap) {
515 		treedepth = ldns_dnssec_trust_tree_depth(tree);
516 		sibmap = LDNS_XMALLOC(uint8_t, treedepth);
517                 if(!sibmap)
518                         return; /* mem err */
519 		memset(sibmap, 0, treedepth);
520 		mapset = true;
521 	}
522 
523 	if (tree) {
524 		if (tree->rr) {
525 			print_tabs(out, tabs, sibmap, treedepth);
526 			ldns_rdf_print(out, ldns_rr_owner(tree->rr));
527 			descriptor = ldns_rr_descript(ldns_rr_get_type(tree->rr));
528 
529 			if (descriptor->_name) {
530 				fprintf(out, " (%s", descriptor->_name);
531 			} else {
532 				fprintf(out, " (TYPE%d",
533 					   ldns_rr_get_type(tree->rr));
534 			}
535 			if (tabs > 0) {
536 				if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DNSKEY) {
537 					fprintf(out, " keytag: %u",
538 					        (unsigned int) ldns_calc_keytag(tree->rr));
539 					fprintf(out, " alg: ");
540 					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
541 					fprintf(out, " flags: ");
542 					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
543 				} else if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DS) {
544 					fprintf(out, " keytag: ");
545 					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
546 					fprintf(out, " digest type: ");
547 					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
548 				}
549 				if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NSEC) {
550 					fprintf(out, " ");
551 					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
552 					fprintf(out, " ");
553 					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 1));
554 				}
555 			}
556 
557 			fprintf(out, ")\n");
558 			for (i = 0; i < tree->parent_count; i++) {
559 				if (tree->parent_count > 1 && i < tree->parent_count - 1) {
560 					sibmap[tabs] = 1;
561 				} else {
562 					sibmap[tabs] = 0;
563 				}
564 				/* only print errors */
565 				if (ldns_rr_get_type(tree->parents[i]->rr) ==
566 				    LDNS_RR_TYPE_NSEC ||
567 				    ldns_rr_get_type(tree->parents[i]->rr) ==
568 				    LDNS_RR_TYPE_NSEC3) {
569 					if (tree->parent_status[i] == LDNS_STATUS_OK) {
570 						print_tabs(out, tabs + 1, sibmap, treedepth);
571 						if (tabs == 0 &&
572 						    ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS &&
573 							ldns_rr_rd_count(tree->rr) > 0) {
574 							fprintf(out, "Existence of DS is denied by:\n");
575 						} else {
576 							fprintf(out, "Existence is denied by:\n");
577 						}
578 					} else {
579 						/* NS records aren't signed */
580 						if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS) {
581 							fprintf(out, "Existence of DS is denied by:\n");
582 						} else {
583 							print_tabs(out, tabs + 1, sibmap, treedepth);
584 							fprintf(out,
585 								   "Error in denial of existence: %s\n",
586 								   ldns_get_errorstr_by_id(
587 									   tree->parent_status[i]));
588 						}
589 					}
590 				} else
591 					if (tree->parent_status[i] != LDNS_STATUS_OK) {
592 						print_tabs(out, tabs + 1, sibmap, treedepth);
593 						fprintf(out,
594 							   "%s:\n",
595 							   ldns_get_errorstr_by_id(
596 							       tree->parent_status[i]));
597 						if (tree->parent_status[i]
598 						    == LDNS_STATUS_SSL_ERR) {
599 							printf("; SSL Error: ");
600 							ERR_load_crypto_strings();
601 							ERR_print_errors_fp(stdout);
602 							printf("\n");
603 						}
604 						ldns_rr_print_fmt(out, fmt,
605 							tree->
606 							parent_signature[i]);
607 						printf("For RRset:\n");
608 						ldns_rr_list_print_fmt(out, fmt,
609 								tree->rrset);
610 						printf("With key:\n");
611 						ldns_rr_print_fmt(out, fmt,
612 							tree->parents[i]->rr);
613 					}
614 				ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
615 						tree->parents[i],
616 						tabs+1,
617 						extended,
618 						sibmap,
619 						treedepth);
620 			}
621 		} else {
622 			print_tabs(out, tabs, sibmap, treedepth);
623 			fprintf(out, "<no data>\n");
624 		}
625 	} else {
626 		fprintf(out, "<null pointer>\n");
627 	}
628 
629 	if (mapset) {
630 		LDNS_FREE(sibmap);
631 	}
632 }
633 
634 void
635 ldns_dnssec_trust_tree_print_fmt(FILE *out, const ldns_output_format *fmt,
636 		ldns_dnssec_trust_tree *tree,
637 		size_t tabs,
638 		bool extended)
639 {
640 	ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
641 			tree, tabs, extended, NULL, 0);
642 }
643 
644 void
645 ldns_dnssec_trust_tree_print(FILE *out,
646 		ldns_dnssec_trust_tree *tree,
647 		size_t tabs,
648 		bool extended)
649 {
650 	ldns_dnssec_trust_tree_print_fmt(out, ldns_output_format_default,
651 			tree, tabs, extended);
652 }
653 
654 
655 ldns_status
656 ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree,
657                                   const ldns_dnssec_trust_tree *parent,
658                                   const ldns_rr *signature,
659                                   const ldns_status parent_status)
660 {
661 	if (tree
662 	    && parent
663 	    && tree->parent_count < LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS) {
664 		/*
665 		  printf("Add parent for: ");
666 		  ldns_rr_print(stdout, tree->rr);
667 		  printf("parent: ");
668 		  ldns_rr_print(stdout, parent->rr);
669 		*/
670 		tree->parents[tree->parent_count] =
671 			(ldns_dnssec_trust_tree *) parent;
672 		tree->parent_status[tree->parent_count] = parent_status;
673 		tree->parent_signature[tree->parent_count] = (ldns_rr *) signature;
674 		tree->parent_count++;
675 		return LDNS_STATUS_OK;
676 	} else {
677 		return LDNS_STATUS_ERR;
678 	}
679 }
680 
681 /* if rr is null, take the first from the rrset */
682 ldns_dnssec_trust_tree *
683 ldns_dnssec_derive_trust_tree_time(
684 		ldns_dnssec_data_chain *data_chain,
685 		ldns_rr *rr,
686 		time_t check_time
687 		)
688 {
689 	ldns_rr_list *cur_rrset;
690 	ldns_rr_list *cur_sigs;
691 	ldns_rr *cur_rr = NULL;
692 	ldns_rr *cur_sig_rr;
693 	size_t i, j;
694 
695 	ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new();
696         if(!new_tree)
697                 return NULL;
698 
699 	if (data_chain && data_chain->rrset) {
700 		cur_rrset = data_chain->rrset;
701 
702 		cur_sigs = data_chain->signatures;
703 
704 		if (rr) {
705 			cur_rr = rr;
706 		}
707 
708 		if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) {
709 			cur_rr = ldns_rr_list_rr(cur_rrset, 0);
710 		}
711 
712 		if (cur_rr) {
713 			new_tree->rr = cur_rr;
714 			new_tree->rrset = cur_rrset;
715 			/* there are three possibilities:
716 			   1 - 'normal' rrset, signed by a key
717 			   2 - dnskey signed by other dnskey
718 			   3 - dnskey proven by higher level DS
719 			   (data denied by nsec is a special case that can
720 			   occur in multiple places)
721 
722 			*/
723 			if (cur_sigs) {
724 				for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) {
725 					/* find the appropriate key in the parent list */
726 					cur_sig_rr = ldns_rr_list_rr(cur_sigs, i);
727 
728 					if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) {
729 						if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
730 										   ldns_rr_owner(cur_rr)))
731 							{
732 								/* find first that does match */
733 
734 								for (j = 0;
735 								     j < ldns_rr_list_rr_count(cur_rrset) &&
736 										ldns_dname_compare(ldns_rr_owner(cur_sig_rr),ldns_rr_owner(cur_rr)) != 0;
737 								     j++) {
738 									cur_rr = ldns_rr_list_rr(cur_rrset, j);
739 
740 								}
741 								if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
742 												   ldns_rr_owner(cur_rr)))
743 									{
744 										break;
745 									}
746 							}
747 
748 					}
749 					/* option 1 */
750 					if (data_chain->parent) {
751 						ldns_dnssec_derive_trust_tree_normal_rrset_time(
752 						    new_tree,
753 						    data_chain,
754 						    cur_sig_rr,
755 						    check_time);
756 					}
757 
758 					/* option 2 */
759 					ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
760 					    new_tree,
761 					    data_chain,
762 					    cur_rr,
763 					    cur_sig_rr,
764 					    check_time);
765 				}
766 
767 				ldns_dnssec_derive_trust_tree_ds_rrset_time(
768 						new_tree, data_chain,
769 						cur_rr, check_time);
770 			} else {
771 				/* no signatures? maybe it's nsec data */
772 
773 				/* just add every rr from parent as new parent */
774 				ldns_dnssec_derive_trust_tree_no_sig_time(
775 					new_tree, data_chain, check_time);
776 			}
777 		}
778 	}
779 
780 	return new_tree;
781 }
782 
783 ldns_dnssec_trust_tree *
784 ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr)
785 {
786 	return ldns_dnssec_derive_trust_tree_time(data_chain, rr, ldns_time(NULL));
787 }
788 
789 void
790 ldns_dnssec_derive_trust_tree_normal_rrset_time(
791 		ldns_dnssec_trust_tree *new_tree,
792 		ldns_dnssec_data_chain *data_chain,
793 		ldns_rr *cur_sig_rr,
794 		time_t check_time)
795 {
796 	size_t i, j;
797 	ldns_rr_list *cur_rrset = ldns_rr_list_clone(data_chain->rrset);
798 	ldns_dnssec_trust_tree *cur_parent_tree;
799 	ldns_rr *cur_parent_rr;
800 	uint16_t cur_keytag;
801 	ldns_rr_list *tmp_rrset = NULL;
802 	ldns_status cur_status;
803 
804 	cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
805 
806 	for (j = 0; j < ldns_rr_list_rr_count(data_chain->parent->rrset); j++) {
807 		cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
808 		if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
809 			if (ldns_calc_keytag(cur_parent_rr) == cur_keytag) {
810 
811 				/* TODO: check wildcard nsec too */
812 				if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
813 					tmp_rrset = cur_rrset;
814 					if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
815 					    == LDNS_RR_TYPE_NSEC ||
816 					    ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
817 					    == LDNS_RR_TYPE_NSEC3) {
818 						/* might contain different names!
819 						   sort and split */
820 						ldns_rr_list_sort(cur_rrset);
821 						assert(tmp_rrset == cur_rrset);
822 						tmp_rrset = ldns_rr_list_pop_rrset(cur_rrset);
823 
824 						/* with nsecs, this might be the wrong one */
825 						while (tmp_rrset &&
826 						       ldns_rr_list_rr_count(cur_rrset) > 0 &&
827 						       ldns_dname_compare(
828 								ldns_rr_owner(ldns_rr_list_rr(
829 										        tmp_rrset, 0)),
830 								ldns_rr_owner(cur_sig_rr)) != 0) {
831 							ldns_rr_list_deep_free(tmp_rrset);
832 							tmp_rrset =
833 								ldns_rr_list_pop_rrset(cur_rrset);
834 						}
835 					}
836 					cur_status = ldns_verify_rrsig_time(
837 							tmp_rrset,
838 							cur_sig_rr,
839 							cur_parent_rr,
840 							check_time);
841 					if (tmp_rrset && tmp_rrset != cur_rrset
842 							) {
843 						ldns_rr_list_deep_free(
844 								tmp_rrset);
845 						tmp_rrset = NULL;
846 					}
847 					/* avoid dupes */
848 					for (i = 0; i < new_tree->parent_count; i++) {
849 						if (cur_parent_rr == new_tree->parents[i]->rr) {
850 							goto done;
851 						}
852 					}
853 
854 					cur_parent_tree =
855 						ldns_dnssec_derive_trust_tree_time(
856 								data_chain->parent,
857 						                cur_parent_rr,
858 								check_time);
859 					(void)ldns_dnssec_trust_tree_add_parent(new_tree,
860 					           cur_parent_tree,
861 					           cur_sig_rr,
862 					           cur_status);
863 				}
864 			}
865 		}
866 	}
867  done:
868 	ldns_rr_list_deep_free(cur_rrset);
869 }
870 
871 void
872 ldns_dnssec_derive_trust_tree_normal_rrset(ldns_dnssec_trust_tree *new_tree,
873                                            ldns_dnssec_data_chain *data_chain,
874                                            ldns_rr *cur_sig_rr)
875 {
876 	ldns_dnssec_derive_trust_tree_normal_rrset_time(
877 			new_tree, data_chain, cur_sig_rr, ldns_time(NULL));
878 }
879 
880 void
881 ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
882 		ldns_dnssec_trust_tree *new_tree,
883 		ldns_dnssec_data_chain *data_chain,
884 		ldns_rr *cur_rr,
885 		ldns_rr *cur_sig_rr,
886 		time_t check_time)
887 {
888 	size_t j;
889 	ldns_rr_list *cur_rrset = data_chain->rrset;
890 	ldns_dnssec_trust_tree *cur_parent_tree;
891 	ldns_rr *cur_parent_rr;
892 	uint16_t cur_keytag;
893 	ldns_status cur_status;
894 
895 	cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
896 
897 	for (j = 0; j < ldns_rr_list_rr_count(cur_rrset); j++) {
898 		cur_parent_rr = ldns_rr_list_rr(cur_rrset, j);
899 		if (cur_parent_rr != cur_rr &&
900 		    ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
901 			if (ldns_calc_keytag(cur_parent_rr) == cur_keytag
902 			    ) {
903 				cur_parent_tree = ldns_dnssec_trust_tree_new();
904 				cur_parent_tree->rr = cur_parent_rr;
905 				cur_parent_tree->rrset = cur_rrset;
906 				cur_status = ldns_verify_rrsig_time(
907 						cur_rrset, cur_sig_rr,
908 						cur_parent_rr, check_time);
909 				if (ldns_dnssec_trust_tree_add_parent(new_tree,
910 				            cur_parent_tree, cur_sig_rr, cur_status))
911 					ldns_dnssec_trust_tree_free(cur_parent_tree);
912 			}
913 		}
914 	}
915 }
916 
917 void
918 ldns_dnssec_derive_trust_tree_dnskey_rrset(ldns_dnssec_trust_tree *new_tree,
919                                            ldns_dnssec_data_chain *data_chain,
920                                            ldns_rr *cur_rr,
921                                            ldns_rr *cur_sig_rr)
922 {
923 	ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
924 			new_tree, data_chain, cur_rr, cur_sig_rr, ldns_time(NULL));
925 }
926 
927 void
928 ldns_dnssec_derive_trust_tree_ds_rrset_time(
929 		ldns_dnssec_trust_tree *new_tree,
930 		ldns_dnssec_data_chain *data_chain,
931 		ldns_rr *cur_rr,
932 		time_t check_time)
933 {
934 	size_t j, h;
935 	ldns_rr_list *cur_rrset = data_chain->rrset;
936 	ldns_dnssec_trust_tree *cur_parent_tree;
937 	ldns_rr *cur_parent_rr;
938 
939 	/* try the parent to see whether there are DSs there */
940 	if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_DNSKEY &&
941 	    data_chain->parent &&
942 	    data_chain->parent->rrset
943 	    ) {
944 		for (j = 0;
945 			j < ldns_rr_list_rr_count(data_chain->parent->rrset);
946 			j++) {
947 			cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
948 			if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DS) {
949 				for (h = 0; h < ldns_rr_list_rr_count(cur_rrset); h++) {
950 					cur_rr = ldns_rr_list_rr(cur_rrset, h);
951 					if (ldns_rr_compare_ds(cur_rr, cur_parent_rr)) {
952 						cur_parent_tree =
953 							ldns_dnssec_derive_trust_tree_time(
954 							    data_chain->parent,
955 							    cur_parent_rr,
956 							    check_time);
957 						(void) ldns_dnssec_trust_tree_add_parent(
958 						            new_tree,
959 						            cur_parent_tree,
960 						            NULL,
961 						            LDNS_STATUS_OK);
962 					} else {
963 						/*ldns_rr_print(stdout, cur_parent_rr);*/
964 					}
965 				}
966 			}
967 		}
968 	}
969 }
970 
971 void
972 ldns_dnssec_derive_trust_tree_ds_rrset(ldns_dnssec_trust_tree *new_tree,
973                                        ldns_dnssec_data_chain *data_chain,
974                                        ldns_rr *cur_rr)
975 {
976 	ldns_dnssec_derive_trust_tree_ds_rrset_time(
977 			new_tree, data_chain, cur_rr, ldns_time(NULL));
978 }
979 
980 void
981 ldns_dnssec_derive_trust_tree_no_sig_time(
982 		ldns_dnssec_trust_tree *new_tree,
983 		ldns_dnssec_data_chain *data_chain,
984 		time_t check_time)
985 {
986 	size_t i;
987 	ldns_rr_list *cur_rrset;
988 	ldns_rr *cur_parent_rr;
989 	ldns_dnssec_trust_tree *cur_parent_tree;
990 	ldns_status result;
991 
992 	if (data_chain->parent && data_chain->parent->rrset) {
993 		cur_rrset = data_chain->parent->rrset;
994 		/* nsec? */
995 		if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
996 			if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
997 			    LDNS_RR_TYPE_NSEC3) {
998 				result = ldns_dnssec_verify_denial_nsec3(
999 					        new_tree->rr,
1000 						   cur_rrset,
1001 						   data_chain->parent->signatures,
1002 						   data_chain->packet_rcode,
1003 						   data_chain->packet_qtype,
1004 						   data_chain->packet_nodata);
1005 			} else if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
1006 					 LDNS_RR_TYPE_NSEC) {
1007 				result = ldns_dnssec_verify_denial(
1008 					        new_tree->rr,
1009 						   cur_rrset,
1010 						   data_chain->parent->signatures);
1011 			} else {
1012 				/* unsigned zone, unsigned parent */
1013 				result = LDNS_STATUS_OK;
1014 			}
1015 		} else {
1016 			result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1017 		}
1018 		for (i = 0; i < ldns_rr_list_rr_count(cur_rrset); i++) {
1019 			cur_parent_rr = ldns_rr_list_rr(cur_rrset, i);
1020 			cur_parent_tree =
1021 				ldns_dnssec_derive_trust_tree_time(
1022 						data_chain->parent,
1023 						cur_parent_rr,
1024 						check_time);
1025 			if (ldns_dnssec_trust_tree_add_parent(new_tree,
1026 			            cur_parent_tree, NULL, result))
1027 				ldns_dnssec_trust_tree_free(cur_parent_tree);
1028 
1029 		}
1030 	}
1031 }
1032 
1033 void
1034 ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree *new_tree,
1035                                      ldns_dnssec_data_chain *data_chain)
1036 {
1037 	ldns_dnssec_derive_trust_tree_no_sig_time(
1038 			new_tree, data_chain, ldns_time(NULL));
1039 }
1040 
1041 /*
1042  * returns OK if there is a path from tree to key with only OK
1043  * the (first) error in between otherwise
1044  * or NOT_FOUND if the key wasn't present at all
1045  */
1046 ldns_status
1047 ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree,
1048 							  ldns_rr_list *trusted_keys)
1049 {
1050 	size_t i;
1051 	ldns_status result = LDNS_STATUS_CRYPTO_NO_DNSKEY;
1052 	bool equal;
1053 	ldns_status parent_result;
1054 
1055 	if (tree && trusted_keys && ldns_rr_list_rr_count(trusted_keys) > 0)
1056 		{ if (tree->rr) {
1057 				for (i = 0; i < ldns_rr_list_rr_count(trusted_keys); i++) {
1058 					equal = ldns_rr_compare_ds(
1059 							  tree->rr,
1060 							  ldns_rr_list_rr(trusted_keys, i));
1061 					if (equal) {
1062 						result = LDNS_STATUS_OK;
1063 						return result;
1064 					}
1065 				}
1066 			}
1067 			for (i = 0; i < tree->parent_count; i++) {
1068 				parent_result =
1069 					ldns_dnssec_trust_tree_contains_keys(tree->parents[i],
1070 												  trusted_keys);
1071 				if (parent_result != LDNS_STATUS_CRYPTO_NO_DNSKEY) {
1072 					if (tree->parent_status[i] != LDNS_STATUS_OK) {
1073 						result = tree->parent_status[i];
1074 					} else {
1075 						if (tree->rr &&
1076 						    ldns_rr_get_type(tree->rr)
1077 						    == LDNS_RR_TYPE_NSEC &&
1078 						    parent_result == LDNS_STATUS_OK
1079 						    ) {
1080 							result =
1081 								LDNS_STATUS_DNSSEC_EXISTENCE_DENIED;
1082 						} else {
1083 							result = parent_result;
1084 						}
1085 					}
1086 				}
1087 			}
1088 		} else {
1089 		result = LDNS_STATUS_ERR;
1090 	}
1091 
1092 	return result;
1093 }
1094 
1095 ldns_status
1096 ldns_verify_time(
1097 		const ldns_rr_list *rrset,
1098 		const ldns_rr_list *rrsig,
1099 		const ldns_rr_list *keys,
1100 		time_t check_time,
1101 		ldns_rr_list *good_keys
1102 		)
1103 {
1104 	uint16_t i;
1105 	ldns_status verify_result = LDNS_STATUS_ERR;
1106 
1107 	if (!rrset || !rrsig || !keys) {
1108 		return LDNS_STATUS_ERR;
1109 	}
1110 
1111 	if (ldns_rr_list_rr_count(rrset) < 1) {
1112 		return LDNS_STATUS_ERR;
1113 	}
1114 
1115 	if (ldns_rr_list_rr_count(rrsig) < 1) {
1116 		return LDNS_STATUS_CRYPTO_NO_RRSIG;
1117 	}
1118 
1119 	if (ldns_rr_list_rr_count(keys) < 1) {
1120 		verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1121 	} else {
1122 		for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1123 			ldns_status s = ldns_verify_rrsig_keylist_time(
1124 					rrset, ldns_rr_list_rr(rrsig, i),
1125 					keys, check_time, good_keys);
1126 			/* try a little to get more descriptive error */
1127 			if(s == LDNS_STATUS_OK) {
1128 				verify_result = LDNS_STATUS_OK;
1129 			} else if(verify_result == LDNS_STATUS_ERR)
1130 				verify_result = s;
1131 			else if(s !=  LDNS_STATUS_ERR && verify_result ==
1132 				LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY)
1133 				verify_result = s;
1134 		}
1135 	}
1136 	return verify_result;
1137 }
1138 
1139 ldns_status
1140 ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys,
1141 		  ldns_rr_list *good_keys)
1142 {
1143 	return ldns_verify_time(rrset, rrsig, keys, ldns_time(NULL), good_keys);
1144 }
1145 
1146 ldns_status
1147 ldns_verify_notime(ldns_rr_list *rrset, ldns_rr_list *rrsig,
1148 	const ldns_rr_list *keys, ldns_rr_list *good_keys)
1149 {
1150 	uint16_t i;
1151 	ldns_status verify_result = LDNS_STATUS_ERR;
1152 
1153 	if (!rrset || !rrsig || !keys) {
1154 		return LDNS_STATUS_ERR;
1155 	}
1156 
1157 	if (ldns_rr_list_rr_count(rrset) < 1) {
1158 		return LDNS_STATUS_ERR;
1159 	}
1160 
1161 	if (ldns_rr_list_rr_count(rrsig) < 1) {
1162 		return LDNS_STATUS_CRYPTO_NO_RRSIG;
1163 	}
1164 
1165 	if (ldns_rr_list_rr_count(keys) < 1) {
1166 		verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1167 	} else {
1168 		for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1169 			ldns_status s = ldns_verify_rrsig_keylist_notime(rrset,
1170 				ldns_rr_list_rr(rrsig, i), keys, good_keys);
1171 
1172 			/* try a little to get more descriptive error */
1173 			if (s == LDNS_STATUS_OK) {
1174 				verify_result = LDNS_STATUS_OK;
1175 			} else if (verify_result == LDNS_STATUS_ERR) {
1176 				verify_result = s;
1177 			} else if (s !=  LDNS_STATUS_ERR && verify_result ==
1178 				LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
1179 				verify_result = s;
1180 			}
1181 		}
1182 	}
1183 	return verify_result;
1184 }
1185 
1186 ldns_rr_list *
1187 ldns_fetch_valid_domain_keys_time(const ldns_resolver *res,
1188                              const ldns_rdf *domain,
1189                              const ldns_rr_list *keys,
1190 			     time_t check_time,
1191                              ldns_status *status)
1192 {
1193 	ldns_rr_list * trusted_keys = NULL;
1194 	ldns_rr_list * ds_keys = NULL;
1195 	ldns_rdf * prev_parent_domain;
1196 	ldns_rdf *      parent_domain;
1197 	ldns_rr_list * parent_keys = NULL;
1198 
1199 	if (res && domain && keys) {
1200 
1201 		if ((trusted_keys = ldns_validate_domain_dnskey_time(res,
1202                                          domain, keys, check_time))) {
1203 			*status = LDNS_STATUS_OK;
1204 		} else {
1205 			/* No trusted keys in this domain, we'll have to find some in the parent domain */
1206 			*status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1207 
1208 			parent_domain = ldns_dname_left_chop(domain);
1209 			while (parent_domain && /* Fail if we are at the root*/
1210 					ldns_rdf_size(parent_domain) > 0) {
1211 
1212 				if ((parent_keys =
1213 					ldns_fetch_valid_domain_keys_time(res,
1214 					     parent_domain,
1215 					     keys,
1216 					     check_time,
1217 					     status))) {
1218 					/* Check DS records */
1219 					if ((ds_keys =
1220 						ldns_validate_domain_ds_time(res,
1221 						     domain,
1222 						     parent_keys,
1223 						     check_time))) {
1224 						trusted_keys =
1225 						ldns_fetch_valid_domain_keys_time(
1226 								res,
1227 								domain,
1228 								ds_keys,
1229 								check_time,
1230 								status);
1231 						ldns_rr_list_deep_free(ds_keys);
1232 					} else {
1233 						/* No valid DS at the parent -- fail */
1234 						*status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DS ;
1235 					}
1236 					ldns_rr_list_deep_free(parent_keys);
1237 					break;
1238 				} else {
1239 					parent_domain = ldns_dname_left_chop((
1240 						prev_parent_domain
1241 							= parent_domain
1242 						));
1243 					ldns_rdf_deep_free(prev_parent_domain);
1244 				}
1245 			}
1246 			if (parent_domain) {
1247 				ldns_rdf_deep_free(parent_domain);
1248 			}
1249 		}
1250 	}
1251 	return trusted_keys;
1252 }
1253 
1254 ldns_rr_list *
1255 ldns_fetch_valid_domain_keys(const ldns_resolver *res,
1256                              const ldns_rdf *domain,
1257                              const ldns_rr_list *keys,
1258                              ldns_status *status)
1259 {
1260 	return ldns_fetch_valid_domain_keys_time(
1261 			res, domain, keys, ldns_time(NULL), status);
1262 }
1263 
1264 ldns_rr_list *
1265 ldns_validate_domain_dnskey_time(
1266 		const ldns_resolver * res,
1267 		const ldns_rdf * domain,
1268 		const ldns_rr_list * keys,
1269 		time_t check_time
1270 		)
1271 {
1272 	ldns_pkt * keypkt;
1273 	ldns_rr * cur_key;
1274 	uint16_t key_i; uint16_t key_j; uint16_t key_k;
1275 	uint16_t sig_i; ldns_rr * cur_sig;
1276 
1277 	ldns_rr_list * domain_keys = NULL;
1278 	ldns_rr_list * domain_sigs = NULL;
1279 	ldns_rr_list * trusted_keys = NULL;
1280 
1281 	/* Fetch keys for the domain */
1282 	keypkt = ldns_resolver_query(res, domain,
1283 		LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, LDNS_RD);
1284 	if (keypkt) {
1285 		domain_keys = ldns_pkt_rr_list_by_type(keypkt,
1286 									    LDNS_RR_TYPE_DNSKEY,
1287 									    LDNS_SECTION_ANSWER);
1288 		domain_sigs = ldns_pkt_rr_list_by_type(keypkt,
1289 									    LDNS_RR_TYPE_RRSIG,
1290 									    LDNS_SECTION_ANSWER);
1291 
1292 		/* Try to validate the record using our keys */
1293 		for (key_i=0; key_i< ldns_rr_list_rr_count(domain_keys); key_i++) {
1294 
1295 			cur_key = ldns_rr_list_rr(domain_keys, key_i);
1296 			for (key_j=0; key_j<ldns_rr_list_rr_count(keys); key_j++) {
1297 				if (ldns_rr_compare_ds(ldns_rr_list_rr(keys, key_j),
1298 								   cur_key)) {
1299 
1300 					/* Current key is trusted -- validate */
1301 					trusted_keys = ldns_rr_list_new();
1302 
1303 					for (sig_i=0;
1304 						sig_i<ldns_rr_list_rr_count(domain_sigs);
1305 						sig_i++) {
1306 						cur_sig = ldns_rr_list_rr(domain_sigs, sig_i);
1307 						/* Avoid non-matching sigs */
1308 						if (ldns_rdf2native_int16(
1309 							   ldns_rr_rrsig_keytag(cur_sig))
1310 						    == ldns_calc_keytag(cur_key)) {
1311 							if (ldns_verify_rrsig_time(
1312 									domain_keys,
1313 									cur_sig,
1314 									cur_key,
1315 									check_time)
1316 							    == LDNS_STATUS_OK) {
1317 
1318 								/* Push the whole rrset
1319 								   -- we can't do much more */
1320 								for (key_k=0;
1321 									key_k<ldns_rr_list_rr_count(
1322 											domain_keys);
1323 									key_k++) {
1324 									ldns_rr_list_push_rr(
1325 									    trusted_keys,
1326 									    ldns_rr_clone(
1327 										   ldns_rr_list_rr(
1328 											  domain_keys,
1329 											  key_k)));
1330 								}
1331 
1332 								ldns_rr_list_deep_free(domain_keys);
1333 								ldns_rr_list_deep_free(domain_sigs);
1334 								ldns_pkt_free(keypkt);
1335 								return trusted_keys;
1336 							}
1337 						}
1338 					}
1339 
1340 					/* Only push our trusted key */
1341 					ldns_rr_list_push_rr(trusted_keys,
1342 									 ldns_rr_clone(cur_key));
1343 				}
1344 			}
1345 		}
1346 
1347 		ldns_rr_list_deep_free(domain_keys);
1348 		ldns_rr_list_deep_free(domain_sigs);
1349 		ldns_pkt_free(keypkt);
1350 
1351 	} else {
1352 		/* LDNS_STATUS_CRYPTO_NO_DNSKEY */
1353 	}
1354 
1355 	return trusted_keys;
1356 }
1357 
1358 ldns_rr_list *
1359 ldns_validate_domain_dnskey(const ldns_resolver * res,
1360 					   const ldns_rdf * domain,
1361 					   const ldns_rr_list * keys)
1362 {
1363 	return ldns_validate_domain_dnskey_time(
1364 			res, domain, keys, ldns_time(NULL));
1365 }
1366 
1367 ldns_rr_list *
1368 ldns_validate_domain_ds_time(
1369 		const ldns_resolver *res,
1370 		const ldns_rdf * domain,
1371 		const ldns_rr_list * keys,
1372 		time_t check_time)
1373 {
1374 	ldns_pkt * dspkt;
1375 	uint16_t key_i;
1376 	ldns_rr_list * rrset = NULL;
1377 	ldns_rr_list * sigs = NULL;
1378 	ldns_rr_list * trusted_keys = NULL;
1379 
1380 	/* Fetch DS for the domain */
1381 	dspkt = ldns_resolver_query(res, domain,
1382 		LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN, LDNS_RD);
1383 	if (dspkt) {
1384 		rrset = ldns_pkt_rr_list_by_type(dspkt,
1385 								   LDNS_RR_TYPE_DS,
1386 								   LDNS_SECTION_ANSWER);
1387 		sigs = ldns_pkt_rr_list_by_type(dspkt,
1388 								  LDNS_RR_TYPE_RRSIG,
1389 								  LDNS_SECTION_ANSWER);
1390 
1391 		/* Validate sigs */
1392 		if (ldns_verify_time(rrset, sigs, keys, check_time, NULL)
1393 			       	== LDNS_STATUS_OK) {
1394 			trusted_keys = ldns_rr_list_new();
1395 			for (key_i=0; key_i<ldns_rr_list_rr_count(rrset); key_i++) {
1396 				ldns_rr_list_push_rr(trusted_keys,
1397 								 ldns_rr_clone(ldns_rr_list_rr(rrset,
1398 														 key_i)
1399 											)
1400 								 );
1401 			}
1402 		}
1403 
1404 		ldns_rr_list_deep_free(rrset);
1405 		ldns_rr_list_deep_free(sigs);
1406 		ldns_pkt_free(dspkt);
1407 
1408 	} else {
1409 		/* LDNS_STATUS_CRYPTO_NO_DS */
1410 	}
1411 
1412 	return trusted_keys;
1413 }
1414 
1415 ldns_rr_list *
1416 ldns_validate_domain_ds(const ldns_resolver *res,
1417 				    const ldns_rdf * domain,
1418 				    const ldns_rr_list * keys)
1419 {
1420 	return ldns_validate_domain_ds_time(res, domain, keys, ldns_time(NULL));
1421 }
1422 
1423 ldns_status
1424 ldns_verify_trusted_time(
1425 		ldns_resolver *res,
1426 		ldns_rr_list *rrset,
1427 		ldns_rr_list * rrsigs,
1428 		time_t check_time,
1429 		ldns_rr_list * validating_keys
1430 		)
1431 {
1432 	uint16_t sig_i; uint16_t key_i;
1433 	ldns_rr * cur_sig; ldns_rr * cur_key;
1434 	ldns_rr_list * trusted_keys = NULL;
1435 	ldns_status result = LDNS_STATUS_ERR;
1436 
1437 	if (!res || !rrset || !rrsigs) {
1438 		return LDNS_STATUS_ERR;
1439 	}
1440 
1441 	if (ldns_rr_list_rr_count(rrset) < 1) {
1442 		return LDNS_STATUS_ERR;
1443 	}
1444 
1445 	if (ldns_rr_list_rr_count(rrsigs) < 1) {
1446 		return LDNS_STATUS_CRYPTO_NO_RRSIG;
1447 	}
1448 
1449 	/* Look at each sig */
1450 	for (sig_i=0; sig_i < ldns_rr_list_rr_count(rrsigs); sig_i++) {
1451 
1452 		cur_sig = ldns_rr_list_rr(rrsigs, sig_i);
1453 		/* Get a valid signer key and validate the sig */
1454 		if ((trusted_keys = ldns_fetch_valid_domain_keys_time(
1455 					res,
1456 					ldns_rr_rrsig_signame(cur_sig),
1457 					ldns_resolver_dnssec_anchors(res),
1458 					check_time,
1459 					&result))) {
1460 
1461 			for (key_i = 0;
1462 				key_i < ldns_rr_list_rr_count(trusted_keys);
1463 				key_i++) {
1464 				cur_key = ldns_rr_list_rr(trusted_keys, key_i);
1465 
1466 				if ((result = ldns_verify_rrsig_time(rrset,
1467 								cur_sig,
1468 								cur_key,
1469 								check_time))
1470 				    == LDNS_STATUS_OK) {
1471 					if (validating_keys) {
1472 						ldns_rr_list_push_rr(validating_keys,
1473 										 ldns_rr_clone(cur_key));
1474 					}
1475 					ldns_rr_list_deep_free(trusted_keys);
1476 					return LDNS_STATUS_OK;
1477 				}
1478 			}
1479 		}
1480 	}
1481 
1482 	ldns_rr_list_deep_free(trusted_keys);
1483 	return result;
1484 }
1485 
1486 ldns_status
1487 ldns_verify_trusted(
1488 		ldns_resolver *res,
1489 		ldns_rr_list *rrset,
1490 		ldns_rr_list * rrsigs,
1491 		ldns_rr_list * validating_keys)
1492 {
1493 	return ldns_verify_trusted_time(
1494 			res, rrset, rrsigs, ldns_time(NULL), validating_keys);
1495 }
1496 
1497 
1498 ldns_status
1499 ldns_dnssec_verify_denial(ldns_rr *rr,
1500                           ldns_rr_list *nsecs,
1501                           ldns_rr_list *rrsigs)
1502 {
1503 	ldns_rdf *rr_name;
1504 	ldns_rdf *wildcard_name;
1505 	ldns_rdf *chopped_dname;
1506 	ldns_rr *cur_nsec;
1507 	size_t i;
1508 	ldns_status result;
1509 	/* needed for wildcard check on exact match */
1510 	ldns_rr *rrsig;
1511 	bool name_covered = false;
1512 	bool type_covered = false;
1513 	bool wildcard_covered = false;
1514 	bool wildcard_type_covered = false;
1515 
1516 	wildcard_name = ldns_dname_new_frm_str("*");
1517 	rr_name = ldns_rr_owner(rr);
1518 	chopped_dname = ldns_dname_left_chop(rr_name);
1519 	result = ldns_dname_cat(wildcard_name, chopped_dname);
1520 	ldns_rdf_deep_free(chopped_dname);
1521 	if (result != LDNS_STATUS_OK) {
1522 		return result;
1523 	}
1524 
1525 	for  (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1526 		cur_nsec = ldns_rr_list_rr(nsecs, i);
1527 		if (ldns_dname_compare(rr_name, ldns_rr_owner(cur_nsec)) == 0) {
1528 			/* see section 5.4 of RFC4035, if the label count of the NSEC's
1529 			   RRSIG is equal, then it is proven that wildcard expansion
1530 			   could not have been used to match the request */
1531 			rrsig = ldns_dnssec_get_rrsig_for_name_and_type(
1532 					  ldns_rr_owner(cur_nsec),
1533 					  ldns_rr_get_type(cur_nsec),
1534 					  rrsigs);
1535 			if (rrsig && ldns_rdf2native_int8(ldns_rr_rrsig_labels(rrsig))
1536 			    == ldns_dname_label_count(rr_name)) {
1537 				wildcard_covered = true;
1538 			}
1539 
1540 			if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
1541 									   ldns_rr_get_type(rr))) {
1542 				type_covered = true;
1543 			}
1544 		}
1545 		if (ldns_nsec_covers_name(cur_nsec, rr_name)) {
1546 			name_covered = true;
1547 		}
1548 
1549 		if (ldns_dname_compare(wildcard_name,
1550 						   ldns_rr_owner(cur_nsec)) == 0) {
1551 			if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
1552 									   ldns_rr_get_type(rr))) {
1553 				wildcard_type_covered = true;
1554 			}
1555 		}
1556 
1557 		if (ldns_nsec_covers_name(cur_nsec, wildcard_name)) {
1558 			wildcard_covered = true;
1559 		}
1560 
1561 	}
1562 
1563 	ldns_rdf_deep_free(wildcard_name);
1564 
1565 	if (type_covered || !name_covered) {
1566 		return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1567 	}
1568 
1569 	if (wildcard_type_covered || !wildcard_covered) {
1570 		return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
1571 	}
1572 
1573 	return LDNS_STATUS_OK;
1574 }
1575 
1576 ldns_status
1577 ldns_dnssec_verify_denial_nsec3_match( ldns_rr *rr
1578 				     , ldns_rr_list *nsecs
1579 				     , ATTR_UNUSED(ldns_rr_list *rrsigs)
1580 				     , ldns_pkt_rcode packet_rcode
1581 				     , ldns_rr_type packet_qtype
1582 				     , bool packet_nodata
1583 				     , ldns_rr **match
1584 				     )
1585 {
1586 	ldns_rdf *closest_encloser;
1587 	ldns_rdf *wildcard;
1588 	ldns_rdf *hashed_wildcard_name;
1589 	bool wildcard_covered = false;
1590 	ldns_rdf *zone_name;
1591 	ldns_rdf *hashed_name;
1592 	ldns_rdf *hashed_next_closer;
1593 	size_t i;
1594 	ldns_status result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1595 
1596 	if (match) {
1597 		*match = NULL;
1598 	}
1599 
1600 	zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
1601 
1602 	/* section 8.4 */
1603 	if (packet_rcode == LDNS_RCODE_NXDOMAIN) {
1604 		closest_encloser = ldns_dnssec_nsec3_closest_encloser(
1605 						   ldns_rr_owner(rr),
1606 						   ldns_rr_get_type(rr),
1607 						   nsecs);
1608                 if(!closest_encloser) {
1609                         result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1610                         goto done;
1611                 }
1612 
1613 		wildcard = ldns_dname_new_frm_str("*");
1614 		(void) ldns_dname_cat(wildcard, closest_encloser);
1615 
1616 		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1617 			hashed_wildcard_name =
1618 				ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
1619 										 wildcard
1620 										 );
1621 			(void) ldns_dname_cat(hashed_wildcard_name, zone_name);
1622 
1623 			if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
1624 								 hashed_wildcard_name)) {
1625 				wildcard_covered = true;
1626 				if (match) {
1627 					*match = ldns_rr_list_rr(nsecs, i);
1628 				}
1629 			}
1630 			ldns_rdf_deep_free(hashed_wildcard_name);
1631 		}
1632 
1633 		if (! wildcard_covered) {
1634 			result = LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
1635 		} else {
1636 			result = LDNS_STATUS_OK;
1637 		}
1638 		ldns_rdf_deep_free(closest_encloser);
1639 		ldns_rdf_deep_free(wildcard);
1640 
1641 	} else if (packet_nodata && packet_qtype != LDNS_RR_TYPE_DS) {
1642 		/* section 8.5 */
1643 		hashed_name = ldns_nsec3_hash_name_frm_nsec3(
1644 		                   ldns_rr_list_rr(nsecs, 0),
1645 		                   ldns_rr_owner(rr));
1646 		(void) ldns_dname_cat(hashed_name, zone_name);
1647 		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1648 			if (ldns_dname_compare(hashed_name,
1649 			         ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
1650 			    == 0) {
1651 				if (!ldns_nsec_bitmap_covers_type(
1652 					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1653 					    packet_qtype)
1654 				    &&
1655 				    !ldns_nsec_bitmap_covers_type(
1656 					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1657 					    LDNS_RR_TYPE_CNAME)) {
1658 					result = LDNS_STATUS_OK;
1659 					if (match) {
1660 						*match = ldns_rr_list_rr(nsecs, i);
1661 					}
1662 					goto done;
1663 				}
1664 			}
1665 		}
1666 		ldns_rdf_deep_free(hashed_name);
1667 		result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1668 		/* wildcard no data? section 8.7 */
1669 		closest_encloser = ldns_dnssec_nsec3_closest_encloser(
1670 				   ldns_rr_owner(rr),
1671 				   ldns_rr_get_type(rr),
1672 				   nsecs);
1673 		if(!closest_encloser) {
1674 			result = LDNS_STATUS_NSEC3_ERR;
1675 			goto done;
1676 		}
1677 		wildcard = ldns_dname_new_frm_str("*");
1678 		(void) ldns_dname_cat(wildcard, closest_encloser);
1679 		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1680 			hashed_wildcard_name =
1681 				ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
1682 					 wildcard);
1683 			(void) ldns_dname_cat(hashed_wildcard_name, zone_name);
1684 
1685 			if (ldns_dname_compare(hashed_wildcard_name,
1686 			         ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
1687 			    == 0) {
1688 				if (!ldns_nsec_bitmap_covers_type(
1689 					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1690 					    packet_qtype)
1691 				    &&
1692 				    !ldns_nsec_bitmap_covers_type(
1693 					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1694 					    LDNS_RR_TYPE_CNAME)) {
1695 					result = LDNS_STATUS_OK;
1696 					if (match) {
1697 						*match = ldns_rr_list_rr(nsecs, i);
1698 					}
1699 				}
1700 			}
1701 			ldns_rdf_deep_free(hashed_wildcard_name);
1702 			if (result == LDNS_STATUS_OK) {
1703 				break;
1704 			}
1705 		}
1706 		ldns_rdf_deep_free(closest_encloser);
1707 		ldns_rdf_deep_free(wildcard);
1708 	} else if (packet_nodata && packet_qtype == LDNS_RR_TYPE_DS) {
1709 		/* section 8.6 */
1710 		/* note: up to XXX this is the same as for 8.5 */
1711 		hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs,
1712 														 0),
1713 											ldns_rr_owner(rr)
1714 											);
1715 		(void) ldns_dname_cat(hashed_name, zone_name);
1716 		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1717 			if (ldns_dname_compare(hashed_name,
1718 							   ldns_rr_owner(ldns_rr_list_rr(nsecs,
1719 													   i)))
1720 			    == 0) {
1721 				if (!ldns_nsec_bitmap_covers_type(
1722 					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1723 					    LDNS_RR_TYPE_DS)
1724 				    &&
1725 				    !ldns_nsec_bitmap_covers_type(
1726 					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1727 					    LDNS_RR_TYPE_CNAME)) {
1728 					result = LDNS_STATUS_OK;
1729 					if (match) {
1730 						*match = ldns_rr_list_rr(nsecs, i);
1731 					}
1732 					goto done;
1733 				}
1734 			}
1735 		}
1736 
1737 		/* XXX see note above */
1738 		result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1739 
1740 		closest_encloser = ldns_dnssec_nsec3_closest_encloser(
1741 				   ldns_rr_owner(rr),
1742 				   ldns_rr_get_type(rr),
1743 				   nsecs);
1744 		if(!closest_encloser) {
1745 			result = LDNS_STATUS_NSEC3_ERR;
1746 			goto done;
1747 		}
1748 		/* Now check if we have a Opt-Out NSEC3 that covers the "next closer"*/
1749 
1750 		if (ldns_dname_label_count(closest_encloser) + 1
1751 		    >= ldns_dname_label_count(ldns_rr_owner(rr))) {
1752 
1753 			/* Query name *is* the "next closer". */
1754 			hashed_next_closer = hashed_name;
1755 		} else {
1756 			ldns_rdf *next_closer;
1757 
1758 			ldns_rdf_deep_free(hashed_name);
1759 			/* "next closer" has less labels than the query name.
1760 			 * Create the name and hash it.
1761 			 */
1762 			next_closer = ldns_dname_clone_from(
1763 					ldns_rr_owner(rr),
1764 					ldns_dname_label_count(ldns_rr_owner(rr))
1765 					- (ldns_dname_label_count(closest_encloser) + 1)
1766 					);
1767 			hashed_next_closer = ldns_nsec3_hash_name_frm_nsec3(
1768 					ldns_rr_list_rr(nsecs, 0),
1769 					next_closer
1770 					);
1771 			(void) ldns_dname_cat(hashed_next_closer, zone_name);
1772 			ldns_rdf_deep_free(next_closer);
1773 		}
1774 		/* Find the NSEC3 that covers the "next closer" */
1775 		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1776 			if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
1777 			                          hashed_next_closer) &&
1778 				ldns_nsec3_optout(ldns_rr_list_rr(nsecs, i))) {
1779 
1780 				result = LDNS_STATUS_OK;
1781 				if (match) {
1782 					*match = ldns_rr_list_rr(nsecs, i);
1783 				}
1784 				break;
1785 			}
1786 		}
1787 		ldns_rdf_deep_free(hashed_next_closer);
1788 		ldns_rdf_deep_free(closest_encloser);
1789 	}
1790 
1791  done:
1792 	ldns_rdf_deep_free(zone_name);
1793 	return result;
1794 }
1795 
1796 ldns_status
1797 ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
1798 						  ldns_rr_list *nsecs,
1799 						  ldns_rr_list *rrsigs,
1800 						  ldns_pkt_rcode packet_rcode,
1801 						  ldns_rr_type packet_qtype,
1802 						  bool packet_nodata)
1803 {
1804 	return ldns_dnssec_verify_denial_nsec3_match(
1805 				rr, nsecs, rrsigs, packet_rcode,
1806 				packet_qtype, packet_nodata, NULL
1807 	       );
1808 }
1809 
1810 #ifdef USE_GOST
1811 EVP_PKEY*
1812 ldns_gost2pkey_raw(const unsigned char* key, size_t keylen)
1813 {
1814 	/* prefix header for X509 encoding */
1815 	uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
1816 		0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
1817 		0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
1818 		0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
1819 	unsigned char encoded[37+64];
1820 	const unsigned char* pp;
1821 	if(keylen != 64) {
1822 		/* key wrong size */
1823 		return NULL;
1824 	}
1825 
1826 	/* create evp_key */
1827 	memmove(encoded, asn, 37);
1828 	memmove(encoded+37, key, 64);
1829 	pp = (unsigned char*)&encoded[0];
1830 
1831 	return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
1832 }
1833 
1834 static ldns_status
1835 ldns_verify_rrsig_gost_raw(const unsigned char* sig, size_t siglen,
1836 	const ldns_buffer* rrset, const unsigned char* key, size_t keylen)
1837 {
1838 	EVP_PKEY *evp_key;
1839 	ldns_status result;
1840 
1841 	(void) ldns_key_EVP_load_gost_id();
1842 	evp_key = ldns_gost2pkey_raw(key, keylen);
1843 	if(!evp_key) {
1844 		/* could not convert key */
1845 		return LDNS_STATUS_CRYPTO_BOGUS;
1846 	}
1847 
1848 	/* verify signature */
1849 	result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset,
1850 		evp_key, EVP_get_digestbyname("md_gost94"));
1851 	EVP_PKEY_free(evp_key);
1852 
1853 	return result;
1854 }
1855 #endif
1856 
1857 #ifdef USE_ED25519
1858 EVP_PKEY*
1859 ldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
1860 {
1861 	/* ASN1 for ED25519 is 302a300506032b6570032100 <32byteskey> */
1862 	uint8_t pre[] = {0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
1863 		0x70, 0x03, 0x21, 0x00};
1864         int pre_len = 12;
1865 	uint8_t buf[256];
1866         EVP_PKEY *evp_key;
1867 	/* pp gets modified by d2i() */
1868         const unsigned char* pp = (unsigned char*)buf;
1869 	if(keylen != 32 || keylen + pre_len > sizeof(buf))
1870 		return NULL; /* wrong length */
1871 	memmove(buf, pre, pre_len);
1872 	memmove(buf+pre_len, key, keylen);
1873 	evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
1874         return evp_key;
1875 }
1876 
1877 static ldns_status
1878 ldns_verify_rrsig_ed25519_raw(unsigned char* sig, size_t siglen,
1879 	ldns_buffer* rrset, unsigned char* key, size_t keylen)
1880 {
1881         EVP_PKEY *evp_key;
1882         ldns_status result;
1883 
1884         evp_key = ldns_ed255192pkey_raw(key, keylen);
1885         if(!evp_key) {
1886 		/* could not convert key */
1887 		return LDNS_STATUS_CRYPTO_BOGUS;
1888         }
1889 	result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, NULL);
1890 	EVP_PKEY_free(evp_key);
1891 	return result;
1892 }
1893 #endif /* USE_ED25519 */
1894 
1895 #ifdef USE_ED448
1896 EVP_PKEY*
1897 ldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
1898 {
1899 	/* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
1900 	uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
1901 		0x71, 0x03, 0x3a, 0x00};
1902         int pre_len = 12;
1903 	uint8_t buf[256];
1904         EVP_PKEY *evp_key;
1905 	/* pp gets modified by d2i() */
1906         const unsigned char* pp = (unsigned char*)buf;
1907 	if(keylen != 57 || keylen + pre_len > sizeof(buf))
1908 		return NULL; /* wrong length */
1909 	memmove(buf, pre, pre_len);
1910 	memmove(buf+pre_len, key, keylen);
1911 	evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
1912         return evp_key;
1913 }
1914 
1915 static ldns_status
1916 ldns_verify_rrsig_ed448_raw(unsigned char* sig, size_t siglen,
1917 	ldns_buffer* rrset, unsigned char* key, size_t keylen)
1918 {
1919         EVP_PKEY *evp_key;
1920         ldns_status result;
1921 
1922         evp_key = ldns_ed4482pkey_raw(key, keylen);
1923         if(!evp_key) {
1924 		/* could not convert key */
1925 		return LDNS_STATUS_CRYPTO_BOGUS;
1926         }
1927 	result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, NULL);
1928 	EVP_PKEY_free(evp_key);
1929 	return result;
1930 }
1931 #endif /* USE_ED448 */
1932 
1933 #ifdef USE_ECDSA
1934 EVP_PKEY*
1935 ldns_ecdsa2pkey_raw(const unsigned char* key, size_t keylen, uint8_t algo)
1936 {
1937 	unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
1938         const unsigned char* pp = buf;
1939         EVP_PKEY *evp_key;
1940         EC_KEY *ec;
1941 	/* check length, which uncompressed must be 2 bignums */
1942         if(algo == LDNS_ECDSAP256SHA256) {
1943 		if(keylen != 2*256/8) return NULL;
1944                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
1945         } else if(algo == LDNS_ECDSAP384SHA384) {
1946 		if(keylen != 2*384/8) return NULL;
1947                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
1948         } else    ec = NULL;
1949         if(!ec) return NULL;
1950 	if(keylen+1 > sizeof(buf))
1951 		return NULL; /* sanity check */
1952 	/* prepend the 0x02 (from docs) (or actually 0x04 from implementation
1953 	 * of openssl) for uncompressed data */
1954 	buf[0] = POINT_CONVERSION_UNCOMPRESSED;
1955 	memmove(buf+1, key, keylen);
1956         if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
1957                 EC_KEY_free(ec);
1958                 return NULL;
1959         }
1960         evp_key = EVP_PKEY_new();
1961         if(!evp_key) {
1962                 EC_KEY_free(ec);
1963                 return NULL;
1964         }
1965         if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
1966 		EVP_PKEY_free(evp_key);
1967 		EC_KEY_free(ec);
1968 		return NULL;
1969 	}
1970         return evp_key;
1971 }
1972 
1973 static ldns_status
1974 ldns_verify_rrsig_ecdsa_raw(unsigned char* sig, size_t siglen,
1975 	ldns_buffer* rrset, unsigned char* key, size_t keylen, uint8_t algo)
1976 {
1977         EVP_PKEY *evp_key;
1978         ldns_status result;
1979         const EVP_MD *d;
1980 
1981         evp_key = ldns_ecdsa2pkey_raw(key, keylen, algo);
1982         if(!evp_key) {
1983 		/* could not convert key */
1984 		return LDNS_STATUS_CRYPTO_BOGUS;
1985         }
1986         if(algo == LDNS_ECDSAP256SHA256)
1987                 d = EVP_sha256();
1988         else    d = EVP_sha384(); /* LDNS_ECDSAP384SHA384 */
1989 	result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, d);
1990 	EVP_PKEY_free(evp_key);
1991 	return result;
1992 }
1993 #endif
1994 
1995 ldns_status
1996 ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf,
1997 					 ldns_buffer *key_buf, uint8_t algo)
1998 {
1999 	return ldns_verify_rrsig_buffers_raw(
2000 			 (unsigned char*)ldns_buffer_begin(rawsig_buf),
2001 			 ldns_buffer_position(rawsig_buf),
2002 			 verify_buf,
2003 			 (unsigned char*)ldns_buffer_begin(key_buf),
2004 			 ldns_buffer_position(key_buf), algo);
2005 }
2006 
2007 ldns_status
2008 ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
2009 						ldns_buffer *verify_buf, unsigned char* key, size_t keylen,
2010 						uint8_t algo)
2011 {
2012 	/* check for right key */
2013 	switch(algo) {
2014 #ifdef USE_DSA
2015 	case LDNS_DSA:
2016 	case LDNS_DSA_NSEC3:
2017 		return ldns_verify_rrsig_dsa_raw(sig,
2018 								   siglen,
2019 								   verify_buf,
2020 								   key,
2021 								   keylen);
2022 		break;
2023 #endif
2024 	case LDNS_RSASHA1:
2025 	case LDNS_RSASHA1_NSEC3:
2026 		return ldns_verify_rrsig_rsasha1_raw(sig,
2027 									  siglen,
2028 									  verify_buf,
2029 									  key,
2030 									  keylen);
2031 		break;
2032 #ifdef USE_SHA2
2033 	case LDNS_RSASHA256:
2034 		return ldns_verify_rrsig_rsasha256_raw(sig,
2035 									    siglen,
2036 									    verify_buf,
2037 									    key,
2038 									    keylen);
2039 		break;
2040 	case LDNS_RSASHA512:
2041 		return ldns_verify_rrsig_rsasha512_raw(sig,
2042 									    siglen,
2043 									    verify_buf,
2044 									    key,
2045 									    keylen);
2046 		break;
2047 #endif
2048 #ifdef USE_GOST
2049 	case LDNS_ECC_GOST:
2050 		return ldns_verify_rrsig_gost_raw(sig, siglen, verify_buf,
2051 			key, keylen);
2052 		break;
2053 #endif
2054 #ifdef USE_ECDSA
2055         case LDNS_ECDSAP256SHA256:
2056         case LDNS_ECDSAP384SHA384:
2057 		return ldns_verify_rrsig_ecdsa_raw(sig, siglen, verify_buf,
2058 			key, keylen, algo);
2059 		break;
2060 #endif
2061 #ifdef USE_ED25519
2062 	case LDNS_ED25519:
2063 		return ldns_verify_rrsig_ed25519_raw(sig, siglen, verify_buf,
2064 			key, keylen);
2065 		break;
2066 #endif
2067 #ifdef USE_ED448
2068 	case LDNS_ED448:
2069 		return ldns_verify_rrsig_ed448_raw(sig, siglen, verify_buf,
2070 			key, keylen);
2071 		break;
2072 #endif
2073 	case LDNS_RSAMD5:
2074 		return ldns_verify_rrsig_rsamd5_raw(sig,
2075 									 siglen,
2076 									 verify_buf,
2077 									 key,
2078 									 keylen);
2079 		break;
2080 	default:
2081 		/* do you know this alg?! */
2082 		return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2083 	}
2084 }
2085 
2086 
2087 /**
2088  * Reset the ttl in the rrset with the orig_ttl from the sig
2089  * and update owner name if it was wildcard
2090  * Also canonicalizes the rrset.
2091  * @param rrset: rrset to modify
2092  * @param sig: signature to take TTL and wildcard values from
2093  */
2094 static void
2095 ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, const ldns_rr* rrsig)
2096 {
2097 	uint32_t orig_ttl;
2098 	uint16_t i;
2099 	uint8_t label_count;
2100 	ldns_rdf *wildcard_name;
2101 	ldns_rdf *wildcard_chopped;
2102 	ldns_rdf *wildcard_chopped_tmp;
2103 
2104 	if ((rrsig == NULL) || ldns_rr_rd_count(rrsig) < 4) {
2105 		return;
2106 	}
2107 
2108 	orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
2109 	label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
2110 
2111 	for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
2112 		if (label_count <
2113 		    ldns_dname_label_count(
2114 			   ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
2115 			(void) ldns_str2rdf_dname(&wildcard_name, "*");
2116 			wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(
2117 				ldns_rr_list_rr(rrset_clone, i)));
2118 			while (label_count < ldns_dname_label_count(wildcard_chopped)) {
2119 				wildcard_chopped_tmp = ldns_dname_left_chop(
2120 					wildcard_chopped);
2121 				ldns_rdf_deep_free(wildcard_chopped);
2122 				wildcard_chopped = wildcard_chopped_tmp;
2123 			}
2124 			(void) ldns_dname_cat(wildcard_name, wildcard_chopped);
2125 			ldns_rdf_deep_free(wildcard_chopped);
2126 			ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(
2127 				rrset_clone, i)));
2128 			ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i),
2129 				wildcard_name);
2130 		}
2131 		ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl);
2132 		/* convert to lowercase */
2133 		ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
2134 	}
2135 }
2136 
2137 /**
2138  * Make raw signature buffer out of rrsig
2139  * @param rawsig_buf: raw signature buffer for result
2140  * @param rrsig: signature to convert
2141  * @return OK or more specific error.
2142  */
2143 static ldns_status
2144 ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, const ldns_rr* rrsig)
2145 {
2146 	uint8_t sig_algo;
2147 
2148 	if (rrsig == NULL) {
2149 		return LDNS_STATUS_CRYPTO_NO_RRSIG;
2150 	}
2151 	if (ldns_rr_rdf(rrsig, 1) == NULL) {
2152 		return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2153 	}
2154 	sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
2155 	/* check for known and implemented algo's now (otherwise
2156 	 * the function could return a wrong error
2157 	 */
2158 	/* create a buffer with signature rdata */
2159 	/* for some algorithms we need other data than for others... */
2160 	/* (the DSA API wants DER encoding for instance) */
2161 
2162 	switch(sig_algo) {
2163 	case LDNS_RSAMD5:
2164 	case LDNS_RSASHA1:
2165 	case LDNS_RSASHA1_NSEC3:
2166 #ifdef USE_SHA2
2167 	case LDNS_RSASHA256:
2168 	case LDNS_RSASHA512:
2169 #endif
2170 #ifdef USE_GOST
2171 	case LDNS_ECC_GOST:
2172 #endif
2173 #ifdef USE_ED25519
2174 	case LDNS_ED25519:
2175 #endif
2176 #ifdef USE_ED448
2177 	case LDNS_ED448:
2178 #endif
2179 		if (ldns_rr_rdf(rrsig, 8) == NULL) {
2180 			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2181 		}
2182 		if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8))
2183 			       	!= LDNS_STATUS_OK) {
2184 			return LDNS_STATUS_MEM_ERR;
2185 		}
2186 		break;
2187 #ifdef USE_DSA
2188 	case LDNS_DSA:
2189 	case LDNS_DSA_NSEC3:
2190 		/* EVP takes rfc2459 format, which is a tad longer than dns format */
2191 		if (ldns_rr_rdf(rrsig, 8) == NULL) {
2192 			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2193 		}
2194 		if (ldns_convert_dsa_rrsig_rdf2asn1(
2195 					rawsig_buf, ldns_rr_rdf(rrsig, 8))
2196 				!= LDNS_STATUS_OK) {
2197 			/*
2198 			  if (ldns_rdf2buffer_wire(rawsig_buf,
2199 			  ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
2200 			*/
2201 			return LDNS_STATUS_MEM_ERR;
2202 		}
2203 		break;
2204 #endif
2205 #ifdef USE_ECDSA
2206         case LDNS_ECDSAP256SHA256:
2207         case LDNS_ECDSAP384SHA384:
2208                 /* EVP produces an ASN prefix on the signature, which is
2209                  * not used in the DNS */
2210 		if (ldns_rr_rdf(rrsig, 8) == NULL) {
2211 			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2212 		}
2213 		if (ldns_convert_ecdsa_rrsig_rdf2asn1(
2214 					rawsig_buf, ldns_rr_rdf(rrsig, 8))
2215 				!= LDNS_STATUS_OK) {
2216 			return LDNS_STATUS_MEM_ERR;
2217                 }
2218                 break;
2219 #endif
2220 	case LDNS_DH:
2221 	case LDNS_ECC:
2222 	case LDNS_INDIRECT:
2223 		return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
2224 	default:
2225 		return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2226 	}
2227 	return LDNS_STATUS_OK;
2228 }
2229 
2230 /**
2231  * Check RRSIG timestamps against the given 'now' time.
2232  * @param rrsig: signature to check.
2233  * @param now: the current time in seconds epoch.
2234  * @return status code LDNS_STATUS_OK if all is fine.
2235  */
2236 static ldns_status
2237 ldns_rrsig_check_timestamps(const ldns_rr* rrsig, time_t now)
2238 {
2239 	int32_t inception, expiration;
2240 
2241 	/* check the signature time stamps */
2242 	inception = (int32_t)ldns_rdf2native_time_t(
2243 		ldns_rr_rrsig_inception(rrsig));
2244 	expiration = (int32_t)ldns_rdf2native_time_t(
2245 		ldns_rr_rrsig_expiration(rrsig));
2246 
2247 	if (expiration - inception < 0) {
2248 		/* bad sig, expiration before inception?? Tsssg */
2249 		return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
2250 	}
2251 	if (((int32_t) now) - inception < 0) {
2252 		/* bad sig, inception date has not yet come to pass */
2253 		return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
2254 	}
2255 	if (expiration - ((int32_t) now) < 0) {
2256 		/* bad sig, expiration date has passed */
2257 		return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
2258 	}
2259 	return LDNS_STATUS_OK;
2260 }
2261 
2262 /**
2263  * Prepare for verification.
2264  * @param rawsig_buf: raw signature buffer made ready.
2265  * @param verify_buf: data for verification buffer made ready.
2266  * @param rrset_clone: made ready.
2267  * @param rrsig: signature to prepare for.
2268  * @return LDNS_STATUS_OK is all went well. Otherwise specific error.
2269  */
2270 static ldns_status
2271 ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
2272 	ldns_rr_list* rrset_clone, const ldns_rr* rrsig)
2273 {
2274 	ldns_status result;
2275 
2276 	/* canonicalize the sig */
2277 	ldns_dname2canonical(ldns_rr_owner(rrsig));
2278 
2279 	/* check if the typecovered is equal to the type checked */
2280 	if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)) !=
2281 	    ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0)))
2282 		return LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR;
2283 
2284 	/* create a buffer with b64 signature rdata */
2285 	result = ldns_rrsig2rawsig_buffer(rawsig_buf, rrsig);
2286 	if(result != LDNS_STATUS_OK)
2287 		return result;
2288 
2289 	/* use TTL from signature. Use wildcard names for wildcards */
2290 	/* also canonicalizes rrset_clone */
2291 	ldns_rrset_use_signature_ttl(rrset_clone, rrsig);
2292 
2293 	/* sort the rrset in canonical order  */
2294 	ldns_rr_list_sort(rrset_clone);
2295 
2296 	/* put the signature rr (without the b64) to the verify_buf */
2297 	if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK)
2298 		return LDNS_STATUS_MEM_ERR;
2299 
2300 	/* add the rrset in verify_buf */
2301 	if(ldns_rr_list2buffer_wire(verify_buf, rrset_clone)
2302 		!= LDNS_STATUS_OK)
2303 		return LDNS_STATUS_MEM_ERR;
2304 
2305 	return LDNS_STATUS_OK;
2306 }
2307 
2308 /**
2309  * Check if a key matches a signature.
2310  * Checks keytag, sigalgo and signature.
2311  * @param rawsig_buf: raw signature buffer for verify
2312  * @param verify_buf: raw data buffer for verify
2313  * @param rrsig: the rrsig
2314  * @param key: key to attempt.
2315  * @return LDNS_STATUS_OK if OK, else some specific error.
2316  */
2317 static ldns_status
2318 ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
2319 	const ldns_rr* rrsig, ldns_rr* key)
2320 {
2321 	uint8_t sig_algo;
2322 
2323 	if (rrsig == NULL) {
2324 		return LDNS_STATUS_CRYPTO_NO_RRSIG;
2325 	}
2326 	if (ldns_rr_rdf(rrsig, 1) == NULL) {
2327 		return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2328 	}
2329 	sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
2330 
2331 	/* before anything, check if the keytags match */
2332 	if (ldns_calc_keytag(key)
2333 	    ==
2334 	    ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
2335 	    ) {
2336 		ldns_buffer* key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2337 		ldns_status result = LDNS_STATUS_ERR;
2338 
2339 		/* put the key-data in a buffer, that's the third rdf, with
2340 		 * the base64 encoded key data */
2341 		if (ldns_rr_rdf(key, 3) == NULL) {
2342 			ldns_buffer_free(key_buf);
2343 			return LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
2344 		}
2345 		if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3))
2346 			       	!= LDNS_STATUS_OK) {
2347 			ldns_buffer_free(key_buf);
2348 			/* returning is bad might screw up
2349 			   good keys later in the list
2350 			   what to do? */
2351 			return LDNS_STATUS_ERR;
2352 		}
2353 
2354 		if (ldns_rr_rdf(key, 2) == NULL) {
2355 			result = LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
2356 		}
2357 		else if (sig_algo == ldns_rdf2native_int8(
2358 					ldns_rr_rdf(key, 2))) {
2359 			result = ldns_verify_rrsig_buffers(rawsig_buf,
2360 				verify_buf, key_buf, sig_algo);
2361 		} else {
2362 			/* No keys with the corresponding algorithm are found */
2363 			result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2364 		}
2365 
2366 		ldns_buffer_free(key_buf);
2367 		return result;
2368 	}
2369 	else {
2370 		/* No keys with the corresponding keytag are found */
2371 		return LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2372 	}
2373 }
2374 
2375 /*
2376  * to verify:
2377  * - create the wire fmt of the b64 key rdata
2378  * - create the wire fmt of the sorted rrset
2379  * - create the wire fmt of the b64 sig rdata
2380  * - create the wire fmt of the sig without the b64 rdata
2381  * - cat the sig data (without b64 rdata) to the rrset
2382  * - verify the rrset+sig, with the b64 data and the b64 key data
2383  */
2384 ldns_status
2385 ldns_verify_rrsig_keylist_time(
2386 		const ldns_rr_list *rrset,
2387 		const ldns_rr *rrsig,
2388 		const ldns_rr_list *keys,
2389 		time_t check_time,
2390 		ldns_rr_list *good_keys)
2391 {
2392 	ldns_status result;
2393 	ldns_rr_list *valid = ldns_rr_list_new();
2394 	if (!valid)
2395 		return LDNS_STATUS_MEM_ERR;
2396 
2397 	result = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, valid);
2398 	if(result != LDNS_STATUS_OK) {
2399 		ldns_rr_list_free(valid);
2400 		return result;
2401 	}
2402 
2403 	/* check timestamps last; its OK except time */
2404 	result = ldns_rrsig_check_timestamps(rrsig, check_time);
2405 	if(result != LDNS_STATUS_OK) {
2406 		ldns_rr_list_free(valid);
2407 		return result;
2408 	}
2409 
2410 	ldns_rr_list_cat(good_keys, valid);
2411 	ldns_rr_list_free(valid);
2412 	return LDNS_STATUS_OK;
2413 }
2414 
2415 /*
2416  * to verify:
2417  * - create the wire fmt of the b64 key rdata
2418  * - create the wire fmt of the sorted rrset
2419  * - create the wire fmt of the b64 sig rdata
2420  * - create the wire fmt of the sig without the b64 rdata
2421  * - cat the sig data (without b64 rdata) to the rrset
2422  * - verify the rrset+sig, with the b64 data and the b64 key data
2423  */
2424 ldns_status
2425 ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
2426 					 ldns_rr *rrsig,
2427 					 const ldns_rr_list *keys,
2428 					 ldns_rr_list *good_keys)
2429 {
2430 	return ldns_verify_rrsig_keylist_time(
2431 			rrset, rrsig, keys, ldns_time(NULL), good_keys);
2432 }
2433 
2434 ldns_status
2435 ldns_verify_rrsig_keylist_notime(const ldns_rr_list *rrset,
2436 					 const ldns_rr *rrsig,
2437 					 const ldns_rr_list *keys,
2438 					 ldns_rr_list *good_keys)
2439 {
2440 	ldns_buffer *rawsig_buf;
2441 	ldns_buffer *verify_buf;
2442 	uint16_t i;
2443 	ldns_status result, status;
2444 	ldns_rr_list *rrset_clone;
2445 	ldns_rr_list *validkeys;
2446 
2447 	if (!rrset) {
2448 		return LDNS_STATUS_ERR;
2449 	}
2450 
2451 	validkeys = ldns_rr_list_new();
2452 	if (!validkeys) {
2453 		return LDNS_STATUS_MEM_ERR;
2454 	}
2455 
2456 	/* clone the rrset so that we can fiddle with it */
2457 	rrset_clone = ldns_rr_list_clone(rrset);
2458 
2459 	/* create the buffers which will certainly hold the raw data */
2460 	rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2461 	verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2462 
2463 	result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
2464 		rrset_clone, rrsig);
2465 	if(result != LDNS_STATUS_OK) {
2466 		ldns_buffer_free(verify_buf);
2467 		ldns_buffer_free(rawsig_buf);
2468 		ldns_rr_list_deep_free(rrset_clone);
2469 		ldns_rr_list_free(validkeys);
2470 		return result;
2471 	}
2472 
2473 	result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2474 	for(i = 0; i < ldns_rr_list_rr_count(keys); i++) {
2475 		status = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
2476 			rrsig, ldns_rr_list_rr(keys, i));
2477 		if (status == LDNS_STATUS_OK) {
2478 			/* one of the keys has matched, don't break
2479 			 * here, instead put the 'winning' key in
2480 			 * the validkey list and return the list
2481 			 * later */
2482 			if (!ldns_rr_list_push_rr(validkeys,
2483 				ldns_rr_list_rr(keys,i))) {
2484 				/* couldn't push the key?? */
2485 				ldns_buffer_free(rawsig_buf);
2486 				ldns_buffer_free(verify_buf);
2487 				ldns_rr_list_deep_free(rrset_clone);
2488 				ldns_rr_list_free(validkeys);
2489 				return LDNS_STATUS_MEM_ERR;
2490 			}
2491 
2492 			result = status;
2493 		}
2494 
2495 		if (result == LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
2496 			result = status;
2497 		}
2498 	}
2499 
2500 	/* no longer needed */
2501 	ldns_rr_list_deep_free(rrset_clone);
2502 	ldns_buffer_free(rawsig_buf);
2503 	ldns_buffer_free(verify_buf);
2504 
2505 	if (ldns_rr_list_rr_count(validkeys) == 0) {
2506 		/* no keys were added, return last error */
2507 		ldns_rr_list_free(validkeys);
2508 		return result;
2509 	}
2510 
2511 	/* do not check timestamps */
2512 
2513 	ldns_rr_list_cat(good_keys, validkeys);
2514 	ldns_rr_list_free(validkeys);
2515 	return LDNS_STATUS_OK;
2516 }
2517 
2518 ldns_status
2519 ldns_verify_rrsig_time(
2520 		ldns_rr_list *rrset,
2521 		ldns_rr *rrsig,
2522 		ldns_rr *key,
2523 		time_t check_time)
2524 {
2525 	ldns_buffer *rawsig_buf;
2526 	ldns_buffer *verify_buf;
2527 	ldns_status result;
2528 	ldns_rr_list *rrset_clone;
2529 
2530 	if (!rrset) {
2531 		return LDNS_STATUS_NO_DATA;
2532 	}
2533 	/* clone the rrset so that we can fiddle with it */
2534 	rrset_clone = ldns_rr_list_clone(rrset);
2535 	/* create the buffers which will certainly hold the raw data */
2536 	rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2537 	verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2538 
2539 	result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
2540 		rrset_clone, rrsig);
2541 	if(result != LDNS_STATUS_OK) {
2542 		ldns_rr_list_deep_free(rrset_clone);
2543 		ldns_buffer_free(rawsig_buf);
2544 		ldns_buffer_free(verify_buf);
2545 		return result;
2546 	}
2547 	result = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
2548 		rrsig, key);
2549 	/* no longer needed */
2550 	ldns_rr_list_deep_free(rrset_clone);
2551 	ldns_buffer_free(rawsig_buf);
2552 	ldns_buffer_free(verify_buf);
2553 
2554 	/* check timestamp last, apart from time its OK */
2555 	if(result == LDNS_STATUS_OK)
2556 		result = ldns_rrsig_check_timestamps(rrsig, check_time);
2557 
2558 	return result;
2559 }
2560 
2561 ldns_status
2562 ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
2563 {
2564 	return ldns_verify_rrsig_time(rrset, rrsig, key, ldns_time(NULL));
2565 }
2566 
2567 
2568 ldns_status
2569 ldns_verify_rrsig_evp(ldns_buffer *sig,
2570 				  ldns_buffer *rrset,
2571 				  EVP_PKEY *key,
2572 				  const EVP_MD *digest_type)
2573 {
2574 	return ldns_verify_rrsig_evp_raw(
2575 			 (unsigned char*)ldns_buffer_begin(sig),
2576 			 ldns_buffer_position(sig),
2577 			 rrset,
2578 			 key,
2579 			 digest_type);
2580 }
2581 
2582 ldns_status
2583 ldns_verify_rrsig_evp_raw(const unsigned char *sig, size_t siglen,
2584 					 const ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
2585 {
2586 	EVP_MD_CTX *ctx;
2587 	int res;
2588 
2589 #ifdef HAVE_EVP_MD_CTX_NEW
2590 	ctx = EVP_MD_CTX_new();
2591 #else
2592 	ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx));
2593 	if(ctx) EVP_MD_CTX_init(ctx);
2594 #endif
2595 	if(!ctx)
2596 		return LDNS_STATUS_MEM_ERR;
2597 
2598 #if defined(USE_ED25519) || defined(USE_ED448)
2599 	if(!digest_type) {
2600 		res = EVP_DigestVerifyInit(ctx, NULL, digest_type, NULL, key);
2601 		if(res == 1) {
2602 			res = EVP_DigestVerify(ctx, sig, siglen,
2603 				ldns_buffer_begin(rrset),
2604 				ldns_buffer_position(rrset));
2605 		}
2606 	} else {
2607 #else
2608 	res = 0;
2609 	if(digest_type) {
2610 #endif
2611 		EVP_VerifyInit(ctx, digest_type);
2612 		EVP_VerifyUpdate(ctx,
2613 					  ldns_buffer_begin(rrset),
2614 					  ldns_buffer_position(rrset));
2615 		res = EVP_VerifyFinal(ctx, sig, (unsigned int) siglen, key);
2616 	}
2617 
2618 	EVP_MD_CTX_destroy(ctx);
2619 
2620 	if (res == 1) {
2621 		return LDNS_STATUS_OK;
2622 
2623 	} else if (res == 0) {
2624 		return LDNS_STATUS_CRYPTO_BOGUS;
2625 	}
2626 	/* TODO how to communicate internal SSL error?
2627 	   let caller use ssl's get_error() */
2628 	return LDNS_STATUS_SSL_ERR;
2629 }
2630 
2631 ldns_status
2632 ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2633 {
2634 	return ldns_verify_rrsig_dsa_raw(
2635 			 (unsigned char*) ldns_buffer_begin(sig),
2636 			 ldns_buffer_position(sig),
2637 			 rrset,
2638 			 (unsigned char*) ldns_buffer_begin(key),
2639 			 ldns_buffer_position(key));
2640 }
2641 
2642 ldns_status
2643 ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2644 {
2645 	return ldns_verify_rrsig_rsasha1_raw(
2646 			 (unsigned char*)ldns_buffer_begin(sig),
2647 			 ldns_buffer_position(sig),
2648 			 rrset,
2649 			 (unsigned char*) ldns_buffer_begin(key),
2650 			 ldns_buffer_position(key));
2651 }
2652 
2653 ldns_status
2654 ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2655 {
2656 	return ldns_verify_rrsig_rsamd5_raw(
2657 			 (unsigned char*)ldns_buffer_begin(sig),
2658 			 ldns_buffer_position(sig),
2659 			 rrset,
2660 			 (unsigned char*) ldns_buffer_begin(key),
2661 			 ldns_buffer_position(key));
2662 }
2663 
2664 ldns_status
2665 ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
2666 					 ldns_buffer* rrset, unsigned char* key, size_t keylen)
2667 {
2668 #ifdef USE_DSA
2669 	EVP_PKEY *evp_key;
2670 	ldns_status result;
2671 
2672 	evp_key = EVP_PKEY_new();
2673 	if (EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen))) {
2674 		result = ldns_verify_rrsig_evp_raw(sig,
2675 								siglen,
2676 								rrset,
2677 								evp_key,
2678 # ifdef HAVE_EVP_DSS1
2679 								EVP_dss1()
2680 # else
2681 								EVP_sha1()
2682 # endif
2683 								);
2684 	} else {
2685 		result = LDNS_STATUS_SSL_ERR;
2686 	}
2687 	EVP_PKEY_free(evp_key);
2688 	return result;
2689 #else
2690 	(void)sig; (void)siglen; (void)rrset; (void)key; (void)keylen;
2691 	return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
2692 #endif
2693 }
2694 
2695 ldns_status
2696 ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen,
2697 						ldns_buffer* rrset, unsigned char* key, size_t keylen)
2698 {
2699 	EVP_PKEY *evp_key;
2700 	ldns_status result;
2701 
2702 	evp_key = EVP_PKEY_new();
2703 	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2704 		result = ldns_verify_rrsig_evp_raw(sig,
2705 								siglen,
2706 								rrset,
2707 								evp_key,
2708 								EVP_sha1());
2709 	} else {
2710 		result = LDNS_STATUS_SSL_ERR;
2711 	}
2712 	EVP_PKEY_free(evp_key);
2713 
2714 	return result;
2715 }
2716 
2717 ldns_status
2718 ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
2719 						  size_t siglen,
2720 						  ldns_buffer* rrset,
2721 						  unsigned char* key,
2722 						  size_t keylen)
2723 {
2724 #ifdef USE_SHA2
2725 	EVP_PKEY *evp_key;
2726 	ldns_status result;
2727 
2728 	evp_key = EVP_PKEY_new();
2729 	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2730 		result = ldns_verify_rrsig_evp_raw(sig,
2731 								siglen,
2732 								rrset,
2733 								evp_key,
2734 								EVP_sha256());
2735 	} else {
2736 		result = LDNS_STATUS_SSL_ERR;
2737 	}
2738 	EVP_PKEY_free(evp_key);
2739 
2740 	return result;
2741 #else
2742 	/* touch these to prevent compiler warnings */
2743 	(void) sig;
2744 	(void) siglen;
2745 	(void) rrset;
2746 	(void) key;
2747 	(void) keylen;
2748 	return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2749 #endif
2750 }
2751 
2752 ldns_status
2753 ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
2754 						  size_t siglen,
2755 						  ldns_buffer* rrset,
2756 						  unsigned char* key,
2757 						  size_t keylen)
2758 {
2759 #ifdef USE_SHA2
2760 	EVP_PKEY *evp_key;
2761 	ldns_status result;
2762 
2763 	evp_key = EVP_PKEY_new();
2764 	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2765 		result = ldns_verify_rrsig_evp_raw(sig,
2766 								siglen,
2767 								rrset,
2768 								evp_key,
2769 								EVP_sha512());
2770 	} else {
2771 		result = LDNS_STATUS_SSL_ERR;
2772 	}
2773 	EVP_PKEY_free(evp_key);
2774 
2775 	return result;
2776 #else
2777 	/* touch these to prevent compiler warnings */
2778 	(void) sig;
2779 	(void) siglen;
2780 	(void) rrset;
2781 	(void) key;
2782 	(void) keylen;
2783 	return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2784 #endif
2785 }
2786 
2787 
2788 ldns_status
2789 ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
2790 					    size_t siglen,
2791 					    ldns_buffer* rrset,
2792 					    unsigned char* key,
2793 					    size_t keylen)
2794 {
2795 	EVP_PKEY *evp_key;
2796 	ldns_status result;
2797 
2798 	evp_key = EVP_PKEY_new();
2799 	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2800 		result = ldns_verify_rrsig_evp_raw(sig,
2801 								siglen,
2802 								rrset,
2803 								evp_key,
2804 								EVP_md5());
2805 	} else {
2806 		result = LDNS_STATUS_SSL_ERR;
2807 	}
2808 	EVP_PKEY_free(evp_key);
2809 
2810 	return result;
2811 }
2812 
2813 #endif
2814