From: Remi Gacogne Date: Tue, 29 Nov 2022 10:43:36 +0000 (+0100) Subject: auth: Better interface for setKey() by requiring the flags X-Git-Tag: dnsdist-1.8.0-rc1~98^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a456662ffdd00b980426916bfdb92b9c71f7a5ab;p=thirdparty%2Fpdns.git auth: Better interface for setKey() by requiring the flags --- diff --git a/pdns/dbdnsseckeeper.cc b/pdns/dbdnsseckeeper.cc index 7228789df5..6d8cb13823 100644 --- a/pdns/dbdnsseckeeper.cc +++ b/pdns/dbdnsseckeeper.cc @@ -103,16 +103,15 @@ bool DNSSECKeeper::addKey(const DNSName& name, bool setSEPBit, int algorithm, in } } } - DNSSECPrivateKey dspk; shared_ptr dpk(DNSCryptoKeyEngine::make(algorithm)); try{ dpk->create(bits); } catch (const std::runtime_error& error){ throw runtime_error("The algorithm does not support the given bit size."); } - dspk.d_algorithm = algorithm; - dspk.d_flags = setSEPBit ? 257 : 256; - dspk.setKey(dpk); + DNSSECPrivateKey dspk; + dspk.setKey(dpk, setSEPBit ? 257 : 256); + dspk.setAlgorithm(algorithm); return addKey(name, dspk, id, active, published) && clearKeyCache(name); } @@ -145,7 +144,7 @@ void DNSSECKeeper::clearCaches(const DNSName& name) bool DNSSECKeeper::addKey(const DNSName& name, const DNSSECPrivateKey& dpk, int64_t& id, bool active, bool published) { DNSBackend::KeyData kd; - kd.flags = dpk.d_flags; // the dpk doesn't get stored, only they key part + kd.flags = dpk.getFlags(); // the dpk doesn't get stored, only they key part kd.active = active; kd.published = published; kd.content = dpk.getKey()->convertToISC(); @@ -168,12 +167,11 @@ DNSSECPrivateKey DNSSECKeeper::getKeyById(const DNSName& zname, unsigned int id) if(kd.id != id) continue; - DNSSECPrivateKey dpk; DNSKEYRecordContent dkrc; auto key = shared_ptr(DNSCryptoKeyEngine::makeFromISCString(dkrc, kd.content)); - dpk.d_flags = kd.flags; - dpk.d_algorithm = dkrc.d_algorithm; - dpk.setKey(key); + DNSSECPrivateKey dpk; + dpk.setKey(key, kd.flags); + dpk.setAlgorithm(dkrc.d_algorithm); return dpk; } @@ -565,10 +563,10 @@ DNSSECKeeper::keyset_t DNSSECKeeper::getKeys(const DNSName& zone, bool useCache) set algoSEP, algoNoSEP; vector algoHasSeparateKSK; for(const DNSBackend::KeyData &keydata : dbkeyset) { - DNSSECPrivateKey dpk; DNSKEYRecordContent dkrc; auto key = shared_ptr(DNSCryptoKeyEngine::makeFromISCString(dkrc, keydata.content)); - dpk.setKey(key); + DNSSECPrivateKey dpk; + dpk.setKey(key, dkrc.d_algorithm); if(keydata.active) { if(keydata.flags == 257) @@ -582,12 +580,11 @@ DNSSECKeeper::keyset_t DNSSECKeeper::getKeys(const DNSName& zone, bool useCache) for(DNSBackend::KeyData& kd : dbkeyset) { - DNSSECPrivateKey dpk; DNSKEYRecordContent dkrc; auto key = shared_ptr(DNSCryptoKeyEngine::makeFromISCString(dkrc, kd.content)); - dpk.d_flags = kd.flags; - dpk.d_algorithm = dkrc.d_algorithm; - dpk.setKey(key); + DNSSECPrivateKey dpk; + dpk.setKey(key, kd.flags); + dpk.setAlgorithm(dkrc.d_algorithm); KeyMetaData kmd; @@ -596,7 +593,7 @@ DNSSECKeeper::keyset_t DNSSECKeeper::getKeys(const DNSName& zone, bool useCache) kmd.hasSEPBit = (kd.flags == 257); kmd.id = kd.id; - if (find(algoHasSeparateKSK.begin(), algoHasSeparateKSK.end(), dpk.d_algorithm) == algoHasSeparateKSK.end()) + if (find(algoHasSeparateKSK.begin(), algoHasSeparateKSK.end(), dpk.getAlgorithm()) == algoHasSeparateKSK.end()) kmd.keyType = CSK; else if(kmd.hasSEPBit) kmd.keyType = KSK; diff --git a/pdns/dnssecinfra.hh b/pdns/dnssecinfra.hh index 94cf23f7bc..9f2888da6f 100644 --- a/pdns/dnssecinfra.hh +++ b/pdns/dnssecinfra.hh @@ -148,30 +148,48 @@ struct DNSSECPrivateKey return d_key; } - void setKey(std::shared_ptr& key) + // be aware that calling setKey() will also set the algorithm + void setKey(std::shared_ptr& key, uint16_t flags) { d_key = key; + d_flags = flags; d_algorithm = d_key->getAlgorithm(); computeDNSKEY(); } - void setKey(std::unique_ptr&& key) + // be aware that calling setKey() will also set the algorithm + void setKey(std::unique_ptr&& key, uint16_t flags) { d_key = std::move(key); + d_flags = flags; d_algorithm = d_key->getAlgorithm(); computeDNSKEY(); } const DNSKEYRecordContent& getDNSKEY() const; - uint16_t d_flags; - uint8_t d_algorithm; + uint16_t getFlags() const + { + return d_flags; + } + + uint8_t getAlgorithm() const + { + return d_algorithm; + } + + void setAlgorithm(uint8_t algo) + { + d_algorithm = algo; + } private: void computeDNSKEY(); DNSKEYRecordContent d_dnskey; std::shared_ptr d_key; + uint16_t d_flags; + uint8_t d_algorithm; }; diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index 1454e2a465..811526ea07 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -1013,7 +1013,7 @@ static void listKey(DomainInfo const &di, DNSSECKeeper& dk, bool printHeader = t cout<getBits()<= 16) ? 1 : 16 - algname.length(); cout< 4) { if (pdns_iequals(cmds.at(4), "ZSK")) { - dpk.d_flags = 256; + flags = 256; } else if (pdns_iequals(cmds.at(4), "KSK")) { - dpk.d_flags = 257; + flags = 257; } else { cerr << "Unknown key flag '" << cmds.at(4) << "'" << endl; @@ -3509,9 +3511,10 @@ try } } else { - dpk.d_flags = 257; // ksk + flags = 257; // ksk } - dpk.setKey(key); + dpk.setKey(key, flags); + dpk.setAlgorithm(algo); int64_t id; if (!dk.addKey(DNSName(zone), dpk, id)) { @@ -3536,23 +3539,18 @@ try } string zone = cmds.at(1); string fname = cmds.at(2); - DNSSECPrivateKey dpk; DNSKEYRecordContent drc; shared_ptr key(DNSCryptoKeyEngine::makeFromISCFile(drc, fname.c_str())); - dpk.d_algorithm = drc.d_algorithm; - - if(dpk.d_algorithm == DNSSECKeeper::RSASHA1NSEC3SHA1) - dpk.d_algorithm = DNSSECKeeper::RSASHA1; - dpk.d_flags = 257; + uint16_t flags = 257; bool active=true; bool published=true; for(unsigned int n = 3; n < cmds.size(); ++n) { if (pdns_iequals(cmds.at(n), "ZSK")) - dpk.d_flags = 256; + flags = 256; else if (pdns_iequals(cmds.at(n), "KSK")) - dpk.d_flags = 257; + flags = 257; else if (pdns_iequals(cmds.at(n), "active")) active = true; else if (pdns_iequals(cmds.at(n), "passive") || pdns_iequals(cmds.at(n), "inactive")) // passive eventually needs to be removed @@ -3566,7 +3564,14 @@ try return 1; } } - dpk.setKey(key); + + DNSSECPrivateKey dpk; + dpk.setKey(key, flags); + + if (dpk.getAlgorithm() == DNSSECKeeper::RSASHA1NSEC3SHA1) { + dpk.setAlgorithm(DNSSECKeeper::RSASHA1); + } + int64_t id; if (!dk.addKey(DNSName(zone), dpk, id, active, published)) { cerr<<"Adding key failed, perhaps DNSSEC not enabled in configuration?"< dpk(DNSCryptoKeyEngine::make(algorithm)); if(!bits) { if(algorithm <= 10) @@ -3645,12 +3649,12 @@ try } } dpk->create(bits); - dspk.d_algorithm = algorithm; - dspk.d_flags = keyOrZone ? 257 : 256; - dspk.setKey(dpk); + DNSSECPrivateKey dspk; + dspk.setKey(dpk, keyOrZone ? 257 : 256); + dspk.setAlgorithm(algorithm); // print key to stdout - cout << "Flags: " << dspk.d_flags << endl << + cout << "Flags: " << dspk.getFlags() << endl << dspk.getKey()->convertToISC() << endl; } else if (cmds.at(0) == "generate-tsig-key") { @@ -3921,15 +3925,14 @@ try "PubLabel: " << pub_label << std::endl; DNSKEYRecordContent drc; - DNSSECPrivateKey dpk; - dpk.d_flags = (keyOrZone ? 257 : 256); shared_ptr dke(DNSCryptoKeyEngine::makeFromISCString(drc, iscString.str())); if(!dke->checkKey()) { cerr << "Invalid DNS Private Key in engine " << module << " slot " << slot << std::endl; return 1; } - dpk.setKey(dke); + DNSSECPrivateKey dpk; + dpk.setKey(dke, keyOrZone ? 257 : 256); // make sure this key isn't being reused. B.getDomainKeys(zone, keys); diff --git a/pdns/recursordist/test-syncres_cc.cc b/pdns/recursordist/test-syncres_cc.cc index f470371095..e8b5a958cf 100644 --- a/pdns/recursordist/test-syncres_cc.cc +++ b/pdns/recursordist/test-syncres_cc.cc @@ -463,8 +463,7 @@ void generateKeyMaterial(const DNSName& name, unsigned int algo, uint8_t digest, auto dcke = std::shared_ptr(DNSCryptoKeyEngine::make(algo)); dcke->create((algo <= 10) ? 2048 : dcke->getBits()); DNSSECPrivateKey dpk; - dpk.d_flags = 256; - dpk.setKey(dcke); + dpk.setKey(dcke, 256); DSRecordContent ds = makeDSFromDNSKey(name, dpk.getDNSKEY(), digest); keys[name] = std::pair(dpk, ds); } diff --git a/pdns/recursordist/test-syncres_cc10.cc b/pdns/recursordist/test-syncres_cc10.cc index 8603b6ea66..8e6ef79863 100644 --- a/pdns/recursordist/test-syncres_cc10.cc +++ b/pdns/recursordist/test-syncres_cc10.cc @@ -928,16 +928,14 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_dnskey_loop) auto dcke = DNSCryptoKeyEngine::make(DNSSECKeeper::ECDSA256); dcke->create(dcke->getBits()); DNSSECPrivateKey key; - key.d_flags = 257; - key.setKey(std::move(dcke)); + key.setKey(std::move(dcke), 257); DSRecordContent drc = makeDSFromDNSKey(DNSName("powerdns.com."), key.getDNSKEY(), DNSSECKeeper::DIGEST_SHA256); testkeysset_t wrongKeys; auto wrongDcke = DNSCryptoKeyEngine::make(DNSSECKeeper::ECDSA256); wrongDcke->create(wrongDcke->getBits()); DNSSECPrivateKey wrongKey; - wrongKey.d_flags = 256; - wrongKey.setKey(std::move(wrongDcke)); + wrongKey.setKey(std::move(wrongDcke), 256); DSRecordContent uselessdrc = makeDSFromDNSKey(DNSName("powerdns.com."), wrongKey.getDNSKEY(), DNSSECKeeper::DIGEST_SHA256); wrongKeys[DNSName("powerdns.com.")] = std::pair(wrongKey, uselessdrc); diff --git a/pdns/recursordist/test-syncres_cc4.cc b/pdns/recursordist/test-syncres_cc4.cc index 47cc29dafc..24f6bd8e0f 100644 --- a/pdns/recursordist/test-syncres_cc4.cc +++ b/pdns/recursordist/test-syncres_cc4.cc @@ -441,8 +441,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_rrsig) dcke->create(dcke->getBits()); // cerr<convertToISC()<create(dckeZ->getBits()); DNSSECPrivateKey ksk; - ksk.d_flags = 257; - ksk.setKey(std::move(dckeZ)); + ksk.setKey(std::move(dckeZ), 257); DSRecordContent kskds = makeDSFromDNSKey(target, ksk.getDNSKEY(), DNSSECKeeper::DIGEST_SHA256); auto dckeK = DNSCryptoKeyEngine::make(DNSSECKeeper::ECDSA256); dckeK->create(dckeK->getBits()); DNSSECPrivateKey zsk; - zsk.d_flags = 256; - zsk.setKey(std::move(dckeK)); + zsk.setKey(std::move(dckeK), 256); DSRecordContent zskds = makeDSFromDNSKey(target, zsk.getDNSKEY(), DNSSECKeeper::DIGEST_SHA256); kskeys[target] = std::pair(ksk, kskds); @@ -699,8 +696,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_dnskey_without_zone_flag) auto dcke = DNSCryptoKeyEngine::make(DNSSECKeeper::ECDSA256); dcke->create(dcke->getBits()); DNSSECPrivateKey csk; - csk.d_flags = 0; - csk.setKey(std::move(dcke)); + csk.setKey(std::move(dcke), 0); DSRecordContent ds = makeDSFromDNSKey(target, csk.getDNSKEY(), DNSSECKeeper::DIGEST_SHA256); keys[target] = std::pair(csk, ds); @@ -776,8 +772,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_dnskey_revoked) auto dcke = DNSCryptoKeyEngine::make(DNSSECKeeper::ECDSA256); dcke->create(dcke->getBits()); DNSSECPrivateKey csk; - csk.d_flags = 257 | 128; - csk.setKey(std::move(dcke)); + csk.setKey(std::move(dcke), 257 | 128); DSRecordContent ds = makeDSFromDNSKey(target, csk.getDNSKEY(), DNSSECKeeper::DIGEST_SHA256); keys[target] = std::pair(csk, ds); @@ -853,15 +848,13 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_dnskey_doesnt_match_ds) auto dckeDS = DNSCryptoKeyEngine::make(DNSSECKeeper::ECDSA256); dckeDS->create(dckeDS->getBits()); DNSSECPrivateKey dskey; - dskey.d_flags = 257; - dskey.setKey(std::move(dckeDS)); + dskey.setKey(std::move(dckeDS), 257); DSRecordContent drc = makeDSFromDNSKey(target, dskey.getDNSKEY(), DNSSECKeeper::DIGEST_SHA256); auto dcke = DNSCryptoKeyEngine::make(DNSSECKeeper::ECDSA256); dcke->create(dcke->getBits()); DNSSECPrivateKey dpk; - dpk.d_flags = 256; - dpk.setKey(std::move(dcke)); + dpk.setKey(std::move(dcke), 256); DSRecordContent uselessdrc = makeDSFromDNSKey(target, dpk.getDNSKEY(), DNSSECKeeper::DIGEST_SHA256); dskeys[target] = std::pair(dskey, drc); @@ -979,8 +972,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_rrsig_signed_with_unknown_dnskey) auto dckeRRSIG = DNSCryptoKeyEngine::make(DNSSECKeeper::ECDSA256); dckeRRSIG->create(dckeRRSIG->getBits()); DNSSECPrivateKey rrsigkey; - rrsigkey.d_flags = 257; - rrsigkey.setKey(std::move(dckeRRSIG)); + rrsigkey.setKey(std::move(dckeRRSIG), 257); DSRecordContent rrsigds = makeDSFromDNSKey(target, rrsigkey.getDNSKEY(), DNSSECKeeper::DIGEST_SHA256); rrsigkeys[target] = std::pair(rrsigkey, rrsigds); @@ -1202,10 +1194,9 @@ BOOST_AUTO_TEST_CASE(test_dnssec_insecure_unknown_ds_algorithm) auto dcke = DNSCryptoKeyEngine::make(DNSSECKeeper::ECDSA256); dcke->create(dcke->getBits()); DNSSECPrivateKey dpk; - dpk.d_flags = 256; + dpk.setKey(std::move(dcke), 256); /* Fake algorithm number (private) */ - dpk.d_algorithm = 253; - dpk.setKey(std::move(dcke)); + dpk.setAlgorithm(253); DSRecordContent drc = makeDSFromDNSKey(target, dpk.getDNSKEY(), DNSSECKeeper::DIGEST_SHA256); keys[target] = std::pair(dpk, drc); @@ -1285,8 +1276,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_insecure_unknown_ds_digest) auto dcke = DNSCryptoKeyEngine::make(DNSSECKeeper::ECDSA256); dcke->create(dcke->getBits()); DNSSECPrivateKey dpk; - dpk.d_flags = 256; - dpk.setKey(std::move(dcke)); + dpk.setKey(std::move(dcke), 256); DSRecordContent drc = makeDSFromDNSKey(target, dpk.getDNSKEY(), DNSSECKeeper::DIGEST_SHA256); /* Fake digest number (reserved) */ drc.d_digesttype = 0; diff --git a/pdns/test-signers.cc b/pdns/test-signers.cc index a89e48b3ef..757d890218 100644 --- a/pdns/test-signers.cc +++ b/pdns/test-signers.cc @@ -305,12 +305,11 @@ static void checkRR(const SignerParams& signer) DNSKEYRecordContent drc; auto dcke = std::shared_ptr(DNSCryptoKeyEngine::makeFromISCString(drc, signer.iscMap)); DNSSECPrivateKey dpk; - dpk.d_flags = signer.rfcFlags; - dpk.setKey(dcke); + dpk.setKey(dcke, signer.rfcFlags); sortedRecords_t rrs; /* values taken from rfc8080 for ed25519 and ed448, rfc5933 for gost */ - DNSName qname(dpk.d_algorithm == DNSSECKeeper::ECCGOST ? "www.example.net." : "example.com."); + DNSName qname(dpk.getAlgorithm() == DNSSECKeeper::ECCGOST ? "www.example.net." : "example.com."); reportBasicTypes(); @@ -318,7 +317,7 @@ static void checkRR(const SignerParams& signer) uint32_t expire = 1440021600; uint32_t inception = 1438207200; - if (dpk.d_algorithm == DNSSECKeeper::ECCGOST) { + if (dpk.getAlgorithm() == DNSSECKeeper::ECCGOST) { rrc.d_signer = DNSName("example.net."); inception = 946684800; expire = 1893456000; @@ -335,7 +334,7 @@ static void checkRR(const SignerParams& signer) rrc.d_type = (*rrs.cbegin())->getType(); rrc.d_labels = qname.countLabels(); rrc.d_tag = dpk.getTag(); - rrc.d_algorithm = dpk.d_algorithm; + rrc.d_algorithm = dpk.getAlgorithm(); string msg = getMessageForRRSET(qname, rrc, rrs, false); @@ -375,8 +374,7 @@ static void test_generic_signer(std::shared_ptr dcke, DNSKEY BOOST_CHECK_EQUAL(drc.d_algorithm, signer.algorithm); DNSSECPrivateKey dpk; - dpk.d_flags = signer.flags; - dpk.setKey(dcke); + dpk.setKey(dcke, signer.flags); drc = dpk.getDNSKEY(); BOOST_CHECK_EQUAL(drc.d_algorithm, signer.algorithm); diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 8342d5af36..50d4b99951 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1130,9 +1130,9 @@ static void apiZoneCryptokeysGET(const DNSName& zonename, int inquireKeyId, Http { "active", value.second.active }, { "published", value.second.published }, { "keytype", keyType }, - { "flags", (uint16_t)value.first.d_flags }, + { "flags", (uint16_t)value.first.getFlags() }, { "dnskey", value.first.getDNSKEY().getZoneRepresentation() }, - { "algorithm", DNSSECKeeper::algorithm2name(value.first.d_algorithm) }, + { "algorithm", DNSSECKeeper::algorithm2name(value.first.getAlgorithm()) }, { "bits", value.first.getKey()->getBits() } }; @@ -1298,17 +1298,20 @@ static void apiZoneCryptokeysPOST(const DNSName& zonename, HttpRequest *req, Htt DNSSECPrivateKey dpk; try { shared_ptr dke(DNSCryptoKeyEngine::makeFromISCString(dkrc, keyData)); - dpk.d_algorithm = dkrc.d_algorithm; - // TODO remove in 4.2.0 - if(dpk.d_algorithm == DNSSECKeeper::RSASHA1NSEC3SHA1) - dpk.d_algorithm = DNSSECKeeper::RSASHA1; - - if (keyOrZone) - dpk.d_flags = 257; - else - dpk.d_flags = 256; + uint16_t flags = 0; + if (keyOrZone) { + flags = 257; + } + else { + flags = 256; + } - dpk.setKey(dke); + uint8_t algorithm = dkrc.d_algorithm; + dpk.setKey(dke, flags); + // TODO remove in 4.2.0 + if (algorithm == DNSSECKeeper::RSASHA1NSEC3SHA1) { + dpk.setAlgorithm(DNSSECKeeper::RSASHA1); + } } catch (std::runtime_error& error) { throw ApiException("Key could not be parsed. Make sure your key format is correct.");