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