nsecValidationStatus = validateWithKeySet(d_now, d_zone, nsecs.records, nsecs.signatures, validKeys);
csp.emplace(std::make_pair(d_zone, QType::NSEC), nsecs);
}
- else if (nsec3s.records.size() > 0 && nsec3s.signatures.size() > 0) {
- nsecValidationStatus = validateWithKeySet(d_now, d_zone, nsec3s.records, nsec3s.signatures, validKeys);
- csp.emplace(std::make_pair(d_zone, QType::NSEC3), nsec3s);
+ else if (nsec3s.records.size() > 0 && nsec3s.signatures.size() > 0 && !zonemd.getNSEC3Label().empty()) {
+ nsecValidationStatus = validateWithKeySet(d_now, zonemd.getNSEC3Label(), nsec3s.records, nsec3s.signatures, validKeys);
+ csp.emplace(std::make_pair(zonemd.getNSEC3Label(), QType::NSEC3), nsec3s);
}
else {
d_log->info("No NSEC(3) records and/or RRSIGS found to deny ZONEMD");
#include "dnssecinfra.hh"
#include "sha.hh"
#include "zoneparser-tng.hh"
+#include "base32.hh"
void pdns::ZoneMD::readRecords(ZoneParserTNG& zpt)
{
d_nsecs.records.emplace(std::dynamic_pointer_cast<NSECRecordContent>(drc));
break;
case QType::NSEC3:
- d_nsecs3.records.emplace(std::dynamic_pointer_cast<NSEC3RecordContent>(drc));
break;
}
}
+ if (dnsResourceRecord.qtype == QType::NSEC3) {
+ d_nsecs3.records.emplace(std::dynamic_pointer_cast<NSEC3RecordContent>(drc));
+ }
RRSetKey_t key = std::pair(dnsResourceRecord.qname, dnsResourceRecord.qtype);
d_resourceRecordSets[key].push_back(drc);
d_resourceRecordSetTTLs[key] = dnsResourceRecord.ttl;
case QType::NSEC:
d_nsecs.records.emplace(std::dynamic_pointer_cast<NSECRecordContent>(record.d_content));
break;
+ case QType::NSEC3:
+ // Handled below
+ break;
+ case QType::NSEC3PARAM:
+ auto param = *std::dynamic_pointer_cast<NSEC3PARAMRecordContent>(record.d_content);
+ d_nsec3label = d_zone;
+ d_nsec3label.prependRawLabel(toBase32Hex(hashQNameWithSalt(param, d_zone)));
+ // XXX We could filter the collected NSEC3 and their RRSIGs in d_nsecs3 at this point as we now know the right label
+ break;
+ }
+ }
+ if (d_nsec3label.empty() || record.d_name == d_nsec3label) {
+ switch (record.d_type) {
case QType::NSEC3:
d_nsecs3.records.emplace(std::dynamic_pointer_cast<NSEC3RecordContent>(record.d_content));
break;
+ case QType::RRSIG:
+ auto rrsig = std::dynamic_pointer_cast<RRSIGRecordContent>(record.d_content);
+ if (rrsig->d_type == QType::NSEC3) {
+ d_nsecs3.signatures.emplace_back(rrsig);
+ }
+ break;
}
}
RRSetKey_t key = std::pair(record.d_name, record.d_type);
return d_nsecs3;
}
+ const DNSName& getNSEC3Label() const {
+ return d_nsec3label;
+ }
+
private:
typedef std::pair<DNSName, QType> RRSetKey_t;
typedef std::vector<std::shared_ptr<DNSRecordContent>> RRVector_t;
std::vector<shared_ptr<RRSIGRecordContent>> d_rrsigs;
ContentSigPair d_nsecs;
ContentSigPair d_nsecs3;
+ DNSName d_nsec3label;
const DNSName d_zone;
};