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_data * | autr_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_ta * | autr_ta_create (uint8_t *rr, size_t rr_len, size_t dname_len) |
create ta | |
static struct trust_anchor * | autr_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_anchor * | find_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_ta * | add_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_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) |
Add new trust anchor from a string in file. More... | |
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) |
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_key * | ub_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_data * | packed_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_anchor * | parse_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_ta * | add_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_anchor * | todo_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... | |
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.
struct autr_global_data* autr_global_create | ( | void | ) |
Create new global 5011 data structure.
References autr_global_data::probe, probetree_cmp(), and rbtree_init().
Referenced by anchors_create().
void autr_global_delete | ( | struct autr_global_data * | global | ) |
Delete global 5011 data structure.
global | global autotrust state to delete. |
Referenced by anchors_delete().
size_t autr_get_num_anchors | ( | struct val_anchors * | anchors | ) |
See if autotrust anchors are configured and how many.
anchors | the trust anchors structure. |
References val_anchors::autr, rbtree_type::count, val_anchors::lock, and autr_global_data::probe.
|
static |
Debug routine to print pretty key information.
Implementation of debug pretty key print.
ta | trust anchor key with DNSKEY data. |
level | verbosity level to print at. |
format | printf style format string. |
References verbosity.
Referenced by check_holddown(), and set_trustanchor_state().
|
static |
Parse comments.
str | to parse |
ta | trust key autotrust metadata |
|
static |
Check if KSK DNSKEY.
pass rdata without rdatalen in front of it
References DNSKEY_BIT_SEP, and dnskey_flags().
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.
tp | trust 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.
|
static |
Add new trust anchor from a string in file.
anchors | all anchors |
str | string with anchor and comments, if any comments. |
tp | trust point returned. |
origin | what to use for @ |
origin_len | length of origin |
prev | previous rr name |
prev_len | length of prev |
skip | if true, the result is NULL, but not an error, skip it. |
|
static |
Load single anchor.
anchors | all points. |
str | comments line |
fname | filename |
origin | the $ORIGIN. |
origin_len | length of origin |
prev | passed to ldns. |
prev_len | length of prev |
skip | if true, the result is NULL, but not an error, skip it. |
Referenced by autr_read_file().
|
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().
|
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().
|
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 .
iter | iterator over the elements in the list. It filters elements. |
list | the list. |
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().
|
static |
Create packed_rrset data on the heap.
iter | iterator over the elements in the list. It filters elements. |
list | the list. |
References packed_rrset_data::count, LDNS_RR_TYPE_RRSIG, log_assert, autr_ta::rr, packed_rrset_data::rr_data, packed_rrset_data::rr_len, autr_ta::rr_len, packed_rrset_data::rr_ttl, packed_rrset_data::rrsig_count, sldns_wirerr_get_rdatalen(), sldns_wirerr_get_rdatawl(), sldns_wirerr_get_ttl(), sldns_wirerr_get_type(), and packed_rrset_data::ttl.
Referenced by autr_assemble().
|
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
tp | the trust point. Must be locked. |
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().
|
static |
Parse variable from trustanchor header.
line | to parse |
anchors | the anchor is added to this, if "id:" is seen. |
anchor | the anchor as result value or previously returned anchor value to read the variable lines into. |
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().
int autr_read_file | ( | struct val_anchors * | anchors, |
const char * | nm | ||
) |
Read autotrust file.
anchors | the anchors structure. |
nm | name of the file (copied). |
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().
void autr_write_file | ( | struct module_env * | env, |
struct trust_anchor * | tp | ||
) |
Write autotrust file.
env | environment with scratch space. |
tp | trust point to write. |
References trust_anchor::autr, autr_point_data::file, log_assert, log_err(), VERB_ALGO, verbose(), and module_env::worker.
|
static |
Verify if dnskey works for trust point.
env | environment (with time) for verification |
ve | validator environment (with options) for verification. |
tp | trust point to verify with |
rrset | DNSKEY rrset to verify. |
qstate | qstate with region. |
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().
|
static |
Compare two RRs skipping the REVOKED bit.
Pass rdata(no 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().
|
static |
Find key.
tp | to search in |
t | rr type of the rdata. |
rdata | to look for (no rdatalen in it) |
rdata_len | length of rdata |
result | returns NULL or the ta key looked for. |
References trust_anchor::autr, autr_point_data::keys, autr_ta::next, and ta_compare().
|
static |
add key and clone RR and tp already locked.
rdata without rdlen.
References autr_ta::rr, and autr_ta::rr_len.
|
static |
Check if the holddown time has already exceeded setting: add-holddown: add holddown timer setting: del-holddown: del holddown timer.
env | environment with current time |
ta | trust anchor to check for. |
holddown | the timer value |
References autr_ta::last_change, log_warn(), module_env::now, VERB_ALGO, and verbose_key().
Referenced by do_addtime(), and do_remtime().
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.
env | qstate environment with the anchors structure. |
ve | validator environment for verification of rrsigs. |
tp | trust anchor to process. |
dnskey_rrset | DNSKEY rrset probed (can be NULL if bad prime result). allocated in a region. Has not been validated yet. |
qstate | qstate with region. |
References trust_anchor::autr, log_assert, log_nametypeclass(), trust_anchor::name, autr_point_data::revoked, and VERB_ALGO.
void autr_debug_print | ( | struct val_anchors * | anchors | ) |
Debug printout of rfc5011 tracked anchors.
anchors | all the anchors. |
References autr_debug_print_tp(), val_anchors::lock, trust_anchor::lock, RBTREE_FOR, and val_anchors::tree.
Referenced by anchors_apply_cfg().
time_t autr_probe_timer | ( | struct module_env * | env | ) |
Process probe timer.
Add new probes if needed.
env | module environment with time, with anchors and with the mesh. |
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().