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