Skip to content

Commit 272c18b

Browse files
committed
Check DNSKEY on denial of DS
1 parent cfcc661 commit 272c18b

File tree

3 files changed

+18
-17
lines changed

3 files changed

+18
-17
lines changed

src/dnssec.cc

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -421,9 +421,8 @@ std::optional<NSEC3> find_matching_nsec3(const std::vector<RR> &nsec3_rrset, con
421421
const auto &nsec3 = std::get<NSEC3>(nsec3_rrset[0].data);
422422

423423
auto matching_domain = get_nsec3_domain(nsec3, domain, zone_domain);
424-
for (const auto &nsec3_rr : nsec3_rrset) {
425-
if (nsec3_rr.domain == matching_domain) return std::get<NSEC3>(nsec3_rr.data);
426-
}
424+
auto nsec3_rr = std::ranges::find(nsec3_rrset, matching_domain, &RR::domain);
425+
if (nsec3_rr != nsec3_rrset.end()) return std::get<NSEC3>(nsec3_rr->data);
427426
} catch (...) {
428427
}
429428
return std::nullopt;
@@ -614,27 +613,26 @@ bool authenticate_name_error(const std::string &domain, const std::vector<RR> &n
614613
return false;
615614
}
616615

617-
bool authenticate_no_ds(const std::string &domain, const std::vector<RR> &nsec3_rrset, const std::optional<RR> &nsec_rr,
618-
const std::string &zone_domain) {
616+
std::optional<bool> authenticate_no_ds(const std::string &domain, const std::vector<RR> &nsec3_rrset,
617+
const std::optional<RR> &nsec_rr, const std::string &zone_domain) {
619618
if (!nsec3_rrset.empty()) {
620619
auto nsec3 = find_matching_nsec3(nsec3_rrset, domain, zone_domain);
621620
if (nsec3.has_value()) {
622-
if (nsec3->types.contains(RRType::DS) || nsec3->types.contains(RRType::CNAME)) return false;
623-
624-
return true;
621+
if (nsec3->types.contains(RRType::DS) || nsec3->types.contains(RRType::CNAME)) return std::nullopt;
622+
return nsec3->types.contains(RRType::DNSKEY);
625623
}
626624

627625
// If no NSEC3 matches the name, the next closer NSEC3 must have opt out flag set.
628626
auto encloser_proof = verify_closest_encloser_proof(nsec3_rrset, domain, zone_domain);
629-
return encloser_proof.has_value() && encloser_proof->next_closer_opt_out;
627+
if (!encloser_proof.has_value() || !encloser_proof->next_closer_opt_out) return std::nullopt;
628+
return true;
630629
}
631630

632-
if (!nsec_rr.has_value() || nsec_rr->type != RRType::NSEC) return false;
631+
if (!nsec_rr.has_value() || nsec_rr->type != RRType::NSEC) return std::nullopt;
633632
const auto &nsec = std::get<NSEC>(nsec_rr->data);
634633

635-
if (nsec.types.contains(RRType::DS) || nsec.types.contains(RRType::CNAME)) return false;
636-
637-
return true;
634+
if (nsec.types.contains(RRType::DS) || nsec.types.contains(RRType::CNAME)) return std::nullopt;
635+
return nsec.types.contains(RRType::DNSKEY);
638636
}
639637

640638
bool authenticate_no_rrset(RRType rr_type, const std::string &domain, const std::vector<RR> &nsec3_rrset,

src/dnssec.hh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ bool authenticate_delegation(const std::vector<RR> &dnskey_rrset, const std::vec
1515
const std::vector<RRSIG> &rrsigs, const std::string &zone_domain);
1616
bool authenticate_name_error(const std::string &domain, const std::vector<RR> &nsec3_rrset,
1717
const std::vector<RR> &nsec_rrset, const std::string &zone_domain);
18-
bool authenticate_no_ds(const std::string &domain, const std::vector<RR> &nsec3_rrset, const std::optional<RR> &nsec_rr,
19-
const std::string &zone_domain);
18+
// Authenticate the denial of existence of DS RRset, and returns whether the domain has DNSKEY.
19+
std::optional<bool> authenticate_no_ds(const std::string &domain, const std::vector<RR> &nsec3_rrset,
20+
const std::optional<RR> &nsec_rr, const std::string &zone_domain);
2021
bool authenticate_no_rrset(RRType rr_type, const std::string &domain, const std::vector<RR> &nsec3_rrset,
2122
const std::optional<RR> &nsec_rr, const std::string &zone_domain);
2223
}; // namespace dnssec

src/resolve.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -615,10 +615,12 @@ std::optional<std::vector<RR>> Resolver::resolve_rec(const std::string &domain,
615615
auto nsec3_rrset = get_rrset(response.authority, RRType::NSEC3, *zone);
616616
auto nsec_rrset = get_rrset(response.authority, RRType::NSEC, referral_zone->domain, *zone);
617617
auto nsec_rr = nsec_rrset.empty() ? std::nullopt : std::optional<RR>{nsec_rrset[0]};
618-
if (!dnssec::authenticate_no_ds(referral_zone->domain, nsec3_rrset, nsec_rr,
619-
zone->domain)) {
618+
auto result
619+
= dnssec::authenticate_no_ds(referral_zone->domain, nsec3_rrset, nsec_rr, zone->domain);
620+
if (!result.has_value()) {
620621
throw std::runtime_error("Failed to authenticate the denial of existence");
621622
}
623+
referral_zone->enable_dnssec = result.value();
622624
}
623625
}
624626

0 commit comments

Comments
 (0)