mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-18 04:32:54 -05:00
zonemd, region freed, and qstate not used when not in a query, and nsec
and nsec3 bitmap checks.
This commit is contained in:
parent
22e82765f9
commit
42d7cdb7d5
2 changed files with 55 additions and 18 deletions
|
|
@ -67,6 +67,7 @@
|
|||
#include "sldns/parseutil.h"
|
||||
#include "sldns/keyraw.h"
|
||||
#include "validator/val_nsec3.h"
|
||||
#include "validator/val_nsec.h"
|
||||
#include "validator/val_secalgo.h"
|
||||
#include "validator/val_sigcrypt.h"
|
||||
#include "validator/val_anchor.h"
|
||||
|
|
@ -7516,8 +7517,10 @@ int auth_zone_generate_zonemd_check(struct auth_zone* z, int scheme,
|
|||
}
|
||||
|
||||
/** log auth zone message with zone name in front. */
|
||||
static void auth_zone_log(uint8_t* name, enum verbosity_value level, const char* format, ...) ATTR_FORMAT(printf, 3, 4);
|
||||
static void auth_zone_log(uint8_t* name, enum verbosity_value level, const char* format, ...)
|
||||
static void auth_zone_log(uint8_t* name, enum verbosity_value level,
|
||||
const char* format, ...) ATTR_FORMAT(printf, 3, 4);
|
||||
static void auth_zone_log(uint8_t* name, enum verbosity_value level,
|
||||
const char* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
|
@ -7532,8 +7535,9 @@ static void auth_zone_log(uint8_t* name, enum verbosity_value level, const char*
|
|||
}
|
||||
|
||||
/** ZONEMD, dnssec verify the rrset with the dnskey */
|
||||
static int zonemd_dnssec_verify(struct auth_zone* z, struct module_env* env,
|
||||
struct ub_packed_rrset_key* dnskey, struct auth_rrset* rrset)
|
||||
static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
|
||||
struct module_env* env, struct ub_packed_rrset_key* dnskey,
|
||||
struct auth_data* node, struct auth_rrset* rrset)
|
||||
{
|
||||
struct ub_packed_rrset_key pk;
|
||||
enum sec_status sec;
|
||||
|
|
@ -7543,7 +7547,7 @@ static int zonemd_dnssec_verify(struct auth_zone* z, struct module_env* env,
|
|||
m = modstack_find(&env->mesh->mods, "validator");
|
||||
if(m == -1) {
|
||||
auth_zone_log(z->name, VERB_ALGO, "zonemd dnssec verify: have "
|
||||
"trust anchor, but no validator module");
|
||||
"DNSKEY chain of trust, but no validator module");
|
||||
return 0;
|
||||
}
|
||||
ve = (struct val_env*)env->modinfo[m];
|
||||
|
|
@ -7551,17 +7555,14 @@ static int zonemd_dnssec_verify(struct auth_zone* z, struct module_env* env,
|
|||
memset(&pk, 0, sizeof(pk));
|
||||
pk.entry.key = &pk;
|
||||
pk.entry.data = rrset->data;
|
||||
pk.rk.dname = z->name;
|
||||
pk.rk.dname_len = z->namelen;
|
||||
pk.rk.dname = node->name;
|
||||
pk.rk.dname_len = node->namelen;
|
||||
pk.rk.type = htons(rrset->type);
|
||||
pk.rk.rrset_class = htons(z->dclass);
|
||||
auth_zone_log(z->name, VERB_ALGO,
|
||||
"zonemd: verify RRset with DNSKEY");
|
||||
/* pass NULL for qstate, it is only used for qtype NSEC to realloc
|
||||
* a new name in the qstate region */
|
||||
sec = dnskeyset_verify_rrset(env, ve, &pk, dnskey, NULL, &why_bogus,
|
||||
LDNS_SECTION_ANSWER, NULL);
|
||||
regional_free_all(env->scratch);
|
||||
if(sec == sec_status_secure) {
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -7570,6 +7571,30 @@ static int zonemd_dnssec_verify(struct auth_zone* z, struct module_env* env,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** check for nsec3, the RR with params equal, if bitmap has the type */
|
||||
static int nsec3_of_param_has_type(struct auth_rrset* nsec3, int algo,
|
||||
size_t iter, uint8_t* salt, size_t saltlen, uint16_t rrtype)
|
||||
{
|
||||
size_t i;
|
||||
struct ub_packed_rrset_key pk;
|
||||
memset(&pk, 0, sizeof(pk));
|
||||
pk.entry.data = nsec3->data;
|
||||
for(i=0; i<nsec3->data->count; i++) {
|
||||
int rralgo;
|
||||
size_t rriter, rrsaltlen;
|
||||
uint8_t* rrsalt;
|
||||
if(!nsec3_get_params(&pk, i, &rralgo, &rriter, &rrsalt,
|
||||
&rrsaltlen))
|
||||
continue; /* no parameters, malformed */
|
||||
if(rralgo != algo || rriter != iter || rrsaltlen != saltlen ||
|
||||
memcmp(rrsalt, salt, saltlen) != 0)
|
||||
continue; /* different parameters */
|
||||
if(nsec3_has_type(&pk, i, rrtype))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Verify the absence of ZONEMD with DNSSEC by checking NSEC, NSEC3 type flag.
|
||||
* return false on failure, reason contains description of failure. */
|
||||
static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
||||
|
|
@ -7583,12 +7608,19 @@ static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
|||
}
|
||||
nsec = az_domain_rrset(apex, LDNS_RR_TYPE_NSEC);
|
||||
if(nsec) {
|
||||
struct ub_packed_rrset_key pk;
|
||||
/* dnssec verify the NSEC */
|
||||
if(!zonemd_dnssec_verify(z, env, dnskey, nsec)) {
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, dnskey, apex, nsec)) {
|
||||
*reason = "DNSSEC verify failed for NSEC RRset";
|
||||
return 0;
|
||||
}
|
||||
/* check type bitmap */
|
||||
memset(&pk, 0, sizeof(pk));
|
||||
pk.entry.data = nsec->data;
|
||||
if(nsec_has_type(&pk, LDNS_RR_TYPE_ZONEMD)) {
|
||||
*reason = "DNSSEC NSEC bitmap says type ZONEMD exists";
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* NSEC3 perhaps ? */
|
||||
int algo;
|
||||
|
|
@ -7619,11 +7651,16 @@ static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
|||
return 0;
|
||||
}
|
||||
/* dnssec verify the NSEC3 */
|
||||
if(!zonemd_dnssec_verify(z, env, dnskey, nsec3)) {
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, dnskey, match, nsec3)) {
|
||||
*reason = "DNSSEC verify failed for NSEC3 RRset";
|
||||
return 0;
|
||||
}
|
||||
/* check type bitmap */
|
||||
if(nsec3_of_param_has_type(nsec3, algo, iter, salt, saltlen,
|
||||
LDNS_RR_TYPE_ZONEMD)) {
|
||||
*reason = "DNSSEC NSEC3 bitmap says type ZONEMD exists";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
@ -7646,11 +7683,11 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z,
|
|||
*reason = "zone has no SOA RRset";
|
||||
return 0;
|
||||
}
|
||||
if(!zonemd_dnssec_verify(z, env, dnskey, soa)) {
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, dnskey, apex, soa)) {
|
||||
*reason = "DNSSEC verify failed for SOA RRset";
|
||||
return 0;
|
||||
}
|
||||
if(!zonemd_dnssec_verify(z, env, dnskey, zonemd_rrset)) {
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, dnskey, apex, zonemd_rrset)) {
|
||||
*reason = "DNSSEC verify failed for ZONEMD RRset";
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -7797,8 +7834,6 @@ zonemd_get_dnskey_from_anchor(struct auth_zone* z, struct module_env* env,
|
|||
keystorage->rk.rrset_class = htons(z->dclass);
|
||||
auth_zone_log(z->name, VERB_QUERY,
|
||||
"zonemd: verify DNSKEY RRset with trust anchor");
|
||||
/* pass NULL for qstate, it is only used when type NSEC needs a
|
||||
* name reallocated to get the qstate region for that */
|
||||
sec = val_verify_DNSKEY_with_TA(env, ve, keystorage, anchor->ds_rrset,
|
||||
anchor->dnskey_rrset, NULL, reason, NULL);
|
||||
regional_free_all(env->scratch);
|
||||
|
|
@ -7842,7 +7877,7 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
|||
if(!reason)
|
||||
reason = "lookup of DNSKEY was bogus";
|
||||
auth_zone_log(z->name, VERB_ALGO,
|
||||
"zonemd lookup of DNSKEY was bogus: %s", why_bogus);
|
||||
"zonemd lookup of DNSKEY was bogus: %s", reason);
|
||||
} else if(rcode == LDNS_RCODE_NOERROR) {
|
||||
uint16_t wanted_qtype = LDNS_RR_TYPE_DNSKEY;
|
||||
struct regional* temp = env->scratch;
|
||||
|
|
@ -7894,6 +7929,7 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
|||
}
|
||||
|
||||
auth_zone_verify_zonemd_with_key(z, env, dnskey, is_insecure);
|
||||
regional_free_all(env->scratch);
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
|
||||
|
|
@ -7998,4 +8034,5 @@ void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env)
|
|||
}
|
||||
|
||||
auth_zone_verify_zonemd_with_key(z, env, dnskey, is_insecure);
|
||||
regional_free_all(env->scratch);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1187,7 +1187,7 @@ rrset_canonical(struct regional* region, sldns_buffer* buf,
|
|||
* section, to prevent that a wildcard synthesized NSEC can be used in
|
||||
* the non-existence proves. */
|
||||
if(ntohs(k->rk.type) == LDNS_RR_TYPE_NSEC &&
|
||||
section == LDNS_SECTION_AUTHORITY) {
|
||||
section == LDNS_SECTION_AUTHORITY && qstate) {
|
||||
k->rk.dname = regional_alloc_init(qstate->region, can_owner,
|
||||
can_owner_len);
|
||||
if(!k->rk.dname)
|
||||
|
|
|
|||
Loading…
Reference in a new issue