File Coverage

src/ldns/dnssec_verify.c
Criterion Covered Total %
statement 133 1053 12.6
branch 55 590 9.3
condition n/a
subroutine n/a
pod n/a
total 188 1643 11.4


line stmt bran cond sub pod time code
1             #include
2              
3             #include
4              
5             #include
6             #include
7              
8             #ifdef HAVE_SSL
9             /* this entire file is rather useless when you don't have
10             * crypto...
11             */
12             #include
13             #include
14             #include
15             #include
16             #include
17              
18             ldns_dnssec_data_chain *
19 0           ldns_dnssec_data_chain_new(void)
20             {
21 0           ldns_dnssec_data_chain *nc = LDNS_CALLOC(ldns_dnssec_data_chain, 1);
22 0 0         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 0           return nc;
36             }
37              
38             void
39 0           ldns_dnssec_data_chain_free(ldns_dnssec_data_chain *chain)
40             {
41 0           LDNS_FREE(chain);
42 0           }
43              
44             void
45 0           ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain)
46             {
47 0           ldns_rr_list_deep_free(chain->rrset);
48 0           ldns_rr_list_deep_free(chain->signatures);
49 0 0         if (chain->parent) {
50 0           ldns_dnssec_data_chain_deep_free(chain->parent);
51             }
52 0           LDNS_FREE(chain);
53 0           }
54              
55             void
56 0           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 0 0         if (chain) {
62 0           ldns_dnssec_data_chain_print_fmt(out, fmt, chain->parent);
63 0 0         if (ldns_rr_list_rr_count(chain->rrset) > 0) {
64 0           rcode = ldns_lookup_by_id(ldns_rcodes,
65 0           (int) chain->packet_rcode);
66 0 0         if (rcode) {
67 0           fprintf(out, ";; rcode: %s\n", rcode->name);
68             }
69              
70 0           rr_descriptor = ldns_rr_descript(chain->packet_qtype);
71 0 0         if (rr_descriptor && rr_descriptor->_name) {
    0          
72 0           fprintf(out, ";; qtype: %s\n", rr_descriptor->_name);
73 0 0         } else if (chain->packet_qtype != 0) {
74 0           fprintf(out, "TYPE%u",
75 0           chain->packet_qtype);
76             }
77 0 0         if (chain->packet_nodata) {
78 0           fprintf(out, ";; NODATA response\n");
79             }
80 0           fprintf(out, "rrset:\n");
81 0           ldns_rr_list_print_fmt(out, fmt, chain->rrset);
82 0           fprintf(out, "sigs:\n");
83 0           ldns_rr_list_print_fmt(out, fmt, chain->signatures);
84 0           fprintf(out, "---\n");
85             } else {
86 0           fprintf(out, "\n");
87             }
88             }
89 0           }
90             void
91 0           ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain)
92             {
93 0           ldns_dnssec_data_chain_print_fmt(
94             out, ldns_output_format_default, chain);
95 0           }
96              
97              
98             static void
99 0           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 0 0         if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
    0          
