/** test if list is all secure */ static int list_is_secure(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key** list, size_t num, struct key_entry_key* kkey, char** reason) { struct packed_rrset_data* d; size_t i; for(i=0; i<num; i++) { d = (struct packed_rrset_data*)list[i]->entry.data; if(list[i]->rk.type != htons(LDNS_RR_TYPE_NSEC3)) continue; if(d->security == sec_status_secure) continue; rrset_check_sec_status(env->rrset_cache, list[i], *env->now); if(d->security == sec_status_secure) continue; d->security = val_verify_rrset_entry(env, ve, list[i], kkey, reason); if(d->security != sec_status_secure) { verbose(VERB_ALGO, "NSEC3 did not verify"); return 0; } rrset_update_sec_status(env->rrset_cache, list[i], *env->now); } return 1; }
enum sec_status val_verify_rrset(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys, char** reason) { enum sec_status sec; struct packed_rrset_data* d = (struct packed_rrset_data*)rrset-> entry.data; if(d->security == sec_status_secure) { /* re-verify all other statuses, because keyset may change*/ log_nametypeclass(VERB_ALGO, "verify rrset cached", rrset->rk.dname, ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class)); return d->security; } /* check in the cache if verification has already been done */ rrset_check_sec_status(env->rrset_cache, rrset, *env->now); if(d->security == sec_status_secure) { log_nametypeclass(VERB_ALGO, "verify rrset from cache", rrset->rk.dname, ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class)); return d->security; } log_nametypeclass(VERB_ALGO, "verify rrset", rrset->rk.dname, ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class)); sec = dnskeyset_verify_rrset(env, ve, rrset, keys, reason); verbose(VERB_ALGO, "verify result: %s", sec_status_to_string(sec)); regional_free_all(env->scratch); /* update rrset security status * only improves security status * and bogus is set only once, even if we rechecked the status */ if(sec > d->security) { d->security = sec; if(sec == sec_status_secure) d->trust = rrset_trust_validated; else if(sec == sec_status_bogus) { size_t i; /* update ttl for rrset to fixed value. */ d->ttl = ve->bogus_ttl; for(i=0; i<d->count+d->rrsig_count; i++) d->rr_ttl[i] = ve->bogus_ttl; /* leave RR specific TTL: not used for determine * if RRset timed out and clients see proper value. */ lock_basic_lock(&ve->bogus_lock); ve->num_rrset_bogus++; lock_basic_unlock(&ve->bogus_lock); } /* if status updated - store in cache for reuse */ rrset_update_sec_status(env->rrset_cache, rrset, *env->now); } return sec; }