Initial vendor import of ldns-1.6.4 into contrib.
[dragonfly.git] / contrib / ldns / dnssec_verify.c
1 #include <ldns/config.h>
2
3 #include <ldns/ldns.h>
4
5 #include <strings.h>
6 #include <time.h>
7
8 #ifdef HAVE_SSL
9 /* this entire file is rather useless when you don't have
10  * crypto...
11  */
12 #include <openssl/ssl.h>
13 #include <openssl/evp.h>
14 #include <openssl/rand.h>
15 #include <openssl/err.h>
16 #include <openssl/md5.h>
17
18 ldns_dnssec_data_chain *
19 ldns_dnssec_data_chain_new()
20 {
21         ldns_dnssec_data_chain *nc = LDNS_XMALLOC(ldns_dnssec_data_chain, 1);
22         nc->rrset = NULL;
23         nc->parent_type = 0;
24         nc->parent = NULL;
25         nc->signatures = NULL;
26         nc->packet_rcode = 0;
27         nc->packet_qtype = 0;
28         nc->packet_nodata = false;
29         return nc;
30 }
31
32 void
33 ldns_dnssec_data_chain_free(ldns_dnssec_data_chain *chain)
34 {
35         LDNS_FREE(chain);
36 }
37
38 void
39 ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain)
40 {
41         ldns_rr_list_deep_free(chain->rrset);
42         ldns_rr_list_deep_free(chain->signatures);
43         if (chain->parent) {
44                 ldns_dnssec_data_chain_deep_free(chain->parent);
45         }
46         LDNS_FREE(chain);
47 }
48
49 void
50 ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain)
51 {
52         ldns_lookup_table *rcode;
53         const ldns_rr_descriptor *rr_descriptor;
54         if (chain) {
55                 ldns_dnssec_data_chain_print(out, chain->parent);
56                 if (ldns_rr_list_rr_count(chain->rrset) > 0) {
57                         rcode = ldns_lookup_by_id(ldns_rcodes,
58                                                                  (int) chain->packet_rcode);
59                         if (rcode) {
60                                 fprintf(out, ";; rcode: %s\n", rcode->name);
61                         }
62
63                         rr_descriptor = ldns_rr_descript(chain->packet_qtype);
64                         if (rr_descriptor && rr_descriptor->_name) {
65                                 fprintf(out, ";; qtype: %s\n", rr_descriptor->_name);
66                         } else if (chain->packet_qtype != 0) {
67                                 fprintf(out, "TYPE%u", 
68                                            chain->packet_qtype);
69                         }
70                         if (chain->packet_nodata) {
71                                 fprintf(out, ";; NODATA response\n");
72                         }
73                         fprintf(out, "rrset:\n");
74                         ldns_rr_list_print(out, chain->rrset);
75                         fprintf(out, "sigs:\n");
76                         ldns_rr_list_print(out, chain->signatures);
77                         fprintf(out, "---\n");
78                 } else {
79                         fprintf(out, "<no data>\n");
80                 }
81         }
82 }
83
84 static void
85 ldns_dnssec_build_data_chain_dnskey(ldns_resolver *res,
86                                             uint16_t qflags,
87                                             const ldns_pkt *pkt,
88                                             ldns_rr_list *signatures,
89                                                 ldns_dnssec_data_chain *new_chain,
90                                                 ldns_rdf *key_name,
91                                                 ldns_rr_class c) {
92         ldns_rr_list *keys;
93         ldns_pkt *my_pkt;
94         if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
95                 new_chain->signatures = ldns_rr_list_clone(signatures);
96                 new_chain->parent_type = 0;
97
98                 keys = ldns_pkt_rr_list_by_name_and_type(
99                                   pkt,
100                                  key_name,
101                                  LDNS_RR_TYPE_DNSKEY,
102                                  LDNS_SECTION_ANY_NOQUESTION
103                           );
104                 if (!keys) {
105                         my_pkt = ldns_resolver_query(res,
106                                                                         key_name,
107                                                                         LDNS_RR_TYPE_DNSKEY,
108                                                                         c,
109                                                                         qflags);
110                         keys = ldns_pkt_rr_list_by_name_and_type(
111                                           my_pkt,
112                                          key_name,
113                                          LDNS_RR_TYPE_DNSKEY,
114                                          LDNS_SECTION_ANY_NOQUESTION
115                                   );
116                         new_chain->parent = ldns_dnssec_build_data_chain(res,
117                                                                                                         qflags,
118                                                                                                         keys,
119                                                                                                         my_pkt,
120                                                                                                         NULL);
121                         new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
122                         ldns_pkt_free(my_pkt);
123                 } else {
124                         new_chain->parent = ldns_dnssec_build_data_chain(res,
125                                                                                                         qflags,
126                                                                                                         keys,
127                                                                                                         pkt,
128                                                                                                         NULL);
129                         new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
130                 }
131                 ldns_rr_list_deep_free(keys);
132         }
133 }
134
135 static void
136 ldns_dnssec_build_data_chain_other(ldns_resolver *res,
137                                             uint16_t qflags,
138                                                 ldns_dnssec_data_chain *new_chain,
139                                                 ldns_rdf *key_name,
140                                                 ldns_rr_class c,
141                                                 ldns_rr_list *dss)
142 {
143         /* 'self-signed', parent is a DS */
144         
145         /* okay, either we have other keys signing the current one,
146          * or the current
147          * one should have a DS record in the parent zone.
148          * How do we find this out? Try both?
149          *
150          * request DNSKEYS for current zone,
151          * add all signatures to current level
152          */
153         ldns_pkt *my_pkt;
154         ldns_rr_list *signatures2;
155         
156         new_chain->parent_type = 1;
157
158         my_pkt = ldns_resolver_query(res,
159                                                         key_name,
160                                                         LDNS_RR_TYPE_DS,
161                                                         c,
162                                                         qflags);
163         dss = ldns_pkt_rr_list_by_name_and_type(my_pkt,
164                                                                         key_name,
165                                                                         LDNS_RR_TYPE_DS,
166                                                                         LDNS_SECTION_ANY_NOQUESTION
167                                                                         );
168         if (dss) {
169                 new_chain->parent = ldns_dnssec_build_data_chain(res,
170                                                                                                 qflags,
171                                                                                                 dss,
172                                                                                                 my_pkt,
173                                                                                                 NULL);
174                 new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
175                 ldns_rr_list_deep_free(dss);
176         }
177         ldns_pkt_free(my_pkt);
178
179         my_pkt = ldns_resolver_query(res,
180                                                         key_name,
181                                                         LDNS_RR_TYPE_DNSKEY,
182                                                         c,
183                                                         qflags);
184         signatures2 = ldns_pkt_rr_list_by_name_and_type(my_pkt,
185                                                                                    key_name,
186                                                                                    LDNS_RR_TYPE_RRSIG,
187                                                                                    LDNS_SECTION_ANSWER);
188         if (signatures2) {
189                 if (new_chain->signatures) {
190                         printf("There were already sigs!\n");
191                         ldns_rr_list_deep_free(new_chain->signatures);
192                         printf("replacing the old sigs\n");
193                 }
194                 new_chain->signatures = signatures2;
195         }
196         ldns_pkt_free(my_pkt);
197 }
198
199 ldns_dnssec_data_chain *
200 ldns_dnssec_build_data_chain_nokeyname(ldns_resolver *res,
201                                        uint16_t qflags,
202                                        ldns_rr *orig_rr,
203                                        const ldns_rr_list *rrset,
204                                        ldns_dnssec_data_chain *new_chain)
205 {
206         ldns_rdf *possible_parent_name;
207         ldns_pkt *my_pkt;
208         /* apparently we were not able to find a signing key, so
209            we assume the chain ends here
210         */
211         /* try parents for auth denial of DS */
212         if (orig_rr) {
213                 possible_parent_name = ldns_rr_owner(orig_rr);
214         } else if (rrset && ldns_rr_list_rr_count(rrset) > 0) {
215                 possible_parent_name = ldns_rr_owner(ldns_rr_list_rr(rrset, 0));
216         } else {
217                 /* no information to go on, give up */
218                 return new_chain;
219         }
220
221         my_pkt = ldns_resolver_query(res,
222                       possible_parent_name,
223                       LDNS_RR_TYPE_DS,
224                       LDNS_RR_CLASS_IN,
225                       qflags);
226
227         if (ldns_pkt_ancount(my_pkt) > 0) {
228                 /* add error, no sigs but DS in parent */
229                 /*ldns_pkt_print(stdout, my_pkt);*/
230                 ldns_pkt_free(my_pkt);
231         } else {
232                 /* are there signatures? */
233                 new_chain->parent =  ldns_dnssec_build_data_chain(res, 
234                                           qflags, 
235                                           NULL,
236                                           my_pkt,
237                                           NULL);
238
239                 new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
240                 
241         }
242         return new_chain;
243 }
244
245
246 ldns_dnssec_data_chain *
247 ldns_dnssec_build_data_chain(ldns_resolver *res,
248                                             uint16_t qflags,
249                                             const ldns_rr_list *rrset,
250                                             const ldns_pkt *pkt,
251                                             ldns_rr *orig_rr)
252 {
253         ldns_rr_list *signatures = NULL;
254         ldns_rr_list *dss = NULL;
255         
256         ldns_rr_list *my_rrset;
257
258         ldns_pkt *my_pkt;
259
260         ldns_rdf *name = NULL, *key_name = NULL;
261         ldns_rr_type type = 0;
262         ldns_rr_class c = 0;
263
264         bool other_rrset = false;
265         
266         ldns_dnssec_data_chain *new_chain = ldns_dnssec_data_chain_new();
267
268         if (!ldns_dnssec_pkt_has_rrsigs(pkt)) {
269                 /* hmm. no dnssec data in the packet. go up to try and deny
270                  * DS? */
271                 return new_chain;
272         }
273
274         if (orig_rr) {
275                 new_chain->rrset = ldns_rr_list_new();
276                 ldns_rr_list_push_rr(new_chain->rrset, orig_rr);
277                 new_chain->parent = ldns_dnssec_build_data_chain(res,
278                                                                                             qflags,
279                                                                                             rrset,
280                                                                                             pkt,
281                                                                                             NULL);
282                 new_chain->packet_rcode = ldns_pkt_get_rcode(pkt);
283                 new_chain->packet_qtype = ldns_rr_get_type(orig_rr);
284                 if (ldns_pkt_ancount(pkt) == 0) {
285                         new_chain->packet_nodata = true;
286                 }
287                 return new_chain;
288         }
289         
290         if (!rrset || ldns_rr_list_rr_count(rrset) < 1) {
291                 /* hmm, no data, do we have denial? only works if pkt was given,
292                    otherwise caller has to do the check himself */
293                 new_chain->packet_nodata = true;
294                 if (pkt) {
295                         my_rrset = ldns_pkt_rr_list_by_type(pkt,
296                                                                                  LDNS_RR_TYPE_NSEC,
297                                                                                  LDNS_SECTION_ANY_NOQUESTION
298                                                                                  );
299                         if (my_rrset) {
300                                 if (ldns_rr_list_rr_count(my_rrset) > 0) {
301                                         type = LDNS_RR_TYPE_NSEC;
302                                         other_rrset = true;
303                                 } else {
304                                         ldns_rr_list_deep_free(my_rrset);
305                                         my_rrset = NULL;
306                                 }
307                         } else {
308                                 /* nothing, try nsec3 */
309                                 my_rrset = ldns_pkt_rr_list_by_type(pkt,
310                                                      LDNS_RR_TYPE_NSEC3,
311                                                         LDNS_SECTION_ANY_NOQUESTION);
312                                 if (my_rrset) {
313                                         if (ldns_rr_list_rr_count(my_rrset) > 0) {
314                                                 type = LDNS_RR_TYPE_NSEC3;
315                                                 other_rrset = true;
316                                         } else {
317                                                 ldns_rr_list_deep_free(my_rrset);
318                                                 my_rrset = NULL;
319                                         }
320                                 } else {
321                                         /* nothing, stop */
322                                         /* try parent zone? for denied insecure? */
323                                         return new_chain;
324                                 }
325                         }
326                 } else {
327                         return new_chain;
328                 }
329         } else {
330                 my_rrset = (ldns_rr_list *) rrset;
331         }
332         
333         if (my_rrset && ldns_rr_list_rr_count(my_rrset) > 0) {
334                 new_chain->rrset = ldns_rr_list_clone(my_rrset);
335                 name = ldns_rr_owner(ldns_rr_list_rr(my_rrset, 0));
336                 type = ldns_rr_get_type(ldns_rr_list_rr(my_rrset, 0));
337                 c = ldns_rr_get_class(ldns_rr_list_rr(my_rrset, 0));
338         }
339         
340         if (other_rrset) {
341                 ldns_rr_list_deep_free(my_rrset);
342         }
343         
344         /* normally there will only be 1 signature 'set'
345            but there can be more than 1 denial (wildcards)
346            so check for NSEC
347         */
348         if (type == LDNS_RR_TYPE_NSEC || type == LDNS_RR_TYPE_NSEC3) {
349                 /* just throw in all signatures, the tree builder must sort
350                    this out */
351                 if (pkt) {
352                         signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
353                 } else {
354                         my_pkt = ldns_resolver_query(res, name, type, c, qflags);
355                         signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
356                         ldns_pkt_free(my_pkt);
357                 }
358         } else {
359                 if (pkt) {
360                         signatures =
361                                 ldns_dnssec_pkt_get_rrsigs_for_name_and_type(pkt,
362                                                                                                         name,
363                                                                                                         type);
364                 }
365                 if (!signatures) {
366                         my_pkt = ldns_resolver_query(res, name, type, c, qflags);
367                         signatures =
368                                 ldns_dnssec_pkt_get_rrsigs_for_name_and_type(my_pkt,
369                                                                                                         name,
370                                                                                                         type);
371                         ldns_pkt_free(my_pkt);
372                 }
373         }
374
375         if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
376                 key_name = ldns_rr_rdf(ldns_rr_list_rr(signatures, 0), 7);
377         }
378
379         if (!key_name) {
380                 return ldns_dnssec_build_data_chain_nokeyname(res,
381                                                               qflags,
382                                                               orig_rr,
383                                                               rrset,
384                                                               new_chain);
385         }
386
387         if (type != LDNS_RR_TYPE_DNSKEY) {
388                 ldns_dnssec_build_data_chain_dnskey(res,
389                                                     qflags,
390                                                     pkt,
391                                                     signatures,
392                                                     new_chain,
393                                                     key_name,
394                                                     c
395                                                     );
396         } else {
397                 ldns_dnssec_build_data_chain_other(res,
398                                                    qflags,
399                                                    new_chain,
400                                                    key_name,
401                                                    c,
402                                                    dss
403                                                     
404                                                     );
405         }
406         if (signatures) {
407                 ldns_rr_list_deep_free(signatures);
408         }
409
410         return new_chain;
411 }
412
413 ldns_dnssec_trust_tree *
414 ldns_dnssec_trust_tree_new()
415 {
416         ldns_dnssec_trust_tree *new_tree = LDNS_XMALLOC(ldns_dnssec_trust_tree,
417                                                                                    1);
418         new_tree->rr = NULL;
419         new_tree->rrset = NULL;
420         new_tree->parent_count = 0;
421
422         return new_tree;
423 }
424
425 void
426 ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree)
427 {
428         size_t i;
429         if (tree) {
430                 for (i = 0; i < tree->parent_count; i++) {
431                         ldns_dnssec_trust_tree_free(tree->parents[i]);
432                 }
433         }
434         LDNS_FREE(tree);
435 }
436
437 size_t
438 ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree)
439 {
440         size_t result = 0;
441         size_t parent = 0;
442         size_t i;
443         
444         for (i = 0; i < tree->parent_count; i++) {
445                 parent = ldns_dnssec_trust_tree_depth(tree->parents[i]);
446                 if (parent > result) {
447                         result = parent;
448                 }
449         }
450         return 1 + result;
451 }
452
453 /* TODO ldns_ */
454 static void
455 print_tabs(FILE *out, size_t nr, uint8_t *map, size_t treedepth)
456 {
457         size_t i;
458         for (i = 0; i < nr; i++) {
459                 if (i == nr - 1) {
460                         fprintf(out, "|---");
461                 } else if (map && i < treedepth && map[i] == 1) {
462                         fprintf(out, "|   ");
463                 } else {
464                         fprintf(out, "    ");
465                 }
466         }
467 }
468
469 void
470 ldns_dnssec_trust_tree_print_sm(FILE *out,
471                                                   ldns_dnssec_trust_tree *tree,
472                                                   size_t tabs,
473                                                   bool extended,
474                                                   uint8_t *sibmap,
475                                                   size_t treedepth)
476 {
477         size_t i;
478         const ldns_rr_descriptor *descriptor;
479         bool mapset = false;
480         
481         if (!sibmap) {
482                 treedepth = ldns_dnssec_trust_tree_depth(tree);
483                 sibmap = malloc(treedepth);
484                 memset(sibmap, 0, treedepth);
485                 mapset = true;
486         }
487         
488         if (tree) {
489                 if (tree->rr) {
490                         print_tabs(out, tabs, sibmap, treedepth);
491                         ldns_rdf_print(out, ldns_rr_owner(tree->rr));
492                         descriptor = ldns_rr_descript(ldns_rr_get_type(tree->rr));
493
494                         if (descriptor->_name) {
495                                 fprintf(out, " (%s", descriptor->_name);
496                         } else {
497                                 fprintf(out, " (TYPE%d", 
498                                            ldns_rr_get_type(tree->rr));
499                         }
500                         if (tabs > 0) {
501                                 if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DNSKEY) {
502                                         fprintf(out, " keytag: %u",
503                                                 (unsigned int) ldns_calc_keytag(tree->rr));
504                                         fprintf(out, " alg: ");
505                                         ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
506                                         fprintf(out, " flags: ");
507                                         ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
508                                 } else if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DS) {
509                                         fprintf(out, " keytag: ");
510                                         ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
511                                         fprintf(out, " digest type: ");
512                                         ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
513                                 }
514                                 if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NSEC) {
515                                         fprintf(out, " ");
516                                         ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
517                                         fprintf(out, " ");
518                                         ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 1));
519                                 }
520                         }
521                         
522                         fprintf(out, ")\n");
523                         for (i = 0; i < tree->parent_count; i++) {
524                                 if (tree->parent_count > 1 && i < tree->parent_count - 1) {
525                                         sibmap[tabs] = 1;
526                                 } else {
527                                         sibmap[tabs] = 0;
528                                 }
529                                 /* only print errors */
530                                 if (ldns_rr_get_type(tree->parents[i]->rr) == 
531                                     LDNS_RR_TYPE_NSEC ||
532                                     ldns_rr_get_type(tree->parents[i]->rr) ==
533                                     LDNS_RR_TYPE_NSEC3) {
534                                         if (tree->parent_status[i] == LDNS_STATUS_OK) {
535                                                 print_tabs(out, tabs + 1, sibmap, treedepth);
536                                                 if (tabs == 0 &&
537                                                     ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS &&
538                                                         ldns_rr_rd_count(tree->rr) > 0) {
539                                                         fprintf(out, "Existence of DS is denied by:\n");
540                                                 } else {
541                                                         fprintf(out, "Existence is denied by:\n");
542                                                 }
543                                         } else {
544                                                 /* NS records aren't signed */
545                                                 if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS) {
546                                                         fprintf(out, "Existence of DS is denied by:\n");
547                                                 } else {
548                                                         print_tabs(out, tabs + 1, sibmap, treedepth);
549                                                         fprintf(out,
550                                                                    "Error in denial of existence: %s\n",
551                                                                    ldns_get_errorstr_by_id(
552                                                                            tree->parent_status[i]));
553                                                 }
554                                         }
555                                 } else
556                                         if (tree->parent_status[i] != LDNS_STATUS_OK) {
557                                                 print_tabs(out, tabs + 1, sibmap, treedepth);
558                                                 fprintf(out,
559                                                            "%s:\n",
560                                                            ldns_get_errorstr_by_id(
561                                                                tree->parent_status[i]));
562                                                 if (tree->parent_status[i]
563                                                     == LDNS_STATUS_SSL_ERR) {
564                                                         printf("; SSL Error: ");
565                                                         ERR_load_crypto_strings();
566                                                         ERR_print_errors_fp(stdout);
567                                                         printf("\n");
568                                                 }
569                                                 ldns_rr_print(out, tree->parent_signature[i]);
570                                                 printf("For RRset:\n");
571                                                 ldns_rr_list_print(out, tree->rrset);
572                                                 printf("With key:\n");
573                                                 ldns_rr_print(out, tree->parents[i]->rr);
574                                         }
575                                 ldns_dnssec_trust_tree_print_sm(out,
576                                                                                   tree->parents[i],
577                                                                                   tabs+1,
578                                                                                   extended,
579                                                                                   sibmap,
580                                                                                   treedepth);
581                         }
582                 } else {
583                         print_tabs(out, tabs, sibmap, treedepth);
584                         fprintf(out, "<no data>\n");
585                 }
586         } else {
587                 fprintf(out, "<null pointer>\n");
588         }
589         
590         if (mapset) {
591                 free(sibmap);
592         }
593 }
594
595 void
596 ldns_dnssec_trust_tree_print(FILE *out,
597                                             ldns_dnssec_trust_tree *tree,
598                                             size_t tabs,
599                                             bool extended)
600 {
601         ldns_dnssec_trust_tree_print_sm(out, tree, tabs, extended, NULL, 0);
602 }
603
604 ldns_status
605 ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree,
606                                   const ldns_dnssec_trust_tree *parent,
607                                   const ldns_rr *signature,
608                                   const ldns_status parent_status)
609 {
610         if (tree
611             && parent
612             && tree->parent_count < LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS) {
613                 /*
614                   printf("Add parent for: ");
615                   ldns_rr_print(stdout, tree->rr);
616                   printf("parent: ");
617                   ldns_rr_print(stdout, parent->rr);
618                 */
619                 tree->parents[tree->parent_count] =
620                         (ldns_dnssec_trust_tree *) parent;
621                 tree->parent_status[tree->parent_count] = parent_status;
622                 tree->parent_signature[tree->parent_count] = (ldns_rr *) signature;
623                 tree->parent_count++;
624                 return LDNS_STATUS_OK;
625         } else {
626                 return LDNS_STATUS_ERR;
627         }
628 }
629
630 /* if rr is null, take the first from the rrset */
631 ldns_dnssec_trust_tree *
632 ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr)
633 {
634         ldns_rr_list *cur_rrset;
635         ldns_rr_list *cur_sigs;
636         ldns_rr *cur_rr = NULL;
637         ldns_rr *cur_sig_rr;
638         uint16_t cur_keytag;
639         size_t i, j;
640
641         ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new();
642         
643         if (data_chain && data_chain->rrset) {
644                 cur_rrset = data_chain->rrset;
645         
646                 cur_sigs = data_chain->signatures;
647
648                 if (rr) {
649                         cur_rr = rr;
650                 }
651
652                 if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) {
653                         cur_rr = ldns_rr_list_rr(cur_rrset, 0);
654                 }
655
656                 if (cur_rr) {
657                         new_tree->rr = cur_rr;
658                         new_tree->rrset = cur_rrset;
659                         /* there are three possibilities:
660                            1 - 'normal' rrset, signed by a key
661                            2 - dnskey signed by other dnskey
662                            3 - dnskey proven by higher level DS
663                            (data denied by nsec is a special case that can
664                            occur in multiple places)
665                                    
666                         */
667                         if (cur_sigs) {
668                                 for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) {
669                                         /* find the appropriate key in the parent list */
670                                         cur_sig_rr = ldns_rr_list_rr(cur_sigs, i);
671                                         cur_keytag = 
672                                                 ldns_rdf2native_int16(
673                                                     ldns_rr_rrsig_keytag(cur_sig_rr));
674
675                                         if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) {
676                                                 if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
677                                                                                    ldns_rr_owner(cur_rr)))
678                                                         {
679                                                                 /* find first that does match */
680
681                                                                 for (j = 0;
682                                                                      j < ldns_rr_list_rr_count(cur_rrset) && 
683                                                                                 ldns_dname_compare(ldns_rr_owner(cur_sig_rr),ldns_rr_owner(cur_rr)) != 0;
684                                                                      j++) {
685                                                                         cur_rr = ldns_rr_list_rr(cur_rrset, j);
686                                                                         
687                                                                 }
688                                                                 if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr), 
689                                                                                                    ldns_rr_owner(cur_rr)))
690                                                                         {
691                                                                                 break;
692                                                                         }
693                                                         }
694                                                         
695                                         }
696                                         /* option 1 */
697                                         if (data_chain->parent) {
698                                                 ldns_dnssec_derive_trust_tree_normal_rrset(
699                                                     new_tree,
700                                                     data_chain,
701                                                     cur_sig_rr);
702                                         }
703
704                                         /* option 2 */
705                                         ldns_dnssec_derive_trust_tree_dnskey_rrset(
706                                             new_tree,
707                                             data_chain,
708                                             cur_rr,
709                                             cur_sig_rr);
710                                 }
711                                         
712                                 ldns_dnssec_derive_trust_tree_ds_rrset(new_tree,
713                                                                                             data_chain,
714                                                                                             cur_rr);
715                         } else {
716                                 /* no signatures? maybe it's nsec data */
717                                         
718                                 /* just add every rr from parent as new parent */
719                                 ldns_dnssec_derive_trust_tree_no_sig(new_tree, data_chain);
720                         }
721                 }
722         }
723
724         return new_tree;
725 }
726
727 void
728 ldns_dnssec_derive_trust_tree_normal_rrset(ldns_dnssec_trust_tree *new_tree,
729                                            ldns_dnssec_data_chain *data_chain,
730                                            ldns_rr *cur_sig_rr)
731 {
732         size_t i, j;
733         ldns_rr_list *cur_rrset = ldns_rr_list_clone(data_chain->rrset); 
734         ldns_dnssec_trust_tree *cur_parent_tree;
735         ldns_rr *cur_parent_rr;
736         uint16_t cur_keytag;
737         ldns_rr_list *tmp_rrset = NULL;
738         ldns_status cur_status;
739
740         cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
741         
742         for (j = 0; j < ldns_rr_list_rr_count(data_chain->parent->rrset); j++) {
743                 cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
744                 if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
745                         if (ldns_calc_keytag(cur_parent_rr) == cur_keytag) {
746
747                                 /* TODO: check wildcard nsec too */
748                                 if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
749                                         tmp_rrset = cur_rrset;
750                                         if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
751                                             == LDNS_RR_TYPE_NSEC ||
752                                             ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
753                                             == LDNS_RR_TYPE_NSEC3) {
754                                                 /* might contain different names! 
755                                                    sort and split */
756                                                 ldns_rr_list_sort(cur_rrset);
757                                                 if (tmp_rrset && tmp_rrset != cur_rrset) {
758                                                         ldns_rr_list_deep_free(tmp_rrset);
759                                                         tmp_rrset = NULL;
760                                                 }
761                                                 tmp_rrset = ldns_rr_list_pop_rrset(cur_rrset);
762                                                 
763                                                 /* with nsecs, this might be the wrong one */
764                                                 while (tmp_rrset &&
765                                                        ldns_rr_list_rr_count(cur_rrset) > 0 &&
766                                                        ldns_dname_compare(
767                                                                 ldns_rr_owner(ldns_rr_list_rr(
768                                                                                         tmp_rrset, 0)),
769                                                                 ldns_rr_owner(cur_sig_rr)) != 0) {
770                                                         ldns_rr_list_deep_free(tmp_rrset);
771                                                         tmp_rrset =
772                                                                 ldns_rr_list_pop_rrset(cur_rrset);
773                                                 }
774                                         }
775                                         cur_status = ldns_verify_rrsig(tmp_rrset,
776                                                                                          cur_sig_rr,
777                                                                                          cur_parent_rr);
778                                         /* avoid dupes */
779                                         for (i = 0; i < new_tree->parent_count; i++) {
780                                                 if (cur_parent_rr == new_tree->parents[i]->rr) {
781                                                         goto done;
782                                                 }
783                                         }
784
785                                         cur_parent_tree =
786                                                 ldns_dnssec_derive_trust_tree(data_chain->parent,
787                                                                               cur_parent_rr);
788                                         (void)ldns_dnssec_trust_tree_add_parent(new_tree,
789                                                    cur_parent_tree,
790                                                    cur_sig_rr,
791                                                    cur_status);
792                                 }
793                         }
794                 }
795         }
796  done:
797         if (tmp_rrset && tmp_rrset != cur_rrset) {
798                 ldns_rr_list_deep_free(tmp_rrset);
799         }
800         ldns_rr_list_deep_free(cur_rrset);
801 }
802
803 void
804 ldns_dnssec_derive_trust_tree_dnskey_rrset(ldns_dnssec_trust_tree *new_tree,
805                                            ldns_dnssec_data_chain *data_chain,
806                                            ldns_rr *cur_rr,
807                                            ldns_rr *cur_sig_rr)
808 {
809         size_t j;
810         ldns_rr_list *cur_rrset = data_chain->rrset;
811         ldns_dnssec_trust_tree *cur_parent_tree;
812         ldns_rr *cur_parent_rr;
813         uint16_t cur_keytag;
814         ldns_status cur_status;
815
816         cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
817
818         for (j = 0; j < ldns_rr_list_rr_count(cur_rrset); j++) {
819                 cur_parent_rr = ldns_rr_list_rr(cur_rrset, j);
820                 if (cur_parent_rr != cur_rr &&
821                     ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
822                         if (ldns_calc_keytag(cur_parent_rr) == cur_keytag
823                             ) {
824                                 cur_parent_tree = ldns_dnssec_trust_tree_new();
825                                 cur_parent_tree->rr = cur_parent_rr;
826                                 cur_parent_tree->rrset = cur_rrset;
827                                 cur_status = ldns_verify_rrsig(cur_rrset,
828                                                                cur_sig_rr,
829                                                                cur_parent_rr);
830                                 (void) ldns_dnssec_trust_tree_add_parent(new_tree,
831                                             cur_parent_tree, cur_sig_rr, cur_status);
832                         }
833                 }
834         }
835 }
836
837 void
838 ldns_dnssec_derive_trust_tree_ds_rrset(ldns_dnssec_trust_tree *new_tree,
839                                        ldns_dnssec_data_chain *data_chain,
840                                        ldns_rr *cur_rr)
841 {
842         size_t j, h;
843         ldns_rr_list *cur_rrset = data_chain->rrset;
844         ldns_dnssec_trust_tree *cur_parent_tree;
845         ldns_rr *cur_parent_rr;
846
847         /* try the parent to see whether there are DSs there */
848         if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_DNSKEY &&
849             data_chain->parent &&
850             data_chain->parent->rrset
851             ) {
852                 for (j = 0;
853                         j < ldns_rr_list_rr_count(data_chain->parent->rrset);
854                         j++) {
855                         cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
856                         if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DS) {
857                                 for (h = 0; h < ldns_rr_list_rr_count(cur_rrset); h++) {
858                                         cur_rr = ldns_rr_list_rr(cur_rrset, h);
859                                         if (ldns_rr_compare_ds(cur_rr, cur_parent_rr)) {
860                                                 cur_parent_tree =
861                                                         ldns_dnssec_derive_trust_tree(
862                                                             data_chain->parent, cur_parent_rr);
863                                                 (void) ldns_dnssec_trust_tree_add_parent(
864                                                             new_tree,
865                                                             cur_parent_tree,
866                                                             NULL,
867                                                             LDNS_STATUS_OK);
868                                         } else {
869                                                 /*ldns_rr_print(stdout, cur_parent_rr);*/
870                                         }
871                                 }
872                                 cur_rr = ldns_rr_list_rr(cur_rrset, 0);
873                         }
874                 }
875         }
876 }
877
878 void
879 ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree *new_tree,
880                                      ldns_dnssec_data_chain *data_chain)
881 {
882         size_t i;
883         ldns_rr_list *cur_rrset;
884         ldns_rr *cur_parent_rr;
885         ldns_dnssec_trust_tree *cur_parent_tree;
886         ldns_status result;
887         
888         if (data_chain->parent && data_chain->parent->rrset) {
889                 cur_rrset = data_chain->parent->rrset;
890                 /* nsec? */
891                 if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
892                         if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
893                             LDNS_RR_TYPE_NSEC3) {
894                                 result = ldns_dnssec_verify_denial_nsec3(
895                                                 new_tree->rr,
896                                                    cur_rrset,
897                                                    data_chain->parent->signatures,
898                                                    data_chain->packet_rcode,
899                                                    data_chain->packet_qtype,
900                                                    data_chain->packet_nodata);
901                         } else if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
902                                          LDNS_RR_TYPE_NSEC3) {
903                                 result = ldns_dnssec_verify_denial(
904                                                 new_tree->rr,
905                                                    cur_rrset,
906                                                    data_chain->parent->signatures);
907                         } else {
908                                 /* unsigned zone, unsigned parent */
909                                 result = LDNS_STATUS_OK;
910                         }
911                 } else {
912                         result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
913                 }
914                 for (i = 0; i < ldns_rr_list_rr_count(cur_rrset); i++) {
915                         cur_parent_rr = ldns_rr_list_rr(cur_rrset, i);
916                         cur_parent_tree = 
917                                 ldns_dnssec_derive_trust_tree(data_chain->parent,
918                                                                                 cur_parent_rr);
919                         (void) ldns_dnssec_trust_tree_add_parent(new_tree,
920                                     cur_parent_tree, NULL, result);
921                 }
922         }
923 }
924
925 /*
926  * returns OK if there is a path from tree to key with only OK
927  * the (first) error in between otherwise
928  * or NOT_FOUND if the key wasn't present at all
929  */
930 ldns_status
931 ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree,
932                                                           ldns_rr_list *trusted_keys)
933 {
934         size_t i;
935         ldns_status result = LDNS_STATUS_CRYPTO_NO_DNSKEY;
936         bool equal;
937         ldns_status parent_result;
938         
939         if (tree && trusted_keys && ldns_rr_list_rr_count(trusted_keys) > 0)
940                 { if (tree->rr) {
941                                 for (i = 0; i < ldns_rr_list_rr_count(trusted_keys); i++) {
942                                         equal = ldns_rr_compare_ds(
943                                                           tree->rr,
944                                                           ldns_rr_list_rr(trusted_keys, i));
945                                         if (equal) {
946                                                 result = LDNS_STATUS_OK;
947                                                 return result;
948                                         }
949                                 }
950                         }
951                         for (i = 0; i < tree->parent_count; i++) {
952                                 parent_result =
953                                         ldns_dnssec_trust_tree_contains_keys(tree->parents[i],
954                                                                                                   trusted_keys);
955                                 if (parent_result != LDNS_STATUS_CRYPTO_NO_DNSKEY) {
956                                         if (tree->parent_status[i] != LDNS_STATUS_OK) {
957                                                 result = tree->parent_status[i];
958                                         } else {
959                                                 if (ldns_rr_get_type(tree->rr)
960                                                     == LDNS_RR_TYPE_NSEC &&
961                                                     parent_result == LDNS_STATUS_OK
962                                                     ) {
963                                                         result =
964                                                                 LDNS_STATUS_DNSSEC_EXISTENCE_DENIED;
965                                                 } else {
966                                                         result = parent_result;
967                                                 }
968                                         }
969                                 }
970                         }
971                 } else {
972                 result = LDNS_STATUS_ERR;
973         }
974         
975         return result;
976 }
977
978 ldns_status
979 ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys, 
980                   ldns_rr_list *good_keys)
981 {
982         uint16_t i;
983         ldns_status verify_result = LDNS_STATUS_ERR;
984
985         if (!rrset || !rrsig || !keys) {
986                 return LDNS_STATUS_ERR;
987         }
988
989         if (ldns_rr_list_rr_count(rrset) < 1) {
990                 return LDNS_STATUS_ERR;
991         }
992
993         if (ldns_rr_list_rr_count(rrsig) < 1) {
994                 return LDNS_STATUS_CRYPTO_NO_RRSIG;
995         }
996         
997         if (ldns_rr_list_rr_count(keys) < 1) {
998                 verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
999         } else {
1000                 for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1001                         ldns_status s = ldns_verify_rrsig_keylist(rrset, 
1002                                 ldns_rr_list_rr(rrsig, i), keys, good_keys);
1003                         /* try a little to get more descriptive error */
1004                         if(s == LDNS_STATUS_OK) {
1005                                 verify_result = LDNS_STATUS_OK;
1006                         } else if(verify_result == LDNS_STATUS_ERR)
1007                                 verify_result = s;
1008                         else if(s !=  LDNS_STATUS_ERR && verify_result ==
1009                                 LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY)
1010                                 verify_result = s;
1011                 }
1012         }
1013         return verify_result;
1014 }
1015
1016 ldns_status
1017 ldns_verify_notime(ldns_rr_list *rrset, ldns_rr_list *rrsig,
1018         const ldns_rr_list *keys, ldns_rr_list *good_keys)
1019 {
1020         uint16_t i;
1021         ldns_status verify_result = LDNS_STATUS_ERR;
1022
1023         if (!rrset || !rrsig || !keys) {
1024                 return LDNS_STATUS_ERR;
1025         }
1026
1027         if (ldns_rr_list_rr_count(rrset) < 1) {
1028                 return LDNS_STATUS_ERR;
1029         }
1030
1031         if (ldns_rr_list_rr_count(rrsig) < 1) {
1032                 return LDNS_STATUS_CRYPTO_NO_RRSIG;
1033         }
1034
1035         if (ldns_rr_list_rr_count(keys) < 1) {
1036                 verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1037         } else {
1038                 for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1039                         ldns_status s = ldns_verify_rrsig_keylist_notime(rrset,
1040                                 ldns_rr_list_rr(rrsig, i), keys, good_keys);
1041
1042                         /* try a little to get more descriptive error */
1043                         if (s == LDNS_STATUS_OK) {
1044                                 verify_result = LDNS_STATUS_OK;
1045                         } else if (verify_result == LDNS_STATUS_ERR) {
1046                                 verify_result = s;
1047                         } else if (s !=  LDNS_STATUS_ERR && verify_result ==
1048                                 LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
1049                                 verify_result = s;
1050                         }
1051                 }
1052         }
1053         return verify_result;
1054 }
1055
1056 ldns_rr_list *
1057 ldns_fetch_valid_domain_keys(const ldns_resolver *res,
1058                              const ldns_rdf *domain,
1059                              const ldns_rr_list *keys,
1060                              ldns_status *status)
1061 {
1062         ldns_rr_list * trusted_keys = NULL;
1063         ldns_rr_list * ds_keys = NULL;
1064
1065         if (res && domain && keys) {
1066
1067                 if ((trusted_keys = ldns_validate_domain_dnskey(res,
1068                                          domain,
1069                                          keys))) {
1070                         *status = LDNS_STATUS_OK;
1071                 } else {
1072                         /* No trusted keys in this domain, we'll have to find some in the parent domain */
1073                         *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1074       
1075                         if (ldns_rdf_size(domain) > 1) {
1076                                 /* Fail if we are at the root */
1077                                 ldns_rr_list * parent_keys;
1078                                 ldns_rdf * parent_domain = ldns_dname_left_chop(domain);
1079         
1080                                 if ((parent_keys = 
1081                                         ldns_fetch_valid_domain_keys(res,
1082                                              parent_domain,
1083                                              keys,
1084                                              status))) {
1085                                         /* Check DS records */
1086                                         if ((ds_keys =
1087                                                 ldns_validate_domain_ds(res,
1088                                                      domain,
1089                                                      parent_keys))) {
1090                                                 trusted_keys =
1091                                                         ldns_fetch_valid_domain_keys(res,
1092                                                              domain,
1093                                                              ds_keys,
1094                                                              status);
1095                                                 ldns_rr_list_deep_free(ds_keys);
1096                                         } else {
1097                                                 /* No valid DS at the parent -- fail */
1098                                                 *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DS ;
1099                                         }
1100                                         ldns_rr_list_deep_free(parent_keys);
1101                                 }
1102                                 ldns_rdf_deep_free(parent_domain);
1103                         }
1104                 }
1105         }
1106         return trusted_keys;
1107 }
1108
1109 ldns_rr_list *
1110 ldns_validate_domain_dnskey(const ldns_resolver * res,
1111                                            const ldns_rdf * domain,
1112                                            const ldns_rr_list * keys)
1113 {
1114         ldns_status status;
1115         ldns_pkt * keypkt;
1116         ldns_rr * cur_key;
1117         uint16_t key_i; uint16_t key_j; uint16_t key_k;
1118         uint16_t sig_i; ldns_rr * cur_sig;
1119
1120         ldns_rr_list * domain_keys = NULL;
1121         ldns_rr_list * domain_sigs = NULL;
1122         ldns_rr_list * trusted_keys = NULL;
1123
1124         /* Fetch keys for the domain */
1125         if ((keypkt = ldns_resolver_query(res,
1126                                                             domain,
1127                                                             LDNS_RR_TYPE_DNSKEY,
1128                                                             LDNS_RR_CLASS_IN,
1129                                                             LDNS_RD))) {
1130
1131                 domain_keys = ldns_pkt_rr_list_by_type(keypkt,
1132                                                                             LDNS_RR_TYPE_DNSKEY,
1133                                                                             LDNS_SECTION_ANSWER);
1134                 domain_sigs = ldns_pkt_rr_list_by_type(keypkt,
1135                                                                             LDNS_RR_TYPE_RRSIG,
1136                                                                             LDNS_SECTION_ANSWER);
1137
1138                 /* Try to validate the record using our keys */
1139                 for (key_i=0; key_i< ldns_rr_list_rr_count(domain_keys); key_i++) {
1140       
1141                         cur_key = ldns_rr_list_rr(domain_keys, key_i);
1142                         for (key_j=0; key_j<ldns_rr_list_rr_count(keys); key_j++) {
1143                                 if (ldns_rr_compare_ds(ldns_rr_list_rr(keys, key_j),
1144                                                                    cur_key)) {
1145           
1146                                         /* Current key is trusted -- validate */
1147                                         trusted_keys = ldns_rr_list_new();
1148           
1149                                         for (sig_i=0;
1150                                                 sig_i<ldns_rr_list_rr_count(domain_sigs);
1151                                                 sig_i++) {
1152                                                 cur_sig = ldns_rr_list_rr(domain_sigs, sig_i);
1153                                                 /* Avoid non-matching sigs */
1154                                                 if (ldns_rdf2native_int16(
1155                                                            ldns_rr_rrsig_keytag(cur_sig))
1156                                                     == ldns_calc_keytag(cur_key)) {
1157                                                         if ((status =
1158                                                                 ldns_verify_rrsig(domain_keys,
1159                                                                                            cur_sig,
1160                                                                                            cur_key))
1161                                                             == LDNS_STATUS_OK) {
1162                 
1163                                                                 /* Push the whole rrset 
1164                                                                    -- we can't do much more */
1165                                                                 for (key_k=0;
1166                                                                         key_k<ldns_rr_list_rr_count(
1167                                                                                         domain_keys);
1168                                                                         key_k++) {
1169                                                                         ldns_rr_list_push_rr(
1170                                                                             trusted_keys,
1171                                                                             ldns_rr_clone(
1172                                                                                    ldns_rr_list_rr(
1173                                                                                           domain_keys,
1174                                                                                           key_k)));
1175                                                                 }
1176                 
1177                                                                 ldns_rr_list_deep_free(domain_keys);
1178                                                                 ldns_rr_list_deep_free(domain_sigs);
1179                                                                 ldns_pkt_free(keypkt);
1180                                                                 return trusted_keys;
1181                                                         }
1182                                                 }
1183                                         }
1184           
1185                                         /* Only push our trusted key */
1186                                         ldns_rr_list_push_rr(trusted_keys,
1187                                                                          ldns_rr_clone(cur_key));
1188                                 }
1189                         }
1190                 }
1191
1192                 ldns_rr_list_deep_free(domain_keys);
1193                 ldns_rr_list_deep_free(domain_sigs);
1194                 ldns_pkt_free(keypkt);
1195
1196         } else {
1197                 status = LDNS_STATUS_CRYPTO_NO_DNSKEY;
1198         }
1199     
1200         return trusted_keys;
1201 }
1202
1203 ldns_rr_list *
1204 ldns_validate_domain_ds(const ldns_resolver *res,
1205                                     const ldns_rdf * domain,
1206                                     const ldns_rr_list * keys)
1207 {
1208         ldns_status status;
1209         ldns_pkt * dspkt;
1210         uint16_t key_i;
1211         ldns_rr_list * rrset = NULL;
1212         ldns_rr_list * sigs = NULL;
1213         ldns_rr_list * trusted_keys = NULL;
1214
1215         /* Fetch DS for the domain */
1216         if ((dspkt = ldns_resolver_query(res,
1217                                                            domain,
1218                                                            LDNS_RR_TYPE_DS,
1219                                                            LDNS_RR_CLASS_IN,
1220                                                            LDNS_RD))) {
1221
1222                 rrset = ldns_pkt_rr_list_by_type(dspkt,
1223                                                                    LDNS_RR_TYPE_DS,
1224                                                                    LDNS_SECTION_ANSWER);
1225                 sigs = ldns_pkt_rr_list_by_type(dspkt,
1226                                                                   LDNS_RR_TYPE_RRSIG,
1227                                                                   LDNS_SECTION_ANSWER);
1228
1229                 /* Validate sigs */
1230                 if ((status = ldns_verify(rrset, sigs, keys, NULL))
1231                     == LDNS_STATUS_OK) {
1232                         trusted_keys = ldns_rr_list_new();
1233                         for (key_i=0; key_i<ldns_rr_list_rr_count(rrset); key_i++) {
1234                                 ldns_rr_list_push_rr(trusted_keys,
1235                                                                  ldns_rr_clone(ldns_rr_list_rr(rrset,
1236                                                                                                                  key_i)
1237                                                                                         )
1238                                                                  );
1239                         }
1240                 }
1241
1242                 ldns_rr_list_deep_free(rrset);
1243                 ldns_rr_list_deep_free(sigs);
1244                 ldns_pkt_free(dspkt);
1245
1246         } else {
1247                 status = LDNS_STATUS_CRYPTO_NO_DS;
1248         }
1249
1250         return trusted_keys;
1251 }
1252
1253 ldns_status
1254 ldns_verify_trusted(ldns_resolver *res,
1255                                 ldns_rr_list *rrset,
1256                                 ldns_rr_list * rrsigs,
1257                                 ldns_rr_list * validating_keys)
1258 {
1259         uint16_t sig_i; uint16_t key_i;
1260         ldns_rr * cur_sig; ldns_rr * cur_key;
1261         ldns_rr_list * trusted_keys = NULL;
1262         ldns_status result = LDNS_STATUS_ERR;
1263
1264         if (!res || !rrset || !rrsigs) {
1265                 return LDNS_STATUS_ERR;
1266         }
1267
1268         if (ldns_rr_list_rr_count(rrset) < 1) {
1269                 return LDNS_STATUS_ERR;
1270         }
1271
1272         if (ldns_rr_list_rr_count(rrsigs) < 1) {
1273                 return LDNS_STATUS_CRYPTO_NO_RRSIG;
1274         }
1275   
1276         /* Look at each sig */
1277         for (sig_i=0; sig_i < ldns_rr_list_rr_count(rrsigs); sig_i++) {
1278
1279                 cur_sig = ldns_rr_list_rr(rrsigs, sig_i);
1280                 /* Get a valid signer key and validate the sig */
1281                 if ((trusted_keys = ldns_fetch_valid_domain_keys(
1282                                                     res,
1283                                                     ldns_rr_rrsig_signame(cur_sig),
1284                                                     ldns_resolver_dnssec_anchors(res),
1285                                                     &result))) {
1286
1287                         for (key_i = 0;
1288                                 key_i < ldns_rr_list_rr_count(trusted_keys);
1289                                 key_i++) {
1290                                 cur_key = ldns_rr_list_rr(trusted_keys, key_i);
1291
1292                                 if ((result = ldns_verify_rrsig(rrset,
1293                                                                                   cur_sig,
1294                                                                                   cur_key))
1295                                     == LDNS_STATUS_OK) {
1296                                         if (validating_keys) {
1297                                                 ldns_rr_list_push_rr(validating_keys,
1298                                                                                  ldns_rr_clone(cur_key));
1299                                         }
1300                                         ldns_rr_list_deep_free(trusted_keys);
1301                                         return LDNS_STATUS_OK;
1302                                 } else {
1303                                         ldns_rr_list_print(stdout, rrset);
1304                                         ldns_rr_print(stdout, cur_sig);
1305                                         ldns_rr_print(stdout, cur_key);
1306                 
1307                                 }
1308                         }
1309                 }
1310         }
1311
1312         ldns_rr_list_deep_free(trusted_keys);
1313         return result;
1314 }
1315
1316 ldns_status
1317 ldns_dnssec_verify_denial(ldns_rr *rr,
1318                           ldns_rr_list *nsecs,
1319                           ldns_rr_list *rrsigs)
1320 {
1321         ldns_rdf *rr_name;
1322         ldns_rdf *wildcard_name;
1323         ldns_rdf *chopped_dname;
1324         ldns_rr *cur_nsec;
1325         size_t i;
1326         ldns_status result;
1327         /* needed for wildcard check on exact match */
1328         ldns_rr *rrsig;
1329         bool name_covered = false;
1330         bool type_covered = false;
1331         bool wildcard_covered = false;
1332         bool wildcard_type_covered = false;
1333
1334         wildcard_name = ldns_dname_new_frm_str("*");
1335         rr_name = ldns_rr_owner(rr);
1336         chopped_dname = ldns_dname_left_chop(rr_name);
1337         result = ldns_dname_cat(wildcard_name, chopped_dname);
1338         if (result != LDNS_STATUS_OK) {
1339                 return result;
1340         }
1341         
1342         ldns_rdf_deep_free(chopped_dname);
1343         
1344         for  (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1345                 cur_nsec = ldns_rr_list_rr(nsecs, i);
1346                 if (ldns_dname_compare(rr_name, ldns_rr_owner(cur_nsec)) == 0) {
1347                         /* see section 5.4 of RFC4035, if the label count of the NSEC's
1348                            RRSIG is equal, then it is proven that wildcard expansion 
1349                            could not have been used to match the request */
1350                         rrsig = ldns_dnssec_get_rrsig_for_name_and_type(
1351                                           ldns_rr_owner(cur_nsec),
1352                                           ldns_rr_get_type(cur_nsec),
1353                                           rrsigs);
1354                         if (rrsig && ldns_rdf2native_int8(ldns_rr_rrsig_labels(rrsig))
1355                             == ldns_dname_label_count(rr_name)) {
1356                                 wildcard_covered = true;
1357                         }
1358                         
1359                         if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
1360                                                                            ldns_rr_get_type(rr))) {
1361                                 type_covered = true;
1362                         }
1363                 }
1364                 if (ldns_nsec_covers_name(cur_nsec, rr_name)) {
1365                         name_covered = true;
1366                 }
1367                 
1368                 if (ldns_dname_compare(wildcard_name,
1369                                                    ldns_rr_owner(cur_nsec)) == 0) {
1370                         if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
1371                                                                            ldns_rr_get_type(rr))) {
1372                                 wildcard_type_covered = true;
1373                         }
1374                 }
1375                 
1376                 if (ldns_nsec_covers_name(cur_nsec, wildcard_name)) {
1377                         wildcard_covered = true;
1378                 }
1379                 
1380         }
1381         
1382         ldns_rdf_deep_free(wildcard_name);
1383         
1384         if (type_covered || !name_covered) {
1385                 return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1386         }
1387         
1388         if (wildcard_type_covered || !wildcard_covered) {
1389                 return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
1390         }
1391
1392         return LDNS_STATUS_OK;
1393 }
1394
1395 #ifdef HAVE_SSL
1396 ldns_status
1397 ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
1398                                                   ldns_rr_list *nsecs,
1399                                                   ldns_rr_list *rrsigs,
1400                                                   ldns_pkt_rcode packet_rcode,
1401                                                   ldns_rr_type packet_qtype,
1402                                                   bool packet_nodata)
1403 {
1404         ldns_rdf *closest_encloser;
1405         ldns_rdf *wildcard;
1406         ldns_rdf *hashed_wildcard_name;
1407         bool wildcard_covered = false;
1408         ldns_rdf *zone_name;
1409         ldns_rdf *hashed_name;
1410         size_t i;
1411         ldns_status result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1412
1413         rrsigs = rrsigs;
1414
1415         zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
1416
1417         /* section 8.4 */
1418         if (packet_rcode == LDNS_RCODE_NXDOMAIN) {
1419                 closest_encloser = ldns_dnssec_nsec3_closest_encloser(
1420                                                    ldns_rr_owner(rr),
1421                                                    ldns_rr_get_type(rr),
1422                                                    nsecs);
1423
1424                 wildcard = ldns_dname_new_frm_str("*");
1425                 (void) ldns_dname_cat(wildcard, closest_encloser);
1426
1427                 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1428                         hashed_wildcard_name =
1429                                 ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
1430                                                                                  wildcard
1431                                                                                  );
1432                         (void) ldns_dname_cat(hashed_wildcard_name, zone_name);
1433
1434                         if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
1435                                                                  hashed_wildcard_name)) {
1436                                 wildcard_covered = true;
1437                         }
1438                         ldns_rdf_deep_free(hashed_wildcard_name);
1439                 }
1440
1441                 ldns_rdf_deep_free(closest_encloser);
1442                 ldns_rdf_deep_free(wildcard);
1443
1444                 if (!wildcard_covered) {
1445                         result = LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
1446                 } else if (closest_encloser && wildcard_covered) {
1447                         result = LDNS_STATUS_OK;
1448                 } else {
1449                         result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1450                 }
1451         } else if (packet_nodata && packet_qtype != LDNS_RR_TYPE_DS) {
1452                 /* section 8.5 */
1453                 hashed_name = ldns_nsec3_hash_name_frm_nsec3(
1454                                    ldns_rr_list_rr(nsecs, 0),
1455                                    ldns_rr_owner(rr));
1456                 (void) ldns_dname_cat(hashed_name, zone_name);
1457                 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1458                         if (ldns_dname_compare(hashed_name,
1459                                  ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
1460                             == 0) {
1461                                 if (!ldns_nsec_bitmap_covers_type(
1462                                             ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1463                                             packet_qtype)
1464                                     && 
1465                                     !ldns_nsec_bitmap_covers_type(
1466                                             ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1467                                             LDNS_RR_TYPE_CNAME)) {
1468                                         result = LDNS_STATUS_OK;
1469                                         goto done;
1470                                 }
1471                         }
1472                 }
1473                 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1474         } else if (packet_nodata && packet_qtype == LDNS_RR_TYPE_DS) {
1475                 /* section 8.6 */
1476                 /* note: up to XXX this is the same as for 8.5 */
1477                 hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs,
1478                                                                                                                  0),
1479                                                                                         ldns_rr_owner(rr)
1480                                                                                         );
1481                 (void) ldns_dname_cat(hashed_name, zone_name);
1482                 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1483                         if (ldns_dname_compare(hashed_name,
1484                                                            ldns_rr_owner(ldns_rr_list_rr(nsecs,
1485                                                                                                            i)))
1486                             == 0) {
1487                                 if (!ldns_nsec_bitmap_covers_type(
1488                                             ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1489                                             LDNS_RR_TYPE_DS)
1490                                     && 
1491                                     !ldns_nsec_bitmap_covers_type(
1492                                             ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1493                                             LDNS_RR_TYPE_CNAME)) {
1494                                         result = LDNS_STATUS_OK;
1495                                         goto done;
1496                                 }
1497                         }
1498                 }
1499
1500                 /* XXX see note above */
1501                 closest_encloser =
1502                         ldns_dnssec_nsec3_closest_encloser(ldns_rr_owner(rr),
1503                                                                                 ldns_rr_get_type(rr),
1504                                                                                 nsecs);
1505
1506                 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1507         }
1508
1509  done:
1510         ldns_rdf_deep_free(zone_name);
1511         return result;
1512 }
1513 #endif /* HAVE_SSL */
1514
1515 #ifdef USE_GOST
1516 EVP_PKEY*
1517 ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
1518 {
1519         /* prefix header for X509 encoding */
1520         uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 
1521                 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85, 
1522                 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 
1523                 0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
1524         unsigned char encoded[37+64];
1525         const unsigned char* pp;
1526         if(keylen != 66) {
1527                 /* key wrong size */
1528                 return NULL;
1529         }
1530         if(key[0] != 0 || key[1] != 0) {
1531                 /* unsupported GOST algo or digest paramset */
1532                 return NULL;
1533         }
1534
1535         /* create evp_key */
1536         memmove(encoded, asn, 37);
1537         memmove(encoded+37, key+2, 64);
1538         pp = (unsigned char*)&encoded[0];
1539
1540         return d2i_PUBKEY(NULL, &pp, sizeof(encoded));
1541 }
1542
1543 static ldns_status
1544 ldns_verify_rrsig_gost_raw(unsigned char* sig, size_t siglen, 
1545         ldns_buffer* rrset, unsigned char* key, size_t keylen)
1546 {
1547         EVP_PKEY *evp_key;
1548         ldns_status result;
1549
1550         (void) ldns_key_EVP_load_gost_id();
1551         evp_key = ldns_gost2pkey_raw(key, keylen);
1552         if(!evp_key) {
1553                 /* could not convert key */
1554                 return LDNS_STATUS_CRYPTO_BOGUS;
1555         }
1556
1557         /* verify signature */
1558         result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, 
1559                 evp_key, EVP_get_digestbyname("md_gost94"));
1560         EVP_PKEY_free(evp_key);
1561
1562         return result;
1563 }
1564 #endif
1565
1566
1567 ldns_status
1568 ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf, 
1569                                          ldns_buffer *key_buf, uint8_t algo)
1570 {
1571         return ldns_verify_rrsig_buffers_raw(
1572                          (unsigned char*)ldns_buffer_begin(rawsig_buf),
1573                          ldns_buffer_position(rawsig_buf),
1574                          verify_buf,
1575                          (unsigned char*)ldns_buffer_begin(key_buf), 
1576                          ldns_buffer_position(key_buf), algo);
1577 }
1578
1579 ldns_status
1580 ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
1581                                                 ldns_buffer *verify_buf, unsigned char* key, size_t keylen, 
1582                                                 uint8_t algo)
1583 {
1584         /* check for right key */
1585         switch(algo) {
1586         case LDNS_DSA:
1587         case LDNS_DSA_NSEC3:
1588                 return ldns_verify_rrsig_dsa_raw(sig,
1589                                                                    siglen,
1590                                                                    verify_buf,
1591                                                                    key,
1592                                                                    keylen);
1593                 break;
1594         case LDNS_RSASHA1:
1595         case LDNS_RSASHA1_NSEC3:
1596                 return ldns_verify_rrsig_rsasha1_raw(sig,
1597                                                                           siglen,
1598                                                                           verify_buf,
1599                                                                           key,
1600                                                                           keylen);
1601                 break;
1602 #ifdef USE_SHA2
1603         case LDNS_RSASHA256:
1604                 return ldns_verify_rrsig_rsasha256_raw(sig,
1605                                                                             siglen,
1606                                                                             verify_buf,
1607                                                                             key,
1608                                                                             keylen);
1609                 break;
1610         case LDNS_RSASHA512:
1611                 return ldns_verify_rrsig_rsasha512_raw(sig,
1612                                                                             siglen,
1613                                                                             verify_buf,
1614                                                                             key,
1615                                                                             keylen);
1616                 break;
1617 #endif
1618 #ifdef USE_GOST
1619         case LDNS_GOST:
1620                 return ldns_verify_rrsig_gost_raw(sig, siglen, verify_buf,
1621                         key, keylen);
1622                 break;
1623 #endif
1624         case LDNS_RSAMD5:
1625                 return ldns_verify_rrsig_rsamd5_raw(sig,
1626                                                                          siglen,
1627                                                                          verify_buf,
1628                                                                          key,
1629                                                                          keylen);
1630                 break;
1631         default:
1632                 /* do you know this alg?! */
1633                 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
1634         }
1635 }
1636
1637
1638 /**
1639  * Reset the ttl in the rrset with the orig_ttl from the sig 
1640  * and update owner name if it was wildcard 
1641  * Also canonicalizes the rrset.
1642  * @param rrset: rrset to modify
1643  * @param sig: signature to take TTL and wildcard values from
1644  */
1645 static void
1646 ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
1647 {
1648         uint32_t orig_ttl;
1649         uint16_t i;
1650         uint8_t label_count;
1651         ldns_rdf *wildcard_name;
1652         ldns_rdf *wildcard_chopped;
1653         ldns_rdf *wildcard_chopped_tmp;
1654
1655         orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
1656         label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
1657
1658         for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
1659                 if (label_count < 
1660                     ldns_dname_label_count(
1661                            ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
1662                         (void) ldns_str2rdf_dname(&wildcard_name, "*");
1663                         wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(
1664                                 ldns_rr_list_rr(rrset_clone, i)));
1665                         while (label_count < ldns_dname_label_count(wildcard_chopped)) {
1666                                 wildcard_chopped_tmp = ldns_dname_left_chop(
1667                                         wildcard_chopped);
1668                                 ldns_rdf_deep_free(wildcard_chopped);
1669                                 wildcard_chopped = wildcard_chopped_tmp;
1670                         }
1671                         (void) ldns_dname_cat(wildcard_name, wildcard_chopped);
1672                         ldns_rdf_deep_free(wildcard_chopped);
1673                         ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(
1674                                 rrset_clone, i)));
1675                         ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i), 
1676                                 wildcard_name);
1677                 }
1678                 ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl);
1679                 /* convert to lowercase */
1680                 ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
1681         }
1682 }
1683
1684 /**
1685  * Make raw signature buffer out of rrsig
1686  * @param rawsig_buf: raw signature buffer for result
1687  * @param rrsig: signature to convert
1688  * @return OK or more specific error.
1689  */
1690 static ldns_status
1691 ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
1692 {
1693         uint8_t sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
1694         /* check for known and implemented algo's now (otherwise 
1695          * the function could return a wrong error
1696          */
1697         /* create a buffer with signature rdata */
1698         /* for some algorithms we need other data than for others... */
1699         /* (the DSA API wants DER encoding for instance) */
1700
1701         switch(sig_algo) {
1702         case LDNS_RSAMD5:
1703         case LDNS_RSASHA1:
1704         case LDNS_RSASHA1_NSEC3:
1705 #ifdef USE_SHA2
1706         case LDNS_RSASHA256:
1707         case LDNS_RSASHA512:
1708 #endif
1709 #ifdef USE_GOST
1710         case LDNS_GOST:
1711 #endif
1712                 if (ldns_rdf2buffer_wire(rawsig_buf, 
1713                     ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
1714                         return LDNS_STATUS_MEM_ERR;
1715                 }
1716                 break;
1717         case LDNS_DSA:
1718         case LDNS_DSA_NSEC3:
1719                 /* EVP takes rfc2459 format, which is a tad longer than dns format */
1720                 if (ldns_convert_dsa_rrsig_rdf2asn1(rawsig_buf, 
1721                         ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
1722                         /*
1723                           if (ldns_rdf2buffer_wire(rawsig_buf,
1724                           ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
1725                         */
1726                         return LDNS_STATUS_MEM_ERR;
1727                 }
1728                 break;
1729         case LDNS_DH:
1730         case LDNS_ECC:
1731         case LDNS_INDIRECT:
1732                 return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
1733         default:
1734                 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
1735         }
1736         return LDNS_STATUS_OK;
1737 }
1738
1739 /**
1740  * Check RRSIG timestamps against the given 'now' time.
1741  * @param rrsig: signature to check.
1742  * @param now: the current time in seconds epoch.
1743  * @return status code LDNS_STATUS_OK if all is fine.
1744  */
1745 static ldns_status
1746 ldns_rrsig_check_timestamps(ldns_rr* rrsig, int32_t now)
1747 {
1748         int32_t inception, expiration;
1749         
1750         /* check the signature time stamps */
1751         inception = (int32_t)ldns_rdf2native_time_t(
1752                 ldns_rr_rrsig_inception(rrsig));
1753         expiration = (int32_t)ldns_rdf2native_time_t(
1754                 ldns_rr_rrsig_expiration(rrsig));
1755
1756         if (expiration - inception < 0) {
1757                 /* bad sig, expiration before inception?? Tsssg */
1758                 return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
1759         }
1760         if (now - inception < 0) {
1761                 /* bad sig, inception date has not yet come to pass */
1762                 return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
1763         }
1764         if (expiration - now < 0) {
1765                 /* bad sig, expiration date has passed */
1766                 return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
1767         }
1768         return LDNS_STATUS_OK;
1769 }
1770
1771 /**
1772  * Prepare for verification.
1773  * @param rawsig_buf: raw signature buffer made ready.
1774  * @param verify_buf: data for verification buffer made ready.
1775  * @param rrset_clone: made ready.
1776  * @param rrsig: signature to prepare for.
1777  * @return LDNS_STATUS_OK is all went well. Otherwise specific error.
1778  */
1779 static ldns_status
1780 ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 
1781         ldns_rr_list* rrset_clone, ldns_rr* rrsig)
1782 {
1783         ldns_status result;
1784
1785         /* canonicalize the sig */
1786         ldns_dname2canonical(ldns_rr_owner(rrsig));
1787         
1788         /* check if the typecovered is equal to the type checked */
1789         if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)) !=
1790             ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0)))
1791                 return LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR;
1792         
1793         /* create a buffer with b64 signature rdata */
1794         result = ldns_rrsig2rawsig_buffer(rawsig_buf, rrsig);
1795         if(result != LDNS_STATUS_OK)
1796                 return result;
1797
1798         /* use TTL from signature. Use wildcard names for wildcards */
1799         /* also canonicalizes rrset_clone */
1800         ldns_rrset_use_signature_ttl(rrset_clone, rrsig);
1801
1802         /* sort the rrset in canonical order  */
1803         ldns_rr_list_sort(rrset_clone);
1804
1805         /* put the signature rr (without the b64) to the verify_buf */
1806         if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK)
1807                 return LDNS_STATUS_MEM_ERR;
1808
1809         /* add the rrset in verify_buf */
1810         if(ldns_rr_list2buffer_wire(verify_buf, rrset_clone) 
1811                 != LDNS_STATUS_OK)
1812                 return LDNS_STATUS_MEM_ERR;
1813
1814         return LDNS_STATUS_OK;
1815 }
1816
1817 /**
1818  * Check if a key matches a signature.
1819  * Checks keytag, sigalgo and signature.
1820  * @param rawsig_buf: raw signature buffer for verify
1821  * @param verify_buf: raw data buffer for verify
1822  * @param rrsig: the rrsig
1823  * @param key: key to attempt.
1824  * @return LDNS_STATUS_OK if OK, else some specific error.
1825  */
1826 static ldns_status
1827 ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 
1828         ldns_rr* rrsig, ldns_rr* key)
1829 {
1830         uint8_t sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
1831
1832         /* before anything, check if the keytags match */
1833         if (ldns_calc_keytag(key)
1834             ==
1835             ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
1836             ) {
1837                 ldns_buffer* key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
1838                 ldns_status result = LDNS_STATUS_ERR;
1839
1840                 /* put the key-data in a buffer, that's the third rdf, with
1841                  * the base64 encoded key data */
1842                 if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3)) 
1843                         != LDNS_STATUS_OK) {
1844                         ldns_buffer_free(key_buf); 
1845                         /* returning is bad might screw up
1846                            good keys later in the list
1847                            what to do? */
1848                         return LDNS_STATUS_ERR;
1849                 }
1850
1851                 if (sig_algo == ldns_rdf2native_int8(ldns_rr_rdf(key, 2))) {
1852                         result = ldns_verify_rrsig_buffers(rawsig_buf, 
1853                                 verify_buf, key_buf, sig_algo);
1854                 } else {
1855                         /* No keys with the corresponding algorithm are found */
1856                         result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
1857                 }
1858
1859                 ldns_buffer_free(key_buf); 
1860                 return result;
1861         }
1862         else {
1863                 /* No keys with the corresponding keytag are found */
1864                 return LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
1865         }
1866 }
1867
1868 /* 
1869  * to verify:
1870  * - create the wire fmt of the b64 key rdata
1871  * - create the wire fmt of the sorted rrset
1872  * - create the wire fmt of the b64 sig rdata
1873  * - create the wire fmt of the sig without the b64 rdata
1874  * - cat the sig data (without b64 rdata) to the rrset
1875  * - verify the rrset+sig, with the b64 data and the b64 key data
1876  */
1877 ldns_status
1878 ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
1879                                          ldns_rr *rrsig,
1880                                          const ldns_rr_list *keys, 
1881                                          ldns_rr_list *good_keys)
1882 {
1883         ldns_status result;
1884         ldns_rr_list *valid = ldns_rr_list_new();
1885         if (!valid)
1886                 return LDNS_STATUS_MEM_ERR;
1887
1888         result = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, valid);
1889         if(result != LDNS_STATUS_OK) {
1890                 ldns_rr_list_free(valid); 
1891                 return result;
1892         }
1893
1894         /* check timestamps last; its OK except time */
1895         result = ldns_rrsig_check_timestamps(rrsig, (int32_t)time(NULL));
1896         if(result != LDNS_STATUS_OK) {
1897                 ldns_rr_list_free(valid); 
1898                 return result;
1899         }
1900
1901         ldns_rr_list_cat(good_keys, valid);
1902         ldns_rr_list_free(valid);
1903         return LDNS_STATUS_OK;
1904 }
1905
1906 ldns_status
1907 ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset,
1908                                          ldns_rr *rrsig,
1909                                          const ldns_rr_list *keys, 
1910                                          ldns_rr_list *good_keys)
1911 {
1912         ldns_buffer *rawsig_buf;
1913         ldns_buffer *verify_buf;
1914         uint16_t i;
1915         ldns_status result, status;
1916         ldns_rr_list *rrset_clone;
1917         ldns_rr_list *validkeys;
1918
1919         if (!rrset) {
1920                 return LDNS_STATUS_ERR;
1921         }
1922
1923         validkeys = ldns_rr_list_new();
1924         if (!validkeys) {
1925                 return LDNS_STATUS_MEM_ERR;
1926         }
1927         
1928         /* clone the rrset so that we can fiddle with it */
1929         rrset_clone = ldns_rr_list_clone(rrset);
1930
1931         /* create the buffers which will certainly hold the raw data */
1932         rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
1933         verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
1934
1935         result = ldns_prepare_for_verify(rawsig_buf, verify_buf, 
1936                 rrset_clone, rrsig);
1937         if(result != LDNS_STATUS_OK) {
1938                 ldns_buffer_free(verify_buf);
1939                 ldns_buffer_free(rawsig_buf);
1940                 ldns_rr_list_deep_free(rrset_clone);
1941                 ldns_rr_list_free(validkeys);
1942                 return result;
1943         }
1944         result = LDNS_STATUS_ERR;
1945
1946         for(i = 0; i < ldns_rr_list_rr_count(keys); i++) {
1947                 status = ldns_verify_test_sig_key(rawsig_buf, verify_buf, 
1948                         rrsig, ldns_rr_list_rr(keys, i));
1949                 if (status == LDNS_STATUS_OK) {
1950                         /* one of the keys has matched, don't break
1951                          * here, instead put the 'winning' key in
1952                          * the validkey list and return the list 
1953                          * later */
1954                         if (!ldns_rr_list_push_rr(validkeys, 
1955                                 ldns_rr_list_rr(keys,i))) {
1956                                 /* couldn't push the key?? */
1957                                 ldns_buffer_free(rawsig_buf);
1958                                 ldns_buffer_free(verify_buf);
1959                                 ldns_rr_list_deep_free(rrset_clone);
1960                                 ldns_rr_list_free(validkeys);
1961                                 return LDNS_STATUS_MEM_ERR;
1962                         }
1963                         /* reset no keytag match error */
1964                         result = LDNS_STATUS_ERR;
1965                 }
1966                 if (result == LDNS_STATUS_ERR) {
1967                         result = status;
1968                 }
1969         }
1970
1971         /* no longer needed */
1972         ldns_rr_list_deep_free(rrset_clone);
1973         ldns_buffer_free(rawsig_buf);
1974         ldns_buffer_free(verify_buf);
1975
1976         if (ldns_rr_list_rr_count(validkeys) == 0) {
1977                 /* no keys were added, return last error */
1978                 ldns_rr_list_free(validkeys); 
1979                 return result;
1980         }
1981
1982         /* do not check timestamps */
1983
1984         ldns_rr_list_cat(good_keys, validkeys);
1985         ldns_rr_list_free(validkeys);
1986         return LDNS_STATUS_OK;
1987 }
1988
1989 ldns_status
1990 ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
1991 {
1992         ldns_buffer *rawsig_buf;
1993         ldns_buffer *verify_buf;
1994         ldns_status result;
1995         ldns_rr_list *rrset_clone;
1996
1997         if (!rrset) {
1998                 return LDNS_STATUS_NO_DATA;
1999         }
2000         /* clone the rrset so that we can fiddle with it */
2001         rrset_clone = ldns_rr_list_clone(rrset);
2002         /* create the buffers which will certainly hold the raw data */
2003         rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2004         verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2005
2006         result = ldns_prepare_for_verify(rawsig_buf, verify_buf, 
2007                 rrset_clone, rrsig);
2008         if(result != LDNS_STATUS_OK) {
2009                 ldns_rr_list_deep_free(rrset_clone);
2010                 ldns_buffer_free(rawsig_buf);
2011                 ldns_buffer_free(verify_buf);
2012                 return result;
2013         }
2014         result = ldns_verify_test_sig_key(rawsig_buf, verify_buf, 
2015                 rrsig, key);
2016         /* no longer needed */
2017         ldns_rr_list_deep_free(rrset_clone);
2018         ldns_buffer_free(rawsig_buf);
2019         ldns_buffer_free(verify_buf);
2020
2021         /* check timestamp last, apart from time its OK */
2022         if(result == LDNS_STATUS_OK)
2023                 result = ldns_rrsig_check_timestamps(rrsig, 
2024                         (int32_t)time(NULL));
2025
2026         return result;
2027 }
2028
2029 ldns_status
2030 ldns_verify_rrsig_evp(ldns_buffer *sig,
2031                                   ldns_buffer *rrset,
2032                                   EVP_PKEY *key,
2033                                   const EVP_MD *digest_type)
2034 {
2035         return ldns_verify_rrsig_evp_raw(
2036                          (unsigned char*)ldns_buffer_begin(sig),
2037                          ldns_buffer_position(sig),
2038                          rrset,
2039                          key,
2040                          digest_type);
2041 }
2042
2043 ldns_status
2044 ldns_verify_rrsig_evp_raw(unsigned char *sig, size_t siglen, 
2045                                          ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
2046 {
2047         EVP_MD_CTX ctx;
2048         int res;
2049
2050         EVP_MD_CTX_init(&ctx);
2051         
2052         EVP_VerifyInit(&ctx, digest_type);
2053         EVP_VerifyUpdate(&ctx,
2054                                   ldns_buffer_begin(rrset),
2055                                   ldns_buffer_position(rrset));
2056         res = EVP_VerifyFinal(&ctx, sig, (unsigned int) siglen, key);
2057         
2058         EVP_MD_CTX_cleanup(&ctx);
2059         
2060         if (res == 1) {
2061                 return LDNS_STATUS_OK;
2062         } else if (res == 0) {
2063                 return LDNS_STATUS_CRYPTO_BOGUS;
2064         }
2065         /* TODO how to communicate internal SSL error?
2066            let caller use ssl's get_error() */
2067         return LDNS_STATUS_SSL_ERR;
2068 }
2069
2070 ldns_status
2071 ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2072 {
2073         return ldns_verify_rrsig_dsa_raw(
2074                          (unsigned char*) ldns_buffer_begin(sig),
2075                          ldns_buffer_position(sig),
2076                          rrset,
2077                          (unsigned char*) ldns_buffer_begin(key),
2078                          ldns_buffer_position(key));
2079 }
2080
2081 ldns_status
2082 ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2083 {
2084         return ldns_verify_rrsig_rsasha1_raw(
2085                          (unsigned char*)ldns_buffer_begin(sig),
2086                          ldns_buffer_position(sig),
2087                          rrset,
2088                          (unsigned char*) ldns_buffer_begin(key),
2089                          ldns_buffer_position(key));
2090 }
2091
2092 ldns_status
2093 ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2094 {
2095         return ldns_verify_rrsig_rsamd5_raw(
2096                          (unsigned char*)ldns_buffer_begin(sig),
2097                          ldns_buffer_position(sig),
2098                          rrset,
2099                          (unsigned char*) ldns_buffer_begin(key),
2100                          ldns_buffer_position(key));
2101 }
2102
2103 ldns_status
2104 ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
2105                                          ldns_buffer* rrset, unsigned char* key, size_t keylen)
2106 {
2107         EVP_PKEY *evp_key;
2108         ldns_status result;
2109
2110         evp_key = EVP_PKEY_new();
2111         EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen));
2112         result = ldns_verify_rrsig_evp_raw(sig,
2113                                                                 siglen,
2114                                                                 rrset,
2115                                                                 evp_key,
2116                                                                 EVP_dss1());
2117         EVP_PKEY_free(evp_key);
2118         return result;
2119
2120 }
2121
2122 ldns_status
2123 ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen,
2124                                                 ldns_buffer* rrset, unsigned char* key, size_t keylen)
2125 {
2126         EVP_PKEY *evp_key;
2127         ldns_status result;
2128
2129         evp_key = EVP_PKEY_new();
2130         EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
2131         result = ldns_verify_rrsig_evp_raw(sig,
2132                                                                 siglen,
2133                                                                 rrset,
2134                                                                 evp_key,
2135                                                                 EVP_sha1());
2136         EVP_PKEY_free(evp_key);
2137
2138         return result;
2139 }
2140
2141 ldns_status
2142 ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
2143                                                   size_t siglen,
2144                                                   ldns_buffer* rrset,
2145                                                   unsigned char* key,
2146                                                   size_t keylen)
2147 {
2148 #ifdef USE_SHA2
2149         EVP_PKEY *evp_key;
2150         ldns_status result;
2151
2152         evp_key = EVP_PKEY_new();
2153         EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
2154         result = ldns_verify_rrsig_evp_raw(sig,
2155                                                                 siglen,
2156                                                                 rrset,
2157                                                                 evp_key,
2158                                                                 EVP_sha256());
2159         EVP_PKEY_free(evp_key);
2160
2161         return result;
2162 #else
2163         /* touch these to prevent compiler warnings */
2164         (void) sig;
2165         (void) siglen;
2166         (void) rrset;
2167         (void) key;
2168         (void) keylen;
2169         return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2170 #endif
2171 }
2172
2173 ldns_status
2174 ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
2175                                                   size_t siglen,
2176                                                   ldns_buffer* rrset,
2177                                                   unsigned char* key,
2178                                                   size_t keylen)
2179 {
2180 #ifdef USE_SHA2
2181         EVP_PKEY *evp_key;
2182         ldns_status result;
2183
2184         evp_key = EVP_PKEY_new();
2185         EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
2186         result = ldns_verify_rrsig_evp_raw(sig,
2187                                                                 siglen,
2188                                                                 rrset,
2189                                                                 evp_key,
2190                                                                 EVP_sha512());
2191         EVP_PKEY_free(evp_key);
2192
2193         return result;
2194 #else
2195         /* touch these to prevent compiler warnings */
2196         (void) sig;
2197         (void) siglen;
2198         (void) rrset;
2199         (void) key;
2200         (void) keylen;
2201         return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2202 #endif
2203 }
2204
2205
2206 ldns_status
2207 ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
2208                                             size_t siglen,
2209                                             ldns_buffer* rrset,
2210                                             unsigned char* key,
2211                                             size_t keylen)
2212 {
2213         EVP_PKEY *evp_key;
2214         ldns_status result;
2215
2216         evp_key = EVP_PKEY_new();
2217         EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
2218         result = ldns_verify_rrsig_evp_raw(sig,
2219                                                                 siglen,
2220                                                                 rrset,
2221                                                                 evp_key,
2222                                                                 EVP_md5());
2223         EVP_PKEY_free(evp_key);
2224
2225         return result;
2226 }
2227
2228 #endif