Beispiel #1
0
/** 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;
}
Beispiel #2
0
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;
}