unbound: validator/val_sigcrypt.c File Reference

unbound 0.1

Data Structures | Functions
val_sigcrypt.c File Reference

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

`#include "config.h"`
`#include "validator/val_sigcrypt.h"`
`#include "validator/val_secalgo.h"`
`#include "validator/validator.h"`
`#include "util/data/msgreply.h"`
`#include "util/data/msgparse.h"`
`#include "util/data/dname.h"`
`#include "util/rbtree.h"`
`#include "util/module.h"`
`#include "util/net_help.h"`
`#include "util/regional.h"`
`#include "util/config_file.h"`
`#include "sldns/keyraw.h"`
`#include "sldns/sbuffer.h"`
`#include "sldns/parseutil.h"`
`#include "sldns/wire2str.h"`
`#include <ctype.h>`

## Data Structures
struct | canon_rr
| RR entries in a canonical sorted tree of RRs. More...

## Functions
static size_t | rrset_get_count (struct ub_packed_rrset_key *rrset)
| return number of rrs in an rrset
static size_t | rrset_get_sigcount (struct ub_packed_rrset_key *k)
| Get RR signature count.
static uint16_t | rrset_get_sig_keytag (struct ub_packed_rrset_key *k, size_t sig_idx)
| Get signature keytag value.
static int | rrset_get_sig_algo (struct ub_packed_rrset_key *k, size_t sig_idx)
| Get signature signing algorithm value.
static void | rrset_get_rdata (struct ub_packed_rrset_key *k, size_t idx, uint8_t **rdata, size_t *len)
| get rdata pointer and size
uint16_t | dnskey_get_flags (struct ub_packed_rrset_key *k, size_t idx)
| Get DNSKEY RR flags.
static int | dnskey_get_protocol (struct ub_packed_rrset_key *k, size_t idx)
| Get DNSKEY protocol value from rdata.
int | dnskey_get_algo (struct ub_packed_rrset_key *k, size_t idx)
| Get DNSKEY RR signature algorithm.
static void | dnskey_get_pubkey (struct ub_packed_rrset_key *k, size_t idx, unsigned char **pk, unsigned int *pklen)
| get public key rdata field from a dnskey RR and do some checks
int | ds_get_key_algo (struct ub_packed_rrset_key *k, size_t idx)
| Get DS RR key algorithm.
int | ds_get_digest_algo (struct ub_packed_rrset_key *k, size_t idx)
| Get DS RR digest algorithm.
uint16_t | ds_get_keytag (struct ub_packed_rrset_key *ds_rrset, size_t ds_idx)
| Get DS keytag, footprint value that matches the DNSKEY keytag it signs.
static void | ds_get_sigdata (struct ub_packed_rrset_key *k, size_t idx, uint8_t **digest, size_t *len)
| Return pointer to the digest in a DS RR.
static size_t | ds_digest_size_algo (struct ub_packed_rrset_key *k, size_t idx)
| Return size of DS digest according to its hash algorithm.
static int | ds_create_dnskey_digest (struct module_env *env, struct ub_packed_rrset_key *dnskey_rrset, size_t dnskey_idx, struct ub_packed_rrset_key *ds_rrset, size_t ds_idx, uint8_t *digest)
| Create a DS digest for a DNSKEY entry.
int | ds_digest_match_dnskey (struct module_env *env, struct ub_packed_rrset_key *dnskey_rrset, size_t dnskey_idx, struct ub_packed_rrset_key *ds_rrset, size_t ds_idx)
| Check if dnskey matches a DS digest Does not check dnskey-keyid footprint, just the digest.
int | ds_digest_algo_is_supported (struct ub_packed_rrset_key *ds_rrset, size_t ds_idx)
| See if DS digest algorithm is supported.
int | ds_key_algo_is_supported (struct ub_packed_rrset_key *ds_rrset, size_t ds_idx)
| See if DS key algorithm is supported.
uint16_t | dnskey_calc_keytag (struct ub_packed_rrset_key *dnskey_rrset, size_t dnskey_idx)
| Get dnskey keytag, footprint value.
int | dnskey_algo_is_supported (struct ub_packed_rrset_key *dnskey_rrset, size_t dnskey_idx)
| See if DNSKEY algorithm is supported.
int | dnskey_size_is_supported (struct ub_packed_rrset_key *dnskey_rrset, size_t dnskey_idx)
| See if the DNSKEY size at that algorithm is supported.
int | dnskeyset_size_is_supported (struct ub_packed_rrset_key *dnskey_rrset)
| See if the DNSKEY size at that algorithm is supported for all the RRs in the DNSKEY RRset.
void | algo_needs_init_dnskey_add (struct algo_needs *n, struct ub_packed_rrset_key *dnskey, uint8_t *sigalg)
| Initialize algo needs structure, set algos from rrset as needed.
void | algo_needs_init_list (struct algo_needs *n, uint8_t *sigalg)
| Initialize algo needs structure from a signalled algo list.
void | algo_needs_init_ds (struct algo_needs *n, struct ub_packed_rrset_key *ds, int fav_ds_algo, uint8_t *sigalg)
| Initialize algo needs structure, set algos from rrset as needed.
int | algo_needs_set_secure (struct algo_needs *n, uint8_t algo)
| Mark this algorithm as a success, sec_secure, and see if we are done.
void | algo_needs_set_bogus (struct algo_needs *n, uint8_t algo)
| Mark this algorithm a failure, sec_bogus.
size_t | algo_needs_num_missing (struct algo_needs *n)
| See how many algorithms are missing (not bogus or secure, but not processed)
int | algo_needs_missing (struct algo_needs *n)
| See which algo is missing.
static enum sec_status | dnskeyset_verify_rrset_sig (struct module_env *env, struct val_env *ve, time_t now, struct ub_packed_rrset_key *rrset, struct ub_packed_rrset_key *dnskey, size_t sig_idx, struct rbtree_type **sortree, char **reason, sldns_ede_code *reason_bogus, sldns_pkt_section section, struct module_qstate *qstate)
| verify rrset, with dnskey rrset, for a specific rrsig in rrset
enum sec_status | dnskeyset_verify_rrset (struct module_env *env, struct val_env *ve, struct ub_packed_rrset_key *rrset, struct ub_packed_rrset_key *dnskey, uint8_t *sigalg, char **reason, sldns_ede_code *reason_bogus, sldns_pkt_section section, struct module_qstate *qstate)
| Verify rrset against dnskey rrset.
void | algo_needs_reason (struct module_env *env, int alg, char **reason, char *s)
| Format error reason for algorithm missing.
enum sec_status | dnskey_verify_rrset (struct module_env *env, struct val_env *ve, struct ub_packed_rrset_key *rrset, struct ub_packed_rrset_key *dnskey, size_t dnskey_idx, char **reason, sldns_ede_code *reason_bogus, sldns_pkt_section section, struct module_qstate *qstate)
| verify rrset against one specific dnskey (from rrset)
static int | canonical_compare_byfield (struct packed_rrset_data *d, const sldns_rr_descriptor *desc, size_t i, size_t j)
| Compare two RR for canonical order, in a field-style sweep.
static int | canonical_compare (struct ub_packed_rrset_key *rrset, size_t i, size_t j)
| Compare two RRs in the same RRset and determine their relative canonical order.
int | canonical_tree_compare (const void *k1, const void *k2)
| canonical compare for two tree entries
static void | canonical_sort (struct ub_packed_rrset_key *rrset, struct packed_rrset_data *d, rbtree_type *sortree, struct canon_rr *rrs)
| Sort RRs for rrset in canonical order.
static void | insert_can_owner (sldns_buffer *buf, struct ub_packed_rrset_key *k, uint8_t *sig, uint8_t **can_owner, size_t *can_owner_len)
| Insert canonical owner name into buffer.
static void | canonicalize_rdata (sldns_buffer *buf, struct ub_packed_rrset_key *rrset, size_t len)
| Canonicalize Rdata in buffer.
int | rrset_canonical_equal (struct regional *region, struct ub_packed_rrset_key *k1, struct ub_packed_rrset_key *k2)
| Compare two rrsets and see if they are the same, canonicalised.
static int | rrset_canonical (struct regional *region, sldns_buffer *buf, struct ub_packed_rrset_key *k, uint8_t *sig, size_t siglen, struct rbtree_type **sortree, sldns_pkt_section section, struct module_qstate *qstate)
| Create canonical form of rrset in the scratch buffer.
int | rrset_canonicalize_to_buffer (struct regional *region, sldns_buffer *buf, struct ub_packed_rrset_key *k)
| Canonicalize an rrset into the buffer.
static void | sigdate_error (const char *str, int32_t expi, int32_t incep, int32_t now)
| pretty print rrsig error with dates
static int | compare_1982 (uint32_t a, uint32_t b)
| RFC 1982 comparison, uses unsigned integers, and tries to avoid compiler optimization (eg.
static uint32_t | subtract_1982 (uint32_t a, uint32_t b)
| if we know that b is larger than a, return the difference between them, that is the distance between them.
static int | check_dates (struct val_env *ve, uint32_t unow, uint8_t *expi_p, uint8_t *incep_p, char **reason, sldns_ede_code *reason_bogus)
| check rrsig dates
static void | adjust_ttl (struct val_env *ve, uint32_t unow, struct ub_packed_rrset_key *rrset, uint8_t *orig_p, uint8_t *expi_p, uint8_t *incep_p)
| adjust rrset TTL for verified rrset, compare to original TTL and expi
enum sec_status | dnskey_verify_rrset_sig (struct regional *region, sldns_buffer *buf, struct val_env *ve, time_t now, struct ub_packed_rrset_key *rrset, struct ub_packed_rrset_key *dnskey, size_t dnskey_idx, size_t sig_idx, struct rbtree_type **sortree, int *buf_canon, char **reason, sldns_ede_code *reason_bogus, sldns_pkt_section section, struct module_qstate *qstate)
| verify rrset, with specific dnskey(from set), for a specific rrsig

## Detailed Description

This file contains helper functions for the validator module.

The functions help with signature verification and checking, the bridging between RR wireformat data and crypto calls.

## Function Documentation

## ◆ rrset_get_sig_keytag()

static uint16_t rrset_get_sig_keytag | ( | struct ub_packed_rrset_key * | k,
|  | size_t | sig_idx
| ) |  |
| static

Get signature keytag value.

Parameters

  k | rrset (with signatures)
  sig_idx | signature index.

Returns
  keytag or 0 if malformed rrsig.

References packed_rrset_data::count, lruhash_entry::data, ub_packed_rrset_key::entry, log_assert, packed_rrset_data::rr_data, packed_rrset_data::rr_len, and packed_rrset_data::rrsig_count.

Referenced by dnskey_verify_rrset(), and dnskeyset_verify_rrset_sig().

## ◆ rrset_get_sig_algo()

static int rrset_get_sig_algo | ( | struct ub_packed_rrset_key * | k,
|  | size_t | sig_idx
| ) |  |
| static

Get signature signing algorithm value.

Parameters

  k | rrset (with signatures)
  sig_idx | signature index.

Returns
  algo or 0 if malformed rrsig.

References packed_rrset_data::count, lruhash_entry::data, ub_packed_rrset_key::entry, log_assert, packed_rrset_data::rr_data, packed_rrset_data::rr_len, and packed_rrset_data::rrsig_count.

Referenced by dnskey_verify_rrset(), dnskeyset_verify_rrset(), and dnskeyset_verify_rrset_sig().

## ◆ dnskey_get_flags()

uint16_t dnskey_get_flags | ( | struct ub_packed_rrset_key * | k,
|  | size_t | idx
| ) |  |

Get DNSKEY RR flags.

Parameters

  k | DNSKEY rrset.
  idx | which DNSKEY RR.

Returns
  flags or 0 if DNSKEY too short.

References rrset_get_rdata().

Referenced by dnskey_verify_rrset_sig().

## ◆ dnskey_get_protocol()

static int dnskey_get_protocol | ( | struct ub_packed_rrset_key * | k,
|  | size_t | idx
| ) |  |
| static

Get DNSKEY protocol value from rdata.

Parameters

  k | DNSKEY rrset.
  idx | which key.

Returns
  protocol octet value

References rrset_get_rdata().

Referenced by dnskey_verify_rrset_sig().

## ◆ dnskey_get_algo()

int dnskey_get_algo | ( | struct ub_packed_rrset_key * | k,
|  | size_t | idx
| ) |  |

Get DNSKEY RR signature algorithm.

Parameters

  k | DNSKEY rrset.
  idx | which DNSKEY RR.

Returns
  algorithm or 0 if DNSKEY too short.

References rrset_get_rdata().

Referenced by algo_needs_init_dnskey_add(), dnskey_algo_is_supported(), dnskey_size_is_supported(), dnskey_verify_rrset(), dnskey_verify_rrset_sig(), dnskeyset_verify_rrset_sig(), key_matches_a_ds(), setup_sigalg(), val_verify_DNSKEY_with_TA(), and verify_dnskeys_with_ds_rr().

## ◆ ds_get_key_algo()

int ds_get_key_algo | ( | struct ub_packed_rrset_key * | k,
|  | size_t | idx
| ) |  |

Get DS RR key algorithm.

This value should match with the DNSKEY algo.

Parameters

  k | DS rrset.
  idx | which DS.

Returns
  algorithm or 0 if DS too short.

References rrset_get_rdata().

Referenced by algo_needs_init_ds(), ds_key_algo_is_supported(), key_matches_a_ds(), val_dsset_isusable(), val_verify_DNSKEY_with_DS(), val_verify_DNSKEY_with_TA(), and verify_dnskeys_with_ds_rr().

## ◆ ds_get_digest_algo()

int ds_get_digest_algo | ( | struct ub_packed_rrset_key * | ds_rrset,
|  | size_t | ds_idx
| ) |  |

Get DS RR digest algorithm.

Parameters

  ds_rrset | DS rrset.
  ds_idx | which DS.

Returns
  algorithm or 0 if DS too short.

References rrset_get_rdata().

Referenced by algo_needs_init_ds(), ds_create_dnskey_digest(), ds_digest_match_dnskey(), ds_digest_size_algo(), key_matches_a_ds(), val_dsset_isusable(), val_favorite_ds_algo(), val_verify_DNSKEY_with_DS(), and val_verify_DNSKEY_with_TA().

## ◆ ds_get_keytag()

uint16_t ds_get_keytag | ( | struct ub_packed_rrset_key * | ds_rrset,
|  | size_t | ds_idx
| ) |  |

Get DS keytag, footprint value that matches the DNSKEY keytag it signs.

Parameters

  ds_rrset | DS rrset
  ds_idx | index of RR in DS rrset.

Returns
  the keytag or 0 for badly formatted DSs.

References rrset_get_rdata().

Referenced by anchor_list_keytags(), key_matches_a_ds(), and verify_dnskeys_with_ds_rr().

## ◆ ds_get_sigdata()

static void ds_get_sigdata | ( | struct ub_packed_rrset_key * | k,
|  | size_t | idx,
|  | uint8_t ** | digest,
|  | size_t * | len
| ) |  |
| static

Return pointer to the digest in a DS RR.

Parameters

  k | DS rrset.
  idx | which DS.
  digest | digest data is returned. on error, this is NULL.
  len | length of digest is returned. on error, the length is 0.

References rrset_get_rdata().

Referenced by ds_digest_match_dnskey().

## ◆ ds_digest_size_algo()

static size_t ds_digest_size_algo | ( | struct ub_packed_rrset_key * | k,
|  | size_t | idx
| ) |  |
| static

Return size of DS digest according to its hash algorithm.

Parameters

  k | DS rrset.
  idx | which DS.

Returns
  size in bytes of digest, or 0 if not supported.

References ds_digest_size_supported(), and ds_get_digest_algo().

Referenced by ds_digest_algo_is_supported(), and ds_digest_match_dnskey().

## ◆ ds_create_dnskey_digest()

static int ds_create_dnskey_digest | ( | struct module_env * | env,
|  | struct ub_packed_rrset_key * | dnskey_rrset,
|  | size_t | dnskey_idx,
|  | struct ub_packed_rrset_key * | ds_rrset,
|  | size_t | ds_idx,
|  | uint8_t * | digest
| ) |  |
| static

Create a DS digest for a DNSKEY entry.

Parameters

  env | module environment. Uses scratch space.
  dnskey_rrset | DNSKEY rrset.
  dnskey_idx | index of RR in rrset.
  ds_rrset | DS rrset
  ds_idx | index of RR in DS rrset.
  digest | digest is returned in here (must be correctly sized).

Returns
  false on error.

References packed_rrset_key::dname, packed_rrset_key::dname_len, ds_get_digest_algo(), query_dname_tolower(), ub_packed_rrset_key::rk, rrset_get_rdata(), module_env::scratch_buffer, secalgo_ds_digest(), sldns_buffer_begin(), sldns_buffer_clear(), sldns_buffer_flip(), sldns_buffer_limit(), and sldns_buffer_write().

Referenced by ds_digest_match_dnskey().

## ◆ ds_digest_match_dnskey()

int ds_digest_match_dnskey | ( | struct module_env * | env,
|  | struct ub_packed_rrset_key * | dnskey_rrset,
|  | size_t | dnskey_idx,
|  | struct ub_packed_rrset_key * | ds_rrset,
|  | size_t | ds_idx
| ) |  |

Check if dnskey matches a DS digest Does not check dnskey-keyid footprint, just the digest.

Parameters

  env | module environment. Uses scratch space.
  dnskey_rrset | DNSKEY rrset.
  dnskey_idx | index of RR in rrset.
  ds_rrset | DS rrset
  ds_idx | index of RR in DS rrset.

Returns
  true if it matches, false on error, not supported or no match.

References ds_create_dnskey_digest(), ds_digest_size_algo(), ds_get_digest_algo(), ds_get_sigdata(), regional_alloc(), module_env::scratch, VERB_QUERY, and verbose().

Referenced by dstest_entry(), key_matches_a_ds(), and verify_dnskeys_with_ds_rr().

## ◆ ds_digest_algo_is_supported()

int ds_digest_algo_is_supported | ( | struct ub_packed_rrset_key * | ds_rrset,
|  | size_t | ds_idx
| ) |  |

See if DS digest algorithm is supported.

Parameters

  ds_rrset | DS rrset
  ds_idx | index of RR in DS rrset.

Returns
  true if supported.

References ds_digest_size_algo().

Referenced by anchors_ds_unsupported(), key_matches_a_ds(), val_dsset_isusable(), val_favorite_ds_algo(), val_verify_DNSKEY_with_DS(), and val_verify_DNSKEY_with_TA().

## ◆ ds_key_algo_is_supported()

int ds_key_algo_is_supported | ( | struct ub_packed_rrset_key * | ds_rrset,
|  | size_t | ds_idx
| ) |  |

See if DS key algorithm is supported.

Parameters

  ds_rrset | DS rrset
  ds_idx | index of RR in DS rrset.

Returns
  true if supported.

References dnskey_algo_id_is_supported(), and ds_get_key_algo().

Referenced by anchors_ds_unsupported(), key_matches_a_ds(), val_dsset_isusable(), val_favorite_ds_algo(), val_verify_DNSKEY_with_DS(), and val_verify_DNSKEY_with_TA().

## ◆ dnskey_calc_keytag()

uint16_t dnskey_calc_keytag | ( | struct ub_packed_rrset_key * | dnskey_rrset,
|  | size_t | dnskey_idx
| ) |  |

Get dnskey keytag, footprint value.

Parameters

  dnskey_rrset | DNSKEY rrset.
  dnskey_idx | index of RR in rrset.

Returns
  the keytag or 0 for badly formatted DNSKEYs.

References rrset_get_rdata(), and sldns_calc_keytag_raw().

Referenced by anchor_list_keytags(), check_contains_revoked(), dnskey_verify_rrset(), dnskey_verify_rrset_sig(), dnskeyset_verify_rrset_sig(), key_matches_a_ds(), and verify_dnskeys_with_ds_rr().

## ◆ dnskey_algo_is_supported()

int dnskey_algo_is_supported | ( | struct ub_packed_rrset_key * | dnskey_rrset,
|  | size_t | dnskey_idx
| ) |  |

See if DNSKEY algorithm is supported.

Parameters

  dnskey_rrset | DNSKEY rrset.
  dnskey_idx | index of RR in rrset.

Returns
  true if supported.

References dnskey_algo_id_is_supported(), and dnskey_get_algo().

Referenced by anchors_dnskey_unsupported(), update_events(), and val_verify_DNSKEY_with_TA().

## ◆ dnskey_size_is_supported()

int dnskey_size_is_supported | ( | struct ub_packed_rrset_key * | dnskey_rrset,
|  | size_t | dnskey_idx
| ) |  |

See if the DNSKEY size at that algorithm is supported.

Parameters

  dnskey_rrset | DNSKEY rrset.
  dnskey_idx | index of RR in rrset.

Returns
  true if supported.

References dnskey_get_algo(), rrset_get_rdata(), and sldns_rr_dnskey_key_size_raw().

Referenced by anchors_dnskey_unsupported(), dnskeyset_size_is_supported(), key_matches_a_ds(), update_events(), val_verify_DNSKEY_with_TA(), and verify_dnskeys_with_ds_rr().

## ◆ dnskeyset_size_is_supported()

int dnskeyset_size_is_supported | ( | struct ub_packed_rrset_key * | dnskey_rrset | ) |

See if the DNSKEY size at that algorithm is supported for all the RRs in the DNSKEY RRset.

Parameters

  dnskey_rrset | DNSKEY rrset.

Returns
  true if supported.

References dnskey_size_is_supported(), and rrset_get_count().

Referenced by val_verify_DNSKEY_with_DS(), and val_verify_DNSKEY_with_TA().

## ◆ algo_needs_init_dnskey_add()

void algo_needs_init_dnskey_add | ( | struct algo_needs * | n,
|  | struct ub_packed_rrset_key * | dnskey,
|  | uint8_t * | sigalg
| ) |  |

Initialize algo needs structure, set algos from rrset as needed.

Results are added to an existing need structure.

Parameters

  n | struct with storage.
  dnskey | algos from this struct set as necessary. DNSKEY set.
  sigalg | adds to signalled algorithm list too.

References dnskey_algo_id_is_supported(), dnskey_get_algo(), algo_needs::needs, algo_needs::num, and rrset_get_count().

Referenced by val_verify_DNSKEY_with_TA().

## ◆ algo_needs_init_list()

void algo_needs_init_list | ( | struct algo_needs * | n,
|  | uint8_t * | sigalg
| ) |  |

Initialize algo needs structure from a signalled algo list.

Parameters

  n | struct with storage.
  sigalg | signalled algorithm list, numbers ends with 0.

References ALGO_NEEDS_MAX, dnskey_algo_id_is_supported(), log_assert, algo_needs::needs, and algo_needs::num.

Referenced by dnskeyset_verify_rrset().

## ◆ algo_needs_init_ds()

void algo_needs_init_ds | ( | struct algo_needs * | n,
|  | struct ub_packed_rrset_key * | ds,
|  | int | fav_ds_algo,
|  | uint8_t * | sigalg
| ) |  |

Initialize algo needs structure, set algos from rrset as needed.

Parameters

  n | struct with storage.
  ds | algos from this struct set as necessary. DS set.
  fav_ds_algo | filter to use only this DS algo.
  sigalg | list of signalled algos, constructed as output, provide size ALGO_NEEDS_MAX+1. list of algonumbers, ends with a zero.

References ALGO_NEEDS_MAX, dnskey_algo_id_is_supported(), ds_get_digest_algo(), ds_get_key_algo(), log_assert, algo_needs::needs, algo_needs::num, and rrset_get_count().

Referenced by val_verify_DNSKEY_with_DS(), and val_verify_DNSKEY_with_TA().

## ◆ algo_needs_set_secure()

int algo_needs_set_secure | ( | struct algo_needs * | n,
|  | uint8_t | algo
| ) |  |

Mark this algorithm as a success, sec_secure, and see if we are done.

Parameters

  n | storage structure processed.
  algo | the algorithm processed to be secure.

Returns
  if true, processing has finished successfully, we are satisfied.

References algo_needs::needs, and algo_needs::num.

Referenced by dnskeyset_verify_rrset(), val_verify_DNSKEY_with_DS(), and val_verify_DNSKEY_with_TA().

## ◆ algo_needs_set_bogus()

void algo_needs_set_bogus | ( | struct algo_needs * | n,
|  | uint8_t | algo
| ) |  |

Mark this algorithm a failure, sec_bogus.

It can later be overridden by a success for this algorithm (with a different signature).

Parameters

  n | storage structure processed.
  algo | the algorithm processed to be bogus.

References algo_needs::needs.

Referenced by dnskeyset_verify_rrset(), val_verify_DNSKEY_with_DS(), and val_verify_DNSKEY_with_TA().

## ◆ algo_needs_num_missing()

size_t algo_needs_num_missing | ( | struct algo_needs * | n | ) |

See how many algorithms are missing (not bogus or secure, but not processed)

Parameters

  n | storage structure processed.

Returns
  number of algorithms missing after processing.

References algo_needs::num.

Referenced by dnskeyset_verify_rrset().

## ◆ algo_needs_missing()

int algo_needs_missing | ( | struct algo_needs * | n | ) |

See which algo is missing.

Parameters

  n | struct after processing.

Returns
  if 0 an algorithm was bogus, if a number, this algorithm was missing. So on 0, report why that was bogus, on number report a missing algorithm. There could be multiple missing, this reports the first one.

References ALGO_NEEDS_MAX, and algo_needs::needs.

Referenced by dnskeyset_verify_rrset(), val_verify_DNSKEY_with_DS(), and val_verify_DNSKEY_with_TA().

## ◆ dnskeyset_verify_rrset_sig()

static enum sec_status dnskeyset_verify_rrset_sig | ( | struct module_env * | env,
|  | struct val_env * | ve,
|  | time_t | now,
|  | struct ub_packed_rrset_key * | rrset,
|  | struct ub_packed_rrset_key * | dnskey,
|  | size_t | sig_idx,
|  | struct rbtree_type ** | sortree,
|  | char ** | reason,
|  | sldns_ede_code * | reason_bogus,
|  | sldns_pkt_section | section,
|  | struct module_qstate * | qstate
| ) |  |
| static

verify rrset, with dnskey rrset, for a specific rrsig in rrset

Parameters

  env | module environment, scratch space is used.
  ve | validator environment, date settings.
  now | current time for validation (can be overridden).
  rrset | to be validated.
  dnskey | DNSKEY rrset, keyset to try.
  sig_idx | which signature to try to validate.
  sortree | reused sorted order. Stored in region. Pass NULL at start, and for a new rrset.
  reason | if bogus, a string returned, fixed 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.

Returns
  secure if any key signs this signature. bogus if no key signs it, unchecked on error, or indeterminate if all keys are not supported by the crypto library (openssl3+ only).

References dnskey_algo_id_is_supported(), dnskey_calc_keytag(), dnskey_get_algo(), dnskey_verify_rrset_sig(), rrset_get_count(), rrset_get_sig_algo(), rrset_get_sig_keytag(), module_env::scratch, module_env::scratch_buffer, sec_status_bogus, sec_status_indeterminate, sec_status_insecure, sec_status_secure, VERB_ALGO, VERB_QUERY, and verbose().

Referenced by dnskeyset_verify_rrset().

## ◆ dnskeyset_verify_rrset()

enum sec_status dnskeyset_verify_rrset | ( | struct module_env * | env,
|  | struct val_env * | ve,
|  | struct ub_packed_rrset_key * | rrset,
|  | struct ub_packed_rrset_key * | dnskey,
|  | uint8_t * | sigalg,
|  | char ** | reason,
|  | sldns_ede_code * | reason_bogus,
|  | sldns_pkt_section | section,
|  | struct module_qstate * | qstate
| ) |  |

Verify rrset against dnskey rrset.

Parameters

  env | module environment, scratch space is used.
  ve | validator environment, date settings.
  rrset | to be validated.
  dnskey | DNSKEY rrset, keyset to try.
  sigalg | if nonNULL provide downgrade protection otherwise one algorithm is enough.
  reason | if bogus, a string returned, fixed 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.

Returns
  SECURE if one key in the set verifies one rrsig. UNCHECKED on allocation errors, unsupported algorithms, malformed data, and BOGUS on verification failures (no keys match any signatures).

References algo_needs_init_list(), algo_needs_missing(), algo_needs_num_missing(), algo_needs_reason(), algo_needs_set_bogus(), algo_needs_set_secure(), dnskeyset_verify_rrset_sig(), algo_needs::needs, module_env::now, algo_needs::num, rrset_get_sig_algo(), rrset_get_sigcount(), sec_status_bogus, sec_status_insecure, sec_status_secure, VERB_ALGO, VERB_QUERY, and verbose().

Referenced by verifytest_rrset(), and zonemd_dnssec_verify_rrset().

## ◆ algo_needs_reason()

void algo_needs_reason | ( | struct module_env * | env,
|  | int | alg,
|  | char ** | reason,
|  | char * | s
| ) |  |

Format error reason for algorithm missing.

Parameters

  env | module env with scratch for temp storage of string.
  alg | DNSKEY-algorithm missing.
  reason | destination.
  s | string, appended with 'with algorithm ..'.

References regional_strdup(), module_env::scratch, and sldns_algorithms.

Referenced by dnskeyset_verify_rrset(), val_verify_DNSKEY_with_DS(), val_verify_DNSKEY_with_TA(), and verify_dnskeys_with_ds_rr().

## ◆ dnskey_verify_rrset()

enum sec_status dnskey_verify_rrset | ( | struct module_env * | env,
|  | struct val_env * | ve,
|  | struct ub_packed_rrset_key * | rrset,
|  | struct ub_packed_rrset_key * | dnskey,
|  | size_t | dnskey_idx,
|  | char ** | reason,
|  | sldns_ede_code * | reason_bogus,
|  | sldns_pkt_section | section,
|  | struct module_qstate * | qstate
| ) |  |

verify rrset against one specific dnskey (from rrset)

Parameters

  env | module environment, scratch space is used.
  ve | validator environment, date settings.
  rrset | to be validated.
  dnskey | DNSKEY rrset, keyset.
  dnskey_idx | which key from the rrset to try.
  reason | if bogus, a string returned, fixed 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.

Returns
  secure if this key signs any of the signatures on rrset. unchecked on error or and bogus on bad signature.

References dnskey_calc_keytag(), dnskey_get_algo(), dnskey_verify_rrset_sig(), module_env::now, algo_needs::num, rrset_get_sig_algo(), rrset_get_sig_keytag(), rrset_get_sigcount(), module_env::scratch, module_env::scratch_buffer, sec_status_bogus, sec_status_indeterminate, sec_status_secure, VERB_ALGO, VERB_QUERY, and verbose().

Referenced by rr_is_selfsigned_revoked(), val_verify_DNSKEY_with_TA(), and verify_dnskeys_with_ds_rr().

## ◆ canonical_compare_byfield()

static int canonical_compare_byfield | ( | struct packed_rrset_data * | d,
|  | const sldns_rr_descriptor * | desc,
|  | size_t | i,
|  | size_t | j
| ) |  |
| static

Compare two RR for canonical order, in a field-style sweep.

Parameters

  d | rrset data
  desc | ldns wireformat descriptor.
  i | first RR to compare
  j | first RR to compare

Returns
  comparison code.

References sldns_struct_rr_descriptor::_dname_count, sldns_struct_rr_descriptor::_wireformat, get_rdf_size(), LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_STR, packed_rrset_data::rr_data, and packed_rrset_data::rr_len.

Referenced by canonical_compare().

## ◆ canonical_compare()

static int canonical_compare | ( | struct ub_packed_rrset_key * | rrset,
|  | size_t | i,
|  | size_t | j
| ) |  |
| static

Compare two RRs in the same RRset and determine their relative canonical order.

Parameters

  rrset | the rrset in which to perform compares.
  i | first RR to compare
  j | first RR to compare

Returns
  0 if RR i== RR j, -1 if <, +1 if >.

References canonical_compare_byfield(), lruhash_entry::data, dname_valid(), ub_packed_rrset_key::entry, LDNS_RR_TYPE_AFSDB, LDNS_RR_TYPE_CNAME, LDNS_RR_TYPE_DNAME, LDNS_RR_TYPE_HINFO, LDNS_RR_TYPE_KX, LDNS_RR_TYPE_MB, LDNS_RR_TYPE_MD, LDNS_RR_TYPE_MF, LDNS_RR_TYPE_MG, LDNS_RR_TYPE_MINFO, LDNS_RR_TYPE_MR, LDNS_RR_TYPE_MX, LDNS_RR_TYPE_NAPTR, LDNS_RR_TYPE_NS, LDNS_RR_TYPE_NXT, LDNS_RR_TYPE_PTR, LDNS_RR_TYPE_PX, LDNS_RR_TYPE_RP, LDNS_RR_TYPE_RRSIG, LDNS_RR_TYPE_RT, LDNS_RR_TYPE_SIG, LDNS_RR_TYPE_SOA, LDNS_RR_TYPE_SRV, log_assert, query_dname_compare(), ub_packed_rrset_key::rk, packed_rrset_data::rr_data, packed_rrset_data::rr_len, sldns_rr_descript(), and packed_rrset_key::type.

Referenced by canonical_tree_compare(), and rrset_canonical_equal().

## ◆ canonical_sort()

static void canonical_sort | ( | struct ub_packed_rrset_key * | rrset,
|  | struct packed_rrset_data * | d,
|  | rbtree_type * | sortree,
|  | struct canon_rr * | rrs
| ) |  |
| static

Sort RRs for rrset in canonical order.

Does not actually canonicalize the RR rdatas. Does not touch rrsigs.

Parameters

  rrset | to sort.
  d | rrset data.
  sortree | tree to sort into.
  rrs | rr storage.

References packed_rrset_data::count, rbnode_type::key, canon_rr::node, rbtree_insert(), canon_rr::rr_idx, and canon_rr::rrset.

Referenced by rrset_canonical(), rrset_canonical_equal(), and rrset_canonicalize_to_buffer().

## ◆ insert_can_owner()

static void insert_can_owner | ( | sldns_buffer * | buf,
|  | struct ub_packed_rrset_key * | k,
|  | uint8_t * | sig,
|  | uint8_t ** | can_owner,
|  | size_t * | can_owner_len
| ) |  |
| static

Insert canonical owner name into buffer.

Parameters

  buf | buffer to insert into at current position.
  k | rrset with its owner name.
  sig | signature with signer name and label count. must be length checked, at least 18 bytes long.
  can_owner | position in buffer returned for future use.
  can_owner_len | length of canonical owner name.

References packed_rrset_key::dname, packed_rrset_key::dname_len, dname_remove_label(), dname_signame_label_count(), log_assert, query_dname_tolower(), ub_packed_rrset_key::rk, sldns_buffer_current(), and sldns_buffer_write().

Referenced by rrset_canonical().

## ◆ canonicalize_rdata()

static void canonicalize_rdata | ( | sldns_buffer * | buf,
|  | struct ub_packed_rrset_key * | rrset,
|  | size_t | len
| ) |  |
| static

Canonicalize Rdata in buffer.

Parameters

  buf | buffer at position just after the rdata.
  rrset | rrset with type.
  len | length of the rdata (including rdatalen uint16).

References dname_valid(), LDNS_RR_TYPE_AFSDB, LDNS_RR_TYPE_CNAME, LDNS_RR_TYPE_DNAME, LDNS_RR_TYPE_HINFO, LDNS_RR_TYPE_KX, LDNS_RR_TYPE_MB, LDNS_RR_TYPE_MD, LDNS_RR_TYPE_MF, LDNS_RR_TYPE_MG, LDNS_RR_TYPE_MINFO, LDNS_RR_TYPE_MR, LDNS_RR_TYPE_MX, LDNS_RR_TYPE_NAPTR, LDNS_RR_TYPE_NS, LDNS_RR_TYPE_NXT, LDNS_RR_TYPE_PTR, LDNS_RR_TYPE_PX, LDNS_RR_TYPE_RP, LDNS_RR_TYPE_RRSIG, LDNS_RR_TYPE_RT, LDNS_RR_TYPE_SIG, LDNS_RR_TYPE_SOA, LDNS_RR_TYPE_SRV, query_dname_tolower(), ub_packed_rrset_key::rk, canon_rr::rrset, sldns_buffer_current(), and packed_rrset_key::type.

Referenced by rrset_canonical(), and rrset_canonicalize_to_buffer().

## ◆ rrset_canonical_equal()

int rrset_canonical_equal | ( | struct regional * | region,
|  | struct ub_packed_rrset_key * | k1,
|  | struct ub_packed_rrset_key * | k2
| ) |  |

Compare two rrsets and see if they are the same, canonicalised.

The rrsets are not altered.

Parameters

  region | temporary region.
  k1 | rrset1
  k2 | rrset2

Returns
  true if equal.

References canonical_compare(), canonical_sort(), canonical_tree_compare(), packed_rrset_data::count, rbtree_type::count, lruhash_entry::data, packed_rrset_key::dname, packed_rrset_key::dname_len, ub_packed_rrset_key::entry, packed_rrset_key::flags, canon_rr::node, query_dname_compare(), rbtree_first(), rbtree_init(), rbtree_next(), RBTREE_NULL, regional_alloc(), ub_packed_rrset_key::rk, RR_COUNT_MAX, packed_rrset_data::rr_data, canon_rr::rr_idx, packed_rrset_data::rr_len, packed_rrset_key::rrset_class, packed_rrset_data::rrsig_count, packed_rrset_data::security, packed_rrset_data::trust, packed_rrset_data::ttl, and packed_rrset_key::type.

Referenced by reply_equal().

## ◆ rrset_canonical()

static int rrset_canonical | ( | struct regional * | region,
|  | sldns_buffer * | buf,
|  | struct ub_packed_rrset_key * | k,
|  | uint8_t * | sig,
|  | size_t | siglen,
|  | struct rbtree_type ** | sortree,
|  | sldns_pkt_section | section,
|  | struct module_qstate * | qstate
| ) |  |
| static

Create canonical form of rrset in the scratch buffer.

Parameters

  region | temporary region.
  buf | the buffer to use.
  k | the rrset to insert.
  sig | RRSIG rdata to include.
  siglen | RRSIG rdata len excluding signature field, but inclusive signer name length.
  sortree | if NULL is passed a new sorted rrset tree is built. Otherwise it is reused.
  section | section of packet where this rrset comes from.
  qstate | qstate with region.

Returns
  false on alloc error.

References canonical_sort(), canonical_tree_compare(), canonicalize_rdata(), packed_rrset_data::count, lruhash_entry::data, packed_rrset_key::dname, packed_rrset_key::dname_len, ub_packed_rrset_key::entry, insert_can_owner(), log_err(), query_dname_tolower(), RBTREE_FOR, rbtree_init(), module_qstate::region, regional_alloc(), regional_alloc_init(), ub_packed_rrset_key::rk, RR_COUNT_MAX, packed_rrset_data::rr_data, packed_rrset_data::rr_len, packed_rrset_key::rrset_class, sldns_buffer_begin(), sldns_buffer_clear(), sldns_buffer_flip(), sldns_buffer_remaining(), sldns_buffer_write(), and packed_rrset_key::type.

Referenced by dnskey_verify_rrset_sig().

## ◆ rrset_canonicalize_to_buffer()

int rrset_canonicalize_to_buffer | ( | struct regional * | region,
|  | struct sldns_buffer * | buf,
|  | struct ub_packed_rrset_key * | k
| ) |  |

Canonicalize an rrset into the buffer.

For an auth zone record, so this does not use a signature, or the RRSIG TTL or the wildcard label count from the RRSIG.

Parameters

  region | temporary region.
  buf | the buffer to use.
  k | the rrset to insert.

Returns
  false on alloc error.

References canonical_sort(), canonical_tree_compare(), canonicalize_rdata(), packed_rrset_data::count, lruhash_entry::data, packed_rrset_key::dname, packed_rrset_key::dname_len, ub_packed_rrset_key::entry, log_err(), query_dname_tolower(), RBTREE_FOR, rbtree_init(), regional_alloc(), ub_packed_rrset_key::rk, RR_COUNT_MAX, packed_rrset_data::rr_data, packed_rrset_data::rr_len, packed_rrset_data::rr_ttl, packed_rrset_key::rrset_class, sldns_buffer_clear(), sldns_buffer_current(), sldns_buffer_flip(), sldns_buffer_remaining(), sldns_buffer_write(), sldns_buffer_write_u32(), and packed_rrset_key::type.

Referenced by zonemd_simple_rrset(), and zonemd_simple_rrsig().

## ◆ compare_1982()

static int compare_1982 | ( | uint32_t | a,
|  | uint32_t | b
| ) |  |
| static

RFC 1982 comparison, uses unsigned integers, and tries to avoid compiler optimization (eg.

by avoiding a-b<0 comparisons), this routine matches compare_serial(), for SOA serial number checks

Referenced by check_dates().

## ◆ subtract_1982()

static uint32_t subtract_1982 | ( | uint32_t | a,
|  | uint32_t | b
| ) |  |
| static

if we know that b is larger than a, return the difference between them, that is the distance between them.

in RFC1982 arith

Referenced by check_dates().

## ◆ dnskey_verify_rrset_sig()

enum sec_status dnskey_verify_rrset_sig | ( | struct regional * | region,
|  | struct sldns_buffer * | buf,
|  | struct val_env * | ve,
|  | time_t | now,
|  | struct ub_packed_rrset_key * | rrset,
|  | struct ub_packed_rrset_key * | dnskey,
|  | size_t | dnskey_idx,
|  | size_t | sig_idx,
|  | struct rbtree_type ** | sortree,
|  | int * | buf_canon,
|  | char ** | reason,
|  | sldns_ede_code * | reason_bogus,
|  | sldns_pkt_section | section,
|  | struct module_qstate * | qstate
| ) |  |

verify rrset, with specific dnskey(from set), for a specific rrsig

Parameters

  region | scratch region used for temporary allocation.
  buf | scratch buffer used for canonicalized rrset data.
  ve | validator environment, date settings.
  now | current time for validation (can be overridden).
  rrset | to be validated.
  dnskey | DNSKEY rrset, keyset.
  dnskey_idx | which key from the rrset to try.
  sig_idx | which signature to try to validate.
  sortree | pass NULL at start, the sorted rrset order is returned. pass it again for the same rrset.
  buf_canon | if true, the buffer is already canonical. pass false at start. pass old value only for same rrset and same signature (but perhaps different key) for reuse.
  reason | if bogus, a string returned, fixed or alloced in scratch.
  reason_bogus | EDE (8914) code paired with the reason of failure.
  section | section of packet where this rrset comes from.
  qstate | qstate with region.

Returns
  secure if this key signs this signature. unchecked on error or bogus if it did not validate.

References adjust_ttl(), check_dates(), packed_rrset_key::dname, dname_signame_label_count(), dname_subdomain_c(), dname_valid(), dnskey_calc_keytag(), dnskey_get_algo(), dnskey_get_flags(), dnskey_get_protocol(), dnskey_get_pubkey(), log_err(), log_nametypeclass(), query_dname_compare(), ub_packed_rrset_key::rk, rrset_canonical(), rrset_get_count(), rrset_get_rdata(), sec_status_bogus, sec_status_secure, sec_status_unchecked, packed_rrset_key::type, VERB_QUERY, verbose(), and verify_canonrrset().

Referenced by dnskey_verify_rrset(), and dnskeyset_verify_rrset_sig().