diff options
Diffstat (limited to 'usr.sbin/unbound/validator')
-rw-r--r-- | usr.sbin/unbound/validator/autotrust.c | 13 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/autotrust.h | 41 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/val_anchor.c | 10 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/val_anchor.h | 57 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/val_neg.c | 13 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/val_neg.h | 10 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/val_nsec.c | 2 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/val_nsec3.c | 28 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/val_nsec3.h | 4 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/val_secalgo.c | 104 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/val_sigcrypt.c | 36 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/val_sigcrypt.h | 42 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/val_utils.c | 26 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/validator.c | 12 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/validator.h | 26 |
15 files changed, 257 insertions, 167 deletions
diff --git a/usr.sbin/unbound/validator/autotrust.c b/usr.sbin/unbound/validator/autotrust.c index 232397c3106..a533733c7a6 100644 --- a/usr.sbin/unbound/validator/autotrust.c +++ b/usr.sbin/unbound/validator/autotrust.c @@ -430,6 +430,8 @@ find_add_tp(struct val_anchors* anchors, uint8_t* rr, size_t rr_len, } tp = autr_tp_create(anchors, rr, dname_len, sldns_wirerr_get_class(rr, rr_len, dname_len)); + if(!tp) + return NULL; lock_basic_lock(&tp->lock); return tp; } @@ -1062,7 +1064,7 @@ int autr_read_file(struct val_anchors* anchors, const char* nm) /** string for a trustanchor state */ static const char* -trustanchor_state2str(autr_state_t s) +trustanchor_state2str(autr_state_type s) { switch (s) { case AUTR_STATE_START: return " START "; @@ -1201,7 +1203,7 @@ void autr_write_file(struct module_env* env, struct trust_anchor* tp) if(fsync(fileno(out)) != 0) log_err("could not fsync(%s): %s", fname, strerror(errno)); #else - FlushFileBuffers((HANDLE)_fileno(out)); + FlushFileBuffers((HANDLE)_get_osfhandle(_fileno(out))); #endif if(fclose(out) != 0) { fatal_exit("could not complete write: %s: %s", @@ -1677,7 +1679,7 @@ reset_holddown(struct module_env* env, struct autr_ta* ta, int* changed) /** Set the state for this trust anchor */ static void set_trustanchor_state(struct module_env* env, struct autr_ta* ta, int* changed, - autr_state_t s) + autr_state_type s) { verbose_key(ta, VERB_ALGO, "update: %s to %s", trustanchor_state2str(ta->s), trustanchor_state2str(s)); @@ -1987,7 +1989,7 @@ calc_next_probe(struct module_env* env, time_t wait) static time_t wait_probe_time(struct val_anchors* anchors) { - rbnode_t* t = rbtree_first(&anchors->autr->probe); + rbnode_type* t = rbtree_first(&anchors->autr->probe); if(t != RBTREE_NULL) return ((struct trust_anchor*)t->key)->autr->next_probe_time; return 0; @@ -2326,6 +2328,7 @@ probe_anchor(struct module_env* env, struct trust_anchor* tp) qinfo.qname_len = tp->namelen; qinfo.qtype = LDNS_RR_TYPE_DNSKEY; qinfo.qclass = tp->dclass; + qinfo.local_alias = NULL; log_query_info(VERB_ALGO, "autotrust probe", &qinfo); verbose(VERB_ALGO, "retry probe set in %d seconds", (int)tp->autr->next_probe_time - (int)*env->now); @@ -2360,7 +2363,7 @@ static struct trust_anchor* todo_probe(struct module_env* env, time_t* next) { struct trust_anchor* tp; - rbnode_t* el; + rbnode_type* el; /* get first one */ lock_basic_lock(&env->anchors->lock); if( (el=rbtree_first(&env->anchors->autr->probe)) == RBTREE_NULL) { diff --git a/usr.sbin/unbound/validator/autotrust.h b/usr.sbin/unbound/validator/autotrust.h index 4e88ed32042..dbaf5126a0b 100644 --- a/usr.sbin/unbound/validator/autotrust.h +++ b/usr.sbin/unbound/validator/autotrust.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -48,6 +48,7 @@ struct trust_anchor; struct ub_packed_rrset_key; struct module_env; struct val_env; +struct sldns_buffer; /** Autotrust anchor states */ typedef enum { @@ -57,7 +58,7 @@ typedef enum { AUTR_STATE_MISSING = 3, AUTR_STATE_REVOKED = 4, AUTR_STATE_REMOVED = 5 -} autr_state_t; +} autr_state_type; /** * Autotrust metadata for one trust anchor key. @@ -66,11 +67,13 @@ struct autr_ta { /** next key */ struct autr_ta* next; /** the RR */ - ldns_rr* rr; + uint8_t* rr; + /** length of rr */ + size_t rr_len, dname_len; /** last update of key state (new pending count keeps date the same) */ time_t last_change; /** 5011 state */ - autr_state_t s; + autr_state_type s; /** pending count */ uint8_t pending_count; /** fresh TA was seen */ @@ -87,7 +90,7 @@ struct autr_point_data { /** file to store the trust point in. chrootdir already applied. */ char* file; /** rbtree node for probe sort, key is struct trust_anchor */ - rbnode_t pnode; + rbnode_type pnode; /** the keys */ struct autr_ta* keys; @@ -104,9 +107,9 @@ struct autr_point_data { time_t next_probe_time; /** when to query if !failed */ - uint32_t query_interval; + time_t query_interval; /** when to retry if failed */ - uint32_t retry_time; + time_t retry_time; /** * How many times did it fail. diagnostic only (has no effect). @@ -123,7 +126,7 @@ struct autr_point_data { struct autr_global_data { /** rbtree of autotrust anchors sorted by next probe time. * When time is equal, sorted by anchor class, name. */ - rbtree_t probe; + rbtree_type probe; }; /** @@ -151,7 +154,7 @@ size_t autr_get_num_anchors(struct val_anchors* anchors); * @return time of next probe (in seconds from now). * If 0, then there is no next probe anymore (trust points deleted). */ -uint32_t autr_probe_timer(struct module_env* env); +time_t autr_probe_timer(struct module_env* env); /** probe tree compare function */ int probetree_cmp(const void* x, const void* y); @@ -199,7 +202,7 @@ int autr_process_prime(struct module_env* env, struct val_env* ve, void autr_debug_print(struct val_anchors* anchors); /** callback for query answer to 5011 probe */ -void probe_answer_cb(void* arg, int rcode, ldns_buffer* buf, +void probe_answer_cb(void* arg, int rcode, struct sldns_buffer* buf, enum sec_status sec, char* errinf); #endif /* VALIDATOR_AUTOTRUST_H */ diff --git a/usr.sbin/unbound/validator/val_anchor.c b/usr.sbin/unbound/validator/val_anchor.c index 4d470b69227..2a7e0beeb6c 100644 --- a/usr.sbin/unbound/validator/val_anchor.c +++ b/usr.sbin/unbound/validator/val_anchor.c @@ -113,7 +113,7 @@ assembled_rrset_delete(struct ub_packed_rrset_key* pkey) /** destroy locks in tree and delete autotrust anchors */ static void -anchors_delfunc(rbnode_t* elem, void* ATTR_UNUSED(arg)) +anchors_delfunc(rbnode_type* elem, void* ATTR_UNUSED(arg)) { struct trust_anchor* ta = (struct trust_anchor*)elem; if(!ta) return; @@ -198,7 +198,7 @@ anchor_find(struct val_anchors* anchors, uint8_t* name, int namelabs, size_t namelen, uint16_t dclass) { struct trust_anchor key; - rbnode_t* n; + rbnode_type* n; if(!name) return NULL; key.node.key = &key; key.name = name; @@ -222,7 +222,7 @@ anchor_new_ta(struct val_anchors* anchors, uint8_t* name, int namelabs, size_t namelen, uint16_t dclass, int lockit) { #ifdef UNBOUND_DEBUG - rbnode_t* r; + rbnode_type* r; #endif struct trust_anchor* ta = (struct trust_anchor*)malloc( sizeof(struct trust_anchor)); @@ -990,7 +990,7 @@ anchors_assemble_rrsets(struct val_anchors* anchors) size_t nods, nokey; lock_basic_lock(&anchors->lock); ta=(struct trust_anchor*)rbtree_first(anchors->tree); - while((rbnode_t*)ta != RBTREE_NULL) { + while((rbnode_type*)ta != RBTREE_NULL) { next = (struct trust_anchor*)rbtree_next(&ta->node); lock_basic_lock(&ta->lock); if(ta->autr || (ta->numDS == 0 && ta->numDNSKEY == 0)) { @@ -1164,7 +1164,7 @@ anchors_lookup(struct val_anchors* anchors, { struct trust_anchor key; struct trust_anchor* result; - rbnode_t* res = NULL; + rbnode_type* res = NULL; key.node.key = &key; key.name = qname; key.namelabs = dname_count_labels(qname); diff --git a/usr.sbin/unbound/validator/val_anchor.h b/usr.sbin/unbound/validator/val_anchor.h index d2f3afc43f1..226165514c5 100644 --- a/usr.sbin/unbound/validator/val_anchor.h +++ b/usr.sbin/unbound/validator/val_anchor.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -43,12 +43,12 @@ #define VALIDATOR_VAL_ANCHOR_H #include "util/rbtree.h" #include "util/locks.h" -struct regional; struct trust_anchor; struct config_file; struct ub_packed_rrset_key; struct autr_point_data; struct autr_global_data; +struct sldns_buffer; /** * Trust anchor store. @@ -59,19 +59,14 @@ struct autr_global_data; */ struct val_anchors { /** lock on trees */ - lock_basic_t lock; - /** - * region where trust anchors are allocated. - * Autotrust anchors are malloced so they can be updated. - */ - struct regional* region; + lock_basic_type lock; /** * Anchors are store in this tree. Sort order is chosen, so that * dnames are in nsec-like order. A lookup on class, name will return * an exact match of the closest match, with the ancestor needed. * contents of type trust_anchor. */ - rbtree_t* tree; + rbtree_type* tree; /** The DLV trust anchor (if one is configured, else NULL) */ struct trust_anchor* dlv_anchor; /** Autotrust global data, anchors sorted by next probe time */ @@ -98,9 +93,9 @@ struct ta_key { */ struct trust_anchor { /** rbtree node, key is this structure */ - rbnode_t node; + rbnode_type node; /** lock on the entire anchor and its keys; for autotrust changes */ - lock_basic_t lock; + lock_basic_type lock; /** name of this trust anchor */ uint8_t* name; /** length of name */ @@ -111,7 +106,6 @@ struct trust_anchor { struct trust_anchor* parent; /** * List of DS or DNSKEY rrs that form the trust anchor. - * It is allocated in the region. */ struct ta_key* keylist; /** Autotrust anchor point data, or NULL */ @@ -191,7 +185,7 @@ struct trust_anchor* anchor_find(struct val_anchors* anchors, * @return NULL on error. */ struct trust_anchor* anchor_store_str(struct val_anchors* anchors, - ldns_buffer* buffer, const char* str); + struct sldns_buffer* buffer, const char* str); /** * Get memory in use by the trust anchor storage @@ -203,4 +197,23 @@ size_t anchors_get_mem(struct val_anchors* anchors); /** compare two trust anchors */ int anchor_cmp(const void* k1, const void* k2); +/** + * Add insecure point trust anchor. For external use (locks and init_parents) + * @param anchors: anchor storage. + * @param c: class. + * @param nm: name of insecure trust point. + * @return false on alloc failure. + */ +int anchors_add_insecure(struct val_anchors* anchors, uint16_t c, uint8_t* nm); + +/** + * Delete insecure point trust anchor. Does not remove if no such point. + * For external use (locks and init_parents) + * @param anchors: anchor storage. + * @param c: class. + * @param nm: name of insecure trust point. + */ +void anchors_delete_insecure(struct val_anchors* anchors, uint16_t c, + uint8_t* nm); + #endif /* VALIDATOR_VAL_ANCHOR_H */ diff --git a/usr.sbin/unbound/validator/val_neg.c b/usr.sbin/unbound/validator/val_neg.c index a5e687fdc41..fe57ac2c442 100644 --- a/usr.sbin/unbound/validator/val_neg.c +++ b/usr.sbin/unbound/validator/val_neg.c @@ -111,7 +111,7 @@ size_t val_neg_get_mem(struct val_neg_cache* neg) /** clear datas on cache deletion */ static void -neg_clear_datas(rbnode_t* n, void* ATTR_UNUSED(arg)) +neg_clear_datas(rbnode_type* n, void* ATTR_UNUSED(arg)) { struct val_neg_data* d = (struct val_neg_data*)n; free(d->name); @@ -120,7 +120,7 @@ neg_clear_datas(rbnode_t* n, void* ATTR_UNUSED(arg)) /** clear zones on cache deletion */ static void -neg_clear_zones(rbnode_t* n, void* ATTR_UNUSED(arg)) +neg_clear_zones(rbnode_type* n, void* ATTR_UNUSED(arg)) { struct val_neg_zone* z = (struct val_neg_zone*)n; /* delete all the rrset entries in the tree */ @@ -371,7 +371,7 @@ static struct val_neg_zone* neg_closest_zone_parent(struct val_neg_cache* neg, { struct val_neg_zone key; struct val_neg_zone* result; - rbnode_t* res = NULL; + rbnode_type* res = NULL; key.node.key = &key; key.name = nm; key.len = nm_len; @@ -411,7 +411,7 @@ static struct val_neg_data* neg_closest_data_parent( { struct val_neg_data key; struct val_neg_data* result; - rbnode_t* res = NULL; + rbnode_type* res = NULL; key.node.key = &key; key.name = nm; key.len = nm_len; @@ -677,7 +677,7 @@ static void wipeout(struct val_neg_cache* neg, struct val_neg_zone* zone, uint8_t* end; size_t end_len; int end_labs, m; - rbnode_t* walk, *next; + rbnode_type* walk, *next; struct val_neg_data* cur; uint8_t buf[257]; /* get endpoint */ @@ -911,7 +911,7 @@ static int neg_closest_data(struct val_neg_zone* zone, uint8_t* qname, size_t len, int labs, struct val_neg_data** data) { struct val_neg_data key; - rbnode_t* r; + rbnode_type* r; key.node.key = &key; key.name = qname; key.len = len; @@ -1007,6 +1007,7 @@ int val_neg_dlvlookup(struct val_neg_cache* neg, uint8_t* qname, size_t len, qinfo.qname = qname; qinfo.qtype = LDNS_RR_TYPE_DLV; qinfo.qclass = qclass; + qinfo.local_alias = NULL; if(!nsec_proves_nodata(nsec, &qinfo, &wc) && !val_nsec_proves_name_error(nsec, qname)) { /* the NSEC is not a denial for the DLV */ diff --git a/usr.sbin/unbound/validator/val_neg.h b/usr.sbin/unbound/validator/val_neg.h index bf3a2471c78..6ae71306c37 100644 --- a/usr.sbin/unbound/validator/val_neg.h +++ b/usr.sbin/unbound/validator/val_neg.h @@ -67,9 +67,9 @@ struct ub_packed_rrset_key; struct val_neg_cache { /** the big lock on the negative cache. Because we use a rbtree * for the data (quick lookup), we need a big lock */ - lock_basic_t lock; + lock_basic_type lock; /** The zone rbtree. contents sorted canonical, type val_neg_zone */ - rbtree_t tree; + rbtree_type tree; /** the first in linked list of LRU of val_neg_data */ struct val_neg_data* first; /** last in lru (least recently used element) */ @@ -87,7 +87,7 @@ struct val_neg_cache { */ struct val_neg_zone { /** rbtree node element, key is this struct: the name, class */ - rbnode_t node; + rbnode_type node; /** name; the key */ uint8_t* name; /** length of name */ @@ -114,7 +114,7 @@ struct val_neg_zone { /** tree of NSEC data for this zone, sorted canonical * by NSEC owner name */ - rbtree_t tree; + rbtree_type tree; /** class of node; host order */ uint16_t dclass; @@ -135,7 +135,7 @@ struct val_neg_zone { */ struct val_neg_data { /** rbtree node element, key is this struct: the name */ - rbnode_t node; + rbnode_type node; /** name; the key */ uint8_t* name; /** length of name */ diff --git a/usr.sbin/unbound/validator/val_nsec.c b/usr.sbin/unbound/validator/val_nsec.c index f104a347c78..1e4f440ffc0 100644 --- a/usr.sbin/unbound/validator/val_nsec.c +++ b/usr.sbin/unbound/validator/val_nsec.c @@ -343,7 +343,7 @@ int nsec_proves_nodata(struct ub_packed_rrset_key* nsec, } else { /* See if the next owner name covers a wildcard * empty non-terminal. */ - while (dname_strict_subdomain_c(nm, nsec->rk.dname)) { + while (dname_canonical_compare(nsec->rk.dname, nm) < 0) { /* wildcard does not apply if qname below * the name that exists under the '*' */ if (dname_subdomain_c(qinfo->qname, nm)) diff --git a/usr.sbin/unbound/validator/val_nsec3.c b/usr.sbin/unbound/validator/val_nsec3.c index 22867d170d7..4d978372aaa 100644 --- a/usr.sbin/unbound/validator/val_nsec3.c +++ b/usr.sbin/unbound/validator/val_nsec3.c @@ -623,14 +623,14 @@ nsec3_calc_b32(struct regional* region, sldns_buffer* buf, } int -nsec3_hash_name(rbtree_t* table, struct regional* region, sldns_buffer* buf, +nsec3_hash_name(rbtree_type* table, struct regional* region, sldns_buffer* buf, struct ub_packed_rrset_key* nsec3, int rr, uint8_t* dname, size_t dname_len, struct nsec3_cached_hash** hash) { struct nsec3_cached_hash* c; struct nsec3_cached_hash looki; #ifdef UNBOUND_DEBUG - rbnode_t* n; + rbnode_type* n; #endif int r; looki.node.key = &looki; @@ -730,7 +730,7 @@ nsec3_hash_matches_owner(struct nsec3_filter* flt, */ static int find_matching_nsec3(struct module_env* env, struct nsec3_filter* flt, - rbtree_t* ct, uint8_t* nm, size_t nmlen, + rbtree_type* ct, uint8_t* nm, size_t nmlen, struct ub_packed_rrset_key** rrset, int* rr) { size_t i_rs; @@ -823,7 +823,7 @@ nsec3_covers(uint8_t* zone, struct nsec3_cached_hash* hash, */ static int find_covering_nsec3(struct module_env* env, struct nsec3_filter* flt, - rbtree_t* ct, uint8_t* nm, size_t nmlen, + rbtree_type* ct, uint8_t* nm, size_t nmlen, struct ub_packed_rrset_key** rrset, int* rr) { size_t i_rs; @@ -869,7 +869,7 @@ find_covering_nsec3(struct module_env* env, struct nsec3_filter* flt, */ static int nsec3_find_closest_encloser(struct module_env* env, struct nsec3_filter* flt, - rbtree_t* ct, struct query_info* qinfo, struct ce_response* ce) + rbtree_type* ct, struct query_info* qinfo, struct ce_response* ce) { uint8_t* nm = qinfo->qname; size_t nmlen = qinfo->qname_len; @@ -936,7 +936,7 @@ next_closer(uint8_t* qname, size_t qnamelen, uint8_t* ce, */ static enum sec_status nsec3_prove_closest_encloser(struct module_env* env, struct nsec3_filter* flt, - rbtree_t* ct, struct query_info* qinfo, int prove_does_not_exist, + rbtree_type* ct, struct query_info* qinfo, int prove_does_not_exist, struct ce_response* ce) { uint8_t* nc; @@ -1016,7 +1016,7 @@ nsec3_ce_wildcard(struct regional* region, uint8_t* ce, size_t celen, /** Do the name error proof */ static enum sec_status nsec3_do_prove_nameerror(struct module_env* env, struct nsec3_filter* flt, - rbtree_t* ct, struct query_info* qinfo) + rbtree_type* ct, struct query_info* qinfo) { struct ce_response ce; uint8_t* wc; @@ -1062,7 +1062,7 @@ nsec3_prove_nameerror(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key** list, size_t num, struct query_info* qinfo, struct key_entry_key* kkey) { - rbtree_t ct; + rbtree_type ct; struct nsec3_filter flt; if(!list || num == 0 || !kkey || !key_entry_isgood(kkey)) @@ -1086,7 +1086,7 @@ nsec3_prove_nameerror(struct module_env* env, struct val_env* ve, /** Do the nodata proof */ static enum sec_status nsec3_do_prove_nodata(struct module_env* env, struct nsec3_filter* flt, - rbtree_t* ct, struct query_info* qinfo) + rbtree_type* ct, struct query_info* qinfo) { struct ce_response ce; uint8_t* wc; @@ -1180,7 +1180,7 @@ nsec3_do_prove_nodata(struct module_env* env, struct nsec3_filter* flt, nsec3_has_type(rrset, rr, LDNS_RR_TYPE_NS) && !nsec3_has_type(rrset, rr, LDNS_RR_TYPE_SOA)) { verbose(VERB_ALGO, "nsec3 nodata proof: matching " - "wilcard is a delegation, bogus"); + "wildcard is a delegation, bogus"); return sec_status_bogus; } /* everything is peachy keen, except for optout spans */ @@ -1221,7 +1221,7 @@ nsec3_prove_nodata(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key** list, size_t num, struct query_info* qinfo, struct key_entry_key* kkey) { - rbtree_t ct; + rbtree_type ct; struct nsec3_filter flt; if(!list || num == 0 || !kkey || !key_entry_isgood(kkey)) @@ -1240,7 +1240,7 @@ nsec3_prove_wildcard(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key** list, size_t num, struct query_info* qinfo, struct key_entry_key* kkey, uint8_t* wc) { - rbtree_t ct; + rbtree_type ct; struct nsec3_filter flt; struct ce_response ce; uint8_t* nc; @@ -1314,7 +1314,7 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key** list, size_t num, struct query_info* qinfo, struct key_entry_key* kkey, char** reason) { - rbtree_t ct; + rbtree_type ct; struct nsec3_filter flt; struct ce_response ce; struct ub_packed_rrset_key* rrset; @@ -1403,7 +1403,7 @@ nsec3_prove_nxornodata(struct module_env* env, struct val_env* ve, struct query_info* qinfo, struct key_entry_key* kkey, int* nodata) { enum sec_status sec, secnx; - rbtree_t ct; + rbtree_type ct; struct nsec3_filter flt; *nodata = 0; diff --git a/usr.sbin/unbound/validator/val_nsec3.h b/usr.sbin/unbound/validator/val_nsec3.h index 69ba78d8323..27e9f9eac19 100644 --- a/usr.sbin/unbound/validator/val_nsec3.h +++ b/usr.sbin/unbound/validator/val_nsec3.h @@ -224,7 +224,7 @@ nsec3_prove_nxornodata(struct module_env* env, struct val_env* ve, */ struct nsec3_cached_hash { /** rbtree node, key is this structure */ - rbnode_t node; + rbnode_type node; /** where are the parameters for conversion, in this rrset data */ struct ub_packed_rrset_key* nsec3; /** where are the parameters for conversion, this RR number in data */ @@ -271,7 +271,7 @@ int nsec3_hash_cmp(const void* c1, const void* c2); * 0 on a malloc failure. * -1 if the NSEC3 rr was badly formatted (i.e. formerr). */ -int nsec3_hash_name(rbtree_t* table, struct regional* region, +int nsec3_hash_name(rbtree_type* table, struct regional* region, struct sldns_buffer* buf, struct ub_packed_rrset_key* nsec3, int rr, uint8_t* dname, size_t dname_len, struct nsec3_cached_hash** hash); diff --git a/usr.sbin/unbound/validator/val_secalgo.c b/usr.sbin/unbound/validator/val_secalgo.c index 11c8cd16e8f..302820fc2f9 100644 --- a/usr.sbin/unbound/validator/val_secalgo.c +++ b/usr.sbin/unbound/validator/val_secalgo.c @@ -72,6 +72,9 @@ #include <openssl/engine.h> #endif +/** fake DSA support for unit tests */ +int fake_dsa = 0; + /* return size of digest if supported, or 0 otherwise */ size_t nsec3_hash_algo_size_supported(int id) @@ -192,9 +195,13 @@ dnskey_algo_id_is_supported(int id) case LDNS_RSAMD5: /* RFC 6725 deprecates RSAMD5 */ return 0; -#ifdef USE_DSA case LDNS_DSA: case LDNS_DSA_NSEC3: +#ifdef USE_DSA + return 1; +#else + if(fake_dsa) return 1; + return 0; #endif case LDNS_RSASHA1: case LDNS_RSASHA1_NSEC3: @@ -264,8 +271,12 @@ setup_dsa_sig(unsigned char** sig, unsigned int* len) dsasig = DSA_SIG_new(); if(!dsasig) return 0; +#ifdef HAVE_DSA_SIG_SET0 + if(!DSA_SIG_set0(dsasig, R, S)) return 0; +#else dsasig->r = R; dsasig->s = S; +#endif *sig = NULL; newlen = i2d_DSA_SIG(dsasig, sig); if(newlen < 0) { @@ -350,6 +361,23 @@ i * the '44' is the total remaining length. } #endif /* USE_ECDSA */ +#ifdef USE_ECDSA_EVP_WORKAROUND +static EVP_MD ecdsa_evp_256_md; +static EVP_MD ecdsa_evp_384_md; +void ecdsa_evp_workaround_init(void) +{ + /* openssl before 1.0.0 fixes RSA with the SHA256 + * hash in EVP. We create one for ecdsa_sha256 */ + ecdsa_evp_256_md = *EVP_sha256(); + ecdsa_evp_256_md.required_pkey_type[0] = EVP_PKEY_EC; + ecdsa_evp_256_md.verify = (void*)ECDSA_verify; + + ecdsa_evp_384_md = *EVP_sha384(); + ecdsa_evp_384_md.required_pkey_type[0] = EVP_PKEY_EC; + ecdsa_evp_384_md.verify = (void*)ECDSA_verify; +} +#endif /* USE_ECDSA_EVP_WORKAROUND */ + /** * Setup key and digest for verification. Adjust sig if necessary. * @@ -389,7 +417,11 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, "EVP_PKEY_assign_DSA failed"); return 0; } +#ifdef HAVE_EVP_DSS1 *digest_type = EVP_dss1(); +#else + *digest_type = EVP_sha1(); +#endif break; #endif /* USE_DSA */ @@ -478,20 +510,7 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, return 0; } #ifdef USE_ECDSA_EVP_WORKAROUND - /* openssl before 1.0.0 fixes RSA with the SHA256 - * hash in EVP. We create one for ecdsa_sha256 */ - { - static int md_ecdsa_256_done = 0; - static EVP_MD md; - if(!md_ecdsa_256_done) { - EVP_MD m = *EVP_sha256(); - md_ecdsa_256_done = 1; - m.required_pkey_type[0] = (*evp_key)->type; - m.verify = (void*)ECDSA_verify; - md = m; - } - *digest_type = &md; - } + *digest_type = &ecdsa_evp_256_md; #else *digest_type = EVP_sha256(); #endif @@ -505,20 +524,7 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, return 0; } #ifdef USE_ECDSA_EVP_WORKAROUND - /* openssl before 1.0.0 fixes RSA with the SHA384 - * hash in EVP. We create one for ecdsa_sha384 */ - { - static int md_ecdsa_384_done = 0; - static EVP_MD md; - if(!md_ecdsa_384_done) { - EVP_MD m = *EVP_sha384(); - md_ecdsa_384_done = 1; - m.required_pkey_type[0] = (*evp_key)->type; - m.verify = (void*)ECDSA_verify; - md = m; - } - *digest_type = &md; - } + *digest_type = &ecdsa_evp_384_md; #else *digest_type = EVP_sha384(); #endif @@ -554,6 +560,11 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, EVP_MD_CTX* ctx; int res, dofree = 0, docrypto_free = 0; EVP_PKEY *evp_key = NULL; + +#ifndef USE_DSA + if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) && fake_dsa) + return sec_status_secure; +#endif if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) { verbose(VERB_QUERY, "verify: failed to setup key"); @@ -601,7 +612,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, log_err("EVP_MD_CTX_new: malloc failure"); EVP_PKEY_free(evp_key); if(dofree) free(sigblock); - else if(docrypto_free) CRYPTO_free(sigblock); + else if(docrypto_free) OPENSSL_free(sigblock); return sec_status_unchecked; } if(EVP_VerifyInit(ctx, digest_type) == 0) { @@ -609,7 +620,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, EVP_MD_CTX_destroy(ctx); EVP_PKEY_free(evp_key); if(dofree) free(sigblock); - else if(docrypto_free) CRYPTO_free(sigblock); + else if(docrypto_free) OPENSSL_free(sigblock); return sec_status_unchecked; } if(EVP_VerifyUpdate(ctx, (unsigned char*)sldns_buffer_begin(buf), @@ -618,7 +629,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, EVP_MD_CTX_destroy(ctx); EVP_PKEY_free(evp_key); if(dofree) free(sigblock); - else if(docrypto_free) CRYPTO_free(sigblock); + else if(docrypto_free) OPENSSL_free(sigblock); return sec_status_unchecked; } @@ -632,7 +643,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, EVP_PKEY_free(evp_key); if(dofree) free(sigblock); - else if(docrypto_free) CRYPTO_free(sigblock); + else if(docrypto_free) OPENSSL_free(sigblock); if(res == 1) { return sec_status_secure; @@ -1207,6 +1218,9 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, #include "macros.h" #include "rsa.h" #include "dsa.h" +#ifdef HAVE_NETTLE_DSA_COMPAT_H +#include "dsa-compat.h" +#endif #include "asn1.h" #ifdef USE_ECDSA #include "ecdsa.h" @@ -1367,12 +1381,13 @@ dnskey_algo_id_is_supported(int id) } } +#ifdef USE_DSA static char * _verify_nettle_dsa(sldns_buffer* buf, unsigned char* sigblock, unsigned int sigblock_len, unsigned char* key, unsigned int keylen) { uint8_t digest[SHA1_DIGEST_SIZE]; - uint8_t key_t; + uint8_t key_t_value; int res = 0; size_t offset; struct dsa_public_key pubkey; @@ -1411,8 +1426,8 @@ _verify_nettle_dsa(sldns_buffer* buf, unsigned char* sigblock, } /* Validate T values constraints - RFC 2536 sec. 2 & sec. 3 */ - key_t = key[0]; - if (key_t > 8) { + key_t_value = key[0]; + if (key_t_value > 8) { return "invalid T value in DSA pubkey"; } @@ -1423,9 +1438,9 @@ _verify_nettle_dsa(sldns_buffer* buf, unsigned char* sigblock, expected_len = 1 + /* T */ 20 + /* Q */ - (64 + key_t*8) + /* P */ - (64 + key_t*8) + /* G */ - (64 + key_t*8); /* Y */ + (64 + key_t_value*8) + /* P */ + (64 + key_t_value*8) + /* G */ + (64 + key_t_value*8); /* Y */ if (keylen != expected_len ) { return "invalid DSA pubkey length"; } @@ -1435,11 +1450,11 @@ _verify_nettle_dsa(sldns_buffer* buf, unsigned char* sigblock, offset = 1; nettle_mpz_set_str_256_u(pubkey.q, 20, key+offset); offset += 20; - nettle_mpz_set_str_256_u(pubkey.p, (64 + key_t*8), key+offset); - offset += (64 + key_t*8); - nettle_mpz_set_str_256_u(pubkey.g, (64 + key_t*8), key+offset); - offset += (64 + key_t*8); - nettle_mpz_set_str_256_u(pubkey.y, (64 + key_t*8), key+offset); + nettle_mpz_set_str_256_u(pubkey.p, (64 + key_t_value*8), key+offset); + offset += (64 + key_t_value*8); + nettle_mpz_set_str_256_u(pubkey.g, (64 + key_t_value*8), key+offset); + offset += (64 + key_t_value*8); + nettle_mpz_set_str_256_u(pubkey.y, (64 + key_t_value*8), key+offset); /* Digest content of "buf" and verify its DSA signature in "sigblock"*/ res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), @@ -1454,6 +1469,7 @@ _verify_nettle_dsa(sldns_buffer* buf, unsigned char* sigblock, else return NULL; } +#endif /* USE_DSA */ static char * _verify_nettle_rsa(sldns_buffer* buf, unsigned int digest_size, char* sigblock, diff --git a/usr.sbin/unbound/validator/val_sigcrypt.c b/usr.sbin/unbound/validator/val_sigcrypt.c index 1dd07b420bd..b0b2e970ff2 100644 --- a/usr.sbin/unbound/validator/val_sigcrypt.c +++ b/usr.sbin/unbound/validator/val_sigcrypt.c @@ -483,7 +483,7 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve, { enum sec_status sec; size_t i, num; - rbtree_t* sortree = NULL; + rbtree_type* sortree = NULL; /* make sure that for all DNSKEY algorithms there are valid sigs */ struct algo_needs needs; int alg; @@ -551,7 +551,7 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve, { enum sec_status sec; size_t i, num, numchecked = 0; - rbtree_t* sortree = NULL; + rbtree_type* sortree = NULL; int buf_canon = 0; uint16_t tag = dnskey_calc_keytag(dnskey, dnskey_idx); int algo = dnskey_get_algo(dnskey, dnskey_idx); @@ -585,7 +585,7 @@ enum sec_status dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve, time_t now, struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, size_t sig_idx, - struct rbtree_t** sortree, char** reason) + struct rbtree_type** sortree, char** reason) { /* find matching keys and check them */ enum sec_status sec = sec_status_bogus; @@ -627,7 +627,7 @@ dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve, */ struct canon_rr { /** rbtree node, key is this structure */ - rbnode_t node; + rbnode_type node; /** rrset the RR is in */ struct ub_packed_rrset_key* rrset; /** which RR in the rrset */ @@ -885,7 +885,7 @@ canonical_tree_compare(const void* k1, const void* k2) */ static void canonical_sort(struct ub_packed_rrset_key* rrset, struct packed_rrset_data* d, - rbtree_t* sortree, struct canon_rr* rrs) + rbtree_type* sortree, struct canon_rr* rrs) { size_t i; /* insert into rbtree to sort and detect duplicates */ @@ -1043,7 +1043,7 @@ canonicalize_rdata(sldns_buffer* buf, struct ub_packed_rrset_key* rrset, int rrset_canonical_equal(struct regional* region, struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2) { - struct rbtree_t sortree1, sortree2; + struct rbtree_type sortree1, sortree2; struct canon_rr *rrs1, *rrs2, *p1, *p2; struct packed_rrset_data* d1=(struct packed_rrset_data*)k1->entry.data; struct packed_rrset_data* d2=(struct packed_rrset_data*)k2->entry.data; @@ -1120,7 +1120,7 @@ int rrset_canonical_equal(struct regional* region, static int rrset_canonical(struct regional* region, sldns_buffer* buf, struct ub_packed_rrset_key* k, uint8_t* sig, size_t siglen, - struct rbtree_t** sortree) + struct rbtree_type** sortree) { struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data; uint8_t* can_owner = NULL; @@ -1129,8 +1129,8 @@ rrset_canonical(struct regional* region, sldns_buffer* buf, struct canon_rr* rrs; if(!*sortree) { - *sortree = (struct rbtree_t*)regional_alloc(region, - sizeof(rbtree_t)); + *sortree = (struct rbtree_type*)regional_alloc(region, + sizeof(rbtree_type)); if(!*sortree) return 0; if(d->count > RR_COUNT_MAX) @@ -1283,15 +1283,23 @@ adjust_ttl(struct val_env* ve, uint32_t unow, /* so now: * d->ttl: rrset ttl read from message or cache. May be reduced * origttl: original TTL from signature, authoritative TTL max. + * MIN_TTL: minimum TTL from config. * expittl: TTL until the signature expires. * - * Use the smallest of these. + * Use the smallest of these, but don't let origttl set the TTL + * below the minimum. */ - if(d->ttl > (time_t)origttl) { - verbose(VERB_QUERY, "rrset TTL larger than original TTL," - " adjusting TTL downwards"); + if(MIN_TTL > (time_t)origttl && d->ttl > MIN_TTL) { + verbose(VERB_QUERY, "rrset TTL larger than original and minimum" + " TTL, adjusting TTL downwards to minimum ttl"); + d->ttl = MIN_TTL; + } + else if(MIN_TTL <= origttl && d->ttl > (time_t)origttl) { + verbose(VERB_QUERY, "rrset TTL larger than original TTL, " + "adjusting TTL downwards to original ttl"); d->ttl = origttl; } + if(expittl > 0 && d->ttl > (time_t)expittl) { verbose(VERB_ALGO, "rrset TTL larger than sig expiration ttl," " adjusting TTL downwards"); @@ -1304,7 +1312,7 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf, struct val_env* ve, time_t now, struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, size_t dnskey_idx, size_t sig_idx, - struct rbtree_t** sortree, int* buf_canon, char** reason) + struct rbtree_type** sortree, int* buf_canon, char** reason) { enum sec_status sec; uint8_t* sig; /* RRSIG rdata */ diff --git a/usr.sbin/unbound/validator/val_sigcrypt.h b/usr.sbin/unbound/validator/val_sigcrypt.h index c220b0083ac..5a975acff4d 100644 --- a/usr.sbin/unbound/validator/val_sigcrypt.h +++ b/usr.sbin/unbound/validator/val_sigcrypt.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -47,8 +47,9 @@ struct val_env; struct module_env; struct ub_packed_rrset_key; -struct rbtree_t; +struct rbtree_type; struct regional; +struct sldns_buffer; /** number of entries in algorithm needs array */ #define ALGO_NEEDS_MAX 256 @@ -274,9 +275,9 @@ enum sec_status dnskey_verify_rrset(struct module_env* env, * or unchecked on error. */ enum sec_status dnskeyset_verify_rrset_sig(struct module_env* env, - struct val_env* ve, uint32_t now, struct ub_packed_rrset_key* rrset, + struct val_env* ve, time_t now, struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, size_t sig_idx, - struct rbtree_t** sortree, char** reason); + struct rbtree_type** sortree, char** reason); /** * verify rrset, with specific dnskey(from set), for a specific rrsig @@ -298,14 +299,25 @@ enum sec_status dnskeyset_verify_rrset_sig(struct module_env* env, * bogus if it did not validate. */ enum sec_status dnskey_verify_rrset_sig(struct regional* region, - ldns_buffer* buf, struct val_env* ve, uint32_t now, + struct sldns_buffer* buf, struct val_env* ve, time_t now, struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, size_t dnskey_idx, size_t sig_idx, - struct rbtree_t** sortree, int* buf_canon, char** reason); + struct rbtree_type** sortree, int* buf_canon, char** reason); /** * canonical compare for two tree entries */ int canonical_tree_compare(const void* k1, const void* k2); +/** + * Compare two rrsets and see if they are the same, canonicalised. + * The rrsets are not altered. + * @param region: temporary region. + * @param k1: rrset1 + * @param k2: rrset2 + * @return true if equal. + */ +int rrset_canonical_equal(struct regional* region, + struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2); + #endif /* VALIDATOR_VAL_SIGCRYPT_H */ diff --git a/usr.sbin/unbound/validator/val_utils.c b/usr.sbin/unbound/validator/val_utils.c index 94f00a7f7ee..da8066aad7e 100644 --- a/usr.sbin/unbound/validator/val_utils.c +++ b/usr.sbin/unbound/validator/val_utils.c @@ -219,7 +219,7 @@ val_find_signer(enum val_classification subtype, struct query_info* qinf, { size_t i; - if(subtype == VAL_CLASS_POSITIVE || subtype == VAL_CLASS_ANY) { + if(subtype == VAL_CLASS_POSITIVE) { /* check for the answer rrset */ for(i=skip; i<rep->an_numrrsets; i++) { if(query_dname_compare(qinf->qname, @@ -271,6 +271,29 @@ val_find_signer(enum val_classification subtype, struct query_info* qinf, signer_name, signer_len, &matchcount); } } + } else if(subtype == VAL_CLASS_ANY) { + /* check for one of the answer rrset that has signatures, + * or potentially a DNAME is in use with a different qname */ + for(i=skip; i<rep->an_numrrsets; i++) { + if(query_dname_compare(qinf->qname, + rep->rrsets[i]->rk.dname) == 0) { + val_find_rrset_signer(rep->rrsets[i], + signer_name, signer_len); + if(*signer_name) + return; + } + } + /* no answer RRSIGs with qname, try a DNAME */ + if(skip < rep->an_numrrsets && + ntohs(rep->rrsets[skip]->rk.type) == + LDNS_RR_TYPE_DNAME) { + val_find_rrset_signer(rep->rrsets[skip], + signer_name, signer_len); + if(*signer_name) + return; + } + *signer_name = NULL; + *signer_len = 0; } else if(subtype == VAL_CLASS_REFERRAL) { /* find keys for the item at skip */ if(skip < rep->rrset_count) { @@ -1115,6 +1138,7 @@ val_find_DS(struct module_env* env, uint8_t* nm, size_t nmlen, uint16_t c, qinfo.qname_len = nmlen; qinfo.qtype = LDNS_RR_TYPE_DS; qinfo.qclass = c; + qinfo.local_alias = NULL; /* do not add SOA to reply message, it is going to be used internal */ msg = val_neg_getmsg(env->neg_cache, &qinfo, region, env->rrset_cache, env->scratch_buffer, *env->now, 0, topname); diff --git a/usr.sbin/unbound/validator/validator.c b/usr.sbin/unbound/validator/validator.c index db4383bedcd..676dcdfe4d8 100644 --- a/usr.sbin/unbound/validator/validator.c +++ b/usr.sbin/unbound/validator/validator.c @@ -156,6 +156,9 @@ val_apply_cfg(struct module_env* env, struct val_env* val_env, return 1; } +#ifdef USE_ECDSA_EVP_WORKAROUND +void ecdsa_evp_workaround_init(void); +#endif int val_init(struct module_env* env, int id) { @@ -171,10 +174,14 @@ val_init(struct module_env* env, int id) lock_basic_init(&val_env->bogus_lock); lock_protect(&val_env->bogus_lock, &val_env->num_rrset_bogus, sizeof(val_env->num_rrset_bogus)); +#ifdef USE_ECDSA_EVP_WORKAROUND + ecdsa_evp_workaround_init(); +#endif if(!val_apply_cfg(env, val_env, env->cfg)) { log_err("validator: could not apply configuration settings."); return 0; } + return 1; } @@ -371,6 +378,7 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name, ask.qname_len = namelen; ask.qtype = qtype; ask.qclass = qclass; + ask.local_alias = NULL; log_query_info(VERB_ALGO, "generate request", &ask); fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); /* enable valrec flag to avoid recursion to the same validation @@ -2081,7 +2089,7 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq, } /* store results in cache */ - if(qstate->query_flags&BIT_RD) { + if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) { /* if secure, this will override cache anyway, no need * to check if from parentNS */ if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo, @@ -2274,6 +2282,7 @@ val_operate(struct module_qstate* qstate, enum module_ev event, int id, (void)outbound; if(event == module_event_new || (event == module_event_pass && vq == NULL)) { + /* pass request to next module, to get it */ verbose(VERB_ALGO, "validator: pass to next module"); qstate->ext_state[id] = module_wait_module; @@ -2282,6 +2291,7 @@ val_operate(struct module_qstate* qstate, enum module_ev event, int id, if(event == module_event_moddone) { /* check if validation is needed */ verbose(VERB_ALGO, "validator: nextmodule returned"); + if(!needs_validation(qstate, qstate->return_rcode, qstate->return_msg)) { /* no need to validate this */ diff --git a/usr.sbin/unbound/validator/validator.h b/usr.sbin/unbound/validator/validator.h index 18e905efcd2..23d3072427a 100644 --- a/usr.sbin/unbound/validator/validator.h +++ b/usr.sbin/unbound/validator/validator.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -56,13 +56,13 @@ struct config_strlist; * will be primed no more often than this interval. Used when harden- * dnssec-stripped is off and the trust anchor fails. */ -#define NULL_KEY_TTL 900 /* seconds */ +#define NULL_KEY_TTL 60 /* seconds */ /** * TTL for bogus key entries. When a DS or DNSKEY fails in the chain of * trust the entire zone for that name is blacked out for this TTL. */ -#define BOGUS_KEY_TTL 900 /* seconds */ +#define BOGUS_KEY_TTL 60 /* seconds */ /** max number of query restarts, number of IPs to probe */ #define VAL_MAX_RESTART_COUNT 5 @@ -126,7 +126,7 @@ struct val_env { size_t* nsec3_maxiter; /** lock on bogus counter */ - lock_basic_t bogus_lock; + lock_basic_type bogus_lock; /** number of times rrsets marked bogus */ size_t num_rrset_bogus; }; |