This file contains helper functions for the validator module. More...
Enumerations | |
enum | val_classification { VAL_CLASS_UNTYPED = 0 , VAL_CLASS_UNKNOWN , VAL_CLASS_POSITIVE , VAL_CLASS_CNAME , VAL_CLASS_NODATA , VAL_CLASS_NAMEERROR , VAL_CLASS_CNAMENOANSWER , VAL_CLASS_REFERRAL , VAL_CLASS_ANY } |
Response classifications for the validator. More... | |
Functions | |
enum val_classification | val_classify_response (uint16_t query_flags, struct query_info *origqinf, struct query_info *qinf, struct reply_info *rep, size_t skip) |
Given a response, classify ANSWER responses into a subtype. More... | |
void | val_find_signer (enum val_classification subtype, struct query_info *qinf, struct reply_info *rep, size_t cname_skip, uint8_t **signer_name, size_t *signer_len) |
Given a response, determine the name of the "signer". More... | |
enum sec_status | val_verify_rrset_entry (struct module_env *env, struct val_env *ve, struct ub_packed_rrset_key *rrset, struct key_entry_key *kkey, char **reason, sldns_ede_code *reason_bogus, sldns_pkt_section section, struct module_qstate *qstate, int *verified, char *reasonbuf, size_t reasonlen) |
Verify RRset with keys from a keyset. More... | |
enum sec_status | val_verify_DNSKEY_with_DS (struct module_env *env, struct val_env *ve, struct ub_packed_rrset_key *dnskey_rrset, struct ub_packed_rrset_key *ds_rrset, uint8_t *sigalg, char **reason, sldns_ede_code *reason_bogus, struct module_qstate *qstate, char *reasonbuf, size_t reasonlen) |
Verify DNSKEYs with DS rrset. More... | |
enum sec_status | val_verify_DNSKEY_with_TA (struct module_env *env, struct val_env *ve, struct ub_packed_rrset_key *dnskey_rrset, struct ub_packed_rrset_key *ta_ds, struct ub_packed_rrset_key *ta_dnskey, uint8_t *sigalg, char **reason, sldns_ede_code *reason_bogus, struct module_qstate *qstate, char *reasonbuf, size_t reasonlen) |
Verify DNSKEYs with DS and DNSKEY rrset. More... | |
struct key_entry_key * | val_verify_new_DNSKEYs (struct regional *region, struct module_env *env, struct val_env *ve, struct ub_packed_rrset_key *dnskey_rrset, struct ub_packed_rrset_key *ds_rrset, int downprot, char **reason, sldns_ede_code *reason_bogus, struct module_qstate *qstate, char *reasonbuf, size_t reasonlen) |
Verify new DNSKEYs with DS rrset. More... | |
struct key_entry_key * | val_verify_new_DNSKEYs_with_ta (struct regional *region, struct module_env *env, struct val_env *ve, struct ub_packed_rrset_key *dnskey_rrset, struct ub_packed_rrset_key *ta_ds_rrset, struct ub_packed_rrset_key *ta_dnskey_rrset, int downprot, char **reason, sldns_ede_code *reason_bogus, struct module_qstate *qstate, char *reasonbuf, size_t reasonlen) |
Verify rrset with trust anchor: DS and DNSKEY rrset. More... | |
int | val_dsset_isusable (struct ub_packed_rrset_key *ds_rrset) |
Determine if DS rrset is usable for validator or not. More... | |
int | val_rrset_wildcard (struct ub_packed_rrset_key *rrset, uint8_t **wc, size_t *wc_len) |
Determine by looking at a signed RRset whether or not the RRset name was the result of a wildcard expansion. More... | |
int | val_chase_cname (struct query_info *qchase, struct reply_info *rep, size_t *cname_skip) |
Chase the cname to the next query name. More... | |
void | val_fill_reply (struct reply_info *chase, struct reply_info *orig, size_t cname_skip, uint8_t *name, size_t len, uint8_t *signer) |
Fill up the chased reply with the content from the original reply; as pointers to those rrsets. More... | |
void | val_reply_remove_auth (struct reply_info *rep, size_t index) |
Remove rrset with index from reply, from the authority section. More... | |
void | val_check_nonsecure (struct module_env *env, struct reply_info *rep) |
Remove all unsigned or non-secure status rrsets from NS and AR sections. More... | |
void | val_mark_indeterminate (struct reply_info *rep, struct val_anchors *anchors, struct rrset_cache *r, struct module_env *env) |
Mark all unchecked rrset entries not below a trust anchor as indeterminate. More... | |
void | val_mark_insecure (struct reply_info *rep, uint8_t *kname, struct rrset_cache *r, struct module_env *env) |
Mark all unchecked rrset entries below a NULL key entry as insecure. More... | |
size_t | val_next_unchecked (struct reply_info *rep, size_t skip) |
Find next unchecked rrset position, return it for skip. More... | |
void | val_find_rrset_signer (struct ub_packed_rrset_key *rrset, uint8_t **sname, size_t *slen) |
Find the signer name for an RRset. More... | |
const char * | val_classification_to_string (enum val_classification subtype) |
Get string to denote the classification result. More... | |
void | val_blacklist (struct sock_list **blacklist, struct regional *region, struct sock_list *origin, int cross) |
Add existing list to blacklist. More... | |
int | val_has_signed_nsecs (struct reply_info *rep, char **reason) |
check if has dnssec info, and if it has signed nsecs. More... | |
int | val_favorite_ds_algo (struct ub_packed_rrset_key *ds_rrset) |
Return algo number for favorite (best) algorithm that we support in DS. More... | |
struct dns_msg * | val_find_DS (struct module_env *env, uint8_t *nm, size_t nmlen, uint16_t c, struct regional *region, uint8_t *topname) |
Find DS denial message in cache. More... | |
This file contains helper functions for the validator module.
enum val_classification |
Response classifications for the validator.
The different types of proofs.
enum val_classification val_classify_response | ( | uint16_t | query_flags, |
struct query_info * | origqinf, | ||
struct query_info * | qinf, | ||
struct reply_info * | rep, | ||
size_t | skip | ||
) |
Given a response, classify ANSWER responses into a subtype.
query_flags | query flags for the original query. |
origqinf | query info. The original query name. |
qinf | query info. The chased query name. |
rep | response. The original response. |
skip | offset into the original response answer section. |
Referenced by processFinished(), and processInit().
void val_find_signer | ( | enum val_classification | subtype, |
struct query_info * | qinf, | ||
struct reply_info * | rep, | ||
size_t | cname_skip, | ||
uint8_t ** | signer_name, | ||
size_t * | signer_len | ||
) |
Given a response, determine the name of the "signer".
This is primarily to determine if the response is, in fact, signed at all, and, if so, what is the name of the most pertinent keyset.
subtype | the type from classify. |
qinf | query, the chased query name. |
rep | response to that, original response. |
cname_skip | how many answer rrsets have been skipped due to CNAME chains being chased around. |
signer_name | signer name, if the response is signed (even partially), or null if the response isn't signed. |
signer_len | length of signer_name of 0 if signer_name is NULL. |
References reply_info::an_numrrsets, cname_under_previous_dname(), packed_rrset_key::dname, dname_strict_subdomain_c(), LDNS_RR_TYPE_CNAME, LDNS_RR_TYPE_DNAME, reply_info::ns_numrrsets, query_info::qname, query_info::qtype, query_dname_compare(), ub_packed_rrset_key::rk, reply_info::rrsets, packed_rrset_key::type, VAL_CLASS_CNAME, VAL_CLASS_NAMEERROR, VAL_CLASS_NODATA, VAL_CLASS_POSITIVE, and val_find_rrset_signer().
enum sec_status val_verify_rrset_entry | ( | struct module_env * | env, |
struct val_env * | ve, | ||
struct ub_packed_rrset_key * | rrset, | ||
struct key_entry_key * | kkey, | ||
char ** | reason, | ||
sldns_ede_code * | reason_bogus, | ||
sldns_pkt_section | section, | ||
struct module_qstate * | qstate, | ||
int * | verified, | ||
char * | reasonbuf, | ||
size_t | reasonlen | ||
) |
Verify RRset with keys from a keyset.
env | module environment (scratch buffer) |
ve | validator environment (verification settings) |
rrset | what to verify |
kkey | key_entry to verify with. |
reason | reason of failure. Fixed string or alloced in scratch. |
reason_bogus | EDE (RFC8914) code paired with the reason of failure. |
section | section of packet where this rrset comes from. |
qstate | qstate with region. |
verified | if not NULL, the number of RRSIG validations is returned. |
reasonbuf | buffer to use for fail reason string print. |
reasonlen | length of reasonbuf. |
Referenced by nsec_verify_rrset().
enum sec_status val_verify_DNSKEY_with_DS | ( | struct module_env * | env, |
struct val_env * | ve, | ||
struct ub_packed_rrset_key * | dnskey_rrset, | ||
struct ub_packed_rrset_key * | ds_rrset, | ||
uint8_t * | sigalg, | ||
char ** | reason, | ||
sldns_ede_code * | reason_bogus, | ||
struct module_qstate * | qstate, | ||
char * | reasonbuf, | ||
size_t | reasonlen | ||
) |
Verify DNSKEYs with DS rrset.
Like val_verify_new_DNSKEYs but returns a sec_status instead of a key_entry.
env | module environment (scratch buffer) |
ve | validator environment (verification settings) |
dnskey_rrset | DNSKEY rrset to verify |
ds_rrset | DS rrset to verify with. |
sigalg | if nonNULL provide downgrade protection otherwise one algorithm is enough. The list of signalled algorithms is returned, must have enough space for ALGO_NEEDS_MAX+1. |
reason | reason of failure. Fixed string or alloced in scratch. |
reason_bogus | EDE (RFC8914) code paired with the reason of failure. |
qstate | qstate with region. |
reasonbuf | buffer to use for fail reason string print. |
reasonlen | length of reasonbuf. |
Referenced by val_verify_DNSKEY_with_TA().
enum sec_status val_verify_DNSKEY_with_TA | ( | struct module_env * | env, |
struct val_env * | ve, | ||
struct ub_packed_rrset_key * | dnskey_rrset, | ||
struct ub_packed_rrset_key * | ta_ds, | ||
struct ub_packed_rrset_key * | ta_dnskey, | ||
uint8_t * | sigalg, | ||
char ** | reason, | ||
sldns_ede_code * | reason_bogus, | ||
struct module_qstate * | qstate, | ||
char * | reasonbuf, | ||
size_t | reasonlen | ||
) |
Verify DNSKEYs with DS and DNSKEY rrset.
Like val_verify_DNSKEY_with_DS but for a trust anchor.
env | module environment (scratch buffer) |
ve | validator environment (verification settings) |
dnskey_rrset | DNSKEY rrset to verify |
ta_ds | DS rrset to verify with. |
ta_dnskey | DNSKEY rrset to verify with. |
sigalg | if nonNULL provide downgrade protection otherwise one algorithm is enough. The list of signalled algorithms is returned, must have enough space for ALGO_NEEDS_MAX+1. |
reason | reason of failure. Fixed string or alloced in scratch. |
reason_bogus | EDE (RFC8914) code paired with the reason of failure. |
qstate | qstate with region. |
reasonbuf | buffer to use for fail reason string print. |
reasonlen | length of reasonbuf. |
References ALGO_NEEDS_MAX, packed_rrset_key::dname, packed_rrset_key::dname_len, key_entry_create_rrset(), ub_packed_rrset_key::rk, packed_rrset_key::rrset_class, sec_status_secure, and val_verify_DNSKEY_with_DS().
Referenced by val_verify_new_DNSKEYs_with_ta(), and verify_dnskey().
struct key_entry_key* val_verify_new_DNSKEYs | ( | struct regional * | region, |
struct module_env * | env, | ||
struct val_env * | ve, | ||
struct ub_packed_rrset_key * | dnskey_rrset, | ||
struct ub_packed_rrset_key * | ds_rrset, | ||
int | downprot, | ||
char ** | reason, | ||
sldns_ede_code * | reason_bogus, | ||
struct module_qstate * | qstate, | ||
char * | reasonbuf, | ||
size_t | reasonlen | ||
) |
Verify new DNSKEYs with DS rrset.
The DS contains hash values that should match the DNSKEY keys. match the DS to a DNSKEY and verify the DNSKEY rrset with that key.
region | where to allocate key entry result. |
env | module environment (scratch buffer) |
ve | validator environment (verification settings) |
dnskey_rrset | DNSKEY rrset to verify |
ds_rrset | DS rrset to verify with. |
downprot | if true provide downgrade protection otherwise one algorithm is enough. |
reason | reason of failure. Fixed string or alloced in scratch. |
reason_bogus | EDE (RFC8914) code paired with the reason of failure. |
qstate | qstate with region. |
reasonbuf | buffer to use for fail reason string print. |
reasonlen | length of reasonbuf. |
struct key_entry_key* val_verify_new_DNSKEYs_with_ta | ( | struct regional * | region, |
struct module_env * | env, | ||
struct val_env * | ve, | ||
struct ub_packed_rrset_key * | dnskey_rrset, | ||
struct ub_packed_rrset_key * | ta_ds_rrset, | ||
struct ub_packed_rrset_key * | ta_dnskey_rrset, | ||
int | downprot, | ||
char ** | reason, | ||
sldns_ede_code * | reason_bogus, | ||
struct module_qstate * | qstate, | ||
char * | reasonbuf, | ||
size_t | reasonlen | ||
) |
Verify rrset with trust anchor: DS and DNSKEY rrset.
region | where to allocate key entry result. |
env | module environment (scratch buffer) |
ve | validator environment (verification settings) |
dnskey_rrset | DNSKEY rrset to verify |
ta_ds_rrset | DS rrset to verify with. |
ta_dnskey_rrset | the DNSKEY rrset to verify with. |
downprot | if true provide downgrade protection otherwise one algorithm is enough. |
reason | reason of failure. Fixed string or alloced in scratch. |
reason_bogus | EDE (RFC8914) code paired with the reason of failure. |
qstate | qstate with region. |
reasonbuf | buffer to use for fail reason string print. |
reasonlen | length of reasonbuf. |
References ALGO_NEEDS_MAX, packed_rrset_key::dname, packed_rrset_key::dname_len, key_entry_create_rrset(), ub_packed_rrset_key::rk, packed_rrset_key::rrset_class, sec_status_secure, and val_verify_DNSKEY_with_TA().
int val_dsset_isusable | ( | struct ub_packed_rrset_key * | ds_rrset | ) |
Determine if DS rrset is usable for validator or not.
Returns true if the algorithms for key and DShash are supported, for at least one RR.
ds_rrset | the newly received DS rrset. |
References ds_digest_algo_is_supported(), ds_get_digest_algo(), ds_get_key_algo(), ds_key_algo_is_supported(), rrset_get_count(), sldns_algorithms, sldns_hashes, sldns_lookup_by_id(), VERB_ALGO, verbose(), and verbosity.
int val_rrset_wildcard | ( | struct ub_packed_rrset_key * | rrset, |
uint8_t ** | wc, | ||
size_t * | wc_len | ||
) |
Determine by looking at a signed RRset whether or not the RRset name was the result of a wildcard expansion.
If so, return the name of the generating wildcard.
rrset | The rrset to check. |
wc | the wildcard name, if the rrset was synthesized from a wildcard. unchanged if not. The wildcard name, without "*." in front, is returned. This is a pointer into the rrset owner name. |
wc_len | the length of the returned wildcard name. |
References packed_rrset_data::count, packed_rrset_key::dname, dname_count_labels(), dname_is_wild(), packed_rrset_key::dname_len, dname_remove_labels(), ub_packed_rrset_key::rk, packed_rrset_data::rrsig_count, and rrsig_get_labcount().
Referenced by dns_cache_lookup(), validate_cname_response(), and validate_positive_response().
int val_chase_cname | ( | struct query_info * | qchase, |
struct reply_info * | rep, | ||
size_t * | cname_skip | ||
) |
Chase the cname to the next query name.
qchase | the current query name, updated to next target. |
rep | original message reply to look at CNAMEs. |
cname_skip | the skip into the answer section. Updated to skip DNAME and CNAME to the next part of the answer. |
References reply_info::an_numrrsets, get_cname_target(), LDNS_RR_TYPE_CNAME, query_info::qname, query_info::qname_len, query_dname_compare(), ub_packed_rrset_key::rk, reply_info::rrsets, and packed_rrset_key::type.
void val_fill_reply | ( | struct reply_info * | chase, |
struct reply_info * | orig, | ||
size_t | cname_skip, | ||
uint8_t * | name, | ||
size_t | len, | ||
uint8_t * | signer | ||
) |
Fill up the chased reply with the content from the original reply; as pointers to those rrsets.
Select the part after the cname_skip into the answer section, NS and AR sections that are signed with same signer.
chase | chased reply, filled up. |
orig | original reply. |
cname_skip | which part of the answer section to skip. The skipped part contains CNAME(and DNAME)s that have been chased. |
name | the signer name to look for. |
len | length of name. |
signer | signer name or NULL if an unsigned RRset is considered. If NULL, rrsets with the lookup name are copied over. |
References reply_info::an_numrrsets, reply_info::ar_numrrsets, cname_under_previous_dname(), packed_rrset_key::dname, LDNS_RR_TYPE_CNAME, LDNS_RR_TYPE_DNAME, reply_info::ns_numrrsets, query_dname_compare(), ub_packed_rrset_key::rk, reply_info::rrset_count, rrset_has_signer(), reply_info::rrsets, and packed_rrset_key::type.
void val_reply_remove_auth | ( | struct reply_info * | rep, |
size_t | index | ||
) |
Remove rrset with index from reply, from the authority section.
rep | reply to remove it from. |
index | rrset to remove, must be in the authority section. |
References reply_info::an_numrrsets, log_assert, reply_info::ns_numrrsets, reply_info::rrset_count, and reply_info::rrsets.
Referenced by remove_spurious_authority().
void val_check_nonsecure | ( | struct module_env * | env, |
struct reply_info * | rep | ||
) |
Remove all unsigned or non-secure status rrsets from NS and AR sections.
So that unsigned data does not get let through to clients, when we have found the data to be secure.
env | environment with cleaning options. |
rep | reply to dump all nonsecure stuff out of. |
References reply_info::an_numrrsets, reply_info::ar_numrrsets, module_env::cfg, lruhash_entry::data, packed_rrset_key::dname, ub_packed_rrset_key::entry, LDNS_RR_TYPE_NS, log_nametypeclass(), reply_info::ns_numrrsets, ub_packed_rrset_key::rk, packed_rrset_key::rrset_class, reply_info::rrset_count, reply_info::rrsets, sec_status_bogus, sec_status_secure, reply_info::security, packed_rrset_key::type, config_file::val_clean_additional, VERB_ALGO, VERB_QUERY, and verbose().
void val_mark_indeterminate | ( | struct reply_info * | rep, |
struct val_anchors * | anchors, | ||
struct rrset_cache * | r, | ||
struct module_env * | env | ||
) |
Mark all unchecked rrset entries not below a trust anchor as indeterminate.
Only security==unchecked rrsets are updated.
rep | the reply with rrsets. |
anchors | the trust anchors. |
r | rrset cache to store updated security status into. |
env | module environment |
References check_no_anchor(), lruhash_entry::data, packed_rrset_key::dname, packed_rrset_key::dname_len, ub_packed_rrset_key::entry, module_env::now, ub_packed_rrset_key::rk, packed_rrset_key::rrset_class, reply_info::rrset_count, rrset_update_sec_status(), reply_info::rrsets, sec_status_indeterminate, sec_status_unchecked, and packed_rrset_data::security.
void val_mark_insecure | ( | struct reply_info * | rep, |
uint8_t * | kname, | ||
struct rrset_cache * | r, | ||
struct module_env * | env | ||
) |
Mark all unchecked rrset entries below a NULL key entry as insecure.
Only security==unchecked rrsets are updated.
rep | the reply with rrsets. |
kname | end of secure space name. |
r | rrset cache to store updated security status into. |
env | module environment |
References lruhash_entry::data, packed_rrset_key::dname, dname_subdomain_c(), ub_packed_rrset_key::entry, module_env::now, ub_packed_rrset_key::rk, reply_info::rrset_count, rrset_update_sec_status(), reply_info::rrsets, sec_status_insecure, sec_status_unchecked, and packed_rrset_data::security.
Referenced by processValidate().
size_t val_next_unchecked | ( | struct reply_info * | rep, |
size_t | skip | ||
) |
Find next unchecked rrset position, return it for skip.
rep | the original reply to look into. |
skip | the skip now. |
References lruhash_entry::data, ub_packed_rrset_key::entry, reply_info::rrset_count, reply_info::rrsets, sec_status_unchecked, and packed_rrset_data::security.
void val_find_rrset_signer | ( | struct ub_packed_rrset_key * | rrset, |
uint8_t ** | sname, | ||
size_t * | slen | ||
) |
Find the signer name for an RRset.
rrset | the rrset. |
sname | signer name is returned or NULL if not signed. |
slen | length of sname (or 0). |
References packed_rrset_data::count, lruhash_entry::data, ub_packed_rrset_key::entry, packed_rrset_data::rr_data, packed_rrset_data::rr_len, packed_rrset_data::rrsig_count, and rrsig_get_signer().
Referenced by iter_ds_toolow(), and val_find_signer().
const char* val_classification_to_string | ( | enum val_classification | subtype | ) |
Get string to denote the classification result.
subtype | from classification function. |
References VAL_CLASS_ANY, VAL_CLASS_CNAME, VAL_CLASS_CNAMENOANSWER, VAL_CLASS_NAMEERROR, VAL_CLASS_NODATA, VAL_CLASS_POSITIVE, VAL_CLASS_REFERRAL, VAL_CLASS_UNKNOWN, and VAL_CLASS_UNTYPED.
void val_blacklist | ( | struct sock_list ** | blacklist, |
struct regional * | region, | ||
struct sock_list * | origin, | ||
int | cross | ||
) |
Add existing list to blacklist.
blacklist | the blacklist with result |
region | the region where blacklist is allocated. Allocation failures are logged. |
origin | origin list to add, if NULL, a cache-entry is added to the blacklist to stop cache from being used. |
cross | if true this is a cross-qstate copy, and the 'origin' list is not allocated in the same region as the blacklist. |
References sock_list::next, sock_list_insert(), sock_list_logentry(), sock_list_merge(), sock_list_prepend(), VERB_ALGO, verbose(), and verbosity.
Referenced by process_ds_response().
int val_has_signed_nsecs | ( | struct reply_info * | rep, |
char ** | reason | ||
) |
check if has dnssec info, and if it has signed nsecs.
gives error reason.
rep | reply to check. |
reason | returned on fail. |
References reply_info::an_numrrsets, reply_info::ns_numrrsets, ub_packed_rrset_key::rk, reply_info::rrsets, and packed_rrset_key::type.
int val_favorite_ds_algo | ( | struct ub_packed_rrset_key * | ds_rrset | ) |
Return algo number for favorite (best) algorithm that we support in DS.
ds_rrset | the DSes in this rrset are inspected and best algo chosen. |
References ds_digest_algo_is_supported(), ds_get_digest_algo(), ds_key_algo_is_supported(), and rrset_get_count().
Referenced by key_matches_a_ds().
struct dns_msg* val_find_DS | ( | struct module_env * | env, |
uint8_t * | nm, | ||
size_t | nmlen, | ||
uint16_t | c, | ||
struct regional * | region, | ||
uint8_t * | topname | ||
) |
Find DS denial message in cache.
Saves new qstate allocation and allows the validator to use partial content which is not enough to construct a message for network (or user) consumption. Without SOA for example, which is a common occurrence in the unbound code since the referrals contain NSEC/NSEC3 rrs without the SOA element, thus do not allow synthesis of a full negative reply, but do allow synthesis of sufficient proof.
env | query env with caches and time. |
nm | name of DS record sought. |
nmlen | length of name. |
c | class of DS RR. |
region | where to allocate result. |
topname | name of the key that is currently in use, that will get used to validate the result, and thus no higher entries from the negative cache need to be examined. |
References reply_info::an_numrrsets, module_env::cfg, dns_msg_create(), ub_packed_rrset_key::entry, LDNS_RR_TYPE_DS, query_info::local_alias, lruhash_entry::lock, module_env::neg_cache, module_env::now, packed_rrset_copy_region(), query_info::qclass, query_info::qname, query_info::qname_len, query_info::qtype, dns_msg::rep, module_env::rrset_cache, rrset_cache_lookup(), reply_info::rrset_count, reply_info::rrsets, module_env::scratch_buffer, and val_neg_getmsg().