unbound 0.1
|
This file contains helper functions for the validator module. More...
Data Structures | |
struct | nsec3_cached_hash |
The NSEC3 hash result storage. More... | |
Defines | |
#define | NSEC3_OPTOUT 0x01 |
0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+ | |O| +-+-+-+-+-+-+-+-+ The OPT-OUT bit in the NSEC3 flags field. | |
#define | NSEC3_UNKNOWN_FLAGS 0xFE |
The unknown flags in the NSEC3 flags field. | |
#define | NSEC3_HASH_SHA1 0x01 |
The SHA1 hash algorithm for NSEC3. | |
Functions | |
enum sec_status | 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) |
Determine if the set of NSEC3 records provided with a response prove NAME ERROR. | |
enum sec_status | 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) |
Determine if the NSEC3s provided in a response prove the NOERROR/NODATA status. | |
enum sec_status | 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) |
Prove that a positive wildcard match was appropriate (no direct match RRset). | |
enum sec_status | 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) |
Prove that a DS response either had no DS, or wasn't a delegation point. | |
enum sec_status | nsec3_prove_nxornodata (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, int *nodata) |
Prove NXDOMAIN or NODATA. | |
int | nsec3_hash_cmp (const void *c1, const void *c2) |
Rbtree for hash cache comparison function. | |
int | nsec3_hash_name (rbtree_t *table, struct regional *region, ldns_buffer *buf, struct ub_packed_rrset_key *nsec3, int rr, uint8_t *dname, size_t dname_len, struct nsec3_cached_hash **hash) |
Obtain the hash of an owner name. | |
size_t | nsec3_get_nextowner_b32 (struct ub_packed_rrset_key *rrset, int r, uint8_t *buf, size_t max) |
Get next owner name, converted to base32 encoding and with the zone name (taken from the nsec3 owner name) appended. | |
size_t | nsec3_hash_to_b32 (uint8_t *hash, size_t hashlen, uint8_t *zone, size_t zonelen, uint8_t *buf, size_t max) |
Convert hash into base32 encoding and with the zone name appended. | |
int | nsec3_get_params (struct ub_packed_rrset_key *rrset, int r, int *algo, size_t *iter, uint8_t **salt, size_t *saltlen) |
Get NSEC3 parameters out of rr. | |
size_t | nsec3_get_hashed (ldns_buffer *buf, uint8_t *nm, size_t nmlen, int algo, size_t iter, uint8_t *salt, size_t saltlen, uint8_t *res, size_t max) |
Get NSEC3 hashed in a buffer. | |
int | nsec3_has_type (struct ub_packed_rrset_key *rrset, int r, uint16_t type) |
see if NSEC3 RR contains given type | |
int | nsec3_has_optout (struct ub_packed_rrset_key *rrset, int r) |
return if nsec3 RR has the optout flag | |
int | nsec3_get_nextowner (struct ub_packed_rrset_key *rrset, int r, uint8_t **next, size_t *nextlen) |
Return nsec3 RR next hashed owner name. | |
int | nsec3_covers (uint8_t *zone, struct nsec3_cached_hash *hash, struct ub_packed_rrset_key *rrset, int rr, ldns_buffer *buf) |
nsec3Covers Given a hash and a candidate NSEC3Record, determine if that NSEC3Record covers the hash. |
This file contains helper functions for the validator module.
The functions help with NSEC3 checking, the different NSEC3 proofs for denial of existance, and proofs for presence of types.
NSEC3 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Hash Alg. | Flags | Iterations | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Salt Length | Salt / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Hash Length | Next Hashed Owner Name / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / Type Bit Maps / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
NSEC3PARAM 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Hash Alg. | Flags | Iterations | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Salt Length | Salt / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#define NSEC3_OPTOUT 0x01 |
0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+ | |O| +-+-+-+-+-+-+-+-+ The OPT-OUT bit in the NSEC3 flags field.
If enabled, there can be zero or more unsigned delegations in the span. If disabled, there are zero unsigned delegations in the span.
Referenced by nsec3_has_optout().
#define NSEC3_UNKNOWN_FLAGS 0xFE |
The unknown flags in the NSEC3 flags field.
They must be zero, or the NSEC3 is ignored.
Referenced by nsec3_unknown_flags().
enum sec_status 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 | ||
) |
Determine if the set of NSEC3 records provided with a response prove NAME ERROR.
This means that the NSEC3s prove a) the closest encloser exists, b) the direct child of the closest encloser towards qname doesn't exist, and c) *.closest encloser does not exist.
env,: | module environment with temporary region and buffer. |
ve,: | validator environment, with iteration count settings. |
list,: | array of RRsets, some of which are NSEC3s. |
num,: | number of RRsets in the array to examine. |
qinfo,: | query that is verified for. |
kkey,: | key entry that signed the NSEC3s. |
References filter_init(), key_entry_isgood(), log_nametypeclass(), nsec3_do_prove_nameerror(), nsec3_hash_cmp(), nsec3_iteration_count_high(), rbtree_init(), sec_status_bogus, sec_status_insecure, VERB_ALGO, and nsec3_filter::zone.
Referenced by validate_nameerror_response().
enum sec_status 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 | ||
) |
Determine if the NSEC3s provided in a response prove the NOERROR/NODATA status.
There are a number of different variants to this:
1) Normal NODATA -- qname is matched to an NSEC3 record, type is not present.
2) ENT NODATA -- because there must be NSEC3 record for empty-non-terminals, this is the same as #1.
3) NSEC3 ownername NODATA -- qname matched an existing, lone NSEC3 ownername, but qtype was not NSEC3. NOTE: as of nsec-05, this case no longer exists.
4) Wildcard NODATA -- A wildcard matched the name, but not the type.
5) Opt-In DS NODATA -- the qname is covered by an opt-in span and qtype == DS. (or maybe some future record with the same parent-side-only property)
env,: | module environment with temporary region and buffer. |
ve,: | validator environment, with iteration count settings. |
list,: | array of RRsets, some of which are NSEC3s. |
num,: | number of RRsets in the array to examine. |
qinfo,: | query that is verified for. |
kkey,: | key entry that signed the NSEC3s. |
References filter_init(), key_entry_isgood(), nsec3_do_prove_nodata(), nsec3_hash_cmp(), nsec3_iteration_count_high(), rbtree_init(), sec_status_bogus, sec_status_insecure, and nsec3_filter::zone.
Referenced by validate_nodata_response().
enum sec_status 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 | ||
) |
Prove that a positive wildcard match was appropriate (no direct match RRset).
env,: | module environment with temporary region and buffer. |
ve,: | validator environment, with iteration count settings. |
list,: | array of RRsets, some of which are NSEC3s. |
num,: | number of RRsets in the array to examine. |
qinfo,: | query that is verified for. |
kkey,: | key entry that signed the NSEC3s. |
wc,: | The purported wildcard that matched. This is the wildcard name as *.wildcard.name., with the *. label already removed. |
References ce_response::ce, ce_response::ce_len, dname_count_size_labels(), filter_init(), find_covering_nsec3(), key_entry_isgood(), ce_response::nc_rr, ce_response::nc_rrset, next_closer(), nsec3_has_optout(), nsec3_hash_cmp(), nsec3_iteration_count_high(), query_info::qname, query_info::qname_len, rbtree_init(), sec_status_bogus, sec_status_insecure, sec_status_secure, VERB_ALGO, verbose(), and nsec3_filter::zone.
Referenced by validate_any_response(), validate_cname_response(), and validate_positive_response().
enum sec_status 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 | ||
) |
Prove that a DS response either had no DS, or wasn't a delegation point.
Fundamentally there are two cases here: normal NODATA and Opt-In NODATA.
env,: | module environment with temporary region and buffer. |
ve,: | validator environment, with iteration count settings. |
list,: | array of RRsets, some of which are NSEC3s. |
num,: | number of RRsets in the array to examine. |
qinfo,: | query that is verified for. |
kkey,: | key entry that signed the NSEC3s. |
reason,: | string for bogus result. |
References filter_init(), find_matching_nsec3(), key_entry_isgood(), list_is_secure(), log_assert, ce_response::nc_rr, ce_response::nc_rrset, nsec3_has_optout(), nsec3_has_type(), nsec3_hash_cmp(), nsec3_iteration_count_high(), nsec3_prove_closest_encloser(), query_info::qname, query_info::qname_len, query_info::qtype, rbtree_init(), sec_status_bogus, sec_status_indeterminate, sec_status_insecure, sec_status_secure, VERB_ALGO, verbose(), and nsec3_filter::zone.
Referenced by ds_response_to_ke().
enum sec_status nsec3_prove_nxornodata | ( | 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, | ||
int * | nodata | ||
) |
Prove NXDOMAIN or NODATA.
env,: | module environment with temporary region and buffer. |
ve,: | validator environment, with iteration count settings. |
list,: | array of RRsets, some of which are NSEC3s. |
num,: | number of RRsets in the array to examine. |
qinfo,: | query that is verified for. |
kkey,: | key entry that signed the NSEC3s. |
nodata,: | if return value is secure, this indicates if nodata or nxdomain was proven. |
References filter_init(), key_entry_isgood(), nsec3_do_prove_nameerror(), nsec3_do_prove_nodata(), nsec3_hash_cmp(), nsec3_iteration_count_high(), rbtree_init(), sec_status_bogus, sec_status_insecure, sec_status_secure, and nsec3_filter::zone.
Referenced by validate_cname_noanswer_response().
int nsec3_hash_cmp | ( | const void * | c1, |
const void * | c2 | ||
) |
Rbtree for hash cache comparison function.
c1,: | key 1. |
c2,: | key 2. |
References nsec3_cached_hash::dname, nsec3_cached_hash::nsec3, nsec3_get_algo(), nsec3_get_iter(), nsec3_get_salt(), query_dname_compare(), and nsec3_cached_hash::rr.
Referenced by fptr_whitelist_rbtree_cmp(), nsec3_hash_test(), nsec3_prove_nameerror(), nsec3_prove_nodata(), nsec3_prove_nods(), nsec3_prove_nxornodata(), and nsec3_prove_wildcard().
int nsec3_hash_name | ( | rbtree_t * | table, |
struct regional * | region, | ||
ldns_buffer * | buf, | ||
struct ub_packed_rrset_key * | nsec3, | ||
int | rr, | ||
uint8_t * | dname, | ||
size_t | dname_len, | ||
struct nsec3_cached_hash ** | hash | ||
) |
Obtain the hash of an owner name.
Used internally by the nsec3 proof functions in this file. published to enable unit testing of hash algorithms and cache.
table,: | the cache table. Must be inited at start. |
region,: | scratch region to use for allocation. This region holds the tree, if you wipe the region, reinit the tree. |
buf,: | temporary buffer. |
nsec3,: | the rrset with parameters |
rr,: | rr number from d that has the NSEC3 parameters to hash to. |
dname,: | name to hash This pointer is used inside the tree, assumed region-alloced. |
dname_len,: | the length of the name. |
hash,: | the hash node is returned on success. |
References nsec3_cached_hash::dname, nsec3_cached_hash::dname_len, rbnode_t::key, log_assert, nsec3_cached_hash::node, nsec3_cached_hash::nsec3, nsec3_calc_b32(), nsec3_calc_hash(), rbtree_insert(), rbtree_search(), regional_alloc(), and nsec3_cached_hash::rr.
Referenced by find_covering_nsec3(), find_matching_nsec3(), and nsec3_hash_test_entry().
size_t nsec3_get_nextowner_b32 | ( | struct ub_packed_rrset_key * | rrset, |
int | r, | ||
uint8_t * | buf, | ||
size_t | max | ||
) |
Get next owner name, converted to base32 encoding and with the zone name (taken from the nsec3 owner name) appended.
rrset,: | the NSEC3 rrset. |
r,: | the rr num of the nsec3 in the rrset. |
buf,: | buffer to store name in |
max,: | size of buffer. |
References packed_rrset_key::dname, packed_rrset_key::dname_len, dname_remove_label(), nsec3_get_nextowner(), nsec3_hash_to_b32(), and ub_packed_rrset_key::rk.
Referenced by wipeout().
size_t nsec3_hash_to_b32 | ( | uint8_t * | hash, |
size_t | hashlen, | ||
uint8_t * | zone, | ||
size_t | zonelen, | ||
uint8_t * | buf, | ||
size_t | max | ||
) |
Convert hash into base32 encoding and with the zone name appended.
hash,: | hashed buffer |
hashlen,: | length of hash |
zone,: | name of zone |
zonelen,: | length of zonename. |
buf,: | buffer to store name in |
max,: | size of buffer. |
References ldns_b32_ntop_extended_hex().
Referenced by neg_find_nsec3_ce(), neg_nsec3_getnc(), and nsec3_get_nextowner_b32().
int nsec3_get_params | ( | struct ub_packed_rrset_key * | rrset, |
int | r, | ||
int * | algo, | ||
size_t * | iter, | ||
uint8_t ** | salt, | ||
size_t * | saltlen | ||
) |
Get NSEC3 parameters out of rr.
rrset,: | the NSEC3 rrset. |
r,: | the rr num of the nsec3 in the rrset. |
algo,: | nsec3 hash algo. |
iter,: | iteration count. |
salt,: | ptr to salt inside rdata. |
saltlen,: | length of salt. |
References nsec3_get_algo(), nsec3_get_iter(), nsec3_get_salt(), nsec3_known_algo(), and nsec3_unknown_flags().
Referenced by neg_insert_data(), and neg_params_ok().
size_t nsec3_get_hashed | ( | ldns_buffer * | buf, |
uint8_t * | nm, | ||
size_t | nmlen, | ||
int | algo, | ||
size_t | iter, | ||
uint8_t * | salt, | ||
size_t | saltlen, | ||
uint8_t * | res, | ||
size_t | max | ||
) |
Get NSEC3 hashed in a buffer.
buf,: | buffer for temp use. |
nm,: | name to hash |
nmlen,: | length of nm. |
algo,: | algo to use, must be known. |
iter,: | iterations |
salt,: | salt for nsec3 |
saltlen,: | length of salt. |
res,: | result of hash stored here. |
max,: | maximum space for result. |
References nsec3_cached_hash::hash_len, log_err(), NSEC3_HASH_SHA1, and query_dname_tolower().
Referenced by neg_find_nsec3_ce().
int nsec3_has_type | ( | struct ub_packed_rrset_key * | rrset, |
int | r, | ||
uint16_t | type | ||
) |
see if NSEC3 RR contains given type
rrset,: | NSEC3 rrset |
r,: | RR in rrset |
type,: | in host order to check bit for. |
References packed_rrset_data::count, lruhash_entry::data, ub_packed_rrset_key::entry, log_assert, nsecbitmap_has_type_rdata(), packed_rrset_data::rr_data, and packed_rrset_data::rr_len.
Referenced by neg_nsec3_proof_ds(), nsec3_do_prove_nodata(), nsec3_no_type(), nsec3_prove_closest_encloser(), and nsec3_prove_nods().
int nsec3_has_optout | ( | struct ub_packed_rrset_key * | rrset, |
int | r | ||
) |
return if nsec3 RR has the optout flag
rrset,: | NSEC3 rrset |
r,: | RR in rrset |
References packed_rrset_data::count, lruhash_entry::data, ub_packed_rrset_key::entry, log_assert, NSEC3_OPTOUT, packed_rrset_data::rr_data, and packed_rrset_data::rr_len.
Referenced by neg_nsec3_proof_ds(), nsec3_do_prove_nameerror(), nsec3_do_prove_nodata(), nsec3_prove_nods(), and nsec3_prove_wildcard().
int nsec3_get_nextowner | ( | struct ub_packed_rrset_key * | rrset, |
int | r, | ||
uint8_t ** | next, | ||
size_t * | nextlen | ||
) |
Return nsec3 RR next hashed owner name.
rrset,: | NSEC3 rrset |
r,: | RR in rrset |
next,: | ptr into rdata to next owner hash |
nextlen,: | length of hash. |
References packed_rrset_data::count, lruhash_entry::data, ub_packed_rrset_key::entry, log_assert, packed_rrset_data::rr_data, and packed_rrset_data::rr_len.
Referenced by nsec3_covers(), and nsec3_get_nextowner_b32().
int nsec3_covers | ( | uint8_t * | zone, |
struct nsec3_cached_hash * | hash, | ||
struct ub_packed_rrset_key * | rrset, | ||
int | rr, | ||
ldns_buffer * | buf | ||
) |
nsec3Covers Given a hash and a candidate NSEC3Record, determine if that NSEC3Record covers the hash.
Covers specifically means that the hash is in between the owner and next hashes and does not equal either.
zone,: | the zone name. |
hash,: | the hash of the name |
rrset,: | the rrset of the NSEC3. |
rr,: | which rr in the rrset. |
buf,: | temporary buffer. |
References nsec3_cached_hash::b32, nsec3_cached_hash::b32_len, packed_rrset_key::dname, nsec3_cached_hash::hash, nsec3_cached_hash::hash_len, label_compare_lower(), ldns_b32_pton_extended_hex(), nsec3_get_nextowner(), query_dname_compare(), and ub_packed_rrset_key::rk.
Referenced by find_covering_nsec3(), and neg_nsec3_proof_ds().