17b5038d7SDag-Erling Smørgrav /*
27b5038d7SDag-Erling Smørgrav * dnssec.c
37b5038d7SDag-Erling Smørgrav * Some DNSSEC helper function are defined here
47b5038d7SDag-Erling Smørgrav * and tracing is done
57b5038d7SDag-Erling Smørgrav * (c) 2005 NLnet Labs
67b5038d7SDag-Erling Smørgrav *
77b5038d7SDag-Erling Smørgrav * See the file LICENSE for the license
87b5038d7SDag-Erling Smørgrav *
97b5038d7SDag-Erling Smørgrav */
107b5038d7SDag-Erling Smørgrav
117b5038d7SDag-Erling Smørgrav #include "drill.h"
127b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h>
137b5038d7SDag-Erling Smørgrav
147b5038d7SDag-Erling Smørgrav /* get rr_type from a server from a server */
157b5038d7SDag-Erling Smørgrav ldns_rr_list *
get_rr(ldns_resolver * res,ldns_rdf * zname,ldns_rr_type t,ldns_rr_class c)167b5038d7SDag-Erling Smørgrav get_rr(ldns_resolver *res, ldns_rdf *zname, ldns_rr_type t, ldns_rr_class c)
177b5038d7SDag-Erling Smørgrav {
187b5038d7SDag-Erling Smørgrav /* query, retrieve, extract and return */
197b5038d7SDag-Erling Smørgrav ldns_pkt *p;
207b5038d7SDag-Erling Smørgrav ldns_rr_list *found;
217b5038d7SDag-Erling Smørgrav
227b5038d7SDag-Erling Smørgrav p = ldns_pkt_new();
237b5038d7SDag-Erling Smørgrav found = NULL;
247b5038d7SDag-Erling Smørgrav
252787e39aSDag-Erling Smørgrav if (ldns_resolver_send(&p, res, zname, t, c, 0) == LDNS_STATUS_OK) {
267b5038d7SDag-Erling Smørgrav found = ldns_pkt_rr_list_by_type(p, t, LDNS_SECTION_ANY_NOQUESTION);
277b5038d7SDag-Erling Smørgrav }
282787e39aSDag-Erling Smørgrav ldns_pkt_free(p);
297b5038d7SDag-Erling Smørgrav return found;
307b5038d7SDag-Erling Smørgrav }
317b5038d7SDag-Erling Smørgrav
327b5038d7SDag-Erling Smørgrav void
drill_pkt_print(FILE * fd,ldns_resolver * r,ldns_pkt * p)337b5038d7SDag-Erling Smørgrav drill_pkt_print(FILE *fd, ldns_resolver *r, ldns_pkt *p)
347b5038d7SDag-Erling Smørgrav {
357b5038d7SDag-Erling Smørgrav ldns_rr_list *new_nss;
367b5038d7SDag-Erling Smørgrav ldns_rr_list *hostnames;
372787e39aSDag-Erling Smørgrav char *answerfrom_str;
387b5038d7SDag-Erling Smørgrav
397b5038d7SDag-Erling Smørgrav if (verbosity < 5) {
407b5038d7SDag-Erling Smørgrav return;
417b5038d7SDag-Erling Smørgrav }
427b5038d7SDag-Erling Smørgrav
437b5038d7SDag-Erling Smørgrav hostnames = ldns_get_rr_list_name_by_addr(r, ldns_pkt_answerfrom(p), 0, 0);
447b5038d7SDag-Erling Smørgrav
457b5038d7SDag-Erling Smørgrav new_nss = ldns_pkt_rr_list_by_type(p,
467b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NS, LDNS_SECTION_ANSWER);
477b5038d7SDag-Erling Smørgrav ldns_rr_list_print(fd, new_nss);
482787e39aSDag-Erling Smørgrav ldns_rr_list_deep_free(new_nss);
497b5038d7SDag-Erling Smørgrav
507b5038d7SDag-Erling Smørgrav fprintf(fd, ";; Received %d bytes from %s#%d(",
517b5038d7SDag-Erling Smørgrav (int) ldns_pkt_size(p),
527b5038d7SDag-Erling Smørgrav ldns_rdf2str(ldns_pkt_answerfrom(p)),
537b5038d7SDag-Erling Smørgrav (int) ldns_resolver_port(r));
547b5038d7SDag-Erling Smørgrav /* if we can resolve this print it, other print the ip again */
557b5038d7SDag-Erling Smørgrav if (hostnames) {
567b5038d7SDag-Erling Smørgrav ldns_rdf_print(fd,
577b5038d7SDag-Erling Smørgrav ldns_rr_rdf(ldns_rr_list_rr(hostnames, 0), 0));
587b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(hostnames);
597b5038d7SDag-Erling Smørgrav } else {
602787e39aSDag-Erling Smørgrav answerfrom_str = ldns_rdf2str(ldns_pkt_answerfrom(p));
612787e39aSDag-Erling Smørgrav if (answerfrom_str) {
622787e39aSDag-Erling Smørgrav fprintf(fd, "%s", answerfrom_str);
632787e39aSDag-Erling Smørgrav LDNS_FREE(answerfrom_str);
642787e39aSDag-Erling Smørgrav }
657b5038d7SDag-Erling Smørgrav }
667b5038d7SDag-Erling Smørgrav fprintf(fd, ") in %u ms\n\n", (unsigned int)ldns_pkt_querytime(p));
677b5038d7SDag-Erling Smørgrav }
687b5038d7SDag-Erling Smørgrav
697b5038d7SDag-Erling Smørgrav void
drill_pkt_print_footer(FILE * fd,ldns_resolver * r,ldns_pkt * p)707b5038d7SDag-Erling Smørgrav drill_pkt_print_footer(FILE *fd, ldns_resolver *r, ldns_pkt *p)
717b5038d7SDag-Erling Smørgrav {
727b5038d7SDag-Erling Smørgrav ldns_rr_list *hostnames;
732787e39aSDag-Erling Smørgrav char *answerfrom_str;
747b5038d7SDag-Erling Smørgrav
757b5038d7SDag-Erling Smørgrav if (verbosity < 5) {
767b5038d7SDag-Erling Smørgrav return;
777b5038d7SDag-Erling Smørgrav }
787b5038d7SDag-Erling Smørgrav
797b5038d7SDag-Erling Smørgrav hostnames = ldns_get_rr_list_name_by_addr(r, ldns_pkt_answerfrom(p), 0, 0);
807b5038d7SDag-Erling Smørgrav
817b5038d7SDag-Erling Smørgrav fprintf(fd, ";; Received %d bytes from %s#%d(",
827b5038d7SDag-Erling Smørgrav (int) ldns_pkt_size(p),
837b5038d7SDag-Erling Smørgrav ldns_rdf2str(ldns_pkt_answerfrom(p)),
847b5038d7SDag-Erling Smørgrav (int) ldns_resolver_port(r));
857b5038d7SDag-Erling Smørgrav /* if we can resolve this print it, other print the ip again */
867b5038d7SDag-Erling Smørgrav if (hostnames) {
877b5038d7SDag-Erling Smørgrav ldns_rdf_print(fd,
887b5038d7SDag-Erling Smørgrav ldns_rr_rdf(ldns_rr_list_rr(hostnames, 0), 0));
897b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(hostnames);
907b5038d7SDag-Erling Smørgrav } else {
912787e39aSDag-Erling Smørgrav answerfrom_str = ldns_rdf2str(ldns_pkt_answerfrom(p));
922787e39aSDag-Erling Smørgrav if (answerfrom_str) {
932787e39aSDag-Erling Smørgrav fprintf(fd, "%s", answerfrom_str);
942787e39aSDag-Erling Smørgrav LDNS_FREE(answerfrom_str);
952787e39aSDag-Erling Smørgrav }
967b5038d7SDag-Erling Smørgrav }
977b5038d7SDag-Erling Smørgrav fprintf(fd, ") in %u ms\n\n", (unsigned int)ldns_pkt_querytime(p));
987b5038d7SDag-Erling Smørgrav }
997b5038d7SDag-Erling Smørgrav /*
1007b5038d7SDag-Erling Smørgrav * generic function to get some RRset from a nameserver
1017b5038d7SDag-Erling Smørgrav * and possible some signatures too (that would be the day...)
1027b5038d7SDag-Erling Smørgrav */
1037b5038d7SDag-Erling Smørgrav ldns_pkt_type
get_dnssec_rr(ldns_pkt * p,ldns_rdf * name,ldns_rr_type t,ldns_rr_list ** rrlist,ldns_rr_list ** sig)1047b5038d7SDag-Erling Smørgrav get_dnssec_rr(ldns_pkt *p, ldns_rdf *name, ldns_rr_type t,
1057b5038d7SDag-Erling Smørgrav ldns_rr_list **rrlist, ldns_rr_list **sig)
1067b5038d7SDag-Erling Smørgrav {
1077b5038d7SDag-Erling Smørgrav ldns_pkt_type pt = LDNS_PACKET_UNKNOWN;
1087b5038d7SDag-Erling Smørgrav ldns_rr_list *sigs = NULL;
1097b5038d7SDag-Erling Smørgrav size_t i;
1107b5038d7SDag-Erling Smørgrav
1117b5038d7SDag-Erling Smørgrav if (!p) {
1127b5038d7SDag-Erling Smørgrav if (rrlist) {
1137b5038d7SDag-Erling Smørgrav *rrlist = NULL;
1147b5038d7SDag-Erling Smørgrav }
1157b5038d7SDag-Erling Smørgrav return LDNS_PACKET_UNKNOWN;
1167b5038d7SDag-Erling Smørgrav }
1177b5038d7SDag-Erling Smørgrav
1187b5038d7SDag-Erling Smørgrav pt = ldns_pkt_reply_type(p);
1197b5038d7SDag-Erling Smørgrav if (name) {
1202787e39aSDag-Erling Smørgrav if (rrlist) {
1212787e39aSDag-Erling Smørgrav *rrlist = ldns_pkt_rr_list_by_name_and_type(p, name, t,
1222787e39aSDag-Erling Smørgrav LDNS_SECTION_ANSWER);
1232787e39aSDag-Erling Smørgrav if (!*rrlist) {
1242787e39aSDag-Erling Smørgrav *rrlist = ldns_pkt_rr_list_by_name_and_type(
1252787e39aSDag-Erling Smørgrav p, name, t,
1262787e39aSDag-Erling Smørgrav LDNS_SECTION_AUTHORITY);
1277b5038d7SDag-Erling Smørgrav }
1282787e39aSDag-Erling Smørgrav }
1292787e39aSDag-Erling Smørgrav if (sig) {
1302787e39aSDag-Erling Smørgrav sigs = ldns_pkt_rr_list_by_name_and_type(p, name,
1312787e39aSDag-Erling Smørgrav LDNS_RR_TYPE_RRSIG,
1327b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANSWER);
1337b5038d7SDag-Erling Smørgrav if (!sigs) {
1342787e39aSDag-Erling Smørgrav sigs = ldns_pkt_rr_list_by_name_and_type(
1352787e39aSDag-Erling Smørgrav p, name, LDNS_RR_TYPE_RRSIG,
1367b5038d7SDag-Erling Smørgrav LDNS_SECTION_AUTHORITY);
1377b5038d7SDag-Erling Smørgrav }
1382787e39aSDag-Erling Smørgrav }
1397b5038d7SDag-Erling Smørgrav } else {
1407b5038d7SDag-Erling Smørgrav /* A DS-referral - get the DS records if they are there */
1412787e39aSDag-Erling Smørgrav if (rrlist) {
1422787e39aSDag-Erling Smørgrav *rrlist = ldns_pkt_rr_list_by_type(
1432787e39aSDag-Erling Smørgrav p, t, LDNS_SECTION_AUTHORITY);
1442787e39aSDag-Erling Smørgrav }
1452787e39aSDag-Erling Smørgrav if (sig) {
1462787e39aSDag-Erling Smørgrav sigs = ldns_pkt_rr_list_by_type(p,
1472787e39aSDag-Erling Smørgrav LDNS_RR_TYPE_RRSIG,
1487b5038d7SDag-Erling Smørgrav LDNS_SECTION_AUTHORITY);
1497b5038d7SDag-Erling Smørgrav }
1502787e39aSDag-Erling Smørgrav }
1517b5038d7SDag-Erling Smørgrav if (sig) {
1527b5038d7SDag-Erling Smørgrav *sig = ldns_rr_list_new();
1537b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(sigs); i++) {
1547b5038d7SDag-Erling Smørgrav /* only add the sigs that cover this type */
1552787e39aSDag-Erling Smørgrav if (t == ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(
1562787e39aSDag-Erling Smørgrav ldns_rr_list_rr(sigs, i)))) {
1572787e39aSDag-Erling Smørgrav
1582787e39aSDag-Erling Smørgrav ldns_rr_list_push_rr(*sig,
1592787e39aSDag-Erling Smørgrav ldns_rr_clone(
1602787e39aSDag-Erling Smørgrav ldns_rr_list_rr(
1612787e39aSDag-Erling Smørgrav sigs, i)));
1627b5038d7SDag-Erling Smørgrav }
1637b5038d7SDag-Erling Smørgrav }
1647b5038d7SDag-Erling Smørgrav }
1657b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(sigs);
1667b5038d7SDag-Erling Smørgrav
1677b5038d7SDag-Erling Smørgrav if (pt == LDNS_PACKET_NXDOMAIN || pt == LDNS_PACKET_NODATA) {
1687b5038d7SDag-Erling Smørgrav return pt;
1697b5038d7SDag-Erling Smørgrav } else {
1707b5038d7SDag-Erling Smørgrav return LDNS_PACKET_ANSWER;
1717b5038d7SDag-Erling Smørgrav }
1727b5038d7SDag-Erling Smørgrav }
1737b5038d7SDag-Erling Smørgrav
1747b5038d7SDag-Erling Smørgrav
1757b5038d7SDag-Erling Smørgrav ldns_status
ldns_verify_denial(ldns_pkt * pkt,ldns_rdf * name,ldns_rr_type type,ldns_rr_list ** nsec_rrs,ldns_rr_list ** nsec_rr_sigs)1767b5038d7SDag-Erling Smørgrav ldns_verify_denial(ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type, ldns_rr_list **nsec_rrs, ldns_rr_list **nsec_rr_sigs)
1777b5038d7SDag-Erling Smørgrav {
1782787e39aSDag-Erling Smørgrav #ifdef HAVE_SSL
1797b5038d7SDag-Erling Smørgrav uint16_t nsec_i;
1807b5038d7SDag-Erling Smørgrav
1817b5038d7SDag-Erling Smørgrav ldns_rr_list *nsecs;
1827b5038d7SDag-Erling Smørgrav ldns_status result;
183*5afab0e5SDag-Erling Smørgrav const ldns_rr_descriptor *descriptor;
1847b5038d7SDag-Erling Smørgrav
185*5afab0e5SDag-Erling Smørgrav if (!pkt) {
186*5afab0e5SDag-Erling Smørgrav descriptor = ldns_rr_descript(type);
187*5afab0e5SDag-Erling Smørgrav
188*5afab0e5SDag-Erling Smørgrav printf("NETWORk ERROR! Cannot verify denial for: ");
189*5afab0e5SDag-Erling Smørgrav ldns_rdf_print(stdout, name);
190*5afab0e5SDag-Erling Smørgrav printf(" type ");
191*5afab0e5SDag-Erling Smørgrav if (descriptor && descriptor->_name)
192*5afab0e5SDag-Erling Smørgrav printf("%s", descriptor->_name);
193*5afab0e5SDag-Erling Smørgrav else
194*5afab0e5SDag-Erling Smørgrav printf("TYPE%u", type);
195*5afab0e5SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_NO_RRSIG;
196*5afab0e5SDag-Erling Smørgrav }
1977b5038d7SDag-Erling Smørgrav if (verbosity >= 5) {
1987b5038d7SDag-Erling Smørgrav printf("VERIFY DENIAL FROM:\n");
1997b5038d7SDag-Erling Smørgrav ldns_pkt_print(stdout, pkt);
2007b5038d7SDag-Erling Smørgrav }
2017b5038d7SDag-Erling Smørgrav
2027b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_CRYPTO_NO_RRSIG;
2037b5038d7SDag-Erling Smørgrav /* Try to see if there are NSECS in the packet */
2047b5038d7SDag-Erling Smørgrav nsecs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_NSEC, LDNS_SECTION_ANY_NOQUESTION);
2057b5038d7SDag-Erling Smørgrav if (nsecs) {
2067b5038d7SDag-Erling Smørgrav for (nsec_i = 0; nsec_i < ldns_rr_list_rr_count(nsecs); nsec_i++) {
2077b5038d7SDag-Erling Smørgrav /* there are four options:
2087b5038d7SDag-Erling Smørgrav * - name equals ownername and is covered by the type bitmap
2097b5038d7SDag-Erling Smørgrav * - name equals ownername but is not covered by the type bitmap
2107b5038d7SDag-Erling Smørgrav * - name falls within nsec coverage but is not equal to the owner name
2117b5038d7SDag-Erling Smørgrav * - name falls outside of nsec coverage
2127b5038d7SDag-Erling Smørgrav */
2137b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(ldns_rr_owner(ldns_rr_list_rr(nsecs, nsec_i)), name) == 0) {
2147b5038d7SDag-Erling Smørgrav /*
2157b5038d7SDag-Erling Smørgrav printf("CHECKING NSEC:\n");
2167b5038d7SDag-Erling Smørgrav ldns_rr_print(stdout, ldns_rr_list_rr(nsecs, nsec_i));
2177b5038d7SDag-Erling Smørgrav printf("DAWASEM\n");
2187b5038d7SDag-Erling Smørgrav */
2197b5038d7SDag-Erling Smørgrav if (ldns_nsec_bitmap_covers_type(
2207b5038d7SDag-Erling Smørgrav ldns_nsec_get_bitmap(ldns_rr_list_rr(nsecs,
2217b5038d7SDag-Erling Smørgrav nsec_i)),
2227b5038d7SDag-Erling Smørgrav type)) {
2237b5038d7SDag-Erling Smørgrav /* Error, according to the nsec this rrset is signed */
2247b5038d7SDag-Erling Smørgrav result = LDNS_STATUS_CRYPTO_NO_RRSIG;
2257b5038d7SDag-Erling Smørgrav } else {
2267b5038d7SDag-Erling Smørgrav /* ok nsec denies existence */
2277b5038d7SDag-Erling Smørgrav if (verbosity >= 3) {
2287b5038d7SDag-Erling Smørgrav printf(";; Existence of data set with this type denied by NSEC\n");
2297b5038d7SDag-Erling Smørgrav }
2307b5038d7SDag-Erling Smørgrav /*printf(";; Verifiably insecure.\n");*/
2317b5038d7SDag-Erling Smørgrav if (nsec_rrs && nsec_rr_sigs) {
2327b5038d7SDag-Erling Smørgrav (void) get_dnssec_rr(pkt, ldns_rr_owner(ldns_rr_list_rr(nsecs, nsec_i)), LDNS_RR_TYPE_NSEC, nsec_rrs, nsec_rr_sigs);
2337b5038d7SDag-Erling Smørgrav }
2347b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(nsecs);
2357b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
2367b5038d7SDag-Erling Smørgrav }
2377b5038d7SDag-Erling Smørgrav } else if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, nsec_i), name)) {
2387b5038d7SDag-Erling Smørgrav if (verbosity >= 3) {
2397b5038d7SDag-Erling Smørgrav printf(";; Existence of data set with this name denied by NSEC\n");
2407b5038d7SDag-Erling Smørgrav }
2417b5038d7SDag-Erling Smørgrav if (nsec_rrs && nsec_rr_sigs) {
2427b5038d7SDag-Erling Smørgrav (void) get_dnssec_rr(pkt, ldns_rr_owner(ldns_rr_list_rr(nsecs, nsec_i)), LDNS_RR_TYPE_NSEC, nsec_rrs, nsec_rr_sigs);
2437b5038d7SDag-Erling Smørgrav }
2447b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(nsecs);
2457b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
2467b5038d7SDag-Erling Smørgrav } else {
2477b5038d7SDag-Erling Smørgrav /* nsec has nothing to do with this data */
2487b5038d7SDag-Erling Smørgrav }
2497b5038d7SDag-Erling Smørgrav }
2507b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(nsecs);
2517b5038d7SDag-Erling Smørgrav } else if( (nsecs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_NSEC3, LDNS_SECTION_ANY_NOQUESTION)) ) {
2527b5038d7SDag-Erling Smørgrav ldns_rr_list* sigs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_RRSIG, LDNS_SECTION_ANY_NOQUESTION);
2537b5038d7SDag-Erling Smørgrav ldns_rr* q = ldns_rr_new();
2547b5038d7SDag-Erling Smørgrav ldns_rr* match = NULL;
2552787e39aSDag-Erling Smørgrav
2562787e39aSDag-Erling Smørgrav if(!sigs) {
2572787e39aSDag-Erling Smørgrav if (q) {
2582787e39aSDag-Erling Smørgrav ldns_rr_free(q);
2592787e39aSDag-Erling Smørgrav }
2602787e39aSDag-Erling Smørgrav ldns_rr_list_deep_free(nsecs);
2612787e39aSDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
2622787e39aSDag-Erling Smørgrav }
2632787e39aSDag-Erling Smørgrav if(!q) {
2642787e39aSDag-Erling Smørgrav ldns_rr_list_deep_free(nsecs);
2652787e39aSDag-Erling Smørgrav ldns_rr_list_deep_free(sigs);
2662787e39aSDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
2672787e39aSDag-Erling Smørgrav }
2687b5038d7SDag-Erling Smørgrav ldns_rr_set_question(q, 1);
2697b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(q, 0);
2707b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(q, ldns_rdf_clone(name));
2712787e39aSDag-Erling Smørgrav if(!ldns_rr_owner(q)) {
2722787e39aSDag-Erling Smørgrav ldns_rr_free(q);
2732787e39aSDag-Erling Smørgrav ldns_rr_list_deep_free(sigs);
2742787e39aSDag-Erling Smørgrav ldns_rr_list_deep_free(nsecs);
2752787e39aSDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
2762787e39aSDag-Erling Smørgrav }
2777b5038d7SDag-Erling Smørgrav ldns_rr_set_type(q, type);
2787b5038d7SDag-Erling Smørgrav
2797b5038d7SDag-Erling Smørgrav /* result = ldns_dnssec_verify_denial_nsec3(q, nsecs, sigs, ldns_pkt_get_rcode(pkt), type, ldns_pkt_ancount(pkt) == 0); */
2807b5038d7SDag-Erling Smørgrav result = ldns_dnssec_verify_denial_nsec3_match(q, nsecs, sigs, ldns_pkt_get_rcode(pkt), type, ldns_pkt_ancount(pkt) == 0, &match);
2817b5038d7SDag-Erling Smørgrav if (result == LDNS_STATUS_OK && match && nsec_rrs && nsec_rr_sigs) {
2827b5038d7SDag-Erling Smørgrav (void) get_dnssec_rr(pkt, ldns_rr_owner(match), LDNS_RR_TYPE_NSEC3, nsec_rrs, nsec_rr_sigs);
2837b5038d7SDag-Erling Smørgrav }
2847b5038d7SDag-Erling Smørgrav ldns_rr_free(q);
2857b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(nsecs);
2867b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(sigs);
2877b5038d7SDag-Erling Smørgrav }
2887b5038d7SDag-Erling Smørgrav return result;
2892787e39aSDag-Erling Smørgrav #else
2902787e39aSDag-Erling Smørgrav (void)pkt;
2912787e39aSDag-Erling Smørgrav (void)name;
2922787e39aSDag-Erling Smørgrav (void)type;
2932787e39aSDag-Erling Smørgrav (void)nsec_rrs;
2942787e39aSDag-Erling Smørgrav (void)nsec_rr_sigs;
2952787e39aSDag-Erling Smørgrav return LDNS_STATUS_ERR;
2962787e39aSDag-Erling Smørgrav #endif /* HAVE_SSL */
2977b5038d7SDag-Erling Smørgrav }
2987b5038d7SDag-Erling Smørgrav
2997b5038d7SDag-Erling Smørgrav /* NSEC3 draft -07 */
3007b5038d7SDag-Erling Smørgrav /*return hash name match*/
3017b5038d7SDag-Erling Smørgrav ldns_rr *
ldns_nsec3_exact_match(ldns_rdf * qname,ldns_rr_type qtype,ldns_rr_list * nsec3s)3027b5038d7SDag-Erling Smørgrav ldns_nsec3_exact_match(ldns_rdf *qname, ldns_rr_type qtype, ldns_rr_list *nsec3s) {
3037b5038d7SDag-Erling Smørgrav uint8_t algorithm;
3047b5038d7SDag-Erling Smørgrav uint32_t iterations;
3057b5038d7SDag-Erling Smørgrav uint8_t salt_length;
3067b5038d7SDag-Erling Smørgrav uint8_t *salt;
3077b5038d7SDag-Erling Smørgrav
3087b5038d7SDag-Erling Smørgrav ldns_rdf *sname = NULL, *hashed_sname = NULL;
3097b5038d7SDag-Erling Smørgrav
3107b5038d7SDag-Erling Smørgrav size_t nsec_i;
3117b5038d7SDag-Erling Smørgrav ldns_rr *nsec;
3127b5038d7SDag-Erling Smørgrav ldns_rr *result = NULL;
3137b5038d7SDag-Erling Smørgrav
3147b5038d7SDag-Erling Smørgrav const ldns_rr_descriptor *descriptor;
3157b5038d7SDag-Erling Smørgrav
3167b5038d7SDag-Erling Smørgrav ldns_rdf *zone_name = NULL;
3177b5038d7SDag-Erling Smørgrav
3187b5038d7SDag-Erling Smørgrav if (verbosity >= 4) {
3197b5038d7SDag-Erling Smørgrav printf(";; finding exact match for ");
3207b5038d7SDag-Erling Smørgrav descriptor = ldns_rr_descript(qtype);
3217b5038d7SDag-Erling Smørgrav if (descriptor && descriptor->_name) {
3227b5038d7SDag-Erling Smørgrav printf("%s ", descriptor->_name);
3237b5038d7SDag-Erling Smørgrav } else {
3247b5038d7SDag-Erling Smørgrav printf("TYPE%d ", qtype);
3257b5038d7SDag-Erling Smørgrav }
3267b5038d7SDag-Erling Smørgrav ldns_rdf_print(stdout, qname);
3277b5038d7SDag-Erling Smørgrav printf("\n");
3287b5038d7SDag-Erling Smørgrav }
3297b5038d7SDag-Erling Smørgrav
3307b5038d7SDag-Erling Smørgrav if (!qname || !nsec3s || ldns_rr_list_rr_count(nsec3s) < 1) {
3317b5038d7SDag-Erling Smørgrav if (verbosity >= 4) {
3327b5038d7SDag-Erling Smørgrav printf("no qname, nsec3s or list empty\n");
3337b5038d7SDag-Erling Smørgrav }
3347b5038d7SDag-Erling Smørgrav return NULL;
3357b5038d7SDag-Erling Smørgrav }
3367b5038d7SDag-Erling Smørgrav
3377b5038d7SDag-Erling Smørgrav nsec = ldns_rr_list_rr(nsec3s, 0);
3387b5038d7SDag-Erling Smørgrav algorithm = ldns_nsec3_algorithm(nsec);
3397b5038d7SDag-Erling Smørgrav salt_length = ldns_nsec3_salt_length(nsec);
3407b5038d7SDag-Erling Smørgrav salt = ldns_nsec3_salt_data(nsec);
3417b5038d7SDag-Erling Smørgrav iterations = ldns_nsec3_iterations(nsec);
3427b5038d7SDag-Erling Smørgrav if (salt == NULL) {
3437b5038d7SDag-Erling Smørgrav goto done;
3447b5038d7SDag-Erling Smørgrav }
3457b5038d7SDag-Erling Smørgrav
3467b5038d7SDag-Erling Smørgrav sname = ldns_rdf_clone(qname);
3477b5038d7SDag-Erling Smørgrav if (sname == NULL) {
3487b5038d7SDag-Erling Smørgrav goto done;
3497b5038d7SDag-Erling Smørgrav }
3507b5038d7SDag-Erling Smørgrav if (verbosity >= 4) {
3517b5038d7SDag-Erling Smørgrav printf(";; owner name hashes to: ");
3527b5038d7SDag-Erling Smørgrav }
3537b5038d7SDag-Erling Smørgrav hashed_sname = ldns_nsec3_hash_name(sname, algorithm, iterations, salt_length, salt);
3547b5038d7SDag-Erling Smørgrav if (hashed_sname == NULL) {
3557b5038d7SDag-Erling Smørgrav goto done;
3567b5038d7SDag-Erling Smørgrav }
3577b5038d7SDag-Erling Smørgrav zone_name = ldns_dname_left_chop(ldns_rr_owner(nsec));
3587b5038d7SDag-Erling Smørgrav if (zone_name == NULL) {
3597b5038d7SDag-Erling Smørgrav goto done;
3607b5038d7SDag-Erling Smørgrav }
3617b5038d7SDag-Erling Smørgrav if (ldns_dname_cat(hashed_sname, zone_name) != LDNS_STATUS_OK) {
3627b5038d7SDag-Erling Smørgrav goto done;
3637b5038d7SDag-Erling Smørgrav };
3647b5038d7SDag-Erling Smørgrav
3657b5038d7SDag-Erling Smørgrav if (verbosity >= 4) {
3667b5038d7SDag-Erling Smørgrav ldns_rdf_print(stdout, hashed_sname);
3677b5038d7SDag-Erling Smørgrav printf("\n");
3687b5038d7SDag-Erling Smørgrav }
3697b5038d7SDag-Erling Smørgrav
3707b5038d7SDag-Erling Smørgrav for (nsec_i = 0; nsec_i < ldns_rr_list_rr_count(nsec3s); nsec_i++) {
3717b5038d7SDag-Erling Smørgrav nsec = ldns_rr_list_rr(nsec3s, nsec_i);
3727b5038d7SDag-Erling Smørgrav
3737b5038d7SDag-Erling Smørgrav /* check values of iterations etc! */
3747b5038d7SDag-Erling Smørgrav
3757b5038d7SDag-Erling Smørgrav /* exact match? */
3767b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(ldns_rr_owner(nsec), hashed_sname) == 0) {
3777b5038d7SDag-Erling Smørgrav result = nsec;
3787b5038d7SDag-Erling Smørgrav goto done;
3797b5038d7SDag-Erling Smørgrav }
3807b5038d7SDag-Erling Smørgrav
3817b5038d7SDag-Erling Smørgrav }
3827b5038d7SDag-Erling Smørgrav
3837b5038d7SDag-Erling Smørgrav done:
3847b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(zone_name);
3857b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(sname);
3867b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_sname);
3877b5038d7SDag-Erling Smørgrav LDNS_FREE(salt);
3887b5038d7SDag-Erling Smørgrav
3897b5038d7SDag-Erling Smørgrav if (verbosity >= 4) {
3907b5038d7SDag-Erling Smørgrav if (result) {
3917b5038d7SDag-Erling Smørgrav printf(";; Found.\n");
3927b5038d7SDag-Erling Smørgrav } else {
3937b5038d7SDag-Erling Smørgrav printf(";; Not foud.\n");
3947b5038d7SDag-Erling Smørgrav }
3957b5038d7SDag-Erling Smørgrav }
3967b5038d7SDag-Erling Smørgrav return result;
3977b5038d7SDag-Erling Smørgrav }
3987b5038d7SDag-Erling Smørgrav
3997b5038d7SDag-Erling Smørgrav /*return the owner name of the closest encloser for name from the list of rrs */
4007b5038d7SDag-Erling Smørgrav /* this is NOT the hash, but the original name! */
4017b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_nsec3_closest_encloser(ldns_rdf * qname,ldns_rr_type qtype,ldns_rr_list * nsec3s)4027b5038d7SDag-Erling Smørgrav ldns_nsec3_closest_encloser(ldns_rdf *qname, ldns_rr_type qtype, ldns_rr_list *nsec3s)
4037b5038d7SDag-Erling Smørgrav {
4047b5038d7SDag-Erling Smørgrav /* remember parameters, they must match */
4057b5038d7SDag-Erling Smørgrav uint8_t algorithm;
4067b5038d7SDag-Erling Smørgrav uint32_t iterations;
4077b5038d7SDag-Erling Smørgrav uint8_t salt_length;
4087b5038d7SDag-Erling Smørgrav uint8_t *salt;
4097b5038d7SDag-Erling Smørgrav
4107b5038d7SDag-Erling Smørgrav ldns_rdf *sname = NULL, *hashed_sname = NULL, *tmp;
4117b5038d7SDag-Erling Smørgrav bool flag;
4127b5038d7SDag-Erling Smørgrav
4137b5038d7SDag-Erling Smørgrav bool exact_match_found;
4147b5038d7SDag-Erling Smørgrav bool in_range_found;
4157b5038d7SDag-Erling Smørgrav
4167b5038d7SDag-Erling Smørgrav ldns_rdf *zone_name = NULL;
4177b5038d7SDag-Erling Smørgrav
4187b5038d7SDag-Erling Smørgrav size_t nsec_i;
4197b5038d7SDag-Erling Smørgrav ldns_rr *nsec;
4207b5038d7SDag-Erling Smørgrav ldns_rdf *result = NULL;
4217b5038d7SDag-Erling Smørgrav
4227b5038d7SDag-Erling Smørgrav if (!qname || !nsec3s || ldns_rr_list_rr_count(nsec3s) < 1) {
4237b5038d7SDag-Erling Smørgrav return NULL;
4247b5038d7SDag-Erling Smørgrav }
4257b5038d7SDag-Erling Smørgrav
4267b5038d7SDag-Erling Smørgrav if (verbosity >= 4) {
4277b5038d7SDag-Erling Smørgrav printf(";; finding closest encloser for type %d ", qtype);
4287b5038d7SDag-Erling Smørgrav ldns_rdf_print(stdout, qname);
4297b5038d7SDag-Erling Smørgrav printf("\n");
4307b5038d7SDag-Erling Smørgrav }
4317b5038d7SDag-Erling Smørgrav
4327b5038d7SDag-Erling Smørgrav nsec = ldns_rr_list_rr(nsec3s, 0);
4337b5038d7SDag-Erling Smørgrav algorithm = ldns_nsec3_algorithm(nsec);
4347b5038d7SDag-Erling Smørgrav salt_length = ldns_nsec3_salt_length(nsec);
4357b5038d7SDag-Erling Smørgrav salt = ldns_nsec3_salt_data(nsec);
4367b5038d7SDag-Erling Smørgrav iterations = ldns_nsec3_iterations(nsec);
4377b5038d7SDag-Erling Smørgrav if (salt == NULL) {
4387b5038d7SDag-Erling Smørgrav goto done;
4397b5038d7SDag-Erling Smørgrav }
4407b5038d7SDag-Erling Smørgrav
4417b5038d7SDag-Erling Smørgrav sname = ldns_rdf_clone(qname);
4427b5038d7SDag-Erling Smørgrav if (sname == NULL) {
4437b5038d7SDag-Erling Smørgrav goto done;
4447b5038d7SDag-Erling Smørgrav }
4457b5038d7SDag-Erling Smørgrav
4467b5038d7SDag-Erling Smørgrav flag = false;
4477b5038d7SDag-Erling Smørgrav
4487b5038d7SDag-Erling Smørgrav zone_name = ldns_dname_left_chop(ldns_rr_owner(nsec));
4497b5038d7SDag-Erling Smørgrav if (zone_name == NULL) {
4507b5038d7SDag-Erling Smørgrav goto done;
4517b5038d7SDag-Erling Smørgrav }
4527b5038d7SDag-Erling Smørgrav
4537b5038d7SDag-Erling Smørgrav /* algorithm from nsec3-07 8.3 */
4547b5038d7SDag-Erling Smørgrav while (ldns_dname_label_count(sname) > 0) {
4557b5038d7SDag-Erling Smørgrav exact_match_found = false;
4567b5038d7SDag-Erling Smørgrav in_range_found = false;
4577b5038d7SDag-Erling Smørgrav
4587b5038d7SDag-Erling Smørgrav if (verbosity >= 3) {
4597b5038d7SDag-Erling Smørgrav printf(";; ");
4607b5038d7SDag-Erling Smørgrav ldns_rdf_print(stdout, sname);
4617b5038d7SDag-Erling Smørgrav printf(" hashes to: ");
4627b5038d7SDag-Erling Smørgrav }
4637b5038d7SDag-Erling Smørgrav hashed_sname = ldns_nsec3_hash_name(sname, algorithm, iterations, salt_length, salt);
4647b5038d7SDag-Erling Smørgrav if (hashed_sname == NULL) {
4657b5038d7SDag-Erling Smørgrav goto done;
4667b5038d7SDag-Erling Smørgrav }
4677b5038d7SDag-Erling Smørgrav
4687b5038d7SDag-Erling Smørgrav if (ldns_dname_cat(hashed_sname, zone_name) != LDNS_STATUS_OK){
469*5afab0e5SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_sname);
4707b5038d7SDag-Erling Smørgrav goto done;
4717b5038d7SDag-Erling Smørgrav }
4727b5038d7SDag-Erling Smørgrav
4737b5038d7SDag-Erling Smørgrav if (verbosity >= 3) {
4747b5038d7SDag-Erling Smørgrav ldns_rdf_print(stdout, hashed_sname);
4757b5038d7SDag-Erling Smørgrav printf("\n");
4767b5038d7SDag-Erling Smørgrav }
4777b5038d7SDag-Erling Smørgrav
4787b5038d7SDag-Erling Smørgrav for (nsec_i = 0; nsec_i < ldns_rr_list_rr_count(nsec3s); nsec_i++) {
4797b5038d7SDag-Erling Smørgrav nsec = ldns_rr_list_rr(nsec3s, nsec_i);
4807b5038d7SDag-Erling Smørgrav
4817b5038d7SDag-Erling Smørgrav /* check values of iterations etc! */
4827b5038d7SDag-Erling Smørgrav
4837b5038d7SDag-Erling Smørgrav /* exact match? */
4847b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(ldns_rr_owner(nsec), hashed_sname) == 0) {
4857b5038d7SDag-Erling Smørgrav if (verbosity >= 4) {
4867b5038d7SDag-Erling Smørgrav printf(";; exact match found\n");
4877b5038d7SDag-Erling Smørgrav }
4887b5038d7SDag-Erling Smørgrav exact_match_found = true;
4897b5038d7SDag-Erling Smørgrav } else if (ldns_nsec_covers_name(nsec, hashed_sname)) {
4907b5038d7SDag-Erling Smørgrav if (verbosity >= 4) {
4917b5038d7SDag-Erling Smørgrav printf(";; in range of an nsec\n");
4927b5038d7SDag-Erling Smørgrav }
4937b5038d7SDag-Erling Smørgrav in_range_found = true;
4947b5038d7SDag-Erling Smørgrav }
4957b5038d7SDag-Erling Smørgrav
4967b5038d7SDag-Erling Smørgrav }
4977b5038d7SDag-Erling Smørgrav if (!exact_match_found && in_range_found) {
4987b5038d7SDag-Erling Smørgrav flag = true;
4997b5038d7SDag-Erling Smørgrav } else if (exact_match_found && flag) {
5007b5038d7SDag-Erling Smørgrav result = ldns_rdf_clone(sname);
5017b5038d7SDag-Erling Smørgrav } else if (exact_match_found && !flag) {
5027b5038d7SDag-Erling Smørgrav // error!
5037b5038d7SDag-Erling Smørgrav if (verbosity >= 4) {
5047b5038d7SDag-Erling Smørgrav printf(";; the closest encloser is the same name (ie. this is an exact match, ie there is no closest encloser)\n");
5057b5038d7SDag-Erling Smørgrav }
5067b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_sname);
5077b5038d7SDag-Erling Smørgrav goto done;
5087b5038d7SDag-Erling Smørgrav } else {
5097b5038d7SDag-Erling Smørgrav flag = false;
5107b5038d7SDag-Erling Smørgrav }
5117b5038d7SDag-Erling Smørgrav
5127b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_sname);
5137b5038d7SDag-Erling Smørgrav tmp = sname;
5147b5038d7SDag-Erling Smørgrav sname = ldns_dname_left_chop(sname);
5157b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(tmp);
5167b5038d7SDag-Erling Smørgrav if (sname == NULL) {
5177b5038d7SDag-Erling Smørgrav goto done;
5187b5038d7SDag-Erling Smørgrav }
5197b5038d7SDag-Erling Smørgrav }
5207b5038d7SDag-Erling Smørgrav
5217b5038d7SDag-Erling Smørgrav done:
5227b5038d7SDag-Erling Smørgrav LDNS_FREE(salt);
5237b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(zone_name);
5247b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(sname);
5257b5038d7SDag-Erling Smørgrav
5267b5038d7SDag-Erling Smørgrav if (!result) {
5277b5038d7SDag-Erling Smørgrav if (verbosity >= 4) {
5287b5038d7SDag-Erling Smørgrav printf(";; no closest encloser found\n");
5297b5038d7SDag-Erling Smørgrav }
5307b5038d7SDag-Erling Smørgrav }
5317b5038d7SDag-Erling Smørgrav
5327b5038d7SDag-Erling Smørgrav /* todo checks from end of 6.2. here or in caller? */
5337b5038d7SDag-Erling Smørgrav return result;
5347b5038d7SDag-Erling Smørgrav }
535