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