]> granicus.if.org Git - pdns/commitdiff
Support for SHA algorithms for TSIG
authorAki Tuomi <cmouse@cmouse.fi>
Sun, 16 Jun 2013 13:36:01 +0000 (16:36 +0300)
committerAki Tuomi <cmouse@desteem.org>
Tue, 3 Sep 2013 15:21:46 +0000 (18:21 +0300)
Added entropy-source paramater and seedRandom helper

pdns/Makefile.am
pdns/backends/bind/binddnssec.cc
pdns/backends/gsql/gsqlbackend.cc
pdns/dnspacket.cc
pdns/dnssecinfra.cc
pdns/pdnssec.cc
pdns/resolver.cc
regression-tests.nobackend/tinydns-data-check/expected_result

index 49ab8d3e198143e49a2fa83d94bf7133cb99b80b..5e826863428b96585cc0872fa3f3ea27fffdc4ae 100644 (file)
@@ -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)
index fac2b367b035b42fd3cd52a06ce055c045c5e502..da53c08a8f6984e50bb29b8fbbd3efedd1c5509d 100644 (file)
@@ -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;
index 8a997cd6ec21bd9b2b510d684d799364dabc5104..737a0a858cba1374136e411309eb85989451683f 100644 (file)
@@ -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();
index 3959d6fbe568cd1be534e30196e89c0ebef878ef..f169a7596e831068c6640307b3a3ce04ee978b25 100644 (file)
@@ -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<<Logger::Error<<"Do not know how to handle TSIG algorithm " << trc->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<<Logger::Error<<"Unsupported TSIG HMAC algorithm " << trc->d_algoName << endl;
+     return false;
   }
 
+  B64Decode(secret64, *secret);
+  result=calculateHMAC(*secret, message, algo) == trc->d_mac;
+
   if(!result) {
     L<<Logger::Error<<"Packet for domain '"<<q->qdomain<<"' denied: TSIG signature mismatch using '"<<*keyname<<"' and algorithm '"<<trc->d_algoName<<"'"<<endl;
   }
index a5b0b268eee06738375a6be1fb9775d9abad028d..2c4bd1cb8d737655cb08883e3f41cfc84dcafbc7 100644 (file)
@@ -423,7 +423,8 @@ void decodeDERIntegerSequence(const std::string& input, vector<string>& 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<<Logger::Error<<"Unsupported HMAC TSIG algorithm " << trc->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<<Logger::Error<<"Unsupported TSIG HMAC algorithm " << trc->d_algoName << endl;
+     return;
   }
 
   string toSign;
@@ -609,7 +627,7 @@ void addTSIG(DNSPacketWriter& pw, TSIGRecordContent* trc, const string& tsigkeyn
   const vector<uint8_t>& 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);
index f1aa48a7289e152248d58df9355d11992c27e9aa..7cf4678c4111f7023bf2be5a354e59cecca9e814 100644 (file)
@@ -13,6 +13,7 @@
 #include "signingpipe.hh"
 #include <boost/scoped_ptr.hpp>
 #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");
index 2523916de2b5c5614f53461be9edcb26821d37e2..9b8eebf827d160c9480cc79ba6ec3577cb2a171e 100644 (file)
@@ -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);
index 3f5b50fdf9fcf525d688ea000ec7beb4fea8dd38..ffbc6cfc7f1d150b1f61f3d418f472a7af693043 100644 (file)
@@ -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