Skip to content
Snippets Groups Projects

lib/dnssec: rewrite most of NSEC validation code

Merged Vladimír Čunát requested to merge dnssec-nsec-negative into master
Viewing commit 6da74af8
Show latest version
3 files
+ 9
105
Preferences
Compare changes
Files
3
+ 0
93
@@ -132,99 +132,6 @@ static int nsec_covers(const knot_rrset_t *nsec, const knot_dname_t *sname)
return kr_nsec_children_in_zone_check(bm, bm_size);
}
#define FLG_NOEXIST_RRTYPE (1 << 0) /**< <SNAME, SCLASS> exists, <SNAME, SCLASS, STYPE> does not exist. */
#define FLG_NOEXIST_RRSET (1 << 1) /**< <SNAME, SCLASS> does not exist. */
#define FLG_NOEXIST_WILDCARD (1 << 2) /**< No wildcard covering <SNAME, SCLASS> exists. */
#define FLG_NOEXIST_CLOSER (1 << 3) /**< Wildcard covering <SNAME, SCLASS> exists, but doesn't match STYPE. */
/**
* According to set flags determine whether NSEC proving
* RRset or RRType non-existence has been found.
* @param f Flags to inspect.
* @return True if required NSEC exists.
*/
#define kr_nsec_rrset_noexist(f) \
((f) & (FLG_NOEXIST_RRTYPE | FLG_NOEXIST_RRSET))
/**
* According to set flags determine whether wildcard non-existence
* has been proven.
* @param f Flags to inspect.
* @return True if wildcard not exists.
*/
#define kr_nsec_wcard_noexist(f) ((f) & FLG_NOEXIST_WILDCARD)
/**
* According to set flags determine whether authenticated denial of existence has been proven.
* @param f Flags to inspect.
* @return True if denial of existence proven.
*/
#define kr_nsec_existence_denied(f) \
((kr_nsec_rrset_noexist(f)) && (kr_nsec_wcard_noexist(f)))
/**
* Name error response check (RFC4035 3.1.3.2; RFC4035 5.4, bullet 2).
* @note Returned flags must be checked in order to prove denial.
* @param flags Flags to be set according to check outcome.
* @param nsec NSEC RR.
* @param name Name to be checked.
* @param pool
* @return 0 or error code.
*/
static int name_error_response_check_rr(int *flags, const knot_rrset_t *nsec,
const knot_dname_t *name)
{
if (kr_fails_assert(flags && nsec && name))
return kr_error(EINVAL);
if (nsec_covers(nsec, name) == 0)
*flags |= FLG_NOEXIST_RRSET;
/* Try to find parent wildcard that is proved by this NSEC. */
uint8_t namebuf[KNOT_DNAME_MAXLEN];
int ret = knot_dname_to_wire(namebuf, name, sizeof(namebuf));
if (ret < 0)
return ret;
knot_dname_t *ptr = namebuf;
while (ptr[0]) {
/* Remove leftmost label and replace it with '\1*'. */
ptr = (uint8_t *) knot_wire_next_label(ptr, NULL);
if (!ptr)
return kr_error(EINVAL);
*(--ptr) = '*';
*(--ptr) = 1;
/* True if this wildcard provably doesn't exist. */
if (nsec_covers(nsec, ptr) == 0) {
*flags |= FLG_NOEXIST_WILDCARD;
break;
}
/* Remove added leftmost asterisk. */
ptr += 2;
}
return kr_ok();
}
int kr_nsec_name_error_response_check(const knot_pkt_t *pkt, knot_section_t section_id,
const knot_dname_t *sname)
{
const knot_pktsection_t *sec = knot_pkt_section(pkt, section_id);
if (!sec || !sname)
return kr_error(EINVAL);
int flags = 0;
for (unsigned i = 0; i < sec->count; ++i) {
const knot_rrset_t *rrset = knot_pkt_rr(sec, i);
if (rrset->type != KNOT_RRTYPE_NSEC)
continue;
int ret = name_error_response_check_rr(&flags, rrset, sname);
if (ret != 0)
return ret;
}
return kr_nsec_existence_denied(flags) ? kr_ok() : kr_error(ENOENT);
}
int kr_nsec_bitmap_nodata_check(const uint8_t *bm, uint16_t bm_size, uint16_t type, const knot_dname_t *owner)
{
const int NO_PROOF = abs(ENOENT);