auto dcke = DNSCryptoKeyEngine::make(DNSSECKeeper::ECDSA256);
dcke->create(dcke->getBits());
- // cerr<<dcke->convertToISC()<<endl;
DNSSECPrivateKey dpk;
dpk.setKey(std::move(dcke), 256);
BOOST_CHECK_EQUAL(queriesCount, 4U);
}
+BOOST_AUTO_TEST_CASE(test_dnssec_bogus_too_many_dss)
+{
+ std::unique_ptr<SyncRes> sr;
+ initSR(sr, true);
+
+ setDNSSECValidation(sr, DNSSECMode::Process);
+
+ primeHints();
+ const DNSName target(".");
+ testkeysset_t keys;
+
+ g_maxDSsToConsider = 1;
+
+ auto luaconfsCopy = g_luaconfs.getCopy();
+ luaconfsCopy.dsAnchors.clear();
+ /* generate more DSs for the zone than we are willing to consider: only the last one will be used to generate DNSKEY records */
+ for (size_t idx = 0; idx < (g_maxDSsToConsider + 10U); idx++) {
+ generateKeyMaterial(g_rootdnsname, DNSSECKeeper::RSASHA512, DNSSECKeeper::DIGEST_SHA384, keys, luaconfsCopy.dsAnchors);
+ }
+ 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<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
+ queriesCount++;
+
+ if (domain == target && type == QType::NS) {
+
+ setLWResult(res, 0, true, false, true);
+ char addr[] = "a.root-servers.net.";
+ for (char idx = 'a'; idx <= 'm'; idx++) {
+ addr[0] = idx;
+ addRecordToLW(res, domain, QType::NS, std::string(addr), DNSResourceRecord::ANSWER, 3600);
+ }
+
+ addRRSIG(keys, res->d_records, domain, 300);
+
+ addRecordToLW(res, "a.root-servers.net.", QType::A, "198.41.0.4", DNSResourceRecord::ADDITIONAL, 3600);
+ addRecordToLW(res, "a.root-servers.net.", QType::AAAA, "2001:503:ba3e::2:30", DNSResourceRecord::ADDITIONAL, 3600);
+
+ return LWResult::Result::Success;
+ }
+ else if (domain == target && type == QType::DNSKEY) {
+
+ setLWResult(res, 0, true, false, true);
+
+ addDNSKEY(keys, domain, 300, res->d_records);
+ addRRSIG(keys, res->d_records, domain, 300);
+
+ return LWResult::Result::Success;
+ }
+
+ return LWResult::Result::Timeout;
+ });
+
+ /* === with validation enabled === */
+ sr->setDNSSECValidationRequested(true);
+ vector<DNSRecord> ret;
+ int res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
+ BOOST_CHECK_EQUAL(res, RCode::NoError);
+ BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoValidDNSKEY);
+ /* 13 NS + 1 RRSIG */
+ BOOST_REQUIRE_EQUAL(ret.size(), 14U);
+ BOOST_CHECK_EQUAL(queriesCount, 2U);
+
+ /* again, to test the cache */
+ ret.clear();
+ res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
+ BOOST_CHECK_EQUAL(res, RCode::NoError);
+ BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoValidDNSKEY);
+ BOOST_REQUIRE_EQUAL(ret.size(), 14U);
+ BOOST_CHECK_EQUAL(queriesCount, 2U);
+
+ g_maxDNSKEYsToConsider = 0;
+}
+
BOOST_AUTO_TEST_CASE(test_dnssec_bogus_too_many_dnskeys)
{
std::unique_ptr<SyncRes> sr;
vector<DNSRecord> ret;
int res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
BOOST_CHECK_EQUAL(res, RCode::NoError);
- BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
+ BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoValidDNSKEY);
/* 13 NS + 1 RRSIG */
BOOST_REQUIRE_EQUAL(ret.size(), 14U);
BOOST_CHECK_EQUAL(queriesCount, 2U);
ret.clear();
res = sr->beginResolve(target, QType(QType::NS), QClass::IN, ret);
BOOST_CHECK_EQUAL(res, RCode::NoError);
- BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Insecure);
+ BOOST_CHECK_EQUAL(sr->getValidationState(), vState::BogusNoValidDNSKEY);
BOOST_REQUIRE_EQUAL(ret.size(), 14U);
BOOST_CHECK_EQUAL(queriesCount, 2U);
uint16_t g_maxRRSIGsPerRecordToConsider{0};
uint16_t g_maxNSEC3sPerRecordToConsider{0};
uint16_t g_maxDNSKEYsToConsider{0};
+uint16_t g_maxDSsToConsider{0};
static bool isAZoneKey(const DNSKEYRecordContent& key)
{
* Check all DNSKEY records against all DS records and place all DNSKEY records
* that have DS records (that we support the algo for) in the tentative key storage
*/
+ uint16_t dssConsidered = 0;
for (const auto& dsrc : dsmap) {
+ if (g_maxDSsToConsider > 0 && dssConsidered > g_maxDSsToConsider) {
+ VLOG(log, zone << ": We have already considered "<<std::to_string(dssConsidered)<<" DS"<<addS(dssConsidered)<<", not considering the remaining ones"<<endl;);
+ return vState::BogusNoValidDNSKEY;
+ }
+ ++dssConsidered;
+
+ uint16_t dnskeysConsidered = 0;
auto record = getByTag(tkeys, dsrc.d_tag, dsrc.d_algorithm, log);
// cerr<<"looking at DS with tag "<<dsrc.d_tag<<", algo "<<DNSSECKeeper::algorithm2name(dsrc.d_algorithm)<<", digest "<<std::to_string(dsrc.d_digesttype)<<" for "<<zone<<", got "<<r.size()<<" DNSKEYs for tag"<<endl;
bool isValid = false;
bool dsCreated = false;
DSRecordContent dsrc2;
+
+ if (g_maxDNSKEYsToConsider > 0 && dnskeysConsidered >= g_maxDNSKEYsToConsider) {
+ VLOG(log, zone << ": We have already considered "<<std::to_string(dnskeysConsidered)<<" DNSKEY"<<addS(dnskeysConsidered)<<" for tag "<<std::to_string(dsrc.d_tag)<<" and algorithm "<<std::to_string(dsrc.d_algorithm)<<", not considering the remaining ones for this DS"<<endl;);
+ return vState::BogusNoValidDNSKEY;
+ }
+ dnskeysConsidered++;
+
try {
dsrc2 = makeDSFromDNSKey(zone, *drc, dsrc.d_digesttype);
dsCreated = true;
if (g_maxRRSIGsPerRecordToConsider > 0 && signaturesConsidered >= g_maxRRSIGsPerRecordToConsider) {
VLOG(log, zone << ": We have already considered "<<std::to_string(signaturesConsidered)<<" RRSIG"<<addS(signaturesConsidered)<<" for this record, stopping now"<<endl;);
// possibly going Bogus, the RRSIGs have not been validated so Insecure would be wrong
- break;
+ return vState::BogusNoValidDNSKEY;
}
string msg = getMessageForRRSET(zone, *sig, toSign);
for (const auto& key : bytag) {
if (g_maxDNSKEYsToConsider > 0 && dnskeysConsidered >= g_maxDNSKEYsToConsider) {
VLOG(log, zone << ": We have already considered "<<std::to_string(dnskeysConsidered)<<" DNSKEY"<<addS(dnskeysConsidered)<<" for tag "<<std::to_string(sig->d_tag)<<" and algorithm "<<std::to_string(sig->d_algorithm)<<", not considering the remaining ones for this signature"<<endl;);
- return vState::Insecure;
+ return vState::BogusNoValidDNSKEY;
}
dnskeysConsidered++;
if (g_maxRRSIGsPerRecordToConsider > 0 && signaturesConsidered >= g_maxRRSIGsPerRecordToConsider) {
VLOG(log, zone << ": We have already considered "<<std::to_string(signaturesConsidered)<<" RRSIG"<<addS(signaturesConsidered)<<" for this record, stopping now"<<endl;);
// possibly going Bogus, the RRSIGs have not been validated so Insecure would be wrong
- break;
+ return vState::BogusNoValidDNSKEY;
}
// cerr<<"validating : ";
bool signIsValid = checkSignatureWithKey(zone, *sig, *key, msg, ede, log);