From: JINMEI Tatuya Date: Tue, 14 Feb 2012 02:53:56 +0000 (-0800) Subject: [1585] implemented unsigned delegation with NSEC3 case X-Git-Tag: trac2351_base~97^2~30^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d20fafd80c35a7c5ad85f097556e79b9d73dbf8a;p=thirdparty%2Fkea.git [1585] implemented unsigned delegation with NSEC3 case --- diff --git a/src/bin/auth/query.cc b/src/bin/auth/query.cc index dee976f272..4c220104c7 100644 --- a/src/bin/auth/query.cc +++ b/src/bin/auth/query.cc @@ -214,10 +214,31 @@ Query::addDS(ZoneFinder& finder, const Name& dname) { finder.find(dname, RRType::DS(), dnssec_opt_); if (ds_result.code == ZoneFinder::SUCCESS) { response_.addRRset(Message::SECTION_AUTHORITY, - boost::const_pointer_cast(ds_result.rrset), + boost::const_pointer_cast( + ds_result.rrset), dnssec_); - } else if (ds_result.code == ZoneFinder::NXRRSET) { + } else if (ds_result.code == ZoneFinder::NXRRSET && + ds_result.isNSECSigned()) { addNXRRsetProof(finder, ds_result); + } else if (ds_result.code == ZoneFinder::NXRRSET && + ds_result.isNSEC3Signed()) { + // Add no DS proof with NSEC3 as specified in RFC5155 Section 7.2.7. + // Depending on whether the zone is optout or not, findNSEC3() may + // return non-NULL or NULL next_proof (respectively). The Opt-Out flag + // must be set or cleared accordingly, but we don't check that + // in this level (as long as the zone signed validly and findNSEC3() + // is valid, the condition should be met; otherwise we'd let the + // validator detect the error). + const ZoneFinder::FindNSEC3Result nsec3_result = + finder.findNSEC3(dname, true); + response_.addRRset(Message::SECTION_AUTHORITY, + boost::const_pointer_cast( + nsec3_result.closest_proof), dnssec_); + if (nsec3_result.next_proof) { + response_.addRRset(Message::SECTION_AUTHORITY, + boost::const_pointer_cast( + nsec3_result.next_proof), dnssec_); + } } else { // Any other case should be an error isc_throw(BadDS, "Unexpected result for DS lookup for delegation"); diff --git a/src/bin/auth/tests/query_unittest.cc b/src/bin/auth/tests/query_unittest.cc index ca32322718..7a0d523593 100644 --- a/src/bin/auth/tests/query_unittest.cc +++ b/src/bin/auth/tests/query_unittest.cc @@ -316,6 +316,8 @@ public: "q00jkcevqvmu85r014c7dkba38o0ji5r"; hash_map_[Name("nxdomain3.example.com")] = "009mhaveqvm6t7vbl5lop2u3t2rp3tom"; + hash_map_[Name("unsigned-delegation.example.com")] = + "q04jkcevqvmu85r014c7dkba38o0ji8r"; // a bit larger than H(www) hash_map_[Name("*.uwild.example.com")] = "b4um86eghhds6nea196smvmlo4ors995"; @@ -1039,6 +1041,55 @@ TEST_F(QueryTest, secureUnsignedDelegation) { NULL); } +TEST_F(QueryTest, secureUnsignedDelegationWithNSEC3) { + // Similar to the previous case, but the zone is signed with NSEC3, + // and this delegation is NOT an optout. + const Name insecurechild_name("unsigned-delegation.example.com"); + const string nsec3_insecurechild_str = + mock_finder->hash_map_[insecurechild_name] + ".example.com. 3600 " + "IN NSEC3 1 1 12 aabbccdd 2t7b4g4vsa5smi47k61mv5bv1a22bojr NS\n"; + mock_finder->setNSEC3Flag(true); + mock_finder->addRecord(nsec3_insecurechild_str); + + Query(memory_client, Name("foo.unsigned-delegation.example.com"), + qtype, response, true).process(); + + // The response should contain the NS and matching NSEC3 with its RRSIG + responseCheck(response, Rcode::NOERROR(), 0, 0, 3, 0, + NULL, + (string(unsigned_delegation_txt) + + nsec3_insecurechild_str + + mock_finder->hash_map_[insecurechild_name] + + ".example.com. 3600 IN RRSIG " + + getCommonRRSIGText("NSEC3")).c_str(), + NULL); +} + +TEST_F(QueryTest, secureUnsignedDelegationWithNSEC3OptOut) { + // Similar to the previous case, but the delegation is an optout. + mock_finder->setNSEC3Flag(true); + + Query(memory_client, Name("foo.unsigned-delegation.example.com"), + qtype, response, true).process(); + + // The response should contain the NS and the closest provable encloser + // proof (and their RRSIGs). The closest encloser is the apex (origin), + // and with our faked hash the covering NSEC3 for the next closer + // (= child zone name) is that for www.example.com. + responseCheck(response, Rcode::NOERROR(), 0, 0, 5, 0, + NULL, + (string(unsigned_delegation_txt) + + string(nsec3_apex_txt) + + mock_finder->hash_map_[mock_finder->getOrigin()] + + ".example.com. 3600 IN RRSIG " + + getCommonRRSIGText("NSEC3") + "\n" + + string(nsec3_www_txt) + + mock_finder->hash_map_[Name("www.example.com")] + + ".example.com. 3600 IN RRSIG " + + getCommonRRSIGText("NSEC3")).c_str(), + NULL); +} + TEST_F(QueryTest, badSecureDelegation) { // Test whether exception is raised if DS query at delegation results in // something different than SUCCESS or NXRRSET