From 3155c04a99d73d0a8843ac057d1ff091cd8a9f22 Mon Sep 17 00:00:00 2001 From: Pieter Lexis Date: Fri, 2 Oct 2015 14:21:01 +0200 Subject: [PATCH] Validate length of the zonename for NSEC3 If the zonename is too long, don't add NSEC3 semantics. Also give an error when the zone is checked. Closes #2402. --- pdns/dnsname.cc | 9 +++++++++ pdns/dnsname.hh | 1 + pdns/pdnssec.cc | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/pdns/dnsname.cc b/pdns/dnsname.cc index 5b5567648..055b4d666 100644 --- a/pdns/dnsname.cc +++ b/pdns/dnsname.cc @@ -105,6 +105,15 @@ size_t DNSName::length() const { return this->toString().length(); } +/** + * Get the length of the DNSName on the wire + * + * @return the total wirelength of the DNSName + */ +size_t DNSName::wirelength() const { + return d_storage.length() + 1; +} + // are WE part of parent bool DNSName::isPartOf(const DNSName& parent) const { diff --git a/pdns/dnsname.hh b/pdns/dnsname.hh index bdb191433..6bf98d32a 100644 --- a/pdns/dnsname.hh +++ b/pdns/dnsname.hh @@ -49,6 +49,7 @@ public: bool isWildcard() const; unsigned int countLabels() const; size_t length() const; // FIXME400 remove me? + size_t wirelength() const; //!< Number of total bytes in the name bool empty() const { return d_empty; } bool isRoot() const { return !d_empty && d_storage.empty(); } void clear() { d_storage.clear(); d_empty=true; } diff --git a/pdns/pdnssec.cc b/pdns/pdnssec.cc index 8c078bb8d..7dc0c43ce 100644 --- a/pdns/pdnssec.cc +++ b/pdns/pdnssec.cc @@ -418,6 +418,10 @@ int checkZone(DNSSECKeeper &dk, UeberBackend &B, const DNSName& zone) DNSResourceRecord rr; uint64_t numrecords=0, numerrors=0, numwarnings=0; + if (haveNSEC3 && isSecure && zone.wirelength() > 222) { + numerrors++; + cerr<<"[Error] zone '" << zone.toStringNoDot() << "' has NSEC3 semantics but is too long to have the hash prepended. Zone name is " << zone.wirelength() << " bytes long, whereas the maximum is 222 bytes." << endl; + } // Check for delegation in parent zone DNSName parent(zone); @@ -1729,6 +1733,10 @@ try NSEC3PARAMRecordContent ns3pr(nsec3params); DNSName zone(cmds[1]); + if (zone.wirelength() > 222) { + cerr<<"Cannot enable NSEC3 for " << zone.toString() << " as it is too long (" << zone.wirelength() << " bytes, maximum is 222 bytes)"<