From: Remi Gacogne Date: Fri, 23 Dec 2016 10:52:43 +0000 (+0100) Subject: dnsdist: Merge the client and server nonces to prevent replay attacks X-Git-Tag: rec-4.1.0-alpha1~323^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F4815%2Fhead;p=thirdparty%2Fpdns.git dnsdist: Merge the client and server nonces to prevent replay attacks Instead of using the local nonce to send messages (and so the remote one for received ones), split and merge the local and remote nonces to create two new nonces, one for client to server and one for server to client. --- diff --git a/pdns/dnsdist-console.cc b/pdns/dnsdist-console.cc index 45052f08db..ad9c4bb3c6 100644 --- a/pdns/dnsdist-console.cc +++ b/pdns/dnsdist-console.cc @@ -56,14 +56,16 @@ void doClient(ComboAddress server, const std::string& command) } SConnect(fd, server); setTCPNoDelay(fd); - SodiumNonce theirs, ours; + SodiumNonce theirs, ours, readingNonce, writingNonce; ours.init(); writen2(fd, (const char*)ours.value, sizeof(ours.value)); readn2(fd, (char*)theirs.value, sizeof(theirs.value)); + readingNonce.merge(ours, theirs); + writingNonce.merge(theirs, ours); if(!command.empty()) { - string msg=sodEncryptSym(command, g_key, ours); + string msg=sodEncryptSym(command, g_key, writingNonce); putMsgLen32(fd, (uint32_t) msg.length()); if(!msg.empty()) writen2(fd, msg); @@ -73,7 +75,7 @@ void doClient(ComboAddress server, const std::string& command) boost::scoped_array resp(new char[len]); readn2(fd, resp.get(), len); msg.assign(resp.get(), len); - msg=sodDecryptSym(msg, g_key, theirs); + msg=sodDecryptSym(msg, g_key, readingNonce); cout< resp(new char[len]); readn2(fd, resp.get(), len); msg.assign(resp.get(), len); - msg=sodDecryptSym(msg, g_key, theirs); + msg=sodDecryptSym(msg, g_key, readingNonce); cout< @@ -42,7 +43,14 @@ struct SodiumNonce { randombytes_buf(value, sizeof value); } - + + void merge(const SodiumNonce& lower, const SodiumNonce& higher) + { + static const size_t halfSize = (sizeof value) / 2; + memcpy(value, lower.value, halfSize); + memcpy(value + halfSize, higher.value + halfSize, halfSize); + } + void increment() { uint32_t* p = (uint32_t*)value; diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index d04c247803..9a649c583d 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -371,11 +371,15 @@ class DNSDistTest(unittest.TestCase): sock.send(ourNonce) theirNonce = sock.recv(len(ourNonce)) - msg = cls._encryptConsole(command, ourNonce) + halfNonceSize = len(ourNonce) / 2 + readingNonce = ourNonce[0:halfNonceSize] + theirNonce[halfNonceSize:] + writingNonce = theirNonce[0:halfNonceSize] + ourNonce[halfNonceSize:] + + msg = cls._encryptConsole(command, writingNonce) sock.send(struct.pack("!I", len(msg))) sock.send(msg) data = sock.recv(4) (responseLen,) = struct.unpack("!I", data) data = sock.recv(responseLen) - response = cls._decryptConsole(data, theirNonce) + response = cls._decryptConsole(data, readingNonce) return response