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		ldns_rr_list *rrset,
1092		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(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(unsigned char* sig, size_t siglen,
1836	ldns_buffer* rrset, 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_ECDSA
1858EVP_PKEY*
1859ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
1860{
1861	unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
1862        const unsigned char* pp = buf;
1863        EVP_PKEY *evp_key;
1864        EC_KEY *ec;
1865	/* check length, which uncompressed must be 2 bignums */
1866        if(algo == LDNS_ECDSAP256SHA256) {
1867		if(keylen != 2*256/8) return NULL;
1868                ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
1869        } else if(algo == LDNS_ECDSAP384SHA384) {
1870		if(keylen != 2*384/8) return NULL;
1871                ec = EC_KEY_new_by_curve_name(NID_secp384r1);
1872        } else    ec = NULL;
1873        if(!ec) return NULL;
1874	if(keylen+1 > sizeof(buf))
1875		return NULL; /* sanity check */
1876	/* prepend the 0x02 (from docs) (or actually 0x04 from implementation
1877	 * of openssl) for uncompressed data */
1878	buf[0] = POINT_CONVERSION_UNCOMPRESSED;
1879	memmove(buf+1, key, keylen);
1880        if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
1881                EC_KEY_free(ec);
1882                return NULL;
1883        }
1884        evp_key = EVP_PKEY_new();
1885        if(!evp_key) {
1886                EC_KEY_free(ec);
1887                return NULL;
1888        }
1889        if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
1890		EVP_PKEY_free(evp_key);
1891		EC_KEY_free(ec);
1892		return NULL;
1893	}
1894        return evp_key;
1895}
1896
1897static ldns_status
1898ldns_verify_rrsig_ecdsa_raw(unsigned char* sig, size_t siglen,
1899	ldns_buffer* rrset, unsigned char* key, size_t keylen, uint8_t algo)
1900{
1901        EVP_PKEY *evp_key;
1902        ldns_status result;
1903        const EVP_MD *d;
1904
1905        evp_key = ldns_ecdsa2pkey_raw(key, keylen, algo);
1906        if(!evp_key) {
1907		/* could not convert key */
1908		return LDNS_STATUS_CRYPTO_BOGUS;
1909        }
1910        if(algo == LDNS_ECDSAP256SHA256)
1911                d = EVP_sha256();
1912        else    d = EVP_sha384(); /* LDNS_ECDSAP384SHA384 */
1913	result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, d);
1914	EVP_PKEY_free(evp_key);
1915	return result;
1916}
1917#endif
1918
1919ldns_status
1920ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf,
1921					 ldns_buffer *key_buf, uint8_t algo)
1922{
1923	return ldns_verify_rrsig_buffers_raw(
1924			 (unsigned char*)ldns_buffer_begin(rawsig_buf),
1925			 ldns_buffer_position(rawsig_buf),
1926			 verify_buf,
1927			 (unsigned char*)ldns_buffer_begin(key_buf),
1928			 ldns_buffer_position(key_buf), algo);
1929}
1930
1931ldns_status
1932ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
1933						ldns_buffer *verify_buf, unsigned char* key, size_t keylen,
1934						uint8_t algo)
1935{
1936	/* check for right key */
1937	switch(algo) {
1938	case LDNS_DSA:
1939	case LDNS_DSA_NSEC3:
1940		return ldns_verify_rrsig_dsa_raw(sig,
1941								   siglen,
1942								   verify_buf,
1943								   key,
1944								   keylen);
1945		break;
1946	case LDNS_RSASHA1:
1947	case LDNS_RSASHA1_NSEC3:
1948		return ldns_verify_rrsig_rsasha1_raw(sig,
1949									  siglen,
1950									  verify_buf,
1951									  key,
1952									  keylen);
1953		break;
1954#ifdef USE_SHA2
1955	case LDNS_RSASHA256:
1956		return ldns_verify_rrsig_rsasha256_raw(sig,
1957									    siglen,
1958									    verify_buf,
1959									    key,
1960									    keylen);
1961		break;
1962	case LDNS_RSASHA512:
1963		return ldns_verify_rrsig_rsasha512_raw(sig,
1964									    siglen,
1965									    verify_buf,
1966									    key,
1967									    keylen);
1968		break;
1969#endif
1970#ifdef USE_GOST
1971	case LDNS_ECC_GOST:
1972		return ldns_verify_rrsig_gost_raw(sig, siglen, verify_buf,
1973			key, keylen);
1974		break;
1975#endif
1976#ifdef USE_ECDSA
1977        case LDNS_ECDSAP256SHA256:
1978        case LDNS_ECDSAP384SHA384:
1979		return ldns_verify_rrsig_ecdsa_raw(sig, siglen, verify_buf,
1980			key, keylen, algo);
1981		break;
1982#endif
1983	case LDNS_RSAMD5:
1984		return ldns_verify_rrsig_rsamd5_raw(sig,
1985									 siglen,
1986									 verify_buf,
1987									 key,
1988									 keylen);
1989		break;
1990	default:
1991		/* do you know this alg?! */
1992		return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
1993	}
1994}
1995
1996
1997/**
1998 * Reset the ttl in the rrset with the orig_ttl from the sig
1999 * and update owner name if it was wildcard
2000 * Also canonicalizes the rrset.
2001 * @param rrset: rrset to modify
2002 * @param sig: signature to take TTL and wildcard values from
2003 */
2004static void
2005ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
2006{
2007	uint32_t orig_ttl;
2008	uint16_t i;
2009	uint8_t label_count;
2010	ldns_rdf *wildcard_name;
2011	ldns_rdf *wildcard_chopped;
2012	ldns_rdf *wildcard_chopped_tmp;
2013
2014	if ((rrsig == NULL) || ldns_rr_rd_count(rrsig) < 4) {
2015		return;
2016	}
2017
2018	orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
2019	label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
2020
2021	for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
2022		if (label_count <
2023		    ldns_dname_label_count(
2024			   ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
2025			(void) ldns_str2rdf_dname(&wildcard_name, "*");
2026			wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(
2027				ldns_rr_list_rr(rrset_clone, i)));
2028			while (label_count < ldns_dname_label_count(wildcard_chopped)) {
2029				wildcard_chopped_tmp = ldns_dname_left_chop(
2030					wildcard_chopped);
2031				ldns_rdf_deep_free(wildcard_chopped);
2032				wildcard_chopped = wildcard_chopped_tmp;
2033			}
2034			(void) ldns_dname_cat(wildcard_name, wildcard_chopped);
2035			ldns_rdf_deep_free(wildcard_chopped);
2036			ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(
2037				rrset_clone, i)));
2038			ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i),
2039				wildcard_name);
2040		}
2041		ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl);
2042		/* convert to lowercase */
2043		ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
2044	}
2045}
2046
2047/**
2048 * Make raw signature buffer out of rrsig
2049 * @param rawsig_buf: raw signature buffer for result
2050 * @param rrsig: signature to convert
2051 * @return OK or more specific error.
2052 */
2053static ldns_status
2054ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
2055{
2056	uint8_t sig_algo;
2057
2058	if (rrsig == NULL) {
2059		return LDNS_STATUS_CRYPTO_NO_RRSIG;
2060	}
2061	if (ldns_rr_rdf(rrsig, 1) == NULL) {
2062		return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2063	}
2064	sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
2065	/* check for known and implemented algo's now (otherwise
2066	 * the function could return a wrong error
2067	 */
2068	/* create a buffer with signature rdata */
2069	/* for some algorithms we need other data than for others... */
2070	/* (the DSA API wants DER encoding for instance) */
2071
2072	switch(sig_algo) {
2073	case LDNS_RSAMD5:
2074	case LDNS_RSASHA1:
2075	case LDNS_RSASHA1_NSEC3:
2076#ifdef USE_SHA2
2077	case LDNS_RSASHA256:
2078	case LDNS_RSASHA512:
2079#endif
2080#ifdef USE_GOST
2081	case LDNS_ECC_GOST:
2082#endif
2083		if (ldns_rr_rdf(rrsig, 8) == NULL) {
2084			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2085		}
2086		if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8))
2087			       	!= LDNS_STATUS_OK) {
2088			return LDNS_STATUS_MEM_ERR;
2089		}
2090		break;
2091	case LDNS_DSA:
2092	case LDNS_DSA_NSEC3:
2093		/* EVP takes rfc2459 format, which is a tad longer than dns format */
2094		if (ldns_rr_rdf(rrsig, 8) == NULL) {
2095			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2096		}
2097		if (ldns_convert_dsa_rrsig_rdf2asn1(
2098					rawsig_buf, ldns_rr_rdf(rrsig, 8))
2099				!= LDNS_STATUS_OK) {
2100			/*
2101			  if (ldns_rdf2buffer_wire(rawsig_buf,
2102			  ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
2103			*/
2104			return LDNS_STATUS_MEM_ERR;
2105		}
2106		break;
2107#ifdef USE_ECDSA
2108        case LDNS_ECDSAP256SHA256:
2109        case LDNS_ECDSAP384SHA384:
2110                /* EVP produces an ASN prefix on the signature, which is
2111                 * not used in the DNS */
2112		if (ldns_rr_rdf(rrsig, 8) == NULL) {
2113			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2114		}
2115		if (ldns_convert_ecdsa_rrsig_rdf2asn1(
2116					rawsig_buf, ldns_rr_rdf(rrsig, 8))
2117				!= LDNS_STATUS_OK) {
2118			return LDNS_STATUS_MEM_ERR;
2119                }
2120                break;
2121#endif
2122	case LDNS_DH:
2123	case LDNS_ECC:
2124	case LDNS_INDIRECT:
2125		return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
2126	default:
2127		return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2128	}
2129	return LDNS_STATUS_OK;
2130}
2131
2132/**
2133 * Check RRSIG timestamps against the given 'now' time.
2134 * @param rrsig: signature to check.
2135 * @param now: the current time in seconds epoch.
2136 * @return status code LDNS_STATUS_OK if all is fine.
2137 */
2138static ldns_status
2139ldns_rrsig_check_timestamps(ldns_rr* rrsig, time_t now)
2140{
2141	int32_t inception, expiration;
2142
2143	/* check the signature time stamps */
2144	inception = (int32_t)ldns_rdf2native_time_t(
2145		ldns_rr_rrsig_inception(rrsig));
2146	expiration = (int32_t)ldns_rdf2native_time_t(
2147		ldns_rr_rrsig_expiration(rrsig));
2148
2149	if (expiration - inception < 0) {
2150		/* bad sig, expiration before inception?? Tsssg */
2151		return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
2152	}
2153	if (((int32_t) now) - inception < 0) {
2154		/* bad sig, inception date has not yet come to pass */
2155		return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
2156	}
2157	if (expiration - ((int32_t) now) < 0) {
2158		/* bad sig, expiration date has passed */
2159		return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
2160	}
2161	return LDNS_STATUS_OK;
2162}
2163
2164/**
2165 * Prepare for verification.
2166 * @param rawsig_buf: raw signature buffer made ready.
2167 * @param verify_buf: data for verification buffer made ready.
2168 * @param rrset_clone: made ready.
2169 * @param rrsig: signature to prepare for.
2170 * @return LDNS_STATUS_OK is all went well. Otherwise specific error.
2171 */
2172static ldns_status
2173ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
2174	ldns_rr_list* rrset_clone, ldns_rr* rrsig)
2175{
2176	ldns_status result;
2177
2178	/* canonicalize the sig */
2179	ldns_dname2canonical(ldns_rr_owner(rrsig));
2180
2181	/* check if the typecovered is equal to the type checked */
2182	if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)) !=
2183	    ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0)))
2184		return LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR;
2185
2186	/* create a buffer with b64 signature rdata */
2187	result = ldns_rrsig2rawsig_buffer(rawsig_buf, rrsig);
2188	if(result != LDNS_STATUS_OK)
2189		return result;
2190
2191	/* use TTL from signature. Use wildcard names for wildcards */
2192	/* also canonicalizes rrset_clone */
2193	ldns_rrset_use_signature_ttl(rrset_clone, rrsig);
2194
2195	/* sort the rrset in canonical order  */
2196	ldns_rr_list_sort(rrset_clone);
2197
2198	/* put the signature rr (without the b64) to the verify_buf */
2199	if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK)
2200		return LDNS_STATUS_MEM_ERR;
2201
2202	/* add the rrset in verify_buf */
2203	if(ldns_rr_list2buffer_wire(verify_buf, rrset_clone)
2204		!= LDNS_STATUS_OK)
2205		return LDNS_STATUS_MEM_ERR;
2206
2207	return LDNS_STATUS_OK;
2208}
2209
2210/**
2211 * Check if a key matches a signature.
2212 * Checks keytag, sigalgo and signature.
2213 * @param rawsig_buf: raw signature buffer for verify
2214 * @param verify_buf: raw data buffer for verify
2215 * @param rrsig: the rrsig
2216 * @param key: key to attempt.
2217 * @return LDNS_STATUS_OK if OK, else some specific error.
2218 */
2219static ldns_status
2220ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
2221	ldns_rr* rrsig, ldns_rr* key)
2222{
2223	uint8_t sig_algo;
2224
2225	if (rrsig == NULL) {
2226		return LDNS_STATUS_CRYPTO_NO_RRSIG;
2227	}
2228	if (ldns_rr_rdf(rrsig, 1) == NULL) {
2229		return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2230	}
2231	sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
2232
2233	/* before anything, check if the keytags match */
2234	if (ldns_calc_keytag(key)
2235	    ==
2236	    ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
2237	    ) {
2238		ldns_buffer* key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2239		ldns_status result = LDNS_STATUS_ERR;
2240
2241		/* put the key-data in a buffer, that's the third rdf, with
2242		 * the base64 encoded key data */
2243		if (ldns_rr_rdf(key, 3) == NULL) {
2244			ldns_buffer_free(key_buf);
2245			return LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
2246		}
2247		if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3))
2248			       	!= LDNS_STATUS_OK) {
2249			ldns_buffer_free(key_buf);
2250			/* returning is bad might screw up
2251			   good keys later in the list
2252			   what to do? */
2253			return LDNS_STATUS_ERR;
2254		}
2255
2256		if (ldns_rr_rdf(key, 2) == NULL) {
2257			result = LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
2258		}
2259		else if (sig_algo == ldns_rdf2native_int8(
2260					ldns_rr_rdf(key, 2))) {
2261			result = ldns_verify_rrsig_buffers(rawsig_buf,
2262				verify_buf, key_buf, sig_algo);
2263		} else {
2264			/* No keys with the corresponding algorithm are found */
2265			result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2266		}
2267
2268		ldns_buffer_free(key_buf);
2269		return result;
2270	}
2271	else {
2272		/* No keys with the corresponding keytag are found */
2273		return LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2274	}
2275}
2276
2277/*
2278 * to verify:
2279 * - create the wire fmt of the b64 key rdata
2280 * - create the wire fmt of the sorted rrset
2281 * - create the wire fmt of the b64 sig rdata
2282 * - create the wire fmt of the sig without the b64 rdata
2283 * - cat the sig data (without b64 rdata) to the rrset
2284 * - verify the rrset+sig, with the b64 data and the b64 key data
2285 */
2286ldns_status
2287ldns_verify_rrsig_keylist_time(
2288		ldns_rr_list *rrset,
2289		ldns_rr *rrsig,
2290		const ldns_rr_list *keys,
2291		time_t check_time,
2292		ldns_rr_list *good_keys)
2293{
2294	ldns_status result;
2295	ldns_rr_list *valid = ldns_rr_list_new();
2296	if (!valid)
2297		return LDNS_STATUS_MEM_ERR;
2298
2299	result = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, valid);
2300	if(result != LDNS_STATUS_OK) {
2301		ldns_rr_list_free(valid);
2302		return result;
2303	}
2304
2305	/* check timestamps last; its OK except time */
2306	result = ldns_rrsig_check_timestamps(rrsig, check_time);
2307	if(result != LDNS_STATUS_OK) {
2308		ldns_rr_list_free(valid);
2309		return result;
2310	}
2311
2312	ldns_rr_list_cat(good_keys, valid);
2313	ldns_rr_list_free(valid);
2314	return LDNS_STATUS_OK;
2315}
2316
2317/*
2318 * to verify:
2319 * - create the wire fmt of the b64 key rdata
2320 * - create the wire fmt of the sorted rrset
2321 * - create the wire fmt of the b64 sig rdata
2322 * - create the wire fmt of the sig without the b64 rdata
2323 * - cat the sig data (without b64 rdata) to the rrset
2324 * - verify the rrset+sig, with the b64 data and the b64 key data
2325 */
2326ldns_status
2327ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
2328					 ldns_rr *rrsig,
2329					 const ldns_rr_list *keys,
2330					 ldns_rr_list *good_keys)
2331{
2332	return ldns_verify_rrsig_keylist_time(
2333			rrset, rrsig, keys, ldns_time(NULL), good_keys);
2334}
2335
2336ldns_status
2337ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset,
2338					 ldns_rr *rrsig,
2339					 const ldns_rr_list *keys,
2340					 ldns_rr_list *good_keys)
2341{
2342	ldns_buffer *rawsig_buf;
2343	ldns_buffer *verify_buf;
2344	uint16_t i;
2345	ldns_status result, status;
2346	ldns_rr_list *rrset_clone;
2347	ldns_rr_list *validkeys;
2348
2349	if (!rrset) {
2350		return LDNS_STATUS_ERR;
2351	}
2352
2353	validkeys = ldns_rr_list_new();
2354	if (!validkeys) {
2355		return LDNS_STATUS_MEM_ERR;
2356	}
2357
2358	/* clone the rrset so that we can fiddle with it */
2359	rrset_clone = ldns_rr_list_clone(rrset);
2360
2361	/* create the buffers which will certainly hold the raw data */
2362	rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2363	verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2364
2365	result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
2366		rrset_clone, rrsig);
2367	if(result != LDNS_STATUS_OK) {
2368		ldns_buffer_free(verify_buf);
2369		ldns_buffer_free(rawsig_buf);
2370		ldns_rr_list_deep_free(rrset_clone);
2371		ldns_rr_list_free(validkeys);
2372		return result;
2373	}
2374
2375	result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2376	for(i = 0; i < ldns_rr_list_rr_count(keys); i++) {
2377		status = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
2378			rrsig, ldns_rr_list_rr(keys, i));
2379		if (status == LDNS_STATUS_OK) {
2380			/* one of the keys has matched, don't break
2381			 * here, instead put the 'winning' key in
2382			 * the validkey list and return the list
2383			 * later */
2384			if (!ldns_rr_list_push_rr(validkeys,
2385				ldns_rr_list_rr(keys,i))) {
2386				/* couldn't push the key?? */
2387				ldns_buffer_free(rawsig_buf);
2388				ldns_buffer_free(verify_buf);
2389				ldns_rr_list_deep_free(rrset_clone);
2390				ldns_rr_list_free(validkeys);
2391				return LDNS_STATUS_MEM_ERR;
2392			}
2393
2394			result = status;
2395		}
2396
2397		if (result == LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
2398			result = status;
2399		}
2400	}
2401
2402	/* no longer needed */
2403	ldns_rr_list_deep_free(rrset_clone);
2404	ldns_buffer_free(rawsig_buf);
2405	ldns_buffer_free(verify_buf);
2406
2407	if (ldns_rr_list_rr_count(validkeys) == 0) {
2408		/* no keys were added, return last error */
2409		ldns_rr_list_free(validkeys);
2410		return result;
2411	}
2412
2413	/* do not check timestamps */
2414
2415	ldns_rr_list_cat(good_keys, validkeys);
2416	ldns_rr_list_free(validkeys);
2417	return LDNS_STATUS_OK;
2418}
2419
2420ldns_status
2421ldns_verify_rrsig_time(
2422		ldns_rr_list *rrset,
2423		ldns_rr *rrsig,
2424		ldns_rr *key,
2425		time_t check_time)
2426{
2427	ldns_buffer *rawsig_buf;
2428	ldns_buffer *verify_buf;
2429	ldns_status result;
2430	ldns_rr_list *rrset_clone;
2431
2432	if (!rrset) {
2433		return LDNS_STATUS_NO_DATA;
2434	}
2435	/* clone the rrset so that we can fiddle with it */
2436	rrset_clone = ldns_rr_list_clone(rrset);
2437	/* create the buffers which will certainly hold the raw data */
2438	rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2439	verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2440
2441	result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
2442		rrset_clone, rrsig);
2443	if(result != LDNS_STATUS_OK) {
2444		ldns_rr_list_deep_free(rrset_clone);
2445		ldns_buffer_free(rawsig_buf);
2446		ldns_buffer_free(verify_buf);
2447		return result;
2448	}
2449	result = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
2450		rrsig, key);
2451	/* no longer needed */
2452	ldns_rr_list_deep_free(rrset_clone);
2453	ldns_buffer_free(rawsig_buf);
2454	ldns_buffer_free(verify_buf);
2455
2456	/* check timestamp last, apart from time its OK */
2457	if(result == LDNS_STATUS_OK)
2458		result = ldns_rrsig_check_timestamps(rrsig, check_time);
2459
2460	return result;
2461}
2462
2463ldns_status
2464ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
2465{
2466	return ldns_verify_rrsig_time(rrset, rrsig, key, ldns_time(NULL));
2467}
2468
2469
2470ldns_status
2471ldns_verify_rrsig_evp(ldns_buffer *sig,
2472				  ldns_buffer *rrset,
2473				  EVP_PKEY *key,
2474				  const EVP_MD *digest_type)
2475{
2476	return ldns_verify_rrsig_evp_raw(
2477			 (unsigned char*)ldns_buffer_begin(sig),
2478			 ldns_buffer_position(sig),
2479			 rrset,
2480			 key,
2481			 digest_type);
2482}
2483
2484ldns_status
2485ldns_verify_rrsig_evp_raw(unsigned char *sig, size_t siglen,
2486					 ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
2487{
2488	EVP_MD_CTX ctx;
2489	int res;
2490
2491	EVP_MD_CTX_init(&ctx);
2492
2493	EVP_VerifyInit(&ctx, digest_type);
2494	EVP_VerifyUpdate(&ctx,
2495				  ldns_buffer_begin(rrset),
2496				  ldns_buffer_position(rrset));
2497	res = EVP_VerifyFinal(&ctx, sig, (unsigned int) siglen, key);
2498
2499	EVP_MD_CTX_cleanup(&ctx);
2500
2501	if (res == 1) {
2502		return LDNS_STATUS_OK;
2503	} else if (res == 0) {
2504		return LDNS_STATUS_CRYPTO_BOGUS;
2505	}
2506	/* TODO how to communicate internal SSL error?
2507	   let caller use ssl's get_error() */
2508	return LDNS_STATUS_SSL_ERR;
2509}
2510
2511ldns_status
2512ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2513{
2514	return ldns_verify_rrsig_dsa_raw(
2515			 (unsigned char*) ldns_buffer_begin(sig),
2516			 ldns_buffer_position(sig),
2517			 rrset,
2518			 (unsigned char*) ldns_buffer_begin(key),
2519			 ldns_buffer_position(key));
2520}
2521
2522ldns_status
2523ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2524{
2525	return ldns_verify_rrsig_rsasha1_raw(
2526			 (unsigned char*)ldns_buffer_begin(sig),
2527			 ldns_buffer_position(sig),
2528			 rrset,
2529			 (unsigned char*) ldns_buffer_begin(key),
2530			 ldns_buffer_position(key));
2531}
2532
2533ldns_status
2534ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2535{
2536	return ldns_verify_rrsig_rsamd5_raw(
2537			 (unsigned char*)ldns_buffer_begin(sig),
2538			 ldns_buffer_position(sig),
2539			 rrset,
2540			 (unsigned char*) ldns_buffer_begin(key),
2541			 ldns_buffer_position(key));
2542}
2543
2544ldns_status
2545ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
2546					 ldns_buffer* rrset, unsigned char* key, size_t keylen)
2547{
2548	EVP_PKEY *evp_key;
2549	ldns_status result;
2550
2551	evp_key = EVP_PKEY_new();
2552	if (EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen))) {
2553		result = ldns_verify_rrsig_evp_raw(sig,
2554								siglen,
2555								rrset,
2556								evp_key,
2557								EVP_dss1());
2558	} else {
2559		result = LDNS_STATUS_SSL_ERR;
2560	}
2561	EVP_PKEY_free(evp_key);
2562	return result;
2563
2564}
2565
2566ldns_status
2567ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen,
2568						ldns_buffer* rrset, unsigned char* key, size_t keylen)
2569{
2570	EVP_PKEY *evp_key;
2571	ldns_status result;
2572
2573	evp_key = EVP_PKEY_new();
2574	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2575		result = ldns_verify_rrsig_evp_raw(sig,
2576								siglen,
2577								rrset,
2578								evp_key,
2579								EVP_sha1());
2580	} else {
2581		result = LDNS_STATUS_SSL_ERR;
2582	}
2583	EVP_PKEY_free(evp_key);
2584
2585	return result;
2586}
2587
2588ldns_status
2589ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
2590						  size_t siglen,
2591						  ldns_buffer* rrset,
2592						  unsigned char* key,
2593						  size_t keylen)
2594{
2595#ifdef USE_SHA2
2596	EVP_PKEY *evp_key;
2597	ldns_status result;
2598
2599	evp_key = EVP_PKEY_new();
2600	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2601		result = ldns_verify_rrsig_evp_raw(sig,
2602								siglen,
2603								rrset,
2604								evp_key,
2605								EVP_sha256());
2606	} else {
2607		result = LDNS_STATUS_SSL_ERR;
2608	}
2609	EVP_PKEY_free(evp_key);
2610
2611	return result;
2612#else
2613	/* touch these to prevent compiler warnings */
2614	(void) sig;
2615	(void) siglen;
2616	(void) rrset;
2617	(void) key;
2618	(void) keylen;
2619	return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2620#endif
2621}
2622
2623ldns_status
2624ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
2625						  size_t siglen,
2626						  ldns_buffer* rrset,
2627						  unsigned char* key,
2628						  size_t keylen)
2629{
2630#ifdef USE_SHA2
2631	EVP_PKEY *evp_key;
2632	ldns_status result;
2633
2634	evp_key = EVP_PKEY_new();
2635	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2636		result = ldns_verify_rrsig_evp_raw(sig,
2637								siglen,
2638								rrset,
2639								evp_key,
2640								EVP_sha512());
2641	} else {
2642		result = LDNS_STATUS_SSL_ERR;
2643	}
2644	EVP_PKEY_free(evp_key);
2645
2646	return result;
2647#else
2648	/* touch these to prevent compiler warnings */
2649	(void) sig;
2650	(void) siglen;
2651	(void) rrset;
2652	(void) key;
2653	(void) keylen;
2654	return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2655#endif
2656}
2657
2658
2659ldns_status
2660ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
2661					    size_t siglen,
2662					    ldns_buffer* rrset,
2663					    unsigned char* key,
2664					    size_t keylen)
2665{
2666	EVP_PKEY *evp_key;
2667	ldns_status result;
2668
2669	evp_key = EVP_PKEY_new();
2670	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2671		result = ldns_verify_rrsig_evp_raw(sig,
2672								siglen,
2673								rrset,
2674								evp_key,
2675								EVP_md5());
2676	} else {
2677		result = LDNS_STATUS_SSL_ERR;
2678	}
2679	EVP_PKEY_free(evp_key);
2680
2681	return result;
2682}
2683
2684#endif
2685