109 0           new_chain->signatures = ldns_rr_list_clone(signatures);
110 0           new_chain->parent_type = 0;
111              
112 0           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 0 0         if (!keys) {
119 0           my_pkt = ldns_resolver_query(res,
120             key_name,
121             LDNS_RR_TYPE_DNSKEY,
122             c,
123             qflags);
124 0 0         if (my_pkt) {
125 0           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 0           new_chain->parent = ldns_dnssec_build_data_chain(res,
132             qflags,
133             keys,
134             my_pkt,
135             NULL);
136 0           new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
137 0           ldns_pkt_free(my_pkt);
138             }
139             } else {
140 0           new_chain->parent = ldns_dnssec_build_data_chain(res,
141             qflags,
142             keys,
143             pkt,
144             NULL);
145 0           new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
146             }
147 0           ldns_rr_list_deep_free(keys);
148             }
149 0           }
150              
151             static void
152 0           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 0           new_chain->parent_type = 1;
173              
174 0           my_pkt = ldns_resolver_query(res,
175             key_name,
176             LDNS_RR_TYPE_DS,
177             c,
178             qflags);
179 0 0         if (my_pkt) {
180 0           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 0 0         if (dss) {
186 0           new_chain->parent = ldns_dnssec_build_data_chain(res,
187             qflags,
188             dss,
189             my_pkt,
190             NULL);
191 0           new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
192 0           ldns_rr_list_deep_free(dss);
193             }
194 0           ldns_pkt_free(my_pkt);
195             }
196              
197 0           my_pkt = ldns_resolver_query(res,
198             key_name,
199             LDNS_RR_TYPE_DNSKEY,
200             c,
201             qflags);
202 0 0         if (my_pkt) {
203 0           signatures2 = ldns_pkt_rr_list_by_name_and_type(my_pkt,
204             key_name,
205             LDNS_RR_TYPE_RRSIG,
206             LDNS_SECTION_ANSWER);
207 0 0         if (signatures2) {
208 0 0         if (new_chain->signatures) {
209 0           printf("There were already sigs!\n");
210 0           ldns_rr_list_deep_free(new_chain->signatures);
211 0           printf("replacing the old sigs\n");
212             }
213 0           new_chain->signatures = signatures2;
214             }
215 0           ldns_pkt_free(my_pkt);
216             }
217 0           }
218              
219             static ldns_dnssec_data_chain *
220 0           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 0 0         if (orig_rr) {
233 0           possible_parent_name = ldns_rr_owner(orig_rr);
234 0 0         } else if (rrset && ldns_rr_list_rr_count(rrset) > 0) {
    0          
235 0           possible_parent_name = ldns_rr_owner(ldns_rr_list_rr(rrset, 0));
236             } else {
237             /* no information to go on, give up */
238 0           return new_chain;
239             }
240              
241 0           my_pkt = ldns_resolver_query(res,
242             possible_parent_name,
243             LDNS_RR_TYPE_DS,
244             LDNS_RR_CLASS_IN,
245             qflags);
246 0 0         if (!my_pkt) {
247 0           return new_chain;
248             }
249              
250 0 0         if (ldns_pkt_ancount(my_pkt) > 0) {
251             /* add error, no sigs but DS in parent */
252             /*ldns_pkt_print(stdout, my_pkt);*/
253 0           ldns_pkt_free(my_pkt);
254             } else {
255             /* are there signatures? */
256 0           new_chain->parent = ldns_dnssec_build_data_chain(res,
257             qflags,
258             NULL,
259             my_pkt,
260             NULL);
261              
262 0           new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
263            
264             }
265 0           return new_chain;
266             }
267              
268              
269             ldns_dnssec_data_chain *
270 0           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 0           ldns_rr_list *signatures = NULL;
277 0           ldns_rr_list *dss = NULL;
278            
279             ldns_rr_list *my_rrset;
280              
281             ldns_pkt *my_pkt;
282              
283 0           ldns_rdf *name = NULL, *key_name = NULL;
284 0           ldns_rr_type type = 0;
285 0           ldns_rr_class c = 0;
286              
287 0           bool other_rrset = false;
288              
289 0           ldns_dnssec_data_chain *new_chain = ldns_dnssec_data_chain_new();
290              
291             assert(pkt != NULL);
292              
293 0 0         if (!ldns_dnssec_pkt_has_rrsigs(pkt)) {
294             /* hmm. no dnssec data in the packet. go up to try and deny
295             * DS? */
296 0           return new_chain;
297             }
298              
299 0 0         if (orig_rr) {
300 0           new_chain->rrset = ldns_rr_list_new();
301 0           ldns_rr_list_push_rr(new_chain->rrset, orig_rr);
302 0           new_chain->parent = ldns_dnssec_build_data_chain(res,
303             qflags,
304             rrset,
305             pkt,
306             NULL);
307 0           new_chain->packet_rcode = ldns_pkt_get_rcode(pkt);
308 0           new_chain->packet_qtype = ldns_rr_get_type(orig_rr);
309 0 0         if (ldns_pkt_ancount(pkt) == 0) {
310 0           new_chain->packet_nodata = true;
311             }
312 0           return new_chain;
313             }
314            
315 0 0         if (!rrset || ldns_rr_list_rr_count(rrset) < 1) {
    0          
316             /* hmm, no data, do we have denial? only works if pkt was given,
317             otherwise caller has to do the check himself */
318 0           new_chain->packet_nodata = true;
319 0 0         if (pkt) {
320 0           my_rrset = ldns_pkt_rr_list_by_type(pkt,
321             LDNS_RR_TYPE_NSEC,
322             LDNS_SECTION_ANY_NOQUESTION
323             );
324 0 0         if (my_rrset) {
325 0 0         if (ldns_rr_list_rr_count(my_rrset) > 0) {
326 0           type = LDNS_RR_TYPE_NSEC;
327 0           other_rrset = true;
328             } else {
329 0           ldns_rr_list_deep_free(my_rrset);
330 0           my_rrset = NULL;
331             }
332             } else {
333             /* nothing, try nsec3 */
334 0           my_rrset = ldns_pkt_rr_list_by_type(pkt,
335             LDNS_RR_TYPE_NSEC3,
336             LDNS_SECTION_ANY_NOQUESTION);
337 0 0         if (my_rrset) {
338 0 0         if (ldns_rr_list_rr_count(my_rrset) > 0) {
339 0           type = LDNS_RR_TYPE_NSEC3;
340 0           other_rrset = true;
341             } else {
342 0           ldns_rr_list_deep_free(my_rrset);
343 0           my_rrset = NULL;
344             }
345             } else {
346             /* nothing, stop */
347             /* try parent zone? for denied insecure? */
348 0           return new_chain;
349             }
350             }
351             } else {
352 0           return new_chain;
353             }
354             } else {
355 0           my_rrset = (ldns_rr_list *) rrset;
356             }
357            
358 0 0         if (my_rrset && ldns_rr_list_rr_count(my_rrset) > 0) {
    0          
359 0           new_chain->rrset = ldns_rr_list_clone(my_rrset);
360 0           name = ldns_rr_owner(ldns_rr_list_rr(my_rrset, 0));
361 0           type = ldns_rr_get_type(ldns_rr_list_rr(my_rrset, 0));
362 0           c = ldns_rr_get_class(ldns_rr_list_rr(my_rrset, 0));
363             }
364            
365 0 0         if (other_rrset) {
366 0           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 0 0         if (type == LDNS_RR_TYPE_NSEC || type == LDNS_RR_TYPE_NSEC3) {
    0          
374             /* just throw in all signatures, the tree builder must sort
375             this out */
376 0 0         if (pkt) {
377 0           signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
378             } else {
379 0           my_pkt = ldns_resolver_query(res, name, type, c, qflags);
380 0 0         if (my_pkt) {
381 0           signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
382 0           ldns_pkt_free(my_pkt);
383             }
384             }
385             } else {
386 0 0         if (pkt) {
387 0           signatures =
388             ldns_dnssec_pkt_get_rrsigs_for_name_and_type(pkt,
389             name,
390             type);
391             }
392 0 0         if (!signatures) {
393 0           my_pkt = ldns_resolver_query(res, name, type, c, qflags);
394 0 0         if (my_pkt) {
395 0           signatures =
396             ldns_dnssec_pkt_get_rrsigs_for_name_and_type(my_pkt,
397             name,
398             type);
399 0           ldns_pkt_free(my_pkt);
400             }
401             }
402             }
403              
404 0 0         if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
    0          
405 0           key_name = ldns_rr_rdf(ldns_rr_list_rr(signatures, 0), 7);
406             }
407 0 0         if (!key_name) {
408 0 0         if (signatures) {
409 0           ldns_rr_list_deep_free(signatures);
410             }
411 0           return ldns_dnssec_build_data_chain_nokeyname(res,
412             qflags,
413             orig_rr,
414             rrset,
415             new_chain);
416             }
417 0 0         if (type != LDNS_RR_TYPE_DNSKEY) {
418 0           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 0           ldns_dnssec_build_data_chain_other(res,
428             qflags,
429             new_chain,
430             key_name,
431             c,
432             dss
433             );
434             }
435 0 0         if (signatures) {
436 0           ldns_rr_list_deep_free(signatures);
437             }
438 0           return new_chain;
439             }
440              
441             ldns_dnssec_trust_tree *
442 0           ldns_dnssec_trust_tree_new(void)
443             {
444 0           ldns_dnssec_trust_tree *new_tree = LDNS_XMALLOC(ldns_dnssec_trust_tree,
445             1);
446 0 0         if(!new_tree) return NULL;
447 0           new_tree->rr = NULL;
448 0           new_tree->rrset = NULL;
449 0           new_tree->parent_count = 0;
450              
451 0           return new_tree;
452             }
453              
454             void
455 0           ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree)
456             {
457             size_t i;
458 0 0         if (tree) {
459 0 0         for (i = 0; i < tree->parent_count; i++) {
460 0           ldns_dnssec_trust_tree_free(tree->parents[i]);
461             }
462             }
463 0           LDNS_FREE(tree);
464 0           }
465              
466             size_t
467 0           ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree)
468             {
469 0           size_t result = 0;
470 0           size_t parent = 0;
471             size_t i;
472            
473 0 0         for (i = 0; i < tree->parent_count; i++) {
474 0           parent = ldns_dnssec_trust_tree_depth(tree->parents[i]);
475 0 0         if (parent > result) {
476 0           result = parent;
477             }
478             }
479 0           return 1 + result;
480             }
481              
482             /* TODO ldns_ */
483             static void
484 0           print_tabs(FILE *out, size_t nr, uint8_t *map, size_t treedepth)
485             {
486             size_t i;
487 0 0         for (i = 0; i < nr; i++) {
488 0 0         if (i == nr - 1) {
489 0           fprintf(out, "|---");
490 0 0         } else if (map && i < treedepth && map[i] == 1) {
    0          
    0          
491 0           fprintf(out, "| ");
492             } else {
493 0           fprintf(out, " ");
494             }
495             }
496 0           }
497              
498             static void
499 0           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 0           bool mapset = false;
510            
511 0 0         if (!sibmap) {
512 0           treedepth = ldns_dnssec_trust_tree_depth(tree);
513 0           sibmap = LDNS_XMALLOC(uint8_t, treedepth);
514 0 0         if(!sibmap)
515 0           return; /* mem err */
516 0           memset(sibmap, 0, treedepth);
517 0           mapset = true;
518             }
519            
520 0 0         if (tree) {
521 0 0         if (tree->rr) {
522 0           print_tabs(out, tabs, sibmap, treedepth);
523 0           ldns_rdf_print(out, ldns_rr_owner(tree->rr));
524 0           descriptor = ldns_rr_descript(ldns_rr_get_type(tree->rr));
525              
526 0 0         if (descriptor->_name) {
527 0           fprintf(out, " (%s", descriptor->_name);
528             } else {
529 0           fprintf(out, " (TYPE%d",
530 0           ldns_rr_get_type(tree->rr));
531             }
532 0 0         if (tabs > 0) {
533 0 0         if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DNSKEY) {
534 0           fprintf(out, " keytag: %u",
535 0           (unsigned int) ldns_calc_keytag(tree->rr));
536 0           fprintf(out, " alg: ");
537 0           ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
538 0           fprintf(out, " flags: ");
539 0           ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
540 0 0         } else if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DS) {
541 0           fprintf(out, " keytag: ");
542 0           ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
543 0           fprintf(out, " digest type: ");
544 0           ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
545             }
546 0 0         if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NSEC) {
547 0           fprintf(out, " ");
548 0           ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
549 0           fprintf(out, " ");
550 0           ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 1));
551             }
552             }
553            
554 0           fprintf(out, ")\n");
555 0 0         for (i = 0; i < tree->parent_count; i++) {
556 0 0         if (tree->parent_count > 1 && i < tree->parent_count - 1) {
    0          
557 0           sibmap[tabs] = 1;
558             } else {
559 0           sibmap[tabs] = 0;
560             }
561             /* only print errors */
562 0 0         if (ldns_rr_get_type(tree->parents[i]->rr) ==
563 0 0         LDNS_RR_TYPE_NSEC ||
564 0           ldns_rr_get_type(tree->parents[i]->rr) ==
565             LDNS_RR_TYPE_NSEC3) {
566 0 0         if (tree->parent_status[i] == LDNS_STATUS_OK) {
567 0           print_tabs(out, tabs + 1, sibmap, treedepth);
568 0           if (tabs == 0 &&
569 0 0         ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS &&
570 0           ldns_rr_rd_count(tree->rr) > 0) {
571 0           fprintf(out, "Existence of DS is denied by:\n");
572             } else {
573 0           fprintf(out, "Existence is denied by:\n");
574             }
575             } else {
576             /* NS records aren't signed */
577 0 0         if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS) {
578 0           fprintf(out, "Existence of DS is denied by:\n");
579             } else {
580 0           print_tabs(out, tabs + 1, sibmap, treedepth);
581 0           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 0 0         if (tree->parent_status[i] != LDNS_STATUS_OK) {
589 0           print_tabs(out, tabs + 1, sibmap, treedepth);
590 0           fprintf(out,
591             "%s:\n",
592             ldns_get_errorstr_by_id(
593             tree->parent_status[i]));
594 0 0         if (tree->parent_status[i]
595             == LDNS_STATUS_SSL_ERR) {
596 0           printf("; SSL Error: ");
597 0           ERR_load_crypto_strings();
598 0           ERR_print_errors_fp(stdout);
599 0           printf("\n");
600             }
601 0           ldns_rr_print_fmt(out, fmt,
602             tree->
603 0           parent_signature[i]);
604 0           printf("For RRset:\n");
605 0           ldns_rr_list_print_fmt(out, fmt,
606 0           tree->rrset);
607 0           printf("With key:\n");
608 0           ldns_rr_print_fmt(out, fmt,
609 0           tree->parents[i]->rr);
610             }
611 0           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 0           print_tabs(out, tabs, sibmap, treedepth);
620 0           fprintf(out, "\n");
621             }
622             } else {
623 0           fprintf(out, "\n");
624             }
625            
626 0 0         if (mapset) {
627 0           LDNS_FREE(sibmap);
628             }
629             }
630              
631             void
632 0           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 0           ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
638             tree, tabs, extended, NULL, 0);
639 0           }
640              
641             void
642 0           ldns_dnssec_trust_tree_print(FILE *out,
643             ldns_dnssec_trust_tree *tree,
644             size_t tabs,
645             bool extended)
646             {
647 0           ldns_dnssec_trust_tree_print_fmt(out, ldns_output_format_default,
648             tree, tabs, extended);
649 0           }
650              
651              
652             ldns_status
653 0           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 0 0         if (tree
659 0 0         && parent
660 0 0         && 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 0           tree->parents[tree->parent_count] =
668             (ldns_dnssec_trust_tree *) parent;
669 0           tree->parent_status[tree->parent_count] = parent_status;
670 0           tree->parent_signature[tree->parent_count] = (ldns_rr *) signature;
671 0           tree->parent_count++;
672 0           return LDNS_STATUS_OK;
673             } else {
674 0           return LDNS_STATUS_ERR;
675             }
676             }
677              
678             /* if rr is null, take the first from the rrset */
679             ldns_dnssec_trust_tree *
680 0           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 0           ldns_rr *cur_rr = NULL;
689             ldns_rr *cur_sig_rr;
690             size_t i, j;
691              
692 0           ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new();
693 0 0         if(!new_tree)
694 0           return NULL;
695            
696 0 0         if (data_chain && data_chain->rrset) {
    0          
697 0           cur_rrset = data_chain->rrset;
698            
699 0           cur_sigs = data_chain->signatures;
700              
701 0 0         if (rr) {
702 0           cur_rr = rr;
703             }
704              
705 0 0         if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) {
    0          
706 0           cur_rr = ldns_rr_list_rr(cur_rrset, 0);
707             }
708              
709 0 0         if (cur_rr) {
710 0           new_tree->rr = cur_rr;
711 0           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 0 0         if (cur_sigs) {
721 0 0         for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) {
722             /* find the appropriate key in the parent list */
723 0           cur_sig_rr = ldns_rr_list_rr(cur_sigs, i);
724              
725 0 0         if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) {
726 0 0         if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
727 0           ldns_rr_owner(cur_rr)))
728             {
729             /* find first that does match */
730              
731 0 0         for (j = 0;
732 0 0         j < ldns_rr_list_rr_count(cur_rrset) &&
733 0           ldns_dname_compare(ldns_rr_owner(cur_sig_rr),ldns_rr_owner(cur_rr)) != 0;
734 0           j++) {
735 0           cur_rr = ldns_rr_list_rr(cur_rrset, j);
736            
737             }
738 0 0         if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
739 0           ldns_rr_owner(cur_rr)))
740             {
741 0           break;
742             }
743             }
744            
745             }
746             /* option 1 */
747 0 0         if (data_chain->parent) {
748 0           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 0           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 0           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 0           ldns_dnssec_derive_trust_tree_no_sig_time(
772             new_tree, data_chain, check_time);
773             }
774             }
775             }
776              
777 0           return new_tree;
778             }
779              
780             ldns_dnssec_trust_tree *
781 0           ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr)
782             {
783 0           return ldns_dnssec_derive_trust_tree_time(data_chain, rr, ldns_time(NULL));
784             }
785              
786             void
787 0           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 0           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 0           ldns_rr_list *tmp_rrset = NULL;
799             ldns_status cur_status;
800              
801 0           cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
802            
803 0 0         for (j = 0; j < ldns_rr_list_rr_count(data_chain->parent->rrset); j++) {
804 0           cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
805 0 0         if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
806 0 0         if (ldns_calc_keytag(cur_parent_rr) == cur_keytag) {
807              
808             /* TODO: check wildcard nsec too */
809 0 0         if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
    0          
810 0           tmp_rrset = cur_rrset;
811 0 0         if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
812 0 0         == LDNS_RR_TYPE_NSEC ||
813 0           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 0           ldns_rr_list_sort(cur_rrset);
818             assert(tmp_rrset == cur_rrset);
819 0           tmp_rrset = ldns_rr_list_pop_rrset(cur_rrset);
820            
821             /* with nsecs, this might be the wrong one */
822 0           while (tmp_rrset &&
823 0 0         ldns_rr_list_rr_count(cur_rrset) > 0 &&
824 0           ldns_dname_compare(
825 0           ldns_rr_owner(ldns_rr_list_rr(
826             tmp_rrset, 0)),
827 0           ldns_rr_owner(cur_sig_rr)) != 0) {
828 0           ldns_rr_list_deep_free(tmp_rrset);
829 0           tmp_rrset =
830             ldns_rr_list_pop_rrset(cur_rrset);
831             }
832             }
833 0           cur_status = ldns_verify_rrsig_time(
834             tmp_rrset,
835             cur_sig_rr,
836             cur_parent_rr,
837             check_time);
838 0 0         if (tmp_rrset && tmp_rrset != cur_rrset
    0          
839             ) {
840 0           ldns_rr_list_deep_free(
841             tmp_rrset);
842 0           tmp_rrset = NULL;
843             }
844             /* avoid dupes */
845 0 0         for (i = 0; i < new_tree->parent_count; i++) {
846 0 0         if (cur_parent_rr == new_tree->parents[i]->rr) {
847 0           goto done;
848             }
849             }
850              
851 0           cur_parent_tree =
852 0           ldns_dnssec_derive_trust_tree_time(
853             data_chain->parent,
854             cur_parent_rr,
855             check_time);
856 0           (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 0           ldns_rr_list_deep_free(cur_rrset);
866 0           }
867              
868             void
869 0           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 0           ldns_dnssec_derive_trust_tree_normal_rrset_time(
874             new_tree, data_chain, cur_sig_rr, ldns_time(NULL));
875 0           }
876              
877             void
878 0           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 0           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 0           cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
893              
894 0 0         for (j = 0; j < ldns_rr_list_rr_count(cur_rrset); j++) {
895 0           cur_parent_rr = ldns_rr_list_rr(cur_rrset, j);
896 0           if (cur_parent_rr != cur_rr &&
897 0           ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
898 0 0         if (ldns_calc_keytag(cur_parent_rr) == cur_keytag
899             ) {
900 0           cur_parent_tree = ldns_dnssec_trust_tree_new();
901 0           cur_parent_tree->rr = cur_parent_rr;
902 0           cur_parent_tree->rrset = cur_rrset;
903 0           cur_status = ldns_verify_rrsig_time(
904             cur_rrset, cur_sig_rr,
905             cur_parent_rr, check_time);
906 0           (void) ldns_dnssec_trust_tree_add_parent(new_tree,
907             cur_parent_tree, cur_sig_rr, cur_status);
908             }
909             }
910             }
911 0           }
912              
913             void
914 0           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 0           ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
920             new_tree, data_chain, cur_rr, cur_sig_rr, ldns_time(NULL));
921 0           }
922              
923             void
924 0           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 0           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 0 0         if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_DNSKEY &&
    0          
