This file contains helper functions for the validator module. More...
Data Structures | |
struct | nsec3_cache_table |
Cache table for NSEC3 hashes. More... | |
struct | nsec3_cached_hash |
The NSEC3 hash result storage. More... | |
Macros | |
#define | NSEC3_OPTOUT 0x01 |
#define | NSEC3_UNKNOWN_FLAGS 0xFE |
The unknown flags in the NSEC3 flags field. More... | |
#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, struct nsec3_cache_table *ct, int *calc) |
Determine if the set of NSEC3 records provided with a response prove NAME ERROR. More... | |
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, struct nsec3_cache_table *ct, int *calc) |
Determine if the NSEC3s provided in a response prove the NOERROR/NODATA status. More... | |
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, struct nsec3_cache_table *ct, int *calc) |
Prove that a positive wildcard match was appropriate (no direct match RRset). More... | |
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, sldns_ede_code *reason_bogus, struct module_qstate *qstate, struct nsec3_cache_table *ct, char *reasonbuf, size_t reasonlen) |
Prove that a DS response either had no DS, or wasn't a delegation point. More... | |
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, struct nsec3_cache_table *ct, int *calc) |
Prove NXDOMAIN or NODATA. More... | |
int | nsec3_hash_cmp (const void *c1, const void *c2) |
Rbtree for hash cache comparison function. More... | |
int | nsec3_cache_table_init (struct nsec3_cache_table *ct, struct regional *region) |
Initialise the NSEC3 cache table. More... | |
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) |
Obtain the hash of an owner name. More... | |
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. More... | |
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. More... | |
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. More... | |
size_t | nsec3_get_hashed (struct sldns_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. More... | |
int | nsec3_has_type (struct ub_packed_rrset_key *rrset, int r, uint16_t type) |
see if NSEC3 RR contains given type More... | |
int | nsec3_has_optout (struct ub_packed_rrset_key *rrset, int r) |
return if nsec3 RR has the optout flag More... | |
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. More... | |
int | nsec3_covers (uint8_t *zone, struct nsec3_cached_hash *hash, struct ub_packed_rrset_key *rrset, int rr, struct sldns_buffer *buf) |
nsec3Covers Given a hash and a candidate NSEC3Record, determine if that NSEC3Record covers the hash. More... | |
This file contains helper functions for the validator module.
The functions help with NSEC3 checking, the different NSEC3 proofs for denial of existence, 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.
#define NSEC3_UNKNOWN_FLAGS 0xFE |
The unknown flags in the NSEC3 flags field.
They must be zero, or the NSEC3 is ignored.
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, | ||
struct nsec3_cache_table * | ct, | ||
int * | calc | ||
) |
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. |
ct | cached hashes table. |
calc | current hash calculations. |
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, | ||
struct nsec3_cache_table * | ct, | ||
int * | calc | ||
) |
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. |
ct | cached hashes table. |
calc | current hash calculations. |
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, | ||
struct nsec3_cache_table * | ct, | ||
int * | calc | ||
) |
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. |
ct | cached hashes table. |
calc | current hash calculations. |
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, | ||
sldns_ede_code * | reason_bogus, | ||
struct module_qstate * | qstate, | ||
struct nsec3_cache_table * | ct, | ||
char * | reasonbuf, | ||
size_t | reasonlen | ||
) |
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. |
reason_bogus | EDE (RFC8914) code paired with the reason of failure. |
qstate | qstate with region. |
ct | cached hashes table. |
reasonbuf | buffer to use for fail reason string print. |
reasonlen | length of reasonbuf. |
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, | ||
struct nsec3_cache_table * | ct, | ||
int * | calc | ||
) |
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. |
ct | cached hashes table. |
calc | current hash calculations. |
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 nsec3_cache_table_init().
int nsec3_cache_table_init | ( | struct nsec3_cache_table * | ct, |
struct regional * | region | ||
) |
Initialise the NSEC3 cache table.
ct | the nsec3 cache table. |
region | the region where allocations for the table will happen. |
References nsec3_hash_cmp(), rbtree_init(), and regional_alloc().
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 | ||
) |
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 initialised 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, nsec3_cached_hash::hash, rbnode_type::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(), and find_matching_nsec3().
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.
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 sldns_b32_ntop_extended_hex().
Referenced by 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_params_ok(), and nsec3_of_param_has_type().
size_t nsec3_get_hashed | ( | struct sldns_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_algo_size_supported(), query_dname_tolower(), secalgo_nsec3_hash(), sldns_buffer_begin(), sldns_buffer_clear(), sldns_buffer_flip(), sldns_buffer_limit(), and sldns_buffer_write().
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 nsec3_no_type(), and nsec3_of_param_has_type().
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.
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, | ||
struct sldns_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 packed_rrset_key::dname, nsec3_cached_hash::hash, label_compare_lower(), nsec3_get_nextowner(), query_dname_compare(), ub_packed_rrset_key::rk, nsec3_cached_hash::rr, sldns_b32_pton_extended_hex(), sldns_buffer_begin(), sldns_buffer_clear(), and sldns_buffer_limit().
Referenced by find_covering_nsec3().