17b5038d7SDag-Erling Smørgrav #include <ldns/config.h>
27b5038d7SDag-Erling Smørgrav
37b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h>
47b5038d7SDag-Erling Smørgrav
57b5038d7SDag-Erling Smørgrav #include <strings.h>
67b5038d7SDag-Erling Smørgrav #include <time.h>
77b5038d7SDag-Erling Smørgrav
87b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
97b5038d7SDag-Erling Smørgrav /* this entire file is rather useless when you don't have
107b5038d7SDag-Erling Smørgrav * crypto...
117b5038d7SDag-Erling Smørgrav */
127b5038d7SDag-Erling Smørgrav #include <openssl/ssl.h>
137b5038d7SDag-Erling Smørgrav #include <openssl/evp.h>
147b5038d7SDag-Erling Smørgrav #include <openssl/rand.h>
157b5038d7SDag-Erling Smørgrav #include <openssl/err.h>
167b5038d7SDag-Erling Smørgrav #include <openssl/md5.h>
177b5038d7SDag-Erling Smørgrav
187b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *
ldns_dnssec_data_chain_new(void)197b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_new(void)
207b5038d7SDag-Erling Smørgrav {
217b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *nc = LDNS_CALLOC(ldns_dnssec_data_chain, 1);
227b5038d7SDag-Erling Smørgrav if(!nc) return NULL;
237b5038d7SDag-Erling Smørgrav /*
24*5afab0e5SDag-Erling Smørgrav * not needed anymore because CALLOC initializes everything to zero.
257b5038d7SDag-Erling Smørgrav
267b5038d7SDag-Erling Smørgrav nc->rrset = NULL;
277b5038d7SDag-Erling Smørgrav nc->parent_type = 0;
287b5038d7SDag-Erling Smørgrav nc->parent = NULL;
297b5038d7SDag-Erling Smørgrav nc->signatures = NULL;
307b5038d7SDag-Erling Smørgrav nc->packet_rcode = 0;
317b5038d7SDag-Erling Smørgrav nc->packet_qtype = 0;
327b5038d7SDag-Erling Smørgrav nc->packet_nodata = false;
337b5038d7SDag-Erling Smørgrav
347b5038d7SDag-Erling Smørgrav */
357b5038d7SDag-Erling Smørgrav return nc;
367b5038d7SDag-Erling Smørgrav }
377b5038d7SDag-Erling Smørgrav
387b5038d7SDag-Erling Smørgrav void
ldns_dnssec_data_chain_free(ldns_dnssec_data_chain * chain)397b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_free(ldns_dnssec_data_chain *chain)
407b5038d7SDag-Erling Smørgrav {
417b5038d7SDag-Erling Smørgrav LDNS_FREE(chain);
427b5038d7SDag-Erling Smørgrav }
437b5038d7SDag-Erling Smørgrav
447b5038d7SDag-Erling Smørgrav void
ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain * chain)457b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain)
467b5038d7SDag-Erling Smørgrav {
477b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(chain->rrset);
487b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(chain->signatures);
497b5038d7SDag-Erling Smørgrav if (chain->parent) {
507b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_deep_free(chain->parent);
517b5038d7SDag-Erling Smørgrav }
527b5038d7SDag-Erling Smørgrav LDNS_FREE(chain);
537b5038d7SDag-Erling Smørgrav }
547b5038d7SDag-Erling Smørgrav
557b5038d7SDag-Erling Smørgrav void
ldns_dnssec_data_chain_print_fmt(FILE * out,const ldns_output_format * fmt,const ldns_dnssec_data_chain * chain)567b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_print_fmt(FILE *out, const ldns_output_format *fmt,
577b5038d7SDag-Erling Smørgrav const ldns_dnssec_data_chain *chain)
587b5038d7SDag-Erling Smørgrav {
597b5038d7SDag-Erling Smørgrav ldns_lookup_table *rcode;
607b5038d7SDag-Erling Smørgrav const ldns_rr_descriptor *rr_descriptor;
617b5038d7SDag-Erling Smørgrav if (chain) {
627b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_print_fmt(out, fmt, chain->parent);
637b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(chain->rrset) > 0) {
647b5038d7SDag-Erling Smørgrav rcode = ldns_lookup_by_id(ldns_rcodes,
657b5038d7SDag-Erling Smørgrav (int) chain->packet_rcode);
667b5038d7SDag-Erling Smørgrav if (rcode) {
677b5038d7SDag-Erling Smørgrav fprintf(out, ";; rcode: %s\n", rcode->name);
687b5038d7SDag-Erling Smørgrav }
697b5038d7SDag-Erling Smørgrav
707b5038d7SDag-Erling Smørgrav rr_descriptor = ldns_rr_descript(chain->packet_qtype);
717b5038d7SDag-Erling Smørgrav if (rr_descriptor && rr_descriptor->_name) {
727b5038d7SDag-Erling Smørgrav fprintf(out, ";; qtype: %s\n", rr_descriptor->_name);
737b5038d7SDag-Erling Smørgrav } else if (chain->packet_qtype != 0) {
747b5038d7SDag-Erling Smørgrav fprintf(out, "TYPE%u",
757b5038d7SDag-Erling Smørgrav chain->packet_qtype);
767b5038d7SDag-Erling Smørgrav }
777b5038d7SDag-Erling Smørgrav if (chain->packet_nodata) {
787b5038d7SDag-Erling Smørgrav fprintf(out, ";; NODATA response\n");
797b5038d7SDag-Erling Smørgrav }
807b5038d7SDag-Erling Smørgrav fprintf(out, "rrset:\n");
817b5038d7SDag-Erling Smørgrav ldns_rr_list_print_fmt(out, fmt, chain->rrset);
827b5038d7SDag-Erling Smørgrav fprintf(out, "sigs:\n");
837b5038d7SDag-Erling Smørgrav ldns_rr_list_print_fmt(out, fmt, chain->signatures);
847b5038d7SDag-Erling Smørgrav fprintf(out, "---\n");
857b5038d7SDag-Erling Smørgrav } else {
867b5038d7SDag-Erling Smørgrav fprintf(out, "<no data>\n");
877b5038d7SDag-Erling Smørgrav }
887b5038d7SDag-Erling Smørgrav }
897b5038d7SDag-Erling Smørgrav }
907b5038d7SDag-Erling Smørgrav void
ldns_dnssec_data_chain_print(FILE * out,const ldns_dnssec_data_chain * chain)917b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain)
927b5038d7SDag-Erling Smørgrav {
937b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain_print_fmt(
947b5038d7SDag-Erling Smørgrav out, ldns_output_format_default, chain);
957b5038d7SDag-Erling Smørgrav }
967b5038d7SDag-Erling Smørgrav
977b5038d7SDag-Erling Smørgrav
987b5038d7SDag-Erling Smørgrav static void
ldns_dnssec_build_data_chain_dnskey(ldns_resolver * res,uint16_t qflags,const ldns_pkt * pkt,ldns_rr_list * signatures,ldns_dnssec_data_chain * new_chain,ldns_rdf * key_name,ldns_rr_class c)997b5038d7SDag-Erling Smørgrav ldns_dnssec_build_data_chain_dnskey(ldns_resolver *res,
1007b5038d7SDag-Erling Smørgrav uint16_t qflags,
1017b5038d7SDag-Erling Smørgrav const ldns_pkt *pkt,
1027b5038d7SDag-Erling Smørgrav ldns_rr_list *signatures,
1037b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *new_chain,
1047b5038d7SDag-Erling Smørgrav ldns_rdf *key_name,
1057b5038d7SDag-Erling Smørgrav ldns_rr_class c) {
1067b5038d7SDag-Erling Smørgrav ldns_rr_list *keys;
1077b5038d7SDag-Erling Smørgrav ldns_pkt *my_pkt;
1087b5038d7SDag-Erling Smørgrav if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
1097b5038d7SDag-Erling Smørgrav new_chain->signatures = ldns_rr_list_clone(signatures);
1107b5038d7SDag-Erling Smørgrav new_chain->parent_type = 0;
1117b5038d7SDag-Erling Smørgrav
1127b5038d7SDag-Erling Smørgrav keys = ldns_pkt_rr_list_by_name_and_type(
1137b5038d7SDag-Erling Smørgrav pkt,
1147b5038d7SDag-Erling Smørgrav key_name,
1157b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DNSKEY,
1167b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY_NOQUESTION
1177b5038d7SDag-Erling Smørgrav );
1187b5038d7SDag-Erling Smørgrav if (!keys) {
1197b5038d7SDag-Erling Smørgrav my_pkt = ldns_resolver_query(res,
1207b5038d7SDag-Erling Smørgrav key_name,
1217b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DNSKEY,
1227b5038d7SDag-Erling Smørgrav c,
1237b5038d7SDag-Erling Smørgrav qflags);
1247b5038d7SDag-Erling Smørgrav if (my_pkt) {
1257b5038d7SDag-Erling Smørgrav keys = ldns_pkt_rr_list_by_name_and_type(
1267b5038d7SDag-Erling Smørgrav my_pkt,
1277b5038d7SDag-Erling Smørgrav key_name,
1287b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DNSKEY,
1297b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY_NOQUESTION
1307b5038d7SDag-Erling Smørgrav );
1317b5038d7SDag-Erling Smørgrav new_chain->parent = ldns_dnssec_build_data_chain(res,
1327b5038d7SDag-Erling Smørgrav qflags,
1337b5038d7SDag-Erling Smørgrav keys,
1347b5038d7SDag-Erling Smørgrav my_pkt,
1357b5038d7SDag-Erling Smørgrav NULL);
1367b5038d7SDag-Erling Smørgrav new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
1377b5038d7SDag-Erling Smørgrav ldns_pkt_free(my_pkt);
1387b5038d7SDag-Erling Smørgrav }
1397b5038d7SDag-Erling Smørgrav } else {
1407b5038d7SDag-Erling Smørgrav new_chain->parent = ldns_dnssec_build_data_chain(res,
1417b5038d7SDag-Erling Smørgrav qflags,
1427b5038d7SDag-Erling Smørgrav keys,
1437b5038d7SDag-Erling Smørgrav pkt,
1447b5038d7SDag-Erling Smørgrav NULL);
1457b5038d7SDag-Erling Smørgrav new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
1467b5038d7SDag-Erling Smørgrav }
1477b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(keys);
1487b5038d7SDag-Erling Smørgrav }
1497b5038d7SDag-Erling Smørgrav }
1507b5038d7SDag-Erling Smørgrav
1517b5038d7SDag-Erling Smørgrav static void
ldns_dnssec_build_data_chain_other(ldns_resolver * res,uint16_t qflags,ldns_dnssec_data_chain * new_chain,ldns_rdf * key_name,ldns_rr_class c,ldns_rr_list * dss)1527b5038d7SDag-Erling Smørgrav ldns_dnssec_build_data_chain_other(ldns_resolver *res,
1537b5038d7SDag-Erling Smørgrav uint16_t qflags,
1547b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *new_chain,
1557b5038d7SDag-Erling Smørgrav ldns_rdf *key_name,
1567b5038d7SDag-Erling Smørgrav ldns_rr_class c,
1577b5038d7SDag-Erling Smørgrav ldns_rr_list *dss)
1587b5038d7SDag-Erling Smørgrav {
1597b5038d7SDag-Erling Smørgrav /* 'self-signed', parent is a DS */
1607b5038d7SDag-Erling Smørgrav
1617b5038d7SDag-Erling Smørgrav /* okay, either we have other keys signing the current one,
1627b5038d7SDag-Erling Smørgrav * or the current
1637b5038d7SDag-Erling Smørgrav * one should have a DS record in the parent zone.
1647b5038d7SDag-Erling Smørgrav * How do we find this out? Try both?
1657b5038d7SDag-Erling Smørgrav *
1667b5038d7SDag-Erling Smørgrav * request DNSKEYS for current zone,
1677b5038d7SDag-Erling Smørgrav * add all signatures to current level
1687b5038d7SDag-Erling Smørgrav */
1697b5038d7SDag-Erling Smørgrav ldns_pkt *my_pkt;
1707b5038d7SDag-Erling Smørgrav ldns_rr_list *signatures2;
1717b5038d7SDag-Erling Smørgrav
1727b5038d7SDag-Erling Smørgrav new_chain->parent_type = 1;
1737b5038d7SDag-Erling Smørgrav
1747b5038d7SDag-Erling Smørgrav my_pkt = ldns_resolver_query(res,
1757b5038d7SDag-Erling Smørgrav key_name,
1767b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DS,
1777b5038d7SDag-Erling Smørgrav c,
1787b5038d7SDag-Erling Smørgrav qflags);
1797b5038d7SDag-Erling Smørgrav if (my_pkt) {
1807b5038d7SDag-Erling Smørgrav dss = ldns_pkt_rr_list_by_name_and_type(my_pkt,
1817b5038d7SDag-Erling Smørgrav key_name,
1827b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DS,
1837b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY_NOQUESTION
1847b5038d7SDag-Erling Smørgrav );
1857b5038d7SDag-Erling Smørgrav if (dss) {
1867b5038d7SDag-Erling Smørgrav new_chain->parent = ldns_dnssec_build_data_chain(res,
1877b5038d7SDag-Erling Smørgrav qflags,
1887b5038d7SDag-Erling Smørgrav dss,
1897b5038d7SDag-Erling Smørgrav my_pkt,
1907b5038d7SDag-Erling Smørgrav NULL);
1917b5038d7SDag-Erling Smørgrav new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
1927b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(dss);
1937b5038d7SDag-Erling Smørgrav }
1947b5038d7SDag-Erling Smørgrav ldns_pkt_free(my_pkt);
1957b5038d7SDag-Erling Smørgrav }
1967b5038d7SDag-Erling Smørgrav
1977b5038d7SDag-Erling Smørgrav my_pkt = ldns_resolver_query(res,
1987b5038d7SDag-Erling Smørgrav key_name,
1997b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DNSKEY,
2007b5038d7SDag-Erling Smørgrav c,
2017b5038d7SDag-Erling Smørgrav qflags);
2027b5038d7SDag-Erling Smørgrav if (my_pkt) {
2037b5038d7SDag-Erling Smørgrav signatures2 = ldns_pkt_rr_list_by_name_and_type(my_pkt,
2047b5038d7SDag-Erling Smørgrav key_name,
2057b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_RRSIG,
2067b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANSWER);
2077b5038d7SDag-Erling Smørgrav if (signatures2) {
2087b5038d7SDag-Erling Smørgrav if (new_chain->signatures) {
2097b5038d7SDag-Erling Smørgrav printf("There were already sigs!\n");
2107b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(new_chain->signatures);
2117b5038d7SDag-Erling Smørgrav printf("replacing the old sigs\n");
2127b5038d7SDag-Erling Smørgrav }
2137b5038d7SDag-Erling Smørgrav new_chain->signatures = signatures2;
2147b5038d7SDag-Erling Smørgrav }
2157b5038d7SDag-Erling Smørgrav ldns_pkt_free(my_pkt);
2167b5038d7SDag-Erling Smørgrav }
2177b5038d7SDag-Erling Smørgrav }
2187b5038d7SDag-Erling Smørgrav
2197b5038d7SDag-Erling Smørgrav static ldns_dnssec_data_chain *
ldns_dnssec_build_data_chain_nokeyname(ldns_resolver * res,uint16_t qflags,ldns_rr * orig_rr,const ldns_rr_list * rrset,ldns_dnssec_data_chain * new_chain)2207b5038d7SDag-Erling Smørgrav ldns_dnssec_build_data_chain_nokeyname(ldns_resolver *res,
2217b5038d7SDag-Erling Smørgrav uint16_t qflags,
2227b5038d7SDag-Erling Smørgrav ldns_rr *orig_rr,
2237b5038d7SDag-Erling Smørgrav const ldns_rr_list *rrset,
2247b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *new_chain)
2257b5038d7SDag-Erling Smørgrav {
2267b5038d7SDag-Erling Smørgrav ldns_rdf *possible_parent_name;
2277b5038d7SDag-Erling Smørgrav ldns_pkt *my_pkt;
2287b5038d7SDag-Erling Smørgrav /* apparently we were not able to find a signing key, so
2297b5038d7SDag-Erling Smørgrav we assume the chain ends here
2307b5038d7SDag-Erling Smørgrav */
2317b5038d7SDag-Erling Smørgrav /* try parents for auth denial of DS */
2327b5038d7SDag-Erling Smørgrav if (orig_rr) {
2337b5038d7SDag-Erling Smørgrav possible_parent_name = ldns_rr_owner(orig_rr);
2347b5038d7SDag-Erling Smørgrav } else if (rrset && ldns_rr_list_rr_count(rrset) > 0) {
2357b5038d7SDag-Erling Smørgrav possible_parent_name = ldns_rr_owner(ldns_rr_list_rr(rrset, 0));
2367b5038d7SDag-Erling Smørgrav } else {
2377b5038d7SDag-Erling Smørgrav /* no information to go on, give up */
2387b5038d7SDag-Erling Smørgrav return new_chain;
2397b5038d7SDag-Erling Smørgrav }
2407b5038d7SDag-Erling Smørgrav
2417b5038d7SDag-Erling Smørgrav my_pkt = ldns_resolver_query(res,
2427b5038d7SDag-Erling Smørgrav possible_parent_name,
2437b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DS,
2447b5038d7SDag-Erling Smørgrav LDNS_RR_CLASS_IN,
2457b5038d7SDag-Erling Smørgrav qflags);
2467b5038d7SDag-Erling Smørgrav if (!my_pkt) {
2477b5038d7SDag-Erling Smørgrav return new_chain;
2487b5038d7SDag-Erling Smørgrav }
2497b5038d7SDag-Erling Smørgrav
2507b5038d7SDag-Erling Smørgrav if (ldns_pkt_ancount(my_pkt) > 0) {
2517b5038d7SDag-Erling Smørgrav /* add error, no sigs but DS in parent */
2527b5038d7SDag-Erling Smørgrav /*ldns_pkt_print(stdout, my_pkt);*/
2537b5038d7SDag-Erling Smørgrav ldns_pkt_free(my_pkt);
2547b5038d7SDag-Erling Smørgrav } else {
2557b5038d7SDag-Erling Smørgrav /* are there signatures? */
2567b5038d7SDag-Erling Smørgrav new_chain->parent = ldns_dnssec_build_data_chain(res,
2577b5038d7SDag-Erling Smørgrav qflags,
2587b5038d7SDag-Erling Smørgrav NULL,
2597b5038d7SDag-Erling Smørgrav my_pkt,
2607b5038d7SDag-Erling Smørgrav NULL);
2617b5038d7SDag-Erling Smørgrav
2627b5038d7SDag-Erling Smørgrav new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
2637b5038d7SDag-Erling Smørgrav
2647b5038d7SDag-Erling Smørgrav }
2657b5038d7SDag-Erling Smørgrav return new_chain;
2667b5038d7SDag-Erling Smørgrav }
2677b5038d7SDag-Erling Smørgrav
2687b5038d7SDag-Erling Smørgrav
2697b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *
ldns_dnssec_build_data_chain(ldns_resolver * res,uint16_t qflags,const ldns_rr_list * rrset,const ldns_pkt * pkt,ldns_rr * orig_rr)2707b5038d7SDag-Erling Smørgrav ldns_dnssec_build_data_chain(ldns_resolver *res,
2717b5038d7SDag-Erling Smørgrav uint16_t qflags,
2727b5038d7SDag-Erling Smørgrav const ldns_rr_list *rrset,
2737b5038d7SDag-Erling Smørgrav const ldns_pkt *pkt,
2747b5038d7SDag-Erling Smørgrav ldns_rr *orig_rr)
2757b5038d7SDag-Erling Smørgrav {
2767b5038d7SDag-Erling Smørgrav ldns_rr_list *signatures = NULL;
2777b5038d7SDag-Erling Smørgrav ldns_rr_list *dss = NULL;
2787b5038d7SDag-Erling Smørgrav
2797b5038d7SDag-Erling Smørgrav ldns_rr_list *my_rrset;
2807b5038d7SDag-Erling Smørgrav
2817b5038d7SDag-Erling Smørgrav ldns_pkt *my_pkt;
2827b5038d7SDag-Erling Smørgrav
2837b5038d7SDag-Erling Smørgrav ldns_rdf *name = NULL, *key_name = NULL;
2847b5038d7SDag-Erling Smørgrav ldns_rr_type type = 0;
2857b5038d7SDag-Erling Smørgrav ldns_rr_class c = 0;
2867b5038d7SDag-Erling Smørgrav
2877b5038d7SDag-Erling Smørgrav bool other_rrset = false;
2887b5038d7SDag-Erling Smørgrav
2897b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *new_chain = ldns_dnssec_data_chain_new();
2907b5038d7SDag-Erling Smørgrav
2912787e39aSDag-Erling Smørgrav assert(pkt != NULL);
2922787e39aSDag-Erling Smørgrav
2937b5038d7SDag-Erling Smørgrav if (!ldns_dnssec_pkt_has_rrsigs(pkt)) {
2947b5038d7SDag-Erling Smørgrav /* hmm. no dnssec data in the packet. go up to try and deny
2957b5038d7SDag-Erling Smørgrav * DS? */
2967b5038d7SDag-Erling Smørgrav return new_chain;
2977b5038d7SDag-Erling Smørgrav }
2987b5038d7SDag-Erling Smørgrav
2997b5038d7SDag-Erling Smørgrav if (orig_rr) {
3007b5038d7SDag-Erling Smørgrav new_chain->rrset = ldns_rr_list_new();
3017b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new_chain->rrset, orig_rr);
3027b5038d7SDag-Erling Smørgrav new_chain->parent = ldns_dnssec_build_data_chain(res,
3037b5038d7SDag-Erling Smørgrav qflags,
3047b5038d7SDag-Erling Smørgrav rrset,
3057b5038d7SDag-Erling Smørgrav pkt,
3067b5038d7SDag-Erling Smørgrav NULL);
3077b5038d7SDag-Erling Smørgrav new_chain->packet_rcode = ldns_pkt_get_rcode(pkt);
3087b5038d7SDag-Erling Smørgrav new_chain->packet_qtype = ldns_rr_get_type(orig_rr);
3097b5038d7SDag-Erling Smørgrav if (ldns_pkt_ancount(pkt) == 0) {
3107b5038d7SDag-Erling Smørgrav new_chain->packet_nodata = true;
3117b5038d7SDag-Erling Smørgrav }
3127b5038d7SDag-Erling Smørgrav return new_chain;
3137b5038d7SDag-Erling Smørgrav }
3147b5038d7SDag-Erling Smørgrav
3157b5038d7SDag-Erling Smørgrav if (!rrset || ldns_rr_list_rr_count(rrset) < 1) {
3167b5038d7SDag-Erling Smørgrav /* hmm, no data, do we have denial? only works if pkt was given,
3177b5038d7SDag-Erling Smørgrav otherwise caller has to do the check himself */
3187b5038d7SDag-Erling Smørgrav new_chain->packet_nodata = true;
3197b5038d7SDag-Erling Smørgrav if (pkt) {
3207b5038d7SDag-Erling Smørgrav my_rrset = ldns_pkt_rr_list_by_type(pkt,
3217b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC,
3227b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY_NOQUESTION
3237b5038d7SDag-Erling Smørgrav );
3247b5038d7SDag-Erling Smørgrav if (my_rrset) {
3257b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(my_rrset) > 0) {
3267b5038d7SDag-Erling Smørgrav type = LDNS_RR_TYPE_NSEC;
3277b5038d7SDag-Erling Smørgrav other_rrset = true;
3287b5038d7SDag-Erling Smørgrav } else {
3297b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(my_rrset);
3307b5038d7SDag-Erling Smørgrav my_rrset = NULL;
3317b5038d7SDag-Erling Smørgrav }
3327b5038d7SDag-Erling Smørgrav } else {
3337b5038d7SDag-Erling Smørgrav /* nothing, try nsec3 */
3347b5038d7SDag-Erling Smørgrav my_rrset = ldns_pkt_rr_list_by_type(pkt,
3357b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC3,
3367b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY_NOQUESTION);
3377b5038d7SDag-Erling Smørgrav if (my_rrset) {
3387b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(my_rrset) > 0) {
3397b5038d7SDag-Erling Smørgrav type = LDNS_RR_TYPE_NSEC3;
3407b5038d7SDag-Erling Smørgrav other_rrset = true;
3417b5038d7SDag-Erling Smørgrav } else {
3427b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(my_rrset);
3437b5038d7SDag-Erling Smørgrav my_rrset = NULL;
3447b5038d7SDag-Erling Smørgrav }
3457b5038d7SDag-Erling Smørgrav } else {
3467b5038d7SDag-Erling Smørgrav /* nothing, stop */
3477b5038d7SDag-Erling Smørgrav /* try parent zone? for denied insecure? */
3487b5038d7SDag-Erling Smørgrav return new_chain;
3497b5038d7SDag-Erling Smørgrav }
3507b5038d7SDag-Erling Smørgrav }
3517b5038d7SDag-Erling Smørgrav } else {
3527b5038d7SDag-Erling Smørgrav return new_chain;
3537b5038d7SDag-Erling Smørgrav }
3547b5038d7SDag-Erling Smørgrav } else {
3557b5038d7SDag-Erling Smørgrav my_rrset = (ldns_rr_list *) rrset;
3567b5038d7SDag-Erling Smørgrav }
3577b5038d7SDag-Erling Smørgrav
3587b5038d7SDag-Erling Smørgrav if (my_rrset && ldns_rr_list_rr_count(my_rrset) > 0) {
3597b5038d7SDag-Erling Smørgrav new_chain->rrset = ldns_rr_list_clone(my_rrset);
3607b5038d7SDag-Erling Smørgrav name = ldns_rr_owner(ldns_rr_list_rr(my_rrset, 0));
3617b5038d7SDag-Erling Smørgrav type = ldns_rr_get_type(ldns_rr_list_rr(my_rrset, 0));
3627b5038d7SDag-Erling Smørgrav c = ldns_rr_get_class(ldns_rr_list_rr(my_rrset, 0));
3637b5038d7SDag-Erling Smørgrav }
3647b5038d7SDag-Erling Smørgrav
3657b5038d7SDag-Erling Smørgrav if (other_rrset) {
3667b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(my_rrset);
3677b5038d7SDag-Erling Smørgrav }
3687b5038d7SDag-Erling Smørgrav
3697b5038d7SDag-Erling Smørgrav /* normally there will only be 1 signature 'set'
3707b5038d7SDag-Erling Smørgrav but there can be more than 1 denial (wildcards)
3717b5038d7SDag-Erling Smørgrav so check for NSEC
3727b5038d7SDag-Erling Smørgrav */
3737b5038d7SDag-Erling Smørgrav if (type == LDNS_RR_TYPE_NSEC || type == LDNS_RR_TYPE_NSEC3) {
3747b5038d7SDag-Erling Smørgrav /* just throw in all signatures, the tree builder must sort
3757b5038d7SDag-Erling Smørgrav this out */
3767b5038d7SDag-Erling Smørgrav if (pkt) {
3777b5038d7SDag-Erling Smørgrav signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
3787b5038d7SDag-Erling Smørgrav } else {
3797b5038d7SDag-Erling Smørgrav my_pkt = ldns_resolver_query(res, name, type, c, qflags);
3807b5038d7SDag-Erling Smørgrav if (my_pkt) {
3817b5038d7SDag-Erling Smørgrav signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
3827b5038d7SDag-Erling Smørgrav ldns_pkt_free(my_pkt);
3837b5038d7SDag-Erling Smørgrav }
3847b5038d7SDag-Erling Smørgrav }
3857b5038d7SDag-Erling Smørgrav } else {
3867b5038d7SDag-Erling Smørgrav if (pkt) {
3877b5038d7SDag-Erling Smørgrav signatures =
3887b5038d7SDag-Erling Smørgrav ldns_dnssec_pkt_get_rrsigs_for_name_and_type(pkt,
3897b5038d7SDag-Erling Smørgrav name,
3907b5038d7SDag-Erling Smørgrav type);
3917b5038d7SDag-Erling Smørgrav }
3927b5038d7SDag-Erling Smørgrav if (!signatures) {
3937b5038d7SDag-Erling Smørgrav my_pkt = ldns_resolver_query(res, name, type, c, qflags);
3947b5038d7SDag-Erling Smørgrav if (my_pkt) {
3957b5038d7SDag-Erling Smørgrav signatures =
3967b5038d7SDag-Erling Smørgrav ldns_dnssec_pkt_get_rrsigs_for_name_and_type(my_pkt,
3977b5038d7SDag-Erling Smørgrav name,
3987b5038d7SDag-Erling Smørgrav type);
3997b5038d7SDag-Erling Smørgrav ldns_pkt_free(my_pkt);
4007b5038d7SDag-Erling Smørgrav }
4017b5038d7SDag-Erling Smørgrav }
4027b5038d7SDag-Erling Smørgrav }
4037b5038d7SDag-Erling Smørgrav
4047b5038d7SDag-Erling Smørgrav if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
4057b5038d7SDag-Erling Smørgrav key_name = ldns_rr_rdf(ldns_rr_list_rr(signatures, 0), 7);
4067b5038d7SDag-Erling Smørgrav }
4077b5038d7SDag-Erling Smørgrav if (!key_name) {
4082787e39aSDag-Erling Smørgrav if (signatures) {
4092787e39aSDag-Erling Smørgrav ldns_rr_list_deep_free(signatures);
4102787e39aSDag-Erling Smørgrav }
4117b5038d7SDag-Erling Smørgrav return ldns_dnssec_build_data_chain_nokeyname(res,
4127b5038d7SDag-Erling Smørgrav qflags,
4137b5038d7SDag-Erling Smørgrav orig_rr,
4147b5038d7SDag-Erling Smørgrav rrset,
4157b5038d7SDag-Erling Smørgrav new_chain);
4167b5038d7SDag-Erling Smørgrav }
4177b5038d7SDag-Erling Smørgrav if (type != LDNS_RR_TYPE_DNSKEY) {
418*5afab0e5SDag-Erling Smørgrav if (type != LDNS_RR_TYPE_DS ||
419*5afab0e5SDag-Erling Smørgrav ldns_dname_is_subdomain(name, key_name)) {
4207b5038d7SDag-Erling Smørgrav ldns_dnssec_build_data_chain_dnskey(res,
4217b5038d7SDag-Erling Smørgrav qflags,
4227b5038d7SDag-Erling Smørgrav pkt,
4237b5038d7SDag-Erling Smørgrav signatures,
4247b5038d7SDag-Erling Smørgrav new_chain,
4257b5038d7SDag-Erling Smørgrav key_name,
4267b5038d7SDag-Erling Smørgrav c
4277b5038d7SDag-Erling Smørgrav );
428*5afab0e5SDag-Erling Smørgrav }
4297b5038d7SDag-Erling Smørgrav } else {
4307b5038d7SDag-Erling Smørgrav ldns_dnssec_build_data_chain_other(res,
4317b5038d7SDag-Erling Smørgrav qflags,
4327b5038d7SDag-Erling Smørgrav new_chain,
4337b5038d7SDag-Erling Smørgrav key_name,
4347b5038d7SDag-Erling Smørgrav c,
4357b5038d7SDag-Erling Smørgrav dss
4367b5038d7SDag-Erling Smørgrav );
4377b5038d7SDag-Erling Smørgrav }
4387b5038d7SDag-Erling Smørgrav if (signatures) {
4397b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(signatures);
4407b5038d7SDag-Erling Smørgrav }
4417b5038d7SDag-Erling Smørgrav return new_chain;
4427b5038d7SDag-Erling Smørgrav }
4437b5038d7SDag-Erling Smørgrav
4447b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *
ldns_dnssec_trust_tree_new(void)4457b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_new(void)
4467b5038d7SDag-Erling Smørgrav {
4477b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *new_tree = LDNS_XMALLOC(ldns_dnssec_trust_tree,
4487b5038d7SDag-Erling Smørgrav 1);
4497b5038d7SDag-Erling Smørgrav if(!new_tree) return NULL;
4507b5038d7SDag-Erling Smørgrav new_tree->rr = NULL;
4517b5038d7SDag-Erling Smørgrav new_tree->rrset = NULL;
4527b5038d7SDag-Erling Smørgrav new_tree->parent_count = 0;
4537b5038d7SDag-Erling Smørgrav
4547b5038d7SDag-Erling Smørgrav return new_tree;
4557b5038d7SDag-Erling Smørgrav }
4567b5038d7SDag-Erling Smørgrav
4577b5038d7SDag-Erling Smørgrav void
ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree * tree)4587b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree)
4597b5038d7SDag-Erling Smørgrav {
4607b5038d7SDag-Erling Smørgrav size_t i;
4617b5038d7SDag-Erling Smørgrav if (tree) {
4627b5038d7SDag-Erling Smørgrav for (i = 0; i < tree->parent_count; i++) {
4637b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_free(tree->parents[i]);
4647b5038d7SDag-Erling Smørgrav }
4657b5038d7SDag-Erling Smørgrav }
4667b5038d7SDag-Erling Smørgrav LDNS_FREE(tree);
4677b5038d7SDag-Erling Smørgrav }
4687b5038d7SDag-Erling Smørgrav
4697b5038d7SDag-Erling Smørgrav size_t
ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree * tree)4707b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree)
4717b5038d7SDag-Erling Smørgrav {
4727b5038d7SDag-Erling Smørgrav size_t result = 0;
4737b5038d7SDag-Erling Smørgrav size_t parent = 0;
4747b5038d7SDag-Erling Smørgrav size_t i;
4757b5038d7SDag-Erling Smørgrav
4767b5038d7SDag-Erling Smørgrav for (i = 0; i < tree->parent_count; i++) {
4777b5038d7SDag-Erling Smørgrav parent = ldns_dnssec_trust_tree_depth(tree->parents[i]);
4787b5038d7SDag-Erling Smørgrav if (parent > result) {
4797b5038d7SDag-Erling Smørgrav result = parent;
4807b5038d7SDag-Erling Smørgrav }
4817b5038d7SDag-Erling Smørgrav }
4827b5038d7SDag-Erling Smørgrav return 1 + result;
4837b5038d7SDag-Erling Smørgrav }
4847b5038d7SDag-Erling Smørgrav
4857b5038d7SDag-Erling Smørgrav /* TODO ldns_ */
4867b5038d7SDag-Erling Smørgrav static void
print_tabs(FILE * out,size_t nr,uint8_t * map,size_t treedepth)4877b5038d7SDag-Erling Smørgrav print_tabs(FILE *out, size_t nr, uint8_t *map, size_t treedepth)
4887b5038d7SDag-Erling Smørgrav {
4897b5038d7SDag-Erling Smørgrav size_t i;
4907b5038d7SDag-Erling Smørgrav for (i = 0; i < nr; i++) {
4917b5038d7SDag-Erling Smørgrav if (i == nr - 1) {
4927b5038d7SDag-Erling Smørgrav fprintf(out, "|---");
4937b5038d7SDag-Erling Smørgrav } else if (map && i < treedepth && map[i] == 1) {
4947b5038d7SDag-Erling Smørgrav fprintf(out, "| ");
4957b5038d7SDag-Erling Smørgrav } else {
4967b5038d7SDag-Erling Smørgrav fprintf(out, " ");
4977b5038d7SDag-Erling Smørgrav }
4987b5038d7SDag-Erling Smørgrav }
4997b5038d7SDag-Erling Smørgrav }
5007b5038d7SDag-Erling Smørgrav
5017b5038d7SDag-Erling Smørgrav static void
ldns_dnssec_trust_tree_print_sm_fmt(FILE * out,const ldns_output_format * fmt,ldns_dnssec_trust_tree * tree,size_t tabs,bool extended,uint8_t * sibmap,size_t treedepth)5027b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_print_sm_fmt(FILE *out,
5037b5038d7SDag-Erling Smørgrav const ldns_output_format *fmt,
5047b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *tree,
5057b5038d7SDag-Erling Smørgrav size_t tabs,
5067b5038d7SDag-Erling Smørgrav bool extended,
5077b5038d7SDag-Erling Smørgrav uint8_t *sibmap,
5087b5038d7SDag-Erling Smørgrav size_t treedepth)
5097b5038d7SDag-Erling Smørgrav {
5107b5038d7SDag-Erling Smørgrav size_t i;
5117b5038d7SDag-Erling Smørgrav const ldns_rr_descriptor *descriptor;
5127b5038d7SDag-Erling Smørgrav bool mapset = false;
5137b5038d7SDag-Erling Smørgrav
5147b5038d7SDag-Erling Smørgrav if (!sibmap) {
5157b5038d7SDag-Erling Smørgrav treedepth = ldns_dnssec_trust_tree_depth(tree);
5167b5038d7SDag-Erling Smørgrav sibmap = LDNS_XMALLOC(uint8_t, treedepth);
5177b5038d7SDag-Erling Smørgrav if(!sibmap)
5187b5038d7SDag-Erling Smørgrav return; /* mem err */
5197b5038d7SDag-Erling Smørgrav memset(sibmap, 0, treedepth);
5207b5038d7SDag-Erling Smørgrav mapset = true;
5217b5038d7SDag-Erling Smørgrav }
5227b5038d7SDag-Erling Smørgrav
5237b5038d7SDag-Erling Smørgrav if (tree) {
5247b5038d7SDag-Erling Smørgrav if (tree->rr) {
5257b5038d7SDag-Erling Smørgrav print_tabs(out, tabs, sibmap, treedepth);
5267b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_rr_owner(tree->rr));
5277b5038d7SDag-Erling Smørgrav descriptor = ldns_rr_descript(ldns_rr_get_type(tree->rr));
5287b5038d7SDag-Erling Smørgrav
5297b5038d7SDag-Erling Smørgrav if (descriptor->_name) {
5307b5038d7SDag-Erling Smørgrav fprintf(out, " (%s", descriptor->_name);
5317b5038d7SDag-Erling Smørgrav } else {
5327b5038d7SDag-Erling Smørgrav fprintf(out, " (TYPE%d",
5337b5038d7SDag-Erling Smørgrav ldns_rr_get_type(tree->rr));
5347b5038d7SDag-Erling Smørgrav }
5357b5038d7SDag-Erling Smørgrav if (tabs > 0) {
5367b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DNSKEY) {
5377b5038d7SDag-Erling Smørgrav fprintf(out, " keytag: %u",
5387b5038d7SDag-Erling Smørgrav (unsigned int) ldns_calc_keytag(tree->rr));
5397b5038d7SDag-Erling Smørgrav fprintf(out, " alg: ");
5407b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
5417b5038d7SDag-Erling Smørgrav fprintf(out, " flags: ");
5427b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
5437b5038d7SDag-Erling Smørgrav } else if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DS) {
5447b5038d7SDag-Erling Smørgrav fprintf(out, " keytag: ");
5457b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
5467b5038d7SDag-Erling Smørgrav fprintf(out, " digest type: ");
5477b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
5487b5038d7SDag-Erling Smørgrav }
5497b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NSEC) {
5507b5038d7SDag-Erling Smørgrav fprintf(out, " ");
5517b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
5527b5038d7SDag-Erling Smørgrav fprintf(out, " ");
5537b5038d7SDag-Erling Smørgrav ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 1));
5547b5038d7SDag-Erling Smørgrav }
5557b5038d7SDag-Erling Smørgrav }
5567b5038d7SDag-Erling Smørgrav
5577b5038d7SDag-Erling Smørgrav fprintf(out, ")\n");
5587b5038d7SDag-Erling Smørgrav for (i = 0; i < tree->parent_count; i++) {
5597b5038d7SDag-Erling Smørgrav if (tree->parent_count > 1 && i < tree->parent_count - 1) {
5607b5038d7SDag-Erling Smørgrav sibmap[tabs] = 1;
5617b5038d7SDag-Erling Smørgrav } else {
5627b5038d7SDag-Erling Smørgrav sibmap[tabs] = 0;
5637b5038d7SDag-Erling Smørgrav }
5647b5038d7SDag-Erling Smørgrav /* only print errors */
5657b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(tree->parents[i]->rr) ==
5667b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC ||
5677b5038d7SDag-Erling Smørgrav ldns_rr_get_type(tree->parents[i]->rr) ==
5687b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC3) {
5697b5038d7SDag-Erling Smørgrav if (tree->parent_status[i] == LDNS_STATUS_OK) {
5707b5038d7SDag-Erling Smørgrav print_tabs(out, tabs + 1, sibmap, treedepth);
5717b5038d7SDag-Erling Smørgrav if (tabs == 0 &&
5727b5038d7SDag-Erling Smørgrav ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS &&
5737b5038d7SDag-Erling Smørgrav ldns_rr_rd_count(tree->rr) > 0) {
5747b5038d7SDag-Erling Smørgrav fprintf(out, "Existence of DS is denied by:\n");
5757b5038d7SDag-Erling Smørgrav } else {
5767b5038d7SDag-Erling Smørgrav fprintf(out, "Existence is denied by:\n");
5777b5038d7SDag-Erling Smørgrav }
5787b5038d7SDag-Erling Smørgrav } else {
5797b5038d7SDag-Erling Smørgrav /* NS records aren't signed */
5807b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS) {
5817b5038d7SDag-Erling Smørgrav fprintf(out, "Existence of DS is denied by:\n");
5827b5038d7SDag-Erling Smørgrav } else {
5837b5038d7SDag-Erling Smørgrav print_tabs(out, tabs + 1, sibmap, treedepth);
5847b5038d7SDag-Erling Smørgrav fprintf(out,
5857b5038d7SDag-Erling Smørgrav "Error in denial of existence: %s\n",
5867b5038d7SDag-Erling Smørgrav ldns_get_errorstr_by_id(
5877b5038d7SDag-Erling Smørgrav tree->parent_status[i]));
5887b5038d7SDag-Erling Smørgrav }
5897b5038d7SDag-Erling Smørgrav }
5907b5038d7SDag-Erling Smørgrav } else
5917b5038d7SDag-Erling Smørgrav if (tree->parent_status[i] != LDNS_STATUS_OK) {
5927b5038d7SDag-Erling Smørgrav print_tabs(out, tabs + 1, sibmap, treedepth);
5937b5038d7SDag-Erling Smørgrav fprintf(out,
5947b5038d7SDag-Erling Smørgrav "%s:\n",
5957b5038d7SDag-Erling Smørgrav ldns_get_errorstr_by_id(
5967b5038d7SDag-Erling Smørgrav tree->parent_status[i]));
5977b5038d7SDag-Erling Smørgrav if (tree->parent_status[i]
5987b5038d7SDag-Erling Smørgrav == LDNS_STATUS_SSL_ERR) {
5997b5038d7SDag-Erling Smørgrav printf("; SSL Error: ");
600*5afab0e5SDag-Erling Smørgrav #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(HAVE_LIBRESSL)
6017b5038d7SDag-Erling Smørgrav ERR_load_crypto_strings();
602*5afab0e5SDag-Erling Smørgrav #endif
6037b5038d7SDag-Erling Smørgrav ERR_print_errors_fp(stdout);
6047b5038d7SDag-Erling Smørgrav printf("\n");
6057b5038d7SDag-Erling Smørgrav }
6067b5038d7SDag-Erling Smørgrav ldns_rr_print_fmt(out, fmt,
6077b5038d7SDag-Erling Smørgrav tree->
6087b5038d7SDag-Erling Smørgrav parent_signature[i]);
6097b5038d7SDag-Erling Smørgrav printf("For RRset:\n");
6107b5038d7SDag-Erling Smørgrav ldns_rr_list_print_fmt(out, fmt,
6117b5038d7SDag-Erling Smørgrav tree->rrset);
6127b5038d7SDag-Erling Smørgrav printf("With key:\n");
6137b5038d7SDag-Erling Smørgrav ldns_rr_print_fmt(out, fmt,
6147b5038d7SDag-Erling Smørgrav tree->parents[i]->rr);
6157b5038d7SDag-Erling Smørgrav }
6167b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
6177b5038d7SDag-Erling Smørgrav tree->parents[i],
6187b5038d7SDag-Erling Smørgrav tabs+1,
6197b5038d7SDag-Erling Smørgrav extended,
6207b5038d7SDag-Erling Smørgrav sibmap,
6217b5038d7SDag-Erling Smørgrav treedepth);
6227b5038d7SDag-Erling Smørgrav }
6237b5038d7SDag-Erling Smørgrav } else {
6247b5038d7SDag-Erling Smørgrav print_tabs(out, tabs, sibmap, treedepth);
6257b5038d7SDag-Erling Smørgrav fprintf(out, "<no data>\n");
6267b5038d7SDag-Erling Smørgrav }
6277b5038d7SDag-Erling Smørgrav } else {
6287b5038d7SDag-Erling Smørgrav fprintf(out, "<null pointer>\n");
6297b5038d7SDag-Erling Smørgrav }
6307b5038d7SDag-Erling Smørgrav
6317b5038d7SDag-Erling Smørgrav if (mapset) {
6327b5038d7SDag-Erling Smørgrav LDNS_FREE(sibmap);
6337b5038d7SDag-Erling Smørgrav }
6347b5038d7SDag-Erling Smørgrav }
6357b5038d7SDag-Erling Smørgrav
6367b5038d7SDag-Erling Smørgrav void
ldns_dnssec_trust_tree_print_fmt(FILE * out,const ldns_output_format * fmt,ldns_dnssec_trust_tree * tree,size_t tabs,bool extended)6377b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_print_fmt(FILE *out, const ldns_output_format *fmt,
6387b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *tree,
6397b5038d7SDag-Erling Smørgrav size_t tabs,
6407b5038d7SDag-Erling Smørgrav bool extended)
6417b5038d7SDag-Erling Smørgrav {
6427b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
6437b5038d7SDag-Erling Smørgrav tree, tabs, extended, NULL, 0);
6447b5038d7SDag-Erling Smørgrav }
6457b5038d7SDag-Erling Smørgrav
6467b5038d7SDag-Erling Smørgrav void
ldns_dnssec_trust_tree_print(FILE * out,ldns_dnssec_trust_tree * tree,size_t tabs,bool extended)6477b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_print(FILE *out,
6487b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *tree,
6497b5038d7SDag-Erling Smørgrav size_t tabs,
6507b5038d7SDag-Erling Smørgrav bool extended)
6517b5038d7SDag-Erling Smørgrav {
6527b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_print_fmt(out, ldns_output_format_default,
6537b5038d7SDag-Erling Smørgrav tree, tabs, extended);
6547b5038d7SDag-Erling Smørgrav }
6557b5038d7SDag-Erling Smørgrav
6567b5038d7SDag-Erling Smørgrav
6577b5038d7SDag-Erling Smørgrav ldns_status
ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree * tree,const ldns_dnssec_trust_tree * parent,const ldns_rr * signature,const ldns_status parent_status)6587b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree,
6597b5038d7SDag-Erling Smørgrav const ldns_dnssec_trust_tree *parent,
6607b5038d7SDag-Erling Smørgrav const ldns_rr *signature,
6617b5038d7SDag-Erling Smørgrav const ldns_status parent_status)
6627b5038d7SDag-Erling Smørgrav {
6637b5038d7SDag-Erling Smørgrav if (tree
6647b5038d7SDag-Erling Smørgrav && parent
6657b5038d7SDag-Erling Smørgrav && tree->parent_count < LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS) {
6667b5038d7SDag-Erling Smørgrav /*
6677b5038d7SDag-Erling Smørgrav printf("Add parent for: ");
6687b5038d7SDag-Erling Smørgrav ldns_rr_print(stdout, tree->rr);
6697b5038d7SDag-Erling Smørgrav printf("parent: ");
6707b5038d7SDag-Erling Smørgrav ldns_rr_print(stdout, parent->rr);
6717b5038d7SDag-Erling Smørgrav */
6727b5038d7SDag-Erling Smørgrav tree->parents[tree->parent_count] =
6737b5038d7SDag-Erling Smørgrav (ldns_dnssec_trust_tree *) parent;
6747b5038d7SDag-Erling Smørgrav tree->parent_status[tree->parent_count] = parent_status;
6757b5038d7SDag-Erling Smørgrav tree->parent_signature[tree->parent_count] = (ldns_rr *) signature;
6767b5038d7SDag-Erling Smørgrav tree->parent_count++;
6777b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
6787b5038d7SDag-Erling Smørgrav } else {
6797b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
6807b5038d7SDag-Erling Smørgrav }
6817b5038d7SDag-Erling Smørgrav }
6827b5038d7SDag-Erling Smørgrav
6837b5038d7SDag-Erling Smørgrav /* if rr is null, take the first from the rrset */
6847b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *
ldns_dnssec_derive_trust_tree_time(ldns_dnssec_data_chain * data_chain,ldns_rr * rr,time_t check_time)6857b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_time(
6867b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain,
6877b5038d7SDag-Erling Smørgrav ldns_rr *rr,
6887b5038d7SDag-Erling Smørgrav time_t check_time
6897b5038d7SDag-Erling Smørgrav )
6907b5038d7SDag-Erling Smørgrav {
6917b5038d7SDag-Erling Smørgrav ldns_rr_list *cur_rrset;
6927b5038d7SDag-Erling Smørgrav ldns_rr_list *cur_sigs;
6937b5038d7SDag-Erling Smørgrav ldns_rr *cur_rr = NULL;
6947b5038d7SDag-Erling Smørgrav ldns_rr *cur_sig_rr;
6957b5038d7SDag-Erling Smørgrav size_t i, j;
6967b5038d7SDag-Erling Smørgrav
6977b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new();
6987b5038d7SDag-Erling Smørgrav if(!new_tree)
6997b5038d7SDag-Erling Smørgrav return NULL;
7007b5038d7SDag-Erling Smørgrav
7017b5038d7SDag-Erling Smørgrav if (data_chain && data_chain->rrset) {
7027b5038d7SDag-Erling Smørgrav cur_rrset = data_chain->rrset;
7037b5038d7SDag-Erling Smørgrav
7047b5038d7SDag-Erling Smørgrav cur_sigs = data_chain->signatures;
7057b5038d7SDag-Erling Smørgrav
7067b5038d7SDag-Erling Smørgrav if (rr) {
7077b5038d7SDag-Erling Smørgrav cur_rr = rr;
7087b5038d7SDag-Erling Smørgrav }
7097b5038d7SDag-Erling Smørgrav
7107b5038d7SDag-Erling Smørgrav if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) {
7117b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_list_rr(cur_rrset, 0);
7127b5038d7SDag-Erling Smørgrav }
7137b5038d7SDag-Erling Smørgrav
7147b5038d7SDag-Erling Smørgrav if (cur_rr) {
7157b5038d7SDag-Erling Smørgrav new_tree->rr = cur_rr;
7167b5038d7SDag-Erling Smørgrav new_tree->rrset = cur_rrset;
7177b5038d7SDag-Erling Smørgrav /* there are three possibilities:
7187b5038d7SDag-Erling Smørgrav 1 - 'normal' rrset, signed by a key
7197b5038d7SDag-Erling Smørgrav 2 - dnskey signed by other dnskey
7207b5038d7SDag-Erling Smørgrav 3 - dnskey proven by higher level DS
7217b5038d7SDag-Erling Smørgrav (data denied by nsec is a special case that can
7227b5038d7SDag-Erling Smørgrav occur in multiple places)
7237b5038d7SDag-Erling Smørgrav
7247b5038d7SDag-Erling Smørgrav */
7257b5038d7SDag-Erling Smørgrav if (cur_sigs) {
7267b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) {
7277b5038d7SDag-Erling Smørgrav /* find the appropriate key in the parent list */
7287b5038d7SDag-Erling Smørgrav cur_sig_rr = ldns_rr_list_rr(cur_sigs, i);
7297b5038d7SDag-Erling Smørgrav
7307b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) {
7317b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
7327b5038d7SDag-Erling Smørgrav ldns_rr_owner(cur_rr)))
7337b5038d7SDag-Erling Smørgrav {
7347b5038d7SDag-Erling Smørgrav /* find first that does match */
7357b5038d7SDag-Erling Smørgrav
7367b5038d7SDag-Erling Smørgrav for (j = 0;
7377b5038d7SDag-Erling Smørgrav j < ldns_rr_list_rr_count(cur_rrset) &&
7387b5038d7SDag-Erling Smørgrav ldns_dname_compare(ldns_rr_owner(cur_sig_rr),ldns_rr_owner(cur_rr)) != 0;
7397b5038d7SDag-Erling Smørgrav j++) {
7407b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_list_rr(cur_rrset, j);
7417b5038d7SDag-Erling Smørgrav
7427b5038d7SDag-Erling Smørgrav }
7437b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
7447b5038d7SDag-Erling Smørgrav ldns_rr_owner(cur_rr)))
7457b5038d7SDag-Erling Smørgrav {
7467b5038d7SDag-Erling Smørgrav break;
7477b5038d7SDag-Erling Smørgrav }
7487b5038d7SDag-Erling Smørgrav }
7497b5038d7SDag-Erling Smørgrav
7507b5038d7SDag-Erling Smørgrav }
7517b5038d7SDag-Erling Smørgrav /* option 1 */
7527b5038d7SDag-Erling Smørgrav if (data_chain->parent) {
7537b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_normal_rrset_time(
7547b5038d7SDag-Erling Smørgrav new_tree,
7557b5038d7SDag-Erling Smørgrav data_chain,
7567b5038d7SDag-Erling Smørgrav cur_sig_rr,
7577b5038d7SDag-Erling Smørgrav check_time);
7587b5038d7SDag-Erling Smørgrav }
7597b5038d7SDag-Erling Smørgrav
7607b5038d7SDag-Erling Smørgrav /* option 2 */
7617b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
7627b5038d7SDag-Erling Smørgrav new_tree,
7637b5038d7SDag-Erling Smørgrav data_chain,
7647b5038d7SDag-Erling Smørgrav cur_rr,
7657b5038d7SDag-Erling Smørgrav cur_sig_rr,
7667b5038d7SDag-Erling Smørgrav check_time);
7677b5038d7SDag-Erling Smørgrav }
7687b5038d7SDag-Erling Smørgrav
7697b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_ds_rrset_time(
7707b5038d7SDag-Erling Smørgrav new_tree, data_chain,
7717b5038d7SDag-Erling Smørgrav cur_rr, check_time);
7727b5038d7SDag-Erling Smørgrav } else {
7737b5038d7SDag-Erling Smørgrav /* no signatures? maybe it's nsec data */
7747b5038d7SDag-Erling Smørgrav
7757b5038d7SDag-Erling Smørgrav /* just add every rr from parent as new parent */
7767b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_no_sig_time(
7777b5038d7SDag-Erling Smørgrav new_tree, data_chain, check_time);
7787b5038d7SDag-Erling Smørgrav }
7797b5038d7SDag-Erling Smørgrav }
7807b5038d7SDag-Erling Smørgrav }
7817b5038d7SDag-Erling Smørgrav
7827b5038d7SDag-Erling Smørgrav return new_tree;
7837b5038d7SDag-Erling Smørgrav }
7847b5038d7SDag-Erling Smørgrav
7857b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *
ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain * data_chain,ldns_rr * rr)7867b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr)
7877b5038d7SDag-Erling Smørgrav {
7887b5038d7SDag-Erling Smørgrav return ldns_dnssec_derive_trust_tree_time(data_chain, rr, ldns_time(NULL));
7897b5038d7SDag-Erling Smørgrav }
7907b5038d7SDag-Erling Smørgrav
7917b5038d7SDag-Erling Smørgrav void
ldns_dnssec_derive_trust_tree_normal_rrset_time(ldns_dnssec_trust_tree * new_tree,ldns_dnssec_data_chain * data_chain,ldns_rr * cur_sig_rr,time_t check_time)7927b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_normal_rrset_time(
7937b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *new_tree,
7947b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain,
7957b5038d7SDag-Erling Smørgrav ldns_rr *cur_sig_rr,
7967b5038d7SDag-Erling Smørgrav time_t check_time)
7977b5038d7SDag-Erling Smørgrav {
7987b5038d7SDag-Erling Smørgrav size_t i, j;
7997b5038d7SDag-Erling Smørgrav ldns_rr_list *cur_rrset = ldns_rr_list_clone(data_chain->rrset);
8007b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *cur_parent_tree;
8017b5038d7SDag-Erling Smørgrav ldns_rr *cur_parent_rr;
8027b5038d7SDag-Erling Smørgrav uint16_t cur_keytag;
8037b5038d7SDag-Erling Smørgrav ldns_rr_list *tmp_rrset = NULL;
8047b5038d7SDag-Erling Smørgrav ldns_status cur_status;
8057b5038d7SDag-Erling Smørgrav
8067b5038d7SDag-Erling Smørgrav cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
8077b5038d7SDag-Erling Smørgrav
8087b5038d7SDag-Erling Smørgrav for (j = 0; j < ldns_rr_list_rr_count(data_chain->parent->rrset); j++) {
8097b5038d7SDag-Erling Smørgrav cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
8107b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
8117b5038d7SDag-Erling Smørgrav if (ldns_calc_keytag(cur_parent_rr) == cur_keytag) {
8127b5038d7SDag-Erling Smørgrav
8137b5038d7SDag-Erling Smørgrav /* TODO: check wildcard nsec too */
8147b5038d7SDag-Erling Smørgrav if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
8157b5038d7SDag-Erling Smørgrav tmp_rrset = cur_rrset;
8167b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
8177b5038d7SDag-Erling Smørgrav == LDNS_RR_TYPE_NSEC ||
8187b5038d7SDag-Erling Smørgrav ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
8197b5038d7SDag-Erling Smørgrav == LDNS_RR_TYPE_NSEC3) {
8207b5038d7SDag-Erling Smørgrav /* might contain different names!
8217b5038d7SDag-Erling Smørgrav sort and split */
8227b5038d7SDag-Erling Smørgrav ldns_rr_list_sort(cur_rrset);
8232787e39aSDag-Erling Smørgrav assert(tmp_rrset == cur_rrset);
8247b5038d7SDag-Erling Smørgrav tmp_rrset = ldns_rr_list_pop_rrset(cur_rrset);
8257b5038d7SDag-Erling Smørgrav
8267b5038d7SDag-Erling Smørgrav /* with nsecs, this might be the wrong one */
8277b5038d7SDag-Erling Smørgrav while (tmp_rrset &&
8287b5038d7SDag-Erling Smørgrav ldns_rr_list_rr_count(cur_rrset) > 0 &&
8297b5038d7SDag-Erling Smørgrav ldns_dname_compare(
8307b5038d7SDag-Erling Smørgrav ldns_rr_owner(ldns_rr_list_rr(
8317b5038d7SDag-Erling Smørgrav tmp_rrset, 0)),
8327b5038d7SDag-Erling Smørgrav ldns_rr_owner(cur_sig_rr)) != 0) {
8337b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(tmp_rrset);
8347b5038d7SDag-Erling Smørgrav tmp_rrset =
8357b5038d7SDag-Erling Smørgrav ldns_rr_list_pop_rrset(cur_rrset);
8367b5038d7SDag-Erling Smørgrav }
8377b5038d7SDag-Erling Smørgrav }
8387b5038d7SDag-Erling Smørgrav cur_status = ldns_verify_rrsig_time(
8397b5038d7SDag-Erling Smørgrav tmp_rrset,
8407b5038d7SDag-Erling Smørgrav cur_sig_rr,
8417b5038d7SDag-Erling Smørgrav cur_parent_rr,
8427b5038d7SDag-Erling Smørgrav check_time);
8432787e39aSDag-Erling Smørgrav if (tmp_rrset && tmp_rrset != cur_rrset
8442787e39aSDag-Erling Smørgrav ) {
8452787e39aSDag-Erling Smørgrav ldns_rr_list_deep_free(
8462787e39aSDag-Erling Smørgrav tmp_rrset);
8472787e39aSDag-Erling Smørgrav tmp_rrset = NULL;
8482787e39aSDag-Erling Smørgrav }
8497b5038d7SDag-Erling Smørgrav /* avoid dupes */
8507b5038d7SDag-Erling Smørgrav for (i = 0; i < new_tree->parent_count; i++) {
8517b5038d7SDag-Erling Smørgrav if (cur_parent_rr == new_tree->parents[i]->rr) {
8527b5038d7SDag-Erling Smørgrav goto done;
8537b5038d7SDag-Erling Smørgrav }
8547b5038d7SDag-Erling Smørgrav }
8557b5038d7SDag-Erling Smørgrav
8567b5038d7SDag-Erling Smørgrav cur_parent_tree =
8577b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_time(
8587b5038d7SDag-Erling Smørgrav data_chain->parent,
8597b5038d7SDag-Erling Smørgrav cur_parent_rr,
8607b5038d7SDag-Erling Smørgrav check_time);
8617b5038d7SDag-Erling Smørgrav (void)ldns_dnssec_trust_tree_add_parent(new_tree,
8627b5038d7SDag-Erling Smørgrav cur_parent_tree,
8637b5038d7SDag-Erling Smørgrav cur_sig_rr,
8647b5038d7SDag-Erling Smørgrav cur_status);
8657b5038d7SDag-Erling Smørgrav }
8667b5038d7SDag-Erling Smørgrav }
8677b5038d7SDag-Erling Smørgrav }
8687b5038d7SDag-Erling Smørgrav }
8697b5038d7SDag-Erling Smørgrav done:
8707b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(cur_rrset);
8717b5038d7SDag-Erling Smørgrav }
8727b5038d7SDag-Erling Smørgrav
8737b5038d7SDag-Erling Smørgrav void
ldns_dnssec_derive_trust_tree_normal_rrset(ldns_dnssec_trust_tree * new_tree,ldns_dnssec_data_chain * data_chain,ldns_rr * cur_sig_rr)8747b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_normal_rrset(ldns_dnssec_trust_tree *new_tree,
8757b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain,
8767b5038d7SDag-Erling Smørgrav ldns_rr *cur_sig_rr)
8777b5038d7SDag-Erling Smørgrav {
8787b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_normal_rrset_time(
8797b5038d7SDag-Erling Smørgrav new_tree, data_chain, cur_sig_rr, ldns_time(NULL));
8807b5038d7SDag-Erling Smørgrav }
8817b5038d7SDag-Erling Smørgrav
8827b5038d7SDag-Erling Smørgrav void
ldns_dnssec_derive_trust_tree_dnskey_rrset_time(ldns_dnssec_trust_tree * new_tree,ldns_dnssec_data_chain * data_chain,ldns_rr * cur_rr,ldns_rr * cur_sig_rr,time_t check_time)8837b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
8847b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *new_tree,
8857b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain,
8867b5038d7SDag-Erling Smørgrav ldns_rr *cur_rr,
8877b5038d7SDag-Erling Smørgrav ldns_rr *cur_sig_rr,
8887b5038d7SDag-Erling Smørgrav time_t check_time)
8897b5038d7SDag-Erling Smørgrav {
8907b5038d7SDag-Erling Smørgrav size_t j;
8917b5038d7SDag-Erling Smørgrav ldns_rr_list *cur_rrset = data_chain->rrset;
8927b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *cur_parent_tree;
8937b5038d7SDag-Erling Smørgrav ldns_rr *cur_parent_rr;
8947b5038d7SDag-Erling Smørgrav uint16_t cur_keytag;
8957b5038d7SDag-Erling Smørgrav ldns_status cur_status;
8967b5038d7SDag-Erling Smørgrav
8977b5038d7SDag-Erling Smørgrav cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
8987b5038d7SDag-Erling Smørgrav
8997b5038d7SDag-Erling Smørgrav for (j = 0; j < ldns_rr_list_rr_count(cur_rrset); j++) {
9007b5038d7SDag-Erling Smørgrav cur_parent_rr = ldns_rr_list_rr(cur_rrset, j);
9017b5038d7SDag-Erling Smørgrav if (cur_parent_rr != cur_rr &&
9027b5038d7SDag-Erling Smørgrav ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
9037b5038d7SDag-Erling Smørgrav if (ldns_calc_keytag(cur_parent_rr) == cur_keytag
9047b5038d7SDag-Erling Smørgrav ) {
9057b5038d7SDag-Erling Smørgrav cur_parent_tree = ldns_dnssec_trust_tree_new();
9067b5038d7SDag-Erling Smørgrav cur_parent_tree->rr = cur_parent_rr;
9077b5038d7SDag-Erling Smørgrav cur_parent_tree->rrset = cur_rrset;
9087b5038d7SDag-Erling Smørgrav cur_status = ldns_verify_rrsig_time(
9097b5038d7SDag-Erling Smørgrav cur_rrset, cur_sig_rr,
9107b5038d7SDag-Erling Smørgrav cur_parent_rr, check_time);
911*5afab0e5SDag-Erling Smørgrav if (ldns_dnssec_trust_tree_add_parent(new_tree,
912*5afab0e5SDag-Erling Smørgrav cur_parent_tree, cur_sig_rr, cur_status))
913*5afab0e5SDag-Erling Smørgrav ldns_dnssec_trust_tree_free(cur_parent_tree);
9147b5038d7SDag-Erling Smørgrav }
9157b5038d7SDag-Erling Smørgrav }
9167b5038d7SDag-Erling Smørgrav }
9177b5038d7SDag-Erling Smørgrav }
9187b5038d7SDag-Erling Smørgrav
9197b5038d7SDag-Erling Smørgrav void
ldns_dnssec_derive_trust_tree_dnskey_rrset(ldns_dnssec_trust_tree * new_tree,ldns_dnssec_data_chain * data_chain,ldns_rr * cur_rr,ldns_rr * cur_sig_rr)9207b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_dnskey_rrset(ldns_dnssec_trust_tree *new_tree,
9217b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain,
9227b5038d7SDag-Erling Smørgrav ldns_rr *cur_rr,
9237b5038d7SDag-Erling Smørgrav ldns_rr *cur_sig_rr)
9247b5038d7SDag-Erling Smørgrav {
9257b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
9267b5038d7SDag-Erling Smørgrav new_tree, data_chain, cur_rr, cur_sig_rr, ldns_time(NULL));
9277b5038d7SDag-Erling Smørgrav }
9287b5038d7SDag-Erling Smørgrav
9297b5038d7SDag-Erling Smørgrav void
ldns_dnssec_derive_trust_tree_ds_rrset_time(ldns_dnssec_trust_tree * new_tree,ldns_dnssec_data_chain * data_chain,ldns_rr * cur_rr,time_t check_time)9307b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_ds_rrset_time(
9317b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *new_tree,
9327b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain,
9337b5038d7SDag-Erling Smørgrav ldns_rr *cur_rr,
9347b5038d7SDag-Erling Smørgrav time_t check_time)
9357b5038d7SDag-Erling Smørgrav {
9367b5038d7SDag-Erling Smørgrav size_t j, h;
9377b5038d7SDag-Erling Smørgrav ldns_rr_list *cur_rrset = data_chain->rrset;
9387b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *cur_parent_tree;
9397b5038d7SDag-Erling Smørgrav ldns_rr *cur_parent_rr;
9407b5038d7SDag-Erling Smørgrav
9417b5038d7SDag-Erling Smørgrav /* try the parent to see whether there are DSs there */
9427b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_DNSKEY &&
9437b5038d7SDag-Erling Smørgrav data_chain->parent &&
9447b5038d7SDag-Erling Smørgrav data_chain->parent->rrset
9457b5038d7SDag-Erling Smørgrav ) {
9467b5038d7SDag-Erling Smørgrav for (j = 0;
9477b5038d7SDag-Erling Smørgrav j < ldns_rr_list_rr_count(data_chain->parent->rrset);
9487b5038d7SDag-Erling Smørgrav j++) {
9497b5038d7SDag-Erling Smørgrav cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
9507b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DS) {
9517b5038d7SDag-Erling Smørgrav for (h = 0; h < ldns_rr_list_rr_count(cur_rrset); h++) {
9527b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_list_rr(cur_rrset, h);
9537b5038d7SDag-Erling Smørgrav if (ldns_rr_compare_ds(cur_rr, cur_parent_rr)) {
9547b5038d7SDag-Erling Smørgrav cur_parent_tree =
9557b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_time(
9567b5038d7SDag-Erling Smørgrav data_chain->parent,
9577b5038d7SDag-Erling Smørgrav cur_parent_rr,
9587b5038d7SDag-Erling Smørgrav check_time);
9597b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_trust_tree_add_parent(
9607b5038d7SDag-Erling Smørgrav new_tree,
9617b5038d7SDag-Erling Smørgrav cur_parent_tree,
9627b5038d7SDag-Erling Smørgrav NULL,
9637b5038d7SDag-Erling Smørgrav LDNS_STATUS_OK);
9647b5038d7SDag-Erling Smørgrav } else {
9657b5038d7SDag-Erling Smørgrav /*ldns_rr_print(stdout, cur_parent_rr);*/
9667b5038d7SDag-Erling Smørgrav }
9677b5038d7SDag-Erling Smørgrav }
9687b5038d7SDag-Erling Smørgrav }
9697b5038d7SDag-Erling Smørgrav }
9707b5038d7SDag-Erling Smørgrav }
9717b5038d7SDag-Erling Smørgrav }
9727b5038d7SDag-Erling Smørgrav
9737b5038d7SDag-Erling Smørgrav void
ldns_dnssec_derive_trust_tree_ds_rrset(ldns_dnssec_trust_tree * new_tree,ldns_dnssec_data_chain * data_chain,ldns_rr * cur_rr)9747b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_ds_rrset(ldns_dnssec_trust_tree *new_tree,
9757b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain,
9767b5038d7SDag-Erling Smørgrav ldns_rr *cur_rr)
9777b5038d7SDag-Erling Smørgrav {
9787b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_ds_rrset_time(
9797b5038d7SDag-Erling Smørgrav new_tree, data_chain, cur_rr, ldns_time(NULL));
9807b5038d7SDag-Erling Smørgrav }
9817b5038d7SDag-Erling Smørgrav
9827b5038d7SDag-Erling Smørgrav void
ldns_dnssec_derive_trust_tree_no_sig_time(ldns_dnssec_trust_tree * new_tree,ldns_dnssec_data_chain * data_chain,time_t check_time)9837b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_no_sig_time(
9847b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *new_tree,
9857b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain,
9867b5038d7SDag-Erling Smørgrav time_t check_time)
9877b5038d7SDag-Erling Smørgrav {
9887b5038d7SDag-Erling Smørgrav size_t i;
9897b5038d7SDag-Erling Smørgrav ldns_rr_list *cur_rrset;
9907b5038d7SDag-Erling Smørgrav ldns_rr *cur_parent_rr;
9917b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree *cur_parent_tree;
9927b5038d7SDag-Erling Smørgrav ldns_status result;
9937b5038d7SDag-Erling Smørgrav
9947b5038d7SDag-Erling Smørgrav if (data_chain->parent && data_chain->parent->rrset) {
9957b5038d7SDag-Erling Smørgrav cur_rrset = data_chain->parent->rrset;
9967b5038d7SDag-Erling Smørgrav /* nsec? */
9977b5038d7SDag-Erling Smørgrav if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
9987b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
9997b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC3) {
10007b5038d7SDag-Erling Smørgrav result = ldns_dnssec_verify_denial_nsec3(
10017b5038d7SDag-Erling Smørgrav new_tree->rr,
10027b5038d7SDag-Erling Smørgrav cur_rrset,
10037b5038d7SDag-Erling Smørgrav data_chain->parent->signatures,
10047b5038d7SDag-Erling Smørgrav data_chain->packet_rcode,
10057b5038d7SDag-Erling Smørgrav data_chain->packet_qtype,
10067b5038d7SDag-Erling Smørgrav data_chain->packet_nodata);
10077b5038d7SDag-Erling Smørgrav } else if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
10087b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC) {
10097b5038d7SDag-Erling Smørgrav result = ldns_dnssec_verify_denial(
10107b5038d7SDag-Erling Smørgrav new_tree->rr,
10117b5038d7SDag-Erling Smørgrav cur_rrset,
10127b5038d7SDag-Erling Smørgrav data_chain->parent->signatures);
10137b5038d7SDag-Erling Smørgrav } else {
10147b5038d7SDag-Erling Smørgrav /* unsigned zone, unsigned parent */
10157b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_OK;
10167b5038d7SDag-Erling Smørgrav }
10177b5038d7SDag-Erling Smørgrav } else {
10187b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
10197b5038d7SDag-Erling Smørgrav }
10207b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(cur_rrset); i++) {
10217b5038d7SDag-Erling Smørgrav cur_parent_rr = ldns_rr_list_rr(cur_rrset, i);
10227b5038d7SDag-Erling Smørgrav cur_parent_tree =
10237b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_time(
10247b5038d7SDag-Erling Smørgrav data_chain->parent,
10257b5038d7SDag-Erling Smørgrav cur_parent_rr,
10267b5038d7SDag-Erling Smørgrav check_time);
1027*5afab0e5SDag-Erling Smørgrav if (ldns_dnssec_trust_tree_add_parent(new_tree,
1028*5afab0e5SDag-Erling Smørgrav cur_parent_tree, NULL, result))
1029*5afab0e5SDag-Erling Smørgrav ldns_dnssec_trust_tree_free(cur_parent_tree);
1030*5afab0e5SDag-Erling Smørgrav
10317b5038d7SDag-Erling Smørgrav }
10327b5038d7SDag-Erling Smørgrav }
10337b5038d7SDag-Erling Smørgrav }
10347b5038d7SDag-Erling Smørgrav
10357b5038d7SDag-Erling Smørgrav void
ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree * new_tree,ldns_dnssec_data_chain * data_chain)10367b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree *new_tree,
10377b5038d7SDag-Erling Smørgrav ldns_dnssec_data_chain *data_chain)
10387b5038d7SDag-Erling Smørgrav {
10397b5038d7SDag-Erling Smørgrav ldns_dnssec_derive_trust_tree_no_sig_time(
10407b5038d7SDag-Erling Smørgrav new_tree, data_chain, ldns_time(NULL));
10417b5038d7SDag-Erling Smørgrav }
10427b5038d7SDag-Erling Smørgrav
10437b5038d7SDag-Erling Smørgrav /*
10447b5038d7SDag-Erling Smørgrav * returns OK if there is a path from tree to key with only OK
10457b5038d7SDag-Erling Smørgrav * the (first) error in between otherwise
10467b5038d7SDag-Erling Smørgrav * or NOT_FOUND if the key wasn't present at all
10477b5038d7SDag-Erling Smørgrav */
10487b5038d7SDag-Erling Smørgrav ldns_status
ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree * tree,ldns_rr_list * trusted_keys)10497b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree,
10507b5038d7SDag-Erling Smørgrav ldns_rr_list *trusted_keys)
10517b5038d7SDag-Erling Smørgrav {
10527b5038d7SDag-Erling Smørgrav size_t i;
10537b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_CRYPTO_NO_DNSKEY;
10547b5038d7SDag-Erling Smørgrav bool equal;
10557b5038d7SDag-Erling Smørgrav ldns_status parent_result;
10567b5038d7SDag-Erling Smørgrav
10577b5038d7SDag-Erling Smørgrav if (tree && trusted_keys && ldns_rr_list_rr_count(trusted_keys) > 0)
10587b5038d7SDag-Erling Smørgrav { if (tree->rr) {
10597b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(trusted_keys); i++) {
10607b5038d7SDag-Erling Smørgrav equal = ldns_rr_compare_ds(
10617b5038d7SDag-Erling Smørgrav tree->rr,
10627b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(trusted_keys, i));
10637b5038d7SDag-Erling Smørgrav if (equal) {
10647b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_OK;
10657b5038d7SDag-Erling Smørgrav return result;
10667b5038d7SDag-Erling Smørgrav }
10677b5038d7SDag-Erling Smørgrav }
10687b5038d7SDag-Erling Smørgrav }
10697b5038d7SDag-Erling Smørgrav for (i = 0; i < tree->parent_count; i++) {
10707b5038d7SDag-Erling Smørgrav parent_result =
10717b5038d7SDag-Erling Smørgrav ldns_dnssec_trust_tree_contains_keys(tree->parents[i],
10727b5038d7SDag-Erling Smørgrav trusted_keys);
10737b5038d7SDag-Erling Smørgrav if (parent_result != LDNS_STATUS_CRYPTO_NO_DNSKEY) {
10747b5038d7SDag-Erling Smørgrav if (tree->parent_status[i] != LDNS_STATUS_OK) {
10757b5038d7SDag-Erling Smørgrav result = tree->parent_status[i];
10767b5038d7SDag-Erling Smørgrav } else {
10772787e39aSDag-Erling Smørgrav if (tree->rr &&
10782787e39aSDag-Erling Smørgrav ldns_rr_get_type(tree->rr)
10797b5038d7SDag-Erling Smørgrav == LDNS_RR_TYPE_NSEC &&
10807b5038d7SDag-Erling Smørgrav parent_result == LDNS_STATUS_OK
10817b5038d7SDag-Erling Smørgrav ) {
10827b5038d7SDag-Erling Smørgrav result =
10837b5038d7SDag-Erling Smørgrav LDNS_STATUS_DNSSEC_EXISTENCE_DENIED;
10847b5038d7SDag-Erling Smørgrav } else {
10857b5038d7SDag-Erling Smørgrav result = parent_result;
10867b5038d7SDag-Erling Smørgrav }
10877b5038d7SDag-Erling Smørgrav }
10887b5038d7SDag-Erling Smørgrav }
10897b5038d7SDag-Erling Smørgrav }
10907b5038d7SDag-Erling Smørgrav } else {
10917b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_ERR;
10927b5038d7SDag-Erling Smørgrav }
10937b5038d7SDag-Erling Smørgrav
10947b5038d7SDag-Erling Smørgrav return result;
10957b5038d7SDag-Erling Smørgrav }
10967b5038d7SDag-Erling Smørgrav
10977b5038d7SDag-Erling Smørgrav ldns_status
ldns_verify_time(const ldns_rr_list * rrset,const ldns_rr_list * rrsig,const ldns_rr_list * keys,time_t check_time,ldns_rr_list * good_keys)10987b5038d7SDag-Erling Smørgrav ldns_verify_time(
1099986ba33cSDag-Erling Smørgrav const ldns_rr_list *rrset,
1100986ba33cSDag-Erling Smørgrav const ldns_rr_list *rrsig,
11017b5038d7SDag-Erling Smørgrav const ldns_rr_list *keys,
11027b5038d7SDag-Erling Smørgrav time_t check_time,
11037b5038d7SDag-Erling Smørgrav ldns_rr_list *good_keys
11047b5038d7SDag-Erling Smørgrav )
11057b5038d7SDag-Erling Smørgrav {
11067b5038d7SDag-Erling Smørgrav uint16_t i;
11077b5038d7SDag-Erling Smørgrav ldns_status verify_result = LDNS_STATUS_ERR;
11087b5038d7SDag-Erling Smørgrav
11097b5038d7SDag-Erling Smørgrav if (!rrset || !rrsig || !keys) {
11107b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
11117b5038d7SDag-Erling Smørgrav }
11127b5038d7SDag-Erling Smørgrav
11137b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(rrset) < 1) {
11147b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
11157b5038d7SDag-Erling Smørgrav }
11167b5038d7SDag-Erling Smørgrav
11177b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(rrsig) < 1) {
11187b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_NO_RRSIG;
11197b5038d7SDag-Erling Smørgrav }
11207b5038d7SDag-Erling Smørgrav
11217b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(keys) < 1) {
11227b5038d7SDag-Erling Smørgrav verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
11237b5038d7SDag-Erling Smørgrav } else {
11247b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
11257b5038d7SDag-Erling Smørgrav ldns_status s = ldns_verify_rrsig_keylist_time(
11267b5038d7SDag-Erling Smørgrav rrset, ldns_rr_list_rr(rrsig, i),
11277b5038d7SDag-Erling Smørgrav keys, check_time, good_keys);
11287b5038d7SDag-Erling Smørgrav /* try a little to get more descriptive error */
11297b5038d7SDag-Erling Smørgrav if(s == LDNS_STATUS_OK) {
11307b5038d7SDag-Erling Smørgrav verify_result = LDNS_STATUS_OK;
11317b5038d7SDag-Erling Smørgrav } else if(verify_result == LDNS_STATUS_ERR)
11327b5038d7SDag-Erling Smørgrav verify_result = s;
11337b5038d7SDag-Erling Smørgrav else if(s != LDNS_STATUS_ERR && verify_result ==
11347b5038d7SDag-Erling Smørgrav LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY)
11357b5038d7SDag-Erling Smørgrav verify_result = s;
11367b5038d7SDag-Erling Smørgrav }
11377b5038d7SDag-Erling Smørgrav }
11387b5038d7SDag-Erling Smørgrav return verify_result;
11397b5038d7SDag-Erling Smørgrav }
11407b5038d7SDag-Erling Smørgrav
11417b5038d7SDag-Erling Smørgrav ldns_status
ldns_verify(ldns_rr_list * rrset,ldns_rr_list * rrsig,const ldns_rr_list * keys,ldns_rr_list * good_keys)11427b5038d7SDag-Erling Smørgrav ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys,
11437b5038d7SDag-Erling Smørgrav ldns_rr_list *good_keys)
11447b5038d7SDag-Erling Smørgrav {
11457b5038d7SDag-Erling Smørgrav return ldns_verify_time(rrset, rrsig, keys, ldns_time(NULL), good_keys);
11467b5038d7SDag-Erling Smørgrav }
11477b5038d7SDag-Erling Smørgrav
11487b5038d7SDag-Erling Smørgrav ldns_status
ldns_verify_notime(ldns_rr_list * rrset,ldns_rr_list * rrsig,const ldns_rr_list * keys,ldns_rr_list * good_keys)11497b5038d7SDag-Erling Smørgrav ldns_verify_notime(ldns_rr_list *rrset, ldns_rr_list *rrsig,
11507b5038d7SDag-Erling Smørgrav const ldns_rr_list *keys, ldns_rr_list *good_keys)
11517b5038d7SDag-Erling Smørgrav {
11527b5038d7SDag-Erling Smørgrav uint16_t i;
11537b5038d7SDag-Erling Smørgrav ldns_status verify_result = LDNS_STATUS_ERR;
11547b5038d7SDag-Erling Smørgrav
11557b5038d7SDag-Erling Smørgrav if (!rrset || !rrsig || !keys) {
11567b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
11577b5038d7SDag-Erling Smørgrav }
11587b5038d7SDag-Erling Smørgrav
11597b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(rrset) < 1) {
11607b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
11617b5038d7SDag-Erling Smørgrav }
11627b5038d7SDag-Erling Smørgrav
11637b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(rrsig) < 1) {
11647b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_NO_RRSIG;
11657b5038d7SDag-Erling Smørgrav }
11667b5038d7SDag-Erling Smørgrav
11677b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(keys) < 1) {
11687b5038d7SDag-Erling Smørgrav verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
11697b5038d7SDag-Erling Smørgrav } else {
11707b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
11717b5038d7SDag-Erling Smørgrav ldns_status s = ldns_verify_rrsig_keylist_notime(rrset,
11727b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rrsig, i), keys, good_keys);
11737b5038d7SDag-Erling Smørgrav
11747b5038d7SDag-Erling Smørgrav /* try a little to get more descriptive error */
11757b5038d7SDag-Erling Smørgrav if (s == LDNS_STATUS_OK) {
11767b5038d7SDag-Erling Smørgrav verify_result = LDNS_STATUS_OK;
11777b5038d7SDag-Erling Smørgrav } else if (verify_result == LDNS_STATUS_ERR) {
11787b5038d7SDag-Erling Smørgrav verify_result = s;
11797b5038d7SDag-Erling Smørgrav } else if (s != LDNS_STATUS_ERR && verify_result ==
11807b5038d7SDag-Erling Smørgrav LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
11817b5038d7SDag-Erling Smørgrav verify_result = s;
11827b5038d7SDag-Erling Smørgrav }
11837b5038d7SDag-Erling Smørgrav }
11847b5038d7SDag-Erling Smørgrav }
11857b5038d7SDag-Erling Smørgrav return verify_result;
11867b5038d7SDag-Erling Smørgrav }
11877b5038d7SDag-Erling Smørgrav
11887b5038d7SDag-Erling Smørgrav ldns_rr_list *
ldns_fetch_valid_domain_keys_time(const ldns_resolver * res,const ldns_rdf * domain,const ldns_rr_list * keys,time_t check_time,ldns_status * status)11897b5038d7SDag-Erling Smørgrav ldns_fetch_valid_domain_keys_time(const ldns_resolver *res,
11907b5038d7SDag-Erling Smørgrav const ldns_rdf *domain,
11917b5038d7SDag-Erling Smørgrav const ldns_rr_list *keys,
11927b5038d7SDag-Erling Smørgrav time_t check_time,
11937b5038d7SDag-Erling Smørgrav ldns_status *status)
11947b5038d7SDag-Erling Smørgrav {
11957b5038d7SDag-Erling Smørgrav ldns_rr_list * trusted_keys = NULL;
11967b5038d7SDag-Erling Smørgrav ldns_rr_list * ds_keys = NULL;
11977b5038d7SDag-Erling Smørgrav ldns_rdf * prev_parent_domain;
11987b5038d7SDag-Erling Smørgrav ldns_rdf * parent_domain;
11997b5038d7SDag-Erling Smørgrav ldns_rr_list * parent_keys = NULL;
12007b5038d7SDag-Erling Smørgrav
12017b5038d7SDag-Erling Smørgrav if (res && domain && keys) {
12027b5038d7SDag-Erling Smørgrav
12037b5038d7SDag-Erling Smørgrav if ((trusted_keys = ldns_validate_domain_dnskey_time(res,
12047b5038d7SDag-Erling Smørgrav domain, keys, check_time))) {
12057b5038d7SDag-Erling Smørgrav *status = LDNS_STATUS_OK;
12067b5038d7SDag-Erling Smørgrav } else {
12077b5038d7SDag-Erling Smørgrav /* No trusted keys in this domain, we'll have to find some in the parent domain */
12087b5038d7SDag-Erling Smørgrav *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
12097b5038d7SDag-Erling Smørgrav
12107b5038d7SDag-Erling Smørgrav parent_domain = ldns_dname_left_chop(domain);
12112787e39aSDag-Erling Smørgrav while (parent_domain && /* Fail if we are at the root*/
12122787e39aSDag-Erling Smørgrav ldns_rdf_size(parent_domain) > 0) {
12137b5038d7SDag-Erling Smørgrav
12147b5038d7SDag-Erling Smørgrav if ((parent_keys =
12157b5038d7SDag-Erling Smørgrav ldns_fetch_valid_domain_keys_time(res,
12167b5038d7SDag-Erling Smørgrav parent_domain,
12177b5038d7SDag-Erling Smørgrav keys,
12187b5038d7SDag-Erling Smørgrav check_time,
12197b5038d7SDag-Erling Smørgrav status))) {
12207b5038d7SDag-Erling Smørgrav /* Check DS records */
12217b5038d7SDag-Erling Smørgrav if ((ds_keys =
12227b5038d7SDag-Erling Smørgrav ldns_validate_domain_ds_time(res,
12237b5038d7SDag-Erling Smørgrav domain,
12247b5038d7SDag-Erling Smørgrav parent_keys,
12257b5038d7SDag-Erling Smørgrav check_time))) {
12267b5038d7SDag-Erling Smørgrav trusted_keys =
12277b5038d7SDag-Erling Smørgrav ldns_fetch_valid_domain_keys_time(
12287b5038d7SDag-Erling Smørgrav res,
12297b5038d7SDag-Erling Smørgrav domain,
12307b5038d7SDag-Erling Smørgrav ds_keys,
12317b5038d7SDag-Erling Smørgrav check_time,
12327b5038d7SDag-Erling Smørgrav status);
12337b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(ds_keys);
12347b5038d7SDag-Erling Smørgrav } else {
12357b5038d7SDag-Erling Smørgrav /* No valid DS at the parent -- fail */
12367b5038d7SDag-Erling Smørgrav *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DS ;
12377b5038d7SDag-Erling Smørgrav }
12387b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(parent_keys);
12397b5038d7SDag-Erling Smørgrav break;
12407b5038d7SDag-Erling Smørgrav } else {
12417b5038d7SDag-Erling Smørgrav parent_domain = ldns_dname_left_chop((
12427b5038d7SDag-Erling Smørgrav prev_parent_domain
12437b5038d7SDag-Erling Smørgrav = parent_domain
12447b5038d7SDag-Erling Smørgrav ));
12457b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(prev_parent_domain);
12467b5038d7SDag-Erling Smørgrav }
12477b5038d7SDag-Erling Smørgrav }
12482787e39aSDag-Erling Smørgrav if (parent_domain) {
12497b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(parent_domain);
12507b5038d7SDag-Erling Smørgrav }
12517b5038d7SDag-Erling Smørgrav }
12522787e39aSDag-Erling Smørgrav }
12537b5038d7SDag-Erling Smørgrav return trusted_keys;
12547b5038d7SDag-Erling Smørgrav }
12557b5038d7SDag-Erling Smørgrav
12567b5038d7SDag-Erling Smørgrav ldns_rr_list *
ldns_fetch_valid_domain_keys(const ldns_resolver * res,const ldns_rdf * domain,const ldns_rr_list * keys,ldns_status * status)12577b5038d7SDag-Erling Smørgrav ldns_fetch_valid_domain_keys(const ldns_resolver *res,
12587b5038d7SDag-Erling Smørgrav const ldns_rdf *domain,
12597b5038d7SDag-Erling Smørgrav const ldns_rr_list *keys,
12607b5038d7SDag-Erling Smørgrav ldns_status *status)
12617b5038d7SDag-Erling Smørgrav {
12627b5038d7SDag-Erling Smørgrav return ldns_fetch_valid_domain_keys_time(
12637b5038d7SDag-Erling Smørgrav res, domain, keys, ldns_time(NULL), status);
12647b5038d7SDag-Erling Smørgrav }
12657b5038d7SDag-Erling Smørgrav
12667b5038d7SDag-Erling Smørgrav ldns_rr_list *
ldns_validate_domain_dnskey_time(const ldns_resolver * res,const ldns_rdf * domain,const ldns_rr_list * keys,time_t check_time)12677b5038d7SDag-Erling Smørgrav ldns_validate_domain_dnskey_time(
12687b5038d7SDag-Erling Smørgrav const ldns_resolver * res,
12697b5038d7SDag-Erling Smørgrav const ldns_rdf * domain,
12707b5038d7SDag-Erling Smørgrav const ldns_rr_list * keys,
12717b5038d7SDag-Erling Smørgrav time_t check_time
12727b5038d7SDag-Erling Smørgrav )
12737b5038d7SDag-Erling Smørgrav {
12747b5038d7SDag-Erling Smørgrav ldns_pkt * keypkt;
12757b5038d7SDag-Erling Smørgrav ldns_rr * cur_key;
12767b5038d7SDag-Erling Smørgrav uint16_t key_i; uint16_t key_j; uint16_t key_k;
12777b5038d7SDag-Erling Smørgrav uint16_t sig_i; ldns_rr * cur_sig;
12787b5038d7SDag-Erling Smørgrav
12797b5038d7SDag-Erling Smørgrav ldns_rr_list * domain_keys = NULL;
12807b5038d7SDag-Erling Smørgrav ldns_rr_list * domain_sigs = NULL;
12817b5038d7SDag-Erling Smørgrav ldns_rr_list * trusted_keys = NULL;
12827b5038d7SDag-Erling Smørgrav
12837b5038d7SDag-Erling Smørgrav /* Fetch keys for the domain */
12847b5038d7SDag-Erling Smørgrav keypkt = ldns_resolver_query(res, domain,
12857b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, LDNS_RD);
12867b5038d7SDag-Erling Smørgrav if (keypkt) {
12877b5038d7SDag-Erling Smørgrav domain_keys = ldns_pkt_rr_list_by_type(keypkt,
12887b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DNSKEY,
12897b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANSWER);
12907b5038d7SDag-Erling Smørgrav domain_sigs = ldns_pkt_rr_list_by_type(keypkt,
12917b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_RRSIG,
12927b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANSWER);
12937b5038d7SDag-Erling Smørgrav
12947b5038d7SDag-Erling Smørgrav /* Try to validate the record using our keys */
12957b5038d7SDag-Erling Smørgrav for (key_i=0; key_i< ldns_rr_list_rr_count(domain_keys); key_i++) {
12967b5038d7SDag-Erling Smørgrav
12977b5038d7SDag-Erling Smørgrav cur_key = ldns_rr_list_rr(domain_keys, key_i);
12987b5038d7SDag-Erling Smørgrav for (key_j=0; key_j<ldns_rr_list_rr_count(keys); key_j++) {
12997b5038d7SDag-Erling Smørgrav if (ldns_rr_compare_ds(ldns_rr_list_rr(keys, key_j),
13007b5038d7SDag-Erling Smørgrav cur_key)) {
13017b5038d7SDag-Erling Smørgrav
13027b5038d7SDag-Erling Smørgrav /* Current key is trusted -- validate */
13037b5038d7SDag-Erling Smørgrav trusted_keys = ldns_rr_list_new();
13047b5038d7SDag-Erling Smørgrav
13057b5038d7SDag-Erling Smørgrav for (sig_i=0;
13067b5038d7SDag-Erling Smørgrav sig_i<ldns_rr_list_rr_count(domain_sigs);
13077b5038d7SDag-Erling Smørgrav sig_i++) {
13087b5038d7SDag-Erling Smørgrav cur_sig = ldns_rr_list_rr(domain_sigs, sig_i);
13097b5038d7SDag-Erling Smørgrav /* Avoid non-matching sigs */
13107b5038d7SDag-Erling Smørgrav if (ldns_rdf2native_int16(
13117b5038d7SDag-Erling Smørgrav ldns_rr_rrsig_keytag(cur_sig))
13127b5038d7SDag-Erling Smørgrav == ldns_calc_keytag(cur_key)) {
13137b5038d7SDag-Erling Smørgrav if (ldns_verify_rrsig_time(
13147b5038d7SDag-Erling Smørgrav domain_keys,
13157b5038d7SDag-Erling Smørgrav cur_sig,
13167b5038d7SDag-Erling Smørgrav cur_key,
13177b5038d7SDag-Erling Smørgrav check_time)
13187b5038d7SDag-Erling Smørgrav == LDNS_STATUS_OK) {
13197b5038d7SDag-Erling Smørgrav
13207b5038d7SDag-Erling Smørgrav /* Push the whole rrset
13217b5038d7SDag-Erling Smørgrav -- we can't do much more */
13227b5038d7SDag-Erling Smørgrav for (key_k=0;
13237b5038d7SDag-Erling Smørgrav key_k<ldns_rr_list_rr_count(
13247b5038d7SDag-Erling Smørgrav domain_keys);
13257b5038d7SDag-Erling Smørgrav key_k++) {
13267b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(
13277b5038d7SDag-Erling Smørgrav trusted_keys,
13287b5038d7SDag-Erling Smørgrav ldns_rr_clone(
13297b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(
13307b5038d7SDag-Erling Smørgrav domain_keys,
13317b5038d7SDag-Erling Smørgrav key_k)));
13327b5038d7SDag-Erling Smørgrav }
13337b5038d7SDag-Erling Smørgrav
13347b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(domain_keys);
13357b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(domain_sigs);
13367b5038d7SDag-Erling Smørgrav ldns_pkt_free(keypkt);
13377b5038d7SDag-Erling Smørgrav return trusted_keys;
13387b5038d7SDag-Erling Smørgrav }
13397b5038d7SDag-Erling Smørgrav }
13407b5038d7SDag-Erling Smørgrav }
13417b5038d7SDag-Erling Smørgrav
13427b5038d7SDag-Erling Smørgrav /* Only push our trusted key */
13437b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(trusted_keys,
13447b5038d7SDag-Erling Smørgrav ldns_rr_clone(cur_key));
13457b5038d7SDag-Erling Smørgrav }
13467b5038d7SDag-Erling Smørgrav }
13477b5038d7SDag-Erling Smørgrav }
13487b5038d7SDag-Erling Smørgrav
13497b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(domain_keys);
13507b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(domain_sigs);
13517b5038d7SDag-Erling Smørgrav ldns_pkt_free(keypkt);
13527b5038d7SDag-Erling Smørgrav
13537b5038d7SDag-Erling Smørgrav } else {
13547b5038d7SDag-Erling Smørgrav /* LDNS_STATUS_CRYPTO_NO_DNSKEY */
13557b5038d7SDag-Erling Smørgrav }
13567b5038d7SDag-Erling Smørgrav
13577b5038d7SDag-Erling Smørgrav return trusted_keys;
13587b5038d7SDag-Erling Smørgrav }
13597b5038d7SDag-Erling Smørgrav
13607b5038d7SDag-Erling Smørgrav ldns_rr_list *
ldns_validate_domain_dnskey(const ldns_resolver * res,const ldns_rdf * domain,const ldns_rr_list * keys)13617b5038d7SDag-Erling Smørgrav ldns_validate_domain_dnskey(const ldns_resolver * res,
13627b5038d7SDag-Erling Smørgrav const ldns_rdf * domain,
13637b5038d7SDag-Erling Smørgrav const ldns_rr_list * keys)
13647b5038d7SDag-Erling Smørgrav {
13657b5038d7SDag-Erling Smørgrav return ldns_validate_domain_dnskey_time(
13667b5038d7SDag-Erling Smørgrav res, domain, keys, ldns_time(NULL));
13677b5038d7SDag-Erling Smørgrav }
13687b5038d7SDag-Erling Smørgrav
13697b5038d7SDag-Erling Smørgrav ldns_rr_list *
ldns_validate_domain_ds_time(const ldns_resolver * res,const ldns_rdf * domain,const ldns_rr_list * keys,time_t check_time)13707b5038d7SDag-Erling Smørgrav ldns_validate_domain_ds_time(
13717b5038d7SDag-Erling Smørgrav const ldns_resolver *res,
13727b5038d7SDag-Erling Smørgrav const ldns_rdf * domain,
13737b5038d7SDag-Erling Smørgrav const ldns_rr_list * keys,
13747b5038d7SDag-Erling Smørgrav time_t check_time)
13757b5038d7SDag-Erling Smørgrav {
13767b5038d7SDag-Erling Smørgrav ldns_pkt * dspkt;
13777b5038d7SDag-Erling Smørgrav uint16_t key_i;
13787b5038d7SDag-Erling Smørgrav ldns_rr_list * rrset = NULL;
13797b5038d7SDag-Erling Smørgrav ldns_rr_list * sigs = NULL;
13807b5038d7SDag-Erling Smørgrav ldns_rr_list * trusted_keys = NULL;
13817b5038d7SDag-Erling Smørgrav
13827b5038d7SDag-Erling Smørgrav /* Fetch DS for the domain */
13837b5038d7SDag-Erling Smørgrav dspkt = ldns_resolver_query(res, domain,
13847b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN, LDNS_RD);
13857b5038d7SDag-Erling Smørgrav if (dspkt) {
13867b5038d7SDag-Erling Smørgrav rrset = ldns_pkt_rr_list_by_type(dspkt,
13877b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DS,
13887b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANSWER);
13897b5038d7SDag-Erling Smørgrav sigs = ldns_pkt_rr_list_by_type(dspkt,
13907b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_RRSIG,
13917b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANSWER);
13927b5038d7SDag-Erling Smørgrav
13937b5038d7SDag-Erling Smørgrav /* Validate sigs */
13947b5038d7SDag-Erling Smørgrav if (ldns_verify_time(rrset, sigs, keys, check_time, NULL)
13957b5038d7SDag-Erling Smørgrav == LDNS_STATUS_OK) {
13967b5038d7SDag-Erling Smørgrav trusted_keys = ldns_rr_list_new();
13977b5038d7SDag-Erling Smørgrav for (key_i=0; key_i<ldns_rr_list_rr_count(rrset); key_i++) {
13987b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(trusted_keys,
13997b5038d7SDag-Erling Smørgrav ldns_rr_clone(ldns_rr_list_rr(rrset,
14007b5038d7SDag-Erling Smørgrav key_i)
14017b5038d7SDag-Erling Smørgrav )
14027b5038d7SDag-Erling Smørgrav );
14037b5038d7SDag-Erling Smørgrav }
14047b5038d7SDag-Erling Smørgrav }
14057b5038d7SDag-Erling Smørgrav
14067b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset);
14077b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(sigs);
14087b5038d7SDag-Erling Smørgrav ldns_pkt_free(dspkt);
14097b5038d7SDag-Erling Smørgrav
14107b5038d7SDag-Erling Smørgrav } else {
14117b5038d7SDag-Erling Smørgrav /* LDNS_STATUS_CRYPTO_NO_DS */
14127b5038d7SDag-Erling Smørgrav }
14137b5038d7SDag-Erling Smørgrav
14147b5038d7SDag-Erling Smørgrav return trusted_keys;
14157b5038d7SDag-Erling Smørgrav }
14167b5038d7SDag-Erling Smørgrav
14177b5038d7SDag-Erling Smørgrav ldns_rr_list *
ldns_validate_domain_ds(const ldns_resolver * res,const ldns_rdf * domain,const ldns_rr_list * keys)14187b5038d7SDag-Erling Smørgrav ldns_validate_domain_ds(const ldns_resolver *res,
14197b5038d7SDag-Erling Smørgrav const ldns_rdf * domain,
14207b5038d7SDag-Erling Smørgrav const ldns_rr_list * keys)
14217b5038d7SDag-Erling Smørgrav {
14227b5038d7SDag-Erling Smørgrav return ldns_validate_domain_ds_time(res, domain, keys, ldns_time(NULL));
14237b5038d7SDag-Erling Smørgrav }
14247b5038d7SDag-Erling Smørgrav
14257b5038d7SDag-Erling Smørgrav ldns_status
ldns_verify_trusted_time(ldns_resolver * res,ldns_rr_list * rrset,ldns_rr_list * rrsigs,time_t check_time,ldns_rr_list * validating_keys)14267b5038d7SDag-Erling Smørgrav ldns_verify_trusted_time(
14277b5038d7SDag-Erling Smørgrav ldns_resolver *res,
14287b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset,
14297b5038d7SDag-Erling Smørgrav ldns_rr_list * rrsigs,
14307b5038d7SDag-Erling Smørgrav time_t check_time,
14317b5038d7SDag-Erling Smørgrav ldns_rr_list * validating_keys
14327b5038d7SDag-Erling Smørgrav )
14337b5038d7SDag-Erling Smørgrav {
14347b5038d7SDag-Erling Smørgrav uint16_t sig_i; uint16_t key_i;
14357b5038d7SDag-Erling Smørgrav ldns_rr * cur_sig; ldns_rr * cur_key;
14367b5038d7SDag-Erling Smørgrav ldns_rr_list * trusted_keys = NULL;
14377b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_ERR;
14387b5038d7SDag-Erling Smørgrav
14397b5038d7SDag-Erling Smørgrav if (!res || !rrset || !rrsigs) {
14407b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
14417b5038d7SDag-Erling Smørgrav }
14427b5038d7SDag-Erling Smørgrav
14437b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(rrset) < 1) {
14447b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
14457b5038d7SDag-Erling Smørgrav }
14467b5038d7SDag-Erling Smørgrav
14477b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(rrsigs) < 1) {
14487b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_NO_RRSIG;
14497b5038d7SDag-Erling Smørgrav }
14507b5038d7SDag-Erling Smørgrav
14517b5038d7SDag-Erling Smørgrav /* Look at each sig */
14527b5038d7SDag-Erling Smørgrav for (sig_i=0; sig_i < ldns_rr_list_rr_count(rrsigs); sig_i++) {
14537b5038d7SDag-Erling Smørgrav
14547b5038d7SDag-Erling Smørgrav cur_sig = ldns_rr_list_rr(rrsigs, sig_i);
14557b5038d7SDag-Erling Smørgrav /* Get a valid signer key and validate the sig */
14567b5038d7SDag-Erling Smørgrav if ((trusted_keys = ldns_fetch_valid_domain_keys_time(
14577b5038d7SDag-Erling Smørgrav res,
14587b5038d7SDag-Erling Smørgrav ldns_rr_rrsig_signame(cur_sig),
14597b5038d7SDag-Erling Smørgrav ldns_resolver_dnssec_anchors(res),
14607b5038d7SDag-Erling Smørgrav check_time,
14617b5038d7SDag-Erling Smørgrav &result))) {
14627b5038d7SDag-Erling Smørgrav
14637b5038d7SDag-Erling Smørgrav for (key_i = 0;
14647b5038d7SDag-Erling Smørgrav key_i < ldns_rr_list_rr_count(trusted_keys);
14657b5038d7SDag-Erling Smørgrav key_i++) {
14667b5038d7SDag-Erling Smørgrav cur_key = ldns_rr_list_rr(trusted_keys, key_i);
14677b5038d7SDag-Erling Smørgrav
14687b5038d7SDag-Erling Smørgrav if ((result = ldns_verify_rrsig_time(rrset,
14697b5038d7SDag-Erling Smørgrav cur_sig,
14707b5038d7SDag-Erling Smørgrav cur_key,
14717b5038d7SDag-Erling Smørgrav check_time))
14727b5038d7SDag-Erling Smørgrav == LDNS_STATUS_OK) {
14737b5038d7SDag-Erling Smørgrav if (validating_keys) {
14747b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(validating_keys,
14757b5038d7SDag-Erling Smørgrav ldns_rr_clone(cur_key));
14767b5038d7SDag-Erling Smørgrav }
14777b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(trusted_keys);
14787b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
14797b5038d7SDag-Erling Smørgrav }
14807b5038d7SDag-Erling Smørgrav }
14817b5038d7SDag-Erling Smørgrav }
14827b5038d7SDag-Erling Smørgrav }
14837b5038d7SDag-Erling Smørgrav
14847b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(trusted_keys);
14857b5038d7SDag-Erling Smørgrav return result;
14867b5038d7SDag-Erling Smørgrav }
14877b5038d7SDag-Erling Smørgrav
14887b5038d7SDag-Erling Smørgrav ldns_status
ldns_verify_trusted(ldns_resolver * res,ldns_rr_list * rrset,ldns_rr_list * rrsigs,ldns_rr_list * validating_keys)14897b5038d7SDag-Erling Smørgrav ldns_verify_trusted(
14907b5038d7SDag-Erling Smørgrav ldns_resolver *res,
14917b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset,
14927b5038d7SDag-Erling Smørgrav ldns_rr_list * rrsigs,
14937b5038d7SDag-Erling Smørgrav ldns_rr_list * validating_keys)
14947b5038d7SDag-Erling Smørgrav {
14957b5038d7SDag-Erling Smørgrav return ldns_verify_trusted_time(
14967b5038d7SDag-Erling Smørgrav res, rrset, rrsigs, ldns_time(NULL), validating_keys);
14977b5038d7SDag-Erling Smørgrav }
14987b5038d7SDag-Erling Smørgrav
14997b5038d7SDag-Erling Smørgrav
15007b5038d7SDag-Erling Smørgrav ldns_status
ldns_dnssec_verify_denial(ldns_rr * rr,ldns_rr_list * nsecs,ldns_rr_list * rrsigs)15017b5038d7SDag-Erling Smørgrav ldns_dnssec_verify_denial(ldns_rr *rr,
15027b5038d7SDag-Erling Smørgrav ldns_rr_list *nsecs,
15037b5038d7SDag-Erling Smørgrav ldns_rr_list *rrsigs)
15047b5038d7SDag-Erling Smørgrav {
15057b5038d7SDag-Erling Smørgrav ldns_rdf *rr_name;
1506*5afab0e5SDag-Erling Smørgrav ldns_rdf *wildcard_name = NULL;
15077b5038d7SDag-Erling Smørgrav ldns_rdf *chopped_dname;
15087b5038d7SDag-Erling Smørgrav ldns_rr *cur_nsec;
15097b5038d7SDag-Erling Smørgrav size_t i;
15107b5038d7SDag-Erling Smørgrav ldns_status result;
15117b5038d7SDag-Erling Smørgrav /* needed for wildcard check on exact match */
15127b5038d7SDag-Erling Smørgrav ldns_rr *rrsig;
15137b5038d7SDag-Erling Smørgrav bool name_covered = false;
15147b5038d7SDag-Erling Smørgrav bool type_covered = false;
15157b5038d7SDag-Erling Smørgrav bool wildcard_covered = false;
15167b5038d7SDag-Erling Smørgrav bool wildcard_type_covered = false;
1517*5afab0e5SDag-Erling Smørgrav bool rr_name_is_root = false;
15187b5038d7SDag-Erling Smørgrav
15197b5038d7SDag-Erling Smørgrav rr_name = ldns_rr_owner(rr);
1520*5afab0e5SDag-Erling Smørgrav rr_name_is_root = ldns_rdf_size(rr_name) == 1
1521*5afab0e5SDag-Erling Smørgrav && *ldns_rdf_data(rr_name) == 0;
1522*5afab0e5SDag-Erling Smørgrav if (!rr_name_is_root) {
1523*5afab0e5SDag-Erling Smørgrav wildcard_name = ldns_dname_new_frm_str("*");
15247b5038d7SDag-Erling Smørgrav chopped_dname = ldns_dname_left_chop(rr_name);
15257b5038d7SDag-Erling Smørgrav result = ldns_dname_cat(wildcard_name, chopped_dname);
15262787e39aSDag-Erling Smørgrav ldns_rdf_deep_free(chopped_dname);
15277b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) {
15287b5038d7SDag-Erling Smørgrav return result;
15297b5038d7SDag-Erling Smørgrav }
1530*5afab0e5SDag-Erling Smørgrav }
15317b5038d7SDag-Erling Smørgrav
15327b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
15337b5038d7SDag-Erling Smørgrav cur_nsec = ldns_rr_list_rr(nsecs, i);
15347b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(rr_name, ldns_rr_owner(cur_nsec)) == 0) {
15357b5038d7SDag-Erling Smørgrav /* see section 5.4 of RFC4035, if the label count of the NSEC's
15367b5038d7SDag-Erling Smørgrav RRSIG is equal, then it is proven that wildcard expansion
15377b5038d7SDag-Erling Smørgrav could not have been used to match the request */
15387b5038d7SDag-Erling Smørgrav rrsig = ldns_dnssec_get_rrsig_for_name_and_type(
15397b5038d7SDag-Erling Smørgrav ldns_rr_owner(cur_nsec),
15407b5038d7SDag-Erling Smørgrav ldns_rr_get_type(cur_nsec),
15417b5038d7SDag-Erling Smørgrav rrsigs);
15427b5038d7SDag-Erling Smørgrav if (rrsig && ldns_rdf2native_int8(ldns_rr_rrsig_labels(rrsig))
15437b5038d7SDag-Erling Smørgrav == ldns_dname_label_count(rr_name)) {
15447b5038d7SDag-Erling Smørgrav wildcard_covered = true;
15457b5038d7SDag-Erling Smørgrav }
15467b5038d7SDag-Erling Smørgrav
15477b5038d7SDag-Erling Smørgrav if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
15487b5038d7SDag-Erling Smørgrav ldns_rr_get_type(rr))) {
15497b5038d7SDag-Erling Smørgrav type_covered = true;
15507b5038d7SDag-Erling Smørgrav }
15517b5038d7SDag-Erling Smørgrav }
15527b5038d7SDag-Erling Smørgrav if (ldns_nsec_covers_name(cur_nsec, rr_name)) {
15537b5038d7SDag-Erling Smørgrav name_covered = true;
15547b5038d7SDag-Erling Smørgrav }
15557b5038d7SDag-Erling Smørgrav
1556*5afab0e5SDag-Erling Smørgrav if (rr_name_is_root)
1557*5afab0e5SDag-Erling Smørgrav continue;
1558*5afab0e5SDag-Erling Smørgrav
15597b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(wildcard_name,
15607b5038d7SDag-Erling Smørgrav ldns_rr_owner(cur_nsec)) == 0) {
15617b5038d7SDag-Erling Smørgrav if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
15627b5038d7SDag-Erling Smørgrav ldns_rr_get_type(rr))) {
15637b5038d7SDag-Erling Smørgrav wildcard_type_covered = true;
15647b5038d7SDag-Erling Smørgrav }
15657b5038d7SDag-Erling Smørgrav }
15667b5038d7SDag-Erling Smørgrav
15677b5038d7SDag-Erling Smørgrav if (ldns_nsec_covers_name(cur_nsec, wildcard_name)) {
15687b5038d7SDag-Erling Smørgrav wildcard_covered = true;
15697b5038d7SDag-Erling Smørgrav }
15707b5038d7SDag-Erling Smørgrav
15717b5038d7SDag-Erling Smørgrav }
15727b5038d7SDag-Erling Smørgrav
15737b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(wildcard_name);
15747b5038d7SDag-Erling Smørgrav
15757b5038d7SDag-Erling Smørgrav if (type_covered || !name_covered) {
15767b5038d7SDag-Erling Smørgrav return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
15777b5038d7SDag-Erling Smørgrav }
15787b5038d7SDag-Erling Smørgrav
1579*5afab0e5SDag-Erling Smørgrav if (rr_name_is_root)
1580*5afab0e5SDag-Erling Smørgrav return LDNS_STATUS_OK;
1581*5afab0e5SDag-Erling Smørgrav
15827b5038d7SDag-Erling Smørgrav if (wildcard_type_covered || !wildcard_covered) {
15837b5038d7SDag-Erling Smørgrav return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
15847b5038d7SDag-Erling Smørgrav }
15857b5038d7SDag-Erling Smørgrav
15867b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
15877b5038d7SDag-Erling Smørgrav }
15887b5038d7SDag-Erling Smørgrav
15897b5038d7SDag-Erling Smørgrav ldns_status
ldns_dnssec_verify_denial_nsec3_match(ldns_rr * rr,ldns_rr_list * nsecs,ATTR_UNUSED (ldns_rr_list * rrsigs),ldns_pkt_rcode packet_rcode,ldns_rr_type packet_qtype,bool packet_nodata,ldns_rr ** match)15907b5038d7SDag-Erling Smørgrav ldns_dnssec_verify_denial_nsec3_match( ldns_rr *rr
15917b5038d7SDag-Erling Smørgrav , ldns_rr_list *nsecs
15927b5038d7SDag-Erling Smørgrav , ATTR_UNUSED(ldns_rr_list *rrsigs)
15937b5038d7SDag-Erling Smørgrav , ldns_pkt_rcode packet_rcode
15947b5038d7SDag-Erling Smørgrav , ldns_rr_type packet_qtype
15957b5038d7SDag-Erling Smørgrav , bool packet_nodata
15967b5038d7SDag-Erling Smørgrav , ldns_rr **match
15977b5038d7SDag-Erling Smørgrav )
15987b5038d7SDag-Erling Smørgrav {
15997b5038d7SDag-Erling Smørgrav ldns_rdf *closest_encloser;
16007b5038d7SDag-Erling Smørgrav ldns_rdf *wildcard;
16017b5038d7SDag-Erling Smørgrav ldns_rdf *hashed_wildcard_name;
16027b5038d7SDag-Erling Smørgrav bool wildcard_covered = false;
16037b5038d7SDag-Erling Smørgrav ldns_rdf *zone_name;
16047b5038d7SDag-Erling Smørgrav ldns_rdf *hashed_name;
16057b5038d7SDag-Erling Smørgrav ldns_rdf *hashed_next_closer;
16067b5038d7SDag-Erling Smørgrav size_t i;
16077b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
16087b5038d7SDag-Erling Smørgrav
16097b5038d7SDag-Erling Smørgrav if (match) {
16107b5038d7SDag-Erling Smørgrav *match = NULL;
16117b5038d7SDag-Erling Smørgrav }
16127b5038d7SDag-Erling Smørgrav
16137b5038d7SDag-Erling Smørgrav zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
16147b5038d7SDag-Erling Smørgrav
16157b5038d7SDag-Erling Smørgrav /* section 8.4 */
16167b5038d7SDag-Erling Smørgrav if (packet_rcode == LDNS_RCODE_NXDOMAIN) {
16177b5038d7SDag-Erling Smørgrav closest_encloser = ldns_dnssec_nsec3_closest_encloser(
16187b5038d7SDag-Erling Smørgrav ldns_rr_owner(rr),
16197b5038d7SDag-Erling Smørgrav ldns_rr_get_type(rr),
16207b5038d7SDag-Erling Smørgrav nsecs);
16217b5038d7SDag-Erling Smørgrav if(!closest_encloser) {
16222787e39aSDag-Erling Smørgrav result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
16237b5038d7SDag-Erling Smørgrav goto done;
16247b5038d7SDag-Erling Smørgrav }
16257b5038d7SDag-Erling Smørgrav
16267b5038d7SDag-Erling Smørgrav wildcard = ldns_dname_new_frm_str("*");
16277b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(wildcard, closest_encloser);
16287b5038d7SDag-Erling Smørgrav
16297b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
16307b5038d7SDag-Erling Smørgrav hashed_wildcard_name =
16317b5038d7SDag-Erling Smørgrav ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
16327b5038d7SDag-Erling Smørgrav wildcard
16337b5038d7SDag-Erling Smørgrav );
16347b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(hashed_wildcard_name, zone_name);
16357b5038d7SDag-Erling Smørgrav
16367b5038d7SDag-Erling Smørgrav if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
16377b5038d7SDag-Erling Smørgrav hashed_wildcard_name)) {
16387b5038d7SDag-Erling Smørgrav wildcard_covered = true;
16397b5038d7SDag-Erling Smørgrav if (match) {
16407b5038d7SDag-Erling Smørgrav *match = ldns_rr_list_rr(nsecs, i);
16417b5038d7SDag-Erling Smørgrav }
16427b5038d7SDag-Erling Smørgrav }
16437b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_wildcard_name);
16447b5038d7SDag-Erling Smørgrav }
16457b5038d7SDag-Erling Smørgrav
16462787e39aSDag-Erling Smørgrav if (! wildcard_covered) {
16472787e39aSDag-Erling Smørgrav result = LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
16482787e39aSDag-Erling Smørgrav } else {
16492787e39aSDag-Erling Smørgrav result = LDNS_STATUS_OK;
16502787e39aSDag-Erling Smørgrav }
16517b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(closest_encloser);
16527b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(wildcard);
16537b5038d7SDag-Erling Smørgrav
16547b5038d7SDag-Erling Smørgrav } else if (packet_nodata && packet_qtype != LDNS_RR_TYPE_DS) {
16557b5038d7SDag-Erling Smørgrav /* section 8.5 */
16567b5038d7SDag-Erling Smørgrav hashed_name = ldns_nsec3_hash_name_frm_nsec3(
16577b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(nsecs, 0),
16587b5038d7SDag-Erling Smørgrav ldns_rr_owner(rr));
16597b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(hashed_name, zone_name);
16607b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
16617b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(hashed_name,
16627b5038d7SDag-Erling Smørgrav ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
16637b5038d7SDag-Erling Smørgrav == 0) {
16647b5038d7SDag-Erling Smørgrav if (!ldns_nsec_bitmap_covers_type(
16657b5038d7SDag-Erling Smørgrav ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
16667b5038d7SDag-Erling Smørgrav packet_qtype)
16677b5038d7SDag-Erling Smørgrav &&
16687b5038d7SDag-Erling Smørgrav !ldns_nsec_bitmap_covers_type(
16697b5038d7SDag-Erling Smørgrav ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
16707b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_CNAME)) {
16717b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_OK;
16727b5038d7SDag-Erling Smørgrav if (match) {
16737b5038d7SDag-Erling Smørgrav *match = ldns_rr_list_rr(nsecs, i);
16747b5038d7SDag-Erling Smørgrav }
16757b5038d7SDag-Erling Smørgrav goto done;
16767b5038d7SDag-Erling Smørgrav }
16777b5038d7SDag-Erling Smørgrav }
16787b5038d7SDag-Erling Smørgrav }
1679*5afab0e5SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_name);
16807b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
16817b5038d7SDag-Erling Smørgrav /* wildcard no data? section 8.7 */
16827b5038d7SDag-Erling Smørgrav closest_encloser = ldns_dnssec_nsec3_closest_encloser(
16837b5038d7SDag-Erling Smørgrav ldns_rr_owner(rr),
16847b5038d7SDag-Erling Smørgrav ldns_rr_get_type(rr),
16857b5038d7SDag-Erling Smørgrav nsecs);
16867b5038d7SDag-Erling Smørgrav if(!closest_encloser) {
16877b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_NSEC3_ERR;
16887b5038d7SDag-Erling Smørgrav goto done;
16897b5038d7SDag-Erling Smørgrav }
16907b5038d7SDag-Erling Smørgrav wildcard = ldns_dname_new_frm_str("*");
16917b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(wildcard, closest_encloser);
16927b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
16937b5038d7SDag-Erling Smørgrav hashed_wildcard_name =
16947b5038d7SDag-Erling Smørgrav ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
16957b5038d7SDag-Erling Smørgrav wildcard);
16967b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(hashed_wildcard_name, zone_name);
16977b5038d7SDag-Erling Smørgrav
16987b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(hashed_wildcard_name,
16997b5038d7SDag-Erling Smørgrav ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
17007b5038d7SDag-Erling Smørgrav == 0) {
17017b5038d7SDag-Erling Smørgrav if (!ldns_nsec_bitmap_covers_type(
17027b5038d7SDag-Erling Smørgrav ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
17037b5038d7SDag-Erling Smørgrav packet_qtype)
17047b5038d7SDag-Erling Smørgrav &&
17057b5038d7SDag-Erling Smørgrav !ldns_nsec_bitmap_covers_type(
17067b5038d7SDag-Erling Smørgrav ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
17077b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_CNAME)) {
17087b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_OK;
17097b5038d7SDag-Erling Smørgrav if (match) {
17107b5038d7SDag-Erling Smørgrav *match = ldns_rr_list_rr(nsecs, i);
17117b5038d7SDag-Erling Smørgrav }
17127b5038d7SDag-Erling Smørgrav }
17137b5038d7SDag-Erling Smørgrav }
17147b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_wildcard_name);
17157b5038d7SDag-Erling Smørgrav if (result == LDNS_STATUS_OK) {
17167b5038d7SDag-Erling Smørgrav break;
17177b5038d7SDag-Erling Smørgrav }
17187b5038d7SDag-Erling Smørgrav }
17197b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(closest_encloser);
17207b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(wildcard);
17217b5038d7SDag-Erling Smørgrav } else if (packet_nodata && packet_qtype == LDNS_RR_TYPE_DS) {
17227b5038d7SDag-Erling Smørgrav /* section 8.6 */
17237b5038d7SDag-Erling Smørgrav /* note: up to XXX this is the same as for 8.5 */
17247b5038d7SDag-Erling Smørgrav hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs,
17257b5038d7SDag-Erling Smørgrav 0),
17267b5038d7SDag-Erling Smørgrav ldns_rr_owner(rr)
17277b5038d7SDag-Erling Smørgrav );
17287b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(hashed_name, zone_name);
17297b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
17307b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(hashed_name,
17317b5038d7SDag-Erling Smørgrav ldns_rr_owner(ldns_rr_list_rr(nsecs,
17327b5038d7SDag-Erling Smørgrav i)))
17337b5038d7SDag-Erling Smørgrav == 0) {
17347b5038d7SDag-Erling Smørgrav if (!ldns_nsec_bitmap_covers_type(
17357b5038d7SDag-Erling Smørgrav ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
17367b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_DS)
17377b5038d7SDag-Erling Smørgrav &&
17387b5038d7SDag-Erling Smørgrav !ldns_nsec_bitmap_covers_type(
17397b5038d7SDag-Erling Smørgrav ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
17407b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_CNAME)) {
17417b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_OK;
17427b5038d7SDag-Erling Smørgrav if (match) {
17437b5038d7SDag-Erling Smørgrav *match = ldns_rr_list_rr(nsecs, i);
17447b5038d7SDag-Erling Smørgrav }
17457b5038d7SDag-Erling Smørgrav goto done;
17467b5038d7SDag-Erling Smørgrav }
17477b5038d7SDag-Erling Smørgrav }
17487b5038d7SDag-Erling Smørgrav }
17497b5038d7SDag-Erling Smørgrav
17507b5038d7SDag-Erling Smørgrav /* XXX see note above */
17517b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
17527b5038d7SDag-Erling Smørgrav
17537b5038d7SDag-Erling Smørgrav closest_encloser = ldns_dnssec_nsec3_closest_encloser(
17547b5038d7SDag-Erling Smørgrav ldns_rr_owner(rr),
17557b5038d7SDag-Erling Smørgrav ldns_rr_get_type(rr),
17567b5038d7SDag-Erling Smørgrav nsecs);
17577b5038d7SDag-Erling Smørgrav if(!closest_encloser) {
17587b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_NSEC3_ERR;
17597b5038d7SDag-Erling Smørgrav goto done;
17607b5038d7SDag-Erling Smørgrav }
17617b5038d7SDag-Erling Smørgrav /* Now check if we have a Opt-Out NSEC3 that covers the "next closer"*/
17627b5038d7SDag-Erling Smørgrav
17637b5038d7SDag-Erling Smørgrav if (ldns_dname_label_count(closest_encloser) + 1
17647b5038d7SDag-Erling Smørgrav >= ldns_dname_label_count(ldns_rr_owner(rr))) {
17657b5038d7SDag-Erling Smørgrav
17667b5038d7SDag-Erling Smørgrav /* Query name *is* the "next closer". */
17677b5038d7SDag-Erling Smørgrav hashed_next_closer = hashed_name;
17687b5038d7SDag-Erling Smørgrav } else {
1769*5afab0e5SDag-Erling Smørgrav ldns_rdf *next_closer;
17707b5038d7SDag-Erling Smørgrav
1771*5afab0e5SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_name);
17727b5038d7SDag-Erling Smørgrav /* "next closer" has less labels than the query name.
17737b5038d7SDag-Erling Smørgrav * Create the name and hash it.
17747b5038d7SDag-Erling Smørgrav */
17757b5038d7SDag-Erling Smørgrav next_closer = ldns_dname_clone_from(
17767b5038d7SDag-Erling Smørgrav ldns_rr_owner(rr),
17777b5038d7SDag-Erling Smørgrav ldns_dname_label_count(ldns_rr_owner(rr))
17787b5038d7SDag-Erling Smørgrav - (ldns_dname_label_count(closest_encloser) + 1)
17797b5038d7SDag-Erling Smørgrav );
17807b5038d7SDag-Erling Smørgrav hashed_next_closer = ldns_nsec3_hash_name_frm_nsec3(
17817b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(nsecs, 0),
17827b5038d7SDag-Erling Smørgrav next_closer
17837b5038d7SDag-Erling Smørgrav );
17847b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(hashed_next_closer, zone_name);
1785*5afab0e5SDag-Erling Smørgrav ldns_rdf_deep_free(next_closer);
17867b5038d7SDag-Erling Smørgrav }
17877b5038d7SDag-Erling Smørgrav /* Find the NSEC3 that covers the "next closer" */
17887b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
17897b5038d7SDag-Erling Smørgrav if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
17907b5038d7SDag-Erling Smørgrav hashed_next_closer) &&
17917b5038d7SDag-Erling Smørgrav ldns_nsec3_optout(ldns_rr_list_rr(nsecs, i))) {
17927b5038d7SDag-Erling Smørgrav
17937b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_OK;
17947b5038d7SDag-Erling Smørgrav if (match) {
17957b5038d7SDag-Erling Smørgrav *match = ldns_rr_list_rr(nsecs, i);
17967b5038d7SDag-Erling Smørgrav }
17977b5038d7SDag-Erling Smørgrav break;
17987b5038d7SDag-Erling Smørgrav }
17997b5038d7SDag-Erling Smørgrav }
18007b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_next_closer);
18017b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(closest_encloser);
18027b5038d7SDag-Erling Smørgrav }
18037b5038d7SDag-Erling Smørgrav
18047b5038d7SDag-Erling Smørgrav done:
18057b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(zone_name);
18067b5038d7SDag-Erling Smørgrav return result;
18077b5038d7SDag-Erling Smørgrav }
18087b5038d7SDag-Erling Smørgrav
18097b5038d7SDag-Erling Smørgrav ldns_status
ldns_dnssec_verify_denial_nsec3(ldns_rr * rr,ldns_rr_list * nsecs,ldns_rr_list * rrsigs,ldns_pkt_rcode packet_rcode,ldns_rr_type packet_qtype,bool packet_nodata)18107b5038d7SDag-Erling Smørgrav ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
18117b5038d7SDag-Erling Smørgrav ldns_rr_list *nsecs,
18127b5038d7SDag-Erling Smørgrav ldns_rr_list *rrsigs,
18137b5038d7SDag-Erling Smørgrav ldns_pkt_rcode packet_rcode,
18147b5038d7SDag-Erling Smørgrav ldns_rr_type packet_qtype,
18157b5038d7SDag-Erling Smørgrav bool packet_nodata)
18167b5038d7SDag-Erling Smørgrav {
18177b5038d7SDag-Erling Smørgrav return ldns_dnssec_verify_denial_nsec3_match(
18187b5038d7SDag-Erling Smørgrav rr, nsecs, rrsigs, packet_rcode,
18197b5038d7SDag-Erling Smørgrav packet_qtype, packet_nodata, NULL
18207b5038d7SDag-Erling Smørgrav );
18217b5038d7SDag-Erling Smørgrav }
18227b5038d7SDag-Erling Smørgrav
18237b5038d7SDag-Erling Smørgrav #ifdef USE_GOST
18247b5038d7SDag-Erling Smørgrav EVP_PKEY*
ldns_gost2pkey_raw(const unsigned char * key,size_t keylen)1825986ba33cSDag-Erling Smørgrav ldns_gost2pkey_raw(const unsigned char* key, size_t keylen)
18267b5038d7SDag-Erling Smørgrav {
18277b5038d7SDag-Erling Smørgrav /* prefix header for X509 encoding */
18287b5038d7SDag-Erling Smørgrav uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
18297b5038d7SDag-Erling Smørgrav 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
18307b5038d7SDag-Erling Smørgrav 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
18317b5038d7SDag-Erling Smørgrav 0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
18327b5038d7SDag-Erling Smørgrav unsigned char encoded[37+64];
18337b5038d7SDag-Erling Smørgrav const unsigned char* pp;
18347b5038d7SDag-Erling Smørgrav if(keylen != 64) {
18357b5038d7SDag-Erling Smørgrav /* key wrong size */
18367b5038d7SDag-Erling Smørgrav return NULL;
18377b5038d7SDag-Erling Smørgrav }
18387b5038d7SDag-Erling Smørgrav
18397b5038d7SDag-Erling Smørgrav /* create evp_key */
18407b5038d7SDag-Erling Smørgrav memmove(encoded, asn, 37);
18417b5038d7SDag-Erling Smørgrav memmove(encoded+37, key, 64);
18427b5038d7SDag-Erling Smørgrav pp = (unsigned char*)&encoded[0];
18437b5038d7SDag-Erling Smørgrav
18447b5038d7SDag-Erling Smørgrav return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
18457b5038d7SDag-Erling Smørgrav }
18467b5038d7SDag-Erling Smørgrav
18477b5038d7SDag-Erling Smørgrav static ldns_status
ldns_verify_rrsig_gost_raw(const unsigned char * sig,size_t siglen,const ldns_buffer * rrset,const unsigned char * key,size_t keylen)1848986ba33cSDag-Erling Smørgrav ldns_verify_rrsig_gost_raw(const unsigned char* sig, size_t siglen,
1849986ba33cSDag-Erling Smørgrav const ldns_buffer* rrset, const unsigned char* key, size_t keylen)
18507b5038d7SDag-Erling Smørgrav {
18517b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key;
18527b5038d7SDag-Erling Smørgrav ldns_status result;
18537b5038d7SDag-Erling Smørgrav
18547b5038d7SDag-Erling Smørgrav (void) ldns_key_EVP_load_gost_id();
18557b5038d7SDag-Erling Smørgrav evp_key = ldns_gost2pkey_raw(key, keylen);
18567b5038d7SDag-Erling Smørgrav if(!evp_key) {
18577b5038d7SDag-Erling Smørgrav /* could not convert key */
18587b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_BOGUS;
18597b5038d7SDag-Erling Smørgrav }
18607b5038d7SDag-Erling Smørgrav
18617b5038d7SDag-Erling Smørgrav /* verify signature */
18627b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset,
18637b5038d7SDag-Erling Smørgrav evp_key, EVP_get_digestbyname("md_gost94"));
18647b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key);
18657b5038d7SDag-Erling Smørgrav
18667b5038d7SDag-Erling Smørgrav return result;
18677b5038d7SDag-Erling Smørgrav }
18687b5038d7SDag-Erling Smørgrav #endif
18697b5038d7SDag-Erling Smørgrav
1870986ba33cSDag-Erling Smørgrav #ifdef USE_ED25519
1871986ba33cSDag-Erling Smørgrav EVP_PKEY*
ldns_ed255192pkey_raw(const unsigned char * key,size_t keylen)1872986ba33cSDag-Erling Smørgrav ldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
1873986ba33cSDag-Erling Smørgrav {
1874*5afab0e5SDag-Erling Smørgrav /* ASN1 for ED25519 is 302a300506032b6570032100 <32byteskey> */
1875*5afab0e5SDag-Erling Smørgrav uint8_t pre[] = {0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
1876*5afab0e5SDag-Erling Smørgrav 0x70, 0x03, 0x21, 0x00};
1877*5afab0e5SDag-Erling Smørgrav int pre_len = 12;
1878*5afab0e5SDag-Erling Smørgrav uint8_t buf[256];
1879986ba33cSDag-Erling Smørgrav EVP_PKEY *evp_key;
1880*5afab0e5SDag-Erling Smørgrav /* pp gets modified by d2i() */
1881*5afab0e5SDag-Erling Smørgrav const unsigned char* pp = (unsigned char*)buf;
1882*5afab0e5SDag-Erling Smørgrav if(keylen != 32 || keylen + pre_len > sizeof(buf))
1883986ba33cSDag-Erling Smørgrav return NULL; /* wrong length */
1884*5afab0e5SDag-Erling Smørgrav memmove(buf, pre, pre_len);
1885*5afab0e5SDag-Erling Smørgrav memmove(buf+pre_len, key, keylen);
1886*5afab0e5SDag-Erling Smørgrav evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
1887986ba33cSDag-Erling Smørgrav return evp_key;
1888986ba33cSDag-Erling Smørgrav }
1889986ba33cSDag-Erling Smørgrav
1890986ba33cSDag-Erling Smørgrav static ldns_status
ldns_verify_rrsig_ed25519_raw(unsigned char * sig,size_t siglen,ldns_buffer * rrset,unsigned char * key,size_t keylen)1891986ba33cSDag-Erling Smørgrav ldns_verify_rrsig_ed25519_raw(unsigned char* sig, size_t siglen,
1892986ba33cSDag-Erling Smørgrav ldns_buffer* rrset, unsigned char* key, size_t keylen)
1893986ba33cSDag-Erling Smørgrav {
1894986ba33cSDag-Erling Smørgrav EVP_PKEY *evp_key;
1895986ba33cSDag-Erling Smørgrav ldns_status result;
1896986ba33cSDag-Erling Smørgrav
1897986ba33cSDag-Erling Smørgrav evp_key = ldns_ed255192pkey_raw(key, keylen);
1898986ba33cSDag-Erling Smørgrav if(!evp_key) {
1899986ba33cSDag-Erling Smørgrav /* could not convert key */
1900986ba33cSDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_BOGUS;
1901986ba33cSDag-Erling Smørgrav }
1902*5afab0e5SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, NULL);
1903986ba33cSDag-Erling Smørgrav EVP_PKEY_free(evp_key);
1904986ba33cSDag-Erling Smørgrav return result;
1905986ba33cSDag-Erling Smørgrav }
1906986ba33cSDag-Erling Smørgrav #endif /* USE_ED25519 */
1907986ba33cSDag-Erling Smørgrav
1908986ba33cSDag-Erling Smørgrav #ifdef USE_ED448
1909986ba33cSDag-Erling Smørgrav EVP_PKEY*
ldns_ed4482pkey_raw(const unsigned char * key,size_t keylen)1910986ba33cSDag-Erling Smørgrav ldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
1911986ba33cSDag-Erling Smørgrav {
1912*5afab0e5SDag-Erling Smørgrav /* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
1913*5afab0e5SDag-Erling Smørgrav uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
1914*5afab0e5SDag-Erling Smørgrav 0x71, 0x03, 0x3a, 0x00};
1915*5afab0e5SDag-Erling Smørgrav int pre_len = 12;
1916*5afab0e5SDag-Erling Smørgrav uint8_t buf[256];
1917986ba33cSDag-Erling Smørgrav EVP_PKEY *evp_key;
1918*5afab0e5SDag-Erling Smørgrav /* pp gets modified by d2i() */
1919*5afab0e5SDag-Erling Smørgrav const unsigned char* pp = (unsigned char*)buf;
1920*5afab0e5SDag-Erling Smørgrav if(keylen != 57 || keylen + pre_len > sizeof(buf))
1921986ba33cSDag-Erling Smørgrav return NULL; /* wrong length */
1922*5afab0e5SDag-Erling Smørgrav memmove(buf, pre, pre_len);
1923*5afab0e5SDag-Erling Smørgrav memmove(buf+pre_len, key, keylen);
1924*5afab0e5SDag-Erling Smørgrav evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
1925986ba33cSDag-Erling Smørgrav return evp_key;
1926986ba33cSDag-Erling Smørgrav }
1927986ba33cSDag-Erling Smørgrav
1928986ba33cSDag-Erling Smørgrav static ldns_status
ldns_verify_rrsig_ed448_raw(unsigned char * sig,size_t siglen,ldns_buffer * rrset,unsigned char * key,size_t keylen)1929986ba33cSDag-Erling Smørgrav ldns_verify_rrsig_ed448_raw(unsigned char* sig, size_t siglen,
1930986ba33cSDag-Erling Smørgrav ldns_buffer* rrset, unsigned char* key, size_t keylen)
1931986ba33cSDag-Erling Smørgrav {
1932986ba33cSDag-Erling Smørgrav EVP_PKEY *evp_key;
1933986ba33cSDag-Erling Smørgrav ldns_status result;
1934986ba33cSDag-Erling Smørgrav
1935986ba33cSDag-Erling Smørgrav evp_key = ldns_ed4482pkey_raw(key, keylen);
1936986ba33cSDag-Erling Smørgrav if(!evp_key) {
1937986ba33cSDag-Erling Smørgrav /* could not convert key */
1938986ba33cSDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_BOGUS;
1939986ba33cSDag-Erling Smørgrav }
1940*5afab0e5SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, NULL);
1941986ba33cSDag-Erling Smørgrav EVP_PKEY_free(evp_key);
1942986ba33cSDag-Erling Smørgrav return result;
1943986ba33cSDag-Erling Smørgrav }
1944986ba33cSDag-Erling Smørgrav #endif /* USE_ED448 */
1945986ba33cSDag-Erling Smørgrav
19467b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA
19477b5038d7SDag-Erling Smørgrav EVP_PKEY*
ldns_ecdsa2pkey_raw(const unsigned char * key,size_t keylen,uint8_t algo)1948986ba33cSDag-Erling Smørgrav ldns_ecdsa2pkey_raw(const unsigned char* key, size_t keylen, uint8_t algo)
19497b5038d7SDag-Erling Smørgrav {
19507b5038d7SDag-Erling Smørgrav unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
19517b5038d7SDag-Erling Smørgrav const unsigned char* pp = buf;
19527b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key;
19537b5038d7SDag-Erling Smørgrav EC_KEY *ec;
19547b5038d7SDag-Erling Smørgrav /* check length, which uncompressed must be 2 bignums */
19557b5038d7SDag-Erling Smørgrav if(algo == LDNS_ECDSAP256SHA256) {
19567b5038d7SDag-Erling Smørgrav if(keylen != 2*256/8) return NULL;
19577b5038d7SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
19587b5038d7SDag-Erling Smørgrav } else if(algo == LDNS_ECDSAP384SHA384) {
19597b5038d7SDag-Erling Smørgrav if(keylen != 2*384/8) return NULL;
19607b5038d7SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_secp384r1);
19617b5038d7SDag-Erling Smørgrav } else ec = NULL;
19627b5038d7SDag-Erling Smørgrav if(!ec) return NULL;
19637b5038d7SDag-Erling Smørgrav if(keylen+1 > sizeof(buf))
19647b5038d7SDag-Erling Smørgrav return NULL; /* sanity check */
19657b5038d7SDag-Erling Smørgrav /* prepend the 0x02 (from docs) (or actually 0x04 from implementation
19667b5038d7SDag-Erling Smørgrav * of openssl) for uncompressed data */
19677b5038d7SDag-Erling Smørgrav buf[0] = POINT_CONVERSION_UNCOMPRESSED;
19687b5038d7SDag-Erling Smørgrav memmove(buf+1, key, keylen);
19697b5038d7SDag-Erling Smørgrav if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
19707b5038d7SDag-Erling Smørgrav EC_KEY_free(ec);
19717b5038d7SDag-Erling Smørgrav return NULL;
19727b5038d7SDag-Erling Smørgrav }
19737b5038d7SDag-Erling Smørgrav evp_key = EVP_PKEY_new();
19747b5038d7SDag-Erling Smørgrav if(!evp_key) {
19757b5038d7SDag-Erling Smørgrav EC_KEY_free(ec);
19767b5038d7SDag-Erling Smørgrav return NULL;
19777b5038d7SDag-Erling Smørgrav }
19787b5038d7SDag-Erling Smørgrav if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
19797b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key);
19807b5038d7SDag-Erling Smørgrav EC_KEY_free(ec);
19817b5038d7SDag-Erling Smørgrav return NULL;
19827b5038d7SDag-Erling Smørgrav }
19837b5038d7SDag-Erling Smørgrav return evp_key;
19847b5038d7SDag-Erling Smørgrav }
19857b5038d7SDag-Erling Smørgrav
19867b5038d7SDag-Erling Smørgrav static ldns_status
ldns_verify_rrsig_ecdsa_raw(unsigned char * sig,size_t siglen,ldns_buffer * rrset,unsigned char * key,size_t keylen,uint8_t algo)19877b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_ecdsa_raw(unsigned char* sig, size_t siglen,
19887b5038d7SDag-Erling Smørgrav ldns_buffer* rrset, unsigned char* key, size_t keylen, uint8_t algo)
19897b5038d7SDag-Erling Smørgrav {
19907b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key;
19917b5038d7SDag-Erling Smørgrav ldns_status result;
19927b5038d7SDag-Erling Smørgrav const EVP_MD *d;
19937b5038d7SDag-Erling Smørgrav
19947b5038d7SDag-Erling Smørgrav evp_key = ldns_ecdsa2pkey_raw(key, keylen, algo);
19957b5038d7SDag-Erling Smørgrav if(!evp_key) {
19967b5038d7SDag-Erling Smørgrav /* could not convert key */
19977b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_BOGUS;
19987b5038d7SDag-Erling Smørgrav }
19997b5038d7SDag-Erling Smørgrav if(algo == LDNS_ECDSAP256SHA256)
20007b5038d7SDag-Erling Smørgrav d = EVP_sha256();
20017b5038d7SDag-Erling Smørgrav else d = EVP_sha384(); /* LDNS_ECDSAP384SHA384 */
20027b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, d);
20037b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key);
20047b5038d7SDag-Erling Smørgrav return result;
20057b5038d7SDag-Erling Smørgrav }
20067b5038d7SDag-Erling Smørgrav #endif
20077b5038d7SDag-Erling Smørgrav
20087b5038d7SDag-Erling Smørgrav ldns_status
ldns_verify_rrsig_buffers(ldns_buffer * rawsig_buf,ldns_buffer * verify_buf,ldns_buffer * key_buf,uint8_t algo)20097b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf,
20107b5038d7SDag-Erling Smørgrav ldns_buffer *key_buf, uint8_t algo)
20117b5038d7SDag-Erling Smørgrav {
20127b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_buffers_raw(
20137b5038d7SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(rawsig_buf),
20147b5038d7SDag-Erling Smørgrav ldns_buffer_position(rawsig_buf),
20157b5038d7SDag-Erling Smørgrav verify_buf,
20167b5038d7SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(key_buf),
20177b5038d7SDag-Erling Smørgrav ldns_buffer_position(key_buf), algo);
20187b5038d7SDag-Erling Smørgrav }
20197b5038d7SDag-Erling Smørgrav
20207b5038d7SDag-Erling Smørgrav ldns_status
ldns_verify_rrsig_buffers_raw(unsigned char * sig,size_t siglen,ldns_buffer * verify_buf,unsigned char * key,size_t keylen,uint8_t algo)20217b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
20227b5038d7SDag-Erling Smørgrav ldns_buffer *verify_buf, unsigned char* key, size_t keylen,
20237b5038d7SDag-Erling Smørgrav uint8_t algo)
20247b5038d7SDag-Erling Smørgrav {
20257b5038d7SDag-Erling Smørgrav /* check for right key */
20267b5038d7SDag-Erling Smørgrav switch(algo) {
2027986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
20287b5038d7SDag-Erling Smørgrav case LDNS_DSA:
20297b5038d7SDag-Erling Smørgrav case LDNS_DSA_NSEC3:
20307b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_dsa_raw(sig,
20317b5038d7SDag-Erling Smørgrav siglen,
20327b5038d7SDag-Erling Smørgrav verify_buf,
20337b5038d7SDag-Erling Smørgrav key,
20347b5038d7SDag-Erling Smørgrav keylen);
20357b5038d7SDag-Erling Smørgrav break;
2036986ba33cSDag-Erling Smørgrav #endif
20377b5038d7SDag-Erling Smørgrav case LDNS_RSASHA1:
20387b5038d7SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3:
20397b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_rsasha1_raw(sig,
20407b5038d7SDag-Erling Smørgrav siglen,
20417b5038d7SDag-Erling Smørgrav verify_buf,
20427b5038d7SDag-Erling Smørgrav key,
20437b5038d7SDag-Erling Smørgrav keylen);
20447b5038d7SDag-Erling Smørgrav break;
20457b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2
20467b5038d7SDag-Erling Smørgrav case LDNS_RSASHA256:
20477b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_rsasha256_raw(sig,
20487b5038d7SDag-Erling Smørgrav siglen,
20497b5038d7SDag-Erling Smørgrav verify_buf,
20507b5038d7SDag-Erling Smørgrav key,
20517b5038d7SDag-Erling Smørgrav keylen);
20527b5038d7SDag-Erling Smørgrav break;
20537b5038d7SDag-Erling Smørgrav case LDNS_RSASHA512:
20547b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_rsasha512_raw(sig,
20557b5038d7SDag-Erling Smørgrav siglen,
20567b5038d7SDag-Erling Smørgrav verify_buf,
20577b5038d7SDag-Erling Smørgrav key,
20587b5038d7SDag-Erling Smørgrav keylen);
20597b5038d7SDag-Erling Smørgrav break;
20607b5038d7SDag-Erling Smørgrav #endif
20617b5038d7SDag-Erling Smørgrav #ifdef USE_GOST
20627b5038d7SDag-Erling Smørgrav case LDNS_ECC_GOST:
20637b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_gost_raw(sig, siglen, verify_buf,
20647b5038d7SDag-Erling Smørgrav key, keylen);
20657b5038d7SDag-Erling Smørgrav break;
20667b5038d7SDag-Erling Smørgrav #endif
20677b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA
20687b5038d7SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256:
20697b5038d7SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384:
20707b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_ecdsa_raw(sig, siglen, verify_buf,
20717b5038d7SDag-Erling Smørgrav key, keylen, algo);
20727b5038d7SDag-Erling Smørgrav break;
20737b5038d7SDag-Erling Smørgrav #endif
2074986ba33cSDag-Erling Smørgrav #ifdef USE_ED25519
2075986ba33cSDag-Erling Smørgrav case LDNS_ED25519:
2076986ba33cSDag-Erling Smørgrav return ldns_verify_rrsig_ed25519_raw(sig, siglen, verify_buf,
2077986ba33cSDag-Erling Smørgrav key, keylen);
2078986ba33cSDag-Erling Smørgrav break;
2079986ba33cSDag-Erling Smørgrav #endif
2080986ba33cSDag-Erling Smørgrav #ifdef USE_ED448
2081986ba33cSDag-Erling Smørgrav case LDNS_ED448:
2082986ba33cSDag-Erling Smørgrav return ldns_verify_rrsig_ed448_raw(sig, siglen, verify_buf,
2083986ba33cSDag-Erling Smørgrav key, keylen);
2084986ba33cSDag-Erling Smørgrav break;
2085986ba33cSDag-Erling Smørgrav #endif
20867b5038d7SDag-Erling Smørgrav case LDNS_RSAMD5:
20877b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_rsamd5_raw(sig,
20887b5038d7SDag-Erling Smørgrav siglen,
20897b5038d7SDag-Erling Smørgrav verify_buf,
20907b5038d7SDag-Erling Smørgrav key,
20917b5038d7SDag-Erling Smørgrav keylen);
20927b5038d7SDag-Erling Smørgrav break;
20937b5038d7SDag-Erling Smørgrav default:
20947b5038d7SDag-Erling Smørgrav /* do you know this alg?! */
20957b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
20967b5038d7SDag-Erling Smørgrav }
20977b5038d7SDag-Erling Smørgrav }
20987b5038d7SDag-Erling Smørgrav
20997b5038d7SDag-Erling Smørgrav
21007b5038d7SDag-Erling Smørgrav /**
21017b5038d7SDag-Erling Smørgrav * Reset the ttl in the rrset with the orig_ttl from the sig
21027b5038d7SDag-Erling Smørgrav * and update owner name if it was wildcard
21037b5038d7SDag-Erling Smørgrav * Also canonicalizes the rrset.
21047b5038d7SDag-Erling Smørgrav * @param rrset: rrset to modify
21057b5038d7SDag-Erling Smørgrav * @param sig: signature to take TTL and wildcard values from
21067b5038d7SDag-Erling Smørgrav */
21077b5038d7SDag-Erling Smørgrav static void
ldns_rrset_use_signature_ttl(ldns_rr_list * rrset_clone,const ldns_rr * rrsig)2108986ba33cSDag-Erling Smørgrav ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, const ldns_rr* rrsig)
21097b5038d7SDag-Erling Smørgrav {
21107b5038d7SDag-Erling Smørgrav uint32_t orig_ttl;
21117b5038d7SDag-Erling Smørgrav uint16_t i;
21127b5038d7SDag-Erling Smørgrav uint8_t label_count;
21137b5038d7SDag-Erling Smørgrav ldns_rdf *wildcard_name;
21147b5038d7SDag-Erling Smørgrav ldns_rdf *wildcard_chopped;
21157b5038d7SDag-Erling Smørgrav ldns_rdf *wildcard_chopped_tmp;
21167b5038d7SDag-Erling Smørgrav
21177b5038d7SDag-Erling Smørgrav if ((rrsig == NULL) || ldns_rr_rd_count(rrsig) < 4) {
21187b5038d7SDag-Erling Smørgrav return;
21197b5038d7SDag-Erling Smørgrav }
21207b5038d7SDag-Erling Smørgrav
21217b5038d7SDag-Erling Smørgrav orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
21227b5038d7SDag-Erling Smørgrav label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
21237b5038d7SDag-Erling Smørgrav
21247b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
21257b5038d7SDag-Erling Smørgrav if (label_count <
21267b5038d7SDag-Erling Smørgrav ldns_dname_label_count(
21277b5038d7SDag-Erling Smørgrav ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
21287b5038d7SDag-Erling Smørgrav (void) ldns_str2rdf_dname(&wildcard_name, "*");
21297b5038d7SDag-Erling Smørgrav wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(
21307b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rrset_clone, i)));
21317b5038d7SDag-Erling Smørgrav while (label_count < ldns_dname_label_count(wildcard_chopped)) {
21327b5038d7SDag-Erling Smørgrav wildcard_chopped_tmp = ldns_dname_left_chop(
21337b5038d7SDag-Erling Smørgrav wildcard_chopped);
21347b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(wildcard_chopped);
21357b5038d7SDag-Erling Smørgrav wildcard_chopped = wildcard_chopped_tmp;
21367b5038d7SDag-Erling Smørgrav }
21377b5038d7SDag-Erling Smørgrav (void) ldns_dname_cat(wildcard_name, wildcard_chopped);
21387b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(wildcard_chopped);
21397b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(
21407b5038d7SDag-Erling Smørgrav rrset_clone, i)));
21417b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i),
21427b5038d7SDag-Erling Smørgrav wildcard_name);
21437b5038d7SDag-Erling Smørgrav }
21447b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl);
21457b5038d7SDag-Erling Smørgrav /* convert to lowercase */
21467b5038d7SDag-Erling Smørgrav ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
21477b5038d7SDag-Erling Smørgrav }
21487b5038d7SDag-Erling Smørgrav }
21497b5038d7SDag-Erling Smørgrav
21507b5038d7SDag-Erling Smørgrav /**
21517b5038d7SDag-Erling Smørgrav * Make raw signature buffer out of rrsig
21527b5038d7SDag-Erling Smørgrav * @param rawsig_buf: raw signature buffer for result
21537b5038d7SDag-Erling Smørgrav * @param rrsig: signature to convert
21547b5038d7SDag-Erling Smørgrav * @return OK or more specific error.
21557b5038d7SDag-Erling Smørgrav */
21567b5038d7SDag-Erling Smørgrav static ldns_status
ldns_rrsig2rawsig_buffer(ldns_buffer * rawsig_buf,const ldns_rr * rrsig)2157986ba33cSDag-Erling Smørgrav ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, const ldns_rr* rrsig)
21587b5038d7SDag-Erling Smørgrav {
21597b5038d7SDag-Erling Smørgrav uint8_t sig_algo;
21607b5038d7SDag-Erling Smørgrav
21617b5038d7SDag-Erling Smørgrav if (rrsig == NULL) {
21627b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_NO_RRSIG;
21637b5038d7SDag-Erling Smørgrav }
21647b5038d7SDag-Erling Smørgrav if (ldns_rr_rdf(rrsig, 1) == NULL) {
21657b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
21667b5038d7SDag-Erling Smørgrav }
21677b5038d7SDag-Erling Smørgrav sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
21687b5038d7SDag-Erling Smørgrav /* check for known and implemented algo's now (otherwise
21697b5038d7SDag-Erling Smørgrav * the function could return a wrong error
21707b5038d7SDag-Erling Smørgrav */
21717b5038d7SDag-Erling Smørgrav /* create a buffer with signature rdata */
21727b5038d7SDag-Erling Smørgrav /* for some algorithms we need other data than for others... */
21737b5038d7SDag-Erling Smørgrav /* (the DSA API wants DER encoding for instance) */
21747b5038d7SDag-Erling Smørgrav
21757b5038d7SDag-Erling Smørgrav switch(sig_algo) {
21767b5038d7SDag-Erling Smørgrav case LDNS_RSAMD5:
21777b5038d7SDag-Erling Smørgrav case LDNS_RSASHA1:
21787b5038d7SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3:
21797b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2
21807b5038d7SDag-Erling Smørgrav case LDNS_RSASHA256:
21817b5038d7SDag-Erling Smørgrav case LDNS_RSASHA512:
21827b5038d7SDag-Erling Smørgrav #endif
21837b5038d7SDag-Erling Smørgrav #ifdef USE_GOST
21847b5038d7SDag-Erling Smørgrav case LDNS_ECC_GOST:
21857b5038d7SDag-Erling Smørgrav #endif
2186*5afab0e5SDag-Erling Smørgrav #ifdef USE_ED25519
2187*5afab0e5SDag-Erling Smørgrav case LDNS_ED25519:
2188*5afab0e5SDag-Erling Smørgrav #endif
2189*5afab0e5SDag-Erling Smørgrav #ifdef USE_ED448
2190*5afab0e5SDag-Erling Smørgrav case LDNS_ED448:
2191*5afab0e5SDag-Erling Smørgrav #endif
21927b5038d7SDag-Erling Smørgrav if (ldns_rr_rdf(rrsig, 8) == NULL) {
21937b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
21947b5038d7SDag-Erling Smørgrav }
21957b5038d7SDag-Erling Smørgrav if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8))
21967b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) {
21977b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
21987b5038d7SDag-Erling Smørgrav }
21997b5038d7SDag-Erling Smørgrav break;
2200986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
22017b5038d7SDag-Erling Smørgrav case LDNS_DSA:
22027b5038d7SDag-Erling Smørgrav case LDNS_DSA_NSEC3:
22037b5038d7SDag-Erling Smørgrav /* EVP takes rfc2459 format, which is a tad longer than dns format */
22047b5038d7SDag-Erling Smørgrav if (ldns_rr_rdf(rrsig, 8) == NULL) {
22057b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
22067b5038d7SDag-Erling Smørgrav }
22077b5038d7SDag-Erling Smørgrav if (ldns_convert_dsa_rrsig_rdf2asn1(
22087b5038d7SDag-Erling Smørgrav rawsig_buf, ldns_rr_rdf(rrsig, 8))
22097b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) {
22107b5038d7SDag-Erling Smørgrav /*
22117b5038d7SDag-Erling Smørgrav if (ldns_rdf2buffer_wire(rawsig_buf,
22127b5038d7SDag-Erling Smørgrav ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
22137b5038d7SDag-Erling Smørgrav */
22147b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
22157b5038d7SDag-Erling Smørgrav }
22167b5038d7SDag-Erling Smørgrav break;
2217986ba33cSDag-Erling Smørgrav #endif
22187b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA
22197b5038d7SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256:
22207b5038d7SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384:
22217b5038d7SDag-Erling Smørgrav /* EVP produces an ASN prefix on the signature, which is
22227b5038d7SDag-Erling Smørgrav * not used in the DNS */
22237b5038d7SDag-Erling Smørgrav if (ldns_rr_rdf(rrsig, 8) == NULL) {
22247b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
22257b5038d7SDag-Erling Smørgrav }
22267b5038d7SDag-Erling Smørgrav if (ldns_convert_ecdsa_rrsig_rdf2asn1(
22277b5038d7SDag-Erling Smørgrav rawsig_buf, ldns_rr_rdf(rrsig, 8))
22287b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) {
22297b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
22307b5038d7SDag-Erling Smørgrav }
22317b5038d7SDag-Erling Smørgrav break;
22327b5038d7SDag-Erling Smørgrav #endif
22337b5038d7SDag-Erling Smørgrav case LDNS_DH:
22347b5038d7SDag-Erling Smørgrav case LDNS_ECC:
22357b5038d7SDag-Erling Smørgrav case LDNS_INDIRECT:
22367b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
22377b5038d7SDag-Erling Smørgrav default:
22387b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
22397b5038d7SDag-Erling Smørgrav }
22407b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
22417b5038d7SDag-Erling Smørgrav }
22427b5038d7SDag-Erling Smørgrav
22437b5038d7SDag-Erling Smørgrav /**
22447b5038d7SDag-Erling Smørgrav * Check RRSIG timestamps against the given 'now' time.
22457b5038d7SDag-Erling Smørgrav * @param rrsig: signature to check.
22467b5038d7SDag-Erling Smørgrav * @param now: the current time in seconds epoch.
22477b5038d7SDag-Erling Smørgrav * @return status code LDNS_STATUS_OK if all is fine.
22487b5038d7SDag-Erling Smørgrav */
22497b5038d7SDag-Erling Smørgrav static ldns_status
ldns_rrsig_check_timestamps(const ldns_rr * rrsig,time_t now)2250986ba33cSDag-Erling Smørgrav ldns_rrsig_check_timestamps(const ldns_rr* rrsig, time_t now)
22517b5038d7SDag-Erling Smørgrav {
22527b5038d7SDag-Erling Smørgrav int32_t inception, expiration;
22537b5038d7SDag-Erling Smørgrav
22547b5038d7SDag-Erling Smørgrav /* check the signature time stamps */
22557b5038d7SDag-Erling Smørgrav inception = (int32_t)ldns_rdf2native_time_t(
22567b5038d7SDag-Erling Smørgrav ldns_rr_rrsig_inception(rrsig));
22577b5038d7SDag-Erling Smørgrav expiration = (int32_t)ldns_rdf2native_time_t(
22587b5038d7SDag-Erling Smørgrav ldns_rr_rrsig_expiration(rrsig));
22597b5038d7SDag-Erling Smørgrav
22607b5038d7SDag-Erling Smørgrav if (expiration - inception < 0) {
22617b5038d7SDag-Erling Smørgrav /* bad sig, expiration before inception?? Tsssg */
22627b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
22637b5038d7SDag-Erling Smørgrav }
22647b5038d7SDag-Erling Smørgrav if (((int32_t) now) - inception < 0) {
22657b5038d7SDag-Erling Smørgrav /* bad sig, inception date has not yet come to pass */
22667b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
22677b5038d7SDag-Erling Smørgrav }
22687b5038d7SDag-Erling Smørgrav if (expiration - ((int32_t) now) < 0) {
22697b5038d7SDag-Erling Smørgrav /* bad sig, expiration date has passed */
22707b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
22717b5038d7SDag-Erling Smørgrav }
22727b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
22737b5038d7SDag-Erling Smørgrav }
22747b5038d7SDag-Erling Smørgrav
22757b5038d7SDag-Erling Smørgrav /**
22767b5038d7SDag-Erling Smørgrav * Prepare for verification.
22777b5038d7SDag-Erling Smørgrav * @param rawsig_buf: raw signature buffer made ready.
22787b5038d7SDag-Erling Smørgrav * @param verify_buf: data for verification buffer made ready.
22797b5038d7SDag-Erling Smørgrav * @param rrset_clone: made ready.
22807b5038d7SDag-Erling Smørgrav * @param rrsig: signature to prepare for.
22817b5038d7SDag-Erling Smørgrav * @return LDNS_STATUS_OK is all went well. Otherwise specific error.
22827b5038d7SDag-Erling Smørgrav */
22837b5038d7SDag-Erling Smørgrav static ldns_status
ldns_prepare_for_verify(ldns_buffer * rawsig_buf,ldns_buffer * verify_buf,ldns_rr_list * rrset_clone,const ldns_rr * rrsig)22847b5038d7SDag-Erling Smørgrav ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
2285986ba33cSDag-Erling Smørgrav ldns_rr_list* rrset_clone, const ldns_rr* rrsig)
22867b5038d7SDag-Erling Smørgrav {
22877b5038d7SDag-Erling Smørgrav ldns_status result;
22887b5038d7SDag-Erling Smørgrav
22897b5038d7SDag-Erling Smørgrav /* canonicalize the sig */
22907b5038d7SDag-Erling Smørgrav ldns_dname2canonical(ldns_rr_owner(rrsig));
22917b5038d7SDag-Erling Smørgrav
22927b5038d7SDag-Erling Smørgrav /* check if the typecovered is equal to the type checked */
22937b5038d7SDag-Erling Smørgrav if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)) !=
22947b5038d7SDag-Erling Smørgrav ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0)))
22957b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR;
22967b5038d7SDag-Erling Smørgrav
22977b5038d7SDag-Erling Smørgrav /* create a buffer with b64 signature rdata */
22987b5038d7SDag-Erling Smørgrav result = ldns_rrsig2rawsig_buffer(rawsig_buf, rrsig);
22997b5038d7SDag-Erling Smørgrav if(result != LDNS_STATUS_OK)
23007b5038d7SDag-Erling Smørgrav return result;
23017b5038d7SDag-Erling Smørgrav
23027b5038d7SDag-Erling Smørgrav /* use TTL from signature. Use wildcard names for wildcards */
23037b5038d7SDag-Erling Smørgrav /* also canonicalizes rrset_clone */
23047b5038d7SDag-Erling Smørgrav ldns_rrset_use_signature_ttl(rrset_clone, rrsig);
23057b5038d7SDag-Erling Smørgrav
23067b5038d7SDag-Erling Smørgrav /* sort the rrset in canonical order */
23077b5038d7SDag-Erling Smørgrav ldns_rr_list_sort(rrset_clone);
23087b5038d7SDag-Erling Smørgrav
23097b5038d7SDag-Erling Smørgrav /* put the signature rr (without the b64) to the verify_buf */
23107b5038d7SDag-Erling Smørgrav if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK)
23117b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
23127b5038d7SDag-Erling Smørgrav
23137b5038d7SDag-Erling Smørgrav /* add the rrset in verify_buf */
23147b5038d7SDag-Erling Smørgrav if(ldns_rr_list2buffer_wire(verify_buf, rrset_clone)
23157b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK)
23167b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
23177b5038d7SDag-Erling Smørgrav
23187b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
23197b5038d7SDag-Erling Smørgrav }
23207b5038d7SDag-Erling Smørgrav
23217b5038d7SDag-Erling Smørgrav /**
23227b5038d7SDag-Erling Smørgrav * Check if a key matches a signature.
23237b5038d7SDag-Erling Smørgrav * Checks keytag, sigalgo and signature.
23247b5038d7SDag-Erling Smørgrav * @param rawsig_buf: raw signature buffer for verify
23257b5038d7SDag-Erling Smørgrav * @param verify_buf: raw data buffer for verify
23267b5038d7SDag-Erling Smørgrav * @param rrsig: the rrsig
23277b5038d7SDag-Erling Smørgrav * @param key: key to attempt.
23287b5038d7SDag-Erling Smørgrav * @return LDNS_STATUS_OK if OK, else some specific error.
23297b5038d7SDag-Erling Smørgrav */
23307b5038d7SDag-Erling Smørgrav static ldns_status
ldns_verify_test_sig_key(ldns_buffer * rawsig_buf,ldns_buffer * verify_buf,const ldns_rr * rrsig,ldns_rr * key)23317b5038d7SDag-Erling Smørgrav ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
2332986ba33cSDag-Erling Smørgrav const ldns_rr* rrsig, ldns_rr* key)
23337b5038d7SDag-Erling Smørgrav {
23347b5038d7SDag-Erling Smørgrav uint8_t sig_algo;
23357b5038d7SDag-Erling Smørgrav
23367b5038d7SDag-Erling Smørgrav if (rrsig == NULL) {
23377b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_NO_RRSIG;
23387b5038d7SDag-Erling Smørgrav }
23397b5038d7SDag-Erling Smørgrav if (ldns_rr_rdf(rrsig, 1) == NULL) {
23407b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
23417b5038d7SDag-Erling Smørgrav }
23427b5038d7SDag-Erling Smørgrav sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
23437b5038d7SDag-Erling Smørgrav
23447b5038d7SDag-Erling Smørgrav /* before anything, check if the keytags match */
23457b5038d7SDag-Erling Smørgrav if (ldns_calc_keytag(key)
23467b5038d7SDag-Erling Smørgrav ==
23477b5038d7SDag-Erling Smørgrav ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
23487b5038d7SDag-Erling Smørgrav ) {
23497b5038d7SDag-Erling Smørgrav ldns_buffer* key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
23507b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_ERR;
23517b5038d7SDag-Erling Smørgrav
23527b5038d7SDag-Erling Smørgrav /* put the key-data in a buffer, that's the third rdf, with
23537b5038d7SDag-Erling Smørgrav * the base64 encoded key data */
23547b5038d7SDag-Erling Smørgrav if (ldns_rr_rdf(key, 3) == NULL) {
23557b5038d7SDag-Erling Smørgrav ldns_buffer_free(key_buf);
23567b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
23577b5038d7SDag-Erling Smørgrav }
23587b5038d7SDag-Erling Smørgrav if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3))
23597b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) {
23607b5038d7SDag-Erling Smørgrav ldns_buffer_free(key_buf);
23617b5038d7SDag-Erling Smørgrav /* returning is bad might screw up
23627b5038d7SDag-Erling Smørgrav good keys later in the list
23637b5038d7SDag-Erling Smørgrav what to do? */
23647b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
23657b5038d7SDag-Erling Smørgrav }
23667b5038d7SDag-Erling Smørgrav
23677b5038d7SDag-Erling Smørgrav if (ldns_rr_rdf(key, 2) == NULL) {
23687b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
23697b5038d7SDag-Erling Smørgrav }
23707b5038d7SDag-Erling Smørgrav else if (sig_algo == ldns_rdf2native_int8(
23717b5038d7SDag-Erling Smørgrav ldns_rr_rdf(key, 2))) {
23727b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_buffers(rawsig_buf,
23737b5038d7SDag-Erling Smørgrav verify_buf, key_buf, sig_algo);
23747b5038d7SDag-Erling Smørgrav } else {
23757b5038d7SDag-Erling Smørgrav /* No keys with the corresponding algorithm are found */
23767b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
23777b5038d7SDag-Erling Smørgrav }
23787b5038d7SDag-Erling Smørgrav
23797b5038d7SDag-Erling Smørgrav ldns_buffer_free(key_buf);
23807b5038d7SDag-Erling Smørgrav return result;
23817b5038d7SDag-Erling Smørgrav }
23827b5038d7SDag-Erling Smørgrav else {
23837b5038d7SDag-Erling Smørgrav /* No keys with the corresponding keytag are found */
23847b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
23857b5038d7SDag-Erling Smørgrav }
23867b5038d7SDag-Erling Smørgrav }
23877b5038d7SDag-Erling Smørgrav
23887b5038d7SDag-Erling Smørgrav /*
23897b5038d7SDag-Erling Smørgrav * to verify:
23907b5038d7SDag-Erling Smørgrav * - create the wire fmt of the b64 key rdata
23917b5038d7SDag-Erling Smørgrav * - create the wire fmt of the sorted rrset
23927b5038d7SDag-Erling Smørgrav * - create the wire fmt of the b64 sig rdata
23937b5038d7SDag-Erling Smørgrav * - create the wire fmt of the sig without the b64 rdata
23947b5038d7SDag-Erling Smørgrav * - cat the sig data (without b64 rdata) to the rrset
23957b5038d7SDag-Erling Smørgrav * - verify the rrset+sig, with the b64 data and the b64 key data
23967b5038d7SDag-Erling Smørgrav */
23977b5038d7SDag-Erling Smørgrav ldns_status
ldns_verify_rrsig_keylist_time(const ldns_rr_list * rrset,const ldns_rr * rrsig,const ldns_rr_list * keys,time_t check_time,ldns_rr_list * good_keys)23987b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_keylist_time(
2399986ba33cSDag-Erling Smørgrav const ldns_rr_list *rrset,
2400986ba33cSDag-Erling Smørgrav const ldns_rr *rrsig,
24017b5038d7SDag-Erling Smørgrav const ldns_rr_list *keys,
24027b5038d7SDag-Erling Smørgrav time_t check_time,
24037b5038d7SDag-Erling Smørgrav ldns_rr_list *good_keys)
24047b5038d7SDag-Erling Smørgrav {
24057b5038d7SDag-Erling Smørgrav ldns_status result;
2406*5afab0e5SDag-Erling Smørgrav ldns_rr_list *valid;
2407*5afab0e5SDag-Erling Smørgrav
2408*5afab0e5SDag-Erling Smørgrav if (!good_keys)
2409*5afab0e5SDag-Erling Smørgrav valid = NULL;
2410*5afab0e5SDag-Erling Smørgrav
2411*5afab0e5SDag-Erling Smørgrav else if (!(valid = ldns_rr_list_new()))
24127b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
24137b5038d7SDag-Erling Smørgrav
24147b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, valid);
24157b5038d7SDag-Erling Smørgrav if(result != LDNS_STATUS_OK) {
24167b5038d7SDag-Erling Smørgrav ldns_rr_list_free(valid);
24177b5038d7SDag-Erling Smørgrav return result;
24187b5038d7SDag-Erling Smørgrav }
24197b5038d7SDag-Erling Smørgrav
24207b5038d7SDag-Erling Smørgrav /* check timestamps last; its OK except time */
24217b5038d7SDag-Erling Smørgrav result = ldns_rrsig_check_timestamps(rrsig, check_time);
24227b5038d7SDag-Erling Smørgrav if(result != LDNS_STATUS_OK) {
24237b5038d7SDag-Erling Smørgrav ldns_rr_list_free(valid);
24247b5038d7SDag-Erling Smørgrav return result;
24257b5038d7SDag-Erling Smørgrav }
24267b5038d7SDag-Erling Smørgrav
24277b5038d7SDag-Erling Smørgrav ldns_rr_list_cat(good_keys, valid);
24287b5038d7SDag-Erling Smørgrav ldns_rr_list_free(valid);
24297b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
24307b5038d7SDag-Erling Smørgrav }
24317b5038d7SDag-Erling Smørgrav
24327b5038d7SDag-Erling Smørgrav /*
24337b5038d7SDag-Erling Smørgrav * to verify:
24347b5038d7SDag-Erling Smørgrav * - create the wire fmt of the b64 key rdata
24357b5038d7SDag-Erling Smørgrav * - create the wire fmt of the sorted rrset
24367b5038d7SDag-Erling Smørgrav * - create the wire fmt of the b64 sig rdata
24377b5038d7SDag-Erling Smørgrav * - create the wire fmt of the sig without the b64 rdata
24387b5038d7SDag-Erling Smørgrav * - cat the sig data (without b64 rdata) to the rrset
24397b5038d7SDag-Erling Smørgrav * - verify the rrset+sig, with the b64 data and the b64 key data
24407b5038d7SDag-Erling Smørgrav */
24417b5038d7SDag-Erling Smørgrav ldns_status
ldns_verify_rrsig_keylist(ldns_rr_list * rrset,ldns_rr * rrsig,const ldns_rr_list * keys,ldns_rr_list * good_keys)24427b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
24437b5038d7SDag-Erling Smørgrav ldns_rr *rrsig,
24447b5038d7SDag-Erling Smørgrav const ldns_rr_list *keys,
24457b5038d7SDag-Erling Smørgrav ldns_rr_list *good_keys)
24467b5038d7SDag-Erling Smørgrav {
24477b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_keylist_time(
24487b5038d7SDag-Erling Smørgrav rrset, rrsig, keys, ldns_time(NULL), good_keys);
24497b5038d7SDag-Erling Smørgrav }
24507b5038d7SDag-Erling Smørgrav
24517b5038d7SDag-Erling Smørgrav ldns_status
ldns_verify_rrsig_keylist_notime(const ldns_rr_list * rrset,const ldns_rr * rrsig,const ldns_rr_list * keys,ldns_rr_list * good_keys)2452986ba33cSDag-Erling Smørgrav ldns_verify_rrsig_keylist_notime(const ldns_rr_list *rrset,
2453986ba33cSDag-Erling Smørgrav const ldns_rr *rrsig,
24547b5038d7SDag-Erling Smørgrav const ldns_rr_list *keys,
24557b5038d7SDag-Erling Smørgrav ldns_rr_list *good_keys)
24567b5038d7SDag-Erling Smørgrav {
24577b5038d7SDag-Erling Smørgrav ldns_buffer *rawsig_buf;
24587b5038d7SDag-Erling Smørgrav ldns_buffer *verify_buf;
24597b5038d7SDag-Erling Smørgrav uint16_t i;
24607b5038d7SDag-Erling Smørgrav ldns_status result, status;
24617b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset_clone;
24627b5038d7SDag-Erling Smørgrav ldns_rr_list *validkeys;
24637b5038d7SDag-Erling Smørgrav
24647b5038d7SDag-Erling Smørgrav if (!rrset) {
24657b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
24667b5038d7SDag-Erling Smørgrav }
24677b5038d7SDag-Erling Smørgrav
24687b5038d7SDag-Erling Smørgrav validkeys = ldns_rr_list_new();
24697b5038d7SDag-Erling Smørgrav if (!validkeys) {
24707b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
24717b5038d7SDag-Erling Smørgrav }
24727b5038d7SDag-Erling Smørgrav
24737b5038d7SDag-Erling Smørgrav /* clone the rrset so that we can fiddle with it */
24747b5038d7SDag-Erling Smørgrav rrset_clone = ldns_rr_list_clone(rrset);
24757b5038d7SDag-Erling Smørgrav
24767b5038d7SDag-Erling Smørgrav /* create the buffers which will certainly hold the raw data */
24777b5038d7SDag-Erling Smørgrav rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
24787b5038d7SDag-Erling Smørgrav verify_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
24797b5038d7SDag-Erling Smørgrav
24807b5038d7SDag-Erling Smørgrav result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
24817b5038d7SDag-Erling Smørgrav rrset_clone, rrsig);
24827b5038d7SDag-Erling Smørgrav if(result != LDNS_STATUS_OK) {
24837b5038d7SDag-Erling Smørgrav ldns_buffer_free(verify_buf);
24847b5038d7SDag-Erling Smørgrav ldns_buffer_free(rawsig_buf);
24857b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone);
24867b5038d7SDag-Erling Smørgrav ldns_rr_list_free(validkeys);
24877b5038d7SDag-Erling Smørgrav return result;
24887b5038d7SDag-Erling Smørgrav }
24897b5038d7SDag-Erling Smørgrav
24907b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
24917b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(keys); i++) {
24927b5038d7SDag-Erling Smørgrav status = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
24937b5038d7SDag-Erling Smørgrav rrsig, ldns_rr_list_rr(keys, i));
24947b5038d7SDag-Erling Smørgrav if (status == LDNS_STATUS_OK) {
24957b5038d7SDag-Erling Smørgrav /* one of the keys has matched, don't break
24967b5038d7SDag-Erling Smørgrav * here, instead put the 'winning' key in
24977b5038d7SDag-Erling Smørgrav * the validkey list and return the list
24987b5038d7SDag-Erling Smørgrav * later */
24997b5038d7SDag-Erling Smørgrav if (!ldns_rr_list_push_rr(validkeys,
25007b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(keys,i))) {
25017b5038d7SDag-Erling Smørgrav /* couldn't push the key?? */
25027b5038d7SDag-Erling Smørgrav ldns_buffer_free(rawsig_buf);
25037b5038d7SDag-Erling Smørgrav ldns_buffer_free(verify_buf);
25047b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone);
25057b5038d7SDag-Erling Smørgrav ldns_rr_list_free(validkeys);
25067b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
25077b5038d7SDag-Erling Smørgrav }
25087b5038d7SDag-Erling Smørgrav
25097b5038d7SDag-Erling Smørgrav result = status;
25107b5038d7SDag-Erling Smørgrav }
25117b5038d7SDag-Erling Smørgrav
25127b5038d7SDag-Erling Smørgrav if (result == LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
25137b5038d7SDag-Erling Smørgrav result = status;
25147b5038d7SDag-Erling Smørgrav }
25157b5038d7SDag-Erling Smørgrav }
25167b5038d7SDag-Erling Smørgrav
25177b5038d7SDag-Erling Smørgrav /* no longer needed */
25187b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone);
25197b5038d7SDag-Erling Smørgrav ldns_buffer_free(rawsig_buf);
25207b5038d7SDag-Erling Smørgrav ldns_buffer_free(verify_buf);
25217b5038d7SDag-Erling Smørgrav
25227b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(validkeys) == 0) {
25237b5038d7SDag-Erling Smørgrav /* no keys were added, return last error */
25247b5038d7SDag-Erling Smørgrav ldns_rr_list_free(validkeys);
25257b5038d7SDag-Erling Smørgrav return result;
25267b5038d7SDag-Erling Smørgrav }
25277b5038d7SDag-Erling Smørgrav
25287b5038d7SDag-Erling Smørgrav /* do not check timestamps */
25297b5038d7SDag-Erling Smørgrav
25307b5038d7SDag-Erling Smørgrav ldns_rr_list_cat(good_keys, validkeys);
25317b5038d7SDag-Erling Smørgrav ldns_rr_list_free(validkeys);
25327b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
25337b5038d7SDag-Erling Smørgrav }
25347b5038d7SDag-Erling Smørgrav
25357b5038d7SDag-Erling Smørgrav ldns_status
ldns_verify_rrsig_time(ldns_rr_list * rrset,ldns_rr * rrsig,ldns_rr * key,time_t check_time)25367b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_time(
25377b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset,
25387b5038d7SDag-Erling Smørgrav ldns_rr *rrsig,
25397b5038d7SDag-Erling Smørgrav ldns_rr *key,
25407b5038d7SDag-Erling Smørgrav time_t check_time)
25417b5038d7SDag-Erling Smørgrav {
25427b5038d7SDag-Erling Smørgrav ldns_buffer *rawsig_buf;
25437b5038d7SDag-Erling Smørgrav ldns_buffer *verify_buf;
25447b5038d7SDag-Erling Smørgrav ldns_status result;
25457b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset_clone;
25467b5038d7SDag-Erling Smørgrav
25477b5038d7SDag-Erling Smørgrav if (!rrset) {
25487b5038d7SDag-Erling Smørgrav return LDNS_STATUS_NO_DATA;
25497b5038d7SDag-Erling Smørgrav }
25507b5038d7SDag-Erling Smørgrav /* clone the rrset so that we can fiddle with it */
25517b5038d7SDag-Erling Smørgrav rrset_clone = ldns_rr_list_clone(rrset);
25527b5038d7SDag-Erling Smørgrav /* create the buffers which will certainly hold the raw data */
25537b5038d7SDag-Erling Smørgrav rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
25547b5038d7SDag-Erling Smørgrav verify_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
25557b5038d7SDag-Erling Smørgrav
25567b5038d7SDag-Erling Smørgrav result = ldns_prepare_for_verify(rawsig_buf, verify_buf,
25577b5038d7SDag-Erling Smørgrav rrset_clone, rrsig);
25587b5038d7SDag-Erling Smørgrav if(result != LDNS_STATUS_OK) {
25597b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone);
25607b5038d7SDag-Erling Smørgrav ldns_buffer_free(rawsig_buf);
25617b5038d7SDag-Erling Smørgrav ldns_buffer_free(verify_buf);
25627b5038d7SDag-Erling Smørgrav return result;
25637b5038d7SDag-Erling Smørgrav }
25647b5038d7SDag-Erling Smørgrav result = ldns_verify_test_sig_key(rawsig_buf, verify_buf,
25657b5038d7SDag-Erling Smørgrav rrsig, key);
25667b5038d7SDag-Erling Smørgrav /* no longer needed */
25677b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone);
25687b5038d7SDag-Erling Smørgrav ldns_buffer_free(rawsig_buf);
25697b5038d7SDag-Erling Smørgrav ldns_buffer_free(verify_buf);
25707b5038d7SDag-Erling Smørgrav
25717b5038d7SDag-Erling Smørgrav /* check timestamp last, apart from time its OK */
25727b5038d7SDag-Erling Smørgrav if(result == LDNS_STATUS_OK)
25737b5038d7SDag-Erling Smørgrav result = ldns_rrsig_check_timestamps(rrsig, check_time);
25747b5038d7SDag-Erling Smørgrav
25757b5038d7SDag-Erling Smørgrav return result;
25767b5038d7SDag-Erling Smørgrav }
25777b5038d7SDag-Erling Smørgrav
25787b5038d7SDag-Erling Smørgrav ldns_status
ldns_verify_rrsig(ldns_rr_list * rrset,ldns_rr * rrsig,ldns_rr * key)25797b5038d7SDag-Erling Smørgrav ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
25807b5038d7SDag-Erling Smørgrav {
25817b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_time(rrset, rrsig, key, ldns_time(NULL));
25827b5038d7SDag-Erling Smørgrav }
25837b5038d7SDag-Erling Smørgrav
25847b5038d7SDag-Erling Smørgrav
25857b5038d7SDag-Erling Smørgrav ldns_status
ldns_verify_rrsig_evp(ldns_buffer * sig,ldns_buffer * rrset,EVP_PKEY * key,const EVP_MD * digest_type)25867b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_evp(ldns_buffer *sig,
25877b5038d7SDag-Erling Smørgrav ldns_buffer *rrset,
25887b5038d7SDag-Erling Smørgrav EVP_PKEY *key,
25897b5038d7SDag-Erling Smørgrav const EVP_MD *digest_type)
25907b5038d7SDag-Erling Smørgrav {
25917b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_evp_raw(
25927b5038d7SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(sig),
25937b5038d7SDag-Erling Smørgrav ldns_buffer_position(sig),
25947b5038d7SDag-Erling Smørgrav rrset,
25957b5038d7SDag-Erling Smørgrav key,
25967b5038d7SDag-Erling Smørgrav digest_type);
25977b5038d7SDag-Erling Smørgrav }
25987b5038d7SDag-Erling Smørgrav
25997b5038d7SDag-Erling Smørgrav ldns_status
ldns_verify_rrsig_evp_raw(const unsigned char * sig,size_t siglen,const ldns_buffer * rrset,EVP_PKEY * key,const EVP_MD * digest_type)2600986ba33cSDag-Erling Smørgrav ldns_verify_rrsig_evp_raw(const unsigned char *sig, size_t siglen,
2601986ba33cSDag-Erling Smørgrav const ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
26027b5038d7SDag-Erling Smørgrav {
2603986ba33cSDag-Erling Smørgrav EVP_MD_CTX *ctx;
26047b5038d7SDag-Erling Smørgrav int res;
26057b5038d7SDag-Erling Smørgrav
2606986ba33cSDag-Erling Smørgrav #ifdef HAVE_EVP_MD_CTX_NEW
2607986ba33cSDag-Erling Smørgrav ctx = EVP_MD_CTX_new();
2608986ba33cSDag-Erling Smørgrav #else
2609986ba33cSDag-Erling Smørgrav ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx));
2610986ba33cSDag-Erling Smørgrav if(ctx) EVP_MD_CTX_init(ctx);
2611986ba33cSDag-Erling Smørgrav #endif
2612986ba33cSDag-Erling Smørgrav if(!ctx)
2613986ba33cSDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
26147b5038d7SDag-Erling Smørgrav
2615*5afab0e5SDag-Erling Smørgrav #if defined(USE_ED25519) || defined(USE_ED448)
2616*5afab0e5SDag-Erling Smørgrav if(!digest_type) {
2617*5afab0e5SDag-Erling Smørgrav res = EVP_DigestVerifyInit(ctx, NULL, digest_type, NULL, key);
2618*5afab0e5SDag-Erling Smørgrav if(res == 1) {
2619*5afab0e5SDag-Erling Smørgrav res = EVP_DigestVerify(ctx, sig, siglen,
2620*5afab0e5SDag-Erling Smørgrav ldns_buffer_begin(rrset),
2621*5afab0e5SDag-Erling Smørgrav ldns_buffer_position(rrset));
2622*5afab0e5SDag-Erling Smørgrav }
2623*5afab0e5SDag-Erling Smørgrav } else {
2624*5afab0e5SDag-Erling Smørgrav #else
2625*5afab0e5SDag-Erling Smørgrav res = 0;
2626*5afab0e5SDag-Erling Smørgrav if(digest_type) {
2627*5afab0e5SDag-Erling Smørgrav #endif
2628986ba33cSDag-Erling Smørgrav EVP_VerifyInit(ctx, digest_type);
2629986ba33cSDag-Erling Smørgrav EVP_VerifyUpdate(ctx,
26307b5038d7SDag-Erling Smørgrav ldns_buffer_begin(rrset),
26317b5038d7SDag-Erling Smørgrav ldns_buffer_position(rrset));
2632986ba33cSDag-Erling Smørgrav res = EVP_VerifyFinal(ctx, sig, (unsigned int) siglen, key);
2633*5afab0e5SDag-Erling Smørgrav }
26347b5038d7SDag-Erling Smørgrav
2635986ba33cSDag-Erling Smørgrav EVP_MD_CTX_destroy(ctx);
26367b5038d7SDag-Erling Smørgrav
26377b5038d7SDag-Erling Smørgrav if (res == 1) {
26387b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
2639*5afab0e5SDag-Erling Smørgrav
26407b5038d7SDag-Erling Smørgrav } else if (res == 0) {
26417b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_BOGUS;
26427b5038d7SDag-Erling Smørgrav }
26437b5038d7SDag-Erling Smørgrav /* TODO how to communicate internal SSL error?
26447b5038d7SDag-Erling Smørgrav let caller use ssl's get_error() */
26457b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SSL_ERR;
26467b5038d7SDag-Erling Smørgrav }
26477b5038d7SDag-Erling Smørgrav
26487b5038d7SDag-Erling Smørgrav ldns_status
26497b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
26507b5038d7SDag-Erling Smørgrav {
26517b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_dsa_raw(
26527b5038d7SDag-Erling Smørgrav (unsigned char*) ldns_buffer_begin(sig),
26537b5038d7SDag-Erling Smørgrav ldns_buffer_position(sig),
26547b5038d7SDag-Erling Smørgrav rrset,
26557b5038d7SDag-Erling Smørgrav (unsigned char*) ldns_buffer_begin(key),
26567b5038d7SDag-Erling Smørgrav ldns_buffer_position(key));
26577b5038d7SDag-Erling Smørgrav }
26587b5038d7SDag-Erling Smørgrav
26597b5038d7SDag-Erling Smørgrav ldns_status
26607b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
26617b5038d7SDag-Erling Smørgrav {
26627b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_rsasha1_raw(
26637b5038d7SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(sig),
26647b5038d7SDag-Erling Smørgrav ldns_buffer_position(sig),
26657b5038d7SDag-Erling Smørgrav rrset,
26667b5038d7SDag-Erling Smørgrav (unsigned char*) ldns_buffer_begin(key),
26677b5038d7SDag-Erling Smørgrav ldns_buffer_position(key));
26687b5038d7SDag-Erling Smørgrav }
26697b5038d7SDag-Erling Smørgrav
26707b5038d7SDag-Erling Smørgrav ldns_status
26717b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
26727b5038d7SDag-Erling Smørgrav {
26737b5038d7SDag-Erling Smørgrav return ldns_verify_rrsig_rsamd5_raw(
26747b5038d7SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(sig),
26757b5038d7SDag-Erling Smørgrav ldns_buffer_position(sig),
26767b5038d7SDag-Erling Smørgrav rrset,
26777b5038d7SDag-Erling Smørgrav (unsigned char*) ldns_buffer_begin(key),
26787b5038d7SDag-Erling Smørgrav ldns_buffer_position(key));
26797b5038d7SDag-Erling Smørgrav }
26807b5038d7SDag-Erling Smørgrav
26817b5038d7SDag-Erling Smørgrav ldns_status
26827b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
26837b5038d7SDag-Erling Smørgrav ldns_buffer* rrset, unsigned char* key, size_t keylen)
26847b5038d7SDag-Erling Smørgrav {
2685986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
26867b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key;
26877b5038d7SDag-Erling Smørgrav ldns_status result;
26887b5038d7SDag-Erling Smørgrav
26897b5038d7SDag-Erling Smørgrav evp_key = EVP_PKEY_new();
26907b5038d7SDag-Erling Smørgrav if (EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen))) {
26917b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig,
26927b5038d7SDag-Erling Smørgrav siglen,
26937b5038d7SDag-Erling Smørgrav rrset,
26947b5038d7SDag-Erling Smørgrav evp_key,
2695986ba33cSDag-Erling Smørgrav # ifdef HAVE_EVP_DSS1
2696986ba33cSDag-Erling Smørgrav EVP_dss1()
2697986ba33cSDag-Erling Smørgrav # else
2698986ba33cSDag-Erling Smørgrav EVP_sha1()
2699986ba33cSDag-Erling Smørgrav # endif
2700986ba33cSDag-Erling Smørgrav );
27017b5038d7SDag-Erling Smørgrav } else {
27027b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_SSL_ERR;
27037b5038d7SDag-Erling Smørgrav }
27047b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key);
27057b5038d7SDag-Erling Smørgrav return result;
2706986ba33cSDag-Erling Smørgrav #else
2707986ba33cSDag-Erling Smørgrav (void)sig; (void)siglen; (void)rrset; (void)key; (void)keylen;
2708986ba33cSDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
2709986ba33cSDag-Erling Smørgrav #endif
27107b5038d7SDag-Erling Smørgrav }
27117b5038d7SDag-Erling Smørgrav
27127b5038d7SDag-Erling Smørgrav ldns_status
27137b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen,
27147b5038d7SDag-Erling Smørgrav ldns_buffer* rrset, unsigned char* key, size_t keylen)
27157b5038d7SDag-Erling Smørgrav {
27167b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key;
27177b5038d7SDag-Erling Smørgrav ldns_status result;
27187b5038d7SDag-Erling Smørgrav
27197b5038d7SDag-Erling Smørgrav evp_key = EVP_PKEY_new();
27207b5038d7SDag-Erling Smørgrav if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
27217b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig,
27227b5038d7SDag-Erling Smørgrav siglen,
27237b5038d7SDag-Erling Smørgrav rrset,
27247b5038d7SDag-Erling Smørgrav evp_key,
27257b5038d7SDag-Erling Smørgrav EVP_sha1());
27267b5038d7SDag-Erling Smørgrav } else {
27277b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_SSL_ERR;
27287b5038d7SDag-Erling Smørgrav }
27297b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key);
27307b5038d7SDag-Erling Smørgrav
27317b5038d7SDag-Erling Smørgrav return result;
27327b5038d7SDag-Erling Smørgrav }
27337b5038d7SDag-Erling Smørgrav
27347b5038d7SDag-Erling Smørgrav ldns_status
27357b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
27367b5038d7SDag-Erling Smørgrav size_t siglen,
27377b5038d7SDag-Erling Smørgrav ldns_buffer* rrset,
27387b5038d7SDag-Erling Smørgrav unsigned char* key,
27397b5038d7SDag-Erling Smørgrav size_t keylen)
27407b5038d7SDag-Erling Smørgrav {
27417b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2
27427b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key;
27437b5038d7SDag-Erling Smørgrav ldns_status result;
27447b5038d7SDag-Erling Smørgrav
27457b5038d7SDag-Erling Smørgrav evp_key = EVP_PKEY_new();
27467b5038d7SDag-Erling Smørgrav if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
27477b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig,
27487b5038d7SDag-Erling Smørgrav siglen,
27497b5038d7SDag-Erling Smørgrav rrset,
27507b5038d7SDag-Erling Smørgrav evp_key,
27517b5038d7SDag-Erling Smørgrav EVP_sha256());
27527b5038d7SDag-Erling Smørgrav } else {
27537b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_SSL_ERR;
27547b5038d7SDag-Erling Smørgrav }
27557b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key);
27567b5038d7SDag-Erling Smørgrav
27577b5038d7SDag-Erling Smørgrav return result;
27587b5038d7SDag-Erling Smørgrav #else
27597b5038d7SDag-Erling Smørgrav /* touch these to prevent compiler warnings */
27607b5038d7SDag-Erling Smørgrav (void) sig;
27617b5038d7SDag-Erling Smørgrav (void) siglen;
27627b5038d7SDag-Erling Smørgrav (void) rrset;
27637b5038d7SDag-Erling Smørgrav (void) key;
27647b5038d7SDag-Erling Smørgrav (void) keylen;
27657b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
27667b5038d7SDag-Erling Smørgrav #endif
27677b5038d7SDag-Erling Smørgrav }
27687b5038d7SDag-Erling Smørgrav
27697b5038d7SDag-Erling Smørgrav ldns_status
27707b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
27717b5038d7SDag-Erling Smørgrav size_t siglen,
27727b5038d7SDag-Erling Smørgrav ldns_buffer* rrset,
27737b5038d7SDag-Erling Smørgrav unsigned char* key,
27747b5038d7SDag-Erling Smørgrav size_t keylen)
27757b5038d7SDag-Erling Smørgrav {
27767b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2
27777b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key;
27787b5038d7SDag-Erling Smørgrav ldns_status result;
27797b5038d7SDag-Erling Smørgrav
27807b5038d7SDag-Erling Smørgrav evp_key = EVP_PKEY_new();
27817b5038d7SDag-Erling Smørgrav if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
27827b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig,
27837b5038d7SDag-Erling Smørgrav siglen,
27847b5038d7SDag-Erling Smørgrav rrset,
27857b5038d7SDag-Erling Smørgrav evp_key,
27867b5038d7SDag-Erling Smørgrav EVP_sha512());
27877b5038d7SDag-Erling Smørgrav } else {
27887b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_SSL_ERR;
27897b5038d7SDag-Erling Smørgrav }
27907b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key);
27917b5038d7SDag-Erling Smørgrav
27927b5038d7SDag-Erling Smørgrav return result;
27937b5038d7SDag-Erling Smørgrav #else
27947b5038d7SDag-Erling Smørgrav /* touch these to prevent compiler warnings */
27957b5038d7SDag-Erling Smørgrav (void) sig;
27967b5038d7SDag-Erling Smørgrav (void) siglen;
27977b5038d7SDag-Erling Smørgrav (void) rrset;
27987b5038d7SDag-Erling Smørgrav (void) key;
27997b5038d7SDag-Erling Smørgrav (void) keylen;
28007b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
28017b5038d7SDag-Erling Smørgrav #endif
28027b5038d7SDag-Erling Smørgrav }
28037b5038d7SDag-Erling Smørgrav
28047b5038d7SDag-Erling Smørgrav
28057b5038d7SDag-Erling Smørgrav ldns_status
28067b5038d7SDag-Erling Smørgrav ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
28077b5038d7SDag-Erling Smørgrav size_t siglen,
28087b5038d7SDag-Erling Smørgrav ldns_buffer* rrset,
28097b5038d7SDag-Erling Smørgrav unsigned char* key,
28107b5038d7SDag-Erling Smørgrav size_t keylen)
28117b5038d7SDag-Erling Smørgrav {
28127b5038d7SDag-Erling Smørgrav EVP_PKEY *evp_key;
28137b5038d7SDag-Erling Smørgrav ldns_status result;
28147b5038d7SDag-Erling Smørgrav
28157b5038d7SDag-Erling Smørgrav evp_key = EVP_PKEY_new();
28167b5038d7SDag-Erling Smørgrav if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
28177b5038d7SDag-Erling Smørgrav result = ldns_verify_rrsig_evp_raw(sig,
28187b5038d7SDag-Erling Smørgrav siglen,
28197b5038d7SDag-Erling Smørgrav rrset,
28207b5038d7SDag-Erling Smørgrav evp_key,
28217b5038d7SDag-Erling Smørgrav EVP_md5());
28227b5038d7SDag-Erling Smørgrav } else {
28237b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_SSL_ERR;
28247b5038d7SDag-Erling Smørgrav }
28257b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key);
28267b5038d7SDag-Erling Smørgrav
28277b5038d7SDag-Erling Smørgrav return result;
28287b5038d7SDag-Erling Smørgrav }
28297b5038d7SDag-Erling Smørgrav
28307b5038d7SDag-Erling Smørgrav #endif
2831