Data Structures | Functions
val_nsec3.c File Reference

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

#include "config.h"
#include <ctype.h>
#include "validator/val_nsec3.h"
#include "validator/val_secalgo.h"
#include "validator/validator.h"
#include "validator/val_kentry.h"
#include "services/cache/rrset.h"
#include "util/regional.h"
#include "util/rbtree.h"
#include "util/module.h"
#include "util/net_help.h"
#include "util/data/packed_rrset.h"
#include "util/data/dname.h"
#include "util/data/msgreply.h"
#include "validator/val_nsec.h"
#include "sldns/sbuffer.h"

Data Structures

struct  ce_response
 Closest encloser (ce) proof results Contains the ce and the next-closer (nc) proof. More...
 
struct  nsec3_filter
 Filter conditions for NSEC3 proof Used to iterate over the applicable NSEC3 RRs. More...
 

Functions

int sldns_b32_ntop_extended_hex (uint8_t const *src, size_t srclength, char *target, size_t targsize)
 This function we get from ldns-compat or from base system it returns the number of data bytes stored at the target, or <0 on error.
 
int sldns_b32_pton_extended_hex (char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize)
 This function we get from ldns-compat or from base system it returns the number of data bytes stored at the target, or <0 on error.
 
static size_t rrset_get_count (struct ub_packed_rrset_key *rrset)
 return number of rrs in an rrset
 
static int nsec3_unknown_flags (struct ub_packed_rrset_key *rrset, int r)
 return if nsec3 RR has unknown flags
 
int nsec3_has_optout (struct ub_packed_rrset_key *rrset, int r)
 return if nsec3 RR has the optout flag More...
 
static int nsec3_get_algo (struct ub_packed_rrset_key *rrset, int r)
 return nsec3 RR algorithm
 
static int nsec3_known_algo (struct ub_packed_rrset_key *rrset, int r)
 return if nsec3 RR has known algorithm
 
static size_t nsec3_get_iter (struct ub_packed_rrset_key *rrset, int r)
 return nsec3 RR iteration count
 
static int nsec3_get_salt (struct ub_packed_rrset_key *rrset, int r, uint8_t **salt, size_t *saltlen)
 return nsec3 RR salt
 
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...
 
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...
 
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...
 
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...
 
int nsec3_has_type (struct ub_packed_rrset_key *rrset, int r, uint16_t type)
 see if NSEC3 RR contains given type More...
 
static struct ub_packed_rrset_keyfilter_next (struct nsec3_filter *filter, size_t *rrsetnum, int *rrnum)
 Iterate through NSEC3 list, per RR This routine gives the next RR in the list (or sets rrset null). More...
 
static struct ub_packed_rrset_keyfilter_first (struct nsec3_filter *filter, size_t *rrsetnum, int *rrnum)
 Start iterating over NSEC3 records. More...
 
static int nsec3_rrset_has_known (struct ub_packed_rrset_key *s)
 see if at least one RR is known (flags, algo)
 
static void filter_init (struct nsec3_filter *filter, struct ub_packed_rrset_key **list, size_t num, struct query_info *qinfo)
 Initialize the filter structure. More...
 
static size_t get_max_iter (struct val_env *ve, size_t bits)
 Find max iteration count using config settings and key size. More...
 
static int nsec3_iteration_count_high (struct val_env *ve, struct nsec3_filter *filter, struct key_entry_key *kkey)
 Determine if any of the NSEC3 rrs iteration count is too high, from key. More...
 
int nsec3_hash_cmp (const void *c1, const void *c2)
 Rbtree for hash cache comparison function. More...
 
