From: Otto Moerbeek Date: Wed, 7 Jun 2023 08:19:13 +0000 (+0200) Subject: Impelement verification of algos 5 and 7 X-Git-Tag: rec-4.10.0-alpha0~2^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=81a9420715139879f925156e2c6ec0cd12a3bf84;p=thirdparty%2Fpdns.git Impelement verification of algos 5 and 7 --- diff --git a/pdns/dnssecinfra.cc b/pdns/dnssecinfra.cc index c2d76a35d0..ae2bcfebc6 100644 --- a/pdns/dnssecinfra.cc +++ b/pdns/dnssecinfra.cc @@ -291,6 +291,103 @@ bool DNSCryptoKeyEngine::testOne(int algo) return ret; } +static map ICSStringToMap(const string& argStr) +{ + unsigned int algorithm = 0; + string sline; + string key; + string value; + string raw; + std::istringstream str(argStr); + map stormap; + + while(std::getline(str, sline)) { + std::tie(key,value)=splitField(sline, ':'); + boost::trim(value); + if(pdns_iequals(key,"algorithm")) { + pdns::checked_stoi_into(algorithm, value); + stormap["algorithm"] = std::to_string(algorithm); + continue; + } + if (pdns_iequals(key,"pin")) { + stormap["pin"] = value; + continue; + } + if (pdns_iequals(key,"engine")) { + stormap["engine"] = value; + continue; + } + if (pdns_iequals(key,"slot")) { + int slot = std::stoi(value); + stormap["slot"]=std::to_string(slot); + continue; + } + if (pdns_iequals(key,"label")) { + stormap["label"] = value; + continue; + } + if(pdns_iequals(key, "Private-key-format")) { + continue; + } + raw.clear(); + B64Decode(value, raw); + stormap[toLower(key)] = raw; + } + return stormap; +} + +void DNSCryptoKeyEngine::testVerify(unsigned int algo, maker_t* verifier) +{ + const string message("Hi! How is life?"); + const string pubkey5 = "AwEAAe2srzo8UfPx5WwoRXTRdo0H8U4iYW6qneronwKlRtXrpOqgZWPtYGVZl1Q7JXqbxxH9aVK5iK6aYOVfxbwwGHejaY0NraqrxL60F5FhHGHg+zox1en8kEX2TcQHxoZaiK1iUgPkMrHJlX5yI5+p2V4qap5VPQsR/WfeFVudNsBEF/XRvg0Exh65fPI/e8sYNgAiflzdN9/5RM644r6viBdieuwUNwEV2HPizCBMssYzx2F29CqNseToqCKQlj1tghuGAsiiSKeosfDLlRPDe/uxtij0wqe0FNybj1oL3OG8Lq3xp8yXIG4CF59xmRDKdnGDmVycKzUWkVOZpesCsUU="; + const string sig5 = "nMnMakbQiiCKIYsEiv4R75+8wvjQav2LPGIKucbqUZUz5sy1ovc2Pp7JVcOuyVyzQu5XH+CetDnTlqiEJWFHNU1jqEwwFK83GVOLABtvXSOvgmGwZGnHOouAchkrzgSSBoEh3+UUN3OsFZA21q6TZVRJBNBm7Ch/PxqSBkFS46ko/qLAUJ1p7/ymzwGNhuOfguHO3dAJ+LgcrNGLZQFDJ1aqT3kZ7LtXX2CQdd7EXgUs6VkE4Z3JN1RmPTk8kAJdZ4JLUR6lgu1dRlSPLGzqv+5d1yI7+h+B0LFNuDdQblDlBstO3LEs1KSaQld+TqVExpjj87oEg6wL/G/XOGabmQ=="; + + const string pubkey7 = "AwEAAc4n7xPG6yJe6YAsg6oQ+7YjbL7wuDLCP4juOSaDsst2Mehc5eYdT7xJT2H9foTIq7ABkkp8Er1Bh6gDzB/0xvArARdH6DS3P5pUP6w5Zoz4Gu79y3pP6IsR3ZyhiQRSnht1ElnIGZzb1zpi7Y4Y8LZ18NYN2qdLasXx/h6hpRjdcF1s7svZKvfJdvCSgDHHD/JFtDGSOn6qt6i5UFSrObxMUMWbxfOsnqr/eXUQcF/aePdqDXO47yDaSH8sFZoglgvEDiOIkky9DV5VKamvVW8anxE5Vv7y4EPpZKXB3CgUW+NvaoasdgYPFmGM4EcnXh2EFFnSPDL6iwDubiL7s2k="; + const string sig7 = "B04Oqmh/nF6BybBGsInauTXH6nlW3VhT2PeSzXVaxQ42QsbbXUgIKuzp2/R7diiEBzbbQ3Eg5vtHOKfEQDkArmOR1oU6yIkyrKHsJkpCvclCyaFiJXrwxkH+A2y8vB+loeDMJKJVwjn7fH9zwBI3Mk7SFuOgYXgzBUNhb5DeQ9RzRbxMcpSc8Cgtjn+QpmTNgL6olpBNsStYz9bSLXBk1EGhmZeBYhliw/2Fse75OoRxIuufKiN6sAD5bKQxp73QQUU+yunVuSeHJizNct8b4f9RXFe49wtZWt5rB0oYXG6zUv0Dq7xJHpUq6v1eB2wf2NucftCKwWu18r4TxkVC5A=="; + + string b64pubkey; + string b64sig; + switch (algo) { + case DNSSECKeeper::RSASHA1: + b64pubkey = pubkey5; + b64sig = sig5; + break; + case DNSSECKeeper::RSASHA1NSEC3SHA1: + b64pubkey = pubkey7; + b64sig = sig7; + break; + default: + throw runtime_error("Verification of verifier called for unimplemented case"); + } + + string pubkey; + string sig; + B64Decode(b64pubkey, pubkey); + B64Decode(b64sig, sig); + auto dckeVerify = verifier(algo); + dckeVerify->fromPublicKeyString(pubkey); + + auto ret = dckeVerify->verify(message, sig); + if (!ret) { + throw runtime_error("Verification of verifier "+dckeVerify->getName() + " failed"); + } +} + +bool DNSCryptoKeyEngine::verifyOne(unsigned int algo) +{ + bool ret=true; + + for (auto* verifier : getAllMakers()[algo]) { + try { + testVerify(algo, verifier); + } + catch (std::exception& e) { + ret = false; + } + } + return ret; +} + void DNSCryptoKeyEngine::testMakers(unsigned int algo, maker_t* creator, maker_t* signer, maker_t* verifier) { auto dckeCreate = creator(algo); @@ -316,40 +413,10 @@ void DNSCryptoKeyEngine::testMakers(unsigned int algo, maker_t* creator, maker_t cout<<"("<getBits()<<" bits) "; unsigned int udiffCreate = dt.udiff() / 100; - { // FIXME: this block copy/pasted from makeFromISCString + { DNSKEYRecordContent dkrc; - unsigned int algorithm = 0; - string sline, key, value, raw; - std::istringstream str(dckeCreate->convertToISC()); - map stormap; - - while(std::getline(str, sline)) { - std::tie(key,value)=splitField(sline, ':'); - boost::trim(value); - if(pdns_iequals(key,"algorithm")) { - pdns::checked_stoi_into(algorithm, value); - stormap["algorithm"]=std::to_string(algorithm); - continue; - } else if (pdns_iequals(key,"pin")) { - stormap["pin"]=value; - continue; - } else if (pdns_iequals(key,"engine")) { - stormap["engine"]=value; - continue; - } else if (pdns_iequals(key,"slot")) { - int slot = std::stoi(value); - stormap["slot"]=std::to_string(slot); - continue; - } else if (pdns_iequals(key,"label")) { - stormap["label"]=value; - continue; - } - else if(pdns_iequals(key, "Private-key-format")) - continue; - raw.clear(); - B64Decode(value, raw); - stormap[toLower(key)]=raw; - } + auto stormap = ICSStringToMap(dckeCreate->convertToISC()); + dckeSign->fromISCMap(dkrc, stormap); if(!dckeSign->checkKey()) { throw runtime_error("Verification of key with creator "+dckeCreate->getName()+" with signer "+dckeSign->getName()+" and verifier "+dckeVerify->getName()+" failed"); @@ -364,6 +431,15 @@ void DNSCryptoKeyEngine::testMakers(unsigned int algo, maker_t* creator, maker_t signature = dckeSign->sign(message); unsigned int udiffSign= dt.udiff()/100, udiffVerify; +#if 0 + if (algo == 7) { + auto pubkey = Base64Encode(dckeSign->getPublicKeyString()); + auto sig = Base64Encode(signature); + cerr << "PubKey: " << pubkey << endl; + cerr << "Signature: " << sig << endl; + } +#endif + dckeVerify->fromPublicKeyString(dckeSign->getPublicKeyString()); if (dckeVerify->getPublicKeyString().compare(dckeSign->getPublicKeyString())) { throw runtime_error("Comparison of public key loaded into verifier produced by signer failed"); diff --git a/pdns/dnssecinfra.hh b/pdns/dnssecinfra.hh index c1628fca1b..7d7da8e7dd 100644 --- a/pdns/dnssecinfra.hh +++ b/pdns/dnssecinfra.hh @@ -177,6 +177,8 @@ class DNSCryptoKeyEngine static vector> listAllAlgosWithBackend(); static bool testAll(); static bool testOne(int algo); + static bool verifyOne(unsigned int algo); + static void testVerify(unsigned int algo, maker_t* verifier); private: using makers_t = std::map; diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 563dab5b15..8e80cefff4 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -38,6 +38,7 @@ #include "rec-taskqueue.hh" #include "secpoll-recursor.hh" #include "logging.hh" +#include "dnsseckeeper.hh" #ifdef NOD_ENABLED #include "nod.hh" @@ -1460,7 +1461,13 @@ static int initDNSSEC(Logr::log_t log) DNSCryptoKeyEngine::switchOffAlgorithm(pdns::checked_stoi(num)); } } else { - // Auto determine algos to switch off + for (auto algo : { DNSSECKeeper::RSASHA1, DNSSECKeeper::RSASHA1NSEC3SHA1 }) { + if (!DNSCryptoKeyEngine::verifyOne(algo)) { + cerr << "XXXX " << algo << endl; + DNSCryptoKeyEngine::switchOffAlgorithm(algo); + nums.push_back(std::to_string(algo)); + } + } } if (!nums.empty()) { if (!g_slogStructured) {