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