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