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