From: Aki Tuomi Date: Sun, 16 Jun 2013 13:36:01 +0000 (+0300) Subject: Support for SHA algorithms for TSIG X-Git-Tag: rec-3.6.0-rc1~468^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a56bc64de40171bbeb99ff149ae075443a072d86;p=thirdparty%2Fpdns.git Support for SHA algorithms for TSIG Added entropy-source paramater and seedRandom helper --- diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 49ab8d3e19..5e82686342 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -102,8 +102,7 @@ pdnssec_SOURCES=pdnssec.cc dbdnsseckeeper.cc sstuff.hh dnsparser.cc dnsparser.hh aes/aescpp.h \ aes/aescrypt.c aes/aes.h aes/aeskey.c aes/aes_modes.c aes/aesopt.h \ aes/aestab.c aes/aestab.h aes/brg_endian.h aes/brg_types.h aes/dns_random.cc json.cc \ - serialtweaker.cc - + serialtweaker.cc randomhelper.cc pdnssec_LDFLAGS=@moduleobjects@ @modulelibs@ @DYNLINKFLAGS@ @LIBDL@ @THREADFLAGS@ $(BOOST_PROGRAM_OPTIONS_LDFLAGS) $(BOOST_SERIALIZATION_LDFLAGS) pdnssec_LDADD= $(POLARSSL_LIBS) $(BOOST_PROGRAM_OPTIONS_LIBS) $(BOOST_SERIALIZATION_LIBS) $(SQLITE3_LIBS) $(LIBCURL_LIBS) $(MYSQL_lib) diff --git a/pdns/backends/bind/binddnssec.cc b/pdns/backends/bind/binddnssec.cc index fac2b367b0..da53c08a8f 100644 --- a/pdns/backends/bind/binddnssec.cc +++ b/pdns/backends/bind/binddnssec.cc @@ -299,7 +299,7 @@ bool Bind2Backend::setTSIGKey(const string& name, const string& algorithm, const d_dnssecdb->doCommand( (fmt % d_dnssecdb->escape(name) % d_dnssecdb->escape(algorithm) % d_dnssecdb->escape(content)).str() ); } catch (SSqlException &e) { - throw AhuException("BindBackend unable to retrieve named TSIG key: "+e.txtReason()); + throw PDNSException("BindBackend unable to retrieve named TSIG key: "+e.txtReason()); } return true; @@ -315,7 +315,7 @@ bool Bind2Backend::deleteTSIGKey(const string& name) d_dnssecdb->doCommand( (fmt % d_dnssecdb->escape(name)).str() ); } catch (SSqlException &e) { - throw AhuException("BindBackend unable to retrieve named TSIG key: "+e.txtReason()); + throw PDNSException("BindBackend unable to retrieve named TSIG key: "+e.txtReason()); } return true; @@ -330,7 +330,7 @@ bool Bind2Backend::getTSIGKeys(std::vector< struct TSIGKey > &keys) d_dnssecdb->doQuery( "select name,algorithm,secret from tsigkeys" ); } catch (SSqlException &e) { - throw AhuException("GSQLBackend unable to retrieve named TSIG key: "+e.txtReason()); + throw PDNSException("GSQLBackend unable to retrieve named TSIG key: "+e.txtReason()); } SSql::row_t row; diff --git a/pdns/backends/gsql/gsqlbackend.cc b/pdns/backends/gsql/gsqlbackend.cc index 8a997cd6ec..737a0a858c 100644 --- a/pdns/backends/gsql/gsqlbackend.cc +++ b/pdns/backends/gsql/gsqlbackend.cc @@ -616,7 +616,7 @@ bool GSQLBackend::setTSIGKey(const string& name, const string& algorithm, const d_db->doCommand(output); } catch (SSqlException &e) { - throw AhuException("GSQLBackend unable to store named TSIG key: "+e.txtReason()); + throw PDNSException("GSQLBackend unable to store named TSIG key: "+e.txtReason()); } return true; } @@ -632,7 +632,7 @@ bool GSQLBackend::deleteTSIGKey(const string& name) d_db->doCommand(output); } catch (SSqlException &e) { - throw AhuException("GSQLBackend unable to store named TSIG key: "+e.txtReason()); + throw PDNSException("GSQLBackend unable to store named TSIG key: "+e.txtReason()); } return true; } @@ -649,7 +649,7 @@ bool GSQLBackend::getTSIGKeys(std::vector< struct TSIGKey > &keys) d_db->doQuery(output); } catch (SSqlException &e) { - throw AhuException("GSQLBackend unable to retrieve named TSIG key: "+e.txtReason()); + throw PDNSException("GSQLBackend unable to retrieve TSIG keys: "+e.txtReason()); } SSql::row_t row; @@ -659,6 +659,7 @@ bool GSQLBackend::getTSIGKeys(std::vector< struct TSIGKey > &keys) key.name = row[0]; key.algorithm = row[1]; key.key = row[2]; + keys.push_back(key); } return keys.empty(); diff --git a/pdns/dnspacket.cc b/pdns/dnspacket.cc index 3959d6fbe5..f169a7596e 100644 --- a/pdns/dnspacket.cc +++ b/pdns/dnspacket.cc @@ -614,17 +614,29 @@ bool checkForCorrectTSIG(const DNSPacket* q, DNSBackend* B, string* keyname, str trc->d_algoName += ".sig-alg.reg.int."; bool result; + TSIGHashEnum algo; + if (*(trc->d_algoName.rbegin()) != '.') trc->d_algoName.append("."); + if (trc->d_algoName == "hmac-md5.sig-alg.reg.int.") - { - B64Decode(secret64, *secret); - result=calculateMD5HMAC(*secret, message) == trc->d_mac; - } - else - { - L<d_algoName << endl; - return false; + algo = TSIG_MD5; + else if (trc->d_algoName == "hmac-sha1.") + algo = TSIG_SHA1; + else if (trc->d_algoName == "hmac-sha224.") + algo = TSIG_SHA224; + else if (trc->d_algoName == "hmac-sha256.") + algo = TSIG_SHA256; + else if (trc->d_algoName == "hmac-sha384.") + algo = TSIG_SHA384; + else if (trc->d_algoName == "hmac-sha512.") + algo = TSIG_SHA512; + else { + L<d_algoName << endl; + return false; } + B64Decode(secret64, *secret); + result=calculateHMAC(*secret, message, algo) == trc->d_mac; + if(!result) { L<qdomain<<"' denied: TSIG signature mismatch using '"<<*keyname<<"' and algorithm '"<d_algoName<<"'"<& output) string calculateMD5HMAC(const std::string& key_, const std::string& text) { - const unsigned char* key=(const unsigned char*)key_.c_str(); + unsigned char key[64] = {0}; + key_.copy((char*)key,64); unsigned char keyIpad[64]; unsigned char keyOpad[64]; @@ -453,7 +454,8 @@ string calculateMD5HMAC(const std::string& key_, const std::string& text) string calculateSHAHMAC(const std::string& key_, const std::string& text, TSIGHashEnum hasher) { - const unsigned char* key=(const unsigned char*)key_.c_str(); + unsigned char key[64] = {0}; + key_.copy((char*)key,64); unsigned char keyIpad[64]; unsigned char keyOpad[64]; @@ -518,7 +520,7 @@ string calculateSHAHMAC(const std::string& key_, const std::string& text, TSIGHa return s2.get(); }; default: - throw new AhuException("Unknown hash algorithm requested for SHA"); + throw new PDNSException("Unknown hash algorithm requested for SHA"); }; return std::string(""); @@ -573,9 +575,25 @@ string makeTSIGMessageFromTSIGPacket(const string& opacket, unsigned int tsigOff void addTSIG(DNSPacketWriter& pw, TSIGRecordContent* trc, const string& tsigkeyname, const string& tsigsecret, const string& tsigprevious, bool timersonly) { - if (trc->d_algoName != "hmac-md5.sig-alg.reg.int.") { - L<d_algoName << endl; - return; + TSIGHashEnum algo; + + if (*(trc->d_algoName.rbegin()) != '.') trc->d_algoName.append("."); + + if (trc->d_algoName == "hmac-md5.sig-alg.reg.int.") + algo = TSIG_MD5; + else if (trc->d_algoName == "hmac-sha1.") + algo = TSIG_SHA1; + else if (trc->d_algoName == "hmac-sha224.") + algo = TSIG_SHA224; + else if (trc->d_algoName == "hmac-sha256.") + algo = TSIG_SHA256; + else if (trc->d_algoName == "hmac-sha384.") + algo = TSIG_SHA384; + else if (trc->d_algoName == "hmac-sha512.") + algo = TSIG_SHA512; + else { + L<d_algoName << endl; + return; } string toSign; @@ -609,7 +627,7 @@ void addTSIG(DNSPacketWriter& pw, TSIGRecordContent* trc, const string& tsigkeyn const vector& signRecord=dw.getRecordBeingWritten(); toSign.append(&*signRecord.begin(), &*signRecord.end()); - trc->d_mac = calculateMD5HMAC(tsigsecret, toSign); + trc->d_mac = calculateHMAC(tsigsecret, toSign, algo); // d_trc->d_mac[0]++; // sabotage pw.startRecord(tsigkeyname, QType::TSIG, 0, QClass::ANY, DNSPacketWriter::ADDITIONAL, false); trc->toPacket(pw); diff --git a/pdns/pdnssec.cc b/pdns/pdnssec.cc index f1aa48a728..7cf4678c41 100644 --- a/pdns/pdnssec.cc +++ b/pdns/pdnssec.cc @@ -13,6 +13,7 @@ #include "signingpipe.hh" #include #include "bindbackend2.hh" +#include "dns_random.hh" StatBag S; PacketCache PC; @@ -128,9 +129,10 @@ void loadMainConfig(const std::string& configdir) ::arg().set("default-ksk-size","Default KSK size (0 means default)")="0"; ::arg().set("default-zsk-algorithms","Default ZSK algorithms")="rsasha256"; ::arg().set("default-zsk-size","Default KSK size (0 means default)")="0"; - ::arg().set("max-ent-entries", "Maximum number of empty non-terminals in a zone")="100000"; ::arg().set("module-dir","Default directory for modules")=LIBDIR; + ::arg().set("entropy-source", "If set, read entropy from this file")="/dev/urandom"; + ::arg().setSwitch("experimental-direct-dnskey","EXPERIMENTAL: fetch DNSKEY RRs from backend during DNSKEY synthesis")="no"; ::arg().laxFile(configname.c_str()); @@ -674,6 +676,7 @@ bool showZone(DNSSECKeeper& dk, const std::string& zone) cerr << "Zone has following allowed TSIG key(s): " << boost::join(meta, ",") << endl; } + meta.clear(); if (B.getDomainMetadata(zone, "AXFR-MASTER-TSIG", meta) && meta.size() > 0) { cerr << "Zone uses following TSIG key(s): " << boost::join(meta, ",") << endl; } @@ -1489,10 +1492,10 @@ try } cerr << "Generating new key with " << klen << " bytes (this can take a while)" << endl; - - ifstream keyin("/dev/random", ifstream::in|ifstream::binary); - // read and hash data - keyin.read(tmpkey, klen); + seedRandom(::arg()["entropy-source"]); + for(size_t i = 0; i < klen; i+=4) { + *(unsigned int*)(tmpkey+i) = dns_random(0xffffffff); + } key = Base64Encode(std::string(tmpkey, klen)); UeberBackend B("default"); diff --git a/pdns/resolver.cc b/pdns/resolver.cc index 2523916de2..9b8eebf827 100644 --- a/pdns/resolver.cc +++ b/pdns/resolver.cc @@ -124,6 +124,8 @@ uint16_t Resolver::sendResolve(const ComboAddress& remote, const char *domain, i TSIGRecordContent trc; if (tsigalgorithm == "hmac-md5") trc.d_algoName = tsigalgorithm + ".sig-alg.reg.int."; + else + trc.d_algoName = tsigalgorithm; trc.d_time = time(0); trc.d_fudge = 300; trc.d_origID=ntohs(d_randomid); @@ -332,7 +334,10 @@ AXFRRetriever::AXFRRetriever(const ComboAddress& remote, pw.getHeader()->id = dns_random(0xffff); if(!tsigkeyname.empty()) { - d_trc.d_algoName = tsigalgorithm + ".sig-alg.reg.int."; + if (tsigalgorithm == "hmac-md5") + d_trc.d_algoName = tsigalgorithm + ".sig-alg.reg.int."; + else + d_trc.d_algoName = tsigalgorithm; d_trc.d_time = time(0); d_trc.d_fudge = 300; d_trc.d_origID=ntohs(pw.getHeader()->id); diff --git a/regression-tests.nobackend/tinydns-data-check/expected_result b/regression-tests.nobackend/tinydns-data-check/expected_result index 3f5b50fdf9..ffbc6cfc7f 100644 --- a/regression-tests.nobackend/tinydns-data-check/expected_result +++ b/regression-tests.nobackend/tinydns-data-check/expected_result @@ -7,3 +7,4 @@ a2dd754820cb88fdd3d80b54a212a270 ../regression-tests/test.com a63dc120391d9df0003f2ec4f461a6af ../regression-tests/secure-delegated.dnssec-parent.com 24514dc104b22206daeb973ff9303545 ../regression-tests/minimal.com f77817aafda5cd6a8e3d4ac998be6fff ../modules/tinydnsbackend/data.cdb +0b20d7a0250576451135483b863750bf ../regression-tests/tsig.com