autotrust.c File Reference

Contains autotrust implementation. More...

#include "config.h"
#include "validator/autotrust.h"
#include "validator/val_anchor.h"
#include "validator/val_utils.h"
#include "validator/val_sigcrypt.h"
#include "util/data/dname.h"
#include "util/data/packed_rrset.h"
#include "util/log.h"
#include "util/module.h"
#include "util/net_help.h"
#include "util/config_file.h"
#include "util/regional.h"
#include "util/random.h"
#include "util/data/msgparse.h"
#include "services/mesh.h"
#include "services/cache/rrset.h"
#include "validator/val_kcache.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"
#include "sldns/str2wire.h"
#include "sldns/keyraw.h"
#include "sldns/rrdef.h"
#include <stdarg.h>
#include <ctype.h>

Macros

#define MIN_PENDINGCOUNT   2
 number of times a key must be seen before it can become valid
 

Functions

static void do_revoked (struct module_env *env, struct autr_ta *anchor, int *c)
 Event: Revoked.
 
struct autr_global_dataautr_global_create (void)
 Create new global 5011 data structure. More...
 
void autr_global_delete (struct autr_global_data *global)
 Delete global 5011 data structure. More...
 
int probetree_cmp (const void *x, const void *y)
 probe tree compare function
 
size_t autr_get_num_anchors (struct val_anchors *anchors)
 See if autotrust anchors are configured and how many. More...
 
static int position_in_string (char *str, const char *sub)
 Position in string.
 
