From 333ea16e1c27c1e4698eb50c37291608e5e38b7e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 23 Dec 2016 11:52:43 +0100 Subject: [PATCH] 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. --- pdns/dnsdist-console.cc | 23 +++++++++++++---------- pdns/sodcrypto.hh | 16 ++++++++++++---- regression-tests.dnsdist/dnsdisttests.py | 8 ++++++-- 3 files changed, 31 insertions(+), 16 deletions(-) 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 -- 2.47.2