xref: /freebsd/contrib/ldns/dnssec_verify.c (revision 81ad6265)
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 		const ldns_rr_list *rrset,
1092 		const 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(const unsigned char* key, size_t keylen)
1813 {
1814 	/* prefix header for X509 encoding */
1815 	uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
1816 		0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
1817 		0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
1818 		0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
1819 	unsigned char encoded[37+64];
1820 	const unsigned char* pp;
1821 	if(keylen != 64) {
1822 		/* key wrong size */
1823 		return NULL;
1824 	}
1825 
1826 	/* create evp_key */
1827 	memmove(encoded, asn, 37);
1828 	memmove(encoded+37, key, 64);
1829 	pp = (unsigned char*)&encoded[0];
1830 
1831 	return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
1832 }
1833 
1834 static ldns_status
1835 ldns_verify_rrsig_gost_raw(const unsigned char* sig, size_t siglen,
1836 	const ldns_buffer* rrset, const unsigned char* key, size_t keylen)
1837 {
1838 	EVP_PKEY *evp_key;
1839 	ldns_status result;
1840 
1841 	(void) ldns_key_EVP_load_gost_id();
1842 	evp_key = ldns_gost2pkey_raw(key, keylen);
1843 	if(!evp_key) {
1844 		/* could not convert key */
1845 		return LDNS_STATUS_CRYPTO_BOGUS;
1846 	}
1847 
1848 	/* verify signature */
1849 	result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset,
1850 		evp_key, EVP_get_digestbyname("md_gost94"));
1851 	EVP_PKEY_free(evp_key);
1852 
1853 	return result;
1854 }
1855 #endif
1856 
1857 #ifdef USE_ED25519
1858 EVP_PKEY*
1859 ldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
1860 {
1861         const unsigned char* pp = key; /* pp gets modified by o2i() */
1862         EVP_PKEY *evp_key;
1863         EC_KEY *ec;
1864 	if(keylen != 32)
1865 		return NULL; /* wrong length */
1866         ec = EC_KEY_new_by_curve_name(NID_X25519);
1867 	if(!ec) return NULL;
1868         if(!o2i_ECPublicKey(&ec, &pp, (int)keylen)) {
1869                 EC_KEY_free(ec);
1870                 return NULL;
1871 	}
1872         evp_key = EVP_PKEY_new();
1873         if(!evp_key) {
1874                 EC_KEY_free(ec);
1875                 return NULL;
1876         }
1877         if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
1878 		EVP_PKEY_free(evp_key);
1879 		EC_KEY_free(ec);
1880 		return NULL;
1881 	}
1882         return evp_key;
1883 }
1884 
1885 static ldns_status
1886 ldns_verify_rrsig_ed25519_raw(unsigned char* sig, size_t siglen,
1887 	ldns_buffer* rrset, unsigned char* key, size_t keylen)
1888 {
1889         EVP_PKEY *evp_key;
1890         ldns_status result;
1891 
1892         evp_key = ldns_ed255192pkey_raw(key, keylen);
1893         if(!evp_key) {
1894 		/* could not convert key */
1895 		return LDNS_STATUS_CRYPTO_BOGUS;
1896         }
1897 	result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key,
1898 		EVP_sha512());
1899 	EVP_PKEY_free(evp_key);
1900 	return result;
1901 }
1902 #endif /* USE_ED25519 */
1903 
1904 #ifdef USE_ED448
1905 EVP_PKEY*
1906 ldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
1907 {
1908         const unsigned char* pp = key; /* pp gets modified by o2i() */
1909         EVP_PKEY *evp_key;
1910         EC_KEY *ec;
1911 	if(keylen != 57)
1912 		return NULL; /* wrong length */
1913         ec = EC_KEY_new_by_curve_name(NID_X448);
1914 	if(!ec) return NULL;
1915         if(!o2i_ECPublicKey(&ec, &pp, (int)keylen)) {
1916                 EC_KEY_free(ec);
1917                 return NULL;
1918 	}
1919         evp_key = EVP_PKEY_new();
1920         if(!evp_key) {
1921                 EC_KEY_free(ec);
1922                 return NULL;
1923         }
1924         if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
1925 		EVP_PKEY_free(evp_key);
1926 		EC_KEY_free(ec);
1927 		return NULL;
1928 	}
1929         return evp_key;
1930 }
1931 
1932 static ldns_status
1933 ldns_verify_rrsig_ed448_raw(unsigned char* sig, size_t siglen,
1934 	ldns_buffer* rrset, unsigned char* key, size_t keylen)
1935 {
1936         EVP_PKEY *evp_key;
1937         ldns_status result;
1938 
1939         evp_key = ldns_ed4482pkey_raw(key, keylen);
1940         if(!evp_key) {
1941 		/* could not convert key */
1942 		return LDNS_STATUS_CRYPTO_BOGUS;
1943         }
1944 	result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key,
1945 		EVP_sha512());
1946 	EVP_PKEY_free(evp_key);
1947 	return result;
1948 }
1949 #endif /* USE_ED448 */
1950 
1951 #ifdef USE_ECDSA
1952 EVP_PKEY*
1953 ldns_ecdsa2pkey_raw(const unsigned char* key, size_t keylen, uint8_t algo)
1954 {
1955 	unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
1956         const unsigned char* pp = buf;
1957         EVP_PKEY *evp_key;
1958         EC_KEY *ec;
1959 	/* check length, which uncompressed must be 2 bignums */
1960         if(algo == LDNS_ECDSAP256SHA256) {
1961 		if(keylen != 2*256/8) return NULL;
1962                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
1963         } else if(algo == LDNS_ECDSAP384SHA384) {
1964 		if(keylen != 2*384/8) return NULL;
1965                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
1966         } else    ec = NULL;
1967         if(!ec) return NULL;
1968 	if(keylen+1 > sizeof(buf))
1969 		return NULL; /* sanity check */
1970 	/* prepend the 0x02 (from docs) (or actually 0x04 from implementation
1971 	 * of openssl) for uncompressed data */
1972 	buf[0] = POINT_CONVERSION_UNCOMPRESSED;
1973 	memmove(buf+1, key, keylen);
1974         if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
1975                 EC_KEY_free(ec);
1976                 return NULL;
1977         }
1978         evp_key = EVP_PKEY_new();
1979         if(!evp_key) {
1980                 EC_KEY_free(ec);
1981                 return NULL;
1982         }
1983         if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
1984 		EVP_PKEY_free(evp_key);
1985 		EC_KEY_free(ec);
1986 		return NULL;
1987 	}
1988         return evp_key;
1989 }
1990 
1991 static ldns_status
1992 ldns_verify_rrsig_ecdsa_raw(unsigned char* sig, size_t siglen,
1993 	ldns_buffer* rrset, unsigned char* key, size_t keylen, uint8_t algo)
1994 {
1995         EVP_PKEY *evp_key;
1996         ldns_status result;
1997         const EVP_MD *d;
1998 
1999         evp_key = ldns_ecdsa2pkey_raw(key, keylen, algo);
2000         if(!evp_key) {
2001 		/* could not convert key */
2002 		return LDNS_STATUS_CRYPTO_BOGUS;
2003         }
2004         if(algo == LDNS_ECDSAP256SHA256)
2005                 d = EVP_sha256();
2006         else    d = EVP_sha384(); /* LDNS_ECDSAP384SHA384 */
2007 	result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, d);
2008 	EVP_PKEY_free(evp_key);
2009 	return result;
2010 }
2011 #endif
2012 
2013 ldns_status
2014 ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf,
2015 					 ldns_buffer *key_buf, uint8_t algo)
2016 {
2017 	return ldns_verify_rrsig_buffers_raw(
2018 			 (unsigned char*)ldns_buffer_begin(rawsig_buf),
2019 			 ldns_buffer_position(rawsig_buf),
2020 			 verify_buf,
2021 			 (unsigned char*)ldns_buffer_begin(key_buf),
2022 			 ldns_buffer_position(key_buf), algo);
2023 }
2024 
2025 ldns_status
2026 ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
2027 						ldns_buffer *verify_buf, unsigned char* key, size_t keylen,
2028 						uint8_t algo)
2029 {
2030 	/* check for right key */
2031 	switch(algo) {
2032 #ifdef USE_DSA
2033 	case LDNS_DSA:
2034 	case LDNS_DSA_NSEC3:
2035 		return ldns_verify_rrsig_dsa_raw(sig,
2036 								   siglen,
2037 								   verify_buf,
2038 								   key,
2039 								   keylen);
2040 		break;
2041 #endif
2042 	case LDNS_RSASHA1:
2043 	case LDNS_RSASHA1_NSEC3:
2044 		return ldns_verify_rrsig_rsasha1_raw(sig,
2045 									  siglen,
2046 									  verify_buf,
2047 									  key,
2048 									  keylen);
2049 		break;
2050 #ifdef USE_SHA2
2051 	case LDNS_RSASHA256:
2052 		return ldns_verify_rrsig_rsasha256_raw(sig,
2053 									    siglen,
2054 									    verify_buf,
2055 									    key,
2056 									    keylen);
2057 		break;
2058 	case LDNS_RSASHA512:
2059 		return ldns_verify_rrsig_rsasha512_raw(sig,
2060 									    siglen,
2061 									    verify_buf,
2062 									    key,
2063 									    keylen);
2064 		break;
2065 #endif
2066 #ifdef USE_GOST
2067 	case LDNS_ECC_GOST:
2068 		return ldns_verify_rrsig_gost_raw(sig, siglen, verify_buf,
2069 			key, keylen);
2070 		break;
2071 #endif
2072 #ifdef USE_ECDSA
2073         case LDNS_ECDSAP256SHA256:
2074         case LDNS_ECDSAP384SHA384:
2075 		return ldns_verify_rrsig_ecdsa_raw(sig, siglen, verify_buf,
2076 			key, keylen, algo);
2077 		break;
2078 #endif
2079 #ifdef USE_ED25519
2080 	case LDNS_ED25519:
2081 		return ldns_verify_rrsig_ed25519_raw(sig, siglen, verify_buf,
2082 			key, keylen);
2083 		break;
2084 #endif
2085 #ifdef USE_ED448
2086 	case LDNS_ED448:
2087 		return ldns_verify_rrsig_ed448_raw(sig, siglen, verify_buf,
2088 			key, keylen);
2089 		break;
2090 #endif
2091 	case LDNS_RSAMD5:
2092 		return ldns_verify_rrsig_rsamd5_raw(sig,
2093 									 siglen,
2094 									 verify_buf,
2095 									 key,
2096 									 keylen);
2097 		break;
2098 	default:
2099 		/* do you know this alg?! */
2100 		return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2101 	}
2102 }
2103 
2104 
2105 /**
2106  * Reset the ttl in the rrset with the orig_ttl from the sig
2107  * and update owner name if it was wildcard
2108  * Also canonicalizes the rrset.
2109  * @param rrset: rrset to modify
2110  * @param sig: signature to take TTL and wildcard values from
2111  */
2112 static void
2113 ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, const ldns_rr* rrsig)
2114 {
2115 	uint32_t orig_ttl;
2116 	uint16_t i;
2117 	uint8_t label_count;
2118 	ldns_rdf *wildcard_name;
2119 	ldns_rdf *wildcard_chopped;
2120 	ldns_rdf *wildcard_chopped_tmp;
2121 
2122 	if ((rrsig == NULL) || ldns_rr_rd_count(rrsig) < 4) {
2123 		return;
2124 	}
2125 
2126 	orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
2127 	label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
2128 
2129 	for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
2130 		if (label_count <
2131 		    ldns_dname_label_count(
2132 			   ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
2133 			(void) ldns_str2rdf_dname(&wildcard_name, "*");
2134 			wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(
2135 				ldns_rr_list_rr(rrset_clone, i)));
2136 			while (label_count < ldns_dname_label_count(wildcard_chopped)) {
2137 				wildcard_chopped_tmp = ldns_dname_left_chop(
2138 					wildcard_chopped);
2139 				ldns_rdf_deep_free(wildcard_chopped);
2140 				wildcard_chopped = wildcard_chopped_tmp;
2141 			}
2142 			(void) ldns_dname_cat(wildcard_name, wildcard_chopped);
2143 			ldns_rdf_deep_free(wildcard_chopped);
2144 			ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(
2145 				rrset_clone, i)));
2146 			ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i),
2147 				wildcard_name);
2148 		}
2149 		ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl);
2150 		/* convert to lowercase */
2151 		ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
2152 	}
2153 }
2154 
2155 /**
2156  * Make raw signature buffer out of rrsig
2157  * @param rawsig_buf: raw signature buffer for result
2158  * @param rrsig: signature to convert
2159  * @return OK or more specific error.
2160  */
2161 static ldns_status
2162 ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, const ldns_rr* rrsig)
2163 {
2164 	uint8_t sig_algo;
2165 
2166 	if (rrsig == NULL) {
2167 		return LDNS_STATUS_CRYPTO_NO_RRSIG;
2168 	}
2169 	if (ldns_rr_rdf(rrsig, 1) == NULL) {
2170 		return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2171 	}
2172 	sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
2173 	/* check for known and implemented algo's now (otherwise
2174 	 * the function could return a wrong error
2175 	 */
2176 	/* create a buffer with signature rdata */
2177 	/* for some algorithms we need other data than for others... */
2178 	/* (the DSA API wants DER encoding for instance) */
2179 
2180 	switch(sig_algo) {
2181 	case LDNS_RSAMD5:
2182 	case LDNS_RSASHA1:
2183 	case LDNS_RSASHA1_NSEC3:
2184 #ifdef USE_SHA2
2185 	case LDNS_RSASHA256:
2186 	case LDNS_RSASHA512:
2187 #endif
2188 #ifdef USE_GOST
2189 	case LDNS_ECC_GOST:
2190 #endif
2191 		if (ldns_rr_rdf(rrsig, 8) == NULL) {
2192 			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2193 		}
2194 		if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8))
2195 			       	!= LDNS_STATUS_OK) {
2196 			return LDNS_STATUS_MEM_ERR;
2197 		}
2198 		break;
2199 #ifdef USE_DSA
2200 	case LDNS_DSA:
2201 	case LDNS_DSA_NSEC3:
2202 		/* EVP takes rfc2459 format, which is a tad longer than dns format */
2203 		if (ldns_rr_rdf(rrsig, 8) == NULL) {
2204 			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2205 		}
2206 		if (ldns_convert_dsa_rrsig_rdf2asn1(
2207 					rawsig_buf, ldns_rr_rdf(rrsig, 8))
2208 				!= LDNS_STATUS_OK) {
2209 			/*
2210 			  if (ldns_rdf2buffer_wire(rawsig_buf,
2211 			  ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
2212 			*/
2213 			return LDNS_STATUS_MEM_ERR;
2214 		}
2215 		break;
2216 #endif
2217 #ifdef USE_ECDSA
2218         case LDNS_ECDSAP256SHA256:
2219         case LDNS_ECDSAP384SHA384:
2220                 /* EVP produces an ASN prefix on the signature, which is
2221                  * not used in the DNS */
2222 		if (ldns_rr_rdf(rrsig, 8) == NULL) {
2223 			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2224 		}
2225 		if (ldns_convert_ecdsa_rrsig_rdf2asn1(
2226 					rawsig_buf, ldns_rr_rdf(rrsig, 8))
2227 				!= LDNS_STATUS_OK) {
2228 			return LDNS_STATUS_MEM_ERR;
2229                 }
2230                 break;
2231 #endif
2232 #ifdef USE_ED25519
2233 	case LDNS_ED25519:
2234                 /* EVP produces an ASN prefix on the signature, which is
2235                  * not used in the DNS */
2236 		if (ldns_rr_rdf(rrsig, 8) == NULL) {
2237 			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2238 		}
2239 		if (ldns_convert_ed25519_rrsig_rdf2asn1(
2240 			rawsig_buf, ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
2241 			return LDNS_STATUS_MEM_ERR;
2242                 }
2243 		break;
2244 #endif
2245 #ifdef USE_ED448
2246 	case LDNS_ED448:
2247                 /* EVP produces an ASN prefix on the signature, which is
2248                  * not used in the DNS */
2249 		if (ldns_rr_rdf(rrsig, 8) == NULL) {
2250 			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2251 		}
2252 		if (ldns_convert_ed448_rrsig_rdf2asn1(
2253 			rawsig_buf, ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
2254 			return LDNS_STATUS_MEM_ERR;
2255                 }
2256 		break;
2257 #endif
2258 	case LDNS_DH:
2259 	case LDNS_ECC:
2260 	case LDNS_INDIRECT:
2261 		return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
2262 	default:
2263 		return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2264 	}
2265 	return LDNS_STATUS_OK;
2266 }
2267 
2268 /**
2269  * Check RRSIG timestamps against the given 'now' time.
2270  * @param rrsig: signature to check.
2271  * @param now: the current time in seconds epoch.
2272  * @return status code LDNS_STATUS_OK if all is fine.
2273  */
2274 static ldns_status
2275 ldns_rrsig_check_timestamps(const ldns_rr* rrsig, time_t now)
2276 {
2277 	int32_t inception, expiration;
2278 
2279 	/* check the signature time stamps */
2280 	inception = (int32_t)ldns_rdf2native_time_t(
2281 		ldns_rr_rrsig_inception(rrsig));
2282 	expiration = (int32_t)ldns_rdf2native_time_t(
2283 		ldns_rr_rrsig_expiration(rrsig));
2284 
2285 	if (expiration - inception < 0) {
2286 		/* bad sig, expiration before inception?? Tsssg */
2287 		return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
2288 	}
2289 	if (((int32_t) now) - inception < 0) {
2290 		/* bad sig, inception date has not yet come to pass */
2291 		return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
2292 	}
2293 	if (expiration - ((int32_t) now) < 0) {
2294 		/* bad sig, expiration date has passed */
2295 		return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
2296 	}
2297 	return LDNS_STATUS_OK;
2298 }
2299 
2300 /**
2301  * Prepare for verification.
2302  * @param rawsig_buf: raw signature buffer made ready.
2303  * @param verify_buf: data for verification buffer made ready.
2304  * @param rrset_clone: made ready.
2305  * @param rrsig: signature to prepare for.
2306  * @return LDNS_STATUS_OK is all went well. Otherwise specific error.
2307  */
2308 static ldns_status
2309 ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
2310 	ldns_rr_list* rrset_clone, const ldns_rr* rrsig)
2311 {
2312 	ldns_status result;
2313 
2314 	/* canonicalize the sig */
2315 	ldns_dname2canonical(ldns_rr_owner(rrsig));
2316 
2317 	/* check if the typecovered is equal to the type checked */
2318 	if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)) !=
2319 	    ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0)))
2320 		return LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR;
2321 
2322 	/* create a buffer with b64 signature rdata */
2323 	result = ldns_rrsig2rawsig_buffer(rawsig_buf, rrsig);
2324 	if(result != LDNS_STATUS_OK)
2325 		return result;
2326 
2327 	/* use TTL from signature. Use wildcard names for wildcards */
2328 	/* also canonicalizes rrset_clone */
2329 	ldns_rrset_use_signature_ttl(rrset_clone, rrsig);
2330 
2331 	/* sort the rrset in canonical order  */
2332 	ldns_rr_list_sort(rrset_clone);
2333 
2334 	/* put the signature rr (without the b64) to the verify_buf */
2335 	if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK)
2336 		return LDNS_STATUS_MEM_ERR;
2337 
2338 	/* add the rrset in verify_buf */
2339 	if(ldns_rr_list2buffer_wire(verify_buf, rrset_clone)
2340 		!= LDNS_STATUS_OK)
2341 		return LDNS_STATUS_MEM_ERR;
2342 
2343 	return LDNS_STATUS_OK;
2344 }
2345 
2346 /**
2347  * Check if a key matches a signature.
2348  * Checks keytag, sigalgo and signature.
2349  * @param rawsig_buf: raw signature buffer for verify
2350  * @param verify_buf: raw data buffer for verify
2351  * @param rrsig: the rrsig
2352  * @param key: key to attempt.
2353  * @return LDNS_STATUS_OK if OK, else some specific error.
2354  */
2355 static ldns_status
2356 ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
2357 	const ldns_rr* rrsig, ldns_rr* key)
2358 {
2359 	uint8_t sig_algo;
2360 
2361 	if (rrsig == NULL) {
2362 		return LDNS_STATUS_CRYPTO_NO_RRSIG;
2363 	}
2364 	if (ldns_rr_rdf(rrsig, 1) == NULL) {
2365 		return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2366 	}
2367 	sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
2368 
2369 	/* before anything, check if the keytags match */
2370 	if (ldns_calc_keytag(key)
2371 	    ==
2372 	    ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
2373 	    ) {
2374 		ldns_buffer* key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2375 		ldns_status result = LDNS_STATUS_ERR;
2376 
2377 		/* put the key-data in a buffer, that's the third rdf, with
2378 		 * the base64 encoded key data */
2379 		if (ldns_rr_rdf(key, 3) == NULL) {
2380 			ldns_buffer_free(key_buf);
2381 			return LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
2382 		}
2383 		if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3))
2384 			       	!= LDNS_STATUS_OK) {
2385 			ldns_buffer_free(key_buf);
2386 			/* returning is bad might screw up
2387 			   good keys later in the list
2388 			   what to do? */
2389 			return LDNS_STATUS_ERR;
2390 		}
2391 
2392 		if (ldns_rr_rdf(key, 2) == NULL) {
2393 			result = LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
2394 		}
2395 		else if (sig_algo == ldns_rdf2native_int8(
2396 					ldns_rr_rdf(key, 2))) {
2397 			result = ldns_verify_rrsig_buffers(rawsig_buf,
2398 				verify_buf, key_buf, sig_algo);
2399 		} else {
2400 			/* No keys with the corresponding algorithm are found */
2401 			result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2402 		}
2403 
2404 		ldns_buffer_free(key_buf);
2405 		return result;
2406 	}
2407 	else {
2408 		/* No keys with the corresponding keytag are found */
2409 		return LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2410 	}
2411 }
2412 
2413 /*
2414  * to verify:
2415  * - create the wire fmt of the b64 key rdata
2416  * - create the wire fmt of the sorted rrset
2417  * - create the wire fmt of the b64 sig rdata
2418  * - create the wire fmt of the sig without the b64 rdata
2419  * - cat the sig data (without b64 rdata) to the rrset
2420  * - verify the rrset+sig, with the b64 data and the b64 key data
2421  */
2422 ldns_status
2423 ldns_verify_rrsig_keylist_time(
2424 		const ldns_rr_list *rrset,
2425 		const ldns_rr *rrsig,
2426 		const ldns_rr_list *keys,
2427 		time_t check_time,
2428 		ldns_rr_list *good_keys)
2429 {
2430 	ldns_status result;
2431 	ldns_rr_list *valid = ldns_rr_list_new();
2432 	if (!valid)
2433 		return LDNS_STATUS_MEM_ERR;
2434 
2435 	result = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, valid);
2436 	if(result != LDNS_STATUS_OK) {
2437 		ldns_rr_list_free(valid);
2438 		return result;
2439 	}
2440 
2441 	/* check timestamps last; its OK except time */
2442 	result = ldns_rrsig_check_timestamps(rrsig, check_time);
2443 	if(result != LDNS_STATUS_OK) {
2444 		ldns_rr_list_free(valid);
2445 		return result;
2446 	}
2447 
2448 	ldns_rr_list_cat(good_keys, valid);
2449 	ldns_rr_list_free(valid);
2450 	return LDNS_STATUS_OK;
2451 }
2452 
2453 /*
2454  * to verify:
2455  * - create the wire fmt of the b64 key rdata
2456  * - create the wire fmt of the sorted rrset
2457  * - create the wire fmt of the b64 sig rdata
2458  * - create the wire fmt of the sig without the b64 rdata
2459  * - cat the sig data (without b64 rdata) to the rrset
2460  * - verify the rrset+sig, with the b64 data and the b64 key data
2461  */
2462 ldns_status
2463 ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
2464 					 ldns_rr *rrsig,
2465 					 const ldns_rr_list *keys,
2466 					 ldns_rr_list *good_keys)
2467 {
2468 	return ldns_verify_rrsig_keylist_time(
2469 			rrset, rrsig, keys, ldns_time(NULL), good_keys);
2470 }
2471 
2472 ldns_status
2473 ldns_verify_rrsig_keylist_notime(const ldns_rr_list *rrset,
2474 					 const ldns_rr *rrsig,
2475 					 const ldns_rr_list *keys,
2476 					 ldns_rr_list *good_keys)
2477 {
2478 	ldns_buffer *rawsig_buf;
2479 	ldns_buffer *verify_buf;
2480 	uint16_t i;
2481 	ldns_status result, status;
2482 	ldns_rr_list *rrset_clone;
2483 	ldns_rr_list *validkeys;
2484 
2485 	if (!rrset) {
2486 		return LDNS_STATUS_ERR;
2487 	}
2488 
2489 	validkeys = ldns_rr_list_new();
2490 	if (!validkeys) {
2491 		return LDNS_STATUS_MEM_ERR;
2492 	}
2493 
2494 	/* clone the rrset so that we can fiddle with it */
2495 	rrset_clone = ldns_rr_list_clone(rrset);
2496 
2497 	/* create the buffers which will certainly hold the raw data */
2498 	rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2499 	verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2500 
2501 	result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
2502 		rrset_clone, rrsig);
2503 	if(result != LDNS_STATUS_OK) {
2504 		ldns_buffer_free(verify_buf);
2505 		ldns_buffer_free(rawsig_buf);
2506 		ldns_rr_list_deep_free(rrset_clone);
2507 		ldns_rr_list_free(validkeys);
2508 		return result;
2509 	}
2510 
2511 	result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2512 	for(i = 0; i < ldns_rr_list_rr_count(keys); i++) {
2513 		status = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
2514 			rrsig, ldns_rr_list_rr(keys, i));
2515 		if (status == LDNS_STATUS_OK) {
2516 			/* one of the keys has matched, don't break
2517 			 * here, instead put the 'winning' key in
2518 			 * the validkey list and return the list
2519 			 * later */
2520 			if (!ldns_rr_list_push_rr(validkeys,
2521 				ldns_rr_list_rr(keys,i))) {
2522 				/* couldn't push the key?? */
2523 				ldns_buffer_free(rawsig_buf);
2524 				ldns_buffer_free(verify_buf);
2525 				ldns_rr_list_deep_free(rrset_clone);
2526 				ldns_rr_list_free(validkeys);
2527 				return LDNS_STATUS_MEM_ERR;
2528 			}
2529 
2530 			result = status;
2531 		}
2532 
2533 		if (result == LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
2534 			result = status;
2535 		}
2536 	}
2537 
2538 	/* no longer needed */
2539 	ldns_rr_list_deep_free(rrset_clone);
2540 	ldns_buffer_free(rawsig_buf);
2541 	ldns_buffer_free(verify_buf);
2542 
2543 	if (ldns_rr_list_rr_count(validkeys) == 0) {
2544 		/* no keys were added, return last error */
2545 		ldns_rr_list_free(validkeys);
2546 		return result;
2547 	}
2548 
2549 	/* do not check timestamps */
2550 
2551 	ldns_rr_list_cat(good_keys, validkeys);
2552 	ldns_rr_list_free(validkeys);
2553 	return LDNS_STATUS_OK;
2554 }
2555 
2556 ldns_status
2557 ldns_verify_rrsig_time(
2558 		ldns_rr_list *rrset,
2559 		ldns_rr *rrsig,
2560 		ldns_rr *key,
2561 		time_t check_time)
2562 {
2563 	ldns_buffer *rawsig_buf;
2564 	ldns_buffer *verify_buf;
2565 	ldns_status result;
2566 	ldns_rr_list *rrset_clone;
2567 
2568 	if (!rrset) {
2569 		return LDNS_STATUS_NO_DATA;
2570 	}
2571 	/* clone the rrset so that we can fiddle with it */
2572 	rrset_clone = ldns_rr_list_clone(rrset);
2573 	/* create the buffers which will certainly hold the raw data */
2574 	rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2575 	verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2576 
2577 	result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
2578 		rrset_clone, rrsig);
2579 	if(result != LDNS_STATUS_OK) {
2580 		ldns_rr_list_deep_free(rrset_clone);
2581 		ldns_buffer_free(rawsig_buf);
2582 		ldns_buffer_free(verify_buf);
2583 		return result;
2584 	}
2585 	result = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
2586 		rrsig, key);
2587 	/* no longer needed */
2588 	ldns_rr_list_deep_free(rrset_clone);
2589 	ldns_buffer_free(rawsig_buf);
2590 	ldns_buffer_free(verify_buf);
2591 
2592 	/* check timestamp last, apart from time its OK */
2593 	if(result == LDNS_STATUS_OK)
2594 		result = ldns_rrsig_check_timestamps(rrsig, check_time);
2595 
2596 	return result;
2597 }
2598 
2599 ldns_status
2600 ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
2601 {
2602 	return ldns_verify_rrsig_time(rrset, rrsig, key, ldns_time(NULL));
2603 }
2604 
2605 
2606 ldns_status
2607 ldns_verify_rrsig_evp(ldns_buffer *sig,
2608 				  ldns_buffer *rrset,
2609 				  EVP_PKEY *key,
2610 				  const EVP_MD *digest_type)
2611 {
2612 	return ldns_verify_rrsig_evp_raw(
2613 			 (unsigned char*)ldns_buffer_begin(sig),
2614 			 ldns_buffer_position(sig),
2615 			 rrset,
2616 			 key,
2617 			 digest_type);
2618 }
2619 
2620 ldns_status
2621 ldns_verify_rrsig_evp_raw(const unsigned char *sig, size_t siglen,
2622 					 const ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
2623 {
2624 	EVP_MD_CTX *ctx;
2625 	int res;
2626 
2627 #ifdef HAVE_EVP_MD_CTX_NEW
2628 	ctx = EVP_MD_CTX_new();
2629 #else
2630 	ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx));
2631 	if(ctx) EVP_MD_CTX_init(ctx);
2632 #endif
2633 	if(!ctx)
2634 		return LDNS_STATUS_MEM_ERR;
2635 
2636 	EVP_VerifyInit(ctx, digest_type);
2637 	EVP_VerifyUpdate(ctx,
2638 				  ldns_buffer_begin(rrset),
2639 				  ldns_buffer_position(rrset));
2640 	res = EVP_VerifyFinal(ctx, sig, (unsigned int) siglen, key);
2641 
2642 	EVP_MD_CTX_destroy(ctx);
2643 
2644 	if (res == 1) {
2645 		return LDNS_STATUS_OK;
2646 	} else if (res == 0) {
2647 		return LDNS_STATUS_CRYPTO_BOGUS;
2648 	}
2649 	/* TODO how to communicate internal SSL error?
2650 	   let caller use ssl's get_error() */
2651 	return LDNS_STATUS_SSL_ERR;
2652 }
2653 
2654 ldns_status
2655 ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2656 {
2657 	return ldns_verify_rrsig_dsa_raw(
2658 			 (unsigned char*) ldns_buffer_begin(sig),
2659 			 ldns_buffer_position(sig),
2660 			 rrset,
2661 			 (unsigned char*) ldns_buffer_begin(key),
2662 			 ldns_buffer_position(key));
2663 }
2664 
2665 ldns_status
2666 ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2667 {
2668 	return ldns_verify_rrsig_rsasha1_raw(
2669 			 (unsigned char*)ldns_buffer_begin(sig),
2670 			 ldns_buffer_position(sig),
2671 			 rrset,
2672 			 (unsigned char*) ldns_buffer_begin(key),
2673 			 ldns_buffer_position(key));
2674 }
2675 
2676 ldns_status
2677 ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2678 {
2679 	return ldns_verify_rrsig_rsamd5_raw(
2680 			 (unsigned char*)ldns_buffer_begin(sig),
2681 			 ldns_buffer_position(sig),
2682 			 rrset,
2683 			 (unsigned char*) ldns_buffer_begin(key),
2684 			 ldns_buffer_position(key));
2685 }
2686 
2687 ldns_status
2688 ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
2689 					 ldns_buffer* rrset, unsigned char* key, size_t keylen)
2690 {
2691 #ifdef USE_DSA
2692 	EVP_PKEY *evp_key;
2693 	ldns_status result;
2694 
2695 	evp_key = EVP_PKEY_new();
2696 	if (EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen))) {
2697 		result = ldns_verify_rrsig_evp_raw(sig,
2698 								siglen,
2699 								rrset,
2700 								evp_key,
2701 # ifdef HAVE_EVP_DSS1
2702 								EVP_dss1()
2703 # else
2704 								EVP_sha1()
2705 # endif
2706 								);
2707 	} else {
2708 		result = LDNS_STATUS_SSL_ERR;
2709 	}
2710 	EVP_PKEY_free(evp_key);
2711 	return result;
2712 #else
2713 	(void)sig; (void)siglen; (void)rrset; (void)key; (void)keylen;
2714 	return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
2715 #endif
2716 }
2717 
2718 ldns_status
2719 ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen,
2720 						ldns_buffer* rrset, unsigned char* key, size_t keylen)
2721 {
2722 	EVP_PKEY *evp_key;
2723 	ldns_status result;
2724 
2725 	evp_key = EVP_PKEY_new();
2726 	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2727 		result = ldns_verify_rrsig_evp_raw(sig,
2728 								siglen,
2729 								rrset,
2730 								evp_key,
2731 								EVP_sha1());
2732 	} else {
2733 		result = LDNS_STATUS_SSL_ERR;
2734 	}
2735 	EVP_PKEY_free(evp_key);
2736 
2737 	return result;
2738 }
2739 
2740 ldns_status
2741 ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
2742 						  size_t siglen,
2743 						  ldns_buffer* rrset,
2744 						  unsigned char* key,
2745 						  size_t keylen)
2746 {
2747 #ifdef USE_SHA2
2748 	EVP_PKEY *evp_key;
2749 	ldns_status result;
2750 
2751 	evp_key = EVP_PKEY_new();
2752 	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2753 		result = ldns_verify_rrsig_evp_raw(sig,
2754 								siglen,
2755 								rrset,
2756 								evp_key,
2757 								EVP_sha256());
2758 	} else {
2759 		result = LDNS_STATUS_SSL_ERR;
2760 	}
2761 	EVP_PKEY_free(evp_key);
2762 
2763 	return result;
2764 #else
2765 	/* touch these to prevent compiler warnings */
2766 	(void) sig;
2767 	(void) siglen;
2768 	(void) rrset;
2769 	(void) key;
2770 	(void) keylen;
2771 	return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2772 #endif
2773 }
2774 
2775 ldns_status
2776 ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
2777 						  size_t siglen,
2778 						  ldns_buffer* rrset,
2779 						  unsigned char* key,
2780 						  size_t keylen)
2781 {
2782 #ifdef USE_SHA2
2783 	EVP_PKEY *evp_key;
2784 	ldns_status result;
2785 
2786 	evp_key = EVP_PKEY_new();
2787 	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2788 		result = ldns_verify_rrsig_evp_raw(sig,
2789 								siglen,
2790 								rrset,
2791 								evp_key,
2792 								EVP_sha512());
2793 	} else {
2794 		result = LDNS_STATUS_SSL_ERR;
2795 	}
2796 	EVP_PKEY_free(evp_key);
2797 
2798 	return result;
2799 #else
2800 	/* touch these to prevent compiler warnings */
2801 	(void) sig;
2802 	(void) siglen;
2803 	(void) rrset;
2804 	(void) key;
2805 	(void) keylen;
2806 	return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2807 #endif
2808 }
2809 
2810 
2811 ldns_status
2812 ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
2813 					    size_t siglen,
2814 					    ldns_buffer* rrset,
2815 					    unsigned char* key,
2816 					    size_t keylen)
2817 {
2818 	EVP_PKEY *evp_key;
2819 	ldns_status result;
2820 
2821 	evp_key = EVP_PKEY_new();
2822 	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2823 		result = ldns_verify_rrsig_evp_raw(sig,
2824 								siglen,
2825 								rrset,
2826 								evp_key,
2827 								EVP_md5());
2828 	} else {
2829 		result = LDNS_STATUS_SSL_ERR;
2830 	}
2831 	EVP_PKEY_free(evp_key);
2832 
2833 	return result;
2834 }
2835 
2836 #endif
2837