#include "util/regional.h"
#include "util/alloc.h"
#include "util/net_help.h"
+#include "validator/val_utils.h"
void
rrset_markdel(void* key)
return 0;
}
+/** See if the name is a within signer authority */
+static int
+dname_subdomain_rrsig_signers(uint8_t* dname,
+ struct ub_packed_rrset_key* rrset)
+{
+ struct packed_rrset_data* d = (struct packed_rrset_data*)
+ rrset->entry.data;
+ size_t i;
+ if(!d || !d->rrsig_count)
+ return 0;
+ for(i=0; i<d->rrsig_count; i++) {
+ uint8_t* sname = NULL;
+ size_t slen = 0;
+ rrsig_get_signer(d->rr_data[d->count+i], d->rr_len[d->count+i],
+ &sname, &slen);
+ if(!sname || !slen)
+ return 0; /* malformed */
+ if(!dname_subdomain_c(dname, sname))
+ return 0; /* not a subdomain */
+ }
+ return 1;
+}
+
void rrset_cache_update_wildcard(struct rrset_cache* rrset_cache,
struct ub_packed_rrset_key* rrset, uint8_t* ce, size_t ce_len,
struct alloc_cache* alloc, time_t timenow)
{
struct rrset_ref ref;
uint8_t wc_dname[LDNS_MAX_DOMAINLEN+3];
+
+ /* See if the RRSIG signer name allows this wildcard,
+ * the new rrset should fall within the zone of the RRSIG signer(s). */
+ if(!dname_subdomain_rrsig_signers(ce, rrset)) {
+ verbose(VERB_ALGO, "wildcard canonical parent outside signer authority");
+ return;
+ }
+
rrset = packed_rrset_copy_alloc(rrset, alloc, timenow);
if(!rrset) {
log_err("malloc failure in rrset_cache_update_wildcard");
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
return sec_status_bogus;
}
+ if((int)sig[2+3] < dname_signame_label_count(signer)) {
+ verbose(VERB_QUERY, "verify: RRSIG label count too low for signer");
+ *reason = "signature labelcount lower than signature signer";
+ if(reason_bogus)
+ *reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
+ return sec_status_bogus;
+ }
/* original ttl, always ok */
}
/** Get signer name from RRSIG */
-static void
+void
rrsig_get_signer(uint8_t* data, size_t len, uint8_t** sname, size_t* slen)
{
/* RRSIG rdata is not allowed to be compressed, it is stored
int derive_cname_from_dname(struct ub_packed_rrset_key* cname,
struct ub_packed_rrset_key* dname, uint8_t* out, size_t outlen);
+/** Get signer name from RRSIG, sname is NULL if malformed. */
+void rrsig_get_signer(uint8_t* data, size_t len, uint8_t** sname,
+ size_t* slen);
+
#endif /* VALIDATOR_VAL_UTILS_H */
uint8_t* wc = NULL;
size_t wl;
int wc_cached = 0;
+ int wc_to_cache = 0;
+ uint8_t* cache_wc = NULL;
+ size_t cache_wl = 0;
+ struct ub_packed_rrset_key* cache_s = NULL;
int wc_NSEC_ok = 0;
/* This is used to update the RRset cache, with the combination
* of the dname expansion and this wildcard, for security status. */
return;
}
if(wc && !wc_cached && env->cfg->aggressive_nsec) {
- rrset_cache_update_wildcard(env->rrset_cache, s, wc, wl,
- env->alloc, *env->now);
+ /* Postpone cache adjust until proof has succeeded. */
+ wc_to_cache = 1;
+ cache_wc = wc;
+ cache_wl = wl;
+ cache_s = s;
wc_cached = 1;
}
if(wc) wc_rrset = s;
entry.data)->security = sec_status_bogus;
return;
}
+ if(wc_to_cache) {
+ rrset_cache_update_wildcard(env->rrset_cache, cache_s,
+ cache_wc, cache_wl, env->alloc, *env->now);
+ }
verbose(VERB_ALGO, "Successfully validated positive response");
chase_reply->security = sec_status_secure;