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 45052f08d..ad9c4bb3c 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 d04c24780..9a649c583 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.40.0