}
if (domain.countLabels() == 1 && type == QType::DS) { // powerdns|DS or example|DS
setLWResult(res, 0, true, false, true);
- addDS(domain, 300, res->d_records, keys);
+ addDS(domain, 300, res->d_records, keys, DNSResourceRecord::ANSWER);
addRRSIG(keys, res->d_records, DNSName("."), 300);
return 1;
}
return 1;
}
if (domain == target && type == QType::DS) { // dname.powerdns|DS
- return genericDSAndDNSKEYHandler(res, domain, dnameOwner, type, keys);
+ return genericDSAndDNSKEYHandler(res, domain, domain, type, keys, false);
}
if (domain == target) {
setLWResult(res, 0, true, false, false);
addRRSIG(keys, res->d_records, domain, 300);
return 1;
}
- if (domain == target && type == QType::DS) { // dname.example|DS
- return genericDSAndDNSKEYHandler(res, domain, dnameTarget, type, keys);
+ if (domain == cnameTarget && type == QType::DS) { // dname.example|DS
+ return genericDSAndDNSKEYHandler(res, domain, domain, type, keys, false);
}
if (domain == cnameTarget) {
setLWResult(res, 0, true, false, false);
}
if (domain == dnameOwner && type == QType::DS) { // powerdns|DS
setLWResult(res, 0, true, false, true);
- addDS(domain, 300, res->d_records, keys);
+ addDS(domain, 300, res->d_records, keys, DNSResourceRecord::ANSWER);
addRRSIG(keys, res->d_records, DNSName("."), 300);
return 1;
}
return 1;
}
if (domain == target && type == QType::DS) { // dname.powerdns|DS
- return genericDSAndDNSKEYHandler(res, domain, dnameOwner, type, keys);
+ return genericDSAndDNSKEYHandler(res, domain, dnameOwner, type, keys, false);
}
if (domain == target) {
setLWResult(res, 0, true, false, false);
}
} else if (ip == ComboAddress("192.0.2.2:53")) {
if (domain == target && type == QType::DS) { // dname.example|DS
- return genericDSAndDNSKEYHandler(res, domain, dnameTarget, type, keys);
+ return genericDSAndDNSKEYHandler(res, domain, dnameTarget, type, keys, false);
}
if (domain == cnameTarget) {
setLWResult(res, 0, true, false, false);
BOOST_CHECK_EQUAL(res, RCode::NoError);
BOOST_CHECK_EQUAL(sr->getValidationState(), Bogus);
BOOST_REQUIRE_EQUAL(ret.size(), 2);
- BOOST_CHECK_EQUAL(queriesCount, 4);
+ BOOST_CHECK_EQUAL(queriesCount, 3);
/* again, to test the cache */
ret.clear();
BOOST_CHECK_EQUAL(res, RCode::NoError);
BOOST_CHECK_EQUAL(sr->getValidationState(), Bogus);
BOOST_REQUIRE_EQUAL(ret.size(), 2);
- BOOST_CHECK_EQUAL(queriesCount, 4);
+ BOOST_CHECK_EQUAL(queriesCount, 3);
/* now we ask directly for the DS */
ret.clear();
BOOST_CHECK_EQUAL(res, RCode::NoError);
BOOST_CHECK_EQUAL(sr->getValidationState(), Bogus);
BOOST_REQUIRE_EQUAL(ret.size(), 1);
- BOOST_CHECK_EQUAL(queriesCount, 4);
+ BOOST_CHECK_EQUAL(queriesCount, 3);
}
BOOST_AUTO_TEST_CASE(test_dnssec_bogus_unsigned_ds_direct) {
auth.chopOff();
dsQueriesCount++;
+ if (domain == target) {
+ if (genericDSAndDNSKEYHandler(res, domain, auth, type, keys, false) == 0) {
+ return 0;
+ }
+ return 1;
+ }
+
setLWResult(res, 0, true, false, true);
addDS(domain, 300, res->d_records, keys, DNSResourceRecord::ANSWER);
addRRSIG(keys, res->d_records, auth, 300);
setLWResult(res, 0, true, false, true);
if (domain == target) {
- addRecordToLW(res, domain, QType::SOA, "ns1.powerdns.com. blah. 2017032800 1800 900 604800 86400", DNSResourceRecord::AUTHORITY, 86400);
- addRRSIG(keys, res->d_records, target, 300);
+ addDS(domain, 300, res->d_records, keys, DNSResourceRecord::ANSWER);
+ addRRSIG(keys, res->d_records, domain, 300);
}
else {
addDS(domain, 300, res->d_records, keys, DNSResourceRecord::ANSWER);
BOOST_CHECK_EQUAL(res, RCode::NoError);
BOOST_CHECK_EQUAL(sr->getValidationState(), Bogus);
BOOST_REQUIRE_EQUAL(ret.size(), 2);
- BOOST_CHECK_EQUAL(queriesCount, 9);
+ BOOST_CHECK_EQUAL(queriesCount, 8);
/* again, to test the cache */
ret.clear();
BOOST_CHECK_EQUAL(res, RCode::NoError);
BOOST_CHECK_EQUAL(sr->getValidationState(), Bogus);
BOOST_REQUIRE_EQUAL(ret.size(), 2);
- BOOST_CHECK_EQUAL(queriesCount, 9);
+ BOOST_CHECK_EQUAL(queriesCount, 8);
}
BOOST_AUTO_TEST_CASE(test_dnssec_dnskey_signed_child) {
auth.chopOff();
setLWResult(res, 0, true, false, true);
- if (domain == target) {
- addRecordToLW(res, domain, QType::SOA, "ns1.powerdns.com. blah. 2017032800 1800 900 604800 86400", DNSResourceRecord::AUTHORITY, 86400);
- addRRSIG(keys, res->d_records, target, 300);
- }
- else {
- addDS(domain, 300, res->d_records, keys, DNSResourceRecord::ANSWER);
- addRRSIG(keys, res->d_records, auth, 300);
- }
+ addDS(domain, 300, res->d_records, keys, DNSResourceRecord::ANSWER);
+ addRRSIG(keys, res->d_records, auth, 300);
return 1;
}
else if (type == QType::DNSKEY) {
BOOST_CHECK_EQUAL(res, RCode::NoError);
BOOST_CHECK_EQUAL(sr->getValidationState(), Bogus);
BOOST_REQUIRE_EQUAL(ret.size(), 2);
- BOOST_CHECK_EQUAL(queriesCount, 9);
+ BOOST_CHECK_EQUAL(queriesCount, 10);
/* again, to test the cache */
ret.clear();
BOOST_CHECK_EQUAL(res, RCode::NoError);
BOOST_CHECK_EQUAL(sr->getValidationState(), Bogus);
BOOST_REQUIRE_EQUAL(ret.size(), 2);
- BOOST_CHECK_EQUAL(queriesCount, 9);
+ BOOST_CHECK_EQUAL(queriesCount, 10);
}
BOOST_AUTO_TEST_CASE(test_dnssec_no_ds_on_referral_insecure) {
if (domain == DNSName("com.")) {
addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
+ addRRSIG(keys, res->d_records, DNSName("."), 300);
/* no DS */
addNSECRecordToLW(DNSName("com."), DNSName("dom."), { QType::NS }, 600, res->d_records);
addRRSIG(keys, res->d_records, DNSName("."), 300);
BOOST_CHECK_EQUAL(sr->getValidationState(), Secure);
BOOST_REQUIRE_EQUAL(ret.size(), 2);
BOOST_CHECK(ret[0].d_type == QType::A);
- BOOST_CHECK_EQUAL(queriesCount, 8);
+ BOOST_CHECK_EQUAL(queriesCount, 7);
/* again, to test the cache */
ret.clear();
BOOST_CHECK_EQUAL(sr->getValidationState(), Secure);
BOOST_REQUIRE_EQUAL(ret.size(), 2);
BOOST_CHECK(ret[0].d_type == QType::A);
- BOOST_CHECK_EQUAL(queriesCount, 8);
+ BOOST_CHECK_EQUAL(queriesCount, 7);
}
BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_nodata) {
d_skipCNAMECheck = oldSkipCNAME;
if (rcode == RCode::NoError || (rcode == RCode::NXDomain && !bogusOnNXD)) {
-
uint8_t bestDigestType = 0;
- if (state == Secure) {
- bool gotCNAME = false;
- for (const auto& record : dsrecords) {
- if (record.d_type == QType::DS) {
- const auto dscontent = getRR<DSRecordContent>(record);
- if (dscontent && isSupportedDS(*dscontent)) {
- // Make GOST a lower prio than SHA256
- if (dscontent->d_digesttype == DNSSECKeeper::GOST && bestDigestType == DNSSECKeeper::SHA256) {
- continue;
- }
- if (dscontent->d_digesttype > bestDigestType || (bestDigestType == DNSSECKeeper::GOST && dscontent->d_digesttype == DNSSECKeeper::SHA256)) {
- bestDigestType = dscontent->d_digesttype;
- }
- ds.insert(*dscontent);
+ bool gotCNAME = false;
+ for (const auto& record : dsrecords) {
+ if (record.d_type == QType::DS) {
+ const auto dscontent = getRR<DSRecordContent>(record);
+ if (dscontent && isSupportedDS(*dscontent)) {
+ // Make GOST a lower prio than SHA256
+ if (dscontent->d_digesttype == DNSSECKeeper::GOST && bestDigestType == DNSSECKeeper::SHA256) {
+ continue;
}
+ if (dscontent->d_digesttype > bestDigestType || (bestDigestType == DNSSECKeeper::GOST && dscontent->d_digesttype == DNSSECKeeper::SHA256)) {
+ bestDigestType = dscontent->d_digesttype;
+ }
+ ds.insert(*dscontent);
}
- else if (record.d_type == QType::CNAME && record.d_name == zone) {
- gotCNAME = true;
- }
}
+ else if (record.d_type == QType::CNAME && record.d_name == zone) {
+ gotCNAME = true;
+ }
+ }
- /* RFC 4509 section 3: "Validator implementations SHOULD ignore DS RRs containing SHA-1
- * digests if DS RRs with SHA-256 digests are present in the DS RRset."
- * As SHA348 is specified as well, the spirit of the this line is "use the best algorithm".
- */
- for (auto dsrec = ds.begin(); dsrec != ds.end(); ) {
- if (dsrec->d_digesttype != bestDigestType) {
- dsrec = ds.erase(dsrec);
- }
- else {
- ++dsrec;
- }
+ /* RFC 4509 section 3: "Validator implementations SHOULD ignore DS RRs containing SHA-1
+ * digests if DS RRs with SHA-256 digests are present in the DS RRset."
+ * As SHA348 is specified as well, the spirit of the this line is "use the best algorithm".
+ */
+ for (auto dsrec = ds.begin(); dsrec != ds.end(); ) {
+ if (dsrec->d_digesttype != bestDigestType) {
+ dsrec = ds.erase(dsrec);
+ }
+ else {
+ ++dsrec;
}
+ }
- if (rcode == RCode::NoError && ds.empty()) {
- if (foundCut) {
- if (gotCNAME || denialProvesNoDelegation(zone, dsrecords)) {
- /* we are still inside the same Secure zone */
+ if (rcode == RCode::NoError) {
+ if (ds.empty()) {
+ if (gotCNAME || denialProvesNoDelegation(zone, dsrecords)) {
+ /* we are still inside the same zone */
+ if (foundCut) {
*foundCut = false;
- return Secure;
}
+ return state;
+ }
+ /* delegation with no DS, might be Secure -> Insecure */
+ if (foundCut) {
*foundCut = true;
}
- return Insecure;
- } else if (foundCut && rcode == RCode::NoError && !ds.empty()) {
- *foundCut = true;
+ return state == Secure ? Insecure : state;
+ } else {
+ /* we have a DS */
+ if (foundCut) {
+ *foundCut = true;
+ }
}
}
if (!signer.empty() && name.isPartOf(signer)) {
if ((qtype == QType::DNSKEY || qtype == QType::DS) && signer == qname) {
/* we are already retrieving those keys, sorry */
+ if (qtype == QType::DS) {
+ /* something is very wrong */
+ LOG(d_prefix<<"The DS for "<<qname<<" is signed by itself, going Bogus"<<endl);
+ return Bogus;
+ }
return Indeterminate;
}
vState state = getDNSKeys(signer, keys, depth);