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