]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Don't copy the same salt for all iterations in hashQNameWithSalt()
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 11 Dec 2020 15:47:51 +0000 (16:47 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 29 Jan 2021 11:12:39 +0000 (12:12 +0100)
The salt does not change between iterations, and the hash size is
constant, so we can just overwrite the hash instead.

pdns/dnssecinfra.cc

index 502c10bbc9a4e2686c1df03718ff1ab929c75cf2..152fd3bf80eec1d85e0c2cd64f3196d8859482f0 100644 (file)
@@ -492,16 +492,34 @@ string hashQNameWithSalt(const NSEC3PARAMRecordContent& ns3prc, const DNSName& q
 string hashQNameWithSalt(const std::string& salt, unsigned int iterations, const DNSName& qname)
 {
   unsigned int times = iterations;
-  unsigned char hash[20];
-  string toHash(qname.toDNSStringLC());
-
-  for(;;) {
-    toHash.append(salt);
-    SHA1((unsigned char*)toHash.c_str(), toHash.length(), hash);
-    toHash.assign((char*)hash, sizeof(hash));
-    if(!times--)
+  unsigned char hash[SHA_DIGEST_LENGTH];
+  string toHash(qname.toDNSStringLC() + salt);
+  if (toHash.capacity() < (salt.size() + sizeof(hash))) {
+    toHash.reserve(salt.size() + sizeof(hash));
+  }
+
+  for (;;) {
+    /* so the first time we hash the (lowercased) qname plus the salt,
+       then the result of the last iteration plus the salt */
+    SHA1(reinterpret_cast<const unsigned char*>(toHash.c_str()), toHash.length(), hash);
+    if (!times--) {
+      /* we are done, just copy the result and return it */
+      toHash.assign(reinterpret_cast<char*>(hash), sizeof(hash));
       break;
+    }
+    if (times == (iterations-1)) {
+      /* first time, we need to replace the qname + salt with
+         the hash plus salt, since the qname will not likely
+         match the size of the hash */
+      toHash.assign(reinterpret_cast<char*>(hash), sizeof(hash));
+      toHash.append(salt);
+    }
+    else {
+      /* starting with the second iteration, the hash size does not change, so we don't need to copy the salt again */
+      std::copy(reinterpret_cast<char*>(hash), reinterpret_cast<char*>(hash) + sizeof(hash), toHash.begin());
+    }
   }
+
   return toHash;
 }