]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Cleaner way of getting the closest encloser from a NSEC
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 23 Feb 2021 17:26:14 +0000 (18:26 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 23 Feb 2021 17:26:14 +0000 (18:26 +0100)
pdns/validate.cc
pdns/validate.hh

index ae01ea4cec98ff6196414363f0b5f3746cf67195..a1618617c6fe678bb88003702c06834f007a79cb 100644 (file)
@@ -283,6 +283,16 @@ static bool provesNoDataWildCard(const DNSName& qname, const uint16_t qtype, con
   return false;
 }
 
+DNSName getClosestEncloserFromNSEC(const DNSName& name, const DNSName& owner, const DNSName& next)
+{
+  DNSName commonWithOwner(name.getCommonLabels(owner));
+  DNSName commonWithNext(name.getCommonLabels(next));
+  if (commonWithOwner.countLabels() >= commonWithNext.countLabels()) {
+    return commonWithOwner;
+  }
+  return commonWithNext;
+}
+
 /*
   This function checks whether the non-existence of a wildcard covering qname|qtype
   is proven by the NSEC records in validrrsets.
@@ -301,25 +311,16 @@ static bool provesNoWildCard(const DNSName& qname, const uint16_t qtype, const c
         }
 
         const DNSName owner = getNSECOwnerName(v.first.first, v.second.signatures);
-        /*
-          A NSEC can only prove the non-existence of a wildcard with at least the same
-          number of labels than the intersection of its owner name and next name.
-        */
-        const DNSName commonLabels = owner.getCommonLabels(nsec->d_next);
-        const unsigned int commonLabelsCount = commonLabels.countLabels();
-
-        DNSName wildcard(qname);
-        unsigned int wildcardLabelsCount = wildcard.countLabels();
-        while (wildcard.chopOff() && wildcardLabelsCount >= commonLabelsCount) {
-          DNSName target = g_wildcarddnsname + wildcard;
-          --wildcardLabelsCount;
-
-          LOG("Comparing owner: "<<owner<<" with target: "<<target<<endl);
+        DNSName closestEncloser = getClosestEncloserFromNSEC(qname, owner, nsec->d_next);
+        if (closestEncloser.countLabels() >= qname.countLabels()) {
+          continue;
+        }
+        DNSName wildcard = g_wildcarddnsname + closestEncloser;
+        LOG("Comparing owner: "<<owner<<" with target: "<<wildcard<<endl);
 
-          if (isCoveredByNSEC(target, owner, nsec->d_next)) {
-            LOG("\tWildcard is covered"<<endl);
-            return true;
-          }
+        if (wildcard != owner && isCoveredByNSEC(wildcard, owner, nsec->d_next)) {
+          LOG("\tWildcard is covered"<<endl);
+          return true;
         }
       }
     }
@@ -828,13 +829,13 @@ static const vector<DNSName> getZoneCuts(const DNSName& begin, const DNSName& en
 
 bool isRRSIGNotExpired(const time_t now, const shared_ptr<RRSIGRecordContent>& sig)
 {
-  // Should use https://www.rfc-editor.org/rfc/rfc4034.txt section 3.1.5 
+  // Should use https://www.rfc-editor.org/rfc/rfc4034.txt section 3.1.5
   return sig->d_sigexpire >= now;
 }
 
 bool isRRSIGIncepted(const time_t now, const shared_ptr<RRSIGRecordContent>& sig)
 {
-  // Should use https://www.rfc-editor.org/rfc/rfc4034.txt section 3.1.5 
+  // Should use https://www.rfc-editor.org/rfc/rfc4034.txt section 3.1.5
   return sig->d_siginception - g_signatureInceptionSkew <= now;
 }
 
@@ -954,7 +955,7 @@ cspmap_t harvestCSPFromRecs(const vector<DNSRecord>& recs)
   for(const auto& rec : recs) {
     //        cerr<<"res "<<rec.d_name<<"/"<<rec.d_type<<endl;
     if(rec.d_type == QType::OPT) continue;
-    
+
     if(rec.d_type == QType::RRSIG) {
       auto rrc = getRR<RRSIGRecordContent>(rec);
       if (rrc) {
index ae3831f8ddb4f439be4bfb24182678eadef6ece9..daafe962c5e6967e62e3be3962134ff0dbd6f7a5 100644 (file)
@@ -97,6 +97,7 @@ dState matchesNSEC(const DNSName& name, uint16_t qtype, const DNSName& nsecOwner
 
 bool isNSEC3AncestorDelegation(const DNSName& signer, const DNSName& owner, const std::shared_ptr<NSEC3RecordContent>& nsec3);
 DNSName getNSECOwnerName(const DNSName& initialOwner, const std::vector<std::shared_ptr<RRSIGRecordContent> >& signatures);
+DNSName getClosestEncloserFromNSEC(const DNSName& name, const DNSName& owner, const DNSName& next);
 
 template <typename NSEC> bool isTypeDenied(const NSEC& nsec, const QType& type)
 {