val_nsec3.h File Reference

This file contains helper functions for the validator module. More...

#include "util/rbtree.h"
#include "util/data/packed_rrset.h"
#include "sldns/rrdef.h"

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...
 

Detailed Description

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 / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Macro Definition Documentation

◆ NSEC3_OPTOUT

#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.

◆ NSEC3_UNKNOWN_FLAGS

#define NSEC3_UNKNOWN_FLAGS   0xFE

The unknown flags in the NSEC3 flags field.

They must be zero, or the NSEC3 is ignored.

Function Documentation

◆ nsec3_prove_nameerror()

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.

Parameters
envmodule environment with temporary region and buffer.
vevalidator environment, with iteration count settings.
listarray of RRsets, some of which are NSEC3s.
numnumber of RRsets in the array to examine.
qinfoquery that is verified for.
kkeykey entry that signed the NSEC3s.
ctcached hashes table.
calccurrent hash calculations.
Returns
: sec_status SECURE of the Name Error is proven by the NSEC3 RRs, BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored, UNCHECKED if no more hash calculations are allowed at this point.

◆ nsec3_prove_nodata()

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)

Parameters
envmodule environment with temporary region and buffer.
vevalidator environment, with iteration count settings.
listarray of RRsets, some of which are NSEC3s.
numnumber of RRsets in the array to examine.
qinfoquery that is verified for.
kkeykey entry that signed the NSEC3s.
ctcached hashes table.
calccurrent hash calculations.
Returns
: sec_status SECURE of the proposition is proven by the NSEC3 RRs, BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored, UNCHECKED if no more hash calculations are allowed at this point.

◆ nsec3_prove_wildcard()

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).

Parameters
envmodule environment with temporary region and buffer.
vevalidator environment, with iteration count settings.
listarray of RRsets, some of which are NSEC3s.
numnumber of RRsets in the array to examine.
qinfoquery that is verified for.
kkeykey entry that signed the NSEC3s.
wcThe purported wildcard that matched. This is the wildcard name as *.wildcard.name., with the *. label already removed.
ctcached hashes table.
calccurrent hash calculations.
Returns
: sec_status SECURE of the proposition is proven by the NSEC3 RRs, BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored, UNCHECKED if no more hash calculations are allowed at this point.

◆ nsec3_prove_nods()

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.

Parameters
envmodule environment with temporary region and buffer.
vevalidator environment, with iteration count settings.
listarray of RRsets, some of which are NSEC3s.
numnumber of RRsets in the array to examine.
qinfoquery that is verified for.
kkeykey entry that signed the NSEC3s.
reasonstring for bogus result.
reason_bogusEDE (RFC8914) code paired with the reason of failure.
qstateqstate with region.
ctcached hashes table.
reasonbufbuffer to use for fail reason string print.
reasonlenlength of reasonbuf.
Returns
: sec_status SECURE of the proposition is proven by the NSEC3 RRs, BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored. or if there was no DS in an insecure (i.e., opt-in) way, INDETERMINATE if it was clear that this wasn't a delegation point, UNCHECKED if no more hash calculations are allowed at this point.

◆ nsec3_prove_nxornodata()

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.

Parameters
envmodule environment with temporary region and buffer.
vevalidator environment, with iteration count settings.
listarray of RRsets, some of which are NSEC3s.
numnumber of RRsets in the array to examine.
qinfoquery that is verified for.
kkeykey entry that signed the NSEC3s.
nodataif return value is secure, this indicates if nodata or nxdomain was proven.
ctcached hashes table.
calccurrent hash calculations.
Returns
: sec_status SECURE of the proposition is proven by the NSEC3 RRs, BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored, UNCHECKED if no more hash calculations are allowed at this point.

◆ nsec3_hash_cmp()

int nsec3_hash_cmp ( const void *  c1,
const void *  c2 
)

Rbtree for hash cache comparison function.

Parameters
c1key 1.
c2key 2.
Returns
: comparison code, -1, 0, 1, of the keys.

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().

◆ nsec3_cache_table_init()

int nsec3_cache_table_init ( struct nsec3_cache_table ct,
struct regional region 
)

Initialise the NSEC3 cache table.

Parameters
ctthe nsec3 cache table.
regionthe region where allocations for the table will happen.
Returns
true on success, false on malloc error.

References nsec3_hash_cmp(), rbtree_init(), and regional_alloc().

◆ nsec3_hash_name()

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.

Parameters
tablethe cache table. Must be initialised at start.
regionscratch region to use for allocation. This region holds the tree, if you wipe the region, reinit the tree.
buftemporary buffer.
nsec3the rrset with parameters
rrrr number from d that has the NSEC3 parameters to hash to.
dnamename to hash This pointer is used inside the tree, assumed region-alloced.
dname_lenthe length of the name.
hashthe hash node is returned on success.
Returns
: 2 on success, hash from cache is returned. 1 on success, newly computed hash is returned. 0 on a malloc failure. -1 if the NSEC3 rr was badly formatted (i.e. formerr).

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().

◆ nsec3_get_nextowner_b32()

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.

Parameters
rrsetthe NSEC3 rrset.
rthe rr num of the nsec3 in the rrset.
bufbuffer to store name in
maxsize of buffer.
Returns
length of name on success. 0 on failure (buffer too short or bad format nsec3 record).

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.

◆ nsec3_hash_to_b32()

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.

Parameters
hashhashed buffer
hashlenlength of hash
zonename of zone
zonelenlength of zonename.
bufbuffer to store name in
maxsize of buffer.
Returns
length of name on success. 0 on failure (buffer too short or bad format nsec3 record).

References sldns_b32_ntop_extended_hex().

Referenced by neg_nsec3_getnc(), and nsec3_get_nextowner_b32().

◆ nsec3_get_params()

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.

Parameters
rrsetthe NSEC3 rrset.
rthe rr num of the nsec3 in the rrset.
algonsec3 hash algo.
iteriteration count.
saltptr to salt inside rdata.
saltlenlength of salt.
Returns
0 if bad formatted, unknown nsec3 hash algo, or unknown flags set.

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().

◆ nsec3_get_hashed()

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.

Parameters
bufbuffer for temp use.
nmname to hash
nmlenlength of nm.
algoalgo to use, must be known.
iteriterations
saltsalt for nsec3
saltlenlength of salt.
resresult of hash stored here.
maxmaximum space for result.
Returns
0 on failure, otherwise bytelength stored.

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().

◆ nsec3_has_type()

int nsec3_has_type ( struct ub_packed_rrset_key rrset,
int  r,
uint16_t  type 
)

see if NSEC3 RR contains given type

Parameters
rrsetNSEC3 rrset
rRR in rrset
typein host order to check bit for.
Returns
true if bit set, false if not or error.

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().

◆ nsec3_has_optout()

int nsec3_has_optout ( struct ub_packed_rrset_key rrset,
int  r 
)

return if nsec3 RR has the optout flag

Parameters
rrsetNSEC3 rrset
rRR in rrset
Returns
true if optout, false on error or not optout

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.

◆ nsec3_get_nextowner()

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.

Parameters
rrsetNSEC3 rrset
rRR in rrset
nextptr into rdata to next owner hash
nextlenlength of hash.
Returns
false on malformed

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().

◆ nsec3_covers()

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.

Parameters
zonethe zone name.
hashthe hash of the name
rrsetthe rrset of the NSEC3.
rrwhich rr in the rrset.
buftemporary buffer.
Returns
true if covers, false if not.

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().