size_t nsec3_get_hashed (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...
 
static int nsec3_calc_hash (struct regional *region, sldns_buffer *buf, struct nsec3_cached_hash *c)
 perform hash of name
 
static int nsec3_calc_b32 (struct regional *region, sldns_buffer *buf, struct nsec3_cached_hash *c)
 perform b32 encoding of hash
 
int nsec3_hash_name (rbtree_type *table, struct regional *region, 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...
 
static int label_compare_lower (uint8_t *lab1, uint8_t *lab2, size_t lablen)
 compare a label lowercased
 
static int nsec3_hash_matches_owner (struct nsec3_filter *flt, struct nsec3_cached_hash *hash, struct ub_packed_rrset_key *s)
 Compare a hashed name with the owner name of an NSEC3 RRset. More...
 
static int find_matching_nsec3 (struct module_env *env, struct nsec3_filter *flt, rbtree_type *ct, uint8_t *nm, size_t nmlen, struct ub_packed_rrset_key **rrset, int *rr)
 Find matching NSEC3 Find the NSEC3Record that matches a hash of a name. More...
 
int nsec3_covers (uint8_t *zone, struct nsec3_cached_hash *hash, struct ub_packed_rrset_key *rrset, int rr, sldns_buffer *buf)
 nsec3Covers Given a hash and a candidate NSEC3Record, determine if that NSEC3Record covers the hash. More...
 
static int find_covering_nsec3 (struct module_env *env, struct nsec3_filter *flt, rbtree_type *ct, uint8_t *nm, size_t nmlen, struct ub_packed_rrset_key **rrset, int *rr)
 findCoveringNSEC3 Given a name, find a covering NSEC3 from among a list of NSEC3s. More...
 
static int nsec3_find_closest_encloser (struct module_env *env, struct nsec3_filter *flt, rbtree_type *ct, struct query_info *qinfo, struct ce_response *ce)
 findClosestEncloser Given a name and a list of NSEC3s, find the candidate closest encloser. More...
 
static void next_closer (uint8_t *qname, size_t qnamelen, uint8_t *ce, uint8_t **nm, size_t *nmlen)
 Given a qname and its proven closest encloser, calculate the "next closest" name. More...
 
static enum sec_status nsec3_prove_closest_encloser (struct module_env *env, struct nsec3_filter *flt, rbtree_type *ct, struct query_info *qinfo, int prove_does_not_exist, struct ce_response *ce)
 proveClosestEncloser Given a List of nsec3 RRs, find and prove the closest encloser to qname. More...
 
static uint8_t * nsec3_ce_wildcard (struct regional *region, uint8_t *ce, size_t celen, size_t *len)
 allocate a wildcard for the closest encloser
 
static enum sec_status nsec3_do_prove_nameerror (struct module_env *env, struct nsec3_filter *flt, rbtree_type *ct, struct query_info *qinfo)
 Do the name error proof.
 
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. More...
 
static enum sec_status nsec3_do_prove_nodata (struct module_env *env, struct nsec3_filter *flt, rbtree_type *ct, struct query_info *qinfo)
 Do the nodata proof.
 
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. 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)
 Prove that a positive wildcard match was appropriate (no direct match RRset). More...
 
static int list_is_secure (struct module_env *env, struct val_env *ve, struct ub_packed_rrset_key **list, size_t num, struct key_entry_key *kkey, char **reason)
 test if list is all secure
 
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. 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)
 Prove NXDOMAIN or NODATA. 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.

Function Documentation

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

Referenced by nsec3_do_prove_nameerror(), nsec3_do_prove_nodata(), nsec3_prove_nods(), and nsec3_prove_wildcard().

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

◆ 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_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_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_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_do_prove_nodata(), nsec3_no_type(), nsec3_prove_closest_encloser(), and nsec3_prove_nods().

◆ filter_next()

static struct ub_packed_rrset_key* filter_next ( struct nsec3_filter filter,
size_t *  rrsetnum,
int *  rrnum 
)
static

Iterate through NSEC3 list, per RR This routine gives the next RR in the list (or sets rrset null).

Usage:

size_t rrsetnum; int rrnum; struct ub_packed_rrset_key* rrset; for(rrset=filter_first(filter, &rrsetnum, &rrnum); rrset; rrset=filter_next(filter, &rrsetnum, &rrnum)) do_stuff;

Also filters out o unknown flag NSEC3s o unknown algorithm NSEC3s.

Parameters
filternsec3 filter structure.
rrsetnumin/out rrset number to look at.
rrnumin/out rr number in rrset to look at.
Returns
ptr to the next rrset (or NULL at end).

References nsec3_filter::list, nsec3_filter::num, ub_packed_rrset_key::rk, packed_rrset_key::type, and nsec3_filter::zone.

Referenced by filter_first(), find_covering_nsec3(), find_matching_nsec3(), and nsec3_iteration_count_high().

◆ filter_first()

static struct ub_packed_rrset_key* filter_first ( struct nsec3_filter filter,
size_t *  rrsetnum,
int *  rrnum 
)
static

Start iterating over NSEC3 records.

Parameters
filterthe filter structure, must have been filter_init-ed.
rrsetnumcan be undefined on call, initialised.
rrnumcan be undefined on call, initialised.
Returns
first rrset of an NSEC3, together with rrnum this points to the first RR to examine. Is NULL on empty list.

References filter_next().

Referenced by find_covering_nsec3(), find_matching_nsec3(), and nsec3_iteration_count_high().

