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