diff --git a/doc/Changelog b/doc/Changelog index 2da993bd2..7fc9f26a4 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +29 January 2018: Ralph + - Use NSEC with longest ce to prove wildcard absence. + - Only use *.ce to prove wildcard absence, no longer names. + 25 January 2018: Wouter - ltrace.conf file for libunbound in contrib. diff --git a/validator/val_nsec.c b/validator/val_nsec.c index 4604f3d6d..a795e7733 100644 --- a/validator/val_nsec.c +++ b/validator/val_nsec.c @@ -513,7 +513,6 @@ val_nsec_proves_no_wc(struct ub_packed_rrset_key* nsec, uint8_t* qname, /* Determine if a NSEC record proves the non-existence of a * wildcard that could have produced qname. */ int labs; - int i; uint8_t* ce = nsec_closest_encloser(qname, nsec); uint8_t* strip; size_t striplen; @@ -526,13 +525,13 @@ val_nsec_proves_no_wc(struct ub_packed_rrset_key* nsec, uint8_t* qname, * and next names. */ labs = dname_count_labels(qname) - dname_count_labels(ce); - for(i=labs; i>0; i--) { + if(labs > 0) { /* i is number of labels to strip off qname, prepend * wild */ strip = qname; striplen = qnamelen; - dname_remove_labels(&strip, &striplen, i); + dname_remove_labels(&strip, &striplen, labs); if(striplen > LDNS_MAX_DOMAINLEN-2) - continue; /* too long to prepend wildcard */ + return 0; /* too long to prepend wildcard */ buf[0] = 1; buf[1] = (uint8_t)'*'; memmove(buf+2, strip, striplen); diff --git a/validator/validator.c b/validator/validator.c index 456bffd00..925791dec 100644 --- a/validator/validator.c +++ b/validator/validator.c @@ -944,6 +944,9 @@ validate_nameerror_response(struct module_env* env, struct val_env* ve, int nsec3s_seen = 0; struct ub_packed_rrset_key* s; size_t i; + uint8_t* ce; + int ce_labs = 0; + int prev_ce_labs = 0; for(i=chase_reply->an_numrrsets; ian_numrrsets+ chase_reply->ns_numrrsets; i++) { @@ -951,9 +954,19 @@ validate_nameerror_response(struct module_env* env, struct val_env* ve, if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC) { if(val_nsec_proves_name_error(s, qchase->qname)) has_valid_nsec = 1; - if(val_nsec_proves_no_wc(s, qchase->qname, - qchase->qname_len)) - has_valid_wnsec = 1; + ce = nsec_closest_encloser(qchase->qname, s); + ce_labs = dname_count_labels(ce); + /* Use longest closest encloser to prove wildcard. */ + if(ce_labs > prev_ce_labs || + (ce_labs == prev_ce_labs && + has_valid_wnsec == 0)) { + if(val_nsec_proves_no_wc(s, qchase->qname, + qchase->qname_len)) + has_valid_wnsec = 1; + else + has_valid_wnsec = 0; + } + prev_ce_labs = ce_labs; if(val_nsec_proves_insecuredelegation(s, qchase)) { verbose(VERB_ALGO, "delegation is insecure"); chase_reply->security = sec_status_insecure;