static void verbose_key (struct autr_ta *ta, enum verbosity_value level, const char *format,...) ATTR_FORMAT(printf
 Debug routine to print pretty key information. More...
 
static int parse_comments (char *str, struct autr_ta *ta)
 Parse comments. More...
 
static int str_contains_data (char *str, char comment)
 Check if a line contains data (besides comments)
 
static int dnskey_flags (uint16_t t, uint8_t *rdata, size_t len)
 Get DNSKEY flags rdata without rdatalen in front of it.
 
static int rr_is_dnskey_sep (uint16_t t, uint8_t *rdata, size_t len)
 Check if KSK DNSKEY. More...
 
static int ta_is_dnskey_sep (struct autr_ta *ta)
 Check if TA is KSK DNSKEY.
 
static int rr_is_dnskey_revoked (uint16_t t, uint8_t *rdata, size_t len)
 Check if REVOKED DNSKEY pass rdata without rdatalen in front of it.
 
static struct autr_taautr_ta_create (uint8_t *rr, size_t rr_len, size_t dname_len)
 create ta
 
static struct trust_anchorautr_tp_create (struct val_anchors *anchors, uint8_t *own, size_t own_len, uint16_t dc)
 create tp
 
static void autr_rrset_delete (struct ub_packed_rrset_key *r)
 delete assembled rrsets
 
void autr_point_delete (struct trust_anchor *tp)
 Delete autr anchor, deletes the autr data but does not do unlinking from trees, caller does that. More...
 
static struct trust_anchorfind_add_tp (struct val_anchors *anchors, uint8_t *rr, size_t rr_len, size_t dname_len)
 find or add a new trust point for autotrust
 
static struct autr_taadd_trustanchor_frm_rr (struct val_anchors *anchors, uint8_t *rr, size_t rr_len, size_t dname_len, struct trust_anchor **tp)
 Add trust anchor from RR.
 
static struct autr_taadd_trustanchor_frm_str (struct val_anchors *anchors, char *str, struct trust_anchor **tp, uint8_t *origin, size_t origin_len, uint8_t **prev, size_t *prev_len, int *skip)
 Add new trust anchor from a string in file. More...
 
static struct trust_anchorload_trustanchor (struct val_anchors *anchors, char *str, const char *fname, uint8_t *origin, size_t origin_len, uint8_t **prev, size_t *prev_len, int *skip)
 Load single anchor. More...
 
static int assemble_iterate_ds (struct autr_ta **list, uint8_t **rr, size_t *rr_len, size_t *dname_len)
 iterator for DSes from keylist. More...
 
static int assemble_iterate_dnskey (struct autr_ta **list, uint8_t **rr, size_t *rr_len, size_t *dname_len)
 iterator for DNSKEYs from keylist. More...
 
static int assemble_iterate_hasfirst (int iter(struct autr_ta **, uint8_t **, size_t *, size_t *), struct autr_ta *list)
 see if iterator-list has any elements in it, or it is empty
 
static size_t assemble_iterate_count (int iter(struct autr_ta **, uint8_t **, size_t *, size_t *), struct autr_ta *list)
 number of elements in iterator list
 
static struct ub_packed_rrset_keyub_packed_rrset_heap_key (int iter(struct autr_ta **, uint8_t **, size_t *, size_t *), struct autr_ta *list)
 Create a ub_packed_rrset_key allocated on the heap. More...
 
static struct packed_rrset_datapacked_rrset_heap_data (int iter(struct autr_ta **, uint8_t **, size_t *, size_t *), struct autr_ta *list)
 Create packed_rrset data on the heap. More...
 
static int autr_assemble (struct trust_anchor *tp)
 Assemble the trust anchors into DS and DNSKEY packed rrsets. More...
 
static unsigned int parse_int (char *line, int *ret)
 parse integer
 
static struct trust_anchorparse_id (struct val_anchors *anchors, char *line)
 parse id sequence for anchor
 
static int parse_var_line (char *line, struct val_anchors *anchors, struct trust_anchor **anchor)
 Parse variable from trustanchor header. More...
 
static int handle_origin (char *line, uint8_t **origin, size_t *origin_len)
 handle origin lines
 
static int read_multiline (char *buf, size_t len, FILE *in, int *linenr)
 Read one line and put multiline RRs onto one line string.
 
int autr_read_file (struct val_anchors *anchors, const char *nm)
 Read autotrust file. More...
 
static const char * trustanchor_state2str (autr_state_type s)
 string for a trustanchor state
 
static char * autr_ctime_r (time_t *t, char *s)
 ctime r for autotrust
 
static int print_id (FILE *out, char *fname, uint8_t *nm, size_t nmlen, uint16_t dclass)
 print ID to file
 
static int autr_write_contents (FILE *out, char *fn, struct trust_anchor *tp)
 
void autr_write_file (struct module_env *env, struct trust_anchor *tp)
 Write autotrust file. More...
 
static int verify_dnskey (struct module_env *env, struct val_env *ve, struct trust_anchor *tp, struct ub_packed_rrset_key *rrset, struct module_qstate *qstate)
 Verify if dnskey works for trust point. More...
 
static int32_t rrsig_get_expiry (uint8_t *d, size_t len)
 
static time_t min_expiry (struct module_env *env, struct packed_rrset_data *dd)
 Find minimum expiration interval from signatures.
 
static int rr_is_selfsigned_revoked (struct module_env *env, struct val_env *ve, struct ub_packed_rrset_key *dnskey_rrset, size_t i, struct module_qstate *qstate)
 Is rr self-signed revoked key.
 
static void seen_trustanchor (struct autr_ta *ta, uint8_t seen)
 Set fetched value.
 
static void seen_revoked_trustanchor (struct autr_ta *ta, uint8_t revoked)
 set revoked value
 
static void revoke_dnskey (struct autr_ta *ta, int off)
 revoke a trust anchor
 
static int dnskey_compare_skip_revbit (uint8_t *a, size_t a_len, uint8_t *b, size_t b_len)
 Compare two RRs skipping the REVOKED bit. More...
 
static int ta_compare (struct autr_ta *a, uint16_t t, uint8_t *b, size_t b_len)
 compare trust anchor with rdata, 0 if equal. More...
 
static int find_key (struct trust_anchor *tp, uint16_t t, uint8_t *rdata, size_t rdata_len, struct autr_ta **result)
 Find key. More...
 
static struct autr_taadd_key (struct trust_anchor *tp, uint32_t ttl, uint8_t *rdata, size_t rdata_len)
 add key and clone RR and tp already locked. More...
 
static time_t key_ttl (struct ub_packed_rrset_key *k)
 get TTL from DNSKEY rrset
 
static void set_tp_times (struct trust_anchor *tp, time_t rrsig_exp_interval, time_t origttl, int *changed)
 update the time values for the trustpoint
 
static void init_events (struct trust_anchor *tp)
 init events to zero
 
static void check_contains_revoked (struct module_env *env, struct val_env *ve, struct trust_anchor *tp, struct ub_packed_rrset_key *dnskey_rrset, int *changed, struct module_qstate *qstate)
 check for revoked keys without trusting any other information
 
static int key_matches_a_ds (struct module_env *env, struct val_env *ve, struct ub_packed_rrset_key *dnskey_rrset, size_t key_idx, struct ub_packed_rrset_key *ds_rrset)
 See if a DNSKEY is verified by one of the DSes.
 
static int update_events (struct module_env *env, struct val_env *ve, struct trust_anchor *tp, struct ub_packed_rrset_key *dnskey_rrset, int *changed)
 Set update events.
 
static time_t check_holddown (struct module_env *env, struct autr_ta *ta, unsigned int holddown)
 Check if the holddown time has already exceeded setting: add-holddown: add holddown timer setting: del-holddown: del holddown timer. More...
 
static void reset_holddown (struct module_env *env, struct autr_ta *ta, int *changed)
 Set last_change to now.
 
static void set_trustanchor_state (struct module_env *env, struct autr_ta *ta, int *changed, autr_state_type s)
 Set the state for this trust anchor.
 
static void do_newkey (struct module_env *env, struct autr_ta *anchor, int *c)
 Event: NewKey.
 
static void do_addtime (struct module_env *env, struct autr_ta *anchor, int *c)
 Event: AddTime.
 
static void do_remtime (struct module_env *env, struct autr_ta *anchor, int *c)
 Event: RemTime.
 
static void do_keyrem (struct module_env *env, struct autr_ta *anchor, int *c)
 Event: KeyRem.
 
static void do_keypres (struct module_env *env, struct autr_ta *anchor, int *c)
 Event: KeyPres.
 
static void anchor_state_update (struct module_env *env, struct autr_ta *anchor, int *c)
 Do statestable transition matrix for anchor.
 
static int init_zsk_to_ksk (struct module_env *env, struct trust_anchor *tp, int *changed)
 if ZSK init then trust KSKs
 
static void remove_missing_trustanchors (struct module_env *env, struct trust_anchor *tp, int *changed)
 Remove missing trustanchors so the list does not grow forever.
 
static int do_statetable (struct module_env *env, struct trust_anchor *tp, int *changed)
 Do the statetable from RFC5011 transition matrix.
 
static void autr_holddown_exceed (struct module_env *env, struct trust_anchor *tp, int *c)
 See if time alone makes ADDPEND to VALID transition.
 
static void autr_cleanup_keys (struct trust_anchor *tp)
 cleanup key list
 
static time_t calc_next_probe (struct module_env *env, time_t wait)
 calculate next probe time
 
static time_t wait_probe_time (struct val_anchors *anchors)
 what is first probe time (anchors must be locked)
 
static void reset_worker_timer (struct module_env *env)
 reset worker timer
 
static int set_next_probe (struct module_env *env, struct trust_anchor *tp, struct ub_packed_rrset_key *dnskey_rrset)
 set next probe for trust anchor
 
static void autr_tp_remove (struct module_env *env, struct trust_anchor *tp, struct ub_packed_rrset_key *dnskey_rrset)
 Revoke and Delete a trust point.
 
int autr_process_prime (struct module_env *env, struct val_env *ve, struct trust_anchor *tp, struct ub_packed_rrset_key *dnskey_rrset, struct module_qstate *qstate)
 Perform autotrust processing. More...
 
static void autr_debug_print_ta (struct autr_ta *ta)
 debug print a trust anchor key
 
static void autr_debug_print_tp (struct trust_anchor *tp)
 debug print a trust point
 
void autr_debug_print (struct val_anchors *anchors)
 Debug printout of rfc5011 tracked anchors. More...
 
void probe_answer_cb (void *arg, int ATTR_UNUSED(rcode), sldns_buffer *ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(sec), char *ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
 
static void probe_anchor (struct module_env *env, struct trust_anchor *tp)
 probe a trust anchor DNSKEY and unlocks tp
 
static struct trust_anchortodo_probe (struct module_env *env, time_t *next)
 fetch first to-probe trust-anchor and lock it and set retrytime
 
time_t autr_probe_timer (struct module_env *env)
 Process probe timer. More...
 

Detailed Description

Contains autotrust implementation.

The implementation was taken from the autotrust daemon (BSD licensed), written by Matthijs Mekking. It was modified to fit into unbound. The state table process is the same.

Function Documentation

◆ autr_global_create()

struct autr_global_data* autr_global_create ( void  )

Create new global 5011 data structure.

Returns
new structure or NULL on malloc failure.

References autr_global_data::probe, probetree_cmp(), and rbtree_init().

Referenced by anchors_create().

◆ autr_global_delete()

void autr_global_delete ( struct autr_global_data global)

Delete global 5011 data structure.

Parameters
globalglobal autotrust state to delete.

Referenced by anchors_delete().

◆ autr_get_num_anchors()

size_t autr_get_num_anchors ( struct val_anchors anchors)

See if autotrust anchors are configured and how many.

Parameters
anchorsthe trust anchors structure.
Returns
number of autotrust trust anchors

References val_anchors::autr, rbtree_type::count, val_anchors::lock, and autr_global_data::probe.

◆ verbose_key()

static void static void verbose_key ( struct autr_ta ta,
enum verbosity_value  level,
const char *  format,
  ... 
)
static

Debug routine to print pretty key information.

Implementation of debug pretty key print.

Parameters
tatrust anchor key with DNSKEY data.
levelverbosity level to print at.
formatprintf style format string.

References verbosity.

Referenced by check_holddown(), and set_trustanchor_state().

◆ parse_comments()

static int parse_comments ( char *  str,
struct autr_ta ta 
)
static

Parse comments.

Parameters
strto parse
tatrust key autotrust metadata
Returns
false on failure.

◆ rr_is_dnskey_sep()

static int rr_is_dnskey_sep ( uint16_t  t,
uint8_t *  rdata,
size_t  len 
)
static

Check if KSK DNSKEY.

pass rdata without rdatalen in front of it

References DNSKEY_BIT_SEP, and dnskey_flags().

◆ autr_point_delete()

void autr_point_delete ( struct trust_anchor tp)

Delete autr anchor, deletes the autr data but does not do unlinking from trees, caller does that.

Parameters
tptrust point to delete.

References trust_anchor::autr, autr_rrset_delete(), trust_anchor::dnskey_rrset, trust_anchor::ds_rrset, autr_point_data::file, autr_point_data::keys, trust_anchor::lock, trust_anchor::name, autr_ta::next, and autr_ta::rr.

◆ add_trustanchor_frm_str()

static struct autr_ta* add_trustanchor_frm_str ( struct val_anchors anchors,
char *  str,
struct trust_anchor **  tp,
uint8_t *  origin,
size_t  origin_len,
uint8_t **  prev,
size_t *  prev_len,
int *  skip 
)
static

Add new trust anchor from a string in file.

Parameters
anchorsall anchors
strstring with anchor and comments, if any comments.
tptrust point returned.
originwhat to use for @
origin_lenlength of origin
prevprevious rr name
prev_lenlength of prev
skipif true, the result is NULL, but not an error, skip it.
Returns
new key in trust point.

◆ load_trustanchor()

static struct trust_anchor* load_trustanchor ( struct val_anchors anchors,
char *  str,
const char *  fname,
uint8_t *  origin,
size_t  origin_len,
uint8_t **  prev,
size_t *  prev_len,
int *  skip 
)
static

Load single anchor.

Parameters
anchorsall points.
strcomments line
fnamefilename
originthe $ORIGIN.
origin_lenlength of origin
prevpassed to ldns.
prev_lenlength of prev
skipif true, the result is NULL, but not an error, skip it.
Returns
false on failure, otherwise the tp read.

Referenced by autr_read_file().

◆ assemble_iterate_ds()

static int assemble_iterate_ds ( struct autr_ta **  list,
uint8_t **  rr,
size_t *  rr_len,
size_t *  dname_len 
)
static

iterator for DSes from keylist.

return true if a next element exists

References LDNS_RR_TYPE_DS, autr_ta::next, and sldns_wirerr_get_type().

Referenced by autr_assemble().

◆ assemble_iterate_dnskey()

static int assemble_iterate_dnskey ( struct autr_ta **  list,
uint8_t **  rr,
size_t *  rr_len,
size_t *  dname_len 
)
static

iterator for DNSKEYs from keylist.

return true if a next element exists

References LDNS_RR_TYPE_DS, and sldns_wirerr_get_type().

Referenced by autr_assemble().

◆ ub_packed_rrset_heap_key()

static struct ub_packed_rrset_key* ub_packed_rrset_heap_key ( int   iterstruct autr_ta **, uint8_t **, size_t *, size_t *,
struct autr_ta list 
)
static

Create a ub_packed_rrset_key allocated on the heap.

It therefore does not have the correct ID value, and cannot be used inside the cache. It can be used in storage outside of the cache. Keys for the cache have to be obtained from alloc.h .

Parameters
iteriterator over the elements in the list. It filters elements.
listthe list.
Returns
key allocated or NULL on failure.

References packed_rrset_key::dname, packed_rrset_key::dname_len, memdup(), ub_packed_rrset_key::rk, packed_rrset_key::rrset_class, sldns_wirerr_get_class(), sldns_wirerr_get_type(), and packed_rrset_key::type.

Referenced by autr_assemble().

◆ packed_rrset_heap_data()

static struct packed_rrset_data* packed_rrset_heap_data ( int   iterstruct autr_ta **, uint8_t **, size_t *, size_t *,
struct autr_ta list 
)
static

◆ autr_assemble()

static int autr_assemble ( struct trust_anchor tp)
static

Assemble the trust anchors into DS and DNSKEY packed rrsets.

Uses only VALID and MISSING DNSKEYs. Read the sldns_rrs and builds packed rrsets

Parameters
tpthe trust point. Must be locked.
Returns
false on malloc failure.

References assemble_iterate_count(), assemble_iterate_dnskey(), assemble_iterate_ds(), assemble_iterate_hasfirst(), trust_anchor::autr, autr_rrset_delete(), lruhash_entry::data, trust_anchor::dnskey_rrset, trust_anchor::ds_rrset, ub_packed_rrset_key::entry, autr_point_data::keys, trust_anchor::numDNSKEY, trust_anchor::numDS, packed_rrset_heap_data(), and ub_packed_rrset_heap_key().

Referenced by autr_read_file().

◆ parse_var_line()

static int parse_var_line ( char *  line,
struct val_anchors anchors,
struct trust_anchor **  anchor 
)
static

Parse variable from trustanchor header.

Parameters
lineto parse
anchorsthe anchor is added to this, if "id:" is seen.
anchorthe anchor as result value or previously returned anchor value to read the variable lines into.
Returns
: 0 no match, -1 failed syntax error, +1 success line read. +2 revoked trust anchor file.

References val_anchors::autr, trust_anchor::autr, autr_point_data::last_queried, autr_point_data::last_success, val_anchors::lock, trust_anchor::lock, log_err(), autr_point_data::next_probe_time, parse_id(), parse_int(), autr_point_data::pnode, autr_global_data::probe, autr_point_data::query_failed, autr_point_data::query_interval, rbtree_delete(), rbtree_insert(), and autr_point_data::retry_time.

Referenced by autr_read_file().

◆ autr_read_file()

int autr_read_file ( struct val_anchors anchors,
const char *  nm 
)

Read autotrust file.

Parameters
anchorsthe anchors structure.
nmname of the file (copied).
Returns
false on failure.

References autr_assemble(), handle_origin(), load_trustanchor(), trust_anchor::lock, log_err(), log_warn(), parse_var_line(), read_multiline(), str_contains_data(), VERB_ALGO, and verbose().

Referenced by anchors_apply_cfg().

◆ autr_write_file()

void autr_write_file ( struct module_env env,
struct trust_anchor tp 
)

Write autotrust file.

Parameters
envenvironment with scratch space.
tptrust point to write.

References trust_anchor::autr, autr_point_data::file, log_assert, log_err(), VERB_ALGO, verbose(), and module_env::worker.

◆ verify_dnskey()

static int verify_dnskey ( struct module_env env,
struct val_env ve,
struct trust_anchor tp,
struct ub_packed_rrset_key rrset,
struct module_qstate qstate 
)
static

Verify if dnskey works for trust point.

Parameters
envenvironment (with time) for verification
vevalidator environment (with options) for verification.
tptrust point to verify with
rrsetDNSKEY rrset to verify.
qstateqstate with region.
Returns
false on failure, true if verification successful.

References ALGO_NEEDS_MAX, module_env::cfg, trust_anchor::dnskey_rrset, trust_anchor::ds_rrset, config_file::harden_algo_downgrade, sec_status_secure, sec_status_to_string(), val_verify_DNSKEY_with_TA(), VERB_ALGO, and verbose().

◆ dnskey_compare_skip_revbit()

static int dnskey_compare_skip_revbit ( uint8_t *  a,
size_t  a_len,
uint8_t *  b,
size_t  b_len 
)
static

Compare two RRs skipping the REVOKED bit.

Pass rdata(no len)

◆ ta_compare()

static int ta_compare ( struct autr_ta a,
uint16_t  t,
uint8_t *  b,
size_t  b_len 
)
static

compare trust anchor with rdata, 0 if equal.

Pass rdata(no len)

References autr_ta::rr, autr_ta::rr_len, and sldns_wirerr_get_type().

Referenced by find_key().

◆ find_key()

static int find_key ( struct trust_anchor tp,
uint16_t  t,
uint8_t *  rdata,
size_t  rdata_len,
struct autr_ta **  result 
)
static

Find key.

Parameters
tpto search in
trr type of the rdata.
rdatato look for (no rdatalen in it)
rdata_lenlength of rdata
resultreturns NULL or the ta key looked for.
Returns
false on malloc failure during search. if true examine result.

References trust_anchor::autr, autr_point_data::keys, autr_ta::next, and ta_compare().

◆ add_key()

static struct autr_ta* add_key ( struct trust_anchor tp,
uint32_t  ttl,
uint8_t *  rdata,
size_t  rdata_len 
)
static

add key and clone RR and tp already locked.

rdata without rdlen.

References autr_ta::rr, and autr_ta::rr_len.

◆ check_holddown()

static time_t check_holddown ( struct module_env env,
struct autr_ta ta,
unsigned int  holddown 
)
static

Check if the holddown time has already exceeded setting: add-holddown: add holddown timer setting: del-holddown: del holddown timer.

Parameters
envenvironment with current time
tatrust anchor to check for.
holddownthe timer value
Returns
number of seconds the holddown has passed.

References autr_ta::last_change, log_warn(), module_env::now, VERB_ALGO, and verbose_key().

Referenced by do_addtime(), and do_remtime().

◆ autr_process_prime()

int autr_process_prime ( struct module_env env,
struct val_env ve,
struct trust_anchor tp,
struct ub_packed_rrset_key dnskey_rrset,
struct module_qstate qstate 
)

Perform autotrust processing.

Parameters
envqstate environment with the anchors structure.
vevalidator environment for verification of rrsigs.
tptrust anchor to process.
dnskey_rrsetDNSKEY rrset probed (can be NULL if bad prime result). allocated in a region. Has not been validated yet.
qstateqstate with region.
Returns
false if trust anchor was revoked completely. Otherwise logs errors to log, does not change return value. On errors, likely the trust point has been unchanged.

References trust_anchor::autr, log_assert, log_nametypeclass(), trust_anchor::name, autr_point_data::revoked, and VERB_ALGO.

◆ autr_debug_print()

void autr_debug_print ( struct val_anchors anchors)

Debug printout of rfc5011 tracked anchors.

Parameters
anchorsall the anchors.

References autr_debug_print_tp(), val_anchors::lock, trust_anchor::lock, RBTREE_FOR, and val_anchors::tree.

Referenced by anchors_apply_cfg().

◆ autr_probe_timer()

time_t autr_probe_timer ( struct module_env env)

Process probe timer.

Add new probes if needed.

Parameters
envmodule environment with time, with anchors and with the mesh.
Returns
time of next probe (in seconds from now). If 0, then there is no next probe anymore (trust points deleted).

References autr_permit_small_holddown, probe_anchor(), regional_free_all(), module_env::scratch, todo_probe(), VERB_ALGO, and verbose().

Referenced by worker_probe_timer_cb().