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