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