937 0 0         data_chain->parent &&
938 0           data_chain->parent->rrset
939             ) {
940 0 0         for (j = 0;
941 0           j < ldns_rr_list_rr_count(data_chain->parent->rrset);
942 0           j++) {
943 0           cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
944 0 0         if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DS) {
945 0 0         for (h = 0; h < ldns_rr_list_rr_count(cur_rrset); h++) {
946 0           cur_rr = ldns_rr_list_rr(cur_rrset, h);
947 0 0         if (ldns_rr_compare_ds(cur_rr, cur_parent_rr)) {
948 0           cur_parent_tree =
949 0           ldns_dnssec_derive_trust_tree_time(
950             data_chain->parent,
951             cur_parent_rr,
952             check_time);
953 0           (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 0           }
966              
967             void
968 0           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 0           ldns_dnssec_derive_trust_tree_ds_rrset_time(
973             new_tree, data_chain, cur_rr, ldns_time(NULL));
974 0           }
975              
976             void
977 0           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 0 0         if (data_chain->parent && data_chain->parent->rrset) {
    0          
989 0           cur_rrset = data_chain->parent->rrset;
990             /* nsec? */
991 0 0         if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
    0          
992 0 0         if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
993             LDNS_RR_TYPE_NSEC3) {
994 0           result = ldns_dnssec_verify_denial_nsec3(
995             new_tree->rr,
996             cur_rrset,
997 0           data_chain->parent->signatures,
998             data_chain->packet_rcode,
999             data_chain->packet_qtype,
1000 0           data_chain->packet_nodata);
1001 0 0         } else if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
1002             LDNS_RR_TYPE_NSEC) {
1003 0           result = ldns_dnssec_verify_denial(
1004             new_tree->rr,
1005             cur_rrset,
1006 0           data_chain->parent->signatures);
1007             } else {
1008             /* unsigned zone, unsigned parent */
1009 0           result = LDNS_STATUS_OK;
1010             }
1011             } else {
1012 0           result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1013             }
1014 0 0         for (i = 0; i < ldns_rr_list_rr_count(cur_rrset); i++) {
1015 0           cur_parent_rr = ldns_rr_list_rr(cur_rrset, i);
1016 0           cur_parent_tree =
1017 0           ldns_dnssec_derive_trust_tree_time(
1018             data_chain->parent,
1019             cur_parent_rr,
1020             check_time);
1021 0           (void) ldns_dnssec_trust_tree_add_parent(new_tree,
1022             cur_parent_tree, NULL, result);
1023             }
1024             }
1025 0           }
1026              
1027             void
1028 0           ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree *new_tree,
1029             ldns_dnssec_data_chain *data_chain)
1030             {
1031 0           ldns_dnssec_derive_trust_tree_no_sig_time(
1032             new_tree, data_chain, ldns_time(NULL));
1033 0           }
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 0           ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree,
1042             ldns_rr_list *trusted_keys)
1043             {
1044             size_t i;
1045 0           ldns_status result = LDNS_STATUS_CRYPTO_NO_DNSKEY;
1046             bool equal;
1047             ldns_status parent_result;
1048            
1049 0 0         if (tree && trusted_keys && ldns_rr_list_rr_count(trusted_keys) > 0)
    0          
    0          
1050 0 0         { if (tree->rr) {
1051 0 0         for (i = 0; i < ldns_rr_list_rr_count(trusted_keys); i++) {
1052 0           equal = ldns_rr_compare_ds(
1053 0           tree->rr,
1054 0           ldns_rr_list_rr(trusted_keys, i));
1055 0 0         if (equal) {
1056 0           result = LDNS_STATUS_OK;
1057 0           return result;
1058             }
1059             }
1060             }
1061 0 0         for (i = 0; i < tree->parent_count; i++) {
1062 0           parent_result =
1063 0           ldns_dnssec_trust_tree_contains_keys(tree->parents[i],
1064             trusted_keys);
1065 0 0         if (parent_result != LDNS_STATUS_CRYPTO_NO_DNSKEY) {
1066 0 0         if (tree->parent_status[i] != LDNS_STATUS_OK) {
1067 0           result = tree->parent_status[i];
1068             } else {
1069 0           if (tree->rr &&
1070 0           ldns_rr_get_type(tree->rr)
1071 0 0         == LDNS_RR_TYPE_NSEC &&
1072             parent_result == LDNS_STATUS_OK
1073             ) {
1074 0           result =
1075             LDNS_STATUS_DNSSEC_EXISTENCE_DENIED;
1076             } else {
1077 0           result = parent_result;
1078             }
1079             }
1080             }
1081             }
1082             } else {
1083 0           result = LDNS_STATUS_ERR;
1084             }
1085            
1086 0           return result;
1087             }
1088              
1089             ldns_status
1090 5           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 5           ldns_status verify_result = LDNS_STATUS_ERR;
1100              
1101 5 50         if (!rrset || !rrsig || !keys) {
    50          
    50          
1102 0           return LDNS_STATUS_ERR;
1103             }
1104              
1105 5 50         if (ldns_rr_list_rr_count(rrset) < 1) {
1106 0           return LDNS_STATUS_ERR;
1107             }
1108              
1109 5 50         if (ldns_rr_list_rr_count(rrsig) < 1) {
1110 0           return LDNS_STATUS_CRYPTO_NO_RRSIG;
1111             }
1112            
1113 5 50         if (ldns_rr_list_rr_count(keys) < 1) {
1114 0           verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1115             } else {
1116 10 100         for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1117 5           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 5 100         if(s == LDNS_STATUS_OK) {
1122 1           verify_result = LDNS_STATUS_OK;
1123 4 50         } else if(verify_result == LDNS_STATUS_ERR)
1124 4           verify_result = s;
1125 0 0         else if(s != LDNS_STATUS_ERR && verify_result ==
    0          
1126             LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY)
1127 0           verify_result = s;
1128             }
1129             }
1130 5           return verify_result;
1131             }
1132              
1133             ldns_status
1134 0           ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys,
1135             ldns_rr_list *good_keys)
1136             {
1137 0           return ldns_verify_time(rrset, rrsig, keys, ldns_time(NULL), good_keys);
1138             }
1139              
1140             ldns_status
1141 0           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 0           ldns_status verify_result = LDNS_STATUS_ERR;
1146              
1147 0 0         if (!rrset || !rrsig || !keys) {
    0          
    0          
1148 0           return LDNS_STATUS_ERR;
1149             }
1150              
1151 0 0         if (ldns_rr_list_rr_count(rrset) < 1) {
1152 0           return LDNS_STATUS_ERR;
1153             }
1154              
1155 0 0         if (ldns_rr_list_rr_count(rrsig) < 1) {
1156 0           return LDNS_STATUS_CRYPTO_NO_RRSIG;
1157             }
1158              
1159 0 0         if (ldns_rr_list_rr_count(keys) < 1) {
1160 0           verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1161             } else {
1162 0 0         for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1163 0           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 0 0         if (s == LDNS_STATUS_OK) {
1168 0           verify_result = LDNS_STATUS_OK;
1169 0 0         } else if (verify_result == LDNS_STATUS_ERR) {
1170 0           verify_result = s;
1171 0 0         } else if (s != LDNS_STATUS_ERR && verify_result ==
    0          
1172             LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
1173 0           verify_result = s;
1174             }
1175             }
1176             }
1177 0           return verify_result;
1178             }
1179              
1180             ldns_rr_list *
1181 0           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 0           ldns_rr_list * trusted_keys = NULL;
1188 0           ldns_rr_list * ds_keys = NULL;
1189             ldns_rdf * prev_parent_domain;
1190             ldns_rdf * parent_domain;
1191 0           ldns_rr_list * parent_keys = NULL;
1192              
1193 0 0         if (res && domain && keys) {
    0          
    0          
1194              
1195 0 0         if ((trusted_keys = ldns_validate_domain_dnskey_time(res,
1196             domain, keys, check_time))) {
1197 0           *status = LDNS_STATUS_OK;
1198             } else {
1199             /* No trusted keys in this domain, we'll have to find some in the parent domain */
1200 0           *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1201              
1202 0           parent_domain = ldns_dname_left_chop(domain);
1203 0           while (parent_domain && /* Fail if we are at the root*/
1204 0           ldns_rdf_size(parent_domain) > 0) {
1205            
1206 0 0         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 0 0         if ((ds_keys =
1214             ldns_validate_domain_ds_time(res,
1215             domain,
1216             parent_keys,
1217             check_time))) {
1218 0           trusted_keys =
1219             ldns_fetch_valid_domain_keys_time(
1220             res,
1221             domain,
1222             ds_keys,
1223             check_time,
1224             status);
1225 0           ldns_rr_list_deep_free(ds_keys);
1226             } else {
1227             /* No valid DS at the parent -- fail */
1228 0           *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DS ;
1229             }
1230 0           ldns_rr_list_deep_free(parent_keys);
1231 0           break;
1232             } else {
1233 0           parent_domain = ldns_dname_left_chop((
1234             prev_parent_domain
1235 0           = parent_domain
1236             ));
1237 0           ldns_rdf_deep_free(prev_parent_domain);
1238             }
1239             }
1240 0 0         if (parent_domain) {
1241 0           ldns_rdf_deep_free(parent_domain);
1242             }
1243             }
1244             }
1245 0           return trusted_keys;
1246             }
1247              
1248             ldns_rr_list *
1249 0           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 0           return ldns_fetch_valid_domain_keys_time(
1255             res, domain, keys, ldns_time(NULL), status);
1256             }
1257              
1258             ldns_rr_list *
1259 0           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 0           ldns_rr_list * domain_keys = NULL;
1272 0           ldns_rr_list * domain_sigs = NULL;
1273 0           ldns_rr_list * trusted_keys = NULL;
1274              
1275             /* Fetch keys for the domain */
1276 0           keypkt = ldns_resolver_query(res, domain,
1277             LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, LDNS_RD);
1278 0 0         if (keypkt) {
1279 0           domain_keys = ldns_pkt_rr_list_by_type(keypkt,
1280             LDNS_RR_TYPE_DNSKEY,
1281             LDNS_SECTION_ANSWER);
1282 0           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 0 0         for (key_i=0; key_i< ldns_rr_list_rr_count(domain_keys); key_i++) {
1288            
1289 0           cur_key = ldns_rr_list_rr(domain_keys, key_i);
1290 0 0         for (key_j=0; key_j
1291 0 0         if (ldns_rr_compare_ds(ldns_rr_list_rr(keys, key_j),
1292             cur_key)) {
1293            
1294             /* Current key is trusted -- validate */
1295 0           trusted_keys = ldns_rr_list_new();
1296            
1297 0 0         for (sig_i=0;
1298 0           sig_i
1299 0           sig_i++) {
1300 0           cur_sig = ldns_rr_list_rr(domain_sigs, sig_i);
1301             /* Avoid non-matching sigs */
1302 0 0         if (ldns_rdf2native_int16(
1303 0           ldns_rr_rrsig_keytag(cur_sig))
1304 0           == ldns_calc_keytag(cur_key)) {
1305 0 0         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 0 0         for (key_k=0;
1315 0           key_k
1316             domain_keys);
1317 0           key_k++) {
1318 0           ldns_rr_list_push_rr(
1319             trusted_keys,
1320 0           ldns_rr_clone(
1321 0           ldns_rr_list_rr(
1322             domain_keys,
1323             key_k)));
1324             }
1325            
1326 0           ldns_rr_list_deep_free(domain_keys);
1327 0           ldns_rr_list_deep_free(domain_sigs);
1328 0           ldns_pkt_free(keypkt);
1329 0           return trusted_keys;
1330             }
1331             }
1332             }
1333            
1334             /* Only push our trusted key */
1335 0           ldns_rr_list_push_rr(trusted_keys,
1336 0           ldns_rr_clone(cur_key));
1337             }
1338             }
1339             }
1340              
1341 0           ldns_rr_list_deep_free(domain_keys);
1342 0           ldns_rr_list_deep_free(domain_sigs);
1343 0           ldns_pkt_free(keypkt);
1344              
1345             } else {
1346             /* LDNS_STATUS_CRYPTO_NO_DNSKEY */
1347             }
1348            
1349 0           return trusted_keys;
1350             }
1351              
1352             ldns_rr_list *
1353 0           ldns_validate_domain_dnskey(const ldns_resolver * res,
1354             const ldns_rdf * domain,
1355             const ldns_rr_list * keys)
1356             {
1357 0           return ldns_validate_domain_dnskey_time(
1358             res, domain, keys, ldns_time(NULL));
1359             }
1360              
1361             ldns_rr_list *
1362 0           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 0           ldns_rr_list * rrset = NULL;
1371 0           ldns_rr_list * sigs = NULL;
1372 0           ldns_rr_list * trusted_keys = NULL;
1373              
1374             /* Fetch DS for the domain */
1375 0           dspkt = ldns_resolver_query(res, domain,
1376             LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN, LDNS_RD);
1377 0 0         if (dspkt) {
1378 0           rrset = ldns_pkt_rr_list_by_type(dspkt,
1379             LDNS_RR_TYPE_DS,
1380             LDNS_SECTION_ANSWER);
1381 0           sigs = ldns_pkt_rr_list_by_type(dspkt,
1382             LDNS_RR_TYPE_RRSIG,
1383             LDNS_SECTION_ANSWER);
1384              
1385             /* Validate sigs */
1386 0 0         if (ldns_verify_time(rrset, sigs, keys, check_time, NULL)
1387             == LDNS_STATUS_OK) {
1388 0           trusted_keys = ldns_rr_list_new();
1389 0 0         for (key_i=0; key_i
1390 0           ldns_rr_list_push_rr(trusted_keys,
1391 0           ldns_rr_clone(ldns_rr_list_rr(rrset,
1392             key_i)
1393             )
1394             );
1395             }
1396             }
1397              
1398 0           ldns_rr_list_deep_free(rrset);
1399 0           ldns_rr_list_deep_free(sigs);
1400 0           ldns_pkt_free(dspkt);
1401              
1402             } else {
1403             /* LDNS_STATUS_CRYPTO_NO_DS */
1404             }
1405              
1406 0           return trusted_keys;
1407             }
1408              
1409             ldns_rr_list *
1410 0           ldns_validate_domain_ds(const ldns_resolver *res,
1411             const ldns_rdf * domain,
1412             const ldns_rr_list * keys)
1413             {
1414 0           return ldns_validate_domain_ds_time(res, domain, keys, ldns_time(NULL));
1415             }
1416              
1417             ldns_status
1418 0           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 0           ldns_rr_list * trusted_keys = NULL;
1429 0           ldns_status result = LDNS_STATUS_ERR;
1430              
1431 0 0         if (!res || !rrset || !rrsigs) {
    0          
    0          
1432 0           return LDNS_STATUS_ERR;
1433             }
1434              
1435 0 0         if (ldns_rr_list_rr_count(rrset) < 1) {
1436 0           return LDNS_STATUS_ERR;
1437             }
1438              
1439 0 0         if (ldns_rr_list_rr_count(rrsigs) < 1) {
1440 0           return LDNS_STATUS_CRYPTO_NO_RRSIG;
1441             }
1442            
1443             /* Look at each sig */
1444 0 0         for (sig_i=0; sig_i < ldns_rr_list_rr_count(rrsigs); sig_i++) {
1445              
1446 0           cur_sig = ldns_rr_list_rr(rrsigs, sig_i);
1447             /* Get a valid signer key and validate the sig */
1448 0 0         if ((trusted_keys = ldns_fetch_valid_domain_keys_time(
1449             res,
1450 0           ldns_rr_rrsig_signame(cur_sig),
1451 0           ldns_resolver_dnssec_anchors(res),
1452             check_time,
1453             &result))) {
1454              
1455 0 0         for (key_i = 0;
1456 0           key_i < ldns_rr_list_rr_count(trusted_keys);
1457 0           key_i++) {
1458 0           cur_key = ldns_rr_list_rr(trusted_keys, key_i);
1459              
1460 0 0         if ((result = ldns_verify_rrsig_time(rrset,
1461             cur_sig,
1462             cur_key,
1463             check_time))
1464 0           == LDNS_STATUS_OK) {
1465 0 0         if (validating_keys) {
1466 0           ldns_rr_list_push_rr(validating_keys,
1467 0           ldns_rr_clone(cur_key));
1468             }
1469 0           ldns_rr_list_deep_free(trusted_keys);
1470 0           return LDNS_STATUS_OK;
1471             }
1472             }
1473             }
1474             }
1475              
1476 0           ldns_rr_list_deep_free(trusted_keys);
1477 0           return result;
1478             }
1479              
1480             ldns_status
1481 0           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 0           return ldns_verify_trusted_time(
1488             res, rrset, rrsigs, ldns_time(NULL), validating_keys);
1489             }
1490              
1491              
1492             ldns_status
1493 0           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 0           bool name_covered = false;
1506 0           bool type_covered = false;
1507 0           bool wildcard_covered = false;
1508 0           bool wildcard_type_covered = false;
1509              
1510 0           wildcard_name = ldns_dname_new_frm_str("*");
1511 0           rr_name = ldns_rr_owner(rr);
1512 0           chopped_dname = ldns_dname_left_chop(rr_name);
1513 0           result = ldns_dname_cat(wildcard_name, chopped_dname);
1514 0           ldns_rdf_deep_free(chopped_dname);
1515 0 0         if (result != LDNS_STATUS_OK) {
1516 0           return result;
1517             }
1518            
1519 0 0         for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1520 0           cur_nsec = ldns_rr_list_rr(nsecs, i);
1521 0 0         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 0           rrsig = ldns_dnssec_get_rrsig_for_name_and_type(
1526 0           ldns_rr_owner(cur_nsec),
1527             ldns_rr_get_type(cur_nsec),
1528             rrsigs);
1529 0 0         if (rrsig && ldns_rdf2native_int8(ldns_rr_rrsig_labels(rrsig))
    0          
1530 0           == ldns_dname_label_count(rr_name)) {
1531 0           wildcard_covered = true;
1532             }
1533            
1534 0 0         if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
1535             ldns_rr_get_type(rr))) {
1536 0           type_covered = true;
1537             }
1538             }
1539 0 0         if (ldns_nsec_covers_name(cur_nsec, rr_name)) {
1540 0           name_covered = true;
1541             }
1542            
1543 0 0         if (ldns_dname_compare(wildcard_name,
1544 0           ldns_rr_owner(cur_nsec)) == 0) {
1545 0 0         if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
1546             ldns_rr_get_type(rr))) {
1547 0           wildcard_type_covered = true;
1548             }
1549             }
1550            
1551 0 0         if (ldns_nsec_covers_name(cur_nsec, wildcard_name)) {
1552 0           wildcard_covered = true;
1553             }
1554            
1555             }
1556            
1557 0           ldns_rdf_deep_free(wildcard_name);
1558            
1559 0 0         if (type_covered || !name_covered) {
    0          
1560 0           return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1561             }
1562            
1563 0 0         if (wildcard_type_covered || !wildcard_covered) {
    0          
1564 0           return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
1565             }
1566              
1567 0           return LDNS_STATUS_OK;
1568             }
1569              
1570             ldns_status
1571 0           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 0           bool wildcard_covered = false;
1584             ldns_rdf *zone_name;
1585             ldns_rdf *hashed_name;
1586             /* self assignment to suppress uninitialized warning */
1587 0           ldns_rdf *next_closer = next_closer;
1588             ldns_rdf *hashed_next_closer;
1589             size_t i;
1590 0           ldns_status result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1591              
1592 0 0         if (match) {
1593 0           *match = NULL;
1594             }
1595              
1596 0           zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
1597              
1598             /* section 8.4 */
1599 0 0         if (packet_rcode == LDNS_RCODE_NXDOMAIN) {
1600 0           closest_encloser = ldns_dnssec_nsec3_closest_encloser(
1601             ldns_rr_owner(rr),
1602             ldns_rr_get_type(rr),
1603             nsecs);
1604 0 0         if(!closest_encloser) {
1605 0           result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1606 0           goto done;
1607             }
1608              
1609 0           wildcard = ldns_dname_new_frm_str("*");
1610 0           (void) ldns_dname_cat(wildcard, closest_encloser);
1611              
1612 0 0         for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1613 0           hashed_wildcard_name =
1614 0           ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
1615             wildcard
1616             );
1617 0           (void) ldns_dname_cat(hashed_wildcard_name, zone_name);
1618              
1619 0 0         if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
1620             hashed_wildcard_name)) {
1621 0           wildcard_covered = true;
1622 0 0         if (match) {
1623 0           *match = ldns_rr_list_rr(nsecs, i);
1624             }
1625             }
1626 0           ldns_rdf_deep_free(hashed_wildcard_name);
1627             }
1628              
1629 0 0         if (! wildcard_covered) {
1630 0           result = LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
1631             } else {
1632 0           result = LDNS_STATUS_OK;
1633             }
1634 0           ldns_rdf_deep_free(closest_encloser);
1635 0           ldns_rdf_deep_free(wildcard);
1636              
1637 0 0         } else if (packet_nodata && packet_qtype != LDNS_RR_TYPE_DS) {
    0          
1638             /* section 8.5 */
1639 0           hashed_name = ldns_nsec3_hash_name_frm_nsec3(
1640 0           ldns_rr_list_rr(nsecs, 0),
1641             ldns_rr_owner(rr));
1642 0           (void) ldns_dname_cat(hashed_name, zone_name);
1643 0 0         for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1644 0 0         if (ldns_dname_compare(hashed_name,
1645 0           ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
1646             == 0) {
1647 0 0         if (!ldns_nsec_bitmap_covers_type(
1648 0           ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1649             packet_qtype)
1650 0 0         &&
1651 0           !ldns_nsec_bitmap_covers_type(
1652 0           ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1653             LDNS_RR_TYPE_CNAME)) {
1654 0           result = LDNS_STATUS_OK;
1655 0 0         if (match) {
1656 0           *match = ldns_rr_list_rr(nsecs, i);
1657             }
1658 0           goto done;
1659             }
1660             }
1661             }
1662 0           result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1663             /* wildcard no data? section 8.7 */
1664 0           closest_encloser = ldns_dnssec_nsec3_closest_encloser(
1665             ldns_rr_owner(rr),
1666             ldns_rr_get_type(rr),
1667             nsecs);
1668 0 0         if(!closest_encloser) {
1669 0           result = LDNS_STATUS_NSEC3_ERR;
1670 0           goto done;
1671             }
1672 0           wildcard = ldns_dname_new_frm_str("*");
1673 0           (void) ldns_dname_cat(wildcard, closest_encloser);
1674 0 0         for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1675 0           hashed_wildcard_name =
1676 0           ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
1677             wildcard);
1678 0           (void) ldns_dname_cat(hashed_wildcard_name, zone_name);
1679              
1680 0 0         if (ldns_dname_compare(hashed_wildcard_name,
1681 0           ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
1682             == 0) {
1683 0 0         if (!ldns_nsec_bitmap_covers_type(
1684 0           ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1685             packet_qtype)
1686 0 0         &&
1687 0           !ldns_nsec_bitmap_covers_type(
1688 0           ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1689             LDNS_RR_TYPE_CNAME)) {
1690 0           result = LDNS_STATUS_OK;
1691 0 0         if (match) {
1692 0           *match = ldns_rr_list_rr(nsecs, i);
1693             }
1694             }
1695             }
1696 0           ldns_rdf_deep_free(hashed_wildcard_name);
1697 0 0         if (result == LDNS_STATUS_OK) {
1698 0           break;
1699             }
1700             }
1701 0           ldns_rdf_deep_free(closest_encloser);
1702 0           ldns_rdf_deep_free(wildcard);
1703 0 0         } else if (packet_nodata && packet_qtype == LDNS_RR_TYPE_DS) {
    0          
1704             /* section 8.6 */
1705             /* note: up to XXX this is the same as for 8.5 */
1706 0           hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs,
1707             0),
1708             ldns_rr_owner(rr)
1709             );
1710 0           (void) ldns_dname_cat(hashed_name, zone_name);
1711 0 0         for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1712 0 0         if (ldns_dname_compare(hashed_name,
1713 0           ldns_rr_owner(ldns_rr_list_rr(nsecs,
1714             i)))
1715             == 0) {
1716 0 0         if (!ldns_nsec_bitmap_covers_type(
1717 0           ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1718             LDNS_RR_TYPE_DS)
1719 0 0         &&
1720 0           !ldns_nsec_bitmap_covers_type(
1721 0           ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1722             LDNS_RR_TYPE_CNAME)) {
1723 0           result = LDNS_STATUS_OK;
1724 0 0         if (match) {
1725 0           *match = ldns_rr_list_rr(nsecs, i);
1726             }
1727 0           goto done;
1728             }
1729             }
1730             }
1731              
1732             /* XXX see note above */
1733 0           result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1734              
1735 0           closest_encloser = ldns_dnssec_nsec3_closest_encloser(
1736             ldns_rr_owner(rr),
1737             ldns_rr_get_type(rr),
1738             nsecs);
1739 0 0         if(!closest_encloser) {
1740 0           result = LDNS_STATUS_NSEC3_ERR;
1741 0           goto done;
1742             }
1743             /* Now check if we have a Opt-Out NSEC3 that covers the "next closer"*/
1744              
1745 0 0         if (ldns_dname_label_count(closest_encloser) + 1
1746 0           >= ldns_dname_label_count(ldns_rr_owner(rr))) {
1747            
1748             /* Query name *is* the "next closer". */
1749 0           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 0           next_closer = ldns_dname_clone_from(
1756 0           ldns_rr_owner(rr),
1757 0           ldns_dname_label_count(ldns_rr_owner(rr))
1758 0           - (ldns_dname_label_count(closest_encloser) + 1)
1759             );
1760 0           hashed_next_closer = ldns_nsec3_hash_name_frm_nsec3(
1761 0           ldns_rr_list_rr(nsecs, 0),
1762             next_closer
1763             );
1764 0           (void) ldns_dname_cat(hashed_next_closer, zone_name);
1765             }
1766             /* Find the NSEC3 that covers the "next closer" */
1767 0 0         for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1768 0 0         if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
1769 0 0         hashed_next_closer) &&
1770 0           ldns_nsec3_optout(ldns_rr_list_rr(nsecs, i))) {
1771              
1772 0           result = LDNS_STATUS_OK;
1773 0 0         if (match) {
1774 0           *match = ldns_rr_list_rr(nsecs, i);
1775             }
1776 0           break;
1777             }
1778             }
1779 0 0         if (ldns_dname_label_count(closest_encloser) + 1
1780 0           < 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 0           ldns_rdf_deep_free(hashed_next_closer);
1786 0           ldns_rdf_deep_free(next_closer);
1787             }
1788 0           ldns_rdf_deep_free(closest_encloser);
1789             }
1790              
1791             done:
1792 0           ldns_rdf_deep_free(zone_name);
1793 0           return result;
1794             }
1795              
1796             ldns_status
1797 0           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 0           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 0           ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
1813             {
1814             /* prefix header for X509 encoding */
1815 0           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 0 0         if(keylen != 64) {
1822             /* key wrong size */
1823 0           return NULL;
1824             }
1825              
1826             /* create evp_key */
1827 0           memmove(encoded, asn, 37);
1828 0           memmove(encoded+37, key, 64);
1829 0           pp = (unsigned char*)&encoded[0];
1830              
1831 0           return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
1832             }
1833              
1834             static ldns_status
1835 0           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 0           (void) ldns_key_EVP_load_gost_id();
1842 0           evp_key = ldns_gost2pkey_raw(key, keylen);
1843 0 0         if(!evp_key) {
1844             /* could not convert key */
1845 0           return LDNS_STATUS_CRYPTO_BOGUS;
1846             }
1847              
1848             /* verify signature */
1849 0           result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset,
1850             evp_key, EVP_get_digestbyname("md_gost94"));
1851 0           EVP_PKEY_free(evp_key);
1852              
1853 0           return result;
1854             }
1855             #endif
1856              
1857             #ifdef USE_ECDSA
1858             EVP_PKEY*
1859 0           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 0           const unsigned char* pp = buf;
1863             EVP_PKEY *evp_key;
1864             EC_KEY *ec;
1865             /* check length, which uncompressed must be 2 bignums */
1866 0 0         if(algo == LDNS_ECDSAP256SHA256) {
1867 0 0         if(keylen != 2*256/8) return NULL;
1868 0           ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
1869 0 0         } else if(algo == LDNS_ECDSAP384SHA384) {
1870 0 0         if(keylen != 2*384/8) return NULL;
1871 0           ec = EC_KEY_new_by_curve_name(NID_secp384r1);
1872 0           } else ec = NULL;
1873 0 0         if(!ec) return NULL;
1874 0 0         if(keylen+1 > sizeof(buf))
1875 0           return NULL; /* sanity check */
1876             /* prepend the 0x02 (from docs) (or actually 0x04 from implementation
1877             * of openssl) for uncompressed data */
1878 0           buf[0] = POINT_CONVERSION_UNCOMPRESSED;
1879 0           memmove(buf+1, key, keylen);
1880 0 0         if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
1881 0           EC_KEY_free(ec);
1882 0           return NULL;
1883             }
1884 0           evp_key = EVP_PKEY_new();
1885 0 0         if(!evp_key) {
1886 0           EC_KEY_free(ec);
1887 0           return NULL;
1888             }
1889 0 0         if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
1890 0           EVP_PKEY_free(evp_key);
1891 0           EC_KEY_free(ec);
1892 0           return NULL;
1893             }
1894 0           return evp_key;
1895             }
1896              
1897             static ldns_status
1898 0           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 0           evp_key = ldns_ecdsa2pkey_raw(key, keylen, algo);
1906 0 0         if(!evp_key) {
1907             /* could not convert key */
1908 0           return LDNS_STATUS_CRYPTO_BOGUS;
1909             }
1910 0 0         if(algo == LDNS_ECDSAP256SHA256)
1911 0           d = EVP_sha256();
1912 0           else d = EVP_sha384(); /* LDNS_ECDSAP384SHA384 */
1913 0           result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, d);
1914 0           EVP_PKEY_free(evp_key);
1915 0           return result;
1916             }
1917             #endif
1918              
1919             ldns_status
1920 3           ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf,
1921             ldns_buffer *key_buf, uint8_t algo)
1922             {
1923 9           return ldns_verify_rrsig_buffers_raw(
1924 3           (unsigned char*)ldns_buffer_begin(rawsig_buf),
1925             ldns_buffer_position(rawsig_buf),
1926             verify_buf,
1927 3           (unsigned char*)ldns_buffer_begin(key_buf),
1928             ldns_buffer_position(key_buf), algo);
1929             }
1930              
1931             ldns_status
1932 3           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 3           switch(algo) {
1938             case LDNS_DSA:
1939             case LDNS_DSA_NSEC3:
1940 0           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 3           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 0           return ldns_verify_rrsig_rsasha256_raw(sig,
1957             siglen,
1958             verify_buf,
1959             key,
1960             keylen);
1961             break;
1962             case LDNS_RSASHA512:
1963 0           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 0           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 0           return ldns_verify_rrsig_ecdsa_raw(sig, siglen, verify_buf,
1980             key, keylen, algo);
1981             break;
1982             #endif
1983             case LDNS_RSAMD5:
1984 0           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 0           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 5           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 5 50         if ((rrsig == NULL) || ldns_rr_rd_count(rrsig) < 4) {
    50          
2015 0           return;
2016             }
2017              
2018 5           orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
2019 5           label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
2020              
2021 10 100         for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
2022 5 50         if (label_count <
2023 5           ldns_dname_label_count(
2024 5           ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
2025 0           (void) ldns_str2rdf_dname(&wildcard_name, "*");
2026 0           wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(
2027 0           ldns_rr_list_rr(rrset_clone, i)));
2028 0 0         while (label_count < ldns_dname_label_count(wildcard_chopped)) {
2029 0           wildcard_chopped_tmp = ldns_dname_left_chop(
2030             wildcard_chopped);
2031 0           ldns_rdf_deep_free(wildcard_chopped);
2032 0           wildcard_chopped = wildcard_chopped_tmp;
2033             }
2034 0           (void) ldns_dname_cat(wildcard_name, wildcard_chopped);
2035 0           ldns_rdf_deep_free(wildcard_chopped);
2036 0           ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(
2037             rrset_clone, i)));
2038 0           ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i),
2039             wildcard_name);
2040             }
2041 5           ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl);
2042             /* convert to lowercase */
2043 5           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 5           ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
2055             {
2056             uint8_t sig_algo;
2057            
2058 5 50         if (rrsig == NULL) {
2059 0           return LDNS_STATUS_CRYPTO_NO_RRSIG;
2060             }
2061 5 50         if (ldns_rr_rdf(rrsig, 1) == NULL) {
2062 0           return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2063             }
2064 5           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 5           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 5 50         if (ldns_rr_rdf(rrsig, 8) == NULL) {
2084 0           return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2085             }
2086 5 50         if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8))
2087             != LDNS_STATUS_OK) {
2088 0           return LDNS_STATUS_MEM_ERR;
2089             }
2090 5           break;
2091             case LDNS_DSA:
2092             case LDNS_DSA_NSEC3:
2093             /* EVP takes rfc2459 format, which is a tad longer than dns format */
2094 0 0         if (ldns_rr_rdf(rrsig, 8) == NULL) {
2095 0           return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2096             }
2097 0 0         if (ldns_convert_dsa_rrsig_rdf2asn1(
2098 0           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 0           return LDNS_STATUS_MEM_ERR;
2105             }
2106 0           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 0 0         if (ldns_rr_rdf(rrsig, 8) == NULL) {
2113 0           return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2114             }
2115 0 0         if (ldns_convert_ecdsa_rrsig_rdf2asn1(
2116 0           rawsig_buf, ldns_rr_rdf(rrsig, 8))
2117             != LDNS_STATUS_OK) {
2118 0           return LDNS_STATUS_MEM_ERR;
2119             }
2120 0           break;
2121             #endif
2122             case LDNS_DH:
2123             case LDNS_ECC:
2124             case LDNS_INDIRECT:
2125 0           return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
2126             default:
2127 0           return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2128             }
2129 5           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 3           ldns_rrsig_check_timestamps(ldns_rr* rrsig, time_t now)
2140             {
2141             int32_t inception, expiration;
2142            
2143             /* check the signature time stamps */
2144 3           inception = (int32_t)ldns_rdf2native_time_t(
2145 3           ldns_rr_rrsig_inception(rrsig));
2146 3           expiration = (int32_t)ldns_rdf2native_time_t(
2147 3           ldns_rr_rrsig_expiration(rrsig));
2148              
2149 3 50         if (expiration - inception < 0) {
2150             /* bad sig, expiration before inception?? Tsssg */
2151 0           return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
2152             }
2153 3 50         if (((int32_t) now) - inception < 0) {
2154             /* bad sig, inception date has not yet come to pass */
2155 0           return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
2156             }
2157 3 100         if (expiration - ((int32_t) now) < 0) {
2158             /* bad sig, expiration date has passed */
2159 2           return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
2160             }
2161 1           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 5           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 5           ldns_dname2canonical(ldns_rr_owner(rrsig));
2180            
2181             /* check if the typecovered is equal to the type checked */
2182 10 50         if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)) !=
2183 5           ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0)))
2184 0           return LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR;
2185            
2186             /* create a buffer with b64 signature rdata */
2187 5           result = ldns_rrsig2rawsig_buffer(rawsig_buf, rrsig);
2188 5 50         if(result != LDNS_STATUS_OK)
2189 0           return result;
2190              
2191             /* use TTL from signature. Use wildcard names for wildcards */
2192             /* also canonicalizes rrset_clone */
2193 5           ldns_rrset_use_signature_ttl(rrset_clone, rrsig);
2194              
2195             /* sort the rrset in canonical order */
2196 5           ldns_rr_list_sort(rrset_clone);
2197              
2198             /* put the signature rr (without the b64) to the verify_buf */
2199 5 50         if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK)
2200 0           return LDNS_STATUS_MEM_ERR;
2201              
2202             /* add the rrset in verify_buf */
2203 5 50         if(ldns_rr_list2buffer_wire(verify_buf, rrset_clone)
2204             != LDNS_STATUS_OK)
2205 0           return LDNS_STATUS_MEM_ERR;
2206              
2207 5           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 8           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 8 50         if (rrsig == NULL) {
2226 0           return LDNS_STATUS_CRYPTO_NO_RRSIG;
2227             }
2228 8 50         if (ldns_rr_rdf(rrsig, 1) == NULL) {
2229 0           return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2230             }
2231 8           sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
2232              
2233             /* before anything, check if the keytags match */
2234 16 100         if (ldns_calc_keytag(key)
2235             ==
2236 8           ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
2237             ) {
2238 3           ldns_buffer* key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2239 3           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 3 50         if (ldns_rr_rdf(key, 3) == NULL) {
2244 0           ldns_buffer_free(key_buf);
2245 0           return LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
2246             }
2247 3 50         if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3))
2248             != LDNS_STATUS_OK) {
2249 0           ldns_buffer_free(key_buf);
2250             /* returning is bad might screw up
2251             good keys later in the list
2252             what to do? */
2253 0           return LDNS_STATUS_ERR;
2254             }
2255              
2256 3 50         if (ldns_rr_rdf(key, 2) == NULL) {
2257 0           result = LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
2258             }
2259 3 50         else if (sig_algo == ldns_rdf2native_int8(
2260 3           ldns_rr_rdf(key, 2))) {
2261 3           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 0           result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2266             }
2267              
2268 3           ldns_buffer_free(key_buf);
2269 3           return result;
2270             }
2271             else {
2272             /* No keys with the corresponding keytag are found */
2273 5           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 5           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 5           ldns_rr_list *valid = ldns_rr_list_new();
2296 5 50         if (!valid)
2297 0           return LDNS_STATUS_MEM_ERR;
2298              
2299 5           result = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, valid);
2300 5 100         if(result != LDNS_STATUS_OK) {
2301 2           ldns_rr_list_free(valid);
2302 2           return result;
2303             }
2304              
2305             /* check timestamps last; its OK except time */
2306 3           result = ldns_rrsig_check_timestamps(rrsig, check_time);
2307 3 100         if(result != LDNS_STATUS_OK) {
2308 2           ldns_rr_list_free(valid);
2309 2           return result;
2310             }
2311              
2312 1           ldns_rr_list_cat(good_keys, valid);
2313 1           ldns_rr_list_free(valid);
2314 1           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 0           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 0           return ldns_verify_rrsig_keylist_time(
2333             rrset, rrsig, keys, ldns_time(NULL), good_keys);
2334             }
2335              
2336             ldns_status
2337 5           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 5 50         if (!rrset) {
2350 0           return LDNS_STATUS_ERR;
2351             }
2352              
2353 5           validkeys = ldns_rr_list_new();
2354 5 50         if (!validkeys) {
2355 0           return LDNS_STATUS_MEM_ERR;
2356             }
2357            
2358             /* clone the rrset so that we can fiddle with it */
2359 5           rrset_clone = ldns_rr_list_clone(rrset);
2360              
2361             /* create the buffers which will certainly hold the raw data */
2362 5           rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2363 5           verify_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2364              
2365 5           result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
2366             rrset_clone, rrsig);
2367 5 50         if(result != LDNS_STATUS_OK) {
2368 0           ldns_buffer_free(verify_buf);
2369 0           ldns_buffer_free(rawsig_buf);
2370 0           ldns_rr_list_deep_free(rrset_clone);
2371 0           ldns_rr_list_free(validkeys);
2372 0           return result;
2373             }
2374              
2375 5           result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2376 13 100         for(i = 0; i < ldns_rr_list_rr_count(keys); i++) {
2377 8           status = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
2378             rrsig, ldns_rr_list_rr(keys, i));
2379 8 100         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 3 50         if (!ldns_rr_list_push_rr(validkeys,
2385 3           ldns_rr_list_rr(keys,i))) {
2386             /* couldn't push the key?? */
2387 0           ldns_buffer_free(rawsig_buf);
2388 0           ldns_buffer_free(verify_buf);
2389 0           ldns_rr_list_deep_free(rrset_clone);
2390 0           ldns_rr_list_free(validkeys);
2391 0           return LDNS_STATUS_MEM_ERR;
2392             }
2393              
2394 3           result = status;
2395             }
2396              
2397 8 100         if (result == LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
2398 5           result = status;
2399             }
2400             }
2401              
2402             /* no longer needed */
2403 5           ldns_rr_list_deep_free(rrset_clone);
2404 5           ldns_buffer_free(rawsig_buf);
2405 5           ldns_buffer_free(verify_buf);
2406              
2407 5 100         if (ldns_rr_list_rr_count(validkeys) == 0) {
2408             /* no keys were added, return last error */
2409 2           ldns_rr_list_free(validkeys);
2410 2           return result;
2411             }
2412              
2413             /* do not check timestamps */
2414              
2415 3           ldns_rr_list_cat(good_keys, validkeys);
2416 3           ldns_rr_list_free(validkeys);
2417 3           return LDNS_STATUS_OK;
2418             }
2419              
2420             ldns_status
2421 0           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 0 0         if (!rrset) {
2433 0           return LDNS_STATUS_NO_DATA;
2434             }
2435             /* clone the rrset so that we can fiddle with it */
2436 0           rrset_clone = ldns_rr_list_clone(rrset);
2437             /* create the buffers which will certainly hold the raw data */
2438 0           rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2439 0           verify_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2440              
2441 0           result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
2442             rrset_clone, rrsig);
2443 0 0         if(result != LDNS_STATUS_OK) {
2444 0           ldns_rr_list_deep_free(rrset_clone);
2445 0           ldns_buffer_free(rawsig_buf);
2446 0           ldns_buffer_free(verify_buf);
2447 0           return result;
2448             }
2449 0           result = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
2450             rrsig, key);
2451             /* no longer needed */
2452 0           ldns_rr_list_deep_free(rrset_clone);
2453 0           ldns_buffer_free(rawsig_buf);
2454 0           ldns_buffer_free(verify_buf);
2455              
2456             /* check timestamp last, apart from time its OK */
2457 0 0         if(result == LDNS_STATUS_OK)
2458 0           result = ldns_rrsig_check_timestamps(rrsig, check_time);
2459              
2460 0           return result;
2461             }
2462              
2463             ldns_status
2464 0           ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
2465             {
2466 0           return ldns_verify_rrsig_time(rrset, rrsig, key, ldns_time(NULL));
2467             }
2468              
2469              
2470             ldns_status
2471 0           ldns_verify_rrsig_evp(ldns_buffer *sig,
2472             ldns_buffer *rrset,
2473             EVP_PKEY *key,
2474             const EVP_MD *digest_type)
2475             {
2476 0           return ldns_verify_rrsig_evp_raw(
2477 0           (unsigned char*)ldns_buffer_begin(sig),
2478             ldns_buffer_position(sig),
2479             rrset,
2480             key,
2481             digest_type);
2482             }
2483              
2484             ldns_status
2485 3           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 3           EVP_MD_CTX_init(&ctx);
2492            
2493 3           EVP_VerifyInit(&ctx, digest_type);
2494 3           EVP_VerifyUpdate(&ctx,
2495             ldns_buffer_begin(rrset),
2496             ldns_buffer_position(rrset));
2497 3           res = EVP_VerifyFinal(&ctx, sig, (unsigned int) siglen, key);
2498            
2499 3           EVP_MD_CTX_cleanup(&ctx);
2500            
2501 3 50         if (res == 1) {
2502 3           return LDNS_STATUS_OK;
2503 0 0         } else if (res == 0) {
2504 0           return LDNS_STATUS_CRYPTO_BOGUS;
2505             }
2506             /* TODO how to communicate internal SSL error?
2507             let caller use ssl's get_error() */
2508 3           return LDNS_STATUS_SSL_ERR;
2509             }
2510              
2511             ldns_status
2512 0           ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2513             {
2514 0           return ldns_verify_rrsig_dsa_raw(
2515 0           (unsigned char*) ldns_buffer_begin(sig),
2516             ldns_buffer_position(sig),
2517             rrset,
2518 0           (unsigned char*) ldns_buffer_begin(key),
2519             ldns_buffer_position(key));
2520             }
2521              
2522             ldns_status
2523 0           ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2524             {
2525 0           return ldns_verify_rrsig_rsasha1_raw(
2526 0           (unsigned char*)ldns_buffer_begin(sig),
2527             ldns_buffer_position(sig),
2528             rrset,
2529 0           (unsigned char*) ldns_buffer_begin(key),
2530             ldns_buffer_position(key));
2531             }
2532              
2533             ldns_status
2534 0           ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2535             {
2536 0           return ldns_verify_rrsig_rsamd5_raw(
2537 0           (unsigned char*)ldns_buffer_begin(sig),
2538             ldns_buffer_position(sig),
2539             rrset,
2540 0           (unsigned char*) ldns_buffer_begin(key),
2541             ldns_buffer_position(key));
2542             }
2543              
2544             ldns_status
2545 0           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 0           evp_key = EVP_PKEY_new();
2552 0 0         if (EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen))) {
2553 0           result = ldns_verify_rrsig_evp_raw(sig,
2554             siglen,
2555             rrset,
2556             evp_key,
2557             EVP_dss1());
2558             } else {
2559 0           result = LDNS_STATUS_SSL_ERR;
2560             }
2561 0           EVP_PKEY_free(evp_key);
2562 0           return result;
2563              
2564             }
2565              
2566             ldns_status
2567 3           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 3           evp_key = EVP_PKEY_new();
2574 3 50         if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2575 3           result = ldns_verify_rrsig_evp_raw(sig,
2576             siglen,
2577             rrset,
2578             evp_key,
2579             EVP_sha1());
2580             } else {
2581 0           result = LDNS_STATUS_SSL_ERR;
2582             }
2583 3           EVP_PKEY_free(evp_key);
2584              
2585 3           return result;
2586             }
2587              
2588             ldns_status
2589 0           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 0           evp_key = EVP_PKEY_new();
2600 0 0         if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2601 0           result = ldns_verify_rrsig_evp_raw(sig,
2602             siglen,
2603             rrset,
2604             evp_key,
2605             EVP_sha256());
2606             } else {
2607 0           result = LDNS_STATUS_SSL_ERR;
2608             }
2609 0           EVP_PKEY_free(evp_key);
2610              
2611 0           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 0           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 0           evp_key = EVP_PKEY_new();
2635 0 0         if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2636 0           result = ldns_verify_rrsig_evp_raw(sig,
2637             siglen,
2638             rrset,
2639             evp_key,
2640             EVP_sha512());
2641             } else {
2642 0           result = LDNS_STATUS_SSL_ERR;
2643             }
2644 0           EVP_PKEY_free(evp_key);
2645              
2646 0           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 0           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 0           evp_key = EVP_PKEY_new();
2670 0 0         if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2671 0           result = ldns_verify_rrsig_evp_raw(sig,
2672             siglen,
2673             rrset,
2674             evp_key,
2675             EVP_md5());
2676             } else {
2677 0           result = LDNS_STATUS_SSL_ERR;
2678             }
2679 0           EVP_PKEY_free(evp_key);
2680              
2681 0           return result;
2682             }
2683              
2684             #endif