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