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