From: JINMEI Tatuya Date: Tue, 31 Jan 2012 04:09:10 +0000 (-0800) Subject: [1574b] checked some NSEC3 parameter consistency X-Git-Tag: trac2351_base~268^2~5^2~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=95f2ccbb56b3dcb8f77e3def5beaade65a8891b2;p=thirdparty%2Fkea.git [1574b] checked some NSEC3 parameter consistency --- diff --git a/src/lib/datasrc/memory_datasrc.cc b/src/lib/datasrc/memory_datasrc.cc index 2ace69c3bd..c3dc37c164 100644 --- a/src/lib/datasrc/memory_datasrc.cc +++ b/src/lib/datasrc/memory_datasrc.cc @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -86,8 +87,14 @@ struct ZoneData { // The optional NSEC3 related data struct NSEC3Data { - NSEC3Map map_; // Actual NSEC3 RRs - // We should also have hash parameters here (maybe hold NSEC3Hash?) + NSEC3Data(const generic::NSEC3PARAM& nsec3param) : + hash_(NSEC3Hash::create(nsec3param)) + {} + NSEC3Data(const generic::NSEC3& nsec3) : + hash_(NSEC3Hash::create(nsec3)) + {} + NSEC3Map map_; // Actual NSEC3 RRs + const scoped_ptr hash_; // hash parameter/calculator }; scoped_ptr nsec3_data_; // non NULL only when it's NSEC3 signed }; @@ -370,9 +377,22 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl { } result::Result addNSEC3(const ConstRRsetPtr rrset, ZoneData& zone_data) { + // We know rrset has exactly one RDATA + const generic::NSEC3& nsec3_rdata = + dynamic_cast( + rrset->getRdataIterator()->getCurrent()); + + // If we've not done any NSEC3 setup for the zone, do it know; + // otherwise check parameter consistency. if (!zone_data.nsec3_data_) { - zone_data.nsec3_data_.reset(new ZoneData::NSEC3Data); + zone_data.nsec3_data_.reset(new ZoneData::NSEC3Data(nsec3_rdata)); + } else { + if (!zone_data.nsec3_data_->hash_->match(nsec3_rdata)) { + isc_throw(AddError, "NSEC3 with inconsistent parameters: " << + rrset->toText()); + } } + string fst_label = rrset->getName().split(0, 1).toText(true); transform(fst_label.begin(), fst_label.end(), fst_label.begin(), ToUpper()); @@ -457,6 +477,17 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl { node->setFlag(DomainNode::FLAG_CALLBACK); } + // If we've added NSEC3PARAM and the zone isn't yet NSEC3-ready + // set it up (note: this part doesn't ensure strong exception + // guarantee) + if (rrset->getType() == RRType::NSEC3PARAM() && + !zone_data.nsec3_data_) { + zone_data.nsec3_data_.reset( + new ZoneData::NSEC3Data( + dynamic_cast( + rrset->getRdataIterator()->getCurrent()))); + } + return (result::SUCCESS); } else { // The RRSet of given type was already there diff --git a/src/lib/datasrc/tests/memory_datasrc_unittest.cc b/src/lib/datasrc/tests/memory_datasrc_unittest.cc index f9177998bb..c735fe979b 100644 --- a/src/lib/datasrc/tests/memory_datasrc_unittest.cc +++ b/src/lib/datasrc/tests/memory_datasrc_unittest.cc @@ -1478,6 +1478,34 @@ TEST_F(InMemoryZoneFinderTest, badRRsigForNSEC3) { InMemoryZoneFinder::AddError); } +TEST_F(InMemoryZoneFinderTest, paramConsistencyWithNSEC3PARAM) { + // First, add an NSEC3PARAM RR + EXPECT_EQ(result::SUCCESS, + zone_finder_.add(textToRRset("example.org. 300 IN NSEC3PARAM " + "1 0 12 aabbccdd"))); + // Adding an NSEC3 that has matching parameters is okay. + EXPECT_EQ(result::SUCCESS, zone_finder_.add( + textToRRset(string(apex_hash) + ".example.org." + + string(nsec3_common)))); + // NSEC3 with inconsistent parameter will be rejected + EXPECT_THROW(zone_finder_.add( + textToRRset("a.example.org. 300 IN NSEC3 1 0 1 aabbccdd " + "2T7B4G4VSA5SMI47K61MV5BV1A22BOJR A RRSIG")), + InMemoryZoneFinder::AddError); +} + +TEST_F(InMemoryZoneFinderTest, paramConsistencyWithNSEC3) { + // Add an NSEC3 without adding NSEC3PARAM + EXPECT_EQ(result::SUCCESS, zone_finder_.add( + textToRRset(string(apex_hash) + ".example.org." + + string(nsec3_common)))); + // Adding an NSEC3 with inconsistent parameter will be rejected at this pt. + EXPECT_THROW(zone_finder_.add( + textToRRset("a.example.org. 300 IN NSEC3 1 0 1 aabbccdd " + "2T7B4G4VSA5SMI47K61MV5BV1A22BOJR A RRSIG")), + InMemoryZoneFinder::AddError); +} + TEST_F(InMemoryZoneFinderTest, multiNSEC3PARAM) { // In this current implementation multiple NSEC3PARAM isn't supported. RRsetPtr nsec3param(new RRset(Name("example.org"), RRClass::IN(), @@ -1488,8 +1516,7 @@ TEST_F(InMemoryZoneFinderTest, multiNSEC3PARAM) { } // TODO -// - parameter consistency // - existence of NSEC3PARAM -// - parameter consistency with NSEC3PARAM -// - add NSEC3PARAM first/second +// - add NSEC3PARAM second, check consistency +// - add NSEC3PARAM at non origin (should be ignored) }