diff --git a/lib/dnssec/nsec3.c b/lib/dnssec/nsec3.c index 8fe13cbaf1b1418a153837716057491e4c01259b..7f1328d97f7f83ed995095afceabb9b3bf808313 100644 --- a/lib/dnssec/nsec3.c +++ b/lib/dnssec/nsec3.c @@ -208,20 +208,43 @@ static int covers_name(int *flags, const knot_rrset_t *nsec3, const knot_dname_t goto fail; } - if ((owner_hash.size != name_hash.size) || - (memcmp(owner_hash.data, name_hash.data, owner_hash.size) >= 0)) { - goto fail; - } - uint8_t next_size = 0; uint8_t *next_hash = NULL; knot_nsec3_next_hashed(&nsec3->rrs, 0, &next_hash, &next_size); - if ((name_hash.size != next_size) || - (memcmp(name_hash.data, next_hash, name_hash.size) >= 0)) { + if ((owner_hash.size != next_size) || (name_hash.size != next_size)) { + /* All hash lengths must be same. */ goto fail; } + const uint8_t *ownrd = owner_hash.data; + const uint8_t *nextd = next_hash; + if (memcmp(ownrd, nextd, next_size) < 0) { + /* + * 0 (...) owner ... next (...) MAX + * ^ + * name + * ==> + * (owner < name) && (name < next) + */ + if ((memcmp(ownrd, name_hash.data, next_size) >= 0) || + (memcmp(name_hash.data, nextd, next_size) >= 0)) { + goto fail; + } + } else { + /* + * owner ... MAX, 0 ... next + * ^ ^ ^ + * name name name + * => + * (owner < name) || (name < next) + */ + if ((memcmp(ownrd, name_hash.data, next_size) >= 0) && + (memcmp(name_hash.data, nextd, next_size) >= 0)) { + goto fail; + } + } + *flags |= FLG_NAME_COVERED; uint8_t nsec3_flags = knot_nsec3_flags(&nsec3->rrs, 0); diff --git a/lib/layer/validate.c b/lib/layer/validate.c index 85a5237f56b2e9179abe208830d1fd7df3b36c85..f5bb333926b9e261cfd60c19960122f9a20466bb 100644 --- a/lib/layer/validate.c +++ b/lib/layer/validate.c @@ -361,7 +361,6 @@ static int validate(knot_layer_t *ctx, knot_pkt_t *pkt) /* Validate non-existence proof if not positive answer. */ if (knot_wire_get_rcode(pkt->wire) == KNOT_RCODE_NXDOMAIN) { -#warning TODO: validate NSECx proof, RRSIGs will be checked later if it matches if (!has_nsec3) { ret = kr_nsec_name_error_response_check(pkt, KNOT_AUTHORITY, qry->sname, &req->pool); } else {