]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Remove duplicate RRs inside a RRSet when computing the signature
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 6 Nov 2019 17:53:35 +0000 (18:53 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 6 Dec 2019 16:07:46 +0000 (17:07 +0100)
These duplicates should not exist but they do happen in the wild.
Since we need to sort the RRs anyway, let's be nice and remove
duplicates as well.

12 files changed:
pdns/dnssecinfra.cc
pdns/dnssecinfra.hh
pdns/dnssecsigner.cc
pdns/pdnsutil.cc
pdns/recursordist/test-syncres_cc.cc
pdns/recursordist/test-syncres_cc.hh
pdns/recursordist/test-syncres_cc4.cc
pdns/recursordist/test-syncres_cc8.cc
pdns/syncres.cc
pdns/test-signers.cc
pdns/validate.cc
pdns/validate.hh

index ef88453939e0c5cf165d5745db6b7698505c3b44..0b0200c953b4d2039324d7b707b57568e41b7e89 100644 (file)
@@ -351,12 +351,6 @@ shared_ptr<DNSCryptoKeyEngine> DNSCryptoKeyEngine::makeFromPEMString(DNSKEYRecor
   return 0;
 }
 
-
-static bool sharedDNSSECCompare(const shared_ptr<DNSRecordContent>& a, const shared_ptr<DNSRecordContent>& b)
-{
-  return a->serialize(g_rootdnsname, true, true) < b->serialize(g_rootdnsname, true, true);
-}
-
 /**
  * Returns the string that should be hashed to create/verify the RRSIG content
  *
@@ -370,10 +364,8 @@ static bool sharedDNSSECCompare(const shared_ptr<DNSRecordContent>& a, const sha
  *                            purposes, as the authoritative server correctly
  *                            sets qname to the wildcard.
  */
-string getMessageForRRSET(const DNSName& qname, const RRSIGRecordContent& rrc, vector<shared_ptr<DNSRecordContent> >& signRecords, bool processRRSIGLabels)
+string getMessageForRRSET(const DNSName& qname, const RRSIGRecordContent& rrc, const sortedRecords_t& signRecords, bool processRRSIGLabels)
 {
-  sort(signRecords.begin(), signRecords.end(), sharedDNSSECCompare);
-
   string toHash;
   toHash.append(const_cast<RRSIGRecordContent&>(rrc).serialize(g_rootdnsname, true, true));
   toHash.resize(toHash.size() - rrc.d_signature.length()); // chop off the end, don't sign the signature!
@@ -396,7 +388,7 @@ string getMessageForRRSET(const DNSName& qname, const RRSIGRecordContent& rrc, v
     }
   }
 
-  for(shared_ptr<DNSRecordContent>& add :  signRecords) {
+  for(const shared_ptr<DNSRecordContent>& add : signRecords) {
     toHash.append(nameToHash);
     uint16_t tmp=htons(rrc.d_type);
     toHash.append((char*)&tmp, 2);
index 45dd5650c58125c75878eda1ccc292044e9332b9..440edc981a4473ad7a2646f4aa50595c9901a593 100644 (file)
@@ -147,7 +147,15 @@ struct CanonicalCompare: public std::binary_function<string, string, bool>
   }
 };
 
-string getMessageForRRSET(const DNSName& qname, const RRSIGRecordContent& rrc, std::vector<std::shared_ptr<DNSRecordContent> >& signRecords, bool processRRSIGLabels = false);
+struct sharedDNSSECRecordCompare {
+    bool operator() (const shared_ptr<DNSRecordContent>& a, const shared_ptr<DNSRecordContent>& b) const {
+      return a->serialize(g_rootdnsname, true, true) < b->serialize(g_rootdnsname, true, true);
+    }
+};
+
+typedef std::set<std::shared_ptr<DNSRecordContent>, sharedDNSSECRecordCompare> sortedRecords_t;
+
+string getMessageForRRSET(const DNSName& qname, const RRSIGRecordContent& rrc, const sortedRecords_t& signRecords, bool processRRSIGLabels = false);
 
 DSRecordContent makeDSFromDNSKey(const DNSName& qname, const DNSKEYRecordContent& drc, uint8_t digest);
 
index 22abee7cc3cb8675ff33eef56f7165682d2b0318..7e6f485ee9fa269acfbab56353d7cb06cfd37577 100644 (file)
@@ -51,7 +51,7 @@ static std::string getLookupKey(const std::string& msg)
   }
 }
 