◆ filter_init()

static void filter_init ( struct nsec3_filter filter,
struct ub_packed_rrset_key **  list,
size_t  num,
struct query_info qinfo 
)
static

Initialize the filter structure.

Finds the zone by looking at available NSEC3 records and best match. (skips the unknown flag and unknown algo NSEC3s).

Parameters
filternsec3 filter structure.
listlist of rrsets, an array of them.
numnumber of rrsets in list.
qinfoquery name to match a zone for. query type (if DS a higher zone must be chosen) qclass, to filter NSEC3s with.

References nsec3_filter::fclass, nsec3_filter::list, nsec3_filter::num, query_info::qclass, ub_packed_rrset_key::rk, packed_rrset_key::type, nsec3_filter::zone, and nsec3_filter::zone_len.

Referenced by nsec3_prove_nameerror(), nsec3_prove_nodata(), nsec3_prove_nods(), nsec3_prove_nxornodata(), and nsec3_prove_wildcard().

◆ get_max_iter()

static size_t get_max_iter ( struct val_env ve,
size_t  bits 
)
static

Find max iteration count using config settings and key size.

Parameters
vevalidator environment with iteration count config settings.
bitskey size
Returns
max iteration count

References log_assert, val_env::nsec3_keyiter_count, and val_env::nsec3_maxiter.

Referenced by nsec3_iteration_count_high().

◆ nsec3_iteration_count_high()

static int nsec3_iteration_count_high ( struct val_env ve,
struct nsec3_filter filter,
struct key_entry_key kkey 
)
static

Determine if any of the NSEC3 rrs iteration count is too high, from key.

Parameters
vevalidator environment with iteration count config settings.
filterwhat NSEC3s to loop over.
kkeykey entry used for verification; used for iteration counts.
Returns
1 if some nsec3s are above the max iteration count.

References filter_first(), filter_next(), get_max_iter(), key_entry_keysize(), nsec3_get_iter(), VERB_ALGO, and verbose().

Referenced by nsec3_prove_nameerror(), nsec3_prove_nodata(), nsec3_prove_nods(), nsec3_prove_nxornodata(), and nsec3_prove_wildcard().

◆ 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_prove_nameerror(), nsec3_prove_nodata(), nsec3_prove_nods(), nsec3_prove_nxornodata(), and nsec3_prove_wildcard().

◆ 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_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
: 1 on success, either from cache or newly hashed 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, 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_hash_matches_owner()

static int nsec3_hash_matches_owner ( struct nsec3_filter flt,
struct nsec3_cached_hash hash,
struct ub_packed_rrset_key s 
)
static

Compare a hashed name with the owner name of an NSEC3 RRset.

Parameters
fltfilter with zone name.
hashthe hashed name.
srrset with owner name.
Returns
true if matches exactly, false if not.

References nsec3_cached_hash::b32, nsec3_cached_hash::b32_len, packed_rrset_key::dname, label_compare_lower(), query_dname_compare(), ub_packed_rrset_key::rk, and nsec3_filter::zone.

Referenced by find_matching_nsec3().

◆ find_matching_nsec3()

static int find_matching_nsec3 ( struct module_env env,
struct nsec3_filter flt,
rbtree_type ct,
uint8_t *  nm,
size_t  nmlen,
struct ub_packed_rrset_key **  rrset,
int *  rr 
)
static

Find matching NSEC3 Find the NSEC3Record that matches a hash of a name.

Parameters
envmodule environment with temporary region and buffer.
fltthe NSEC3 RR filter, contains zone name and RRs.
ctcached hashes table.
nmname to look for.
nmlenlength of name.
rrsetnsec3 that matches is returned here.
rrrr number in nsec3 rrset that matches.
Returns
true if a matching NSEC3 is found, false if not.

References filter_first(), filter_next(), nsec3_cached_hash::hash, log_err(), nsec3_hash_matches_owner(), nsec3_hash_name(), module_env::scratch, and module_env::scratch_buffer.

Referenced by nsec3_do_prove_nodata(), nsec3_find_closest_encloser(), and nsec3_prove_nods().

◆ 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 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(), nsec3_get_nextowner(), query_dname_compare(), ub_packed_rrset_key::rk, sldns_b32_pton_extended_hex(), sldns_buffer_begin(), sldns_buffer_clear(), and sldns_buffer_limit().

Referenced by find_covering_nsec3().

◆ find_covering_nsec3()

