toeplitz: Add comment.
[dragonfly.git] / contrib / ldns / dnssec_verify.c
blobd8d466479ed337d860a8664851c39a682c77462d
1 #include <ldns/config.h>
3 #include <ldns/ldns.h>
5 #include <strings.h>
6 #include <time.h>
8 #ifdef HAVE_SSL
9 /* this entire file is rather useless when you don't have
10 * crypto...
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>
18 ldns_dnssec_data_chain *
19 ldns_dnssec_data_chain_new()
21 ldns_dnssec_data_chain *nc = LDNS_CALLOC(ldns_dnssec_data_chain, 1);
22 if(!nc) return NULL;
23 /*
24 * not needed anymore because CALLOC initalizes everything to zero.
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;
35 return nc;
38 void
39 ldns_dnssec_data_chain_free(ldns_dnssec_data_chain *chain)
41 LDNS_FREE(chain);
44 void
45 ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain)
47 ldns_rr_list_deep_free(chain->rrset);
48 ldns_rr_list_deep_free(chain->signatures);
49 if (chain->parent) {
50 ldns_dnssec_data_chain_deep_free(chain->parent);
52 LDNS_FREE(chain);
55 void
56 ldns_dnssec_data_chain_print_fmt(FILE *out, const ldns_output_format *fmt,
57 const ldns_dnssec_data_chain *chain)
59 ldns_lookup_table *rcode;
60 const ldns_rr_descriptor *rr_descriptor;
61 if (chain) {
62 ldns_dnssec_data_chain_print_fmt(out, fmt, chain->parent);
63 if (ldns_rr_list_rr_count(chain->rrset) > 0) {
64 rcode = ldns_lookup_by_id(ldns_rcodes,
65 (int) chain->packet_rcode);
66 if (rcode) {
67 fprintf(out, ";; rcode: %s\n", rcode->name);
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);
77 if (chain->packet_nodata) {
78 fprintf(out, ";; NODATA response\n");
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");
90 void
91 ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain)
93 ldns_dnssec_data_chain_print_fmt(
94 out, ldns_output_format_default, chain);
98 static void
99 ldns_dnssec_build_data_chain_dnskey(ldns_resolver *res,
100 uint16_t qflags,
101 const ldns_pkt *pkt,
102 ldns_rr_list *signatures,
103 ldns_dnssec_data_chain *new_chain,
104 ldns_rdf *key_name,
105 ldns_rr_class c) {
106 ldns_rr_list *keys;
107 ldns_pkt *my_pkt;
108 if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
109 new_chain->signatures = ldns_rr_list_clone(signatures);
110 new_chain->parent_type = 0;
112 keys = ldns_pkt_rr_list_by_name_and_type(
113 pkt,
114 key_name,
115 LDNS_RR_TYPE_DNSKEY,
116 LDNS_SECTION_ANY_NOQUESTION
118 if (!keys) {
119 my_pkt = ldns_resolver_query(res,
120 key_name,
121 LDNS_RR_TYPE_DNSKEY,
123 qflags);
124 if (my_pkt) {
125 keys = ldns_pkt_rr_list_by_name_and_type(
126 my_pkt,
127 key_name,
128 LDNS_RR_TYPE_DNSKEY,
129 LDNS_SECTION_ANY_NOQUESTION
131 new_chain->parent = ldns_dnssec_build_data_chain(res,
132 qflags,
133 keys,
134 my_pkt,
135 NULL);
136 new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
137 ldns_pkt_free(my_pkt);
139 } else {
140 new_chain->parent = ldns_dnssec_build_data_chain(res,
141 qflags,
142 keys,
143 pkt,
144 NULL);
145 new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
147 ldns_rr_list_deep_free(keys);
151 static void
152 ldns_dnssec_build_data_chain_other(ldns_resolver *res,
153 uint16_t qflags,
154 ldns_dnssec_data_chain *new_chain,
155 ldns_rdf *key_name,
156 ldns_rr_class c,
157 ldns_rr_list *dss)
159 /* 'self-signed', parent is a DS */
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?
166 * request DNSKEYS for current zone,
167 * add all signatures to current level
169 ldns_pkt *my_pkt;
170 ldns_rr_list *signatures2;
172 new_chain->parent_type = 1;
174 my_pkt = ldns_resolver_query(res,
175 key_name,
176 LDNS_RR_TYPE_DS,
178 qflags);
179 if (my_pkt) {
180 dss = ldns_pkt_rr_list_by_name_and_type(my_pkt,
181 key_name,
182 LDNS_RR_TYPE_DS,
183 LDNS_SECTION_ANY_NOQUESTION
185 if (dss) {
186 new_chain->parent = ldns_dnssec_build_data_chain(res,
187 qflags,
188 dss,
189 my_pkt,
190 NULL);
191 new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
192 ldns_rr_list_deep_free(dss);
194 ldns_pkt_free(my_pkt);
197 my_pkt = ldns_resolver_query(res,
198 key_name,
199 LDNS_RR_TYPE_DNSKEY,
201 qflags);
202 if (my_pkt) {
203 signatures2 = ldns_pkt_rr_list_by_name_and_type(my_pkt,
204 key_name,
205 LDNS_RR_TYPE_RRSIG,
206 LDNS_SECTION_ANSWER);
207 if (signatures2) {
208 if (new_chain->signatures) {
209 printf("There were already sigs!\n");
210 ldns_rr_list_deep_free(new_chain->signatures);
211 printf("replacing the old sigs\n");
213 new_chain->signatures = signatures2;
215 ldns_pkt_free(my_pkt);
219 ldns_dnssec_data_chain *
220 ldns_dnssec_build_data_chain_nokeyname(ldns_resolver *res,
221 uint16_t qflags,
222 ldns_rr *orig_rr,
223 const ldns_rr_list *rrset,
224 ldns_dnssec_data_chain *new_chain)
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
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;
241 my_pkt = ldns_resolver_query(res,
242 possible_parent_name,
243 LDNS_RR_TYPE_DS,
244 LDNS_RR_CLASS_IN,
245 qflags);
246 if (!my_pkt) {
247 return new_chain;
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);
262 new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
265 return new_chain;
269 ldns_dnssec_data_chain *
270 ldns_dnssec_build_data_chain(ldns_resolver *res,
271 uint16_t qflags,
272 const ldns_rr_list *rrset,
273 const ldns_pkt *pkt,
274 ldns_rr *orig_rr)
276 ldns_rr_list *signatures = NULL;
277 ldns_rr_list *dss = NULL;
279 ldns_rr_list *my_rrset;
281 ldns_pkt *my_pkt;
283 ldns_rdf *name = NULL, *key_name = NULL;
284 ldns_rr_type type = 0;
285 ldns_rr_class c = 0;
287 bool other_rrset = false;
289 ldns_dnssec_data_chain *new_chain = ldns_dnssec_data_chain_new();
291 assert(pkt != NULL);
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;
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;
312 return new_chain;
315 if (!rrset || ldns_rr_list_rr_count(rrset) < 1) {
316 /* hmm, no data, do we have denial? only works if pkt was given,
317 otherwise caller has to do the check himself */
318 new_chain->packet_nodata = true;
319 if (pkt) {
320 my_rrset = ldns_pkt_rr_list_by_type(pkt,
321 LDNS_RR_TYPE_NSEC,
322 LDNS_SECTION_ANY_NOQUESTION
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;
332 } else {
333 /* nothing, try nsec3 */
334 my_rrset = ldns_pkt_rr_list_by_type(pkt,
335 LDNS_RR_TYPE_NSEC3,
336 LDNS_SECTION_ANY_NOQUESTION);
337 if (my_rrset) {
338 if (ldns_rr_list_rr_count(my_rrset) > 0) {
339 type = LDNS_RR_TYPE_NSEC3;
340 other_rrset = true;
341 } else {
342 ldns_rr_list_deep_free(my_rrset);
343 my_rrset = NULL;
345 } else {
346 /* nothing, stop */
347 /* try parent zone? for denied insecure? */
348 return new_chain;
351 } else {
352 return new_chain;
354 } else {
355 my_rrset = (ldns_rr_list *) rrset;
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));
365 if (other_rrset) {
366 ldns_rr_list_deep_free(my_rrset);
369 /* normally there will only be 1 signature 'set'
370 but there can be more than 1 denial (wildcards)
371 so check for NSEC
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);
385 } else {
386 if (pkt) {
387 signatures =
388 ldns_dnssec_pkt_get_rrsigs_for_name_and_type(pkt,
389 name,
390 type);
392 if (!signatures) {
393 my_pkt = ldns_resolver_query(res, name, type, c, qflags);
394 if (my_pkt) {
395 signatures =
396 ldns_dnssec_pkt_get_rrsigs_for_name_and_type(my_pkt,
397 name,
398 type);
399 ldns_pkt_free(my_pkt);
404 if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
405 key_name = ldns_rr_rdf(ldns_rr_list_rr(signatures, 0), 7);
407 if (!key_name) {
408 if (signatures) {
409 ldns_rr_list_deep_free(signatures);
411 return ldns_dnssec_build_data_chain_nokeyname(res,
412 qflags,
413 orig_rr,
414 rrset,
415 new_chain);
417 if (type != LDNS_RR_TYPE_DNSKEY) {
418 ldns_dnssec_build_data_chain_dnskey(res,
419 qflags,
420 pkt,
421 signatures,
422 new_chain,
423 key_name,
426 } else {
427 ldns_dnssec_build_data_chain_other(res,
428 qflags,
429 new_chain,
430 key_name,
435 if (signatures) {
436 ldns_rr_list_deep_free(signatures);
438 return new_chain;
441 ldns_dnssec_trust_tree *
442 ldns_dnssec_trust_tree_new()
444 ldns_dnssec_trust_tree *new_tree = LDNS_XMALLOC(ldns_dnssec_trust_tree,
446 if(!new_tree) return NULL;
447 new_tree->rr = NULL;
448 new_tree->rrset = NULL;
449 new_tree->parent_count = 0;
451 return new_tree;
454 void
455 ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree)
457 size_t i;
458 if (tree) {
459 for (i = 0; i < tree->parent_count; i++) {
460 ldns_dnssec_trust_tree_free(tree->parents[i]);
463 LDNS_FREE(tree);
466 size_t
467 ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree)
469 size_t result = 0;
470 size_t parent = 0;
471 size_t i;
473 for (i = 0; i < tree->parent_count; i++) {
474 parent = ldns_dnssec_trust_tree_depth(tree->parents[i]);
475 if (parent > result) {
476 result = parent;
479 return 1 + result;
482 /* TODO ldns_ */
483 static void
484 print_tabs(FILE *out, size_t nr, uint8_t *map, size_t treedepth)
486 size_t i;
487 for (i = 0; i < nr; i++) {
488 if (i == nr - 1) {
489 fprintf(out, "|---");
490 } else if (map && i < treedepth && map[i] == 1) {
491 fprintf(out, "| ");
492 } else {
493 fprintf(out, " ");
498 void
499 ldns_dnssec_trust_tree_print_sm_fmt(FILE *out,
500 const ldns_output_format *fmt,
501 ldns_dnssec_trust_tree *tree,
502 size_t tabs,
503 bool extended,
504 uint8_t *sibmap,
505 size_t treedepth)
507 size_t i;
508 const ldns_rr_descriptor *descriptor;
509 bool mapset = false;
511 if (!sibmap) {
512 treedepth = ldns_dnssec_trust_tree_depth(tree);
513 sibmap = LDNS_XMALLOC(uint8_t, treedepth);
514 if(!sibmap)
515 return; /* mem err */
516 memset(sibmap, 0, treedepth);
517 mapset = true;
520 if (tree) {
521 if (tree->rr) {
522 print_tabs(out, tabs, sibmap, treedepth);
523 ldns_rdf_print(out, ldns_rr_owner(tree->rr));
524 descriptor = ldns_rr_descript(ldns_rr_get_type(tree->rr));
526 if (descriptor->_name) {
527 fprintf(out, " (%s", descriptor->_name);
528 } else {
529 fprintf(out, " (TYPE%d",
530 ldns_rr_get_type(tree->rr));
532 if (tabs > 0) {
533 if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DNSKEY) {
534 fprintf(out, " keytag: %u",
535 (unsigned int) ldns_calc_keytag(tree->rr));
536 fprintf(out, " alg: ");
537 ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
538 fprintf(out, " flags: ");
539 ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
540 } else if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DS) {
541 fprintf(out, " keytag: ");
542 ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
543 fprintf(out, " digest type: ");
544 ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
546 if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NSEC) {
547 fprintf(out, " ");
548 ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
549 fprintf(out, " ");
550 ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 1));
554 fprintf(out, ")\n");
555 for (i = 0; i < tree->parent_count; i++) {
556 if (tree->parent_count > 1 && i < tree->parent_count - 1) {
557 sibmap[tabs] = 1;
558 } else {
559 sibmap[tabs] = 0;
561 /* only print errors */
562 if (ldns_rr_get_type(tree->parents[i]->rr) ==
563 LDNS_RR_TYPE_NSEC ||
564 ldns_rr_get_type(tree->parents[i]->rr) ==
565 LDNS_RR_TYPE_NSEC3) {
566 if (tree->parent_status[i] == LDNS_STATUS_OK) {
567 print_tabs(out, tabs + 1, sibmap, treedepth);
568 if (tabs == 0 &&
569 ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS &&
570 ldns_rr_rd_count(tree->rr) > 0) {
571 fprintf(out, "Existence of DS is denied by:\n");
572 } else {
573 fprintf(out, "Existence is denied by:\n");
575 } else {
576 /* NS records aren't signed */
577 if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS) {
578 fprintf(out, "Existence of DS is denied by:\n");
579 } else {
580 print_tabs(out, tabs + 1, sibmap, treedepth);
581 fprintf(out,
582 "Error in denial of existence: %s\n",
583 ldns_get_errorstr_by_id(
584 tree->parent_status[i]));
587 } else
588 if (tree->parent_status[i] != LDNS_STATUS_OK) {
589 print_tabs(out, tabs + 1, sibmap, treedepth);
590 fprintf(out,
591 "%s:\n",
592 ldns_get_errorstr_by_id(
593 tree->parent_status[i]));
594 if (tree->parent_status[i]
595 == LDNS_STATUS_SSL_ERR) {
596 printf("; SSL Error: ");
597 ERR_load_crypto_strings();
598 ERR_print_errors_fp(stdout);
599 printf("\n");
601 ldns_rr_print_fmt(out, fmt,
602 tree->
603 parent_signature[i]);
604 printf("For RRset:\n");
605 ldns_rr_list_print_fmt(out, fmt,
606 tree->rrset);
607 printf("With key:\n");
608 ldns_rr_print_fmt(out, fmt,
609 tree->parents[i]->rr);
611 ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
612 tree->parents[i],
613 tabs+1,
614 extended,
615 sibmap,
616 treedepth);
618 } else {
619 print_tabs(out, tabs, sibmap, treedepth);
620 fprintf(out, "<no data>\n");
622 } else {
623 fprintf(out, "<null pointer>\n");
626 if (mapset) {
627 LDNS_FREE(sibmap);
631 void
632 ldns_dnssec_trust_tree_print_sm(FILE *out,
633 ldns_dnssec_trust_tree *tree,
634 size_t tabs,
635 bool extended,
636 uint8_t *sibmap,
637 size_t treedepth)
639 ldns_dnssec_trust_tree_print_sm_fmt(out, ldns_output_format_default,
640 tree, tabs, extended, sibmap, treedepth);
643 void
644 ldns_dnssec_trust_tree_print_fmt(FILE *out, const ldns_output_format *fmt,
645 ldns_dnssec_trust_tree *tree,
646 size_t tabs,
647 bool extended)
649 ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
650 tree, tabs, extended, NULL, 0);
653 void
654 ldns_dnssec_trust_tree_print(FILE *out,
655 ldns_dnssec_trust_tree *tree,
656 size_t tabs,
657 bool extended)
659 ldns_dnssec_trust_tree_print_fmt(out, ldns_output_format_default,
660 tree, tabs, extended);
664 ldns_status
665 ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree,
666 const ldns_dnssec_trust_tree *parent,
667 const ldns_rr *signature,
668 const ldns_status parent_status)
670 if (tree
671 && parent
672 && tree->parent_count < LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS) {
674 printf("Add parent for: ");
675 ldns_rr_print(stdout, tree->rr);
676 printf("parent: ");
677 ldns_rr_print(stdout, parent->rr);
679 tree->parents[tree->parent_count] =
680 (ldns_dnssec_trust_tree *) parent;
681 tree->parent_status[tree->parent_count] = parent_status;
682 tree->parent_signature[tree->parent_count] = (ldns_rr *) signature;
683 tree->parent_count++;
684 return LDNS_STATUS_OK;
685 } else {
686 return LDNS_STATUS_ERR;
690 /* if rr is null, take the first from the rrset */
691 ldns_dnssec_trust_tree *
692 ldns_dnssec_derive_trust_tree_time(
693 ldns_dnssec_data_chain *data_chain,
694 ldns_rr *rr,
695 time_t check_time
698 ldns_rr_list *cur_rrset;
699 ldns_rr_list *cur_sigs;
700 ldns_rr *cur_rr = NULL;
701 ldns_rr *cur_sig_rr;
702 size_t i, j;
704 ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new();
705 if(!new_tree)
706 return NULL;
708 if (data_chain && data_chain->rrset) {
709 cur_rrset = data_chain->rrset;
711 cur_sigs = data_chain->signatures;
713 if (rr) {
714 cur_rr = rr;
717 if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) {
718 cur_rr = ldns_rr_list_rr(cur_rrset, 0);
721 if (cur_rr) {
722 new_tree->rr = cur_rr;
723 new_tree->rrset = cur_rrset;
724 /* there are three possibilities:
725 1 - 'normal' rrset, signed by a key
726 2 - dnskey signed by other dnskey
727 3 - dnskey proven by higher level DS
728 (data denied by nsec is a special case that can
729 occur in multiple places)
732 if (cur_sigs) {
733 for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) {
734 /* find the appropriate key in the parent list */
735 cur_sig_rr = ldns_rr_list_rr(cur_sigs, i);
737 if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) {
738 if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
739 ldns_rr_owner(cur_rr)))
741 /* find first that does match */
743 for (j = 0;
744 j < ldns_rr_list_rr_count(cur_rrset) &&
745 ldns_dname_compare(ldns_rr_owner(cur_sig_rr),ldns_rr_owner(cur_rr)) != 0;
746 j++) {
747 cur_rr = ldns_rr_list_rr(cur_rrset, j);
750 if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
751 ldns_rr_owner(cur_rr)))
753 break;
758 /* option 1 */
759 if (data_chain->parent) {
760 ldns_dnssec_derive_trust_tree_normal_rrset_time(
761 new_tree,
762 data_chain,
763 cur_sig_rr,
764 check_time);
767 /* option 2 */
768 ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
769 new_tree,
770 data_chain,
771 cur_rr,
772 cur_sig_rr,
773 check_time);
776 ldns_dnssec_derive_trust_tree_ds_rrset_time(
777 new_tree, data_chain,
778 cur_rr, check_time);
779 } else {
780 /* no signatures? maybe it's nsec data */
782 /* just add every rr from parent as new parent */
783 ldns_dnssec_derive_trust_tree_no_sig_time(
784 new_tree, data_chain, check_time);
789 return new_tree;
792 ldns_dnssec_trust_tree *
793 ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr)
795 return ldns_dnssec_derive_trust_tree_time(data_chain, rr, ldns_time(NULL));
798 void
799 ldns_dnssec_derive_trust_tree_normal_rrset_time(
800 ldns_dnssec_trust_tree *new_tree,
801 ldns_dnssec_data_chain *data_chain,
802 ldns_rr *cur_sig_rr,
803 time_t check_time)
805 size_t i, j;
806 ldns_rr_list *cur_rrset = ldns_rr_list_clone(data_chain->rrset);
807 ldns_dnssec_trust_tree *cur_parent_tree;
808 ldns_rr *cur_parent_rr;
809 uint16_t cur_keytag;
810 ldns_rr_list *tmp_rrset = NULL;
811 ldns_status cur_status;
813 cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
815 for (j = 0; j < ldns_rr_list_rr_count(data_chain->parent->rrset); j++) {
816 cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
817 if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
818 if (ldns_calc_keytag(cur_parent_rr) == cur_keytag) {
820 /* TODO: check wildcard nsec too */
821 if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
822 tmp_rrset = cur_rrset;
823 if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
824 == LDNS_RR_TYPE_NSEC ||
825 ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
826 == LDNS_RR_TYPE_NSEC3) {
827 /* might contain different names!
828 sort and split */
829 ldns_rr_list_sort(cur_rrset);
830 assert(tmp_rrset == cur_rrset);
831 tmp_rrset = ldns_rr_list_pop_rrset(cur_rrset);
833 /* with nsecs, this might be the wrong one */
834 while (tmp_rrset &&
835 ldns_rr_list_rr_count(cur_rrset) > 0 &&
836 ldns_dname_compare(
837 ldns_rr_owner(ldns_rr_list_rr(
838 tmp_rrset, 0)),
839 ldns_rr_owner(cur_sig_rr)) != 0) {
840 ldns_rr_list_deep_free(tmp_rrset);
841 tmp_rrset =
842 ldns_rr_list_pop_rrset(cur_rrset);
845 cur_status = ldns_verify_rrsig_time(
846 tmp_rrset,
847 cur_sig_rr,
848 cur_parent_rr,
849 check_time);
850 if (tmp_rrset && tmp_rrset != cur_rrset
852 ldns_rr_list_deep_free(
853 tmp_rrset);
854 tmp_rrset = NULL;
856 /* avoid dupes */
857 for (i = 0; i < new_tree->parent_count; i++) {
858 if (cur_parent_rr == new_tree->parents[i]->rr) {
859 goto done;
863 cur_parent_tree =
864 ldns_dnssec_derive_trust_tree_time(
865 data_chain->parent,
866 cur_parent_rr,
867 check_time);
868 (void)ldns_dnssec_trust_tree_add_parent(new_tree,
869 cur_parent_tree,
870 cur_sig_rr,
871 cur_status);
876 done:
877 ldns_rr_list_deep_free(cur_rrset);
880 void
881 ldns_dnssec_derive_trust_tree_normal_rrset(ldns_dnssec_trust_tree *new_tree,
882 ldns_dnssec_data_chain *data_chain,
883 ldns_rr *cur_sig_rr)
885 ldns_dnssec_derive_trust_tree_normal_rrset_time(
886 new_tree, data_chain, cur_sig_rr, ldns_time(NULL));
889 void
890 ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
891 ldns_dnssec_trust_tree *new_tree,
892 ldns_dnssec_data_chain *data_chain,
893 ldns_rr *cur_rr,
894 ldns_rr *cur_sig_rr,
895 time_t check_time)
897 size_t j;
898 ldns_rr_list *cur_rrset = data_chain->rrset;
899 ldns_dnssec_trust_tree *cur_parent_tree;
900 ldns_rr *cur_parent_rr;
901 uint16_t cur_keytag;
902 ldns_status cur_status;
904 cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
906 for (j = 0; j < ldns_rr_list_rr_count(cur_rrset); j++) {
907 cur_parent_rr = ldns_rr_list_rr(cur_rrset, j);
908 if (cur_parent_rr != cur_rr &&
909 ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
910 if (ldns_calc_keytag(cur_parent_rr) == cur_keytag
912 cur_parent_tree = ldns_dnssec_trust_tree_new();
913 cur_parent_tree->rr = cur_parent_rr;
914 cur_parent_tree->rrset = cur_rrset;
915 cur_status = ldns_verify_rrsig_time(
916 cur_rrset, cur_sig_rr,
917 cur_parent_rr, check_time);
918 (void) ldns_dnssec_trust_tree_add_parent(new_tree,
919 cur_parent_tree, cur_sig_rr, cur_status);
925 void
926 ldns_dnssec_derive_trust_tree_dnskey_rrset(ldns_dnssec_trust_tree *new_tree,
927 ldns_dnssec_data_chain *data_chain,
928 ldns_rr *cur_rr,
929 ldns_rr *cur_sig_rr)
931 ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
932 new_tree, data_chain, cur_rr, cur_sig_rr, ldns_time(NULL));
935 void
936 ldns_dnssec_derive_trust_tree_ds_rrset_time(
937 ldns_dnssec_trust_tree *new_tree,
938 ldns_dnssec_data_chain *data_chain,
939 ldns_rr *cur_rr,
940 time_t check_time)
942 size_t j, h;
943 ldns_rr_list *cur_rrset = data_chain->rrset;
944 ldns_dnssec_trust_tree *cur_parent_tree;
945 ldns_rr *cur_parent_rr;
947 /* try the parent to see whether there are DSs there */
948 if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_DNSKEY &&
949 data_chain->parent &&
950 data_chain->parent->rrset
952 for (j = 0;
953 j < ldns_rr_list_rr_count(data_chain->parent->rrset);
954 j++) {
955 cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
956 if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DS) {
957 for (h = 0; h < ldns_rr_list_rr_count(cur_rrset); h++) {
958 cur_rr = ldns_rr_list_rr(cur_rrset, h);
959 if (ldns_rr_compare_ds(cur_rr, cur_parent_rr)) {
960 cur_parent_tree =
961 ldns_dnssec_derive_trust_tree_time(
962 data_chain->parent,
963 cur_parent_rr,
964 check_time);
965 (void) ldns_dnssec_trust_tree_add_parent(
966 new_tree,
967 cur_parent_tree,
968 NULL,
969 LDNS_STATUS_OK);
970 } else {
971 /*ldns_rr_print(stdout, cur_parent_rr);*/
979 void
980 ldns_dnssec_derive_trust_tree_ds_rrset(ldns_dnssec_trust_tree *new_tree,
981 ldns_dnssec_data_chain *data_chain,
982 ldns_rr *cur_rr)
984 ldns_dnssec_derive_trust_tree_ds_rrset_time(
985 new_tree, data_chain, cur_rr, ldns_time(NULL));
988 void
989 ldns_dnssec_derive_trust_tree_no_sig_time(
990 ldns_dnssec_trust_tree *new_tree,
991 ldns_dnssec_data_chain *data_chain,
992 time_t check_time)
994 size_t i;
995 ldns_rr_list *cur_rrset;
996 ldns_rr *cur_parent_rr;
997 ldns_dnssec_trust_tree *cur_parent_tree;
998 ldns_status result;
1000 if (data_chain->parent && data_chain->parent->rrset) {
1001 cur_rrset = data_chain->parent->rrset;
1002 /* nsec? */
1003 if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
1004 if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
1005 LDNS_RR_TYPE_NSEC3) {
1006 result = ldns_dnssec_verify_denial_nsec3(
1007 new_tree->rr,
1008 cur_rrset,
1009 data_chain->parent->signatures,
1010 data_chain->packet_rcode,
1011 data_chain->packet_qtype,
1012 data_chain->packet_nodata);
1013 } else if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
1014 LDNS_RR_TYPE_NSEC) {
1015 result = ldns_dnssec_verify_denial(
1016 new_tree->rr,
1017 cur_rrset,
1018 data_chain->parent->signatures);
1019 } else {
1020 /* unsigned zone, unsigned parent */
1021 result = LDNS_STATUS_OK;
1023 } else {
1024 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1026 for (i = 0; i < ldns_rr_list_rr_count(cur_rrset); i++) {
1027 cur_parent_rr = ldns_rr_list_rr(cur_rrset, i);
1028 cur_parent_tree =
1029 ldns_dnssec_derive_trust_tree_time(
1030 data_chain->parent,
1031 cur_parent_rr,
1032 check_time);
1033 (void) ldns_dnssec_trust_tree_add_parent(new_tree,
1034 cur_parent_tree, NULL, result);
1039 void
1040 ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree *new_tree,
1041 ldns_dnssec_data_chain *data_chain)
1043 ldns_dnssec_derive_trust_tree_no_sig_time(
1044 new_tree, data_chain, ldns_time(NULL));
1048 * returns OK if there is a path from tree to key with only OK
1049 * the (first) error in between otherwise
1050 * or NOT_FOUND if the key wasn't present at all
1052 ldns_status
1053 ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree,
1054 ldns_rr_list *trusted_keys)
1056 size_t i;
1057 ldns_status result = LDNS_STATUS_CRYPTO_NO_DNSKEY;
1058 bool equal;
1059 ldns_status parent_result;
1061 if (tree && trusted_keys && ldns_rr_list_rr_count(trusted_keys) > 0)
1062 { if (tree->rr) {
1063 for (i = 0; i < ldns_rr_list_rr_count(trusted_keys); i++) {
1064 equal = ldns_rr_compare_ds(
1065 tree->rr,
1066 ldns_rr_list_rr(trusted_keys, i));
1067 if (equal) {
1068 result = LDNS_STATUS_OK;
1069 return result;
1073 for (i = 0; i < tree->parent_count; i++) {
1074 parent_result =
1075 ldns_dnssec_trust_tree_contains_keys(tree->parents[i],
1076 trusted_keys);
1077 if (parent_result != LDNS_STATUS_CRYPTO_NO_DNSKEY) {
1078 if (tree->parent_status[i] != LDNS_STATUS_OK) {
1079 result = tree->parent_status[i];
1080 } else {
1081 if (tree->rr &&
1082 ldns_rr_get_type(tree->rr)
1083 == LDNS_RR_TYPE_NSEC &&
1084 parent_result == LDNS_STATUS_OK
1086 result =
1087 LDNS_STATUS_DNSSEC_EXISTENCE_DENIED;
1088 } else {
1089 result = parent_result;
1094 } else {
1095 result = LDNS_STATUS_ERR;
1098 return result;
1101 ldns_status
1102 ldns_verify_time(
1103 ldns_rr_list *rrset,
1104 ldns_rr_list *rrsig,
1105 const ldns_rr_list *keys,
1106 time_t check_time,
1107 ldns_rr_list *good_keys
1110 uint16_t i;
1111 ldns_status verify_result = LDNS_STATUS_ERR;
1113 if (!rrset || !rrsig || !keys) {
1114 return LDNS_STATUS_ERR;
1117 if (ldns_rr_list_rr_count(rrset) < 1) {
1118 return LDNS_STATUS_ERR;
1121 if (ldns_rr_list_rr_count(rrsig) < 1) {
1122 return LDNS_STATUS_CRYPTO_NO_RRSIG;
1125 if (ldns_rr_list_rr_count(keys) < 1) {
1126 verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1127 } else {
1128 for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1129 ldns_status s = ldns_verify_rrsig_keylist_time(
1130 rrset, ldns_rr_list_rr(rrsig, i),
1131 keys, check_time, good_keys);
1132 /* try a little to get more descriptive error */
1133 if(s == LDNS_STATUS_OK) {
1134 verify_result = LDNS_STATUS_OK;
1135 } else if(verify_result == LDNS_STATUS_ERR)
1136 verify_result = s;
1137 else if(s != LDNS_STATUS_ERR && verify_result ==
1138 LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY)
1139 verify_result = s;
1142 return verify_result;
1145 ldns_status
1146 ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys,
1147 ldns_rr_list *good_keys)
1149 return ldns_verify_time(rrset, rrsig, keys, ldns_time(NULL), good_keys);
1152 ldns_status
1153 ldns_verify_notime(ldns_rr_list *rrset, ldns_rr_list *rrsig,
1154 const ldns_rr_list *keys, ldns_rr_list *good_keys)
1156 uint16_t i;
1157 ldns_status verify_result = LDNS_STATUS_ERR;
1159 if (!rrset || !rrsig || !keys) {
1160 return LDNS_STATUS_ERR;
1163 if (ldns_rr_list_rr_count(rrset) < 1) {
1164 return LDNS_STATUS_ERR;
1167 if (ldns_rr_list_rr_count(rrsig) < 1) {
1168 return LDNS_STATUS_CRYPTO_NO_RRSIG;
1171 if (ldns_rr_list_rr_count(keys) < 1) {
1172 verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1173 } else {
1174 for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1175 ldns_status s = ldns_verify_rrsig_keylist_notime(rrset,
1176 ldns_rr_list_rr(rrsig, i), keys, good_keys);
1178 /* try a little to get more descriptive error */
1179 if (s == LDNS_STATUS_OK) {
1180 verify_result = LDNS_STATUS_OK;
1181 } else if (verify_result == LDNS_STATUS_ERR) {
1182 verify_result = s;
1183 } else if (s != LDNS_STATUS_ERR && verify_result ==
1184 LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
1185 verify_result = s;
1189 return verify_result;
1192 ldns_rr_list *
1193 ldns_fetch_valid_domain_keys_time(const ldns_resolver *res,
1194 const ldns_rdf *domain,
1195 const ldns_rr_list *keys,
1196 time_t check_time,
1197 ldns_status *status)
1199 ldns_rr_list * trusted_keys = NULL;
1200 ldns_rr_list * ds_keys = NULL;
1201 ldns_rdf * prev_parent_domain;
1202 ldns_rdf * parent_domain;
1203 ldns_rr_list * parent_keys = NULL;
1205 if (res && domain && keys) {
1207 if ((trusted_keys = ldns_validate_domain_dnskey_time(res,
1208 domain, keys, check_time))) {
1209 *status = LDNS_STATUS_OK;
1210 } else {
1211 /* No trusted keys in this domain, we'll have to find some in the parent domain */
1212 *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1214 parent_domain = ldns_dname_left_chop(domain);
1215 while (parent_domain && /* Fail if we are at the root*/
1216 ldns_rdf_size(parent_domain) > 0) {
1218 if ((parent_keys =
1219 ldns_fetch_valid_domain_keys_time(res,
1220 parent_domain,
1221 keys,
1222 check_time,
1223 status))) {
1224 /* Check DS records */
1225 if ((ds_keys =
1226 ldns_validate_domain_ds_time(res,
1227 domain,
1228 parent_keys,
1229 check_time))) {
1230 trusted_keys =
1231 ldns_fetch_valid_domain_keys_time(
1232 res,
1233 domain,
1234 ds_keys,
1235 check_time,
1236 status);
1237 ldns_rr_list_deep_free(ds_keys);
1238 } else {
1239 /* No valid DS at the parent -- fail */
1240 *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DS ;
1242 ldns_rr_list_deep_free(parent_keys);
1243 break;
1244 } else {
1245 parent_domain = ldns_dname_left_chop((
1246 prev_parent_domain
1247 = parent_domain
1249 ldns_rdf_deep_free(prev_parent_domain);
1252 if (parent_domain) {
1253 ldns_rdf_deep_free(parent_domain);
1257 return trusted_keys;
1260 ldns_rr_list *
1261 ldns_fetch_valid_domain_keys(const ldns_resolver *res,
1262 const ldns_rdf *domain,
1263 const ldns_rr_list *keys,
1264 ldns_status *status)
1266 return ldns_fetch_valid_domain_keys_time(
1267 res, domain, keys, ldns_time(NULL), status);
1270 ldns_rr_list *
1271 ldns_validate_domain_dnskey_time(
1272 const ldns_resolver * res,
1273 const ldns_rdf * domain,
1274 const ldns_rr_list * keys,
1275 time_t check_time
1278 ldns_pkt * keypkt;
1279 ldns_rr * cur_key;
1280 uint16_t key_i; uint16_t key_j; uint16_t key_k;
1281 uint16_t sig_i; ldns_rr * cur_sig;
1283 ldns_rr_list * domain_keys = NULL;
1284 ldns_rr_list * domain_sigs = NULL;
1285 ldns_rr_list * trusted_keys = NULL;
1287 /* Fetch keys for the domain */
1288 keypkt = ldns_resolver_query(res, domain,
1289 LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, LDNS_RD);
1290 if (keypkt) {
1291 domain_keys = ldns_pkt_rr_list_by_type(keypkt,
1292 LDNS_RR_TYPE_DNSKEY,
1293 LDNS_SECTION_ANSWER);
1294 domain_sigs = ldns_pkt_rr_list_by_type(keypkt,
1295 LDNS_RR_TYPE_RRSIG,
1296 LDNS_SECTION_ANSWER);
1298 /* Try to validate the record using our keys */
1299 for (key_i=0; key_i< ldns_rr_list_rr_count(domain_keys); key_i++) {
1301 cur_key = ldns_rr_list_rr(domain_keys, key_i);
1302 for (key_j=0; key_j<ldns_rr_list_rr_count(keys); key_j++) {
1303 if (ldns_rr_compare_ds(ldns_rr_list_rr(keys, key_j),
1304 cur_key)) {
1306 /* Current key is trusted -- validate */
1307 trusted_keys = ldns_rr_list_new();
1309 for (sig_i=0;
1310 sig_i<ldns_rr_list_rr_count(domain_sigs);
1311 sig_i++) {
1312 cur_sig = ldns_rr_list_rr(domain_sigs, sig_i);
1313 /* Avoid non-matching sigs */
1314 if (ldns_rdf2native_int16(
1315 ldns_rr_rrsig_keytag(cur_sig))
1316 == ldns_calc_keytag(cur_key)) {
1317 if (ldns_verify_rrsig_time(
1318 domain_keys,
1319 cur_sig,
1320 cur_key,
1321 check_time)
1322 == LDNS_STATUS_OK) {
1324 /* Push the whole rrset
1325 -- we can't do much more */
1326 for (key_k=0;
1327 key_k<ldns_rr_list_rr_count(
1328 domain_keys);
1329 key_k++) {
1330 ldns_rr_list_push_rr(
1331 trusted_keys,
1332 ldns_rr_clone(
1333 ldns_rr_list_rr(
1334 domain_keys,
1335 key_k)));
1338 ldns_rr_list_deep_free(domain_keys);
1339 ldns_rr_list_deep_free(domain_sigs);
1340 ldns_pkt_free(keypkt);
1341 return trusted_keys;
1346 /* Only push our trusted key */
1347 ldns_rr_list_push_rr(trusted_keys,
1348 ldns_rr_clone(cur_key));
1353 ldns_rr_list_deep_free(domain_keys);
1354 ldns_rr_list_deep_free(domain_sigs);
1355 ldns_pkt_free(keypkt);
1357 } else {
1358 /* LDNS_STATUS_CRYPTO_NO_DNSKEY */
1361 return trusted_keys;
1364 ldns_rr_list *
1365 ldns_validate_domain_dnskey(const ldns_resolver * res,
1366 const ldns_rdf * domain,
1367 const ldns_rr_list * keys)
1369 return ldns_validate_domain_dnskey_time(
1370 res, domain, keys, ldns_time(NULL));
1373 ldns_rr_list *
1374 ldns_validate_domain_ds_time(
1375 const ldns_resolver *res,
1376 const ldns_rdf * domain,
1377 const ldns_rr_list * keys,
1378 time_t check_time)
1380 ldns_pkt * dspkt;
1381 uint16_t key_i;
1382 ldns_rr_list * rrset = NULL;
1383 ldns_rr_list * sigs = NULL;
1384 ldns_rr_list * trusted_keys = NULL;
1386 /* Fetch DS for the domain */
1387 dspkt = ldns_resolver_query(res, domain,
1388 LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN, LDNS_RD);
1389 if (dspkt) {
1390 rrset = ldns_pkt_rr_list_by_type(dspkt,
1391 LDNS_RR_TYPE_DS,
1392 LDNS_SECTION_ANSWER);
1393 sigs = ldns_pkt_rr_list_by_type(dspkt,
1394 LDNS_RR_TYPE_RRSIG,
1395 LDNS_SECTION_ANSWER);
1397 /* Validate sigs */
1398 if (ldns_verify_time(rrset, sigs, keys, check_time, NULL)
1399 == LDNS_STATUS_OK) {
1400 trusted_keys = ldns_rr_list_new();
1401 for (key_i=0; key_i<ldns_rr_list_rr_count(rrset); key_i++) {
1402 ldns_rr_list_push_rr(trusted_keys,
1403 ldns_rr_clone(ldns_rr_list_rr(rrset,
1404 key_i)
1410 ldns_rr_list_deep_free(rrset);
1411 ldns_rr_list_deep_free(sigs);
1412 ldns_pkt_free(dspkt);
1414 } else {
1415 /* LDNS_STATUS_CRYPTO_NO_DS */
1418 return trusted_keys;
1421 ldns_rr_list *
1422 ldns_validate_domain_ds(const ldns_resolver *res,
1423 const ldns_rdf * domain,
1424 const ldns_rr_list * keys)
1426 return ldns_validate_domain_ds_time(res, domain, keys, ldns_time(NULL));
1429 ldns_status
1430 ldns_verify_trusted_time(
1431 ldns_resolver *res,
1432 ldns_rr_list *rrset,
1433 ldns_rr_list * rrsigs,
1434 time_t check_time,
1435 ldns_rr_list * validating_keys
1438 uint16_t sig_i; uint16_t key_i;
1439 ldns_rr * cur_sig; ldns_rr * cur_key;
1440 ldns_rr_list * trusted_keys = NULL;
1441 ldns_status result = LDNS_STATUS_ERR;
1443 if (!res || !rrset || !rrsigs) {
1444 return LDNS_STATUS_ERR;
1447 if (ldns_rr_list_rr_count(rrset) < 1) {
1448 return LDNS_STATUS_ERR;
1451 if (ldns_rr_list_rr_count(rrsigs) < 1) {
1452 return LDNS_STATUS_CRYPTO_NO_RRSIG;
1455 /* Look at each sig */
1456 for (sig_i=0; sig_i < ldns_rr_list_rr_count(rrsigs); sig_i++) {
1458 cur_sig = ldns_rr_list_rr(rrsigs, sig_i);
1459 /* Get a valid signer key and validate the sig */
1460 if ((trusted_keys = ldns_fetch_valid_domain_keys_time(
1461 res,
1462 ldns_rr_rrsig_signame(cur_sig),
1463 ldns_resolver_dnssec_anchors(res),
1464 check_time,
1465 &result))) {
1467 for (key_i = 0;
1468 key_i < ldns_rr_list_rr_count(trusted_keys);
1469 key_i++) {
1470 cur_key = ldns_rr_list_rr(trusted_keys, key_i);
1472 if ((result = ldns_verify_rrsig_time(rrset,
1473 cur_sig,
1474 cur_key,
1475 check_time))
1476 == LDNS_STATUS_OK) {
1477 if (validating_keys) {
1478 ldns_rr_list_push_rr(validating_keys,
1479 ldns_rr_clone(cur_key));
1481 ldns_rr_list_deep_free(trusted_keys);
1482 return LDNS_STATUS_OK;
1488 ldns_rr_list_deep_free(trusted_keys);
1489 return result;
1492 ldns_status
1493 ldns_verify_trusted(
1494 ldns_resolver *res,
1495 ldns_rr_list *rrset,
1496 ldns_rr_list * rrsigs,
1497 ldns_rr_list * validating_keys)
1499 return ldns_verify_trusted_time(
1500 res, rrset, rrsigs, ldns_time(NULL), validating_keys);
1504 ldns_status
1505 ldns_dnssec_verify_denial(ldns_rr *rr,
1506 ldns_rr_list *nsecs,
1507 ldns_rr_list *rrsigs)
1509 ldns_rdf *rr_name;
1510 ldns_rdf *wildcard_name;
1511 ldns_rdf *chopped_dname;
1512 ldns_rr *cur_nsec;
1513 size_t i;
1514 ldns_status result;
1515 /* needed for wildcard check on exact match */
1516 ldns_rr *rrsig;
1517 bool name_covered = false;
1518 bool type_covered = false;
1519 bool wildcard_covered = false;
1520 bool wildcard_type_covered = false;
1522 wildcard_name = ldns_dname_new_frm_str("*");
1523 rr_name = ldns_rr_owner(rr);
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;
1531 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1532 cur_nsec = ldns_rr_list_rr(nsecs, i);
1533 if (ldns_dname_compare(rr_name, ldns_rr_owner(cur_nsec)) == 0) {
1534 /* see section 5.4 of RFC4035, if the label count of the NSEC's
1535 RRSIG is equal, then it is proven that wildcard expansion
1536 could not have been used to match the request */
1537 rrsig = ldns_dnssec_get_rrsig_for_name_and_type(
1538 ldns_rr_owner(cur_nsec),
1539 ldns_rr_get_type(cur_nsec),
1540 rrsigs);
1541 if (rrsig && ldns_rdf2native_int8(ldns_rr_rrsig_labels(rrsig))
1542 == ldns_dname_label_count(rr_name)) {
1543 wildcard_covered = true;
1546 if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
1547 ldns_rr_get_type(rr))) {
1548 type_covered = true;
1551 if (ldns_nsec_covers_name(cur_nsec, rr_name)) {
1552 name_covered = true;
1555 if (ldns_dname_compare(wildcard_name,
1556 ldns_rr_owner(cur_nsec)) == 0) {
1557 if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
1558 ldns_rr_get_type(rr))) {
1559 wildcard_type_covered = true;
1563 if (ldns_nsec_covers_name(cur_nsec, wildcard_name)) {
1564 wildcard_covered = true;
1569 ldns_rdf_deep_free(wildcard_name);
1571 if (type_covered || !name_covered) {
1572 return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1575 if (wildcard_type_covered || !wildcard_covered) {
1576 return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
1579 return LDNS_STATUS_OK;
1582 ldns_status
1583 ldns_dnssec_verify_denial_nsec3_match( ldns_rr *rr
1584 , ldns_rr_list *nsecs
1585 , ATTR_UNUSED(ldns_rr_list *rrsigs)
1586 , ldns_pkt_rcode packet_rcode
1587 , ldns_rr_type packet_qtype
1588 , bool packet_nodata
1589 , ldns_rr **match
1592 ldns_rdf *closest_encloser;
1593 ldns_rdf *wildcard;
1594 ldns_rdf *hashed_wildcard_name;
1595 bool wildcard_covered = false;
1596 ldns_rdf *zone_name;
1597 ldns_rdf *hashed_name;
1598 /* self assignment to suppress uninitialized warning */
1599 ldns_rdf *next_closer = NULL;
1600 ldns_rdf *hashed_next_closer;
1601 size_t i;
1602 ldns_status result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1604 if (match) {
1605 *match = NULL;
1608 zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
1610 /* section 8.4 */
1611 if (packet_rcode == LDNS_RCODE_NXDOMAIN) {
1612 closest_encloser = ldns_dnssec_nsec3_closest_encloser(
1613 ldns_rr_owner(rr),
1614 ldns_rr_get_type(rr),
1615 nsecs);
1616 if(!closest_encloser) {
1617 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1618 goto done;
1621 wildcard = ldns_dname_new_frm_str("*");
1622 (void) ldns_dname_cat(wildcard, closest_encloser);
1624 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1625 hashed_wildcard_name =
1626 ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
1627 wildcard
1629 (void) ldns_dname_cat(hashed_wildcard_name, zone_name);
1631 if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
1632 hashed_wildcard_name)) {
1633 wildcard_covered = true;
1634 if (match) {
1635 *match = ldns_rr_list_rr(nsecs, i);
1638 ldns_rdf_deep_free(hashed_wildcard_name);
1641 if (! wildcard_covered) {
1642 result = LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
1643 } else {
1644 result = LDNS_STATUS_OK;
1646 ldns_rdf_deep_free(closest_encloser);
1647 ldns_rdf_deep_free(wildcard);
1649 } else if (packet_nodata && packet_qtype != LDNS_RR_TYPE_DS) {
1650 /* section 8.5 */
1651 hashed_name = ldns_nsec3_hash_name_frm_nsec3(
1652 ldns_rr_list_rr(nsecs, 0),
1653 ldns_rr_owner(rr));
1654 (void) ldns_dname_cat(hashed_name, zone_name);
1655 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1656 if (ldns_dname_compare(hashed_name,
1657 ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
1658 == 0) {
1659 if (!ldns_nsec_bitmap_covers_type(
1660 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1661 packet_qtype)
1663 !ldns_nsec_bitmap_covers_type(
1664 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1665 LDNS_RR_TYPE_CNAME)) {
1666 result = LDNS_STATUS_OK;
1667 if (match) {
1668 *match = ldns_rr_list_rr(nsecs, i);
1670 goto done;
1674 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1675 /* wildcard no data? section 8.7 */
1676 closest_encloser = ldns_dnssec_nsec3_closest_encloser(
1677 ldns_rr_owner(rr),
1678 ldns_rr_get_type(rr),
1679 nsecs);
1680 if(!closest_encloser) {
1681 result = LDNS_STATUS_NSEC3_ERR;
1682 goto done;
1684 wildcard = ldns_dname_new_frm_str("*");
1685 (void) ldns_dname_cat(wildcard, closest_encloser);
1686 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1687 hashed_wildcard_name =
1688 ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
1689 wildcard);
1690 (void) ldns_dname_cat(hashed_wildcard_name, zone_name);
1692 if (ldns_dname_compare(hashed_wildcard_name,
1693 ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
1694 == 0) {
1695 if (!ldns_nsec_bitmap_covers_type(
1696 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1697 packet_qtype)
1699 !ldns_nsec_bitmap_covers_type(
1700 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1701 LDNS_RR_TYPE_CNAME)) {
1702 result = LDNS_STATUS_OK;
1703 if (match) {
1704 *match = ldns_rr_list_rr(nsecs, i);
1708 ldns_rdf_deep_free(hashed_wildcard_name);
1709 if (result == LDNS_STATUS_OK) {
1710 break;
1713 ldns_rdf_deep_free(closest_encloser);
1714 ldns_rdf_deep_free(wildcard);
1715 } else if (packet_nodata && packet_qtype == LDNS_RR_TYPE_DS) {
1716 /* section 8.6 */
1717 /* note: up to XXX this is the same as for 8.5 */
1718 hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs,
1720 ldns_rr_owner(rr)
1722 (void) ldns_dname_cat(hashed_name, zone_name);
1723 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1724 if (ldns_dname_compare(hashed_name,
1725 ldns_rr_owner(ldns_rr_list_rr(nsecs,
1726 i)))
1727 == 0) {
1728 if (!ldns_nsec_bitmap_covers_type(
1729 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1730 LDNS_RR_TYPE_DS)
1732 !ldns_nsec_bitmap_covers_type(
1733 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1734 LDNS_RR_TYPE_CNAME)) {
1735 result = LDNS_STATUS_OK;
1736 if (match) {
1737 *match = ldns_rr_list_rr(nsecs, i);
1739 goto done;
1744 /* XXX see note above */
1745 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1747 closest_encloser = ldns_dnssec_nsec3_closest_encloser(
1748 ldns_rr_owner(rr),
1749 ldns_rr_get_type(rr),
1750 nsecs);
1751 if(!closest_encloser) {
1752 result = LDNS_STATUS_NSEC3_ERR;
1753 goto done;
1755 /* Now check if we have a Opt-Out NSEC3 that covers the "next closer"*/
1757 if (ldns_dname_label_count(closest_encloser) + 1
1758 >= ldns_dname_label_count(ldns_rr_owner(rr))) {
1760 /* Query name *is* the "next closer". */
1761 hashed_next_closer = hashed_name;
1762 } else {
1764 /* "next closer" has less labels than the query name.
1765 * Create the name and hash it.
1767 next_closer = ldns_dname_clone_from(
1768 ldns_rr_owner(rr),
1769 ldns_dname_label_count(ldns_rr_owner(rr))
1770 - (ldns_dname_label_count(closest_encloser) + 1)
1772 hashed_next_closer = ldns_nsec3_hash_name_frm_nsec3(
1773 ldns_rr_list_rr(nsecs, 0),
1774 next_closer
1776 (void) ldns_dname_cat(hashed_next_closer, zone_name);
1778 /* Find the NSEC3 that covers the "next closer" */
1779 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1780 if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
1781 hashed_next_closer) &&
1782 ldns_nsec3_optout(ldns_rr_list_rr(nsecs, i))) {
1784 result = LDNS_STATUS_OK;
1785 if (match) {
1786 *match = ldns_rr_list_rr(nsecs, i);
1788 break;
1791 if (ldns_dname_label_count(closest_encloser) + 1
1792 < ldns_dname_label_count(ldns_rr_owner(rr))) {
1794 /* "next closer" has less labels than the query name.
1795 * Dispose of the temporary variables that held that name.
1797 ldns_rdf_deep_free(hashed_next_closer);
1798 ldns_rdf_deep_free(next_closer);
1800 ldns_rdf_deep_free(closest_encloser);
1803 done:
1804 ldns_rdf_deep_free(zone_name);
1805 return result;
1808 ldns_status
1809 ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
1810 ldns_rr_list *nsecs,
1811 ldns_rr_list *rrsigs,
1812 ldns_pkt_rcode packet_rcode,
1813 ldns_rr_type packet_qtype,
1814 bool packet_nodata)
1816 return ldns_dnssec_verify_denial_nsec3_match(
1817 rr, nsecs, rrsigs, packet_rcode,
1818 packet_qtype, packet_nodata, NULL
1822 #ifdef USE_GOST
1823 EVP_PKEY*
1824 ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
1826 /* prefix header for X509 encoding */
1827 uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
1828 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
1829 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
1830 0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
1831 unsigned char encoded[37+64];
1832 const unsigned char* pp;
1833 if(keylen != 64) {
1834 /* key wrong size */
1835 return NULL;
1838 /* create evp_key */
1839 memmove(encoded, asn, 37);
1840 memmove(encoded+37, key, 64);
1841 pp = (unsigned char*)&encoded[0];
1843 return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
1846 static ldns_status
1847 ldns_verify_rrsig_gost_raw(unsigned char* sig, size_t siglen,
1848 ldns_buffer* rrset, unsigned char* key, size_t keylen)
1850 EVP_PKEY *evp_key;
1851 ldns_status result;
1853 (void) ldns_key_EVP_load_gost_id();
1854 evp_key = ldns_gost2pkey_raw(key, keylen);
1855 if(!evp_key) {
1856 /* could not convert key */
1857 return LDNS_STATUS_CRYPTO_BOGUS;
1860 /* verify signature */
1861 result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset,
1862 evp_key, EVP_get_digestbyname("md_gost94"));
1863 EVP_PKEY_free(evp_key);
1865 return result;
1867 #endif
1869 #ifdef USE_ECDSA
1870 EVP_PKEY*
1871 ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
1873 unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
1874 const unsigned char* pp = buf;
1875 EVP_PKEY *evp_key;
1876 EC_KEY *ec;
1877 /* check length, which uncompressed must be 2 bignums */
1878 if(algo == LDNS_ECDSAP256SHA256) {
1879 if(keylen != 2*256/8) return NULL;
1880 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
1881 } else if(algo == LDNS_ECDSAP384SHA384) {
1882 if(keylen != 2*384/8) return NULL;
1883 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
1884 } else ec = NULL;
1885 if(!ec) return NULL;
1886 if(keylen+1 > sizeof(buf))
1887 return NULL; /* sanity check */
1888 /* prepend the 0x02 (from docs) (or actually 0x04 from implementation
1889 * of openssl) for uncompressed data */
1890 buf[0] = POINT_CONVERSION_UNCOMPRESSED;
1891 memmove(buf+1, key, keylen);
1892 if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
1893 EC_KEY_free(ec);
1894 return NULL;
1896 evp_key = EVP_PKEY_new();
1897 if(!evp_key) {
1898 EC_KEY_free(ec);
1899 return NULL;
1901 if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
1902 EVP_PKEY_free(evp_key);
1903 EC_KEY_free(ec);
1904 return NULL;
1906 return evp_key;
1909 static ldns_status
1910 ldns_verify_rrsig_ecdsa_raw(unsigned char* sig, size_t siglen,
1911 ldns_buffer* rrset, unsigned char* key, size_t keylen, uint8_t algo)
1913 EVP_PKEY *evp_key;
1914 ldns_status result;
1915 const EVP_MD *d;
1917 evp_key = ldns_ecdsa2pkey_raw(key, keylen, algo);
1918 if(!evp_key) {
1919 /* could not convert key */
1920 return LDNS_STATUS_CRYPTO_BOGUS;
1922 if(algo == LDNS_ECDSAP256SHA256)
1923 d = EVP_sha256();
1924 else d = EVP_sha384(); /* LDNS_ECDSAP384SHA384 */
1925 result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, d);
1926 EVP_PKEY_free(evp_key);
1927 return result;
1929 #endif
1931 ldns_status
1932 ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf,
1933 ldns_buffer *key_buf, uint8_t algo)
1935 return ldns_verify_rrsig_buffers_raw(
1936 (unsigned char*)ldns_buffer_begin(rawsig_buf),
1937 ldns_buffer_position(rawsig_buf),
1938 verify_buf,
1939 (unsigned char*)ldns_buffer_begin(key_buf),
1940 ldns_buffer_position(key_buf), algo);
1943 ldns_status
1944 ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
1945 ldns_buffer *verify_buf, unsigned char* key, size_t keylen,
1946 uint8_t algo)
1948 /* check for right key */
1949 switch(algo) {
1950 case LDNS_DSA:
1951 case LDNS_DSA_NSEC3:
1952 return ldns_verify_rrsig_dsa_raw(sig,
1953 siglen,
1954 verify_buf,
1955 key,
1956 keylen);
1957 break;
1958 case LDNS_RSASHA1:
1959 case LDNS_RSASHA1_NSEC3:
1960 return ldns_verify_rrsig_rsasha1_raw(sig,
1961 siglen,
1962 verify_buf,
1963 key,
1964 keylen);
1965 break;
1966 #ifdef USE_SHA2
1967 case LDNS_RSASHA256:
1968 return ldns_verify_rrsig_rsasha256_raw(sig,
1969 siglen,
1970 verify_buf,
1971 key,
1972 keylen);
1973 break;
1974 case LDNS_RSASHA512:
1975 return ldns_verify_rrsig_rsasha512_raw(sig,
1976 siglen,
1977 verify_buf,
1978 key,
1979 keylen);
1980 break;
1981 #endif
1982 #ifdef USE_GOST
1983 case LDNS_ECC_GOST:
1984 return ldns_verify_rrsig_gost_raw(sig, siglen, verify_buf,
1985 key, keylen);
1986 break;
1987 #endif
1988 #ifdef USE_ECDSA
1989 case LDNS_ECDSAP256SHA256:
1990 case LDNS_ECDSAP384SHA384:
1991 return ldns_verify_rrsig_ecdsa_raw(sig, siglen, verify_buf,
1992 key, keylen, algo);
1993 break;
1994 #endif
1995 case LDNS_RSAMD5:
1996 return ldns_verify_rrsig_rsamd5_raw(sig,
1997 siglen,
1998 verify_buf,
1999 key,
2000 keylen);
2001 break;
2002 default:
2003 /* do you know this alg?! */
2004 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2010 * Reset the ttl in the rrset with the orig_ttl from the sig
2011 * and update owner name if it was wildcard
2012 * Also canonicalizes the rrset.
2013 * @param rrset: rrset to modify
2014 * @param sig: signature to take TTL and wildcard values from
2016 static void
2017 ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
2019 uint32_t orig_ttl;
2020 uint16_t i;
2021 uint8_t label_count;
2022 ldns_rdf *wildcard_name;
2023 ldns_rdf *wildcard_chopped;
2024 ldns_rdf *wildcard_chopped_tmp;
2026 if ((rrsig == NULL) || ldns_rr_rd_count(rrsig) < 4) {
2027 return;
2030 orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
2031 label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
2033 for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
2034 if (label_count <
2035 ldns_dname_label_count(
2036 ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
2037 (void) ldns_str2rdf_dname(&wildcard_name, "*");
2038 wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(
2039 ldns_rr_list_rr(rrset_clone, i)));
2040 while (label_count < ldns_dname_label_count(wildcard_chopped)) {
2041 wildcard_chopped_tmp = ldns_dname_left_chop(
2042 wildcard_chopped);
2043 ldns_rdf_deep_free(wildcard_chopped);
2044 wildcard_chopped = wildcard_chopped_tmp;
2046 (void) ldns_dname_cat(wildcard_name, wildcard_chopped);
2047 ldns_rdf_deep_free(wildcard_chopped);
2048 ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(
2049 rrset_clone, i)));
2050 ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i),
2051 wildcard_name);
2053 ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl);
2054 /* convert to lowercase */
2055 ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
2060 * Make raw signature buffer out of rrsig
2061 * @param rawsig_buf: raw signature buffer for result
2062 * @param rrsig: signature to convert
2063 * @return OK or more specific error.
2065 static ldns_status
2066 ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
2068 uint8_t sig_algo;
2070 if (rrsig == NULL) {
2071 return LDNS_STATUS_CRYPTO_NO_RRSIG;
2073 if (ldns_rr_rdf(rrsig, 1) == NULL) {
2074 return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2076 sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
2077 /* check for known and implemented algo's now (otherwise
2078 * the function could return a wrong error
2080 /* create a buffer with signature rdata */
2081 /* for some algorithms we need other data than for others... */
2082 /* (the DSA API wants DER encoding for instance) */
2084 switch(sig_algo) {
2085 case LDNS_RSAMD5:
2086 case LDNS_RSASHA1:
2087 case LDNS_RSASHA1_NSEC3:
2088 #ifdef USE_SHA2
2089 case LDNS_RSASHA256:
2090 case LDNS_RSASHA512:
2091 #endif
2092 #ifdef USE_GOST
2093 case LDNS_ECC_GOST:
2094 #endif
2095 if (ldns_rr_rdf(rrsig, 8) == NULL) {
2096 return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2098 if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8))
2099 != LDNS_STATUS_OK) {
2100 return LDNS_STATUS_MEM_ERR;
2102 break;
2103 case LDNS_DSA:
2104 case LDNS_DSA_NSEC3:
2105 /* EVP takes rfc2459 format, which is a tad longer than dns format */
2106 if (ldns_rr_rdf(rrsig, 8) == NULL) {
2107 return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2109 if (ldns_convert_dsa_rrsig_rdf2asn1(
2110 rawsig_buf, ldns_rr_rdf(rrsig, 8))
2111 != LDNS_STATUS_OK) {
2113 if (ldns_rdf2buffer_wire(rawsig_buf,
2114 ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
2116 return LDNS_STATUS_MEM_ERR;
2118 break;
2119 #ifdef USE_ECDSA
2120 case LDNS_ECDSAP256SHA256:
2121 case LDNS_ECDSAP384SHA384:
2122 /* EVP produces an ASN prefix on the signature, which is
2123 * not used in the DNS */
2124 if (ldns_rr_rdf(rrsig, 8) == NULL) {
2125 return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2127 if (ldns_convert_ecdsa_rrsig_rdf2asn1(
2128 rawsig_buf, ldns_rr_rdf(rrsig, 8))
2129 != LDNS_STATUS_OK) {
2130 return LDNS_STATUS_MEM_ERR;
2132 break;
2133 #endif
2134 case LDNS_DH:
2135 case LDNS_ECC:
2136 case LDNS_INDIRECT:
2137 return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
2138 default:
2139 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2141 return LDNS_STATUS_OK;
2145 * Check RRSIG timestamps against the given 'now' time.
2146 * @param rrsig: signature to check.
2147 * @param now: the current time in seconds epoch.
2148 * @return status code LDNS_STATUS_OK if all is fine.
2150 static ldns_status
2151 ldns_rrsig_check_timestamps(ldns_rr* rrsig, time_t now)
2153 int32_t inception, expiration;
2155 /* check the signature time stamps */
2156 inception = (int32_t)ldns_rdf2native_time_t(
2157 ldns_rr_rrsig_inception(rrsig));
2158 expiration = (int32_t)ldns_rdf2native_time_t(
2159 ldns_rr_rrsig_expiration(rrsig));
2161 if (expiration - inception < 0) {
2162 /* bad sig, expiration before inception?? Tsssg */
2163 return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
2165 if (((int32_t) now) - inception < 0) {
2166 /* bad sig, inception date has not yet come to pass */
2167 return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
2169 if (expiration - ((int32_t) now) < 0) {
2170 /* bad sig, expiration date has passed */
2171 return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
2173 return LDNS_STATUS_OK;
2177 * Prepare for verification.
2178 * @param rawsig_buf: raw signature buffer made ready.
2179 * @param verify_buf: data for verification buffer made ready.
2180 * @param rrset_clone: made ready.
2181 * @param rrsig: signature to prepare for.
2182 * @return LDNS_STATUS_OK is all went well. Otherwise specific error.
2184 static ldns_status
2185 ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
2186 ldns_rr_list* rrset_clone, ldns_rr* rrsig)
2188 ldns_status result;
2190 /* canonicalize the sig */
2191 ldns_dname2canonical(ldns_rr_owner(rrsig));
2193 /* check if the typecovered is equal to the type checked */
2194 if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)) !=
2195 ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0)))
2196 return LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR;
2198 /* create a buffer with b64 signature rdata */
2199 result = ldns_rrsig2rawsig_buffer(rawsig_buf, rrsig);
2200 if(result != LDNS_STATUS_OK)
2201 return result;
2203 /* use TTL from signature. Use wildcard names for wildcards */
2204 /* also canonicalizes rrset_clone */
2205 ldns_rrset_use_signature_ttl(rrset_clone, rrsig);
2207 /* sort the rrset in canonical order */
2208 ldns_rr_list_sort(rrset_clone);
2210 /* put the signature rr (without the b64) to the verify_buf */
2211 if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK)
2212 return LDNS_STATUS_MEM_ERR;
2214 /* add the rrset in verify_buf */
2215 if(ldns_rr_list2buffer_wire(verify_buf, rrset_clone)
2216 != LDNS_STATUS_OK)
2217 return LDNS_STATUS_MEM_ERR;
2219 return LDNS_STATUS_OK;
2223 * Check if a key matches a signature.
2224 * Checks keytag, sigalgo and signature.
2225 * @param rawsig_buf: raw signature buffer for verify
2226 * @param verify_buf: raw data buffer for verify
2227 * @param rrsig: the rrsig
2228 * @param key: key to attempt.
2229 * @return LDNS_STATUS_OK if OK, else some specific error.
2231 static ldns_status
2232 ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
2233 ldns_rr* rrsig, ldns_rr* key)
2235 uint8_t sig_algo;
2237 if (rrsig == NULL) {
2238 return LDNS_STATUS_CRYPTO_NO_RRSIG;
2240 if (ldns_rr_rdf(rrsig, 1) == NULL) {
2241 return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2243 sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
2245 /* before anything, check if the keytags match */
2246 if (ldns_calc_keytag(key)
2248 ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
2250 ldns_buffer* key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2251 ldns_status result = LDNS_STATUS_ERR;
2253 /* put the key-data in a buffer, that's the third rdf, with
2254 * the base64 encoded key data */
2255 if (ldns_rr_rdf(key, 3) == NULL) {
2256 ldns_buffer_free(key_buf);
2257 return LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
2259 if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3))
2260 != LDNS_STATUS_OK) {
2261 ldns_buffer_free(key_buf);
2262 /* returning is bad might screw up
2263 good keys later in the list
2264 what to do? */
2265 return LDNS_STATUS_ERR;
2268 if (ldns_rr_rdf(key, 2) == NULL) {
2269 result = LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
2271 else if (sig_algo == ldns_rdf2native_int8(
2272 ldns_rr_rdf(key, 2))) {
2273 result = ldns_verify_rrsig_buffers(rawsig_buf,
2274 verify_buf, key_buf, sig_algo);
2275 } else {
2276 /* No keys with the corresponding algorithm are found */
2277 result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2280 ldns_buffer_free(key_buf);
2281 return result;
2283 else {
2284 /* No keys with the corresponding keytag are found */
2285 return LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2290 * to verify:
2291 * - create the wire fmt of the b64 key rdata
2292 * - create the wire fmt of the sorted rrset
2293 * - create the wire fmt of the b64 sig rdata
2294 * - create the wire fmt of the sig without the b64 rdata
2295 * - cat the sig data (without b64 rdata) to the rrset
2296 * - verify the rrset+sig, with the b64 data and the b64 key data
2298 ldns_status
2299 ldns_verify_rrsig_keylist_time(
2300 ldns_rr_list *rrset,
2301 ldns_rr *rrsig,
2302 const ldns_rr_list *keys,
2303 time_t check_time,
2304 ldns_rr_list *good_keys)
2306 ldns_status result;
2307 ldns_rr_list *valid = ldns_rr_list_new();
2308 if (!valid)
2309 return LDNS_STATUS_MEM_ERR;
2311 result = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, valid);
2312 if(result != LDNS_STATUS_OK) {
2313 ldns_rr_list_free(valid);
2314 return result;
2317 /* check timestamps last; its OK except time */
2318 result = ldns_rrsig_check_timestamps(rrsig, check_time);
2319 if(result != LDNS_STATUS_OK) {
2320 ldns_rr_list_free(valid);
2321 return result;
2324 ldns_rr_list_cat(good_keys, valid);
2325 ldns_rr_list_free(valid);
2326 return LDNS_STATUS_OK;
2330 * to verify:
2331 * - create the wire fmt of the b64 key rdata
2332 * - create the wire fmt of the sorted rrset
2333 * - create the wire fmt of the b64 sig rdata
2334 * - create the wire fmt of the sig without the b64 rdata
2335 * - cat the sig data (without b64 rdata) to the rrset
2336 * - verify the rrset+sig, with the b64 data and the b64 key data
2338 ldns_status
2339 ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
2340 ldns_rr *rrsig,
2341 const ldns_rr_list *keys,
2342 ldns_rr_list *good_keys)
2344 return ldns_verify_rrsig_keylist_time(
2345 rrset, rrsig, keys, ldns_time(NULL), good_keys);
2348 ldns_status
2349 ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset,
2350 ldns_rr *rrsig,
2351 const ldns_rr_list *keys,
2352 ldns_rr_list *good_keys)
2354 ldns_buffer *rawsig_buf;
2355 ldns_buffer *verify_buf;
2356 uint16_t i;
2357 ldns_status result, status;
2358 ldns_rr_list *rrset_clone;
2359 ldns_rr_list *validkeys;
2361 if (!rrset) {
2362 return LDNS_STATUS_ERR;
2365 validkeys = ldns_rr_list_new();
2366 if (!validkeys) {
2367 return LDNS_STATUS_MEM_ERR;
2370 /* clone the rrset so that we can fiddle with it */
2371 rrset_clone = ldns_rr_list_clone(rrset);
2373 /* create the buffers which will certainly hold the raw data */
2374 rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2375 verify_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2377 result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
2378 rrset_clone, rrsig);
2379 if(result != LDNS_STATUS_OK) {
2380 ldns_buffer_free(verify_buf);
2381 ldns_buffer_free(rawsig_buf);
2382 ldns_rr_list_deep_free(rrset_clone);
2383 ldns_rr_list_free(validkeys);
2384 return result;
2387 result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2388 for(i = 0; i < ldns_rr_list_rr_count(keys); i++) {
2389 status = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
2390 rrsig, ldns_rr_list_rr(keys, i));
2391 if (status == LDNS_STATUS_OK) {
2392 /* one of the keys has matched, don't break
2393 * here, instead put the 'winning' key in
2394 * the validkey list and return the list
2395 * later */
2396 if (!ldns_rr_list_push_rr(validkeys,
2397 ldns_rr_list_rr(keys,i))) {
2398 /* couldn't push the key?? */
2399 ldns_buffer_free(rawsig_buf);
2400 ldns_buffer_free(verify_buf);
2401 ldns_rr_list_deep_free(rrset_clone);
2402 ldns_rr_list_free(validkeys);
2403 return LDNS_STATUS_MEM_ERR;
2406 result = status;
2409 if (result == LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
2410 result = status;
2414 /* no longer needed */
2415 ldns_rr_list_deep_free(rrset_clone);
2416 ldns_buffer_free(rawsig_buf);
2417 ldns_buffer_free(verify_buf);
2419 if (ldns_rr_list_rr_count(validkeys) == 0) {
2420 /* no keys were added, return last error */
2421 ldns_rr_list_free(validkeys);
2422 return result;
2425 /* do not check timestamps */
2427 ldns_rr_list_cat(good_keys, validkeys);
2428 ldns_rr_list_free(validkeys);
2429 return LDNS_STATUS_OK;
2432 ldns_status
2433 ldns_verify_rrsig_time(
2434 ldns_rr_list *rrset,
2435 ldns_rr *rrsig,
2436 ldns_rr *key,
2437 time_t check_time)
2439 ldns_buffer *rawsig_buf;
2440 ldns_buffer *verify_buf;
2441 ldns_status result;
2442 ldns_rr_list *rrset_clone;
2444 if (!rrset) {
2445 return LDNS_STATUS_NO_DATA;
2447 /* clone the rrset so that we can fiddle with it */
2448 rrset_clone = ldns_rr_list_clone(rrset);
2449 /* create the buffers which will certainly hold the raw data */
2450 rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2451 verify_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2453 result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
2454 rrset_clone, rrsig);
2455 if(result != LDNS_STATUS_OK) {
2456 ldns_rr_list_deep_free(rrset_clone);
2457 ldns_buffer_free(rawsig_buf);
2458 ldns_buffer_free(verify_buf);
2459 return result;
2461 result = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
2462 rrsig, key);
2463 /* no longer needed */
2464 ldns_rr_list_deep_free(rrset_clone);
2465 ldns_buffer_free(rawsig_buf);
2466 ldns_buffer_free(verify_buf);
2468 /* check timestamp last, apart from time its OK */
2469 if(result == LDNS_STATUS_OK)
2470 result = ldns_rrsig_check_timestamps(rrsig, check_time);
2472 return result;
2475 ldns_status
2476 ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
2478 return ldns_verify_rrsig_time(rrset, rrsig, key, ldns_time(NULL));
2482 ldns_status
2483 ldns_verify_rrsig_evp(ldns_buffer *sig,
2484 ldns_buffer *rrset,
2485 EVP_PKEY *key,
2486 const EVP_MD *digest_type)
2488 return ldns_verify_rrsig_evp_raw(
2489 (unsigned char*)ldns_buffer_begin(sig),
2490 ldns_buffer_position(sig),
2491 rrset,
2492 key,
2493 digest_type);
2496 ldns_status
2497 ldns_verify_rrsig_evp_raw(unsigned char *sig, size_t siglen,
2498 ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
2500 EVP_MD_CTX ctx;
2501 int res;
2503 EVP_MD_CTX_init(&ctx);
2505 EVP_VerifyInit(&ctx, digest_type);
2506 EVP_VerifyUpdate(&ctx,
2507 ldns_buffer_begin(rrset),
2508 ldns_buffer_position(rrset));
2509 res = EVP_VerifyFinal(&ctx, sig, (unsigned int) siglen, key);
2511 EVP_MD_CTX_cleanup(&ctx);
2513 if (res == 1) {
2514 return LDNS_STATUS_OK;
2515 } else if (res == 0) {
2516 return LDNS_STATUS_CRYPTO_BOGUS;
2518 /* TODO how to communicate internal SSL error?
2519 let caller use ssl's get_error() */
2520 return LDNS_STATUS_SSL_ERR;
2523 ldns_status
2524 ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2526 return ldns_verify_rrsig_dsa_raw(
2527 (unsigned char*) ldns_buffer_begin(sig),
2528 ldns_buffer_position(sig),
2529 rrset,
2530 (unsigned char*) ldns_buffer_begin(key),
2531 ldns_buffer_position(key));
2534 ldns_status
2535 ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2537 return ldns_verify_rrsig_rsasha1_raw(
2538 (unsigned char*)ldns_buffer_begin(sig),
2539 ldns_buffer_position(sig),
2540 rrset,
2541 (unsigned char*) ldns_buffer_begin(key),
2542 ldns_buffer_position(key));
2545 ldns_status
2546 ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2548 return ldns_verify_rrsig_rsamd5_raw(
2549 (unsigned char*)ldns_buffer_begin(sig),
2550 ldns_buffer_position(sig),
2551 rrset,
2552 (unsigned char*) ldns_buffer_begin(key),
2553 ldns_buffer_position(key));
2556 ldns_status
2557 ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
2558 ldns_buffer* rrset, unsigned char* key, size_t keylen)
2560 EVP_PKEY *evp_key;
2561 ldns_status result;
2563 evp_key = EVP_PKEY_new();
2564 if (EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen))) {
2565 result = ldns_verify_rrsig_evp_raw(sig,
2566 siglen,
2567 rrset,
2568 evp_key,
2569 EVP_dss1());
2570 } else {
2571 result = LDNS_STATUS_SSL_ERR;
2573 EVP_PKEY_free(evp_key);
2574 return result;
2578 ldns_status
2579 ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen,
2580 ldns_buffer* rrset, unsigned char* key, size_t keylen)
2582 EVP_PKEY *evp_key;
2583 ldns_status result;
2585 evp_key = EVP_PKEY_new();
2586 if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2587 result = ldns_verify_rrsig_evp_raw(sig,
2588 siglen,
2589 rrset,
2590 evp_key,
2591 EVP_sha1());
2592 } else {
2593 result = LDNS_STATUS_SSL_ERR;
2595 EVP_PKEY_free(evp_key);
2597 return result;
2600 ldns_status
2601 ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
2602 size_t siglen,
2603 ldns_buffer* rrset,
2604 unsigned char* key,
2605 size_t keylen)
2607 #ifdef USE_SHA2
2608 EVP_PKEY *evp_key;
2609 ldns_status result;
2611 evp_key = EVP_PKEY_new();
2612 if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2613 result = ldns_verify_rrsig_evp_raw(sig,
2614 siglen,
2615 rrset,
2616 evp_key,
2617 EVP_sha256());
2618 } else {
2619 result = LDNS_STATUS_SSL_ERR;
2621 EVP_PKEY_free(evp_key);
2623 return result;
2624 #else
2625 /* touch these to prevent compiler warnings */
2626 (void) sig;
2627 (void) siglen;
2628 (void) rrset;
2629 (void) key;
2630 (void) keylen;
2631 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2632 #endif
2635 ldns_status
2636 ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
2637 size_t siglen,
2638 ldns_buffer* rrset,
2639 unsigned char* key,
2640 size_t keylen)
2642 #ifdef USE_SHA2
2643 EVP_PKEY *evp_key;
2644 ldns_status result;
2646 evp_key = EVP_PKEY_new();
2647 if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2648 result = ldns_verify_rrsig_evp_raw(sig,
2649 siglen,
2650 rrset,
2651 evp_key,
2652 EVP_sha512());
2653 } else {
2654 result = LDNS_STATUS_SSL_ERR;
2656 EVP_PKEY_free(evp_key);
2658 return result;
2659 #else
2660 /* touch these to prevent compiler warnings */
2661 (void) sig;
2662 (void) siglen;
2663 (void) rrset;
2664 (void) key;
2665 (void) keylen;
2666 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2667 #endif
2671 ldns_status
2672 ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
2673 size_t siglen,
2674 ldns_buffer* rrset,
2675 unsigned char* key,
2676 size_t keylen)
2678 EVP_PKEY *evp_key;
2679 ldns_status result;
2681 evp_key = EVP_PKEY_new();
2682 if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
2683 result = ldns_verify_rrsig_evp_raw(sig,
2684 siglen,
2685 rrset,
2686 evp_key,
2687 EVP_md5());
2688 } else {
2689 result = LDNS_STATUS_SSL_ERR;
2691 EVP_PKEY_free(evp_key);
2693 return result;
2696 #endif