Initial vendor import of ldns-1.6.4 into contrib.
[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 uint16_t cur_keytag;
639 size_t i, j;
640
641 ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new();
642
643 if (data_chain && data_chain->rrset) {
644 cur_rrset = data_chain->rrset;
645
646 cur_sigs = data_chain->signatures;
647
648 if (rr) {
649 cur_rr = rr;
650 }
651
652 if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) {
653 cur_rr = ldns_rr_list_rr(cur_rrset, 0);
654 }
655
656 if (cur_rr) {
657 new_tree->rr = cur_rr;
658 new_tree->rrset = cur_rrset;
659 /* there are three possibilities:
660 1 - 'normal' rrset, signed by a key
661 2 - dnskey signed by other dnskey
662 3 - dnskey proven by higher level DS
663 (data denied by nsec is a special case that can
664 occur in multiple places)
665
666 */
667 if (cur_sigs) {
668 for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) {
669 /* find the appropriate key in the parent list */
670 cur_sig_rr = ldns_rr_list_rr(cur_sigs, i);
671 cur_keytag =
672 ldns_rdf2native_int16(
673 ldns_rr_rrsig_keytag(cur_sig_rr));
674
675 if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) {
676 if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
677 ldns_rr_owner(cur_rr)))
678 {
679 /* find first that does match */
680
681 for (j = 0;
682 j < ldns_rr_list_rr_count(cur_rrset) &&
683 ldns_dname_compare(ldns_rr_owner(cur_sig_rr),ldns_rr_owner(cur_rr)) != 0;
684 j++) {
685 cur_rr = ldns_rr_list_rr(cur_rrset, j);
686
687 }
688 if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
689 ldns_rr_owner(cur_rr)))
690 {
691 break;
692 }
693 }
694
695 }
696 /* option 1 */
697 if (data_chain->parent) {
698 ldns_dnssec_derive_trust_tree_normal_rrset(
699 new_tree,
700 data_chain,
701 cur_sig_rr);
702 }
703
704 /* option 2 */
705 ldns_dnssec_derive_trust_tree_dnskey_rrset(
706 new_tree,
707 data_chain,
708 cur_rr,
709 cur_sig_rr);
710 }
711
712 ldns_dnssec_derive_trust_tree_ds_rrset(new_tree,
713 data_chain,
714 cur_rr);
715 } else {
716 /* no signatures? maybe it's nsec data */
717
718 /* just add every rr from parent as new parent */
719 ldns_dnssec_derive_trust_tree_no_sig(new_tree, data_chain);
720 }
721 }
722 }
723
724 return new_tree;
725}
726
727void
728ldns_dnssec_derive_trust_tree_normal_rrset(ldns_dnssec_trust_tree *new_tree,
729 ldns_dnssec_data_chain *data_chain,
730 ldns_rr *cur_sig_rr)
731{
732 size_t i, j;
733 ldns_rr_list *cur_rrset = ldns_rr_list_clone(data_chain->rrset);
734 ldns_dnssec_trust_tree *cur_parent_tree;
735 ldns_rr *cur_parent_rr;
736 uint16_t cur_keytag;
737 ldns_rr_list *tmp_rrset = NULL;
738 ldns_status cur_status;
739
740 cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
741
742 for (j = 0; j < ldns_rr_list_rr_count(data_chain->parent->rrset); j++) {
743 cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
744 if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
745 if (ldns_calc_keytag(cur_parent_rr) == cur_keytag) {
746
747 /* TODO: check wildcard nsec too */
748 if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
749 tmp_rrset = cur_rrset;
750 if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
751 == LDNS_RR_TYPE_NSEC ||
752 ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
753 == LDNS_RR_TYPE_NSEC3) {
754 /* might contain different names!
755 sort and split */
756 ldns_rr_list_sort(cur_rrset);
757 if (tmp_rrset && tmp_rrset != cur_rrset) {
758 ldns_rr_list_deep_free(tmp_rrset);
759 tmp_rrset = NULL;
760 }
761 tmp_rrset = ldns_rr_list_pop_rrset(cur_rrset);
762
763 /* with nsecs, this might be the wrong one */
764 while (tmp_rrset &&
765 ldns_rr_list_rr_count(cur_rrset) > 0 &&
766 ldns_dname_compare(
767 ldns_rr_owner(ldns_rr_list_rr(
768 tmp_rrset, 0)),
769 ldns_rr_owner(cur_sig_rr)) != 0) {
770 ldns_rr_list_deep_free(tmp_rrset);
771 tmp_rrset =
772 ldns_rr_list_pop_rrset(cur_rrset);
773 }
774 }
775 cur_status = ldns_verify_rrsig(tmp_rrset,
776 cur_sig_rr,
777 cur_parent_rr);
778 /* avoid dupes */
779 for (i = 0; i < new_tree->parent_count; i++) {
780 if (cur_parent_rr == new_tree->parents[i]->rr) {
781 goto done;
782 }
783 }
784
785 cur_parent_tree =
786 ldns_dnssec_derive_trust_tree(data_chain->parent,
787 cur_parent_rr);
788 (void)ldns_dnssec_trust_tree_add_parent(new_tree,
789 cur_parent_tree,
790 cur_sig_rr,
791 cur_status);
792 }
793 }
794 }
795 }
796 done:
797 if (tmp_rrset && tmp_rrset != cur_rrset) {
798 ldns_rr_list_deep_free(tmp_rrset);
799 }
800 ldns_rr_list_deep_free(cur_rrset);
801}
802
803void
804ldns_dnssec_derive_trust_tree_dnskey_rrset(ldns_dnssec_trust_tree *new_tree,
805 ldns_dnssec_data_chain *data_chain,
806 ldns_rr *cur_rr,
807 ldns_rr *cur_sig_rr)
808{
809 size_t j;
810 ldns_rr_list *cur_rrset = data_chain->rrset;
811 ldns_dnssec_trust_tree *cur_parent_tree;
812 ldns_rr *cur_parent_rr;
813 uint16_t cur_keytag;
814 ldns_status cur_status;
815
816 cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
817
818 for (j = 0; j < ldns_rr_list_rr_count(cur_rrset); j++) {
819 cur_parent_rr = ldns_rr_list_rr(cur_rrset, j);
820 if (cur_parent_rr != cur_rr &&
821 ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
822 if (ldns_calc_keytag(cur_parent_rr) == cur_keytag
823 ) {
824 cur_parent_tree = ldns_dnssec_trust_tree_new();
825 cur_parent_tree->rr = cur_parent_rr;
826 cur_parent_tree->rrset = cur_rrset;
827 cur_status = ldns_verify_rrsig(cur_rrset,
828 cur_sig_rr,
829 cur_parent_rr);
830 (void) ldns_dnssec_trust_tree_add_parent(new_tree,
831 cur_parent_tree, cur_sig_rr, cur_status);
832 }
833 }
834 }
835}
836
837void
838ldns_dnssec_derive_trust_tree_ds_rrset(ldns_dnssec_trust_tree *new_tree,
839 ldns_dnssec_data_chain *data_chain,
840 ldns_rr *cur_rr)
841{
842 size_t j, h;
843 ldns_rr_list *cur_rrset = data_chain->rrset;
844 ldns_dnssec_trust_tree *cur_parent_tree;
845 ldns_rr *cur_parent_rr;
846
847 /* try the parent to see whether there are DSs there */
848 if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_DNSKEY &&
849 data_chain->parent &&
850 data_chain->parent->rrset
851 ) {
852 for (j = 0;
853 j < ldns_rr_list_rr_count(data_chain->parent->rrset);
854 j++) {
855 cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
856 if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DS) {
857 for (h = 0; h < ldns_rr_list_rr_count(cur_rrset); h++) {
858 cur_rr = ldns_rr_list_rr(cur_rrset, h);
859 if (ldns_rr_compare_ds(cur_rr, cur_parent_rr)) {
860 cur_parent_tree =
861 ldns_dnssec_derive_trust_tree(
862 data_chain->parent, cur_parent_rr);
863 (void) ldns_dnssec_trust_tree_add_parent(
864 new_tree,
865 cur_parent_tree,
866 NULL,
867 LDNS_STATUS_OK);
868 } else {
869 /*ldns_rr_print(stdout, cur_parent_rr);*/
870 }
871 }
872 cur_rr = ldns_rr_list_rr(cur_rrset, 0);
873 }
874 }
875 }
876}
877
878void
879ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree *new_tree,
880 ldns_dnssec_data_chain *data_chain)
881{
882 size_t i;
883 ldns_rr_list *cur_rrset;
884 ldns_rr *cur_parent_rr;
885 ldns_dnssec_trust_tree *cur_parent_tree;
886 ldns_status result;
887
888 if (data_chain->parent && data_chain->parent->rrset) {
889 cur_rrset = data_chain->parent->rrset;
890 /* nsec? */
891 if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
892 if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
893 LDNS_RR_TYPE_NSEC3) {
894 result = ldns_dnssec_verify_denial_nsec3(
895 new_tree->rr,
896 cur_rrset,
897 data_chain->parent->signatures,
898 data_chain->packet_rcode,
899 data_chain->packet_qtype,
900 data_chain->packet_nodata);
901 } else if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
902 LDNS_RR_TYPE_NSEC3) {
903 result = ldns_dnssec_verify_denial(
904 new_tree->rr,
905 cur_rrset,
906 data_chain->parent->signatures);
907 } else {
908 /* unsigned zone, unsigned parent */
909 result = LDNS_STATUS_OK;
910 }
911 } else {
912 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
913 }
914 for (i = 0; i < ldns_rr_list_rr_count(cur_rrset); i++) {
915 cur_parent_rr = ldns_rr_list_rr(cur_rrset, i);
916 cur_parent_tree =
917 ldns_dnssec_derive_trust_tree(data_chain->parent,
918 cur_parent_rr);
919 (void) ldns_dnssec_trust_tree_add_parent(new_tree,
920 cur_parent_tree, NULL, result);
921 }
922 }
923}
924
925/*
926 * returns OK if there is a path from tree to key with only OK
927 * the (first) error in between otherwise
928 * or NOT_FOUND if the key wasn't present at all
929 */
930ldns_status
931ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree,
932 ldns_rr_list *trusted_keys)
933{
934 size_t i;
935 ldns_status result = LDNS_STATUS_CRYPTO_NO_DNSKEY;
936 bool equal;
937 ldns_status parent_result;
938
939 if (tree && trusted_keys && ldns_rr_list_rr_count(trusted_keys) > 0)
940 { if (tree->rr) {
941 for (i = 0; i < ldns_rr_list_rr_count(trusted_keys); i++) {
942 equal = ldns_rr_compare_ds(
943 tree->rr,
944 ldns_rr_list_rr(trusted_keys, i));
945 if (equal) {
946 result = LDNS_STATUS_OK;
947 return result;
948 }
949 }
950 }
951 for (i = 0; i < tree->parent_count; i++) {
952 parent_result =
953 ldns_dnssec_trust_tree_contains_keys(tree->parents[i],
954 trusted_keys);
955 if (parent_result != LDNS_STATUS_CRYPTO_NO_DNSKEY) {
956 if (tree->parent_status[i] != LDNS_STATUS_OK) {
957 result = tree->parent_status[i];
958 } else {
959 if (ldns_rr_get_type(tree->rr)
960 == LDNS_RR_TYPE_NSEC &&
961 parent_result == LDNS_STATUS_OK
962 ) {
963 result =
964 LDNS_STATUS_DNSSEC_EXISTENCE_DENIED;
965 } else {
966 result = parent_result;
967 }
968 }
969 }
970 }
971 } else {
972 result = LDNS_STATUS_ERR;
973 }
974
975 return result;
976}
977
978ldns_status
979ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys,
980 ldns_rr_list *good_keys)
981{
982 uint16_t i;
983 ldns_status verify_result = LDNS_STATUS_ERR;
984
985 if (!rrset || !rrsig || !keys) {
986 return LDNS_STATUS_ERR;
987 }
988
989 if (ldns_rr_list_rr_count(rrset) < 1) {
990 return LDNS_STATUS_ERR;
991 }
992
993 if (ldns_rr_list_rr_count(rrsig) < 1) {
994 return LDNS_STATUS_CRYPTO_NO_RRSIG;
995 }
996
997 if (ldns_rr_list_rr_count(keys) < 1) {
998 verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
999 } else {
1000 for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1001 ldns_status s = ldns_verify_rrsig_keylist(rrset,
1002 ldns_rr_list_rr(rrsig, i), keys, good_keys);
1003 /* try a little to get more descriptive error */
1004 if(s == LDNS_STATUS_OK) {
1005 verify_result = LDNS_STATUS_OK;
1006 } else if(verify_result == LDNS_STATUS_ERR)
1007 verify_result = s;
1008 else if(s != LDNS_STATUS_ERR && verify_result ==
1009 LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY)
1010 verify_result = s;
1011 }
1012 }
1013 return verify_result;
1014}
1015
1016ldns_status
1017ldns_verify_notime(ldns_rr_list *rrset, ldns_rr_list *rrsig,
1018 const ldns_rr_list *keys, ldns_rr_list *good_keys)
1019{
1020 uint16_t i;
1021 ldns_status verify_result = LDNS_STATUS_ERR;
1022
1023 if (!rrset || !rrsig || !keys) {
1024 return LDNS_STATUS_ERR;
1025 }
1026
1027 if (ldns_rr_list_rr_count(rrset) < 1) {
1028 return LDNS_STATUS_ERR;
1029 }
1030
1031 if (ldns_rr_list_rr_count(rrsig) < 1) {
1032 return LDNS_STATUS_CRYPTO_NO_RRSIG;
1033 }
1034
1035 if (ldns_rr_list_rr_count(keys) < 1) {
1036 verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1037 } else {
1038 for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
1039 ldns_status s = ldns_verify_rrsig_keylist_notime(rrset,
1040 ldns_rr_list_rr(rrsig, i), keys, good_keys);
1041
1042 /* try a little to get more descriptive error */
1043 if (s == LDNS_STATUS_OK) {
1044 verify_result = LDNS_STATUS_OK;
1045 } else if (verify_result == LDNS_STATUS_ERR) {
1046 verify_result = s;
1047 } else if (s != LDNS_STATUS_ERR && verify_result ==
1048 LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
1049 verify_result = s;
1050 }
1051 }
1052 }
1053 return verify_result;
1054}
1055
1056ldns_rr_list *
1057ldns_fetch_valid_domain_keys(const ldns_resolver *res,
1058 const ldns_rdf *domain,
1059 const ldns_rr_list *keys,
1060 ldns_status *status)
1061{
1062 ldns_rr_list * trusted_keys = NULL;
1063 ldns_rr_list * ds_keys = NULL;
1064
1065 if (res && domain && keys) {
1066
1067 if ((trusted_keys = ldns_validate_domain_dnskey(res,
1068 domain,
1069 keys))) {
1070 *status = LDNS_STATUS_OK;
1071 } else {
1072 /* No trusted keys in this domain, we'll have to find some in the parent domain */
1073 *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
1074
1075 if (ldns_rdf_size(domain) > 1) {
1076 /* Fail if we are at the root */
1077 ldns_rr_list * parent_keys;
1078 ldns_rdf * parent_domain = ldns_dname_left_chop(domain);
1079
1080 if ((parent_keys =
1081 ldns_fetch_valid_domain_keys(res,
1082 parent_domain,
1083 keys,
1084 status))) {
1085 /* Check DS records */
1086 if ((ds_keys =
1087 ldns_validate_domain_ds(res,
1088 domain,
1089 parent_keys))) {
1090 trusted_keys =
1091 ldns_fetch_valid_domain_keys(res,
1092 domain,
1093 ds_keys,
1094 status);
1095 ldns_rr_list_deep_free(ds_keys);
1096 } else {
1097 /* No valid DS at the parent -- fail */
1098 *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DS ;
1099 }
1100 ldns_rr_list_deep_free(parent_keys);
1101 }
1102 ldns_rdf_deep_free(parent_domain);
1103 }
1104 }
1105 }
1106 return trusted_keys;
1107}
1108
1109ldns_rr_list *
1110ldns_validate_domain_dnskey(const ldns_resolver * res,
1111 const ldns_rdf * domain,
1112 const ldns_rr_list * keys)
1113{
1114 ldns_status status;
1115 ldns_pkt * keypkt;
1116 ldns_rr * cur_key;
1117 uint16_t key_i; uint16_t key_j; uint16_t key_k;
1118 uint16_t sig_i; ldns_rr * cur_sig;
1119
1120 ldns_rr_list * domain_keys = NULL;
1121 ldns_rr_list * domain_sigs = NULL;
1122 ldns_rr_list * trusted_keys = NULL;
1123
1124 /* Fetch keys for the domain */
1125 if ((keypkt = ldns_resolver_query(res,
1126 domain,
1127 LDNS_RR_TYPE_DNSKEY,
1128 LDNS_RR_CLASS_IN,
1129 LDNS_RD))) {
1130
1131 domain_keys = ldns_pkt_rr_list_by_type(keypkt,
1132 LDNS_RR_TYPE_DNSKEY,
1133 LDNS_SECTION_ANSWER);
1134 domain_sigs = ldns_pkt_rr_list_by_type(keypkt,
1135 LDNS_RR_TYPE_RRSIG,
1136 LDNS_SECTION_ANSWER);
1137
1138 /* Try to validate the record using our keys */
1139 for (key_i=0; key_i< ldns_rr_list_rr_count(domain_keys); key_i++) {
1140
1141 cur_key = ldns_rr_list_rr(domain_keys, key_i);
1142 for (key_j=0; key_j<ldns_rr_list_rr_count(keys); key_j++) {
1143 if (ldns_rr_compare_ds(ldns_rr_list_rr(keys, key_j),
1144 cur_key)) {
1145
1146 /* Current key is trusted -- validate */
1147 trusted_keys = ldns_rr_list_new();
1148
1149 for (sig_i=0;
1150 sig_i<ldns_rr_list_rr_count(domain_sigs);
1151 sig_i++) {
1152 cur_sig = ldns_rr_list_rr(domain_sigs, sig_i);
1153 /* Avoid non-matching sigs */
1154 if (ldns_rdf2native_int16(
1155 ldns_rr_rrsig_keytag(cur_sig))
1156 == ldns_calc_keytag(cur_key)) {
1157 if ((status =
1158 ldns_verify_rrsig(domain_keys,
1159 cur_sig,
1160 cur_key))
1161 == LDNS_STATUS_OK) {
1162
1163 /* Push the whole rrset
1164 -- we can't do much more */
1165 for (key_k=0;
1166 key_k<ldns_rr_list_rr_count(
1167 domain_keys);
1168 key_k++) {
1169 ldns_rr_list_push_rr(
1170 trusted_keys,
1171 ldns_rr_clone(
1172 ldns_rr_list_rr(
1173 domain_keys,
1174 key_k)));
1175 }
1176
1177 ldns_rr_list_deep_free(domain_keys);
1178 ldns_rr_list_deep_free(domain_sigs);
1179 ldns_pkt_free(keypkt);
1180 return trusted_keys;
1181 }
1182 }
1183 }
1184
1185 /* Only push our trusted key */
1186 ldns_rr_list_push_rr(trusted_keys,
1187 ldns_rr_clone(cur_key));
1188 }
1189 }
1190 }
1191
1192 ldns_rr_list_deep_free(domain_keys);
1193 ldns_rr_list_deep_free(domain_sigs);
1194 ldns_pkt_free(keypkt);
1195
1196 } else {
1197 status = LDNS_STATUS_CRYPTO_NO_DNSKEY;
1198 }
1199
1200 return trusted_keys;
1201}
1202
1203ldns_rr_list *
1204ldns_validate_domain_ds(const ldns_resolver *res,
1205 const ldns_rdf * domain,
1206 const ldns_rr_list * keys)
1207{
1208 ldns_status status;
1209 ldns_pkt * dspkt;
1210 uint16_t key_i;
1211 ldns_rr_list * rrset = NULL;
1212 ldns_rr_list * sigs = NULL;
1213 ldns_rr_list * trusted_keys = NULL;
1214
1215 /* Fetch DS for the domain */
1216 if ((dspkt = ldns_resolver_query(res,
1217 domain,
1218 LDNS_RR_TYPE_DS,
1219 LDNS_RR_CLASS_IN,
1220 LDNS_RD))) {
1221
1222 rrset = ldns_pkt_rr_list_by_type(dspkt,
1223 LDNS_RR_TYPE_DS,
1224 LDNS_SECTION_ANSWER);
1225 sigs = ldns_pkt_rr_list_by_type(dspkt,
1226 LDNS_RR_TYPE_RRSIG,
1227 LDNS_SECTION_ANSWER);
1228
1229 /* Validate sigs */
1230 if ((status = ldns_verify(rrset, sigs, keys, NULL))
1231 == LDNS_STATUS_OK) {
1232 trusted_keys = ldns_rr_list_new();
1233 for (key_i=0; key_i<ldns_rr_list_rr_count(rrset); key_i++) {
1234 ldns_rr_list_push_rr(trusted_keys,
1235 ldns_rr_clone(ldns_rr_list_rr(rrset,
1236 key_i)
1237 )
1238 );
1239 }
1240 }
1241
1242 ldns_rr_list_deep_free(rrset);
1243 ldns_rr_list_deep_free(sigs);
1244 ldns_pkt_free(dspkt);
1245
1246 } else {
1247 status = LDNS_STATUS_CRYPTO_NO_DS;
1248 }
1249
1250 return trusted_keys;
1251}
1252
1253ldns_status
1254ldns_verify_trusted(ldns_resolver *res,
1255 ldns_rr_list *rrset,
1256 ldns_rr_list * rrsigs,
1257 ldns_rr_list * validating_keys)
1258{
1259 uint16_t sig_i; uint16_t key_i;
1260 ldns_rr * cur_sig; ldns_rr * cur_key;
1261 ldns_rr_list * trusted_keys = NULL;
1262 ldns_status result = LDNS_STATUS_ERR;
1263
1264 if (!res || !rrset || !rrsigs) {
1265 return LDNS_STATUS_ERR;
1266 }
1267
1268 if (ldns_rr_list_rr_count(rrset) < 1) {
1269 return LDNS_STATUS_ERR;
1270 }
1271
1272 if (ldns_rr_list_rr_count(rrsigs) < 1) {
1273 return LDNS_STATUS_CRYPTO_NO_RRSIG;
1274 }
1275
1276 /* Look at each sig */
1277 for (sig_i=0; sig_i < ldns_rr_list_rr_count(rrsigs); sig_i++) {
1278
1279 cur_sig = ldns_rr_list_rr(rrsigs, sig_i);
1280 /* Get a valid signer key and validate the sig */
1281 if ((trusted_keys = ldns_fetch_valid_domain_keys(
1282 res,
1283 ldns_rr_rrsig_signame(cur_sig),
1284 ldns_resolver_dnssec_anchors(res),
1285 &result))) {
1286
1287 for (key_i = 0;
1288 key_i < ldns_rr_list_rr_count(trusted_keys);
1289 key_i++) {
1290 cur_key = ldns_rr_list_rr(trusted_keys, key_i);
1291
1292 if ((result = ldns_verify_rrsig(rrset,
1293 cur_sig,
1294 cur_key))
1295 == LDNS_STATUS_OK) {
1296 if (validating_keys) {
1297 ldns_rr_list_push_rr(validating_keys,
1298 ldns_rr_clone(cur_key));
1299 }
1300 ldns_rr_list_deep_free(trusted_keys);
1301 return LDNS_STATUS_OK;
1302 } else {
1303 ldns_rr_list_print(stdout, rrset);
1304 ldns_rr_print(stdout, cur_sig);
1305 ldns_rr_print(stdout, cur_key);
1306
1307 }
1308 }
1309 }
1310 }
1311
1312 ldns_rr_list_deep_free(trusted_keys);
1313 return result;
1314}
1315
1316ldns_status
1317ldns_dnssec_verify_denial(ldns_rr *rr,
1318 ldns_rr_list *nsecs,
1319 ldns_rr_list *rrsigs)
1320{
1321 ldns_rdf *rr_name;
1322 ldns_rdf *wildcard_name;
1323 ldns_rdf *chopped_dname;
1324 ldns_rr *cur_nsec;
1325 size_t i;
1326 ldns_status result;
1327 /* needed for wildcard check on exact match */
1328 ldns_rr *rrsig;
1329 bool name_covered = false;
1330 bool type_covered = false;
1331 bool wildcard_covered = false;
1332 bool wildcard_type_covered = false;
1333
1334 wildcard_name = ldns_dname_new_frm_str("*");
1335 rr_name = ldns_rr_owner(rr);
1336 chopped_dname = ldns_dname_left_chop(rr_name);
1337 result = ldns_dname_cat(wildcard_name, chopped_dname);
1338 if (result != LDNS_STATUS_OK) {
1339 return result;
1340 }
1341
1342 ldns_rdf_deep_free(chopped_dname);
1343
1344 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1345 cur_nsec = ldns_rr_list_rr(nsecs, i);
1346 if (ldns_dname_compare(rr_name, ldns_rr_owner(cur_nsec)) == 0) {
1347 /* see section 5.4 of RFC4035, if the label count of the NSEC's
1348 RRSIG is equal, then it is proven that wildcard expansion
1349 could not have been used to match the request */
1350 rrsig = ldns_dnssec_get_rrsig_for_name_and_type(
1351 ldns_rr_owner(cur_nsec),
1352 ldns_rr_get_type(cur_nsec),
1353 rrsigs);
1354 if (rrsig && ldns_rdf2native_int8(ldns_rr_rrsig_labels(rrsig))
1355 == ldns_dname_label_count(rr_name)) {
1356 wildcard_covered = true;
1357 }
1358
1359 if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
1360 ldns_rr_get_type(rr))) {
1361 type_covered = true;
1362 }
1363 }
1364 if (ldns_nsec_covers_name(cur_nsec, rr_name)) {
1365 name_covered = true;
1366 }
1367
1368 if (ldns_dname_compare(wildcard_name,
1369 ldns_rr_owner(cur_nsec)) == 0) {
1370 if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
1371 ldns_rr_get_type(rr))) {
1372 wildcard_type_covered = true;
1373 }
1374 }
1375
1376 if (ldns_nsec_covers_name(cur_nsec, wildcard_name)) {
1377 wildcard_covered = true;
1378 }
1379
1380 }
1381
1382 ldns_rdf_deep_free(wildcard_name);
1383
1384 if (type_covered || !name_covered) {
1385 return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1386 }
1387
1388 if (wildcard_type_covered || !wildcard_covered) {
1389 return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
1390 }
1391
1392 return LDNS_STATUS_OK;
1393}
1394
1395#ifdef HAVE_SSL
1396ldns_status
1397ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
1398 ldns_rr_list *nsecs,
1399 ldns_rr_list *rrsigs,
1400 ldns_pkt_rcode packet_rcode,
1401 ldns_rr_type packet_qtype,
1402 bool packet_nodata)
1403{
1404 ldns_rdf *closest_encloser;
1405 ldns_rdf *wildcard;
1406 ldns_rdf *hashed_wildcard_name;
1407 bool wildcard_covered = false;
1408 ldns_rdf *zone_name;
1409 ldns_rdf *hashed_name;
1410 size_t i;
1411 ldns_status result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1412
1413 rrsigs = rrsigs;
1414
1415 zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
1416
1417 /* section 8.4 */
1418 if (packet_rcode == LDNS_RCODE_NXDOMAIN) {
1419 closest_encloser = ldns_dnssec_nsec3_closest_encloser(
1420 ldns_rr_owner(rr),
1421 ldns_rr_get_type(rr),
1422 nsecs);
1423
1424 wildcard = ldns_dname_new_frm_str("*");
1425 (void) ldns_dname_cat(wildcard, closest_encloser);
1426
1427 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1428 hashed_wildcard_name =
1429 ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
1430 wildcard
1431 );
1432 (void) ldns_dname_cat(hashed_wildcard_name, zone_name);
1433
1434 if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
1435 hashed_wildcard_name)) {
1436 wildcard_covered = true;
1437 }
1438 ldns_rdf_deep_free(hashed_wildcard_name);
1439 }
1440
1441 ldns_rdf_deep_free(closest_encloser);
1442 ldns_rdf_deep_free(wildcard);
1443
1444 if (!wildcard_covered) {
1445 result = LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
1446 } else if (closest_encloser && wildcard_covered) {
1447 result = LDNS_STATUS_OK;
1448 } else {
1449 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1450 }
1451 } else if (packet_nodata && packet_qtype != LDNS_RR_TYPE_DS) {
1452 /* section 8.5 */
1453 hashed_name = ldns_nsec3_hash_name_frm_nsec3(
1454 ldns_rr_list_rr(nsecs, 0),
1455 ldns_rr_owner(rr));
1456 (void) ldns_dname_cat(hashed_name, zone_name);
1457 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1458 if (ldns_dname_compare(hashed_name,
1459 ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
1460 == 0) {
1461 if (!ldns_nsec_bitmap_covers_type(
1462 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1463 packet_qtype)
1464 &&
1465 !ldns_nsec_bitmap_covers_type(
1466 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1467 LDNS_RR_TYPE_CNAME)) {
1468 result = LDNS_STATUS_OK;
1469 goto done;
1470 }
1471 }
1472 }
1473 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1474 } else if (packet_nodata && packet_qtype == LDNS_RR_TYPE_DS) {
1475 /* section 8.6 */
1476 /* note: up to XXX this is the same as for 8.5 */
1477 hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs,
1478 0),
1479 ldns_rr_owner(rr)
1480 );
1481 (void) ldns_dname_cat(hashed_name, zone_name);
1482 for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
1483 if (ldns_dname_compare(hashed_name,
1484 ldns_rr_owner(ldns_rr_list_rr(nsecs,
1485 i)))
1486 == 0) {
1487 if (!ldns_nsec_bitmap_covers_type(
1488 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1489 LDNS_RR_TYPE_DS)
1490 &&
1491 !ldns_nsec_bitmap_covers_type(
1492 ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
1493 LDNS_RR_TYPE_CNAME)) {
1494 result = LDNS_STATUS_OK;
1495 goto done;
1496 }
1497 }
1498 }
1499
1500 /* XXX see note above */
1501 closest_encloser =
1502 ldns_dnssec_nsec3_closest_encloser(ldns_rr_owner(rr),
1503 ldns_rr_get_type(rr),
1504 nsecs);
1505
1506 result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
1507 }
1508
1509 done:
1510 ldns_rdf_deep_free(zone_name);
1511 return result;
1512}
1513#endif /* HAVE_SSL */
1514
1515#ifdef USE_GOST
1516EVP_PKEY*
1517ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
1518{
1519 /* prefix header for X509 encoding */
1520 uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
1521 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
1522 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
1523 0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
1524 unsigned char encoded[37+64];
1525 const unsigned char* pp;
1526 if(keylen != 66) {
1527 /* key wrong size */
1528 return NULL;
1529 }
1530 if(key[0] != 0 || key[1] != 0) {
1531 /* unsupported GOST algo or digest paramset */
1532 return NULL;
1533 }
1534
1535 /* create evp_key */
1536 memmove(encoded, asn, 37);
1537 memmove(encoded+37, key+2, 64);
1538 pp = (unsigned char*)&encoded[0];
1539
1540 return d2i_PUBKEY(NULL, &pp, sizeof(encoded));
1541}
1542
1543static ldns_status
1544ldns_verify_rrsig_gost_raw(unsigned char* sig, size_t siglen,
1545 ldns_buffer* rrset, unsigned char* key, size_t keylen)
1546{
1547 EVP_PKEY *evp_key;
1548 ldns_status result;
1549
1550 (void) ldns_key_EVP_load_gost_id();
1551 evp_key = ldns_gost2pkey_raw(key, keylen);
1552 if(!evp_key) {
1553 /* could not convert key */
1554 return LDNS_STATUS_CRYPTO_BOGUS;
1555 }
1556
1557 /* verify signature */
1558 result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset,
1559 evp_key, EVP_get_digestbyname("md_gost94"));
1560 EVP_PKEY_free(evp_key);
1561
1562 return result;
1563}
1564#endif
1565
1566
1567ldns_status
1568ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf,
1569 ldns_buffer *key_buf, uint8_t algo)
1570{
1571 return ldns_verify_rrsig_buffers_raw(
1572 (unsigned char*)ldns_buffer_begin(rawsig_buf),
1573 ldns_buffer_position(rawsig_buf),
1574 verify_buf,
1575 (unsigned char*)ldns_buffer_begin(key_buf),
1576 ldns_buffer_position(key_buf), algo);
1577}
1578
1579ldns_status
1580ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
1581 ldns_buffer *verify_buf, unsigned char* key, size_t keylen,
1582 uint8_t algo)
1583{
1584 /* check for right key */
1585 switch(algo) {
1586 case LDNS_DSA:
1587 case LDNS_DSA_NSEC3:
1588 return ldns_verify_rrsig_dsa_raw(sig,
1589 siglen,
1590 verify_buf,
1591 key,
1592 keylen);
1593 break;
1594 case LDNS_RSASHA1:
1595 case LDNS_RSASHA1_NSEC3:
1596 return ldns_verify_rrsig_rsasha1_raw(sig,
1597 siglen,
1598 verify_buf,
1599 key,
1600 keylen);
1601 break;
1602#ifdef USE_SHA2
1603 case LDNS_RSASHA256:
1604 return ldns_verify_rrsig_rsasha256_raw(sig,
1605 siglen,
1606 verify_buf,
1607 key,
1608 keylen);
1609 break;
1610 case LDNS_RSASHA512:
1611 return ldns_verify_rrsig_rsasha512_raw(sig,
1612 siglen,
1613 verify_buf,
1614 key,
1615 keylen);
1616 break;
1617#endif
1618#ifdef USE_GOST
1619 case LDNS_GOST:
1620 return ldns_verify_rrsig_gost_raw(sig, siglen, verify_buf,
1621 key, keylen);
1622 break;
1623#endif
1624 case LDNS_RSAMD5:
1625 return ldns_verify_rrsig_rsamd5_raw(sig,
1626 siglen,
1627 verify_buf,
1628 key,
1629 keylen);
1630 break;
1631 default:
1632 /* do you know this alg?! */
1633 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
1634 }
1635}
1636
1637
1638/**
1639 * Reset the ttl in the rrset with the orig_ttl from the sig
1640 * and update owner name if it was wildcard
1641 * Also canonicalizes the rrset.
1642 * @param rrset: rrset to modify
1643 * @param sig: signature to take TTL and wildcard values from
1644 */
1645static void
1646ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
1647{
1648 uint32_t orig_ttl;
1649 uint16_t i;
1650 uint8_t label_count;
1651 ldns_rdf *wildcard_name;
1652 ldns_rdf *wildcard_chopped;
1653 ldns_rdf *wildcard_chopped_tmp;
1654
1655 orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
1656 label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
1657
1658 for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
1659 if (label_count <
1660 ldns_dname_label_count(
1661 ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
1662 (void) ldns_str2rdf_dname(&wildcard_name, "*");
1663 wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(
1664 ldns_rr_list_rr(rrset_clone, i)));
1665 while (label_count < ldns_dname_label_count(wildcard_chopped)) {
1666 wildcard_chopped_tmp = ldns_dname_left_chop(
1667 wildcard_chopped);
1668 ldns_rdf_deep_free(wildcard_chopped);
1669 wildcard_chopped = wildcard_chopped_tmp;
1670 }
1671 (void) ldns_dname_cat(wildcard_name, wildcard_chopped);
1672 ldns_rdf_deep_free(wildcard_chopped);
1673 ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(
1674 rrset_clone, i)));
1675 ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i),
1676 wildcard_name);
1677 }
1678 ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl);
1679 /* convert to lowercase */
1680 ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
1681 }
1682}
1683
1684/**
1685 * Make raw signature buffer out of rrsig
1686 * @param rawsig_buf: raw signature buffer for result
1687 * @param rrsig: signature to convert
1688 * @return OK or more specific error.
1689 */
1690static ldns_status
1691ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
1692{
1693 uint8_t sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
1694 /* check for known and implemented algo's now (otherwise
1695 * the function could return a wrong error
1696 */
1697 /* create a buffer with signature rdata */
1698 /* for some algorithms we need other data than for others... */
1699 /* (the DSA API wants DER encoding for instance) */
1700
1701 switch(sig_algo) {
1702 case LDNS_RSAMD5:
1703 case LDNS_RSASHA1:
1704 case LDNS_RSASHA1_NSEC3:
1705#ifdef USE_SHA2
1706 case LDNS_RSASHA256:
1707 case LDNS_RSASHA512:
1708#endif
1709#ifdef USE_GOST
1710 case LDNS_GOST:
1711#endif
1712 if (ldns_rdf2buffer_wire(rawsig_buf,
1713 ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
1714 return LDNS_STATUS_MEM_ERR;
1715 }
1716 break;
1717 case LDNS_DSA:
1718 case LDNS_DSA_NSEC3:
1719 /* EVP takes rfc2459 format, which is a tad longer than dns format */
1720 if (ldns_convert_dsa_rrsig_rdf2asn1(rawsig_buf,
1721 ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
1722 /*
1723 if (ldns_rdf2buffer_wire(rawsig_buf,
1724 ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
1725 */
1726 return LDNS_STATUS_MEM_ERR;
1727 }
1728 break;
1729 case LDNS_DH:
1730 case LDNS_ECC:
1731 case LDNS_INDIRECT:
1732 return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
1733 default:
1734 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
1735 }
1736 return LDNS_STATUS_OK;
1737}
1738
1739/**
1740 * Check RRSIG timestamps against the given 'now' time.
1741 * @param rrsig: signature to check.
1742 * @param now: the current time in seconds epoch.
1743 * @return status code LDNS_STATUS_OK if all is fine.
1744 */
1745static ldns_status
1746ldns_rrsig_check_timestamps(ldns_rr* rrsig, int32_t now)
1747{
1748 int32_t inception, expiration;
1749
1750 /* check the signature time stamps */
1751 inception = (int32_t)ldns_rdf2native_time_t(
1752 ldns_rr_rrsig_inception(rrsig));
1753 expiration = (int32_t)ldns_rdf2native_time_t(
1754 ldns_rr_rrsig_expiration(rrsig));
1755
1756 if (expiration - inception < 0) {
1757 /* bad sig, expiration before inception?? Tsssg */
1758 return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
1759 }
1760 if (now - inception < 0) {
1761 /* bad sig, inception date has not yet come to pass */
1762 return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
1763 }
1764 if (expiration - now < 0) {
1765 /* bad sig, expiration date has passed */
1766 return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
1767 }
1768 return LDNS_STATUS_OK;
1769}
1770
1771/**
1772 * Prepare for verification.
1773 * @param rawsig_buf: raw signature buffer made ready.
1774 * @param verify_buf: data for verification buffer made ready.
1775 * @param rrset_clone: made ready.
1776 * @param rrsig: signature to prepare for.
1777 * @return LDNS_STATUS_OK is all went well. Otherwise specific error.
1778 */
1779static ldns_status
1780ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
1781 ldns_rr_list* rrset_clone, ldns_rr* rrsig)
1782{
1783 ldns_status result;
1784
1785 /* canonicalize the sig */
1786 ldns_dname2canonical(ldns_rr_owner(rrsig));
1787
1788 /* check if the typecovered is equal to the type checked */
1789 if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)) !=
1790 ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0)))
1791 return LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR;
1792
1793 /* create a buffer with b64 signature rdata */
1794 result = ldns_rrsig2rawsig_buffer(rawsig_buf, rrsig);
1795 if(result != LDNS_STATUS_OK)
1796 return result;
1797
1798 /* use TTL from signature. Use wildcard names for wildcards */
1799 /* also canonicalizes rrset_clone */
1800 ldns_rrset_use_signature_ttl(rrset_clone, rrsig);
1801
1802 /* sort the rrset in canonical order */
1803 ldns_rr_list_sort(rrset_clone);
1804
1805 /* put the signature rr (without the b64) to the verify_buf */
1806 if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK)
1807 return LDNS_STATUS_MEM_ERR;
1808
1809 /* add the rrset in verify_buf */
1810 if(ldns_rr_list2buffer_wire(verify_buf, rrset_clone)
1811 != LDNS_STATUS_OK)
1812 return LDNS_STATUS_MEM_ERR;
1813
1814 return LDNS_STATUS_OK;
1815}
1816
1817/**
1818 * Check if a key matches a signature.
1819 * Checks keytag, sigalgo and signature.
1820 * @param rawsig_buf: raw signature buffer for verify
1821 * @param verify_buf: raw data buffer for verify
1822 * @param rrsig: the rrsig
1823 * @param key: key to attempt.
1824 * @return LDNS_STATUS_OK if OK, else some specific error.
1825 */
1826static ldns_status
1827ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
1828 ldns_rr* rrsig, ldns_rr* key)
1829{
1830 uint8_t sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
1831
1832 /* before anything, check if the keytags match */
1833 if (ldns_calc_keytag(key)
1834 ==
1835 ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
1836 ) {
1837 ldns_buffer* key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
1838 ldns_status result = LDNS_STATUS_ERR;
1839
1840 /* put the key-data in a buffer, that's the third rdf, with
1841 * the base64 encoded key data */
1842 if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3))
1843 != LDNS_STATUS_OK) {
1844 ldns_buffer_free(key_buf);
1845 /* returning is bad might screw up
1846 good keys later in the list
1847 what to do? */
1848 return LDNS_STATUS_ERR;
1849 }
1850
1851 if (sig_algo == ldns_rdf2native_int8(ldns_rr_rdf(key, 2))) {
1852 result = ldns_verify_rrsig_buffers(rawsig_buf,
1853 verify_buf, key_buf, sig_algo);
1854 } else {
1855 /* No keys with the corresponding algorithm are found */
1856 result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
1857 }
1858
1859 ldns_buffer_free(key_buf);
1860 return result;
1861 }
1862 else {
1863 /* No keys with the corresponding keytag are found */
1864 return LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
1865 }
1866}
1867
1868/*
1869 * to verify:
1870 * - create the wire fmt of the b64 key rdata
1871 * - create the wire fmt of the sorted rrset
1872 * - create the wire fmt of the b64 sig rdata
1873 * - create the wire fmt of the sig without the b64 rdata
1874 * - cat the sig data (without b64 rdata) to the rrset
1875 * - verify the rrset+sig, with the b64 data and the b64 key data
1876 */
1877ldns_status
1878ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
1879 ldns_rr *rrsig,
1880 const ldns_rr_list *keys,
1881 ldns_rr_list *good_keys)
1882{
1883 ldns_status result;
1884 ldns_rr_list *valid = ldns_rr_list_new();
1885 if (!valid)
1886 return LDNS_STATUS_MEM_ERR;
1887
1888 result = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, valid);
1889 if(result != LDNS_STATUS_OK) {
1890 ldns_rr_list_free(valid);
1891 return result;
1892 }
1893
1894 /* check timestamps last; its OK except time */
1895 result = ldns_rrsig_check_timestamps(rrsig, (int32_t)time(NULL));
1896 if(result != LDNS_STATUS_OK) {
1897 ldns_rr_list_free(valid);
1898 return result;
1899 }
1900
1901 ldns_rr_list_cat(good_keys, valid);
1902 ldns_rr_list_free(valid);
1903 return LDNS_STATUS_OK;
1904}
1905
1906ldns_status
1907ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset,
1908 ldns_rr *rrsig,
1909 const ldns_rr_list *keys,
1910 ldns_rr_list *good_keys)
1911{
1912 ldns_buffer *rawsig_buf;
1913 ldns_buffer *verify_buf;
1914 uint16_t i;
1915 ldns_status result, status;
1916 ldns_rr_list *rrset_clone;
1917 ldns_rr_list *validkeys;
1918
1919 if (!rrset) {
1920 return LDNS_STATUS_ERR;
1921 }
1922
1923 validkeys = ldns_rr_list_new();
1924 if (!validkeys) {
1925 return LDNS_STATUS_MEM_ERR;
1926 }
1927
1928 /* clone the rrset so that we can fiddle with it */
1929 rrset_clone = ldns_rr_list_clone(rrset);
1930
1931 /* create the buffers which will certainly hold the raw data */
1932 rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
1933 verify_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
1934
1935 result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
1936 rrset_clone, rrsig);
1937 if(result != LDNS_STATUS_OK) {
1938 ldns_buffer_free(verify_buf);
1939 ldns_buffer_free(rawsig_buf);
1940 ldns_rr_list_deep_free(rrset_clone);
1941 ldns_rr_list_free(validkeys);
1942 return result;
1943 }
1944 result = LDNS_STATUS_ERR;
1945
1946 for(i = 0; i < ldns_rr_list_rr_count(keys); i++) {
1947 status = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
1948 rrsig, ldns_rr_list_rr(keys, i));
1949 if (status == LDNS_STATUS_OK) {
1950 /* one of the keys has matched, don't break
1951 * here, instead put the 'winning' key in
1952 * the validkey list and return the list
1953 * later */
1954 if (!ldns_rr_list_push_rr(validkeys,
1955 ldns_rr_list_rr(keys,i))) {
1956 /* couldn't push the key?? */
1957 ldns_buffer_free(rawsig_buf);
1958 ldns_buffer_free(verify_buf);
1959 ldns_rr_list_deep_free(rrset_clone);
1960 ldns_rr_list_free(validkeys);
1961 return LDNS_STATUS_MEM_ERR;
1962 }
1963 /* reset no keytag match error */
1964 result = LDNS_STATUS_ERR;
1965 }
1966 if (result == LDNS_STATUS_ERR) {
1967 result = status;
1968 }
1969 }
1970
1971 /* no longer needed */
1972 ldns_rr_list_deep_free(rrset_clone);
1973 ldns_buffer_free(rawsig_buf);
1974 ldns_buffer_free(verify_buf);
1975
1976 if (ldns_rr_list_rr_count(validkeys) == 0) {
1977 /* no keys were added, return last error */
1978 ldns_rr_list_free(validkeys);
1979 return result;
1980 }
1981
1982 /* do not check timestamps */
1983
1984 ldns_rr_list_cat(good_keys, validkeys);
1985 ldns_rr_list_free(validkeys);
1986 return LDNS_STATUS_OK;
1987}
1988
1989ldns_status
1990ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
1991{
1992 ldns_buffer *rawsig_buf;
1993 ldns_buffer *verify_buf;
1994 ldns_status result;
1995 ldns_rr_list *rrset_clone;
1996
1997 if (!rrset) {
1998 return LDNS_STATUS_NO_DATA;
1999 }
2000 /* clone the rrset so that we can fiddle with it */
2001 rrset_clone = ldns_rr_list_clone(rrset);
2002 /* create the buffers which will certainly hold the raw data */
2003 rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2004 verify_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2005
2006 result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
2007 rrset_clone, rrsig);
2008 if(result != LDNS_STATUS_OK) {
2009 ldns_rr_list_deep_free(rrset_clone);
2010 ldns_buffer_free(rawsig_buf);
2011 ldns_buffer_free(verify_buf);
2012 return result;
2013 }
2014 result = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
2015 rrsig, key);
2016 /* no longer needed */
2017 ldns_rr_list_deep_free(rrset_clone);
2018 ldns_buffer_free(rawsig_buf);
2019 ldns_buffer_free(verify_buf);
2020
2021 /* check timestamp last, apart from time its OK */
2022 if(result == LDNS_STATUS_OK)
2023 result = ldns_rrsig_check_timestamps(rrsig,
2024 (int32_t)time(NULL));
2025
2026 return result;
2027}
2028
2029ldns_status
2030ldns_verify_rrsig_evp(ldns_buffer *sig,
2031 ldns_buffer *rrset,
2032 EVP_PKEY *key,
2033 const EVP_MD *digest_type)
2034{
2035 return ldns_verify_rrsig_evp_raw(
2036 (unsigned char*)ldns_buffer_begin(sig),
2037 ldns_buffer_position(sig),
2038 rrset,
2039 key,
2040 digest_type);
2041}
2042
2043ldns_status
2044ldns_verify_rrsig_evp_raw(unsigned char *sig, size_t siglen,
2045 ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
2046{
2047 EVP_MD_CTX ctx;
2048 int res;
2049
2050 EVP_MD_CTX_init(&ctx);
2051
2052 EVP_VerifyInit(&ctx, digest_type);
2053 EVP_VerifyUpdate(&ctx,
2054 ldns_buffer_begin(rrset),
2055 ldns_buffer_position(rrset));
2056 res = EVP_VerifyFinal(&ctx, sig, (unsigned int) siglen, key);
2057
2058 EVP_MD_CTX_cleanup(&ctx);
2059
2060 if (res == 1) {
2061 return LDNS_STATUS_OK;
2062 } else if (res == 0) {
2063 return LDNS_STATUS_CRYPTO_BOGUS;
2064 }
2065 /* TODO how to communicate internal SSL error?
2066 let caller use ssl's get_error() */
2067 return LDNS_STATUS_SSL_ERR;
2068}
2069
2070ldns_status
2071ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2072{
2073 return ldns_verify_rrsig_dsa_raw(
2074 (unsigned char*) ldns_buffer_begin(sig),
2075 ldns_buffer_position(sig),
2076 rrset,
2077 (unsigned char*) ldns_buffer_begin(key),
2078 ldns_buffer_position(key));
2079}
2080
2081ldns_status
2082ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2083{
2084 return ldns_verify_rrsig_rsasha1_raw(
2085 (unsigned char*)ldns_buffer_begin(sig),
2086 ldns_buffer_position(sig),
2087 rrset,
2088 (unsigned char*) ldns_buffer_begin(key),
2089 ldns_buffer_position(key));
2090}
2091
2092ldns_status
2093ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
2094{
2095 return ldns_verify_rrsig_rsamd5_raw(
2096 (unsigned char*)ldns_buffer_begin(sig),
2097 ldns_buffer_position(sig),
2098 rrset,
2099 (unsigned char*) ldns_buffer_begin(key),
2100 ldns_buffer_position(key));
2101}
2102
2103ldns_status
2104ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
2105 ldns_buffer* rrset, unsigned char* key, size_t keylen)
2106{
2107 EVP_PKEY *evp_key;
2108 ldns_status result;
2109
2110 evp_key = EVP_PKEY_new();
2111 EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen));
2112 result = ldns_verify_rrsig_evp_raw(sig,
2113 siglen,
2114 rrset,
2115 evp_key,
2116 EVP_dss1());
2117 EVP_PKEY_free(evp_key);
2118 return result;
2119
2120}
2121
2122ldns_status
2123ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen,
2124 ldns_buffer* rrset, unsigned char* key, size_t keylen)
2125{
2126 EVP_PKEY *evp_key;
2127 ldns_status result;
2128
2129 evp_key = EVP_PKEY_new();
2130 EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
2131 result = ldns_verify_rrsig_evp_raw(sig,
2132 siglen,
2133 rrset,
2134 evp_key,
2135 EVP_sha1());
2136 EVP_PKEY_free(evp_key);
2137
2138 return result;
2139}
2140
2141ldns_status
2142ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
2143 size_t siglen,
2144 ldns_buffer* rrset,
2145 unsigned char* key,
2146 size_t keylen)
2147{
2148#ifdef USE_SHA2
2149 EVP_PKEY *evp_key;
2150 ldns_status result;
2151
2152 evp_key = EVP_PKEY_new();
2153 EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
2154 result = ldns_verify_rrsig_evp_raw(sig,
2155 siglen,
2156 rrset,
2157 evp_key,
2158 EVP_sha256());
2159 EVP_PKEY_free(evp_key);
2160
2161 return result;
2162#else
2163 /* touch these to prevent compiler warnings */
2164 (void) sig;
2165 (void) siglen;
2166 (void) rrset;
2167 (void) key;
2168 (void) keylen;
2169 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2170#endif
2171}
2172
2173ldns_status
2174ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
2175 size_t siglen,
2176 ldns_buffer* rrset,
2177 unsigned char* key,
2178 size_t keylen)
2179{
2180#ifdef USE_SHA2
2181 EVP_PKEY *evp_key;
2182 ldns_status result;
2183
2184 evp_key = EVP_PKEY_new();
2185 EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
2186 result = ldns_verify_rrsig_evp_raw(sig,
2187 siglen,
2188 rrset,
2189 evp_key,
2190 EVP_sha512());
2191 EVP_PKEY_free(evp_key);
2192
2193 return result;
2194#else
2195 /* touch these to prevent compiler warnings */
2196 (void) sig;
2197 (void) siglen;
2198 (void) rrset;
2199 (void) key;
2200 (void) keylen;
2201 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
2202#endif
2203}
2204
2205
2206ldns_status
2207ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
2208 size_t siglen,
2209 ldns_buffer* rrset,
2210 unsigned char* key,
2211 size_t keylen)
2212{
2213 EVP_PKEY *evp_key;
2214 ldns_status result;
2215
2216 evp_key = EVP_PKEY_new();
2217 EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
2218 result = ldns_verify_rrsig_evp_raw(sig,
2219 siglen,
2220 rrset,
2221 evp_key,
2222 EVP_md5());
2223 EVP_PKEY_free(evp_key);
2224
2225 return result;
2226}
2227
2228#endif