Exemple #1
0
/**
 * This routine adds a new RR to a trust anchor. The trust anchor may not
 * exist yet, and is created if not. The RR can be DS or DNSKEY.
 * This routine will also remove duplicates; storing them only once.
 * @param anchors: anchor storage.
 * @param name: name of trust anchor (wireformat)
 * @param type: type or RR
 * @param dclass: class of RR
 * @param rdata: rdata wireformat, starting with rdlength.
 *	If NULL, nothing is stored, but an entry is created.
 * @param rdata_len: length of rdata including rdlength.
 * @return: NULL on error, else the trust anchor.
 */
static struct trust_anchor*
anchor_store_new_key(struct val_anchors* anchors, uint8_t* name, uint16_t type,
	uint16_t dclass, uint8_t* rdata, size_t rdata_len)
{
	struct ta_key* k;
	struct trust_anchor* ta;
	int namelabs;
	size_t namelen;
	namelabs = dname_count_size_labels(name, &namelen);
	if(type != LDNS_RR_TYPE_DS && type != LDNS_RR_TYPE_DNSKEY) {
		log_err("Bad type for trust anchor");
		return 0;
	}
	/* lookup or create trustanchor */
	ta = anchor_find(anchors, name, namelabs, namelen, dclass);
	if(!ta) {
		ta = anchor_new_ta(anchors, name, namelabs, namelen, dclass);
		if(!ta)
			return NULL;
		lock_basic_lock(&ta->lock);
	}
	if(!rdata) {
		lock_basic_unlock(&ta->lock);
		return ta;
	}
	/* look for duplicates */
	if(anchor_find_key(ta, rdata, rdata_len, type)) {
		lock_basic_unlock(&ta->lock);
		return ta;
	}
	k = anchor_new_ta_key(anchors, rdata, rdata_len, type);
	if(!k) {
		lock_basic_unlock(&ta->lock);
		return NULL;
	}
	/* add new key */
	if(type == LDNS_RR_TYPE_DS)
		ta->numDS++;
	else	ta->numDNSKEY++;
	k->next = ta->keylist;
	ta->keylist = k;
	lock_basic_unlock(&ta->lock);
	return ta;
}
int
anchor_has_keytag(struct val_anchors* anchors, uint8_t* name, int namelabs,
	size_t namelen, uint16_t dclass, uint16_t keytag)
{
	uint16_t* taglist;
	uint16_t* tl;
	size_t numtag, i;
	struct trust_anchor* anchor = anchor_find(anchors,
		name, namelabs, namelen, dclass);
	if(!anchor)
		return 0;
	if(!anchor->numDS && !anchor->numDNSKEY) {
		lock_basic_unlock(&anchor->lock);
		return 0;
	}

	taglist = calloc(anchor->numDS + anchor->numDNSKEY, sizeof(*taglist));
	if(!taglist) {
		lock_basic_unlock(&anchor->lock);
		return 0;
	}

	numtag = anchor_list_keytags(anchor, taglist,
		anchor->numDS+anchor->numDNSKEY);
	lock_basic_unlock(&anchor->lock);
	if(!numtag) {
		free(taglist);
		return 0;
	}
	tl = taglist;
	for(i=0; i<numtag; i++) {
		if(*tl == keytag) {
			free(taglist);
			return 1;
		}
		tl++;
	}
	free(taglist);
	return 0;
}
Exemple #3
0
int 
iter_indicates_dnssec(struct module_env* env, struct delegpt* dp,
        struct dns_msg* msg, uint16_t dclass)
{
	struct trust_anchor* a;
	/* information not available, !env->anchors can be common */
	if(!env || !env->anchors || !dp || !dp->name)
		return 0;
	/* a trust anchor exists with this name, RRSIGs expected */
	if((a=anchor_find(env->anchors, dp->name, dp->namelabs, dp->namelen,
		dclass))) {
		lock_basic_unlock(&a->lock);
		return 1;
	}
	/* see if DS rrset was given, in AUTH section */
	if(msg && msg->rep &&
		reply_find_rrset_section_ns(msg->rep, dp->name, dp->namelen,
		LDNS_RR_TYPE_DS, dclass))
		return 1;
	/* look in key cache */
	if(env->key_cache) {
		struct key_entry_key* kk = key_cache_obtain(env->key_cache,
			dp->name, dp->namelen, dclass, env->scratch, *env->now);
		if(kk) {
			if(query_dname_compare(kk->name, dp->name) == 0) {
			  if(key_entry_isgood(kk) || key_entry_isbad(kk)) {
				regional_free_all(env->scratch);
				return 1;
			  } else if(key_entry_isnull(kk)) {
				regional_free_all(env->scratch);
				return 0;
			  }
			}
			regional_free_all(env->scratch);
		}
	}
	return 0;
}