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