Skip to content
Snippets Groups Projects
Commit 2d228445 authored by Karel Slaný's avatar Karel Slaný
Browse files

layer/validate: NSEC3 wildcard answer response check is enabled

parent 3937198b
No related branches found
No related tags found
No related merge requests found
......@@ -148,7 +148,8 @@ static int wildcard_radix_len_diff(const knot_dname_t *expanded,
int kr_rrset_validate(const knot_pkt_t *pkt, knot_section_t section_id,
const knot_rrset_t *covered, const knot_rrset_t *keys,
const knot_dname_t *zone_name, uint32_t timestamp)
const knot_dname_t *zone_name, uint32_t timestamp,
bool has_nsec3)
{
if (!pkt || !covered || !keys || !zone_name) {
return kr_error(EINVAL);
......@@ -156,7 +157,7 @@ int kr_rrset_validate(const knot_pkt_t *pkt, knot_section_t section_id,
int ret = kr_error(KNOT_DNSSEC_ENOKEY);
for (unsigned i = 0; i < keys->rrs.rr_count; ++i) {
ret = kr_rrset_validate_with_key(pkt, section_id, covered, keys, i, NULL, zone_name, timestamp);
ret = kr_rrset_validate_with_key(pkt, section_id, covered, keys, i, NULL, zone_name, timestamp, has_nsec3);
if (ret == 0) {
break;
}
......@@ -168,7 +169,8 @@ int kr_rrset_validate(const knot_pkt_t *pkt, knot_section_t section_id,
int kr_rrset_validate_with_key(const knot_pkt_t *pkt, knot_section_t section_id,
const knot_rrset_t *covered, const knot_rrset_t *keys,
size_t key_pos, const struct dseckey *key,
const knot_dname_t *zone_name, uint32_t timestamp)
const knot_dname_t *zone_name, uint32_t timestamp,
bool has_nsec3)
{
int ret;
int val_flgs;
......@@ -209,7 +211,12 @@ int kr_rrset_validate_with_key(const knot_pkt_t *pkt, knot_section_t section_id,
continue;
}
if (val_flgs & FLG_WILDCARD_EXPANSION) {
if (kr_nsec_wildcard_answer_response_check(pkt, KNOT_AUTHORITY, covered->owner) != 0) {
if (!has_nsec3) {
ret = kr_nsec_wildcard_answer_response_check(pkt, KNOT_AUTHORITY, covered->owner);
} else {
ret = kr_nsec3_wildcard_answer_response_check(pkt, KNOT_AUTHORITY, covered->owner, trim_labels - 1);
}
if (ret != 0) {
continue;
}
}
......@@ -226,7 +233,8 @@ int kr_rrset_validate_with_key(const knot_pkt_t *pkt, knot_section_t section_id,
}
int kr_dnskeys_trusted(const knot_pkt_t *pkt, knot_section_t section_id, const knot_rrset_t *keys,
const knot_rrset_t *ta, const knot_dname_t *zone_name, uint32_t timestamp)
const knot_rrset_t *ta, const knot_dname_t *zone_name, uint32_t timestamp,
bool has_nsec3)
{
if (!pkt || !keys || !ta) {
return kr_error(EINVAL);
......@@ -255,7 +263,7 @@ int kr_dnskeys_trusted(const knot_pkt_t *pkt, knot_section_t section_id, const k
kr_dnssec_key_free(&key);
continue;
}
if (kr_rrset_validate_with_key(pkt, section_id, keys, keys, i, key, zone_name, timestamp) != 0) {
if (kr_rrset_validate_with_key(pkt, section_id, keys, keys, i, key, zone_name, timestamp, has_nsec3) != 0) {
kr_dnssec_key_free(&key);
continue;
}
......
......@@ -46,11 +46,13 @@ struct dseckey;
* @param keys DNSKEY RRSet.
* @param zone_name Name of the zone containing the RRSIG RRSet.
* @param timestamp Validation time.
* @param has_nsec3 Whether to use NSEC3 validation.
* @return 0 or error code.
*/
int kr_rrset_validate(const knot_pkt_t *pkt, knot_section_t section_id,
const knot_rrset_t *covered, const knot_rrset_t *keys,
const knot_dname_t *zone_name, uint32_t timestamp);
const knot_dname_t *zone_name, uint32_t timestamp,
bool has_nsec3);
/**
* Validate RRSet using a specific key.
......@@ -62,12 +64,14 @@ int kr_rrset_validate(const knot_pkt_t *pkt, knot_section_t section_id,
* @param key Key to be used to validate. If NULL, then key from DNSKEY RRSet is used.
* @param zone_name Name of the zone containing the RRSIG RRSet.
* @param timestamp Validation time.
* @param has_nsec3 Whether to use NSEC3 validation.
* @return 0 or error code.
*/
int kr_rrset_validate_with_key(const knot_pkt_t *pkt, knot_section_t section_id,
const knot_rrset_t *covered, const knot_rrset_t *keys,
size_t key_pos, const struct dseckey *key,
const knot_dname_t *zone_name, uint32_t timestamp);
const knot_dname_t *zone_name, uint32_t timestamp,
bool has_nsec3);
/**
* Check whether the DNSKEY rrset matches the supplied trust anchor RRSet.
......@@ -77,10 +81,12 @@ int kr_rrset_validate_with_key(const knot_pkt_t *pkt, knot_section_t section_id,
* @param ta Trust anchor RRSet against which to validate the DNSKEY RRSet.
* @param zone_name Name of the zone containing the RRSet.
* @param timestamp Time stamp.
* @param has_nsec3 Whether to use NSEC3 validation.
* @return 0 or error code.
*/
int kr_dnskeys_trusted(const knot_pkt_t *pkt, knot_section_t section_id, const knot_rrset_t *keys,
const knot_rrset_t *ta, const knot_dname_t *zone_name, uint32_t timestamp);
const knot_rrset_t *ta, const knot_dname_t *zone_name, uint32_t timestamp,
bool has_nsec3);
/**
* Construct a DNSSEC key.
......
......@@ -18,6 +18,7 @@
#include <sys/time.h>
#include <string.h>
#include <libknot/packet/wire.h>
#include <libknot/rrtype/rdname.h>
#include <libknot/rrtype/rrsig.h>
......@@ -102,7 +103,8 @@ static int rrtypes_add(struct contained_ids *stored, const knot_rrset_t *rr)
}
static int validate_section(struct kr_query *qry, knot_pkt_t *answer,
knot_section_t section_id, mm_ctx_t *pool)
knot_section_t section_id, mm_ctx_t *pool,
bool has_nsec3)
{
const knot_pktsection_t *sec = knot_pkt_section(answer, section_id);
if (!sec) {
......@@ -157,7 +159,7 @@ static int validate_section(struct kr_query *qry, knot_pkt_t *answer,
* change when updating cut information before validation.
*/
const knot_dname_t *zone_name = qry->zone_cut.key ? qry->zone_cut.key->owner : NULL;
ret = kr_rrset_validate(answer, section_id, covered, qry->zone_cut.key, zone_name, qry->timestamp.tv_sec);
ret = kr_rrset_validate(answer, section_id, covered, qry->zone_cut.key, zone_name, qry->timestamp.tv_sec, has_nsec3);
if (ret != 0) {
break;
}
......@@ -169,7 +171,7 @@ fail:
return ret;
}
static int validate_records(struct kr_query *qry, knot_pkt_t *answer, mm_ctx_t *pool)
static int validate_records(struct kr_query *qry, knot_pkt_t *answer, mm_ctx_t *pool, bool has_nsec3)
{
#warning TODO: validate RRSIGS (records with ZSK, keys with KSK), return FAIL if failed
if (!qry->zone_cut.key) {
......@@ -179,16 +181,16 @@ static int validate_records(struct kr_query *qry, knot_pkt_t *answer, mm_ctx_t *
int ret;
ret = validate_section(qry, answer, KNOT_ANSWER, pool);
ret = validate_section(qry, answer, KNOT_ANSWER, pool, has_nsec3);
if (ret != 0) {
return ret;
}
ret = validate_section(qry, answer, KNOT_AUTHORITY, pool);
ret = validate_section(qry, answer, KNOT_AUTHORITY, pool, has_nsec3);
return ret;
}
static int validate_keyset(struct kr_query *qry, knot_pkt_t *answer)
static int validate_keyset(struct kr_query *qry, knot_pkt_t *answer, bool has_nsec3)
{
/* Merge DNSKEY records from answer */
const knot_pktsection_t *an = knot_pkt_section(answer, KNOT_ANSWER);
......@@ -224,7 +226,7 @@ static int validate_keyset(struct kr_query *qry, knot_pkt_t *answer)
/* Check if there's a key for current TA. */
int ret = kr_dnskeys_trusted(answer, KNOT_ANSWER, qry->zone_cut.key,
qry->zone_cut.trust_anchor, qry->zone_cut.name,
qry->timestamp.tv_sec);
qry->timestamp.tv_sec, has_nsec3);
if (ret != 0) {
knot_rrset_free(&qry->zone_cut.key, qry->zone_cut.pool);
return ret;
......@@ -386,7 +388,7 @@ static int validate(knot_layer_t *ctx, knot_pkt_t *pkt)
}
}
ret = validate_keyset(qry, pkt);
ret = validate_keyset(qry, pkt, has_nsec3);
if (ret != 0) {
DEBUG_MSG("<= bad keys, broken trust chain\n");
qry->flags |= QUERY_DNSSEC_BOGUS;
......@@ -395,7 +397,7 @@ static int validate(knot_layer_t *ctx, knot_pkt_t *pkt)
}
/* Validate all records, fail as bogus if it doesn't match. */
ret = validate_records(qry, pkt, req->rplan.pool);
ret = validate_records(qry, pkt, req->rplan.pool, has_nsec3);
if (ret != 0) {
DEBUG_MSG("<= couldn't validate RRSIGs\n");
qry->flags |= QUERY_DNSSEC_BOGUS;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment