/** verify and test one rrset against the key rrset */
static void
verifytest_rrset(struct module_env* env, struct val_env* ve, 
	struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
	struct query_info* qinfo)
{
	enum sec_status sec;
	char* reason = NULL;
	uint8_t sigalg[ALGO_NEEDS_MAX+1];
	if(vsig) {
		log_nametypeclass(VERB_QUERY, "verify of rrset",
			rrset->rk.dname, ntohs(rrset->rk.type),
			ntohs(rrset->rk.rrset_class));
	}
	setup_sigalg(dnskey, sigalg); /* check all algorithms in the dnskey */
	sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason);
	if(vsig) {
		printf("verify outcome is: %s %s\n", sec_status_to_string(sec),
			reason?reason:"");
	}
	if(should_be_bogus(rrset, qinfo)) {
		unit_assert(sec == sec_status_bogus);
	} else {
		unit_assert(sec == sec_status_secure);
	}
}
Ejemplo n.º 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;
}