/** * findCoveringNSEC3 * Given a name, find a covering NSEC3 from among a list of NSEC3s. * * @param env: module environment with temporary region and buffer. * @param flt: the NSEC3 RR filter, contains zone name and RRs. * @param ct: cached hashes table. * @param nm: name to check if covered. * @param nmlen: length of name. * @param rrset: covering NSEC3 rrset is returned here. * @param rr: rr of cover is returned here. * @return true if a covering NSEC3 is found, false if not. */ static int find_covering_nsec3(struct module_env* env, struct nsec3_filter* flt, rbtree_t* ct, uint8_t* nm, size_t nmlen, struct ub_packed_rrset_key** rrset, int* rr) { size_t i_rs; int i_rr; struct ub_packed_rrset_key* s; struct nsec3_cached_hash* hash; int r; /* this loop skips other-zone and unknown NSEC3s, also non-NSEC3 RRs */ for(s=filter_first(flt, &i_rs, &i_rr); s; s=filter_next(flt, &i_rs, &i_rr)) { /* get name hashed for this NSEC3 RR */ r = nsec3_hash_name(ct, env->scratch, env->scratch_buffer, s, i_rr, nm, nmlen, &hash); if(r == 0) { log_err("nsec3: malloc failure"); break; /* alloc failure */ } else if(r < 0) continue; /* malformed NSEC3 */ else if(nsec3_covers(flt->zone, hash, s, i_rr, env->scratch_buffer)) { *rrset = s; /* rrset with this name */ *rr = i_rr; /* covers hash with these parameters */ return 1; } } *rrset = NULL; *rr = 0; return 0; }
/** Test hash algo - NSEC3 hash it and compare result */ static void nsec3_hash_test_entry(struct entry* e, rbtree_type* ct, struct alloc_cache* alloc, struct regional* region, sldns_buffer* buf) { struct query_info qinfo; struct reply_info* rep = NULL; struct ub_packed_rrset_key* answer, *nsec3; struct nsec3_cached_hash* hash = NULL; int ret; uint8_t* qname; if(vsig) { char* s = sldns_wire2str_pkt(e->reply_list->reply_pkt, e->reply_list->reply_len); printf("verifying NSEC3 hash:\n%s\n", s?s:"outofmemory"); free(s); } entry_to_repinfo(e, alloc, region, buf, &qinfo, &rep); nsec3 = find_rrset_type(rep, LDNS_RR_TYPE_NSEC3); answer = find_rrset_type(rep, LDNS_RR_TYPE_AAAA); qname = regional_alloc_init(region, qinfo.qname, qinfo.qname_len); /* check test is OK */ unit_assert(nsec3 && answer && qname); ret = nsec3_hash_name(ct, region, buf, nsec3, 0, qname, qinfo.qname_len, &hash); if(ret != 1) { printf("Bad nsec3_hash_name retcode %d\n", ret); unit_assert(ret == 1); } unit_assert(hash->dname && hash->hash && hash->hash_len && hash->b32 && hash->b32_len); unit_assert(hash->b32_len == (size_t)answer->rk.dname[0]); /* does not do lowercasing. */ unit_assert(memcmp(hash->b32, answer->rk.dname+1, hash->b32_len) == 0); reply_info_parsedelete(rep, alloc); query_info_clear(&qinfo); }