summaryrefslogtreecommitdiff
path: root/usr.sbin/unbound/validator
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/unbound/validator')
-rw-r--r--usr.sbin/unbound/validator/autotrust.c13
-rw-r--r--usr.sbin/unbound/validator/autotrust.h41
-rw-r--r--usr.sbin/unbound/validator/val_anchor.c10
-rw-r--r--usr.sbin/unbound/validator/val_anchor.h57
-rw-r--r--usr.sbin/unbound/validator/val_neg.c13
-rw-r--r--usr.sbin/unbound/validator/val_neg.h10
-rw-r--r--usr.sbin/unbound/validator/val_nsec.c2
-rw-r--r--usr.sbin/unbound/validator/val_nsec3.c28
-rw-r--r--usr.sbin/unbound/validator/val_nsec3.h4
-rw-r--r--usr.sbin/unbound/validator/val_secalgo.c104
-rw-r--r--usr.sbin/unbound/validator/val_sigcrypt.c36
-rw-r--r--usr.sbin/unbound/validator/val_sigcrypt.h42
-rw-r--r--usr.sbin/unbound/validator/val_utils.c26
-rw-r--r--usr.sbin/unbound/validator/validator.c12
-rw-r--r--usr.sbin/unbound/validator/validator.h26
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;
};