xref: /dragonfly/contrib/ldns/dnssec_verify.c (revision 81c11cd3)
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 	size_t i, j;
639 
640 	ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new();
641 
642 	if (data_chain && data_chain->rrset) {
643 		cur_rrset = data_chain->rrset;
644 
645 		cur_sigs = data_chain->signatures;
646 
647 		if (rr) {
648 			cur_rr = rr;
649 		}
650 
651 		if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) {
652 			cur_rr = ldns_rr_list_rr(cur_rrset, 0);
653 		}
654 
655 		if (cur_rr) {
656 			new_tree->rr = cur_rr;
657 			new_tree->rrset = cur_rrset;
658 			/* there are three possibilities:
659 			   1 - 'normal' rrset, signed by a key
660 			   2 - dnskey signed by other dnskey
661 			   3 - dnskey proven by higher level DS
662 			   (data denied by nsec is a special case that can
663 			   occur in multiple places)
664 
665 			*/
666 			if (cur_sigs) {
667 				for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) {
668 					/* find the appropriate key in the parent list */
669 					cur_sig_rr = ldns_rr_list_rr(cur_sigs, i);
670 
671 					if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) {
672 						if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
673 										   ldns_rr_owner(cur_rr)))
674 							{
675 								/* find first that does match */
676 
677 								for (j = 0;
678 								     j < ldns_rr_list_rr_count(cur_rrset) &&
679 										ldns_dname_compare(ldns_rr_owner(cur_sig_rr),ldns_rr_owner(cur_rr)) != 0;
680 								     j++) {
681 									cur_rr = ldns_rr_list_rr(cur_rrset, j);
682 
683 								}
684 								if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
685 												   ldns_rr_owner(cur_rr)))
686 									{
687 										break;
688 									}
689 							}
690 
691 					}
692 					/* option 1 */
693 					if (data_chain->parent) {
694 						ldns_dnssec_derive_trust_tree_normal_rrset(
695 						    new_tree,
696 						    data_chain,
697 						    cur_sig_rr);
698 					}
699 
700 					/* option 2 */
701 					ldns_dnssec_derive_trust_tree_dnskey_rrset(
702 					    new_tree,
703 					    data_chain,
704 					    cur_rr,
705 					    cur_sig_rr);
706 				}
707 
708 				ldns_dnssec_derive_trust_tree_ds_rrset(new_tree,
709 											    data_chain,
710 											    cur_rr);
711 			} else {
712 				/* no signatures? maybe it's nsec data */
713 
714 				/* just add every rr from parent as new parent */
715 				ldns_dnssec_derive_trust_tree_no_sig(new_tree, data_chain);
716 			}
717 		}
718 	}
719 
720 	return new_tree;
721 }
722 
723 void
724 ldns_dnssec_derive_trust_tree_normal_rrset(ldns_dnssec_trust_tree *new_tree,
725                                            ldns_dnssec_data_chain *data_chain,
726                                            ldns_rr *cur_sig_rr)
727 {
728 	size_t i, j;
729 	ldns_rr_list *cur_rrset = ldns_rr_list_clone(data_chain->rrset);
730 	ldns_dnssec_trust_tree *cur_parent_tree;
731 	ldns_rr *cur_parent_rr;
732 	uint16_t cur_keytag;
733 	ldns_rr_list *tmp_rrset = NULL;
734 	ldns_status cur_status;
735 
736 	cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
737 
738 	for (j = 0; j < ldns_rr_list_rr_count(data_chain->parent->rrset); j++) {
739 		cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
740 		if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
741 			if (ldns_calc_keytag(cur_parent_rr) == cur_keytag) {
742 
743 				/* TODO: check wildcard nsec too */
744 				if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
745 					tmp_rrset = cur_rrset;
746 					if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
747 					    == LDNS_RR_TYPE_NSEC ||
748 					    ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
749 					    == LDNS_RR_TYPE_NSEC3) {
750 						/* might contain different names!
751 						   sort and split */
752 						ldns_rr_list_sort(cur_rrset);
753 						if (tmp_rrset && tmp_rrset != cur_rrset) {
754 							ldns_rr_list_deep_free(tmp_rrset);
755 							tmp_rrset = NULL;
756 						}
757 						tmp_rrset = ldns_rr_list_pop_rrset(cur_rrset);
758 
759 						/* with nsecs, this might be the wrong one */
760 						while (tmp_rrset &&
761 						       ldns_rr_list_rr_count(cur_rrset) > 0 &&
762 						       ldns_dname_compare(
763 								ldns_rr_owner(ldns_rr_list_rr(
764 										        tmp_rrset, 0)),
765 								ldns_rr_owner(cur_sig_rr)) != 0) {
766 							ldns_rr_list_deep_free(tmp_rrset);
767 							tmp_rrset =
768 								ldns_rr_list_pop_rrset(cur_rrset);
769 						}
770 					}
771 					cur_status = ldns_verify_rrsig(tmp_rrset,
772 											 cur_sig_rr,
773 											 cur_parent_rr);
774 					/* avoid dupes */
775 					for (i = 0; i < new_tree->parent_count; i++) {
776 						if (cur_parent_rr == new_tree->parents[i]->rr) {
777 							goto done;
778 						}
779 					}
780 
781 					cur_parent_tree =
782 						ldns_dnssec_derive_trust_tree(data_chain->parent,
783 						                              cur_parent_rr);
784 					(void)ldns_dnssec_trust_tree_add_parent(new_tree,
785 					           cur_parent_tree,
786 					           cur_sig_rr,
787 					           cur_status);
788 				}
789 			}
790 		}
791 	}
792  done:
793 	if (tmp_rrset && tmp_rrset != cur_rrset) {
794 		ldns_rr_list_deep_free(tmp_rrset);
795 	}
796 	ldns_rr_list_deep_free(cur_rrset);
797 }
798 
799 void
800 ldns_dnssec_derive_trust_tree_dnskey_rrset(ldns_dnssec_trust_tree *new_tree,
801                                            ldns_dnssec_data_chain *data_chain,
802                                            ldns_rr *cur_rr,
803                                            ldns_rr *cur_sig_rr)
804 {
805 	size_t j;
806 	ldns_rr_list *cur_rrset = data_chain->rrset;
807 	ldns_dnssec_trust_tree *cur_parent_tree;
808 	ldns_rr *cur_parent_rr;
809 	uint16_t cur_keytag;
810 	ldns_status cur_status;
811 
812 	cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
813 
814 	for (j = 0; j < ldns_rr_list_rr_count(cur_rrset); j++) {
815 		cur_parent_rr = ldns_rr_list_rr(cur_rrset, j);
816 		if (cur_parent_rr != cur_rr &&
817 		    ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
818 			if (ldns_calc_keytag(cur_parent_rr) == cur_keytag
819 			    ) {
820 				cur_parent_tree = ldns_dnssec_trust_tree_new();
821 				cur_parent_tree->rr = cur_parent_rr;
822 				cur_parent_tree->rrset = cur_rrset;
823 				cur_status = ldns_verify_rrsig(cur_rrset,
824 				                               cur_sig_rr,
825 				                               cur_parent_rr);
826 				(void) ldns_dnssec_trust_tree_add_parent(new_tree,
827 				            cur_parent_tree, cur_sig_rr, cur_status);
828 			}
829 		}
830 	}
831 }
832 
833 void
834 ldns_dnssec_derive_trust_tree_ds_rrset(ldns_dnssec_trust_tree *new_tree,
835                                        ldns_dnssec_data_chain *data_chain,
836                                        ldns_rr *cur_rr)
837 {
838 	size_t j, h;
839 	ldns_rr_list *cur_rrset = data_chain->rrset;
840 	ldns_dnssec_trust_tree *cur_parent_tree;
841 	ldns_rr *cur_parent_rr;
842 
843 	/* try the parent to see whether there are DSs there */
844 	if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_DNSKEY &&
845 	    data_chain->parent &&
846 	    data_chain->parent->rrset
847 	    ) {
848 		for (j = 0;
849 			j < ldns_rr_list_rr_count(data_chain->parent->rrset);
850 			j++) {
851 			cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
852 			if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DS) {
853 				for (h = 0; h < ldns_rr_list_rr_count(cur_rrset); h++) {
854 					cur_rr = ldns_rr_list_rr(cur_rrset, h);
855 					if (ldns_rr_compare_ds(cur_rr, cur_parent_rr)) {
856 						cur_parent_tree =
857 							ldns_dnssec_derive_trust_tree(
858 							    data_chain->parent, cur_parent_rr);
859 						(void) ldns_dnssec_trust_tree_add_parent(
860 						            new_tree,
861 						            cur_parent_tree,
862 						            NULL,
863 						            LDNS_STATUS_OK);
864 					} else {
865 						/*ldns_rr_print(stdout, cur_parent_rr);*/
866 					}
867 				}
868 			}
869 		}
870 	}
871 }
872 
873 void
874 ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree *new_tree,
875                                      ldns_dnssec_data_chain *data_chain)
876 {
877 	size_t i;
878 	ldns_rr_list *cur_rrset;
879 	ldns_rr *cur_parent_rr;
880 	ldns_dnssec_trust_tree *cur_parent_tree;
881 	ldns_status result;
882 
883 	if (data_chain->parent && data_chain->parent->rrset) {
884 		cur_rrset = data_chain->parent->rrset;
885 		/* nsec? */
886 		if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
887 			if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
888 			    LDNS_RR_TYPE_NSEC3) {
889 				result = ldns_dnssec_verify_denial_nsec3(
890 					        new_tree->rr,
891 						   cur_rrset,
892 						   data_chain->parent->signatures,
893 						   data_chain->packet_rcode,
894 						   data_chain->packet_qtype,
895 						   data_chain->packet_nodata);
896 			} else if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
897 					 LDNS_RR_TYPE_NSEC3) {
898 				result = ldns_dnssec_verify_denial(
899 					        new_tree->rr,
900 						   cur_rrset,
901 						   data_chain->parent->signatures);
902 			} else {
903 				/* unsigned zone, unsigned parent */
904 				result = LDNS_STATUS_OK;
905 			}
906 		} else {
907 			result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
908 		}
909 		for (i = 0; i < ldns_rr_list_rr_count(cur_rrset); i++) {
910 			cur_parent_rr = ldns_rr_list_rr(cur_rrset, i);
911 			cur_parent_tree =
912 				ldns_dnssec_derive_trust_tree(data_chain->parent,
913 										cur_parent_rr);
914 			(void) ldns_dnssec_trust_tree_add_parent(new_tree,
915 			            cur_parent_tree, NULL, result);
916 		}
917 	}
918 }
919 
920 /*
921  * returns OK if there is a path from tree to key with only OK
922  * the (first) error in between otherwise
923  * or NOT_FOUND if the key wasn't present at all
924  */
925 ldns_status
926 ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree,
927 							  ldns_rr_list *trusted_keys)
928 {
929 	size_t i;
930 	ldns_status result = LDNS_STATUS_CRYPTO_NO_DNSKEY;
931 	bool equal;
932 	ldns_status parent_result;
933 
934 	if (tree && trusted_keys && ldns_rr_list_rr_count(trusted_keys) > 0)
935 		{ if (tree->rr) {
936 				for (i = 0; i < ldns_rr_list_rr_count(trusted_keys); i++) {
937 					equal = ldns_rr_compare_ds(
938 							  tree->rr,
939 							  ldns_rr_list_rr(trusted_keys, i));
940 					if (equal) {
941 						result = LDNS_STATUS_OK;
942 						return result;
943 					}
944 				}
945 			}
946 			for (i = 0; i < tree->parent_count; i++) {
947 				parent_result =
948 					ldns_dnssec_trust_tree_contains_keys(tree->parents[i],
949 												  trusted_keys);
950 				if (parent_result != LDNS_STATUS_CRYPTO_NO_DNSKEY) {
951 					if (tree->parent_status[i] != LDNS_STATUS_OK) {
952 						result = tree->parent_status[i];
953 					} else {
954 						if (ldns_rr_get_type(tree->rr)
955 						    == LDNS_RR_TYPE_NSEC &&
956 						    parent_result == LDNS_STATUS_OK
957 						    ) {
958 							result =
959 								LDNS_STATUS_DNSSEC_EXISTENCE_DENIED;
960 						} else {
961 							result = parent_result;
962 						}
963 					}
964 				}
965 			}
966 		} else {
967 		result = LDNS_STATUS_ERR;
968 	}
969 
970 	return result;
971 }
972 
973 ldns_status
974 ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys,
975 		  ldns_rr_list *good_keys)
976 {
977 	uint16_t i;
978 	ldns_status verify_result = LDNS_STATUS_ERR;
979 
980 	if (!rrset || !rrsig || !keys) {
981 		return LDNS_STATUS_ERR;
982 	}
983 
984 	if (ldns_rr_list_rr_count(rrset) < 1) {
985 		return LDNS_STATUS_ERR;
986 	}
987 
988 	if (ldns_rr_list_rr_count(rrsig) < 1) {
989 		return LDNS_STATUS_CRYPTO_NO_RRSIG;
990 	}
991 
992 	if (ldns_rr_list_rr_count(keys) < 1) {
993 		verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
994 	} else {
995 		for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
996 			ldns_status s = ldns_verify_rrsig_keylist(rrset,
997 				ldns_rr_list_rr(rrsig, i), keys, good_keys);
998 			/* try a little to get more descriptive error */
999 			if(s == LDNS_STATUS_OK) {
1000 				verify_result = LDNS_STATUS_OK;
1001 			} else if(verify_result == LDNS_STATUS_ERR)
1002 				verify_result = s;
1003 			else if(s !=  LDNS_STATUS_ERR && verify_result ==
1004 				LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY)
1005 				verify_result = s;
1006 		}
1007 	}
1008 	return verify_result;
1009 }
1010 
1011 ldns_status
1012 ldns_verify_notime(ldns_rr_list *rrset, ldns_rr_list *rrsig,
1013 	const ldns_rr_list *keys, ldns_rr_list *good_keys)
1014 {
1015 	uint16_t i;
1016 	ldns_status verify_result = LDNS_STATUS_ERR;
1017 
1018 	if (!rrset || !rrsig || !keys) {
1019 		return LDNS_STATUS_ERR;
1020 	}
1021 
1022 	if (ldns_rr_list_rr_count(rrset) < 1) {
1023 		return LDNS_STATUS_ERR;
1024 	}
1025 
1026 	if (ldns_rr_list_rr_count(rrsig) < 1) {
1027 		return LDNS_STATUS_CRYPTO_NO_RRSIG;
1028 	}
1029 
1030 	if (ldns_rr_list_rr_count(keys) < 1) {
1031 		verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1032 	} else {
1033 		for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1034 			ldns_status s = ldns_verify_rrsig_keylist_notime(rrset,
1035 				ldns_rr_list_rr(rrsig, i), keys, good_keys);
1036 
1037 			/* try a little to get more descriptive error */
1038 			if (s == LDNS_STATUS_OK) {
1039 				verify_result = LDNS_STATUS_OK;
1040 			} else if (verify_result == LDNS_STATUS_ERR) {
1041 				verify_result = s;
1042 			} else if (s !=  LDNS_STATUS_ERR && verify_result ==
1043 				LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
1044 				verify_result = s;
1045 			}
1046 		}
1047 	}
1048 	return verify_result;
1049 }
1050 
1051 ldns_rr_list *
1052 ldns_fetch_valid_domain_keys(const ldns_resolver *res,
1053                              const ldns_rdf *domain,
1054                              const ldns_rr_list *keys,
1055                              ldns_status *status)
1056 {
1057 	ldns_rr_list * trusted_keys = NULL;
1058 	ldns_rr_list * ds_keys = NULL;
1059 
1060 	if (res && domain && keys) {
1061 
1062 		if ((trusted_keys = ldns_validate_domain_dnskey(res,
1063                                          domain,
1064                                          keys))) {
1065 			*status = LDNS_STATUS_OK;
1066 		} else {
1067 			/* No trusted keys in this domain, we'll have to find some in the parent domain */
1068 			*status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1069 
1070 			if (ldns_rdf_size(domain) > 1) {
1071 				/* Fail if we are at the root */
1072 				ldns_rr_list * parent_keys;
1073 				ldns_rdf * parent_domain = ldns_dname_left_chop(domain);
1074 
1075 				if ((parent_keys =
1076 					ldns_fetch_valid_domain_keys(res,
1077 					     parent_domain,
1078 					     keys,
1079 					     status))) {
1080 					/* Check DS records */
1081 					if ((ds_keys =
1082 						ldns_validate_domain_ds(res,
1083 						     domain,
1084 						     parent_keys))) {
1085 						trusted_keys =
1086 							ldns_fetch_valid_domain_keys(res,
1087 							     domain,
1088 							     ds_keys,
1089 							     status);
1090 						ldns_rr_list_deep_free(ds_keys);
1091 					} else {
1092 						/* No valid DS at the parent -- fail */
1093 						*status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DS ;
1094 					}
1095 					ldns_rr_list_deep_free(parent_keys);
1096 				}
1097 				ldns_rdf_deep_free(parent_domain);
1098 			}
1099 		}
1100 	}
1101 	return trusted_keys;
1102 }
1103 
1104 ldns_rr_list *
1105 ldns_validate_domain_dnskey(const ldns_resolver * res,
1106 					   const ldns_rdf * domain,
1107 					   const ldns_rr_list * keys)
1108 {
1109 	ldns_pkt * keypkt;
1110 	ldns_rr * cur_key;
1111 	uint16_t key_i; uint16_t key_j; uint16_t key_k;
1112 	uint16_t sig_i; ldns_rr * cur_sig;
1113 
1114 	ldns_rr_list * domain_keys = NULL;
1115 	ldns_rr_list * domain_sigs = NULL;
1116 	ldns_rr_list * trusted_keys = NULL;
1117 
1118 	/* Fetch keys for the domain */
1119 	if ((keypkt = ldns_resolver_query(res,
1120 							    domain,
1121 							    LDNS_RR_TYPE_DNSKEY,
1122 							    LDNS_RR_CLASS_IN,
1123 							    LDNS_RD))) {
1124 
1125 		domain_keys = ldns_pkt_rr_list_by_type(keypkt,
1126 									    LDNS_RR_TYPE_DNSKEY,
1127 									    LDNS_SECTION_ANSWER);
1128 		domain_sigs = ldns_pkt_rr_list_by_type(keypkt,
1129 									    LDNS_RR_TYPE_RRSIG,
1130 									    LDNS_SECTION_ANSWER);
1131 
1132 		/* Try to validate the record using our keys */
1133 		for (key_i=0; key_i< ldns_rr_list_rr_count(domain_keys); key_i++) {
1134 
1135 			cur_key = ldns_rr_list_rr(domain_keys, key_i);
1136 			for (key_j=0; key_j<ldns_rr_list_rr_count(keys); key_j++) {
1137 				if (ldns_rr_compare_ds(ldns_rr_list_rr(keys, key_j),
1138 								   cur_key)) {
1139 
1140 					/* Current key is trusted -- validate */
1141 					trusted_keys = ldns_rr_list_new();
1142 
1143 					for (sig_i=0;
1144 						sig_i<ldns_rr_list_rr_count(domain_sigs);
1145 						sig_i++) {
1146 						cur_sig = ldns_rr_list_rr(domain_sigs, sig_i);
1147 						/* Avoid non-matching sigs */
1148 						if (ldns_rdf2native_int16(
1149 							   ldns_rr_rrsig_keytag(cur_sig))
1150 						    == ldns_calc_keytag(cur_key)) {
1151 							if (ldns_verify_rrsig(domain_keys,
1152 											   cur_sig,
1153 											   cur_key)
1154 							    == LDNS_STATUS_OK) {
1155 
1156 								/* Push the whole rrset
1157 								   -- we can't do much more */
1158 								for (key_k=0;
1159 									key_k<ldns_rr_list_rr_count(
1160 											domain_keys);
1161 									key_k++) {
1162 									ldns_rr_list_push_rr(
1163 									    trusted_keys,
1164 									    ldns_rr_clone(
1165 										   ldns_rr_list_rr(
1166 											  domain_keys,
1167 											  key_k)));
1168 								}
1169 
1170 								ldns_rr_list_deep_free(domain_keys);
1171 								ldns_rr_list_deep_free(domain_sigs);
1172 								ldns_pkt_free(keypkt);
1173 								return trusted_keys;
1174 							}
1175 						}
1176 					}
1177 
1178 					/* Only push our trusted key */
1179 					ldns_rr_list_push_rr(trusted_keys,
1180 									 ldns_rr_clone(cur_key));
1181 				}
1182 			}
1183 		}
1184 
1185 		ldns_rr_list_deep_free(domain_keys);
1186 		ldns_rr_list_deep_free(domain_sigs);
1187 		ldns_pkt_free(keypkt);
1188 
1189 	} else {
1190 		/* LDNS_STATUS_CRYPTO_NO_DNSKEY */
1191 	}
1192 
1193 	return trusted_keys;
1194 }
1195 
1196 ldns_rr_list *
1197 ldns_validate_domain_ds(const ldns_resolver *res,
1198 				    const ldns_rdf * domain,
1199 				    const ldns_rr_list * keys)
1200 {
1201 	ldns_pkt * dspkt;
1202 	uint16_t key_i;
1203 	ldns_rr_list * rrset = NULL;
1204 	ldns_rr_list * sigs = NULL;
1205 	ldns_rr_list * trusted_keys = NULL;
1206 
1207 	/* Fetch DS for the domain */
1208 	if ((dspkt = ldns_resolver_query(res,
1209 							   domain,
1210 							   LDNS_RR_TYPE_DS,
1211 							   LDNS_RR_CLASS_IN,
1212 							   LDNS_RD))) {
1213 
1214 		rrset = ldns_pkt_rr_list_by_type(dspkt,
1215 								   LDNS_RR_TYPE_DS,
1216 								   LDNS_SECTION_ANSWER);
1217 		sigs = ldns_pkt_rr_list_by_type(dspkt,
1218 								  LDNS_RR_TYPE_RRSIG,
1219 								  LDNS_SECTION_ANSWER);
1220 
1221 		/* Validate sigs */
1222 		if (ldns_verify(rrset, sigs, keys, NULL) == LDNS_STATUS_OK) {
1223 			trusted_keys = ldns_rr_list_new();
1224 			for (key_i=0; key_i<ldns_rr_list_rr_count(rrset); key_i++) {
1225 				ldns_rr_list_push_rr(trusted_keys,
1226 								 ldns_rr_clone(ldns_rr_list_rr(rrset,
1227 														 key_i)
1228 											)
1229 								 );
1230 			}
1231 		}
1232 
1233 		ldns_rr_list_deep_free(rrset);
1234 		ldns_rr_list_deep_free(sigs);
1235 		ldns_pkt_free(dspkt);
1236 
1237 	} else {
1238 		/* LDNS_STATUS_CRYPTO_NO_DS */
1239 	}
1240 
1241 	return trusted_keys;
1242 }
1243 
1244 ldns_status
1245 ldns_verify_trusted(ldns_resolver *res,
1246 				ldns_rr_list *rrset,
1247 				ldns_rr_list * rrsigs,
1248 				ldns_rr_list * validating_keys)
1249 {
1250 	uint16_t sig_i; uint16_t key_i;
1251 	ldns_rr * cur_sig; ldns_rr * cur_key;
1252 	ldns_rr_list * trusted_keys = NULL;
1253 	ldns_status result = LDNS_STATUS_ERR;
1254 
1255 	if (!res || !rrset || !rrsigs) {
1256 		return LDNS_STATUS_ERR;
1257 	}
1258 
1259 	if (ldns_rr_list_rr_count(rrset) < 1) {
1260 		return LDNS_STATUS_ERR;
1261 	}
1262 
1263 	if (ldns_rr_list_rr_count(rrsigs) < 1) {
1264 		return LDNS_STATUS_CRYPTO_NO_RRSIG;
1265 	}
1266 
1267 	/* Look at each sig */
1268 	for (sig_i=0; sig_i < ldns_rr_list_rr_count(rrsigs); sig_i++) {
1269 
1270 		cur_sig = ldns_rr_list_rr(rrsigs, sig_i);
1271 		/* Get a valid signer key and validate the sig */
1272 		if ((trusted_keys = ldns_fetch_valid_domain_keys(
1273 						    res,
1274 						    ldns_rr_rrsig_signame(cur_sig),
1275 						    ldns_resolver_dnssec_anchors(res),
1276 						    &result))) {
1277 
1278 			for (key_i = 0;
1279 				key_i < ldns_rr_list_rr_count(trusted_keys);
1280 				key_i++) {
1281 				cur_key = ldns_rr_list_rr(trusted_keys, key_i);
1282 
1283 				if ((result = ldns_verify_rrsig(rrset,
1284 										  cur_sig,
1285 										  cur_key))
1286 				    == LDNS_STATUS_OK) {
1287 					if (validating_keys) {
1288 						ldns_rr_list_push_rr(validating_keys,
1289 										 ldns_rr_clone(cur_key));
1290 					}
1291 					ldns_rr_list_deep_free(trusted_keys);
1292 					return LDNS_STATUS_OK;
1293 				} else {
1294 					ldns_rr_list_print(stdout, rrset);
1295 					ldns_rr_print(stdout, cur_sig);
1296 					ldns_rr_print(stdout, cur_key);
1297 
1298 				}
1299 			}
1300 		}
1301 	}
1302 
1303 	ldns_rr_list_deep_free(trusted_keys);
1304 	return result;
1305 }
1306 
1307 ldns_status
1308 ldns_dnssec_verify_denial(ldns_rr *rr,
1309                           ldns_rr_list *nsecs,
1310                           ldns_rr_list *rrsigs)
1311 {
1312 	ldns_rdf *rr_name;
1313 	ldns_rdf *wildcard_name;
1314 	ldns_rdf *chopped_dname;
1315 	ldns_rr *cur_nsec;
1316 	size_t i;
1317 	ldns_status result;
1318 	/* needed for wildcard check on exact match */
1319 	ldns_rr *rrsig;
1320 	bool name_covered = false;
1321 	bool type_covered = false;
1322 	bool wildcard_covered = false;
1323 	bool wildcard_type_covered = false;
1324 
1325 	wildcard_name = ldns_dname_new_frm_str("*");
1326 	rr_name = ldns_rr_owner(rr);
1327 	chopped_dname = ldns_dname_left_chop(rr_name);
1328 	result = ldns_dname_cat(wildcard_name, chopped_dname);
1329 	if (result != LDNS_STATUS_OK) {
1330 		return result;
1331 	}
1332 
1333 	ldns_rdf_deep_free(chopped_dname);
1334 
1335 	for  (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1336 		cur_nsec = ldns_rr_list_rr(nsecs, i);
1337 		if (ldns_dname_compare(rr_name, ldns_rr_owner(cur_nsec)) == 0) {
1338 			/* see section 5.4 of RFC4035, if the label count of the NSEC's
1339 			   RRSIG is equal, then it is proven that wildcard expansion
1340 			   could not have been used to match the request */
1341 			rrsig = ldns_dnssec_get_rrsig_for_name_and_type(
1342 					  ldns_rr_owner(cur_nsec),
1343 					  ldns_rr_get_type(cur_nsec),
1344 					  rrsigs);
1345 			if (rrsig && ldns_rdf2native_int8(ldns_rr_rrsig_labels(rrsig))
1346 			    == ldns_dname_label_count(rr_name)) {
1347 				wildcard_covered = true;
1348 			}
1349 
1350 			if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
1351 									   ldns_rr_get_type(rr))) {
1352 				type_covered = true;
1353 			}
1354 		}
1355 		if (ldns_nsec_covers_name(cur_nsec, rr_name)) {
1356 			name_covered = true;
1357 		}
1358 
1359 		if (ldns_dname_compare(wildcard_name,
1360 						   ldns_rr_owner(cur_nsec)) == 0) {
1361 			if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
1362 									   ldns_rr_get_type(rr))) {
1363 				wildcard_type_covered = true;
1364 			}
1365 		}
1366 
1367 		if (ldns_nsec_covers_name(cur_nsec, wildcard_name)) {
1368 			wildcard_covered = true;
1369 		}
1370 
1371 	}
1372 
1373 	ldns_rdf_deep_free(wildcard_name);
1374 
1375 	if (type_covered || !name_covered) {
1376 		return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1377 	}
1378 
1379 	if (wildcard_type_covered || !wildcard_covered) {
1380 		return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
1381 	}
1382 
1383 	return LDNS_STATUS_OK;
1384 }
1385 
1386 #ifdef HAVE_SSL
1387 ldns_status
1388 ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
1389 						  ldns_rr_list *nsecs,
1390 						  ldns_rr_list *rrsigs,
1391 						  ldns_pkt_rcode packet_rcode,
1392 						  ldns_rr_type packet_qtype,
1393 						  bool packet_nodata)
1394 {
1395 	ldns_rdf *closest_encloser;
1396 	ldns_rdf *wildcard;
1397 	ldns_rdf *hashed_wildcard_name;
1398 	bool wildcard_covered = false;
1399 	ldns_rdf *zone_name;
1400 	ldns_rdf *hashed_name;
1401 	size_t i;
1402 	ldns_status result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1403 
1404 	rrsigs = rrsigs;
1405 
1406 	zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
1407 
1408 	/* section 8.4 */
1409 	if (packet_rcode == LDNS_RCODE_NXDOMAIN) {
1410 		closest_encloser = ldns_dnssec_nsec3_closest_encloser(
1411 						   ldns_rr_owner(rr),
1412 						   ldns_rr_get_type(rr),
1413 						   nsecs);
1414                 if(!closest_encloser) {
1415                         result = LDNS_STATUS_NSEC3_ERR;
1416                         goto done;
1417                 }
1418 
1419 		wildcard = ldns_dname_new_frm_str("*");
1420 		(void) ldns_dname_cat(wildcard, closest_encloser);
1421 
1422 		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1423 			hashed_wildcard_name =
1424 				ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
1425 										 wildcard
1426 										 );
1427 			(void) ldns_dname_cat(hashed_wildcard_name, zone_name);
1428 
1429 			if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
1430 								 hashed_wildcard_name)) {
1431 				wildcard_covered = true;
1432 			}
1433 			ldns_rdf_deep_free(hashed_wildcard_name);
1434 		}
1435 
1436 		ldns_rdf_deep_free(closest_encloser);
1437 		ldns_rdf_deep_free(wildcard);
1438 
1439 		if (!wildcard_covered) {
1440 			result = LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
1441 		} else if (closest_encloser && wildcard_covered) {
1442 			result = LDNS_STATUS_OK;
1443 		} else {
1444 			result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1445 		}
1446 	} else if (packet_nodata && packet_qtype != LDNS_RR_TYPE_DS) {
1447 		/* section 8.5 */
1448 		hashed_name = ldns_nsec3_hash_name_frm_nsec3(
1449 		                   ldns_rr_list_rr(nsecs, 0),
1450 		                   ldns_rr_owner(rr));
1451 		(void) ldns_dname_cat(hashed_name, zone_name);
1452 		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1453 			if (ldns_dname_compare(hashed_name,
1454 			         ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
1455 			    == 0) {
1456 				if (!ldns_nsec_bitmap_covers_type(
1457 					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1458 					    packet_qtype)
1459 				    &&
1460 				    !ldns_nsec_bitmap_covers_type(
1461 					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1462 					    LDNS_RR_TYPE_CNAME)) {
1463 					result = LDNS_STATUS_OK;
1464 					goto done;
1465 				}
1466 			}
1467 		}
1468 		result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1469 	} else if (packet_nodata && packet_qtype == LDNS_RR_TYPE_DS) {
1470 		/* section 8.6 */
1471 		/* note: up to XXX this is the same as for 8.5 */
1472 		hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs,
1473 														 0),
1474 											ldns_rr_owner(rr)
1475 											);
1476 		(void) ldns_dname_cat(hashed_name, zone_name);
1477 		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1478 			if (ldns_dname_compare(hashed_name,
1479 							   ldns_rr_owner(ldns_rr_list_rr(nsecs,
1480 													   i)))
1481 			    == 0) {
1482 				if (!ldns_nsec_bitmap_covers_type(
1483 					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1484 					    LDNS_RR_TYPE_DS)
1485 				    &&
1486 				    !ldns_nsec_bitmap_covers_type(
1487 					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1488 					    LDNS_RR_TYPE_CNAME)) {
1489 					result = LDNS_STATUS_OK;
1490 					goto done;
1491 				}
1492 			}
1493 		}
1494 
1495 		/* XXX see note above */
1496 		result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1497 	}
1498 
1499  done:
1500 	ldns_rdf_deep_free(zone_name);
1501 	return result;
1502 }
1503 #endif /* HAVE_SSL */
1504 
1505 #ifdef USE_GOST
1506 EVP_PKEY*
1507 ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
1508 {
1509 	/* prefix header for X509 encoding */
1510 	uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
1511 		0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
1512 		0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
1513 		0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
1514 	unsigned char encoded[37+64];
1515 	const unsigned char* pp;
1516 	if(keylen != 64) {
1517 		/* key wrong size */
1518 		return NULL;
1519 	}
1520 
1521 	/* create evp_key */
1522 	memmove(encoded, asn, 37);
1523 	memmove(encoded+37, key, 64);
1524 	pp = (unsigned char*)&encoded[0];
1525 
1526 	return d2i_PUBKEY(NULL, &pp, sizeof(encoded));
1527 }
1528 
1529 static ldns_status
1530 ldns_verify_rrsig_gost_raw(unsigned char* sig, size_t siglen,
1531 	ldns_buffer* rrset, unsigned char* key, size_t keylen)
1532 {
1533 	EVP_PKEY *evp_key;
1534 	ldns_status result;
1535 
1536 	(void) ldns_key_EVP_load_gost_id();
1537 	evp_key = ldns_gost2pkey_raw(key, keylen);
1538 	if(!evp_key) {
1539 		/* could not convert key */
1540 		return LDNS_STATUS_CRYPTO_BOGUS;
1541 	}
1542 
1543 	/* verify signature */
1544 	result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset,
1545 		evp_key, EVP_get_digestbyname("md_gost94"));
1546 	EVP_PKEY_free(evp_key);
1547 
1548 	return result;
1549 }
1550 #endif
1551 
1552 #ifdef USE_ECDSA
1553 EVP_PKEY*
1554 ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
1555 {
1556 	unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
1557         const unsigned char* pp = buf;
1558         EVP_PKEY *evp_key;
1559         EC_KEY *ec;
1560 	/* check length, which uncompressed must be 2 bignums */
1561         if(algo == LDNS_ECDSAP256SHA256) {
1562 		if(keylen != 2*256/8) return NULL;
1563                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
1564         } else if(algo == LDNS_ECDSAP384SHA384) {
1565 		if(keylen != 2*384/8) return NULL;
1566                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
1567         } else    ec = NULL;
1568         if(!ec) return NULL;
1569 	if(keylen+1 > sizeof(buf))
1570 		return NULL; /* sanity check */
1571 	/* prepend the 0x02 (from docs) (or actually 0x04 from implementation
1572 	 * of openssl) for uncompressed data */
1573 	buf[0] = POINT_CONVERSION_UNCOMPRESSED;
1574 	memmove(buf+1, key, keylen);
1575         if(!o2i_ECPublicKey(&ec, &pp, keylen+1)) {
1576                 EC_KEY_free(ec);
1577                 return NULL;
1578         }
1579         evp_key = EVP_PKEY_new();
1580         if(!evp_key) {
1581                 EC_KEY_free(ec);
1582                 return NULL;
1583         }
1584         EVP_PKEY_assign_EC_KEY(evp_key, ec);
1585         return evp_key;
1586 }
1587 
1588 static ldns_status
1589 ldns_verify_rrsig_ecdsa_raw(unsigned char* sig, size_t siglen,
1590 	ldns_buffer* rrset, unsigned char* key, size_t keylen, uint8_t algo)
1591 {
1592         EVP_PKEY *evp_key;
1593         ldns_status result;
1594         const EVP_MD *d;
1595 
1596         evp_key = ldns_ecdsa2pkey_raw(key, keylen, algo);
1597         if(!evp_key) {
1598 		/* could not convert key */
1599 		return LDNS_STATUS_CRYPTO_BOGUS;
1600         }
1601         if(algo == LDNS_ECDSAP256SHA256)
1602                 d = EVP_sha256();
1603         else    d = EVP_sha384(); /* LDNS_ECDSAP384SHA384 */
1604 	result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, d);
1605 	EVP_PKEY_free(evp_key);
1606 	return result;
1607 }
1608 #endif
1609 
1610 ldns_status
1611 ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf,
1612 					 ldns_buffer *key_buf, uint8_t algo)
1613 {
1614 	return ldns_verify_rrsig_buffers_raw(
1615 			 (unsigned char*)ldns_buffer_begin(rawsig_buf),
1616 			 ldns_buffer_position(rawsig_buf),
1617 			 verify_buf,
1618 			 (unsigned char*)ldns_buffer_begin(key_buf),
1619 			 ldns_buffer_position(key_buf), algo);
1620 }
1621 
1622 ldns_status
1623 ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
1624 						ldns_buffer *verify_buf, unsigned char* key, size_t keylen,
1625 						uint8_t algo)
1626 {
1627 	/* check for right key */
1628 	switch(algo) {
1629 	case LDNS_DSA:
1630 	case LDNS_DSA_NSEC3:
1631 		return ldns_verify_rrsig_dsa_raw(sig,
1632 								   siglen,
1633 								   verify_buf,
1634 								   key,
1635 								   keylen);
1636 		break;
1637 	case LDNS_RSASHA1:
1638 	case LDNS_RSASHA1_NSEC3:
1639 		return ldns_verify_rrsig_rsasha1_raw(sig,
1640 									  siglen,
1641 									  verify_buf,
1642 									  key,
1643 									  keylen);
1644 		break;
1645 #ifdef USE_SHA2
1646 	case LDNS_RSASHA256:
1647 		return ldns_verify_rrsig_rsasha256_raw(sig,
1648 									    siglen,
1649 									    verify_buf,
1650 									    key,
1651 									    keylen);
1652 		break;
1653 	case LDNS_RSASHA512:
1654 		return ldns_verify_rrsig_rsasha512_raw(sig,
1655 									    siglen,
1656 									    verify_buf,
1657 									    key,
1658 									    keylen);
1659 		break;
1660 #endif
1661 #ifdef USE_GOST
1662 	case LDNS_ECC_GOST:
1663 		return ldns_verify_rrsig_gost_raw(sig, siglen, verify_buf,
1664 			key, keylen);
1665 		break;
1666 #endif
1667 #ifdef USE_ECDSA
1668         case LDNS_ECDSAP256SHA256:
1669         case LDNS_ECDSAP384SHA384:
1670 		return ldns_verify_rrsig_ecdsa_raw(sig, siglen, verify_buf,
1671 			key, keylen, algo);
1672 		break;
1673 #endif
1674 	case LDNS_RSAMD5:
1675 		return ldns_verify_rrsig_rsamd5_raw(sig,
1676 									 siglen,
1677 									 verify_buf,
1678 									 key,
1679 									 keylen);
1680 		break;
1681 	default:
1682 		/* do you know this alg?! */
1683 		return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
1684 	}
1685 }
1686 
1687 
1688 /**
1689  * Reset the ttl in the rrset with the orig_ttl from the sig
1690  * and update owner name if it was wildcard
1691  * Also canonicalizes the rrset.
1692  * @param rrset: rrset to modify
1693  * @param sig: signature to take TTL and wildcard values from
1694  */
1695 static void
1696 ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
1697 {
1698 	uint32_t orig_ttl;
1699 	uint16_t i;
1700 	uint8_t label_count;
1701 	ldns_rdf *wildcard_name;
1702 	ldns_rdf *wildcard_chopped;
1703 	ldns_rdf *wildcard_chopped_tmp;
1704 
1705 	orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
1706 	label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
1707 
1708 	for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
1709 		if (label_count <
1710 		    ldns_dname_label_count(
1711 			   ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
1712 			(void) ldns_str2rdf_dname(&wildcard_name, "*");
1713 			wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(
1714 				ldns_rr_list_rr(rrset_clone, i)));
1715 			while (label_count < ldns_dname_label_count(wildcard_chopped)) {
1716 				wildcard_chopped_tmp = ldns_dname_left_chop(
1717 					wildcard_chopped);
1718 				ldns_rdf_deep_free(wildcard_chopped);
1719 				wildcard_chopped = wildcard_chopped_tmp;
1720 			}
1721 			(void) ldns_dname_cat(wildcard_name, wildcard_chopped);
1722 			ldns_rdf_deep_free(wildcard_chopped);
1723 			ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(
1724 				rrset_clone, i)));
1725 			ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i),
1726 				wildcard_name);
1727 		}
1728 		ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl);
1729 		/* convert to lowercase */
1730 		ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
1731 	}
1732 }
1733 
1734 /**
1735  * Make raw signature buffer out of rrsig
1736  * @param rawsig_buf: raw signature buffer for result
1737  * @param rrsig: signature to convert
1738  * @return OK or more specific error.
1739  */
1740 static ldns_status
1741 ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
1742 {
1743 	uint8_t sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
1744 	/* check for known and implemented algo's now (otherwise
1745 	 * the function could return a wrong error
1746 	 */
1747 	/* create a buffer with signature rdata */
1748 	/* for some algorithms we need other data than for others... */
1749 	/* (the DSA API wants DER encoding for instance) */
1750 
1751 	switch(sig_algo) {
1752 	case LDNS_RSAMD5:
1753 	case LDNS_RSASHA1:
1754 	case LDNS_RSASHA1_NSEC3:
1755 #ifdef USE_SHA2
1756 	case LDNS_RSASHA256:
1757 	case LDNS_RSASHA512:
1758 #endif
1759 #ifdef USE_GOST
1760 	case LDNS_ECC_GOST:
1761 #endif
1762 		if (ldns_rdf2buffer_wire(rawsig_buf,
1763 		    ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
1764 			return LDNS_STATUS_MEM_ERR;
1765 		}
1766 		break;
1767 	case LDNS_DSA:
1768 	case LDNS_DSA_NSEC3:
1769 		/* EVP takes rfc2459 format, which is a tad longer than dns format */
1770 		if (ldns_convert_dsa_rrsig_rdf2asn1(rawsig_buf,
1771 			ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
1772 			/*
1773 			  if (ldns_rdf2buffer_wire(rawsig_buf,
1774 			  ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
1775 			*/
1776 			return LDNS_STATUS_MEM_ERR;
1777 		}
1778 		break;
1779 #ifdef USE_ECDSA
1780         case LDNS_ECDSAP256SHA256:
1781         case LDNS_ECDSAP384SHA384:
1782                 /* EVP produces an ASN prefix on the signature, which is
1783                  * not used in the DNS */
1784 		if (ldns_convert_ecdsa_rrsig_rdf2asn1(rawsig_buf,
1785 			ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
1786 			return LDNS_STATUS_MEM_ERR;
1787                 }
1788                 break;
1789 #endif
1790 	case LDNS_DH:
1791 	case LDNS_ECC:
1792 	case LDNS_INDIRECT:
1793 		return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
1794 	default:
1795 		return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
1796 	}
1797 	return LDNS_STATUS_OK;
1798 }
1799 
1800 /**
1801  * Check RRSIG timestamps against the given 'now' time.
1802  * @param rrsig: signature to check.
1803  * @param now: the current time in seconds epoch.
1804  * @return status code LDNS_STATUS_OK if all is fine.
1805  */
1806 static ldns_status
1807 ldns_rrsig_check_timestamps(ldns_rr* rrsig, int32_t now)
1808 {
1809 	int32_t inception, expiration;
1810 
1811 	/* check the signature time stamps */
1812 	inception = (int32_t)ldns_rdf2native_time_t(
1813 		ldns_rr_rrsig_inception(rrsig));
1814 	expiration = (int32_t)ldns_rdf2native_time_t(
1815 		ldns_rr_rrsig_expiration(rrsig));
1816 
1817 	if (expiration - inception < 0) {
1818 		/* bad sig, expiration before inception?? Tsssg */
1819 		return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
1820 	}
1821 	if (now - inception < 0) {
1822 		/* bad sig, inception date has not yet come to pass */
1823 		return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
1824 	}
1825 	if (expiration - now < 0) {
1826 		/* bad sig, expiration date has passed */
1827 		return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
1828 	}
1829 	return LDNS_STATUS_OK;
1830 }
1831 
1832 /**
1833  * Prepare for verification.
1834  * @param rawsig_buf: raw signature buffer made ready.
1835  * @param verify_buf: data for verification buffer made ready.
1836  * @param rrset_clone: made ready.
1837  * @param rrsig: signature to prepare for.
1838  * @return LDNS_STATUS_OK is all went well. Otherwise specific error.
1839  */
1840 static ldns_status
1841 ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
1842 	ldns_rr_list* rrset_clone, ldns_rr* rrsig)
1843 {
1844 	ldns_status result;
1845 
1846 	/* canonicalize the sig */
1847 	ldns_dname2canonical(ldns_rr_owner(rrsig));
1848 
1849 	/* check if the typecovered is equal to the type checked */
1850 	if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)) !=
1851 	    ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0)))
1852 		return LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR;
1853 
1854 	/* create a buffer with b64 signature rdata */
1855 	result = ldns_rrsig2rawsig_buffer(rawsig_buf, rrsig);
1856 	if(result != LDNS_STATUS_OK)
1857 		return result;
1858 
1859 	/* use TTL from signature. Use wildcard names for wildcards */
1860 	/* also canonicalizes rrset_clone */
1861 	ldns_rrset_use_signature_ttl(rrset_clone, rrsig);
1862 
1863 	/* sort the rrset in canonical order  */
1864 	ldns_rr_list_sort(rrset_clone);
1865 
1866 	/* put the signature rr (without the b64) to the verify_buf */
1867 	if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK)
1868 		return LDNS_STATUS_MEM_ERR;
1869 
1870 	/* add the rrset in verify_buf */
1871 	if(ldns_rr_list2buffer_wire(verify_buf, rrset_clone)
1872 		!= LDNS_STATUS_OK)
1873 		return LDNS_STATUS_MEM_ERR;
1874 
1875 	return LDNS_STATUS_OK;
1876 }
1877 
1878 /**
1879  * Check if a key matches a signature.
1880  * Checks keytag, sigalgo and signature.
1881  * @param rawsig_buf: raw signature buffer for verify
1882  * @param verify_buf: raw data buffer for verify
1883  * @param rrsig: the rrsig
1884  * @param key: key to attempt.
1885  * @return LDNS_STATUS_OK if OK, else some specific error.
1886  */
1887 static ldns_status
1888 ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
1889 	ldns_rr* rrsig, ldns_rr* key)
1890 {
1891 	uint8_t sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
1892 
1893 	/* before anything, check if the keytags match */
1894 	if (ldns_calc_keytag(key)
1895 	    ==
1896 	    ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
1897 	    ) {
1898 		ldns_buffer* key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
1899 		ldns_status result = LDNS_STATUS_ERR;
1900 
1901 		/* put the key-data in a buffer, that's the third rdf, with
1902 		 * the base64 encoded key data */
1903 		if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3))
1904 			!= LDNS_STATUS_OK) {
1905 			ldns_buffer_free(key_buf);
1906 			/* returning is bad might screw up
1907 			   good keys later in the list
1908 			   what to do? */
1909 			return LDNS_STATUS_ERR;
1910 		}
1911 
1912 		if (sig_algo == ldns_rdf2native_int8(ldns_rr_rdf(key, 2))) {
1913 			result = ldns_verify_rrsig_buffers(rawsig_buf,
1914 				verify_buf, key_buf, sig_algo);
1915 		} else {
1916 			/* No keys with the corresponding algorithm are found */
1917 			result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
1918 		}
1919 
1920 		ldns_buffer_free(key_buf);
1921 		return result;
1922 	}
1923 	else {
1924 		/* No keys with the corresponding keytag are found */
1925 		return LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
1926 	}
1927 }
1928 
1929 /*
1930  * to verify:
1931  * - create the wire fmt of the b64 key rdata
1932  * - create the wire fmt of the sorted rrset
1933  * - create the wire fmt of the b64 sig rdata
1934  * - create the wire fmt of the sig without the b64 rdata
1935  * - cat the sig data (without b64 rdata) to the rrset
1936  * - verify the rrset+sig, with the b64 data and the b64 key data
1937  */
1938 ldns_status
1939 ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
1940 					 ldns_rr *rrsig,
1941 					 const ldns_rr_list *keys,
1942 					 ldns_rr_list *good_keys)
1943 {
1944 	ldns_status result;
1945 	ldns_rr_list *valid = ldns_rr_list_new();
1946 	if (!valid)
1947 		return LDNS_STATUS_MEM_ERR;
1948 
1949 	result = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, valid);
1950 	if(result != LDNS_STATUS_OK) {
1951 		ldns_rr_list_free(valid);
1952 		return result;
1953 	}
1954 
1955 	/* check timestamps last; its OK except time */
1956 	result = ldns_rrsig_check_timestamps(rrsig, (int32_t)time(NULL));
1957 	if(result != LDNS_STATUS_OK) {
1958 		ldns_rr_list_free(valid);
1959 		return result;
1960 	}
1961 
1962 	ldns_rr_list_cat(good_keys, valid);
1963 	ldns_rr_list_free(valid);
1964 	return LDNS_STATUS_OK;
1965 }
1966 
1967 ldns_status
1968 ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset,
1969 					 ldns_rr *rrsig,
1970 					 const ldns_rr_list *keys,
1971 					 ldns_rr_list *good_keys)
1972 {
1973 	ldns_buffer *rawsig_buf;
1974 	ldns_buffer *verify_buf;
1975 	uint16_t i;
1976 	ldns_status result, status;
1977 	ldns_rr_list *rrset_clone;
1978 	ldns_rr_list *validkeys;
1979 
1980 	if (!rrset) {
1981 		return LDNS_STATUS_ERR;
1982 	}
1983 
1984 	validkeys = ldns_rr_list_new();
1985 	if (!validkeys) {
1986 		return LDNS_STATUS_MEM_ERR;
1987 	}
1988 
1989 	/* clone the rrset so that we can fiddle with it */
1990 	rrset_clone = ldns_rr_list_clone(rrset);
1991 
1992 	/* create the buffers which will certainly hold the raw data */
1993 	rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
1994 	verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
1995 
1996 	result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
1997 		rrset_clone, rrsig);
1998 	if(result != LDNS_STATUS_OK) {
1999 		ldns_buffer_free(verify_buf);
2000 		ldns_buffer_free(rawsig_buf);
2001 		ldns_rr_list_deep_free(rrset_clone);
2002 		ldns_rr_list_free(validkeys);
2003 		return result;
2004 	}
2005 
2006 	result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2007 	for(i = 0; i < ldns_rr_list_rr_count(keys); i++) {
2008 		status = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
2009 			rrsig, ldns_rr_list_rr(keys, i));
2010 		if (status == LDNS_STATUS_OK) {
2011 			/* one of the keys has matched, don't break
2012 			 * here, instead put the 'winning' key in
2013 			 * the validkey list and return the list
2014 			 * later */
2015 			if (!ldns_rr_list_push_rr(validkeys,
2016 				ldns_rr_list_rr(keys,i))) {
2017 				/* couldn't push the key?? */
2018 				ldns_buffer_free(rawsig_buf);
2019 				ldns_buffer_free(verify_buf);
2020 				ldns_rr_list_deep_free(rrset_clone);
2021 				ldns_rr_list_free(validkeys);
2022 				return LDNS_STATUS_MEM_ERR;
2023 			}
2024 
2025 			result = status;
2026 		}
2027 
2028 		if (result == LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
2029 			result = status;
2030 		}
2031 	}
2032 
2033 	/* no longer needed */
2034 	ldns_rr_list_deep_free(rrset_clone);
2035 	ldns_buffer_free(rawsig_buf);
2036 	ldns_buffer_free(verify_buf);
2037 
2038 	if (ldns_rr_list_rr_count(validkeys) == 0) {
2039 		/* no keys were added, return last error */
2040 		ldns_rr_list_free(validkeys);
2041 		return result;
2042 	}
2043 
2044 	/* do not check timestamps */
2045 
2046 	ldns_rr_list_cat(good_keys, validkeys);
2047 	ldns_rr_list_free(validkeys);
2048 	return LDNS_STATUS_OK;
2049 }
2050 
2051 ldns_status
2052 ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
2053 {
2054 	ldns_buffer *rawsig_buf;
2055 	ldns_buffer *verify_buf;
2056 	ldns_status result;
2057 	ldns_rr_list *rrset_clone;
2058 
2059 	if (!rrset) {
2060 		return LDNS_STATUS_NO_DATA;
2061 	}
2062 	/* clone the rrset so that we can fiddle with it */
2063 	rrset_clone = ldns_rr_list_clone(rrset);
2064 	/* create the buffers which will certainly hold the raw data */
2065 	rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2066 	verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2067 
2068 	result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
2069 		rrset_clone, rrsig);
2070 	if(result != LDNS_STATUS_OK) {
2071 		ldns_rr_list_deep_free(rrset_clone);
2072 		ldns_buffer_free(rawsig_buf);
2073 		ldns_buffer_free(verify_buf);
2074 		return result;
2075 	}
2076 	result = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
2077 		rrsig, key);
2078 	/* no longer needed */
2079 	ldns_rr_list_deep_free(rrset_clone);
2080 	ldns_buffer_free(rawsig_buf);
2081 	ldns_buffer_free(verify_buf);
2082 
2083 	/* check timestamp last, apart from time its OK */
2084 	if(result == LDNS_STATUS_OK)
2085 		result = ldns_rrsig_check_timestamps(rrsig,
2086 			(int32_t)time(NULL));
2087 
2088 	return result;
2089 }
2090 
2091 ldns_status
2092 ldns_verify_rrsig_evp(ldns_buffer *sig,
2093 				  ldns_buffer *rrset,
2094 				  EVP_PKEY *key,
2095 				  const EVP_MD *digest_type)
2096 {
2097 	return ldns_verify_rrsig_evp_raw(
2098 			 (unsigned char*)ldns_buffer_begin(sig),
2099 			 ldns_buffer_position(sig),
2100 			 rrset,
2101 			 key,
2102 			 digest_type);
2103 }
2104 
2105 ldns_status
2106 ldns_verify_rrsig_evp_raw(unsigned char *sig, size_t siglen,
2107 					 ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
2108 {
2109 	EVP_MD_CTX ctx;
2110 	int res;
2111 
2112 	EVP_MD_CTX_init(&ctx);
2113 
2114 	EVP_VerifyInit(&ctx, digest_type);
2115 	EVP_VerifyUpdate(&ctx,
2116 				  ldns_buffer_begin(rrset),
2117 				  ldns_buffer_position(rrset));
2118 	res = EVP_VerifyFinal(&ctx, sig, (unsigned int) siglen, key);
2119 
2120 	EVP_MD_CTX_cleanup(&ctx);
2121 
2122 	if (res == 1) {
2123 		return LDNS_STATUS_OK;
2124 	} else if (res == 0) {
2125 		return LDNS_STATUS_CRYPTO_BOGUS;
2126 	}
2127 	/* TODO how to communicate internal SSL error?
2128 	   let caller use ssl's get_error() */
2129 	return LDNS_STATUS_SSL_ERR;
2130 }
2131 
2132 ldns_status
2133 ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2134 {
2135 	return ldns_verify_rrsig_dsa_raw(
2136 			 (unsigned char*) ldns_buffer_begin(sig),
2137 			 ldns_buffer_position(sig),
2138 			 rrset,
2139 			 (unsigned char*) ldns_buffer_begin(key),
2140 			 ldns_buffer_position(key));
2141 }
2142 
2143 ldns_status
2144 ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2145 {
2146 	return ldns_verify_rrsig_rsasha1_raw(
2147 			 (unsigned char*)ldns_buffer_begin(sig),
2148 			 ldns_buffer_position(sig),
2149 			 rrset,
2150 			 (unsigned char*) ldns_buffer_begin(key),
2151 			 ldns_buffer_position(key));
2152 }
2153 
2154 ldns_status
2155 ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2156 {
2157 	return ldns_verify_rrsig_rsamd5_raw(
2158 			 (unsigned char*)ldns_buffer_begin(sig),
2159 			 ldns_buffer_position(sig),
2160 			 rrset,
2161 			 (unsigned char*) ldns_buffer_begin(key),
2162 			 ldns_buffer_position(key));
2163 }
2164 
2165 ldns_status
2166 ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
2167 					 ldns_buffer* rrset, unsigned char* key, size_t keylen)
2168 {
2169 	EVP_PKEY *evp_key;
2170 	ldns_status result;
2171 
2172 	evp_key = EVP_PKEY_new();
2173 	EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen));
2174 	result = ldns_verify_rrsig_evp_raw(sig,
2175 								siglen,
2176 								rrset,
2177 								evp_key,
2178 								EVP_dss1());
2179 	EVP_PKEY_free(evp_key);
2180 	return result;
2181 
2182 }
2183 
2184 ldns_status
2185 ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen,
2186 						ldns_buffer* rrset, unsigned char* key, size_t keylen)
2187 {
2188 	EVP_PKEY *evp_key;
2189 	ldns_status result;
2190 
2191 	evp_key = EVP_PKEY_new();
2192 	EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
2193 	result = ldns_verify_rrsig_evp_raw(sig,
2194 								siglen,
2195 								rrset,
2196 								evp_key,
2197 								EVP_sha1());
2198 	EVP_PKEY_free(evp_key);
2199 
2200 	return result;
2201 }
2202 
2203 ldns_status
2204 ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
2205 						  size_t siglen,
2206 						  ldns_buffer* rrset,
2207 						  unsigned char* key,
2208 						  size_t keylen)
2209 {
2210 #ifdef USE_SHA2
2211 	EVP_PKEY *evp_key;
2212 	ldns_status result;
2213 
2214 	evp_key = EVP_PKEY_new();
2215 	EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
2216 	result = ldns_verify_rrsig_evp_raw(sig,
2217 								siglen,
2218 								rrset,
2219 								evp_key,
2220 								EVP_sha256());
2221 	EVP_PKEY_free(evp_key);
2222 
2223 	return result;
2224 #else
2225 	/* touch these to prevent compiler warnings */
2226 	(void) sig;
2227 	(void) siglen;
2228 	(void) rrset;
2229 	(void) key;
2230 	(void) keylen;
2231 	return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2232 #endif
2233 }
2234 
2235 ldns_status
2236 ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
2237 						  size_t siglen,
2238 						  ldns_buffer* rrset,
2239 						  unsigned char* key,
2240 						  size_t keylen)
2241 {
2242 #ifdef USE_SHA2
2243 	EVP_PKEY *evp_key;
2244 	ldns_status result;
2245 
2246 	evp_key = EVP_PKEY_new();
2247 	EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
2248 	result = ldns_verify_rrsig_evp_raw(sig,
2249 								siglen,
2250 								rrset,
2251 								evp_key,
2252 								EVP_sha512());
2253 	EVP_PKEY_free(evp_key);
2254 
2255 	return result;
2256 #else
2257 	/* touch these to prevent compiler warnings */
2258 	(void) sig;
2259 	(void) siglen;
2260 	(void) rrset;
2261 	(void) key;
2262 	(void) keylen;
2263 	return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2264 #endif
2265 }
2266 
2267 
2268 ldns_status
2269 ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
2270 					    size_t siglen,
2271 					    ldns_buffer* rrset,
2272 					    unsigned char* key,
2273 					    size_t keylen)
2274 {
2275 	EVP_PKEY *evp_key;
2276 	ldns_status result;
2277 
2278 	evp_key = EVP_PKEY_new();
2279 	EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
2280 	result = ldns_verify_rrsig_evp_raw(sig,
2281 								siglen,
2282 								rrset,
2283 								evp_key,
2284 								EVP_md5());
2285 	EVP_PKEY_free(evp_key);
2286 
2287 	return result;
2288 }
2289 
2290 #endif
2291