-static void fillOutRRSIG(DNSSECPrivateKey& dpk, const DNSName& signQName, RRSIGRecordContent& rrc, vector<shared_ptr<DNSRecordContent> >& toSign)
+static void fillOutRRSIG(DNSSECPrivateKey& dpk, const DNSName& signQName, RRSIGRecordContent& rrc, const sortedRecords_t& toSign)
 {
   if(!g_signatureCount)
     g_signatureCount = S.getPointer("signatures");
@@ -96,7 +96,7 @@ static void fillOutRRSIG(DNSSECPrivateKey& dpk, const DNSName& signQName, RRSIGR
 /* this is where the RRSIGs begin, keys are retrieved,
    but the actual signing happens in fillOutRRSIG */
 static int getRRSIGsForRRSET(DNSSECKeeper& dk, const DNSName& signer, const DNSName& signQName, uint16_t signQType, uint32_t signTTL,
-                             vector<shared_ptr<DNSRecordContent> >& toSign, vector<RRSIGRecordContent>& rrcs)
+                             const sortedRecords_t& toSign, vector<RRSIGRecordContent>& rrcs)
 {
   if(toSign.empty())
     return -1;
@@ -134,7 +134,7 @@ static int getRRSIGsForRRSET(DNSSECKeeper& dk, const DNSName& signer, const DNSN
 // this is the entrypoint from DNSPacket
 static void addSignature(DNSSECKeeper& dk, UeberBackend& db, const DNSName& signer, const DNSName& signQName, const DNSName& wildcardname, uint16_t signQType,
                          uint32_t signTTL, DNSResourceRecord::Place signPlace,
-                         vector<shared_ptr<DNSRecordContent> >& toSign, vector<DNSZoneRecord>& outsigned, uint32_t origTTL)
+                         sortedRecords_t& toSign, vector<DNSZoneRecord>& outsigned, uint32_t origTTL)
 {
   //cerr<<"Asked to sign '"<<signQName<<"'|"<<DNSRecordContent::NumberToType(signQType)<<", "<<toSign.size()<<" records\n";
   if(toSign.empty())
@@ -203,7 +203,7 @@ void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const set<DNSName>& authSet,
   uint32_t origTTL=0;
   
   DNSResourceRecord::Place signPlace=DNSResourceRecord::ANSWER;
-  vector<shared_ptr<DNSRecordContent> > toSign;
+  sortedRecords_t toSign;
 
   vector<DNSZoneRecord> signedRecords;
   signedRecords.reserve(rrs.size()*1.5);
@@ -228,7 +228,7 @@ void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const set<DNSName>& authSet,
     origTTL = pos->dr.d_ttl;
     signPlace = pos->dr.d_place;
     if(pos->auth || pos->dr.d_type == QType::DS) {
-      toSign.push_back(pos->dr.d_content); // so ponder.. should this be a deep copy perhaps?
+      toSign.insert(pos->dr.d_content); // so ponder.. should this be a deep copy perhaps?
     }
   }
   if(getBestAuthFromSet(authSet, signQName, signer))
index 152c7a70a430d3eae07785a7790ff2bc1787732c..895e0a8427714b22578b85822af0d18ece40b17a 100644 (file)
@@ -1428,26 +1428,26 @@ void verifyCrypto(const string& zone)
   DNSKEYRecordContent drc;
   RRSIGRecordContent rrc;
   DSRecordContent dsrc;
-  vector<shared_ptr<DNSRecordContent> > toSign;
+  sortedRecords_t toSign;
   DNSName qname, apex;
   dsrc.d_digesttype=0;
   while(zpt.get(rr)) {
     if(rr.qtype.getCode() == QType::DNSKEY) {
       cerr<<"got DNSKEY!"<<endl;
       apex=rr.qname;
-      drc = *std::dynamic_pointer_cast<DNSKEYRecordContent>(DNSRecordContent::mastermake(QType::DNSKEY, 1, rr.content));
+      drc = *std::dynamic_pointer_cast<DNSKEYRecordContent>(DNSRecordContent::mastermake(QType::DNSKEY, QClass::IN, rr.content));
     }
     else if(rr.qtype.getCode() == QType::RRSIG) {
       cerr<<"got RRSIG"<<endl;
-      rrc = *std::dynamic_pointer_cast<RRSIGRecordContent>(DNSRecordContent::mastermake(QType::RRSIG, 1, rr.content));
+      rrc = *std::dynamic_pointer_cast<RRSIGRecordContent>(DNSRecordContent::mastermake(QType::RRSIG, QClass::IN, rr.content));
     }
     else if(rr.qtype.getCode() == QType::DS) {
       cerr<<"got DS"<<endl;
-      dsrc = *std::dynamic_pointer_cast<DSRecordContent>(DNSRecordContent::mastermake(QType::DS, 1, rr.content));
+      dsrc = *std::dynamic_pointer_cast<DSRecordContent>(DNSRecordContent::mastermake(QType::DS, QClass::IN, rr.content));
     }
     else {
       qname = rr.qname;
-      toSign.push_back(DNSRecordContent::mastermake(rr.qtype.getCode(), 1, rr.content));
+      toSign.insert(DNSRecordContent::mastermake(rr.qtype.getCode(), QClass::IN, rr.content));
     }
   }
 
index 69fb5ba1b67340f09d65ef72ba13acdb83c85294..db7e11363e758ff031f1aaa5a2b374fa2f617cf4 100644 (file)
@@ -243,7 +243,7 @@ bool isRootServer(const ComboAddress& ip)
   return false;
 }
 
-void computeRRSIG(const DNSSECPrivateKey& dpk, const DNSName& signer, const DNSName& signQName, uint16_t signQType, uint32_t signTTL, uint32_t sigValidity, RRSIGRecordContent& rrc, vector<shared_ptr<DNSRecordContent>>& toSign, boost::optional<uint8_t> algo, boost::optional<uint32_t> inception, boost::optional<time_t> now)
+void computeRRSIG(const DNSSECPrivateKey& dpk, const DNSName& signer, const DNSName& signQName, uint16_t signQType, uint32_t signTTL, uint32_t sigValidity, RRSIGRecordContent& rrc, const sortedRecords_t& toSign, boost::optional<uint8_t> algo, boost::optional<uint32_t> inception, boost::optional<time_t> now)
 {
   if (!now) {
     now = time(nullptr);
@@ -283,10 +283,10 @@ bool addRRSIG(const testkeysset_t& keys, std::vector<DNSRecord>& records, const
   const DNSName& name = records[recordsCount - 1].d_name;
   const uint16_t type = records[recordsCount - 1].d_type;
 
-  std::vector<std::shared_ptr<DNSRecordContent>> recordcontents;
+  sortedRecords_t recordcontents;
   for (const auto record : records) {
     if (record.d_name == name && record.d_type == type) {
-      recordcontents.push_back(record.d_content);
+      recordcontents.insert(record.d_content);
     }
   }
 
index 2c1fd30fdac02ce73d2c78f79a6a9fb7d1c1c053..40ccd0f4e700918b8da91eb8f57ab982ca0558af 100644 (file)
@@ -51,7 +51,9 @@ bool isRootServer(const ComboAddress& ip);
 
 void computeRRSIG(const DNSSECPrivateKey& dpk, const DNSName& signer, const DNSName& signQName, uint16_t signQType, uint32_t signTTL, uint32_t sigValidity, RRSIGRecordContent& rrc, vector<shared_ptr<DNSRecordContent>>& toSign, boost::optional<uint8_t> algo = boost::none, boost::optional<uint32_t> inception = boost::none, boost::optional<time_t> now = boost::none);
 
-typedef std::unordered_map<DNSName, std::pair<DNSSECPrivateKey, DSRecordContent>> testkeysset_t;
+void computeRRSIG(const DNSSECPrivateKey& dpk, const DNSName& signer, const DNSName& signQName, uint16_t signQType, uint32_t signTTL, uint32_t sigValidity, RRSIGRecordContent& rrc, const sortedRecords_t& toSign, boost::optional<uint8_t> algo=boost::none, boost::optional<uint32_t> inception=boost::none, boost::optional<time_t> now=boost::none);
+
+typedef std::unordered_map<DNSName, std::pair<DNSSECPrivateKey, DSRecordContent> > testkeysset_t;
 
 bool addRRSIG(const testkeysset_t& keys, std::vector<DNSRecord>& records, const DNSName& signer, uint32_t sigValidity, bool broken = false, boost::optional<uint8_t> algo = boost::none, boost::optional<DNSName> wildcard = boost::none, boost::optional<time_t> now = boost::none);
 
index cee166ace715ac20ecd41c044aa084f5d1f8b870..f879409d4ab56668f5e7d2b0b35478a718c99d37 100644 (file)
@@ -444,8 +444,8 @@ BOOST_AUTO_TEST_CASE(test_dnssec_rrsig)
   dpk.d_flags = 256;
   dpk.setKey(dcke);
 
-  std::vector<std::shared_ptr<DNSRecordContent>> recordcontents;
-  recordcontents.push_back(getRecordContent(QType::A, "192.0.2.1"));
+  sortedRecords_t recordcontents;
+  recordcontents.insert(getRecordContent(QType::A, "192.0.2.1"));
 
   DNSName qname("powerdns.com.");
 
index a015227119cc0ee1306cef6e8a5cf87b81cfab7a..147a3e01fa19e1e07cbb9b9cabf6d410b9d1d8c2 100644 (file)
@@ -14,15 +14,15 @@ BOOST_AUTO_TEST_CASE(test_nsec_denial_nowrap)
 
   vector<DNSRecord> records;
 
-  vector<shared_ptr<DNSRecordContent>> recordContents;
+  sortedRecords_t recordContents;
   vector<shared_ptr<RRSIGRecordContent>> signatureContents;
 
   /*
     No wrap test case:
     a.example.org. -> d.example.org. denies the existence of b.example.org.
    */
-  addNSECRecordToLW(DNSName("a.example.org."), DNSName("d.example.org"), {QType::A, QType::TXT, QType::RRSIG, QType::NSEC}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSECRecordToLW(DNSName("a.example.org."), DNSName("d.example.org"), { QType::A, QType::TXT, QType::RRSIG, QType::NSEC }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("example.org."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
   records.clear();
@@ -36,8 +36,8 @@ BOOST_AUTO_TEST_CASE(test_nsec_denial_nowrap)
   /* add wildcard denial */
   recordContents.clear();
   signatureContents.clear();
-  addNSECRecordToLW(DNSName("example.org."), DNSName("+.example.org"), {QType::A, QType::TXT, QType::RRSIG, QType::NSEC}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSECRecordToLW(DNSName("example.org."), DNSName("+.example.org"), { QType::A, QType::TXT, QType::RRSIG, QType::NSEC }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("example.org."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
   records.clear();
@@ -63,15 +63,15 @@ BOOST_AUTO_TEST_CASE(test_nsec_denial_wrap_case_1)
 
   vector<DNSRecord> records;
 
-  vector<shared_ptr<DNSRecordContent>> recordContents;
+  sortedRecords_t recordContents;
   vector<shared_ptr<RRSIGRecordContent>> signatureContents;
 
   /*
     Wrap case 1 test case:
     z.example.org. -> b.example.org. denies the existence of a.example.org.
    */
-  addNSECRecordToLW(DNSName("z.example.org."), DNSName("b.example.org"), {QType::A, QType::TXT, QType::RRSIG, QType::NSEC}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSECRecordToLW(DNSName("z.example.org."), DNSName("b.example.org"), { QType::A, QType::TXT, QType::RRSIG, QType::NSEC }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("example.org."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
   records.clear();
@@ -99,15 +99,15 @@ BOOST_AUTO_TEST_CASE(test_nsec_denial_wrap_case_2)
 
   vector<DNSRecord> records;
 
-  vector<shared_ptr<DNSRecordContent>> recordContents;
+  sortedRecords_t recordContents;
   vector<shared_ptr<RRSIGRecordContent>> signatureContents;
 
   /*
     Wrap case 2 test case:
     y.example.org. -> a.example.org. denies the existence of z.example.org.
    */
-  addNSECRecordToLW(DNSName("y.example.org."), DNSName("a.example.org"), {QType::A, QType::TXT, QType::RRSIG, QType::NSEC}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSECRecordToLW(DNSName("y.example.org."), DNSName("a.example.org"), { QType::A, QType::TXT, QType::RRSIG, QType::NSEC }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("example.org."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
   records.clear();
@@ -135,15 +135,15 @@ BOOST_AUTO_TEST_CASE(test_nsec_denial_only_one_nsec)
 
   vector<DNSRecord> records;
 
-  vector<shared_ptr<DNSRecordContent>> recordContents;
+  sortedRecords_t recordContents;
   vector<shared_ptr<RRSIGRecordContent>> signatureContents;
 
   /*
     Only one NSEC in the whole zone test case:
     a.example.org. -> a.example.org. denies the existence of b.example.org.
    */
-  addNSECRecordToLW(DNSName("a.example.org."), DNSName("a.example.org"), {QType::A, QType::TXT, QType::RRSIG, QType::NSEC}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSECRecordToLW(DNSName("a.example.org."), DNSName("a.example.org"), { QType::A, QType::TXT, QType::RRSIG, QType::NSEC }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("example.org."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
   records.clear();
@@ -171,15 +171,15 @@ BOOST_AUTO_TEST_CASE(test_nsec_root_nxd_denial)
 
   vector<DNSRecord> records;
 
-  vector<shared_ptr<DNSRecordContent>> recordContents;
+  sortedRecords_t recordContents;
   vector<shared_ptr<RRSIGRecordContent>> signatureContents;
 
   /*
     The RRSIG from "." denies the existence of anything between a. and c.,
     including b.
   */
-  addNSECRecordToLW(DNSName("a."), DNSName("c."), {QType::NS}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSECRecordToLW(DNSName("a."), DNSName("c."), { QType::NS }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
   records.clear();
@@ -193,8 +193,8 @@ BOOST_AUTO_TEST_CASE(test_nsec_root_nxd_denial)
   /* add wildcard denial */
   recordContents.clear();
   signatureContents.clear();
-  addNSECRecordToLW(DNSName("."), DNSName("+"), {QType::A, QType::TXT, QType::RRSIG, QType::NSEC}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSECRecordToLW(DNSName("."), DNSName("+"), { QType::A, QType::TXT, QType::RRSIG, QType::NSEC }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
   records.clear();
@@ -216,7 +216,7 @@ BOOST_AUTO_TEST_CASE(test_nsec_ancestor_nxqtype_denial)
 
   vector<DNSRecord> records;
 
-  vector<shared_ptr<DNSRecordContent>> recordContents;
+  sortedRecords_t recordContents;
   vector<shared_ptr<RRSIGRecordContent>> signatureContents;
 
   /*
@@ -225,8 +225,8 @@ BOOST_AUTO_TEST_CASE(test_nsec_ancestor_nxqtype_denial)
     signer field that is shorter than the owner name of the NSEC RR) it can't
     be used to deny anything except the whole name or a DS.
   */
-  addNSECRecordToLW(DNSName("a."), DNSName("b."), {QType::NS}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSECRecordToLW(DNSName("a."), DNSName("b."), { QType::NS }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
   records.clear();
@@ -266,7 +266,7 @@ BOOST_AUTO_TEST_CASE(test_nsec_insecure_delegation_denial)
 
   vector<DNSRecord> records;
 
-  vector<shared_ptr<DNSRecordContent>> recordContents;
+  sortedRecords_t recordContents;
   vector<shared_ptr<RRSIGRecordContent>> signatureContents;
 
   /*
@@ -281,8 +281,8 @@ BOOST_AUTO_TEST_CASE(test_nsec_insecure_delegation_denial)
     NS should be set if it was proving an insecure delegation, let's check that
     we correctly detect that it's not.
   */
-  addNSECRecordToLW(DNSName("a."), DNSName("b."), {}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSECRecordToLW(DNSName("a."), DNSName("b."), { }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
   records.clear();
@@ -308,11 +308,11 @@ BOOST_AUTO_TEST_CASE(test_nsec_nxqtype_cname)
 
   vector<DNSRecord> records;
 
-  vector<shared_ptr<DNSRecordContent>> recordContents;
+  sortedRecords_t recordContents;
   vector<shared_ptr<RRSIGRecordContent>> signatureContents;
 
-  addNSECRecordToLW(DNSName("a.powerdns.com."), DNSName("a.c.powerdns.com."), {QType::CNAME}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSECRecordToLW(DNSName("a.powerdns.com."), DNSName("a.c.powerdns.com."), { QType::CNAME }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("powerdns.com."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
   records.clear();
@@ -337,11 +337,11 @@ BOOST_AUTO_TEST_CASE(test_nsec3_nxqtype_cname)
 
   vector<DNSRecord> records;
 
-  vector<shared_ptr<DNSRecordContent>> recordContents;
+  sortedRecords_t recordContents;
   vector<shared_ptr<RRSIGRecordContent>> signatureContents;
 
-  addNSEC3UnhashedRecordToLW(DNSName("a.powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::CNAME}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSEC3UnhashedRecordToLW(DNSName("a.powerdns.com."), DNSName("powerdns.com."), "whatever", { QType::CNAME }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("powerdns.com."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
 
@@ -366,11 +366,11 @@ BOOST_AUTO_TEST_CASE(test_nsec_nxdomain_denial_missing_wildcard)
 
   vector<DNSRecord> records;
 
-  vector<shared_ptr<DNSRecordContent>> recordContents;
+  sortedRecords_t recordContents;
   vector<shared_ptr<RRSIGRecordContent>> signatureContents;
 
-  addNSECRecordToLW(DNSName("a.powerdns.com."), DNSName("d.powerdns.com"), {QType::A, QType::TXT, QType::RRSIG, QType::NSEC}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSECRecordToLW(DNSName("a.powerdns.com."), DNSName("d.powerdns.com"), { QType::A, QType::TXT, QType::RRSIG, QType::NSEC }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("powerdns.com."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
   records.clear();
@@ -394,11 +394,11 @@ BOOST_AUTO_TEST_CASE(test_nsec3_nxdomain_denial_missing_wildcard)
 
   vector<DNSRecord> records;
 
-  vector<shared_ptr<DNSRecordContent>> recordContents;
+  sortedRecords_t recordContents;
   vector<shared_ptr<RRSIGRecordContent>> signatureContents;
 
-  addNSEC3NarrowRecordToLW(DNSName("a.powerdns.com."), DNSName("powerdns.com."), {QType::A, QType::TXT, QType::RRSIG, QType::NSEC}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSEC3NarrowRecordToLW(DNSName("a.powerdns.com."), DNSName("powerdns.com."), { QType::A, QType::TXT, QType::RRSIG, QType::NSEC }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("powerdns.com."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
 
@@ -412,8 +412,8 @@ BOOST_AUTO_TEST_CASE(test_nsec3_nxdomain_denial_missing_wildcard)
   recordContents.clear();
   signatureContents.clear();
   records.clear();
-  addNSEC3UnhashedRecordToLW(DNSName("powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::A, QType::TXT, QType::RRSIG, QType::NSEC}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSEC3UnhashedRecordToLW(DNSName("powerdns.com."), DNSName("powerdns.com."), "whatever", { QType::A, QType::TXT, QType::RRSIG, QType::NSEC }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("powerdns.com."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
 
@@ -434,11 +434,11 @@ BOOST_AUTO_TEST_CASE(test_nsec_ent_denial)
 
   vector<DNSRecord> records;
 
-  vector<shared_ptr<DNSRecordContent>> recordContents;
+  sortedRecords_t recordContents;
   vector<shared_ptr<RRSIGRecordContent>> signatureContents;
 
-  addNSECRecordToLW(DNSName("a.powerdns.com."), DNSName("a.c.powerdns.com."), {QType::A}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSECRecordToLW(DNSName("a.powerdns.com."), DNSName("a.c.powerdns.com."), { QType::A }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("powerdns.com."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
   records.clear();
@@ -466,8 +466,8 @@ BOOST_AUTO_TEST_CASE(test_nsec_ent_denial)
   /* if we add the wildcard denial proof, we should get a NXDOMAIN proof for b.powerdns.com */
   recordContents.clear();
   signatureContents.clear();
-  addNSECRecordToLW(DNSName(").powerdns.com."), DNSName("+.powerdns.com."), {}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSECRecordToLW(DNSName(").powerdns.com."), DNSName("+.powerdns.com."), { }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("powerdns.com."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
   records.clear();
@@ -488,7 +488,7 @@ BOOST_AUTO_TEST_CASE(test_nsec3_ancestor_nxqtype_denial)
 
   vector<DNSRecord> records;
 
-  vector<shared_ptr<DNSRecordContent>> recordContents;
+  sortedRecords_t recordContents;
   vector<shared_ptr<RRSIGRecordContent>> signatureContents;
 
   /*
@@ -497,8 +497,8 @@ BOOST_AUTO_TEST_CASE(test_nsec3_ancestor_nxqtype_denial)
     signer field that is shorter than the owner name of the NSEC RR) it can't
     be used to deny anything except the whole name or a DS.
   */
-  addNSEC3UnhashedRecordToLW(DNSName("a."), DNSName("."), "whatever", {QType::NS}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSEC3UnhashedRecordToLW(DNSName("a."), DNSName("."), "whatever", { QType::NS }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
 
@@ -529,8 +529,8 @@ BOOST_AUTO_TEST_CASE(test_nsec3_ancestor_nxqtype_denial)
   recordContents.clear();
   signatureContents.clear();
   records.clear();
-  addNSEC3NarrowRecordToLW(DNSName("sub.a."), DNSName("."), {QType::A, QType::TXT, QType::RRSIG, QType::NSEC3}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSEC3NarrowRecordToLW(DNSName("sub.a."), DNSName("."), { QType::A, QType::TXT, QType::RRSIG, QType::NSEC3 }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
 
@@ -542,8 +542,8 @@ BOOST_AUTO_TEST_CASE(test_nsec3_ancestor_nxqtype_denial)
   recordContents.clear();
   signatureContents.clear();
   records.clear();
-  addNSEC3NarrowRecordToLW(DNSName("*.a."), DNSName("."), {QType::A, QType::TXT, QType::RRSIG, QType::NSEC3}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSEC3NarrowRecordToLW(DNSName("*.a."), DNSName("."), { QType::A, QType::TXT, QType::RRSIG, QType::NSEC3 }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
 
@@ -564,12 +564,12 @@ BOOST_AUTO_TEST_CASE(test_nsec3_denial_too_many_iterations)
 
   vector<DNSRecord> records;
 
-  vector<shared_ptr<DNSRecordContent>> recordContents;
+  sortedRecords_t recordContents;
   vector<shared_ptr<RRSIGRecordContent>> signatureContents;
 
   /* adding a NSEC3 with more iterations that we support */
-  addNSEC3UnhashedRecordToLW(DNSName("a."), DNSName("."), "whatever", {QType::AAAA}, 600, records, g_maxNSEC3Iterations + 100);
-  recordContents.push_back(records.at(0).d_content);
+  addNSEC3UnhashedRecordToLW(DNSName("a."), DNSName("."), "whatever", { QType::AAAA }, 600, records, g_maxNSEC3Iterations + 100);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
 
@@ -594,7 +594,7 @@ BOOST_AUTO_TEST_CASE(test_nsec3_insecure_delegation_denial)
 
   vector<DNSRecord> records;
 
-  vector<shared_ptr<DNSRecordContent>> recordContents;
+  sortedRecords_t recordContents;
   vector<shared_ptr<RRSIGRecordContent>> signatureContents;
 
   /*
@@ -609,8 +609,8 @@ BOOST_AUTO_TEST_CASE(test_nsec3_insecure_delegation_denial)
     NS should be set if it was proving an insecure delegation, let's check that
     we correctly detect that it's not.
   */
-  addNSEC3UnhashedRecordToLW(DNSName("a."), DNSName("."), "whatever", {}, 600, records);
-  recordContents.push_back(records.at(0).d_content);
+  addNSEC3UnhashedRecordToLW(DNSName("a."), DNSName("."), "whatever", { }, 600, records);
+  recordContents.insert(records.at(0).d_content);
   addRRSIG(keys, records, DNSName("."), 300);
   signatureContents.push_back(getRR<RRSIGRecordContent>(records.at(1)));
 
index 527bb3abd79751d138920b957e106016c16ab13b..dd82572626a75666270ad8ff10c2060d46113faa 100644 (file)
@@ -1771,7 +1771,7 @@ static cspmap_t harvestCSPFromNE(const NegCache::NegCacheEntry& ne)
     }
   }
   for(const auto& rec : ne.DNSSECRecords.records) {
-    cspmap[{rec.d_name, rec.d_type}].records.push_back(rec.d_content);
+    cspmap[{rec.d_name, rec.d_type}].records.insert(rec.d_content);
   }
   return cspmap;
 }
@@ -2229,14 +2229,14 @@ vState SyncRes::validateDNSKeys(const DNSName& zone, const std::vector<DNSRecord
   }
 
   skeyset_t tentativeKeys;
-  std::vector<shared_ptr<DNSRecordContent> > toSign;
+  sortedRecords_t toSign;
 
   for (const auto& dnskey : dnskeys) {
     if (dnskey.d_type == QType::DNSKEY) {
       auto content = getRR<DNSKEYRecordContent>(dnskey);
       if (content) {
         tentativeKeys.insert(content);
-        toSign.push_back(content);
+        toSign.insert(content);
       }
     }
   }
@@ -2316,9 +2316,9 @@ vState SyncRes::validateRecordsWithSigs(unsigned int depth, const DNSName& qname
     return Bogus;
   }
 
-  std::vector<std::shared_ptr<DNSRecordContent> > recordcontents;
+  sortedRecords_t recordcontents;
   for (const auto& record : records) {
-    recordcontents.push_back(record.d_content);
+    recordcontents.insert(record.d_content);
   }
 
   LOG(d_prefix<<"Going to validate "<<recordcontents.size()<< " record contents with "<<signatures.size()<<" sigs and "<<keys.size()<<" keys for "<<name<<endl);
index adbafc87ae66ff704715ba2b708bf140a2332d1b..da21db062a16d40576322225309f15da3f28f1b7 100644 (file)
@@ -111,7 +111,7 @@ static void checkRR(const signerParams& signer)
   dpk.setKey(dcke);
   dpk.d_flags = signer.rfcFlags;
 
-  vector<std::shared_ptr<DNSRecordContent> > rrs;
+  sortedRecords_t rrs;
   /* values taken from rfc8080 for ed25519 and ed448, rfc5933 for gost */
   DNSName qname(dpk.d_algorithm == 12 ? "www.example.net." : "example.com.");
 
@@ -125,17 +125,17 @@ static void checkRR(const signerParams& signer)
     rrc.d_signer = DNSName("example.net.");
     inception = 946684800;
     expire = 1893456000;
-    rrs.push_back(DNSRecordContent::mastermake(QType::A, QClass::IN, "192.0.2.1"));
+    rrs.insert(DNSRecordContent::mastermake(QType::A, QClass::IN, "192.0.2.1"));
   }
   else {
     rrc.d_signer = qname;
-    rrs.push_back(DNSRecordContent::mastermake(QType::MX, QClass::IN, "10 mail.example.com."));
+    rrs.insert(DNSRecordContent::mastermake(QType::MX, QClass::IN, "10 mail.example.com."));
   }
 
   rrc.d_originalttl = 3600;
   rrc.d_sigexpire = expire;
   rrc.d_siginception = inception;
-  rrc.d_type = rrs.at(0)->getType();
+  rrc.d_type = (*rrs.cbegin())->getType();
   rrc.d_labels = qname.countLabels();
   rrc.d_tag = dpk.getTag();
   rrc.d_algorithm = dpk.d_algorithm;
@@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE(test_generic_signers)
 
 #if defined(HAVE_LIBDECAF) || defined(HAVE_LIBCRYPTO_ED448)
 BOOST_AUTO_TEST_CASE(test_ed448_signer) {
-    vector<std::shared_ptr<DNSRecordContent> > rrs;
+    sortedRecords_t rrs;
     DNSName qname("example.com.");
     DNSKEYRecordContent drc;
 
@@ -230,7 +230,7 @@ BOOST_AUTO_TEST_CASE(test_ed448_signer) {
 
     reportBasicTypes();
 
-    rrs.push_back(DNSRecordContent::mastermake(QType::MX, 1, "10 mail.example.com."));
+    rrs.insert(DNSRecordContent::mastermake(QType::MX, 1, "10 mail.example.com."));
 
     RRSIGRecordContent rrc;
     rrc.d_originalttl = 3600;
index ab7fa3d9e25d76286fd0f373d6400ef63ba13e43..8bbacc3a9f743f2c325b236bd130782e8a9e139e 100644 (file)
@@ -733,7 +733,7 @@ static bool checkSignatureWithKey(time_t now, const shared_ptr<RRSIGRecordConten
   return result;
 }
 
-bool validateWithKeySet(time_t now, const DNSName& name, const vector<shared_ptr<DNSRecordContent> >& records, const vector<shared_ptr<RRSIGRecordContent> >& signatures, const skeyset_t& keys, bool validateAllSigs)
+bool validateWithKeySet(time_t now, const DNSName& name, const sortedRecords_t& toSign, const vector<shared_ptr<RRSIGRecordContent> >& signatures, const skeyset_t& keys, bool validateAllSigs)
 {
   bool isValid = false;
 
@@ -743,8 +743,6 @@ bool validateWithKeySet(time_t now, const DNSName& name, const vector<shared_ptr
       LOG(name<<": Discarding invalid RRSIG whose label count is "<<signature->d_labels<<" while the RRset owner name has only "<<labelCount<<endl);
     }
 
-    vector<shared_ptr<DNSRecordContent> > toSign = records;
-
     auto r = getByTag(keys, signature->d_tag, signature->d_algorithm);
 
     if(r.empty()) {
@@ -810,7 +808,7 @@ cspmap_t harvestCSPFromRecs(const vector<DNSRecord>& recs)
       }
     }
     else {
-      cspmap[{rec.d_name, rec.d_type}].records.push_back(rec.d_content);
+      cspmap[{rec.d_name, rec.d_type}].records.insert(rec.d_content);
     }
   }
   return cspmap;
@@ -840,7 +838,7 @@ bool haveNegativeTrustAnchor(const map<DNSName,std::string>& negAnchors, const D
   return true;
 }
 
-void validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t& dsmap, const skeyset_t& tkeys, vector<shared_ptr<DNSRecordContent> >& toSign, const vector<shared_ptr<RRSIGRecordContent> >& sigs, skeyset_t& validkeys)
+void validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t& dsmap, const skeyset_t& tkeys, const sortedRecords_t& toSign, const vector<shared_ptr<RRSIGRecordContent> >& sigs, skeyset_t& validkeys)
 {
   /*
    * Check all DNSKEY records against all DS records and place all DNSKEY records
@@ -978,7 +976,7 @@ vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, skeyset_t& keyset)
   for(auto zoneCutIter = zoneCuts.cbegin(); zoneCutIter != zoneCuts.cend(); ++zoneCutIter)
   {
     vector<shared_ptr<RRSIGRecordContent> > sigs;
-    vector<shared_ptr<DNSRecordContent> > toSign;
+    sortedRecords_t toSign;
 
     skeyset_t tkeys; // tentative keys
     validkeys.clear();
@@ -1007,7 +1005,7 @@ vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, skeyset_t& keyset)
           tkeys.insert(drc);
           LOG("Inserting key with tag "<<drc->getTag()<<" and algorithm "<<DNSSECKeeper::algorithm2name(drc->d_algorithm)<<": "<<drc->getZoneRepresentation()<<endl);
 
-          toSign.push_back(rec.d_content);
+          toSign.insert(rec.d_content);
         }
       }
     }
index b30fca1c6e79533b316c744f34ee116a418afcec..76e9de3d046ab204d1da8c0bb92cd33c44492b30 100644 (file)
@@ -26,6 +26,7 @@
 #include <vector>
 #include "namespaces.hh"
 #include "dnsrecords.hh"
+#include "dnssecinfra.hh"
  
 extern bool g_dnssecLOG;
 extern time_t g_signatureInceptionSkew;
@@ -48,7 +49,7 @@ public:
 
 struct ContentSigPair
 {
-  vector<shared_ptr<DNSRecordContent>> records;
+  sortedRecords_t records;
   vector<shared_ptr<RRSIGRecordContent>> signatures;
   // ponder adding a validate method that accepts a key
 };
@@ -65,13 +66,13 @@ struct sharedDNSKeyRecordContentCompare
 
 typedef set<shared_ptr<DNSKEYRecordContent>, sharedDNSKeyRecordContentCompare > skeyset_t;
 
-bool validateWithKeySet(time_t now, const DNSName& name, const vector<shared_ptr<DNSRecordContent> >& records, const vector<shared_ptr<RRSIGRecordContent> >& signatures, const skeyset_t& keys, bool validateAllSigs=true);
+bool validateWithKeySet(time_t now, const DNSName& name, const sortedRecords_t& records, const vector<shared_ptr<RRSIGRecordContent> >& signatures, const skeyset_t& keys, bool validateAllSigs=true);
 void validateWithKeySet(const cspmap_t& rrsets, cspmap_t& validated, const skeyset_t& keys);
 cspmap_t harvestCSPFromRecs(const vector<DNSRecord>& recs);
 vState getKeysFor(DNSRecordOracle& dro, const DNSName& zone, skeyset_t& keyset);
 bool getTrustAnchor(const map<DNSName,dsmap_t>& anchors, const DNSName& zone, dsmap_t &res);
 bool haveNegativeTrustAnchor(const map<DNSName,std::string>& negAnchors, const DNSName& zone, std::string& reason);
-void validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t& dsmap, const skeyset_t& tkeys, vector<shared_ptr<DNSRecordContent> >& toSign, const vector<shared_ptr<RRSIGRecordContent> >& sigs, skeyset_t& validkeys);
+void validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t& dsmap, const skeyset_t& tkeys, const sortedRecords_t& toSign, const vector<shared_ptr<RRSIGRecordContent> >& sigs, skeyset_t& validkeys);
 dState getDenial(const cspmap_t &validrrsets, const DNSName& qname, const uint16_t qtype, bool referralToUnsigned, bool wantsNoDataProof, bool needsWildcardProof=true, unsigned int wildcardLabelsCount=0);
 bool isSupportedDS(const DSRecordContent& ds);
 DNSName getSigner(const std::vector<std::shared_ptr<RRSIGRecordContent> >& signatures);