From: Remi Gacogne Date: Tue, 13 Jul 2021 09:56:00 +0000 (+0200) Subject: rec: Ancestor NSEC3s can only deny the existence of a DS X-Git-Tag: dnsdist-1.7.0-alpha1~83^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d270600bf4d310dcdc3d422ecc9be6d8210e7849;p=thirdparty%2Fpdns.git rec: Ancestor NSEC3s can only deny the existence of a DS Before that commit, the aggressive NSEC(3) cache could have mistakenly used NSEC3s from the parent zone to prove that a given name in the child zone did not exist, which is incorrect. It happened because we did not properly detect that the NSEC3 for the closest encloser was an ancestor NSEC3 indicating a delegation, and then in the unlikely but possible case that we found a NSEC3 from the parent zone whose hashes covered the next closer we wrongly concluded that the name did not exist, returning a NXDomain with an invalid proof of denial. --- diff --git a/pdns/recursordist/aggressive_nsec.cc b/pdns/recursordist/aggressive_nsec.cc index a637720eeb..370750d403 100644 --- a/pdns/recursordist/aggressive_nsec.cc +++ b/pdns/recursordist/aggressive_nsec.cc @@ -580,6 +580,18 @@ bool AggressiveNSECCache::getNSEC3Denial(time_t now, std::shared_ptr sr; + initSR(sr, true); + g_aggressiveNSECCache = make_unique(10000); + + setDNSSECValidation(sr, DNSSECMode::ValidateAll); + + primeHints(); + /* powerdns.com is signed, sub.powerdns.com. is not. + We first get a query for sub.powerdns.com. which leads to an ancestor NSEC covering sub.powerdns.com.|DS to be inserted + into the aggressive cache, check that we don't mistakenly use that later to prove that something else below that name + doesn't exist either. */ + const DNSName target("sub.powerdns.com."); + testkeysset_t keys; + + auto luaconfsCopy = g_luaconfs.getCopy(); + luaconfsCopy.dsAnchors.clear(); + generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors); + generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys); + + g_luaconfs.setState(luaconfsCopy); + + size_t queriesCount = 0; + + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + queriesCount++; + + if (type == QType::DS || type == QType::DNSKEY) { + if (domain == DNSName("com.")) { + /* no cut */ + return genericDSAndDNSKEYHandler(res, domain, DNSName("."), type, keys, false); + } + else { + /* cut */ + return genericDSAndDNSKEYHandler(res, domain, domain, type, keys); + } + } + else { + if (isRootServer(ip)) { + setLWResult(res, 0, false, false, true); + addRecordToLW(res, "powerdns.com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600); + addDS(DNSName("powerdns.com."), 300, res->d_records, keys); + addRRSIG(keys, res->d_records, DNSName("."), 300); + addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600); + return LWResult::Result::Success; + } + else if (ip == ComboAddress("192.0.2.1:53")) { + if (domain.isPartOf(DNSName("sub.powerdns.com."))) { + setLWResult(res, 0, false, false, true); + addRecordToLW(res, "sub.powerdns.com.", QType::NS, "ns.sub.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600); + /* proof that the DS doesn't exist follows */ + /* NSEC ancestor for sub.powerdns.com */ + addNSECRecordToLW(DNSName("sub.powerdns.com."), DNSName("sub1.powerdns.com"), {QType::NS}, 600, res->d_records); + addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); + addRecordToLW(res, "ns.sub.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600); + return LWResult::Result::Success; + } + else if (domain == DNSName("sub16.powerdns.com.")) { + setLWResult(res, RCode::NXDomain, true, false, true); + addRecordToLW(res, DNSName("powerdns.com."), QType::SOA, "powerdns.com. powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600); + addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); + addNSECRecordToLW(DNSName("sub15.powerdns.com."), DNSName("sub17.powerdns.com."), {QType::A}, 600, res->d_records); + addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); + /* then the wildcard *.powerdns.com + next covers the wildcard *.sub.powerdns.com + */ + addNSECRecordToLW(DNSName(").powerdns.com"), DNSName("+.sub.powerdns.com"), {QType::TXT, QType::RRSIG}, 600, res->d_records); + addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); + return LWResult::Result::Success; + } + } + else if (ip == ComboAddress("192.0.2.2:53")) { + if (domain == target && type == QType::A) { + setLWResult(res, RCode::NoError, true, false, true); + addRecordToLW(res, DNSName("sub.powerdns.com."), QType::A, "192.0.2.42"); + return LWResult::Result::Success; + } + else if (domain == DNSName("4.sub.powerdns.com.") && type == QType::A) { + setLWResult(res, RCode::NoError, true, false, true); + addRecordToLW(res, DNSName("4.sub.powerdns.com."), QType::A, "192.0.2.84"); + return LWResult::Result::Success; + } + } + } + + return LWResult::Result::Timeout; + }); + + vector ret; + int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); + BOOST_CHECK_EQUAL(res, RCode::NoError); + BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure); + BOOST_REQUIRE_EQUAL(ret.size(), 1U); + BOOST_CHECK_EQUAL(queriesCount, 5U); + + /* now we query sub16.powerdns.com, to get a NSEC covering the wildcard for *.sub.powerdns.com */ + ret.clear(); + res = sr->beginResolve(DNSName("sub16.powerdns.com."), QType(QType::A), QClass::IN, ret); + BOOST_CHECK_EQUAL(res, RCode::NXDomain); + BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure); + BOOST_REQUIRE_EQUAL(ret.size(), 6U); + BOOST_CHECK_EQUAL(queriesCount, 6U); + + /* now we query other2.sub.powerdns.com, we should NOT be able to use the NSEC3s we have + to prove that the name does not exist */ + ret.clear(); + res = sr->beginResolve(DNSName("4.sub.powerdns.com"), QType(QType::A), QClass::IN, ret); + BOOST_CHECK_EQUAL(res, RCode::NoError); + BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure); + BOOST_REQUIRE_EQUAL(ret.size(), 1U); + BOOST_CHECK_EQUAL(queriesCount, 8U); +} + BOOST_AUTO_TEST_CASE(test_aggressive_nsec_wildcard_synthesis) { std::unique_ptr sr; @@ -622,13 +736,13 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec3_nodata_wildcard) addRecordToLW(res, DNSName("powerdns.com."), QType::SOA, "powerdns.com. powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600); addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); /* first the closest encloser */ - addNSEC3UnhashedRecordToLW(DNSName("powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::A, QType::TXT, QType::RRSIG}, 600, res->d_records); + addNSEC3UnhashedRecordToLW(DNSName("powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::A, QType::TXT, QType::RRSIG}, 600, res->d_records, 10); addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); /* then the next closer */ - addNSEC3UnhashedRecordToLW(DNSName("+.powerdns.com."), DNSName("powerdns.com."), "v", {QType::RRSIG}, 600, res->d_records); + addNSEC3UnhashedRecordToLW(DNSName("+.powerdns.com."), DNSName("powerdns.com."), "v", {QType::RRSIG}, 600, res->d_records, 10); addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); /* a wildcard applies but does not have this type */ - addNSEC3UnhashedRecordToLW(DNSName("*.powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::TXT, QType::RRSIG}, 600, res->d_records); + addNSEC3UnhashedRecordToLW(DNSName("*.powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::TXT, QType::RRSIG}, 600, res->d_records, 10); addRRSIG(keys, res->d_records, DNSName("powerdns.com"), 300, false, boost::none, DNSName("*.powerdns.com")); return LWResult::Result::Success; } @@ -660,13 +774,13 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec3_nodata_wildcard) addRecordToLW(res, DNSName("powerdns.com."), QType::SOA, "powerdns.com. powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600); addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); /* first the closest encloser */ - addNSEC3UnhashedRecordToLW(DNSName("powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::A, QType::TXT, QType::RRSIG}, 600, res->d_records); + addNSEC3UnhashedRecordToLW(DNSName("powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::A, QType::TXT, QType::RRSIG}, 600, res->d_records, 10); addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); /* then the next closer */ - addNSEC3UnhashedRecordToLW(DNSName("+.powerdns.com."), DNSName("powerdns.com."), "v", {QType::RRSIG}, 600, res->d_records); + addNSEC3UnhashedRecordToLW(DNSName("+.powerdns.com."), DNSName("powerdns.com."), "v", {QType::RRSIG}, 600, res->d_records, 10); addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); /* a wildcard applies but does not have this type */ - addNSEC3UnhashedRecordToLW(DNSName("*.powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::TXT, QType::RRSIG}, 600, res->d_records); + addNSEC3UnhashedRecordToLW(DNSName("*.powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::TXT, QType::RRSIG}, 600, res->d_records, 10); addRRSIG(keys, res->d_records, DNSName("powerdns.com"), 300, false, boost::none, DNSName("*.powerdns.com")); return LWResult::Result::Success; } @@ -691,6 +805,126 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec3_nodata_wildcard) BOOST_CHECK_EQUAL(queriesCount, 4U); } +BOOST_AUTO_TEST_CASE(test_aggressive_nsec3_ancestor) +{ + std::unique_ptr sr; + initSR(sr, true); + g_aggressiveNSECCache = make_unique(10000); + + setDNSSECValidation(sr, DNSSECMode::ValidateAll); + + primeHints(); + /* powerdns.com is signed, sub.powerdns.com. is not. + We first get a query for sub.powerdns.com. which leads to an ancestor NSEC3 covering sub.powerdns.com.|DS to be inserted + into the aggressive cache, check that we don't mistakenly use that later to prove that something else below that name + doesn't exist either. */ + const DNSName target("sub.powerdns.com."); + testkeysset_t keys; + + auto luaconfsCopy = g_luaconfs.getCopy(); + luaconfsCopy.dsAnchors.clear(); + generateKeyMaterial(g_rootdnsname, DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors); + generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys); + + g_luaconfs.setState(luaconfsCopy); + + size_t queriesCount = 0; + + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + queriesCount++; + + if (type == QType::DS || type == QType::DNSKEY) { + if (domain == DNSName("com.")) { + /* no cut */ + return genericDSAndDNSKEYHandler(res, domain, DNSName("."), type, keys, false); + } + else { + /* cut */ + return genericDSAndDNSKEYHandler(res, domain, domain, type, keys); + } + } + else { + if (isRootServer(ip)) { + setLWResult(res, 0, false, false, true); + addRecordToLW(res, "powerdns.com.", QType::NS, "a.gtld-servers.com.", DNSResourceRecord::AUTHORITY, 3600); + addDS(DNSName("powerdns.com."), 300, res->d_records, keys); + addRRSIG(keys, res->d_records, DNSName("."), 300); + addRecordToLW(res, "a.gtld-servers.com.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600); + return LWResult::Result::Success; + } + else if (ip == ComboAddress("192.0.2.1:53")) { + if (domain.isPartOf(DNSName("sub.powerdns.com."))) { + setLWResult(res, 0, false, false, true); + addRecordToLW(res, "sub.powerdns.com.", QType::NS, "ns.sub.powerdns.com.", DNSResourceRecord::AUTHORITY, 3600); + /* proof that the DS doesn't exist follows */ + /* NSEC3 ancestor for sub.powerdns.com (1 additional iteration, deadbeef as salt), : 7v5rgf7okrmumvb8rscop0t3j1m5o4mb + next is crafted to cover 4.sub.powerdns.com => 930v7tmju1s48fopjh5ktsp1jmagi20p */ + addNSEC3RecordToLW(DNSName("7v5rgf7okrmumvb8rscop0t3j1m5o4mb.powerdns.com."), fromBase32Hex("930v7tmju1s48fopjh5ktsp1jmagi20q"), "deadbeef", 1, {QType::NS}, 600, res->d_records); + addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); + addRecordToLW(res, "ns.sub.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600); + return LWResult::Result::Success; + } + else if (domain == DNSName("sub16.powerdns.com.")) { + setLWResult(res, RCode::NXDomain, true, false, true); + addRecordToLW(res, DNSName("powerdns.com."), QType::SOA, "powerdns.com. powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600); + addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); + /* first the closest encloser */ + addNSEC3UnhashedRecordToLW(DNSName("powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::SOA, QType::NS}, 600, res->d_records, 1); + addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); + /* then the next closer sub16.powerdns.com. */ + addNSEC3NarrowRecordToLW(DNSName("sub16.powerdns.com."), DNSName("powerdns.com."), {QType::A}, 600, res->d_records, 1); + addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); + /* then the wildcard *.powerdns.com: mtrrinpd8l9e7fmn8lp74o8dffnivs8i (minus one because NXD) + next is crafted to cover the wildcard *.sub.powerdns.com (ocgb0ilk3g1m3olpms0q1quhn18nncc0) + */ + addNSEC3RecordToLW(DNSName("mtrrinpd8l9e7fmn8lp74o8dffnivs8h.powerdns.com."), fromBase32Hex("ocgb0ilk3g1m3olpms0q1quhn18nncc1"), "deadbeef", 1, {QType::TXT, QType::RRSIG}, 600, res->d_records); + addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); + return LWResult::Result::Success; + } + } + else if (ip == ComboAddress("192.0.2.2:53")) { + if (domain == target && type == QType::A) { + setLWResult(res, RCode::NoError, true, false, true); + addRecordToLW(res, DNSName("sub.powerdns.com."), QType::A, "192.0.2.42"); + return LWResult::Result::Success; + } + else if (domain == DNSName("4.sub.powerdns.com.") && type == QType::A) { + setLWResult(res, RCode::NoError, true, false, true); + addRecordToLW(res, DNSName("4.sub.powerdns.com."), QType::A, "192.0.2.84"); + return LWResult::Result::Success; + } + } + } + + return LWResult::Result::Timeout; + }); + + vector ret; + int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); + BOOST_CHECK_EQUAL(res, RCode::NoError); + BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure); + BOOST_REQUIRE_EQUAL(ret.size(), 1U); + BOOST_CHECK_EQUAL(queriesCount, 5U); + + /* now we query sub16.powerdns.com, to get a hash covering the wildcard for + *.sub.powerdns.com */ + ret.clear(); + res = sr->beginResolve(DNSName("sub16.powerdns.com."), QType(QType::A), QClass::IN, ret); + BOOST_CHECK_EQUAL(res, RCode::NXDomain); + BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure); + BOOST_REQUIRE_EQUAL(ret.size(), 8U); + BOOST_CHECK_EQUAL(queriesCount, 6U); + + /* now we query other2.sub.powerdns.com, we should NOT be able to use the NSEC3s we have + to prove that the name does not exist */ + ret.clear(); + res = sr->beginResolve(DNSName("4.sub.powerdns.com"), QType(QType::A), QClass::IN, ret); + BOOST_CHECK_EQUAL(res, RCode::NoError); + BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure); + BOOST_REQUIRE_EQUAL(ret.size(), 1U); + BOOST_CHECK_EQUAL(queriesCount, 8U); +} + BOOST_AUTO_TEST_CASE(test_aggressive_nsec3_wildcard_synthesis) { std::unique_ptr sr; @@ -727,13 +961,13 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec3_wildcard_synthesis) addRecordToLW(res, DNSName("powerdns.com."), QType::SOA, "powerdns.com. powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600); addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); /* first the closest encloser */ - addNSEC3UnhashedRecordToLW(DNSName("powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::A, QType::TXT, QType::RRSIG}, 600, res->d_records); + addNSEC3UnhashedRecordToLW(DNSName("powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::A, QType::TXT, QType::RRSIG}, 600, res->d_records, 10); addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); /* then the next closer */ - addNSEC3UnhashedRecordToLW(DNSName("+.powerdns.com."), DNSName("powerdns.com."), "v", {QType::RRSIG}, 600, res->d_records); + addNSEC3UnhashedRecordToLW(DNSName("+.powerdns.com."), DNSName("powerdns.com."), "v", {QType::RRSIG}, 600, res->d_records, 10); addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); /* a wildcard applies but does not have this type */ - addNSEC3UnhashedRecordToLW(DNSName("*.powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::A, QType::RRSIG}, 600, res->d_records); + addNSEC3UnhashedRecordToLW(DNSName("*.powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::A, QType::RRSIG}, 600, res->d_records, 10); addRRSIG(keys, res->d_records, DNSName("powerdns.com"), 300, false, boost::none, DNSName("*.powerdns.com")); return LWResult::Result::Success; } @@ -765,7 +999,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec3_wildcard_synthesis) addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300, false, boost::none, DNSName("*.powerdns.com")); /* no need for the closest encloser since we have a positive answer expanded from a wildcard */ /* the next closer */ - addNSEC3UnhashedRecordToLW(DNSName("+.powerdns.com."), DNSName("powerdns.com."), "v", {QType::RRSIG}, 600, res->d_records); + addNSEC3UnhashedRecordToLW(DNSName("+.powerdns.com."), DNSName("powerdns.com."), "v", {QType::RRSIG}, 600, res->d_records, 10); addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); /* and of course we don't deny the wildcard itself */ return LWResult::Result::Success; @@ -776,13 +1010,13 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec3_wildcard_synthesis) addRecordToLW(res, DNSName("powerdns.com."), QType::SOA, "powerdns.com. powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY); addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); /* the closest encloser */ - addNSEC3UnhashedRecordToLW(DNSName("powerdns.com."), DNSName("powerdns.com."), "v", {QType::SOA, QType::NS, QType::NSEC3, QType::DNSKEY, QType::RRSIG}, 600, res->d_records); + addNSEC3UnhashedRecordToLW(DNSName("powerdns.com."), DNSName("powerdns.com."), "v", {QType::SOA, QType::NS, QType::NSEC3, QType::DNSKEY, QType::RRSIG}, 600, res->d_records, 10); addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); /* the next closer */ - addNSEC3UnhashedRecordToLW(DNSName("+.powerdns.com."), DNSName("powerdns.com."), "v", {QType::RRSIG}, 600, res->d_records); + addNSEC3UnhashedRecordToLW(DNSName("+.powerdns.com."), DNSName("powerdns.com."), "v", {QType::RRSIG}, 600, res->d_records, 10); addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); /* and the wildcard expanded unto itself */ - addNSEC3UnhashedRecordToLW(DNSName("*.powerdns.com."), DNSName("powerdns.com."), "v", {QType::A}, 600, res->d_records); + addNSEC3UnhashedRecordToLW(DNSName("*.powerdns.com."), DNSName("powerdns.com."), "v", {QType::A}, 600, res->d_records, 10); addRRSIG(keys, res->d_records, DNSName("powerdns.com."), 300); return LWResult::Result::Success; } diff --git a/pdns/recursordist/test-syncres_cc8.cc b/pdns/recursordist/test-syncres_cc8.cc index 747f787f19..509e4789e5 100644 --- a/pdns/recursordist/test-syncres_cc8.cc +++ b/pdns/recursordist/test-syncres_cc8.cc @@ -397,7 +397,7 @@ BOOST_AUTO_TEST_CASE(test_nsec3_nxdomain_denial_missing_wildcard) sortedRecords_t recordContents; vector> signatureContents; - addNSEC3NarrowRecordToLW(DNSName("a.powerdns.com."), DNSName("powerdns.com."), {QType::A, QType::TXT, QType::RRSIG, QType::NSEC}, 600, records); + addNSEC3NarrowRecordToLW(DNSName("a.powerdns.com."), DNSName("powerdns.com."), {QType::A, QType::TXT, QType::RRSIG, QType::NSEC}, 600, records, 10); recordContents.insert(records.at(0).d_content); addRRSIG(keys, records, DNSName("powerdns.com."), 300); signatureContents.push_back(getRR(records.at(1))); @@ -412,7 +412,7 @@ 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); + addNSEC3UnhashedRecordToLW(DNSName("powerdns.com."), DNSName("powerdns.com."), "whatever", {QType::A, QType::TXT, QType::RRSIG, QType::NSEC}, 600, records, 10); recordContents.insert(records.at(0).d_content); addRRSIG(keys, records, DNSName("powerdns.com."), 300); signatureContents.push_back(getRR(records.at(1)));