/** verify and test an entry - every rr in the message */ static void verifytest_entry(struct entry* e, struct alloc_cache* alloc, struct regional* region, ldns_buffer* pkt, struct ub_packed_rrset_key* dnskey, struct module_env* env, struct val_env* ve) { struct query_info qinfo; struct reply_info* rep = NULL; size_t i; regional_free_all(region); if(vsig) { printf("verifying pkt:\n"); ldns_pkt_print(stdout, e->reply_list->reply); printf("\n"); } entry_to_repinfo(e, alloc, region, pkt, &qinfo, &rep); for(i=0; i<rep->rrset_count; i++) { verifytest_rrset(env, ve, rep->rrsets[i], dnskey, &qinfo); } reply_info_parsedelete(rep, alloc); query_info_clear(&qinfo); }
/** 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); }
/** DS sig test an entry - get DNSKEY and DS in entry and verify */ static void dstest_entry(struct entry* e, struct alloc_cache* alloc, struct regional* region, sldns_buffer* pkt, struct module_env* env) { struct query_info qinfo; struct reply_info* rep = NULL; struct ub_packed_rrset_key* ds, *dnskey; int ret; regional_free_all(region); if(vsig) { char* s = sldns_wire2str_pkt(e->reply_list->reply_pkt, e->reply_list->reply_len); printf("verifying DS-DNSKEY match:\n%s\n", s?s:"outofmemory"); free(s); } entry_to_repinfo(e, alloc, region, pkt, &qinfo, &rep); ds = find_rrset_type(rep, LDNS_RR_TYPE_DS); dnskey = find_rrset_type(rep, LDNS_RR_TYPE_DNSKEY); /* check test is OK */ unit_assert(ds && dnskey); ret = ds_digest_match_dnskey(env, dnskey, 0, ds, 0); if(strncmp((char*)qinfo.qname, "\003yes", 4) == 0) { if(vsig) { printf("result(yes)= %s\n", ret?"yes":"no"); } unit_assert(ret); } else if (strncmp((char*)qinfo.qname, "\002no", 3) == 0) { if(vsig) { printf("result(no)= %s\n", ret?"yes":"no"); } unit_assert(!ret); verbose(VERB_QUERY, "DS fail: OK; matched unit test"); } else { fatal_exit("Bad qname in DS unit test, yes or no"); } reply_info_parsedelete(rep, alloc); query_info_clear(&qinfo); }
/** extract DNSKEY rrset from answer and convert it */ static struct ub_packed_rrset_key* extract_keys(struct entry* e, struct alloc_cache* alloc, struct regional* region, ldns_buffer* pkt) { struct ub_packed_rrset_key* dnskey = NULL; struct query_info qinfo; struct reply_info* rep = NULL; size_t i; entry_to_repinfo(e, alloc, region, pkt, &qinfo, &rep); for(i=0; i<rep->an_numrrsets; i++) { if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_DNSKEY) { dnskey = rep->rrsets[i]; rep->rrsets[i] = NULL; break; } } unit_assert(dnskey); reply_info_parsedelete(rep, alloc); query_info_clear(&qinfo); return dnskey; }