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