Commit 169a7a0b authored by Grigorii Demidov's avatar Grigorii Demidov

lib/cache;lib/dnssec;lib/layer: some issues were fixed

parent 1e9aec00
......@@ -42,20 +42,18 @@
/** @internal Removes all records from cache. */
static int cache_purge(struct kr_cache_txn *txn)
{
int ret;
if (!txn_is_valid(txn)) {
return kr_error(EINVAL);
int ret = kr_error(EINVAL);
if (txn_is_valid(txn)) {
txn->owner->stats.delete += 1;
ret = txn_api(txn)->clear(&txn->t);
}
txn->owner->stats.delete += 1;
ret = txn_api(txn)->clear(&txn->t);
return ret;
}
/** @internal Check cache internal data version. Clear if it doesn't match.
* returns : EEXIST - cache data version matched.
* 0 - cache recreated, txn has to be committed.
* otherwise - cache recreation fails.
* 0 - cache recreated, txn has to be committed.
* Otherwise - cache recreation fails.
*/
static int assert_right_version_txn(struct kr_cache_txn *txn)
{
......@@ -67,7 +65,7 @@ static int assert_right_version_txn(struct kr_cache_txn *txn)
ret = kr_error(EEXIST);
} else {
/*
* Version doesn't not match.
* Version doesn't match.
* Recreate cache and write version key.
*/
ret = txn_api(txn)->count(&txn->t);
......
......@@ -222,62 +222,44 @@ static int covers_name(int *flags, const knot_rrset_t *nsec3, const knot_dname_t
uint8_t *next_hash = NULL;
knot_nsec3_next_hashed(&nsec3->rrs, 0, &next_hash, &next_size);
if ((owner_hash.size != next_size) || (name_hash.size != next_size)) {
/*
* All hash lengths must be same.
* NSEC3 rr span doesn't cover name which has to be checked.
* Exit with no-error return code,
* FLG_NAME_COVERED will not be set.
*/
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)) {
if ((owner_hash.size == next_size) && (name_hash.size == next_size)) {
/* All hash lengths must be same. */
const uint8_t *ownrd = owner_hash.data;
const uint8_t *nextd = next_hash;
int covered = 0;
int greater_then_owner = (memcmp(ownrd, name_hash.data, next_size) < 0);
int less_then_next = (memcmp(name_hash.data, nextd, next_size) < 0);
if (memcmp(ownrd, nextd, next_size) < 0) {
/*
* NSEC3 rr span doesn't cover name has to be checked.
* Exit with no-error return code,
* FLG_NAME_COVERED will not be set.
* 0 (...) owner ... next (...) MAX
* ^
* name
* ==>
* (owner < name) && (name < next)
*/
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)) {
covered = ((greater_then_owner) && (less_then_next));
} else {
/*
* NSEC3 rr span doesn't cover name has to be checked.
* Exit with no-error return code,
* FLG_NAME_COVERED will not be set.
* owner ... MAX, 0 ... next
* ^ ^ ^
* name name name
* =>
* (owner < name) || (name < next)
*/
goto fail;
covered = ((greater_then_owner) || (less_then_next));
}
}
*flags |= FLG_NAME_COVERED;
if (covered) {
*flags |= FLG_NAME_COVERED;
uint8_t nsec3_flags = knot_nsec3_flags(&nsec3->rrs, 0);
if (nsec3_flags & ~OPT_OUT_BIT) {
/* RFC5155 3.1.2 */
ret = kr_error(EINVAL);
} else {
ret = kr_ok();
uint8_t nsec3_flags = knot_nsec3_flags(&nsec3->rrs, 0);
if (nsec3_flags & ~OPT_OUT_BIT) {
/* RFC5155 3.1.2 */
ret = kr_error(EINVAL);
} else {
ret = kr_ok();
}
}
}
fail:
......@@ -344,19 +326,12 @@ static int matches_name(int *flags, const knot_rrset_t *nsec3, const knot_dname_
goto fail;
}
if ((owner_hash.size != name_hash.size) ||
(memcmp(owner_hash.data, name_hash.data, owner_hash.size) != 0)) {
/*
* NSEC3 owner does not match name has to be checked.
* Exit with no-error return code,
* FLG_NAME_MATCHED will not be set.
*/
goto fail;
if ((owner_hash.size == name_hash.size) &&
(memcmp(owner_hash.data, name_hash.data, owner_hash.size) == 0)) {
*flags |= FLG_NAME_MATCHED;
ret = kr_ok();
}
*flags |= FLG_NAME_MATCHED;
ret = kr_ok();
fail:
if (params.salt.data) {
dnssec_nsec3_params_free(&params);
......@@ -639,7 +614,10 @@ static int matches_closest_encloser_wildcard(const knot_pkt_t *pkt, knot_section
/* TODO -- The loop resembles no_data_response_no_ds() exept
* the following condition.
*/
if ((flags & FLG_NAME_MATCHED) && (flags & FLG_TYPE_BIT_MISSING)) {
if ((flags & FLG_NAME_MATCHED) &&
(flags & FLG_TYPE_BIT_MISSING) &&
(flags & FLG_CNAME_BIT_MISSING)) {
/* rfc5155 8.7 */
return kr_ok();
}
}
......@@ -680,45 +658,16 @@ int kr_nsec3_wildcard_answer_response_check(const knot_pkt_t *pkt, knot_section_
}
int kr_nsec3_no_data_ds(const knot_pkt_t *pkt, knot_section_t section_id,
const knot_dname_t *sname)
{
/* DS record may be also matched by an existing NSEC3 RR. */
int ret = no_data_response_no_ds(pkt, section_id, sname, KNOT_RRTYPE_DS);
if (ret == 0) {
/* Satisfies RFC5155 8.6, first paragraph. */
return ret;
}
/* Find closest provable encloser. */
const knot_dname_t *encloser_name = NULL;
const knot_rrset_t *covering_next_nsec3 = NULL;
ret = closest_encloser_proof(pkt, section_id, sname, &encloser_name,
NULL, &covering_next_nsec3);
if (ret != 0) {
return ret;
}
assert(encloser_name && covering_next_nsec3);
if (!has_optout(covering_next_nsec3)) {
/* Don't satisfies RFC5155 8.6, second paragraph. */
ret = kr_error(DNSSEC_NOT_FOUND);
}
return ret;
}
int kr_nsec3_no_data_no_ds(const knot_pkt_t *pkt, knot_section_t section_id,
int kr_nsec3_no_data(const knot_pkt_t *pkt, knot_section_t section_id,
const knot_dname_t *sname, uint16_t stype)
{
/* DS record may be also matched by an existing NSEC3 RR. */
int ret = no_data_response_no_ds(pkt, section_id, sname, stype);
if (ret == 0) {
/* Satisfies RFC5155 8.5, first paragraph. */
/* Satisfies RFC5155 8.5 and 8.6, both first paragraph. */
return ret;
}
/* Check RFC5155 8.7. */
/* Find closest provable encloser. */
const knot_dname_t *encloser_name = NULL;
const knot_rrset_t *covering_next_nsec3 = NULL;
......@@ -736,15 +685,16 @@ int kr_nsec3_no_data_no_ds(const knot_pkt_t *pkt, knot_section_t section_id,
return ret;
}
if (has_optout(covering_next_nsec3)) {
if (!has_optout(covering_next_nsec3)) {
/* Bogus */
ret = kr_error(ENOENT);
} else {
/*
* Satisfies RFC5155 ERRATA 3441 8.5
* (No Data Responses, QTYPE is not DS)
* - empty nonterminal derived from unsecure delegation.
* Moreover, ENT may be wilcard.
* Hence it covers "wilcard nodata response" case.
* It is not an error, but
* denial of existance can not be proven.
* Satisfies RFC5155 8.6 (QTYPE == DS), 2nd paragraph.
* Also satisfies ERRATA 3441 8.5 (QTYPE != DS), 3rd paragraph.
* - (wildcard) empty nonterminal
* derived from unsecure delegation.
* Denial of existance can not be proven.
* Set error code to proceed unsecure.
*/
ret = kr_error(DNSSEC_NOT_FOUND);
......
......@@ -47,18 +47,9 @@ int kr_nsec3_wildcard_answer_response_check(const knot_pkt_t *pkt, knot_section_
* @param section_id Packet section to be processed.
* @param sname Queried domain name.
* @param stype Queried type.
* @return 0 or error code.
* @retval DNSSEC_NOT_FOUND denial of existence can't be proven due to opt-out.
* @return 0 or error code:
* DNSSEC_NOT_FOUND - denial of existence can't be proven
* due to opt-out, otherwise - bogus.
*/
int kr_nsec3_no_data_no_ds(const knot_pkt_t *pkt, knot_section_t section_id,
int kr_nsec3_no_data(const knot_pkt_t *pkt, knot_section_t section_id,
const knot_dname_t *sname, uint16_t stype);
/**
* Authenticated denial of existence according to RFC5155 8.6
* @note No RRSIGs are validated.
* @param pkt Packet structure to be processed.
* @param section_id Packet section to be processed.
* @param sname Queried domain name.
* @return 0 or error code.
*/
int kr_nsec3_no_data_ds(const knot_pkt_t *pkt, knot_section_t section_id,
const knot_dname_t *sname);
......@@ -295,7 +295,11 @@ static int update_delegation(struct kr_request *req, struct kr_query *qry, knot_
if (!has_nsec3) {
ret = kr_nsec_existence_denial(answer, KNOT_AUTHORITY, proved_name, KNOT_RRTYPE_DS);
} else {
ret = kr_nsec3_no_data_ds(answer, KNOT_AUTHORITY, proved_name);
ret = kr_nsec3_no_data(answer, KNOT_AUTHORITY, proved_name, KNOT_RRTYPE_DS);
if (ret == kr_error(DNSSEC_NOT_FOUND)) {
/* Not bogus, but going insecure */
ret = 0;
}
}
if (ret != 0) {
DEBUG_MSG(qry, "<= bogus proof of DS non-existence\n");
......@@ -422,7 +426,7 @@ static int validate(knot_layer_t *ctx, knot_pkt_t *pkt)
if (!has_nsec3) {
ret = kr_nsec_existence_denial(pkt, KNOT_AUTHORITY, knot_pkt_qname(pkt), knot_pkt_qtype(pkt));
} else {
ret = kr_nsec3_no_data_no_ds(pkt, KNOT_AUTHORITY, knot_pkt_qname(pkt), knot_pkt_qtype(pkt));
ret = kr_nsec3_no_data(pkt, KNOT_AUTHORITY, knot_pkt_qname(pkt), knot_pkt_qtype(pkt));
}
if (ret != 0) {
if (has_nsec3 && (ret == kr_error(DNSSEC_NOT_FOUND))) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment