sbin/hammer2/cmd_debug.c: Clear errno
[dragonfly.git] / contrib / ldns / dnssec_verify.c
blobd76f32eba71a65e40a67d7ee0fdb6a40236e28c7
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(void)
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 initializes 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 static ldns_dnssec_data_chain *
220 ldns_dnssec_build_data_chain_nokeyname(ldns_resolver *res,
221 uint16_t qflags,
222 ldns_rr *orig_rr,
223 const ldns_rr_list *rrset,
224 ldns_dnssec_data_chain *new_chain)
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 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,
429 } else {
430 ldns_dnssec_build_data_chain_other(res,
431 qflags,
432 new_chain,
433 key_name,
438 if (signatures) {
439 ldns_rr_list_deep_free(signatures);
441 return new_chain;
444 ldns_dnssec_trust_tree *
445 ldns_dnssec_trust_tree_new(void)
447 ldns_dnssec_trust_tree *new_tree = LDNS_XMALLOC(ldns_dnssec_trust_tree,
449 if(!new_tree) return NULL;
450 new_tree->rr = NULL;
451 new_tree->rrset = NULL;
452 new_tree->parent_count = 0;
454 return new_tree;
457 void
458 ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree)
460 size_t i;
461 if (tree) {
462 for (i = 0; i < tree->parent_count; i++) {
463 ldns_dnssec_trust_tree_free(tree->parents[i]);
466 LDNS_FREE(tree);
469 size_t
470 ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree)
472 size_t result = 0;
473 size_t parent = 0;
474 size_t i;
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;
482 return 1 + result;
485 /* TODO ldns_ */
486 static void
487 print_tabs(FILE *out, size_t nr, uint8_t *map, size_t treedepth)
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, " ");
501 static void
502 ldns_dnssec_trust_tree_print_sm_fmt(FILE *out,
503 const ldns_output_format *fmt,
504 ldns_dnssec_trust_tree *tree,
505 size_t tabs,
506 bool extended,
507 uint8_t *sibmap,
508 size_t treedepth)
510 size_t i;
511 const ldns_rr_descriptor *descriptor;
512 bool mapset = false;
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;
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));
529 if (descriptor->_name) {
530 fprintf(out, " (%s", descriptor->_name);
531 } else {
532 fprintf(out, " (TYPE%d",
533 ldns_rr_get_type(tree->rr));
535 if (tabs > 0) {
536 if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DNSKEY) {
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));
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));
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;
564 /* only print errors */
565 if (ldns_rr_get_type(tree->parents[i]->rr) ==
566 LDNS_RR_TYPE_NSEC ||
567 ldns_rr_get_type(tree->parents[i]->rr) ==
568 LDNS_RR_TYPE_NSEC3) {
569 if (tree->parent_status[i] == LDNS_STATUS_OK) {
570 print_tabs(out, tabs + 1, sibmap, treedepth);
571 if (tabs == 0 &&
572 ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS &&
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");
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",
586 ldns_get_errorstr_by_id(
587 tree->parent_status[i]));
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",
595 ldns_get_errorstr_by_id(
596 tree->parent_status[i]));
597 if (tree->parent_status[i]
598 == LDNS_STATUS_SSL_ERR) {
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");
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);
616 ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
617 tree->parents[i],
618 tabs+1,
619 extended,
620 sibmap,
621 treedepth);
623 } else {
624 print_tabs(out, tabs, sibmap, treedepth);
625 fprintf(out, "<no data>\n");
627 } else {
628 fprintf(out, "<null pointer>\n");
631 if (mapset) {
632 LDNS_FREE(sibmap);
636 void
637 ldns_dnssec_trust_tree_print_fmt(FILE *out, const ldns_output_format *fmt,
638 ldns_dnssec_trust_tree *tree,
639 size_t tabs,
640 bool extended)
642 ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
643 tree, tabs, extended, NULL, 0);
646 void
647 ldns_dnssec_trust_tree_print(FILE *out,
648 ldns_dnssec_trust_tree *tree,
649 size_t tabs,
650 bool extended)
652 ldns_dnssec_trust_tree_print_fmt(out, ldns_output_format_default,
653 tree, tabs, extended);
657 ldns_status
658 ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree,
659 const ldns_dnssec_trust_tree *parent,
660 const ldns_rr *signature,
661 const ldns_status parent_status)
663 if (tree
664 && parent
665 && tree->parent_count < LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS) {
667 printf("Add parent for: ");
668 ldns_rr_print(stdout, tree->rr);
669 printf("parent: ");
670 ldns_rr_print(stdout, parent->rr);
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;
683 /* if rr is null, take the first from the rrset */
684 ldns_dnssec_trust_tree *
685 ldns_dnssec_derive_trust_tree_time(
686 ldns_dnssec_data_chain *data_chain,
687 ldns_rr *rr,
688 time_t check_time
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;
697 ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new();
698 if(!new_tree)
699 return NULL;
701 if (data_chain && data_chain->rrset) {
702 cur_rrset = data_chain->rrset;
704 cur_sigs = data_chain->signatures;
706 if (rr) {
707 cur_rr = rr;
710 if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) {
711 cur_rr = ldns_rr_list_rr(cur_rrset, 0);
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)
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);
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)))
734 /* find first that does match */
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);
743 if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
744 ldns_rr_owner(cur_rr)))
746 break;
751 /* option 1 */
752 if (data_chain->parent) {
753 ldns_dnssec_derive_trust_tree_normal_rrset_time(
754 new_tree,
755 data_chain,
756 cur_sig_rr,
757 check_time);
760 /* option 2 */
761 ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
762 new_tree,
763 data_chain,
764 cur_rr,
765 cur_sig_rr,
766 check_time);
769 ldns_dnssec_derive_trust_tree_ds_rrset_time(
770 new_tree, data_chain,
771 cur_rr, check_time);
772 } else {
773 /* no signatures? maybe it's nsec data */
775 /* just add every rr from parent as new parent */
776 ldns_dnssec_derive_trust_tree_no_sig_time(
777 new_tree, data_chain, check_time);
782 return new_tree;
785 ldns_dnssec_trust_tree *
786 ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr)
788 return ldns_dnssec_derive_trust_tree_time(data_chain, rr, ldns_time(NULL));
791 void
792 ldns_dnssec_derive_trust_tree_normal_rrset_time(
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)
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;
806 cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
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) {
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))
817 == LDNS_RR_TYPE_NSEC ||
818 ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
819 == LDNS_RR_TYPE_NSEC3) {
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);
826 /* with nsecs, this might be the wrong one */
827 while (tmp_rrset &&
828 ldns_rr_list_rr_count(cur_rrset) > 0 &&
829 ldns_dname_compare(
830 ldns_rr_owner(ldns_rr_list_rr(
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);
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
845 ldns_rr_list_deep_free(
846 tmp_rrset);
847 tmp_rrset = NULL;
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;
856 cur_parent_tree =
857 ldns_dnssec_derive_trust_tree_time(
858 data_chain->parent,
859 cur_parent_rr,
860 check_time);
861 (void)ldns_dnssec_trust_tree_add_parent(new_tree,
862 cur_parent_tree,
863 cur_sig_rr,
864 cur_status);
869 done:
870 ldns_rr_list_deep_free(cur_rrset);
873 void
874 ldns_dnssec_derive_trust_tree_normal_rrset(ldns_dnssec_trust_tree *new_tree,
875 ldns_dnssec_data_chain *data_chain,
876 ldns_rr *cur_sig_rr)
878 ldns_dnssec_derive_trust_tree_normal_rrset_time(
879 new_tree, data_chain, cur_sig_rr, ldns_time(NULL));
882 void
883 ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
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)
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;
897 cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
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
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);
911 if (ldns_dnssec_trust_tree_add_parent(new_tree,
912 cur_parent_tree, cur_sig_rr, cur_status))
913 ldns_dnssec_trust_tree_free(cur_parent_tree);
919 void
920 ldns_dnssec_derive_trust_tree_dnskey_rrset(ldns_dnssec_trust_tree *new_tree,
921 ldns_dnssec_data_chain *data_chain,
922 ldns_rr *cur_rr,
923 ldns_rr *cur_sig_rr)
925 ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
926 new_tree, data_chain, cur_rr, cur_sig_rr, ldns_time(NULL));
929 void
930 ldns_dnssec_derive_trust_tree_ds_rrset_time(
931 ldns_dnssec_trust_tree *new_tree,
932 ldns_dnssec_data_chain *data_chain,
933 ldns_rr *cur_rr,
934 time_t check_time)
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;
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
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 =
955 ldns_dnssec_derive_trust_tree_time(
956 data_chain->parent,
957 cur_parent_rr,
958 check_time);
959 (void) ldns_dnssec_trust_tree_add_parent(
960 new_tree,
961 cur_parent_tree,
962 NULL,
963 LDNS_STATUS_OK);
964 } else {
965 /*ldns_rr_print(stdout, cur_parent_rr);*/
973 void
974 ldns_dnssec_derive_trust_tree_ds_rrset(ldns_dnssec_trust_tree *new_tree,
975 ldns_dnssec_data_chain *data_chain,
976 ldns_rr *cur_rr)
978 ldns_dnssec_derive_trust_tree_ds_rrset_time(
979 new_tree, data_chain, cur_rr, ldns_time(NULL));
982 void
983 ldns_dnssec_derive_trust_tree_no_sig_time(
984 ldns_dnssec_trust_tree *new_tree,
985 ldns_dnssec_data_chain *data_chain,
986 time_t check_time)
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;
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)) ==
999 LDNS_RR_TYPE_NSEC3) {
1000 result = ldns_dnssec_verify_denial_nsec3(
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)) ==
1008 LDNS_RR_TYPE_NSEC) {
1009 result = ldns_dnssec_verify_denial(
1010 new_tree->rr,
1011 cur_rrset,
1012 data_chain->parent->signatures);
1013 } else {
1014 /* unsigned zone, unsigned parent */
1015 result = LDNS_STATUS_OK;
1017 } else {
1018 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
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 =
1023 ldns_dnssec_derive_trust_tree_time(
1024 data_chain->parent,
1025 cur_parent_rr,
1026 check_time);
1027 if (ldns_dnssec_trust_tree_add_parent(new_tree,
1028 cur_parent_tree, NULL, result))
1029 ldns_dnssec_trust_tree_free(cur_parent_tree);
1035 void
1036 ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree *new_tree,
1037 ldns_dnssec_data_chain *data_chain)
1039 ldns_dnssec_derive_trust_tree_no_sig_time(
1040 new_tree, data_chain, ldns_time(NULL));
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
1048 ldns_status
1049 ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree,
1050 ldns_rr_list *trusted_keys)
1052 size_t i;
1053 ldns_status result = LDNS_STATUS_CRYPTO_NO_DNSKEY;
1054 bool equal;
1055 ldns_status parent_result;
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;
1069 for (i = 0; i < tree->parent_count; i++) {
1070 parent_result =
1071 ldns_dnssec_trust_tree_contains_keys(tree->parents[i],
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
1082 result =
1083 LDNS_STATUS_DNSSEC_EXISTENCE_DENIED;
1084 } else {
1085 result = parent_result;
1090 } else {
1091 result = LDNS_STATUS_ERR;
1094 return result;
1097 ldns_status
1098 ldns_verify_time(
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
1106 uint16_t i;
1107 ldns_status verify_result = LDNS_STATUS_ERR;
1109 if (!rrset || !rrsig || !keys) {
1110 return LDNS_STATUS_ERR;
1113 if (ldns_rr_list_rr_count(rrset) < 1) {
1114 return LDNS_STATUS_ERR;
1117 if (ldns_rr_list_rr_count(rrsig) < 1) {
1118 return LDNS_STATUS_CRYPTO_NO_RRSIG;
1121 if (ldns_rr_list_rr_count(keys) < 1) {
1122 verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1123 } else {
1124 for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1125 ldns_status s = ldns_verify_rrsig_keylist_time(
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 ==
1134 LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY)
1135 verify_result = s;
1138 return verify_result;
1141 ldns_status
1142 ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys,
1143 ldns_rr_list *good_keys)
1145 return ldns_verify_time(rrset, rrsig, keys, ldns_time(NULL), good_keys);
1148 ldns_status
1149 ldns_verify_notime(ldns_rr_list *rrset, ldns_rr_list *rrsig,
1150 const ldns_rr_list *keys, ldns_rr_list *good_keys)
1152 uint16_t i;
1153 ldns_status verify_result = LDNS_STATUS_ERR;
1155 if (!rrset || !rrsig || !keys) {
1156 return LDNS_STATUS_ERR;
1159 if (ldns_rr_list_rr_count(rrset) < 1) {
1160 return LDNS_STATUS_ERR;
1163 if (ldns_rr_list_rr_count(rrsig) < 1) {
1164 return LDNS_STATUS_CRYPTO_NO_RRSIG;
1167 if (ldns_rr_list_rr_count(keys) < 1) {
1168 verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1169 } else {
1170 for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1171 ldns_status s = ldns_verify_rrsig_keylist_notime(rrset,
1172 ldns_rr_list_rr(rrsig, i), keys, good_keys);
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 ==
1180 LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
1181 verify_result = s;
1185 return verify_result;
1188 ldns_rr_list *
1189 ldns_fetch_valid_domain_keys_time(const ldns_resolver *res,
1190 const ldns_rdf *domain,
1191 const ldns_rr_list *keys,
1192 time_t check_time,
1193 ldns_status *status)
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;
1201 if (res && domain && keys) {
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 */
1208 *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
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) {
1214 if ((parent_keys =
1215 ldns_fetch_valid_domain_keys_time(res,
1216 parent_domain,
1217 keys,
1218 check_time,
1219 status))) {
1220 /* Check DS records */
1221 if ((ds_keys =
1222 ldns_validate_domain_ds_time(res,
1223 domain,
1224 parent_keys,
1225 check_time))) {
1226 trusted_keys =
1227 ldns_fetch_valid_domain_keys_time(
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 */
1236 *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DS ;
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
1245 ldns_rdf_deep_free(prev_parent_domain);
1248 if (parent_domain) {
1249 ldns_rdf_deep_free(parent_domain);
1253 return trusted_keys;
1256 ldns_rr_list *
1257 ldns_fetch_valid_domain_keys(const ldns_resolver *res,
1258 const ldns_rdf *domain,
1259 const ldns_rr_list *keys,
1260 ldns_status *status)
1262 return ldns_fetch_valid_domain_keys_time(
1263 res, domain, keys, ldns_time(NULL), status);
1266 ldns_rr_list *
1267 ldns_validate_domain_dnskey_time(
1268 const ldns_resolver * res,
1269 const ldns_rdf * domain,
1270 const ldns_rr_list * keys,
1271 time_t check_time
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;
1279 ldns_rr_list * domain_keys = NULL;
1280 ldns_rr_list * domain_sigs = NULL;
1281 ldns_rr_list * trusted_keys = NULL;
1283 /* Fetch keys for the domain */
1284 keypkt = ldns_resolver_query(res, domain,
1285 LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, LDNS_RD);
1286 if (keypkt) {
1287 domain_keys = ldns_pkt_rr_list_by_type(keypkt,
1288 LDNS_RR_TYPE_DNSKEY,
1289 LDNS_SECTION_ANSWER);
1290 domain_sigs = ldns_pkt_rr_list_by_type(keypkt,
1291 LDNS_RR_TYPE_RRSIG,
1292 LDNS_SECTION_ANSWER);
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++) {
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)) {
1302 /* Current key is trusted -- validate */
1303 trusted_keys = ldns_rr_list_new();
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 */
1310 if (ldns_rdf2native_int16(
1311 ldns_rr_rrsig_keytag(cur_sig))
1312 == ldns_calc_keytag(cur_key)) {
1313 if (ldns_verify_rrsig_time(
1314 domain_keys,
1315 cur_sig,
1316 cur_key,
1317 check_time)
1318 == LDNS_STATUS_OK) {
1320 /* Push the whole rrset
1321 -- we can't do much more */
1322 for (key_k=0;
1323 key_k<ldns_rr_list_rr_count(
1324 domain_keys);
1325 key_k++) {
1326 ldns_rr_list_push_rr(
1327 trusted_keys,
1328 ldns_rr_clone(
1329 ldns_rr_list_rr(
1330 domain_keys,
1331 key_k)));
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;
1342 /* Only push our trusted key */
1343 ldns_rr_list_push_rr(trusted_keys,
1344 ldns_rr_clone(cur_key));
1349 ldns_rr_list_deep_free(domain_keys);
1350 ldns_rr_list_deep_free(domain_sigs);
1351 ldns_pkt_free(keypkt);
1353 } else {
1354 /* LDNS_STATUS_CRYPTO_NO_DNSKEY */
1357 return trusted_keys;
1360 ldns_rr_list *
1361 ldns_validate_domain_dnskey(const ldns_resolver * res,
1362 const ldns_rdf * domain,
1363 const ldns_rr_list * keys)
1365 return ldns_validate_domain_dnskey_time(
1366 res, domain, keys, ldns_time(NULL));
1369 ldns_rr_list *
1370 ldns_validate_domain_ds_time(
1371 const ldns_resolver *res,
1372 const ldns_rdf * domain,
1373 const ldns_rr_list * keys,
1374 time_t check_time)
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;
1382 /* Fetch DS for the domain */
1383 dspkt = ldns_resolver_query(res, domain,
1384 LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN, LDNS_RD);
1385 if (dspkt) {
1386 rrset = ldns_pkt_rr_list_by_type(dspkt,
1387 LDNS_RR_TYPE_DS,
1388 LDNS_SECTION_ANSWER);
1389 sigs = ldns_pkt_rr_list_by_type(dspkt,
1390 LDNS_RR_TYPE_RRSIG,
1391 LDNS_SECTION_ANSWER);
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,
1399 ldns_rr_clone(ldns_rr_list_rr(rrset,
1400 key_i)
1406 ldns_rr_list_deep_free(rrset);
1407 ldns_rr_list_deep_free(sigs);
1408 ldns_pkt_free(dspkt);
1410 } else {
1411 /* LDNS_STATUS_CRYPTO_NO_DS */
1414 return trusted_keys;
1417 ldns_rr_list *
1418 ldns_validate_domain_ds(const ldns_resolver *res,
1419 const ldns_rdf * domain,
1420 const ldns_rr_list * keys)
1422 return ldns_validate_domain_ds_time(res, domain, keys, ldns_time(NULL));
1425 ldns_status
1426 ldns_verify_trusted_time(
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
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;
1437 ldns_status result = LDNS_STATUS_ERR;
1439 if (!res || !rrset || !rrsigs) {
1440 return LDNS_STATUS_ERR;
1443 if (ldns_rr_list_rr_count(rrset) < 1) {
1444 return LDNS_STATUS_ERR;
1447 if (ldns_rr_list_rr_count(rrsigs) < 1) {
1448 return LDNS_STATUS_CRYPTO_NO_RRSIG;
1451 /* Look at each sig */
1452 for (sig_i=0; sig_i < ldns_rr_list_rr_count(rrsigs); sig_i++) {
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),
1459 ldns_resolver_dnssec_anchors(res),
1460 check_time,
1461 &result))) {
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);
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));
1477 ldns_rr_list_deep_free(trusted_keys);
1478 return LDNS_STATUS_OK;
1484 ldns_rr_list_deep_free(trusted_keys);
1485 return result;
1488 ldns_status
1489 ldns_verify_trusted(
1490 ldns_resolver *res,
1491 ldns_rr_list *rrset,
1492 ldns_rr_list * rrsigs,
1493 ldns_rr_list * validating_keys)
1495 return ldns_verify_trusted_time(
1496 res, rrset, rrsigs, ldns_time(NULL), validating_keys);
1500 ldns_status
1501 ldns_dnssec_verify_denial(ldns_rr *rr,
1502 ldns_rr_list *nsecs,
1503 ldns_rr_list *rrsigs)
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;
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;
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 */
1538 rrsig = ldns_dnssec_get_rrsig_for_name_and_type(
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;
1547 if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
1548 ldns_rr_get_type(rr))) {
1549 type_covered = true;
1552 if (ldns_nsec_covers_name(cur_nsec, rr_name)) {
1553 name_covered = true;
1556 if (rr_name_is_root)
1557 continue;
1559 if (ldns_dname_compare(wildcard_name,
1560 ldns_rr_owner(cur_nsec)) == 0) {
1561 if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
1562 ldns_rr_get_type(rr))) {
1563 wildcard_type_covered = true;
1567 if (ldns_nsec_covers_name(cur_nsec, wildcard_name)) {
1568 wildcard_covered = true;
1573 ldns_rdf_deep_free(wildcard_name);
1575 if (type_covered || !name_covered) {
1576 return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1579 if (rr_name_is_root)
1580 return LDNS_STATUS_OK;
1582 if (wildcard_type_covered || !wildcard_covered) {
1583 return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
1586 return LDNS_STATUS_OK;
1589 ldns_status
1590 ldns_dnssec_verify_denial_nsec3_match( ldns_rr *rr
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
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;
1607 ldns_status result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1609 if (match) {
1610 *match = NULL;
1613 zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
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) {
1622 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1623 goto done;
1626 wildcard = ldns_dname_new_frm_str("*");
1627 (void) ldns_dname_cat(wildcard, closest_encloser);
1629 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1630 hashed_wildcard_name =
1631 ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
1632 wildcard
1634 (void) ldns_dname_cat(hashed_wildcard_name, zone_name);
1636 if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
1637 hashed_wildcard_name)) {
1638 wildcard_covered = true;
1639 if (match) {
1640 *match = ldns_rr_list_rr(nsecs, i);
1643 ldns_rdf_deep_free(hashed_wildcard_name);
1646 if (! wildcard_covered) {
1647 result = LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
1648 } else {
1649 result = LDNS_STATUS_OK;
1651 ldns_rdf_deep_free(closest_encloser);
1652 ldns_rdf_deep_free(wildcard);
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) {
1664 if (!ldns_nsec_bitmap_covers_type(
1665 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1666 packet_qtype)
1668 !ldns_nsec_bitmap_covers_type(
1669 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1670 LDNS_RR_TYPE_CNAME)) {
1671 result = LDNS_STATUS_OK;
1672 if (match) {
1673 *match = ldns_rr_list_rr(nsecs, i);
1675 goto done;
1679 ldns_rdf_deep_free(hashed_name);
1680 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
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;
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 =
1694 ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
1695 wildcard);
1696 (void) ldns_dname_cat(hashed_wildcard_name, zone_name);
1698 if (ldns_dname_compare(hashed_wildcard_name,
1699 ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
1700 == 0) {
1701 if (!ldns_nsec_bitmap_covers_type(
1702 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1703 packet_qtype)
1705 !ldns_nsec_bitmap_covers_type(
1706 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1707 LDNS_RR_TYPE_CNAME)) {
1708 result = LDNS_STATUS_OK;
1709 if (match) {
1710 *match = ldns_rr_list_rr(nsecs, i);
1714 ldns_rdf_deep_free(hashed_wildcard_name);
1715 if (result == LDNS_STATUS_OK) {
1716 break;
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 */
1724 hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs,
1726 ldns_rr_owner(rr)
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,
1731 ldns_rr_owner(ldns_rr_list_rr(nsecs,
1732 i)))
1733 == 0) {
1734 if (!ldns_nsec_bitmap_covers_type(
1735 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1736 LDNS_RR_TYPE_DS)
1738 !ldns_nsec_bitmap_covers_type(
1739 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1740 LDNS_RR_TYPE_CNAME)) {
1741 result = LDNS_STATUS_OK;
1742 if (match) {
1743 *match = ldns_rr_list_rr(nsecs, i);
1745 goto done;
1750 /* XXX see note above */
1751 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
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;
1761 /* Now check if we have a Opt-Out NSEC3 that covers the "next closer"*/
1763 if (ldns_dname_label_count(closest_encloser) + 1
1764 >= ldns_dname_label_count(ldns_rr_owner(rr))) {
1766 /* Query name *is* the "next closer". */
1767 hashed_next_closer = hashed_name;
1768 } else {
1769 ldns_rdf *next_closer;
1771 ldns_rdf_deep_free(hashed_name);
1772 /* "next closer" has less labels than the query name.
1773 * Create the name and hash it.
1775 next_closer = ldns_dname_clone_from(
1776 ldns_rr_owner(rr),
1777 ldns_dname_label_count(ldns_rr_owner(rr))
1778 - (ldns_dname_label_count(closest_encloser) + 1)
1780 hashed_next_closer = ldns_nsec3_hash_name_frm_nsec3(
1781 ldns_rr_list_rr(nsecs, 0),
1782 next_closer
1784 (void) ldns_dname_cat(hashed_next_closer, zone_name);
1785 ldns_rdf_deep_free(next_closer);
1787 /* Find the NSEC3 that covers the "next closer" */
1788 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1789 if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
1790 hashed_next_closer) &&
1791 ldns_nsec3_optout(ldns_rr_list_rr(nsecs, i))) {
1793 result = LDNS_STATUS_OK;
1794 if (match) {
1795 *match = ldns_rr_list_rr(nsecs, i);
1797 break;
1800 ldns_rdf_deep_free(hashed_next_closer);
1801 ldns_rdf_deep_free(closest_encloser);
1804 done:
1805 ldns_rdf_deep_free(zone_name);
1806 return result;
1809 ldns_status
1810 ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
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)
1817 return ldns_dnssec_verify_denial_nsec3_match(
1818 rr, nsecs, rrsigs, packet_rcode,
1819 packet_qtype, packet_nodata, NULL
1823 #ifdef USE_GOST
1824 EVP_PKEY*
1825 ldns_gost2pkey_raw(const unsigned char* key, size_t keylen)
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;
1839 /* create evp_key */
1840 memmove(encoded, asn, 37);
1841 memmove(encoded+37, key, 64);
1842 pp = (unsigned char*)&encoded[0];
1844 return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
1847 static ldns_status
1848 ldns_verify_rrsig_gost_raw(const unsigned char* sig, size_t siglen,
1849 const ldns_buffer* rrset, const unsigned char* key, size_t keylen)
1851 EVP_PKEY *evp_key;
1852 ldns_status result;
1854 (void) ldns_key_EVP_load_gost_id();
1855 evp_key = ldns_gost2pkey_raw(key, keylen);
1856 if(!evp_key) {
1857 /* could not convert key */
1858 return LDNS_STATUS_CRYPTO_BOGUS;
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);
1866 return result;
1868 #endif
1870 #ifdef USE_ED25519
1871 EVP_PKEY*
1872 ldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
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;
1890 static ldns_status
1891 ldns_verify_rrsig_ed25519_raw(unsigned char* sig, size_t siglen,
1892 ldns_buffer* rrset, unsigned char* key, size_t keylen)
1894 EVP_PKEY *evp_key;
1895 ldns_status result;
1897 evp_key = ldns_ed255192pkey_raw(key, keylen);
1898 if(!evp_key) {
1899 /* could not convert key */
1900 return LDNS_STATUS_CRYPTO_BOGUS;
1902 result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, NULL);
1903 EVP_PKEY_free(evp_key);
1904 return result;
1906 #endif /* USE_ED25519 */
1908 #ifdef USE_ED448
1909 EVP_PKEY*
1910 ldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
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;
1928 static ldns_status
1929 ldns_verify_rrsig_ed448_raw(unsigned char* sig, size_t siglen,
1930 ldns_buffer* rrset, unsigned char* key, size_t keylen)
1932 EVP_PKEY *evp_key;
1933 ldns_status result;
1935 evp_key = ldns_ed4482pkey_raw(key, keylen);
1936 if(!evp_key) {
1937 /* could not convert key */
1938 return LDNS_STATUS_CRYPTO_BOGUS;
1940 result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, NULL);
1941 EVP_PKEY_free(evp_key);
1942 return result;
1944 #endif /* USE_ED448 */
1946 #ifdef USE_ECDSA
1947 EVP_PKEY*
1948 ldns_ecdsa2pkey_raw(const unsigned char* key, size_t keylen, uint8_t algo)
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;
1973 evp_key = EVP_PKEY_new();
1974 if(!evp_key) {
1975 EC_KEY_free(ec);
1976 return NULL;
1978 if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
1979 EVP_PKEY_free(evp_key);
1980 EC_KEY_free(ec);
1981 return NULL;
1983 return evp_key;
1986 static ldns_status
1987 ldns_verify_rrsig_ecdsa_raw(unsigned char* sig, size_t siglen,
1988 ldns_buffer* rrset, unsigned char* key, size_t keylen, uint8_t algo)
1990 EVP_PKEY *evp_key;
1991 ldns_status result;
1992 const EVP_MD *d;
1994 evp_key = ldns_ecdsa2pkey_raw(key, keylen, algo);
1995 if(!evp_key) {
1996 /* could not convert key */
1997 return LDNS_STATUS_CRYPTO_BOGUS;
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;
2006 #endif
2008 ldns_status
2009 ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf,
2010 ldns_buffer *key_buf, uint8_t algo)
2012 return ldns_verify_rrsig_buffers_raw(
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);
2020 ldns_status
2021 ldns_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)
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:
2039 return ldns_verify_rrsig_rsasha1_raw(sig,
2040 siglen,
2041 verify_buf,
2042 key,
2043 keylen);
2044 break;
2045 #ifdef USE_SHA2
2046 case LDNS_RSASHA256:
2047 return ldns_verify_rrsig_rsasha256_raw(sig,
2048 siglen,
2049 verify_buf,
2050 key,
2051 keylen);
2052 break;
2053 case LDNS_RSASHA512:
2054 return ldns_verify_rrsig_rsasha512_raw(sig,
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
2068 case LDNS_ECDSAP256SHA256:
2069 case LDNS_ECDSAP384SHA384:
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:
2087 return ldns_verify_rrsig_rsamd5_raw(sig,
2088 siglen,
2089 verify_buf,
2090 key,
2091 keylen);
2092 break;
2093 default:
2094 /* do you know this alg?! */
2095 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2101 * Reset the ttl in the rrset with the orig_ttl from the sig
2102 * and update owner name if it was wildcard
2103 * Also canonicalizes the rrset.
2104 * @param rrset: rrset to modify
2105 * @param sig: signature to take TTL and wildcard values from
2107 static void
2108 ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, const ldns_rr* rrsig)
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;
2117 if ((rrsig == NULL) || ldns_rr_rd_count(rrsig) < 4) {
2118 return;
2121 orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
2122 label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
2124 for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
2125 if (label_count <
2126 ldns_dname_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;
2137 (void) ldns_dname_cat(wildcard_name, wildcard_chopped);
2138 ldns_rdf_deep_free(wildcard_chopped);
2139 ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(
2140 rrset_clone, i)));
2141 ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i),
2142 wildcard_name);
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));
2151 * Make raw signature buffer out of rrsig
2152 * @param rawsig_buf: raw signature buffer for result
2153 * @param rrsig: signature to convert
2154 * @return OK or more specific error.
2156 static ldns_status
2157 ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, const ldns_rr* rrsig)
2159 uint8_t sig_algo;
2161 if (rrsig == NULL) {
2162 return LDNS_STATUS_CRYPTO_NO_RRSIG;
2164 if (ldns_rr_rdf(rrsig, 1) == NULL) {
2165 return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
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
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) */
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) {
2193 return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2195 if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8))
2196 != LDNS_STATUS_OK) {
2197 return LDNS_STATUS_MEM_ERR;
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) {
2205 return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2207 if (ldns_convert_dsa_rrsig_rdf2asn1(
2208 rawsig_buf, ldns_rr_rdf(rrsig, 8))
2209 != LDNS_STATUS_OK) {
2211 if (ldns_rdf2buffer_wire(rawsig_buf,
2212 ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
2214 return LDNS_STATUS_MEM_ERR;
2216 break;
2217 #endif
2218 #ifdef USE_ECDSA
2219 case LDNS_ECDSAP256SHA256:
2220 case LDNS_ECDSAP384SHA384:
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) {
2224 return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2226 if (ldns_convert_ecdsa_rrsig_rdf2asn1(
2227 rawsig_buf, ldns_rr_rdf(rrsig, 8))
2228 != LDNS_STATUS_OK) {
2229 return LDNS_STATUS_MEM_ERR;
2231 break;
2232 #endif
2233 case LDNS_DH:
2234 case LDNS_ECC:
2235 case LDNS_INDIRECT:
2236 return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
2237 default:
2238 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2240 return LDNS_STATUS_OK;
2244 * Check RRSIG timestamps against the given 'now' time.
2245 * @param rrsig: signature to check.
2246 * @param now: the current time in seconds epoch.
2247 * @return status code LDNS_STATUS_OK if all is fine.
2249 static ldns_status
2250 ldns_rrsig_check_timestamps(const ldns_rr* rrsig, time_t now)
2252 int32_t inception, expiration;
2254 /* check the signature time stamps */
2255 inception = (int32_t)ldns_rdf2native_time_t(
2256 ldns_rr_rrsig_inception(rrsig));
2257 expiration = (int32_t)ldns_rdf2native_time_t(
2258 ldns_rr_rrsig_expiration(rrsig));
2260 if (expiration - inception < 0) {
2261 /* bad sig, expiration before inception?? Tsssg */
2262 return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
2264 if (((int32_t) now) - inception < 0) {
2265 /* bad sig, inception date has not yet come to pass */
2266 return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
2268 if (expiration - ((int32_t) now) < 0) {
2269 /* bad sig, expiration date has passed */
2270 return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
2272 return LDNS_STATUS_OK;
2276 * Prepare for verification.
2277 * @param rawsig_buf: raw signature buffer made ready.
2278 * @param verify_buf: data for verification buffer made ready.
2279 * @param rrset_clone: made ready.
2280 * @param rrsig: signature to prepare for.
2281 * @return LDNS_STATUS_OK is all went well. Otherwise specific error.
2283 static ldns_status
2284 ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
2285 ldns_rr_list* rrset_clone, const ldns_rr* rrsig)
2287 ldns_status result;
2289 /* canonicalize the sig */
2290 ldns_dname2canonical(ldns_rr_owner(rrsig));
2292 /* check if the typecovered is equal to the type checked */
2293 if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)) !=
2294 ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0)))
2295 return LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR;
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;
2302 /* use TTL from signature. Use wildcard names for wildcards */
2303 /* also canonicalizes rrset_clone */
2304 ldns_rrset_use_signature_ttl(rrset_clone, rrsig);
2306 /* sort the rrset in canonical order */
2307 ldns_rr_list_sort(rrset_clone);
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;
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;
2318 return LDNS_STATUS_OK;
2322 * Check if a key matches a signature.
2323 * Checks keytag, sigalgo and signature.
2324 * @param rawsig_buf: raw signature buffer for verify
2325 * @param verify_buf: raw data buffer for verify
2326 * @param rrsig: the rrsig
2327 * @param key: key to attempt.
2328 * @return LDNS_STATUS_OK if OK, else some specific error.
2330 static ldns_status
2331 ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
2332 const ldns_rr* rrsig, ldns_rr* key)
2334 uint8_t sig_algo;
2336 if (rrsig == NULL) {
2337 return LDNS_STATUS_CRYPTO_NO_RRSIG;
2339 if (ldns_rr_rdf(rrsig, 1) == NULL) {
2340 return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
2342 sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
2344 /* before anything, check if the keytags match */
2345 if (ldns_calc_keytag(key)
2347 ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
2349 ldns_buffer* key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2350 ldns_status result = LDNS_STATUS_ERR;
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);
2356 return LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
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;
2367 if (ldns_rr_rdf(key, 2) == NULL) {
2368 result = LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
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 */
2376 result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
2379 ldns_buffer_free(key_buf);
2380 return result;
2382 else {
2383 /* No keys with the corresponding keytag are found */
2384 return LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
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
2397 ldns_status
2398 ldns_verify_rrsig_keylist_time(
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)
2405 ldns_status result;
2406 ldns_rr_list *valid;
2408 if (!good_keys)
2409 valid = NULL;
2411 else if (!(valid = ldns_rr_list_new()))
2412 return LDNS_STATUS_MEM_ERR;
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;
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;
2427 ldns_rr_list_cat(good_keys, valid);
2428 ldns_rr_list_free(valid);
2429 return LDNS_STATUS_OK;
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
2441 ldns_status
2442 ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
2443 ldns_rr *rrsig,
2444 const ldns_rr_list *keys,
2445 ldns_rr_list *good_keys)
2447 return ldns_verify_rrsig_keylist_time(
2448 rrset, rrsig, keys, ldns_time(NULL), good_keys);
2451 ldns_status
2452 ldns_verify_rrsig_keylist_notime(const ldns_rr_list *rrset,
2453 const ldns_rr *rrsig,
2454 const ldns_rr_list *keys,
2455 ldns_rr_list *good_keys)
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;
2464 if (!rrset) {
2465 return LDNS_STATUS_ERR;
2468 validkeys = ldns_rr_list_new();
2469 if (!validkeys) {
2470 return LDNS_STATUS_MEM_ERR;
2473 /* clone the rrset so that we can fiddle with it */
2474 rrset_clone = ldns_rr_list_clone(rrset);
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);
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;
2490 result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
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;
2509 result = status;
2512 if (result == LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
2513 result = status;
2517 /* no longer needed */
2518 ldns_rr_list_deep_free(rrset_clone);
2519 ldns_buffer_free(rawsig_buf);
2520 ldns_buffer_free(verify_buf);
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;
2528 /* do not check timestamps */
2530 ldns_rr_list_cat(good_keys, validkeys);
2531 ldns_rr_list_free(validkeys);
2532 return LDNS_STATUS_OK;
2535 ldns_status
2536 ldns_verify_rrsig_time(
2537 ldns_rr_list *rrset,
2538 ldns_rr *rrsig,
2539 ldns_rr *key,
2540 time_t check_time)
2542 ldns_buffer *rawsig_buf;
2543 ldns_buffer *verify_buf;
2544 ldns_status result;
2545 ldns_rr_list *rrset_clone;
2547 if (!rrset) {
2548 return LDNS_STATUS_NO_DATA;
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);
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;
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);
2571 /* check timestamp last, apart from time its OK */
2572 if(result == LDNS_STATUS_OK)
2573 result = ldns_rrsig_check_timestamps(rrsig, check_time);
2575 return result;
2578 ldns_status
2579 ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
2581 return ldns_verify_rrsig_time(rrset, rrsig, key, ldns_time(NULL));
2585 ldns_status
2586 ldns_verify_rrsig_evp(ldns_buffer *sig,
2587 ldns_buffer *rrset,
2588 EVP_PKEY *key,
2589 const EVP_MD *digest_type)
2591 return ldns_verify_rrsig_evp_raw(
2592 (unsigned char*)ldns_buffer_begin(sig),
2593 ldns_buffer_position(sig),
2594 rrset,
2595 key,
2596 digest_type);
2599 ldns_status
2600 ldns_verify_rrsig_evp_raw(const unsigned char *sig, size_t siglen,
2601 const ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
2603 EVP_MD_CTX *ctx;
2604 int res;
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;
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));
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);
2635 EVP_MD_CTX_destroy(ctx);
2637 if (res == 1) {
2638 return LDNS_STATUS_OK;
2640 } else if (res == 0) {
2641 return LDNS_STATUS_CRYPTO_BOGUS;
2643 /* TODO how to communicate internal SSL error?
2644 let caller use ssl's get_error() */
2645 return LDNS_STATUS_SSL_ERR;
2648 ldns_status
2649 ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2651 return ldns_verify_rrsig_dsa_raw(
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));
2659 ldns_status
2660 ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2662 return ldns_verify_rrsig_rsasha1_raw(
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));
2670 ldns_status
2671 ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2673 return ldns_verify_rrsig_rsamd5_raw(
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));
2681 ldns_status
2682 ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
2683 ldns_buffer* rrset, unsigned char* key, size_t keylen)
2685 #ifdef USE_DSA
2686 EVP_PKEY *evp_key;
2687 ldns_status result;
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
2701 } else {
2702 result = LDNS_STATUS_SSL_ERR;
2704 EVP_PKEY_free(evp_key);
2705 return result;
2706 #else
2707 (void)sig; (void)siglen; (void)rrset; (void)key; (void)keylen;
2708 return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
2709 #endif
2712 ldns_status
2713 ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen,
2714 ldns_buffer* rrset, unsigned char* key, size_t keylen)
2716 EVP_PKEY *evp_key;
2717 ldns_status result;
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;
2729 EVP_PKEY_free(evp_key);
2731 return result;
2734 ldns_status
2735 ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
2736 size_t siglen,
2737 ldns_buffer* rrset,
2738 unsigned char* key,
2739 size_t keylen)
2741 #ifdef USE_SHA2
2742 EVP_PKEY *evp_key;
2743 ldns_status result;
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;
2755 EVP_PKEY_free(evp_key);
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;
2765 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2766 #endif
2769 ldns_status
2770 ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
2771 size_t siglen,
2772 ldns_buffer* rrset,
2773 unsigned char* key,
2774 size_t keylen)
2776 #ifdef USE_SHA2
2777 EVP_PKEY *evp_key;
2778 ldns_status result;
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;
2790 EVP_PKEY_free(evp_key);
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;
2800 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2801 #endif
2805 ldns_status
2806 ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
2807 size_t siglen,
2808 ldns_buffer* rrset,
2809 unsigned char* key,
2810 size_t keylen)
2812 EVP_PKEY *evp_key;
2813 ldns_status result;
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;
2825 EVP_PKEY_free(evp_key);
2827 return result;
2830 #endif