示例#1
0
/** verify that a DS RR hashes to a key and that key signs the set */
static enum sec_status
verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve, 
	struct ub_packed_rrset_key* dnskey_rrset, 
        struct ub_packed_rrset_key* ds_rrset, size_t ds_idx, char** reason)
{
	enum sec_status sec = sec_status_bogus;
	size_t i, num, numchecked = 0, numhashok = 0;
	num = rrset_get_count(dnskey_rrset);
	for(i=0; i<num; i++) {
		/* Skip DNSKEYs that don't match the basic criteria. */
		if(ds_get_key_algo(ds_rrset, ds_idx) 
		   != dnskey_get_algo(dnskey_rrset, i)
		   || dnskey_calc_keytag(dnskey_rrset, i)
		   != ds_get_keytag(ds_rrset, ds_idx)) {
			continue;
		}
		numchecked++;
		verbose(VERB_ALGO, "attempt DS match algo %d keytag %d",
			ds_get_key_algo(ds_rrset, ds_idx),
			ds_get_keytag(ds_rrset, ds_idx));

		/* Convert the candidate DNSKEY into a hash using the 
		 * same DS hash algorithm. */
		if(!ds_digest_match_dnskey(env, dnskey_rrset, i, ds_rrset, 
			ds_idx)) {
			verbose(VERB_ALGO, "DS match attempt failed");
			continue;
		}
		numhashok++;
		verbose(VERB_ALGO, "DS match digest ok, trying signature");

		/* Otherwise, we have a match! Make sure that the DNSKEY 
		 * verifies *with this key*  */
		sec = dnskey_verify_rrset(env, ve, dnskey_rrset, 
			dnskey_rrset, i, reason);
		if(sec == sec_status_secure) {
			return sec;
		}
		/* If it didn't validate with the DNSKEY, try the next one! */
	}
	if(numchecked == 0)
		algo_needs_reason(env, ds_get_key_algo(ds_rrset, ds_idx),
			reason, "no keys have a DS");
	else if(numhashok == 0)
		*reason = "DS hash mismatches key";
	else if(!*reason)
		*reason = "keyset not secured by DNSKEY that matches DS";
	return sec_status_bogus;
}
示例#2
0
size_t
anchor_list_keytags(struct trust_anchor* ta, uint16_t* list, size_t num)
{
	size_t i, ret = 0;
	if(ta->numDS == 0 && ta->numDNSKEY == 0)
		return 0; /* insecure point */
	if(ta->numDS != 0 && ta->ds_rrset) {
		struct packed_rrset_data* d=(struct packed_rrset_data*)
			ta->ds_rrset->entry.data;
		for(i=0; i<d->count; i++) {
			if(ret == num) continue;
			list[ret++] = ds_get_keytag(ta->ds_rrset, i);
		}
	}
	if(ta->numDNSKEY != 0 && ta->dnskey_rrset) {
		struct packed_rrset_data* d=(struct packed_rrset_data*)
			ta->dnskey_rrset->entry.data;
		for(i=0; i<d->count; i++) {
			if(ret == num) continue;
			list[ret++] = dnskey_calc_keytag(ta->dnskey_rrset, i);
		}
	}
	qsort(list, ret, sizeof(*list), keytag_compare);
	return ret;
}