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