namespace pdns
{
- class SHADigest
+class SHADigest
+{
+public:
+ SHADigest(int bits)
{
- public:
- SHADigest(int bits)
- {
- mdctx = EVP_MD_CTX_new();
- if (mdctx == nullptr) {
- throw std::runtime_error("VSHADigest: P_MD_CTX_new failed");
- }
- switch (bits) {
- case 256:
- md = EVP_sha256();
- break;
- case 384:
- md = EVP_sha384();
- break;
- case 512:
- md = EVP_sha512();
- break;
- default:
- throw std::runtime_error("SHADigest: unsupported size");
- }
- if (EVP_DigestInit_ex(mdctx, md, NULL) == 0) {
- throw std::runtime_error("SHADigest: init error");
- }
+ mdctx = EVP_MD_CTX_new();
+ if (mdctx == nullptr) {
+ throw std::runtime_error("VSHADigest: P_MD_CTX_new failed");
+ }
+ switch (bits) {
+ case 256:
+ md = EVP_sha256();
+ break;
+ case 384:
+ md = EVP_sha384();
+ break;
+ case 512:
+ md = EVP_sha512();
+ break;
+ default:
+ throw std::runtime_error("SHADigest: unsupported size");
}
+ if (EVP_DigestInit_ex(mdctx, md, NULL) == 0) {
+ throw std::runtime_error("SHADigest: init error");
+ }
+ }
- ~SHADigest()
- {
- // No free of md needed afaik
- if (mdctx != nullptr) {
- EVP_MD_CTX_free(mdctx);
- }
+ ~SHADigest()
+ {
+ // No free of md needed afaik
+ if (mdctx != nullptr) {
+ EVP_MD_CTX_free(mdctx);
}
+ }
- void process(const std::string& msg, size_t sz)
- {
- if (EVP_DigestUpdate(mdctx, msg.data(), msg.size()) == 0) {
- throw std::runtime_error("SHADigest: update error");
- }
+ void process(const std::string& msg, size_t sz)
+ {
+ if (EVP_DigestUpdate(mdctx, msg.data(), msg.size()) == 0) {
+ throw std::runtime_error("SHADigest: update error");
}
+ }
- std::string digest()
- {
- std::string md_value;
- md_value.resize(EVP_MD_size(md));
- unsigned int md_len;
- if (EVP_DigestFinal_ex(mdctx, reinterpret_cast<unsigned char*>(md_value.data()), &md_len) == 0) {
- throw std::runtime_error("SHADigest: finalize error");
- }
- if (md_len != md_value.size()) {
- throw std::runtime_error("SHADigest: inconsisten size");
- }
- return md_value;
+ std::string digest()
+ {
+ std::string md_value;
+ md_value.resize(EVP_MD_size(md));
+ unsigned int md_len;
+ if (EVP_DigestFinal_ex(mdctx, reinterpret_cast<unsigned char*>(md_value.data()), &md_len) == 0) {
+ throw std::runtime_error("SHADigest: finalize error");
}
- private:
- EVP_MD_CTX *mdctx{nullptr};
- const EVP_MD *md;
- };
+ if (md_len != md_value.size()) {
+ throw std::runtime_error("SHADigest: inconsisten size");
+ }
+ return md_value;
+ }
+
+private:
+ EVP_MD_CTX* mdctx{nullptr};
+ const EVP_MD* md;
+};
}
BOOST_AUTO_TEST_SUITE(test_zonemd_cc)
-static void testZoneMD(const std::string& zone, const std::string& file, bool ex, bool done, bool ok) {
+static void testZoneMD(const std::string& zone, const std::string& file, bool ex, bool done, bool ok)
+{
const char* p = std::getenv("SRCDIR");
if (!p) {
p = ".";
BOOST_CHECK(validationOK == ok);
}
-
-BOOST_AUTO_TEST_CASE(test_zonemd1) {
+BOOST_AUTO_TEST_CASE(test_zonemd1)
+{
testZoneMD("example", "zonemd1.zone", false, true, true);
}
-BOOST_AUTO_TEST_CASE(test_zonemd2) {
+BOOST_AUTO_TEST_CASE(test_zonemd2)
+{
testZoneMD("example", "zonemd2.zone", false, true, true);
}
-BOOST_AUTO_TEST_CASE(test_zonemd3) {
+BOOST_AUTO_TEST_CASE(test_zonemd3)
+{
testZoneMD("example", "zonemd3.zone", false, true, true);
}
-BOOST_AUTO_TEST_CASE(test_zonemd4) {
+BOOST_AUTO_TEST_CASE(test_zonemd4)
+{
testZoneMD("uri.arpa", "zonemd4.zone", false, true, true);
}
-BOOST_AUTO_TEST_CASE(test_zonemd5) {
+BOOST_AUTO_TEST_CASE(test_zonemd5)
+{
testZoneMD("root-servers.net", "zonemd5.zone", false, true, true);
}
-BOOST_AUTO_TEST_CASE(test_zonemd6) {
+BOOST_AUTO_TEST_CASE(test_zonemd6)
+{
testZoneMD("example", "zonemd-invalid.zone", false, true, false);
}
-BOOST_AUTO_TEST_CASE(test_zonemd7) {
+BOOST_AUTO_TEST_CASE(test_zonemd7)
+{
testZoneMD("example", "zonemd-nozonemd.zone", false, false, false);
}
-BOOST_AUTO_TEST_CASE(test_zonemd8) {
+BOOST_AUTO_TEST_CASE(test_zonemd8)
+{
testZoneMD("example", "zonemd-allunsup.zone", false, false, false);
}
-BOOST_AUTO_TEST_CASE(test_zonemd9) {
+BOOST_AUTO_TEST_CASE(test_zonemd9)
+{
testZoneMD("example", "zonemd-sha512.zone", false, true, true);
}
-BOOST_AUTO_TEST_CASE(test_zonemd10) {
+BOOST_AUTO_TEST_CASE(test_zonemd10)
+{
testZoneMD("example", "zonemd-serialmismatch.zone", false, false, false);
}
-BOOST_AUTO_TEST_CASE(test_zonemd11) {
+BOOST_AUTO_TEST_CASE(test_zonemd11)
+{
testZoneMD("example", "zonemd-duplicate.zone", false, false, false);
}
-BOOST_AUTO_TEST_CASE(test_zonemd12) {
+BOOST_AUTO_TEST_CASE(test_zonemd12)
+{
testZoneMD("root-servers.net", "zonemd-syntax.zone", true, false, false);
}
-BOOST_AUTO_TEST_CASE(test_zonemd13) {
+BOOST_AUTO_TEST_CASE(test_zonemd13)
+{
testZoneMD("xxx", "zonemd1.zone", false, false, false);
}
typedef std::pair<DNSName, QType> rrSetKey_t;
typedef std::vector<std::shared_ptr<DNSRecordContent>> rrVector_t;
-struct CanonrrSetKeyCompare: public std::binary_function<rrSetKey_t, rrSetKey_t, bool>
+struct CanonrrSetKeyCompare : public std::binary_function<rrSetKey_t, rrSetKey_t, bool>
{
- bool operator()(const rrSetKey_t&a, const rrSetKey_t& b) const
+ bool operator()(const rrSetKey_t& a, const rrSetKey_t& b) const
{
// FIXME surely we can be smarter here
- if(a.first.canonCompare(b.first)) {
+ if (a.first.canonCompare(b.first)) {
return true;
}
if (b.first.canonCompare(a.first)) {
typedef std::map<rrSetKey_t, rrVector_t, CanonrrSetKeyCompare> RRsetMap_t;
-void pdns::zonemdVerify(const DNSName& zone, ZoneParserTNG &zpt, bool& validationDone, bool& validationOK)
+void pdns::zonemdVerify(const DNSName& zone, ZoneParserTNG& zpt, bool& validationDone, bool& validationOK)
{
validationDone = false;
validationOK = false;
drc = DNSRecordContent::mastermake(dnsrr.qtype, QClass::IN, dnsrr.content);
}
catch (const PDNSException& pe) {
- std::string err = "Bad record content in record for '" + dnsrr.qname.toStringNoDot() + "'|" + dnsrr.qtype.toString() + ": "+ pe.reason;
+ std::string err = "Bad record content in record for '" + dnsrr.qname.toStringNoDot() + "'|" + dnsrr.qtype.toString() + ": " + pe.reason;
throw PDNSException(err);
}
catch (const std::exception& e) {
// Determine which digests to compute based on accepted zonemd records present
unique_ptr<pdns::SHADigest> sha384digest{nullptr}, sha512digest{nullptr};
- for (auto it = zonemdRecords.begin(); it != zonemdRecords.end(); ) {
+ for (auto it = zonemdRecords.begin(); it != zonemdRecords.end();) {
// The SOA Serial field MUST exactly match the ZONEMD Serial
// field. If the fields do not match, digest verification MUST
// NOT be considered successful with this ZONEMD RR.
// considered successful with this ZONEMD RR.
const auto duplicate = it->second.duplicate;
const auto& r = it->second.record;
- if (!duplicate && r->d_serial == soarc->d_st.serial &&
- r->d_scheme == 1 &&
- (r->d_hashalgo == 1 || r->d_hashalgo == 2)) {
+ if (!duplicate && r->d_serial == soarc->d_st.serial && r->d_scheme == 1 && (r->d_hashalgo == 1 || r->d_hashalgo == 2)) {
// A supported ZONEMD record
if (r->d_hashalgo == 1) {
sha384digest = make_unique<pdns::SHADigest>(384);
sha512digest = make_unique<pdns::SHADigest>(512);
}
++it;
- } else {
+ }
+ else {
it = zonemdRecords.erase(it);
}
}
};
// Compute requested digests
- for (auto& rrset: RRsets) {
+ for (auto& rrset : RRsets) {
const auto& qname = rrset.first.first;
const auto& qtype = rrset.first.second;
if (qtype == QType::ZONEMD && qname == zone) {
}
sortedRecords_t sorted;
- for (auto& rr: rrset.second) {
+ for (auto& rr : rrset.second) {
if (qtype == QType::RRSIG) {
const auto rrsig = std::dynamic_pointer_cast<RRSIGRecordContent>(rr);
if (rrsig->d_type == QType::ZONEMD && qname == zone) {
rrc.d_type = qtype;
auto msg = getMessageForRRSET(qname, rrc, sorted, false, false);
hash(msg);
- } else {
+ }
+ else {
// RRSIG is special, since original TTL depends on qtype covered by RRSIG
// which can be different per record
for (const auto& rrsig : sorted) {
RRSIGRecordContent rrc;
rrc.d_originalttl = RRsetTTLs[pair(rrset.first.first, rrsigc->d_type)];
rrc.d_type = qtype;
- auto msg = getMessageForRRSET(qname, rrc, { rrsigc }, false, false);
+ auto msg = getMessageForRRSET(qname, rrc, {rrsigc}, false, false);
hash(msg);
}
}
namespace pdns
{
- void zonemdVerify(const DNSName& zone, ZoneParserTNG &zpt, bool& validationDone, bool& validationOK);
+void zonemdVerify(const DNSName& zone, ZoneParserTNG& zpt, bool& validationDone, bool& validationOK);
}