static int find_covering_nsec3 ( struct module_env env,
struct nsec3_filter flt,
rbtree_type ct,
uint8_t *  nm,
size_t  nmlen,
struct ub_packed_rrset_key **  rrset,
int *  rr 
)
static

findCoveringNSEC3 Given a name, find a covering NSEC3 from among a list of NSEC3s.

Parameters
envmodule environment with temporary region and buffer.
fltthe NSEC3 RR filter, contains zone name and RRs.
ctcached hashes table.
nmname to check if covered.
nmlenlength of name.
rrsetcovering NSEC3 rrset is returned here.
rrrr of cover is returned here.
Returns
true if a covering NSEC3 is found, false if not.

References filter_first(), filter_next(), nsec3_cached_hash::hash, log_err(), nsec3_covers(), nsec3_hash_name(), module_env::scratch, module_env::scratch_buffer, and nsec3_filter::zone.

Referenced by nsec3_do_prove_nameerror(), nsec3_prove_closest_encloser(), and nsec3_prove_wildcard().

◆ nsec3_find_closest_encloser()

static int nsec3_find_closest_encloser ( struct module_env env,
struct nsec3_filter flt,
rbtree_type ct,
struct query_info qinfo,
struct ce_response ce 
)
static

findClosestEncloser Given a name and a list of NSEC3s, find the candidate closest encloser.

This will be the first ancestor of 'name' (including itself) to have a matching NSEC3 RR.

Parameters
envmodule environment with temporary region and buffer.
fltthe NSEC3 RR filter, contains zone name and RRs.
ctcached hashes table.
qinfoquery that is verified for.
ceclosest encloser information is returned in here.
Returns
true if a closest encloser candidate is found, false if not.

References ce_response::ce, ce_response::ce_len, ce_response::ce_rr, ce_response::ce_rrset, dname_remove_label(), dname_subdomain_c(), find_matching_nsec3(), query_info::qname, query_info::qname_len, and nsec3_filter::zone.

Referenced by nsec3_prove_closest_encloser().

◆ next_closer()

static void next_closer ( uint8_t *  qname,
size_t  qnamelen,
uint8_t *  ce,
uint8_t **  nm,
size_t *  nmlen 
)
static

Given a qname and its proven closest encloser, calculate the "next closest" name.

Basically, this is the name that is one label longer than the closest encloser that is still a subdomain of qname.

Parameters
qnamequery name.
qnamelenlength of qname.
ceclosest encloser
nmresult name.
nmlenlength of nm.

References dname_count_labels(), and dname_remove_labels().

Referenced by nsec3_prove_closest_encloser(), and nsec3_prove_wildcard().

◆ nsec3_prove_closest_encloser()

static enum sec_status nsec3_prove_closest_encloser ( struct module_env env,
struct nsec3_filter flt,
rbtree_type ct,
struct query_info qinfo,
int  prove_does_not_exist,
struct ce_response ce 
)
static

proveClosestEncloser Given a List of nsec3 RRs, find and prove the closest encloser to qname.

Parameters
envmodule environment with temporary region and buffer.
fltthe NSEC3 RR filter, contains zone name and RRs.
ctcached hashes table.
qinfoquery that is verified for.
prove_does_not_existIf true, then if the closest encloser turns out to be qname, then null is returned. If set true, and the return value is true, then you can be certain that the ce.nc_rrset and ce.nc_rr are set properly.
ceclosest encloser information is returned in here.
Returns
bogus if no closest encloser could be proven. secure if a closest encloser could be proven, ce is set. insecure if the closest-encloser candidate turns out to prove that an insecure delegation exists above the qname.

References ce_response::ce, ce_response::ce_rr, ce_response::ce_rrset, find_covering_nsec3(), LDNS_RR_TYPE_DNAME, LDNS_RR_TYPE_DS, LDNS_RR_TYPE_NS, LDNS_RR_TYPE_SOA, log_nametypeclass(), ce_response::nc_rr, ce_response::nc_rrset, next_closer(), nsec3_find_closest_encloser(), nsec3_has_type(), query_info::qname, query_info::qname_len, query_dname_compare(), sec_status_bogus, sec_status_insecure, sec_status_secure, VERB_ALGO, and verbose().

Referenced by nsec3_do_prove_nameerror(), nsec3_do_prove_nodata(), and nsec3_prove_nods().

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

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

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.

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

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

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.

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

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

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.

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

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

References filter_init(), find_matching_nsec3(), key_entry_isgood(), LDNS_RR_TYPE_DS, LDNS_RR_TYPE_NS, LDNS_RR_TYPE_SOA, 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.

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

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

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.