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