2121#include " write.hh"
2222
2323namespace {
24- struct RRWithData {
25- std::reference_wrapper<const RR> rr;
26- std::vector<std::string_view> labels;
27- std::vector<uint8_t > data;
28-
29- RRWithData (const RR &rr, std::vector<std::string_view> &&labels) : rr(rr), labels(labels) {}
30- };
31-
3224using EVP_PKEY_unique_ptr = std::unique_ptr<EVP_PKEY, decltype ([](auto *pkey) { EVP_PKEY_free (pkey); })>;
3325using BIGNUM_unique_ptr = std::unique_ptr<BIGNUM, decltype ([](auto *bn) { BN_free (bn); })>;
3426using OSSL_PARAM_BLD_unique_ptr
@@ -105,7 +97,7 @@ EVP_PKEY_unique_ptr load_ecdsa_key(const std::vector<uint8_t> &dnskey, const std
10597}
10698
10799EVP_PKEY_unique_ptr load_eddsa_key (const std::vector<uint8_t > &dnskey, int type) {
108- auto *pkey = EVP_PKEY_new_raw_public_key (type, NULL , dnskey.data (), dnskey.size ());
100+ auto *pkey = EVP_PKEY_new_raw_public_key (type, nullptr , dnskey.data (), dnskey.size ());
109101 if (pkey == nullptr ) throw std::runtime_error (" Failed to load EdDSA key" );
110102 return EVP_PKEY_unique_ptr{pkey};
111103}
@@ -215,6 +207,14 @@ std::vector<std::string_view> domain_to_labels(const std::string_view &domain) {
215207 return labels;
216208}
217209
210+ struct RRWithData {
211+ std::reference_wrapper<const RR> rr;
212+ std::vector<std::string_view> labels;
213+ std::vector<uint8_t > data;
214+
215+ RRWithData (const RR &rr, std::vector<std::string_view> &&labels) : rr(rr), labels(labels) {}
216+ };
217+
218218std::vector<RRWithData> add_data_to_rrset (const std::vector<RR> &rrset) {
219219 std::vector<RRWithData> result;
220220 result.reserve (rrset.size ());
@@ -359,10 +359,10 @@ int compare_domains(const std::vector<std::string_view> &a, const std::vector<st
359359 return 0 ;
360360}
361361
362- bool is_domain_between (const std::string_view &domain, const std::string_view &before, const std::string_view &after) {
362+ bool is_domain_between (const std::string &domain, const std::string &before, const std::string &after) {
363+ auto domain_labels = domain_to_labels (domain);
363364 auto before_labels = domain_to_labels (before);
364365 auto after_labels = domain_to_labels (after);
365- auto domain_labels = domain_to_labels (domain);
366366 return compare_domains (before_labels, domain_labels) < 0 && compare_domains (domain_labels, after_labels) < 0 ;
367367}
368368
@@ -394,7 +394,7 @@ std::string get_nsec3_domain(const NSEC3 &nsec3, const std::string_view &domain,
394394 }
395395 }
396396
397- return base32_encode (digest) + " ." + zone_domain;
397+ return base32hex_encode (digest) + " ." + zone_domain;
398398}
399399
400400std::optional<NSEC3> find_covering_nsec3 (const std::vector<RR> &nsec3_rrset, const std::string_view &domain,
@@ -406,7 +406,7 @@ std::optional<NSEC3> find_covering_nsec3(const std::vector<RR> &nsec3_rrset, con
406406 auto covered_domain = get_nsec3_domain (nsec3, domain, zone_domain);
407407 for (const auto &nsec3_rr : nsec3_rrset) {
408408 const auto &nsec3 = std::get<NSEC3>(nsec3_rr.data );
409- auto next_domain = base32_encode (nsec3.next_domain_hash ) + " ." + zone_domain;
409+ auto next_domain = base32hex_encode (nsec3.next_domain_hash ) + " ." + zone_domain;
410410 if (is_domain_between (covered_domain, nsec3_rr.domain , next_domain)) return std::get<NSEC3>(nsec3_rr.data );
411411 }
412412 } catch (...) {
@@ -463,6 +463,7 @@ std::optional<EncloserProof> verify_closest_encloser_proof(const std::vector<RR>
463463}
464464} // namespace
465465
466+ namespace dnssec {
466467int get_ds_digest_size (DigestAlgorithm algorithm) {
467468 auto digest_size = EVP_MD_get_size (get_ds_digest_algorithm (algorithm));
468469 if (digest_size <= 0 ) throw std::runtime_error (" Failed to get digest size" );
@@ -550,10 +551,10 @@ bool authenticate_rrset(const std::vector<RR> &rrset, const std::vector<RRSIG> &
550551
551552bool authenticate_delegation (const std::vector<RR> &dnskey_rrset, const std::vector<DS> &dss,
552553 const std::vector<RRSIG> &rrsigs, const std::string &zone_domain) {
553- if (dnskey_rrset.empty () || dss.empty ()) return {} ;
554+ if (dnskey_rrset.empty () || dss.empty ()) return false ;
554555
555556 EVP_MD_CTX_unique_ptr ctx{EVP_MD_CTX_new ()};
556- if (ctx == nullptr ) return {} ;
557+ if (ctx == nullptr ) return false ;
557558
558559 std::vector<uint8_t > canonical_domain;
559560 std::vector<uint8_t > digest;
@@ -565,7 +566,9 @@ bool authenticate_delegation(const std::vector<RR> &dnskey_rrset, const std::vec
565566 if (digest_size <= 0 ) continue ;
566567
567568 for (const auto &dnskey_rr : dnskey_rrset) {
569+ if (dnskey_rr.type != RRType::DNSKEY) return false ;
568570 const auto &dnskey = std::get<DNSKEY>(dnskey_rr.data );
571+
569572 if (dnskey.key_tag != ds.key_tag ) continue ;
570573
571574 canonical_domain.clear ();
@@ -602,9 +605,10 @@ bool authenticate_name_error(const std::string &domain, const std::vector<RR> &n
602605 return find_covering_nsec3 (nsec3_rrset, wildcard_domain, zone_domain).has_value ();
603606 }
604607
605- for (const auto &rr : nsec_rrset) {
606- const auto &nsec = std::get<NSEC>(rr.data );
607- if (is_domain_between (domain, rr.domain , nsec.next_domain )) return true ;
608+ for (const auto &nsec_rr : nsec_rrset) {
609+ if (nsec_rr.type != RRType::NSEC) return false ;
610+ const auto &nsec = std::get<NSEC>(nsec_rr.data );
611+ if (is_domain_between (domain, nsec_rr.domain , nsec.next_domain )) return true ;
608612 }
609613
610614 return false ;
@@ -625,9 +629,9 @@ bool authenticate_no_ds(const std::string &domain, const std::vector<RR> &nsec3_
625629 return encloser_proof.has_value () && encloser_proof->next_closer_opt_out ;
626630 }
627631
628- if (!nsec_rr.has_value ()) return false ;
629-
632+ if (!nsec_rr.has_value () || nsec_rr->type != RRType::NSEC) return false ;
630633 const auto &nsec = std::get<NSEC>(nsec_rr->data );
634+
631635 if (nsec.types .contains (RRType::DS) || nsec.types .contains (RRType::CNAME)) return false ;
632636
633637 return true ;
@@ -642,9 +646,9 @@ bool authenticate_no_rrset(RRType rr_type, const std::string &domain, const std:
642646 return true ;
643647 }
644648
645- if (!nsec_rr.has_value ()) return false ;
646-
649+ if (!nsec_rr.has_value () || nsec_rr->type != RRType::NSEC) return false ;
647650 const auto &nsec = std::get<NSEC>(nsec_rr->data );
648- if (nsec. types . contains (rr_type) || nsec. types . contains (RRType::CNAME)) return false ;
649- return true ;
651+
652+ return !nsec. types . contains (rr_type) && !nsec. types . contains (RRType::CNAME) ;
650653}
654+ }; // namespace dnssec
0 commit comments