From b5db7ee8f9cc1480c2dd47a2ecd9fd40122212ec Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 20 Sep 2023 15:49:56 +0200 Subject: [PATCH] dnsdist: Refactoring of SodiumNonce and friends --- pdns/base64.hh | 2 +- pdns/dnsdist-console.cc | 8 ++--- pdns/sodcrypto.cc | 71 +++++++++++++++++++++++++++++++---------- pdns/sodcrypto.hh | 69 ++++++++++++++------------------------- 4 files changed, 84 insertions(+), 66 deletions(-) diff --git a/pdns/base64.hh b/pdns/base64.hh index a84181db3212..f07814bf1b93 100644 --- a/pdns/base64.hh +++ b/pdns/base64.hh @@ -22,5 +22,5 @@ #pragma once #include -template int B64Decode(const std::string& src, Container& dst); +template int B64Decode(const std::string& strInput, Container& strOutput); std::string Base64Encode (const std::string& src); diff --git a/pdns/dnsdist-console.cc b/pdns/dnsdist-console.cc index a451f31e1ad7..a49a50914759 100644 --- a/pdns/dnsdist-console.cc +++ b/pdns/dnsdist-console.cc @@ -236,8 +236,8 @@ void doClient(ComboAddress server, const std::string& command) SodiumNonce theirs, ours, readingNonce, writingNonce; ours.init(); - writen2(fd.getHandle(), (const char*)ours.value, sizeof(ours.value)); - readn2(fd.getHandle(), (char*)theirs.value, sizeof(theirs.value)); + writen2(fd.getHandle(), ours.value.data(), ours.value.size()); + readn2(fd.getHandle(), theirs.value.data(), theirs.value.size()); readingNonce.merge(ours, theirs); writingNonce.merge(theirs, ours); @@ -868,8 +868,8 @@ static void controlClientThread(ConsoleConnection&& conn) SodiumNonce theirs, ours, readingNonce, writingNonce; ours.init(); - readn2(conn.getFD(), (char*)theirs.value, sizeof(theirs.value)); - writen2(conn.getFD(), (char*)ours.value, sizeof(ours.value)); + readn2(conn.getFD(), theirs.value.data(), theirs.value.size()); + writen2(conn.getFD(), ours.value.data(), ours.value.size()); readingNonce.merge(ours, theirs); writingNonce.merge(theirs, ours); diff --git a/pdns/sodcrypto.cc b/pdns/sodcrypto.cc index b92c6e0e53bb..9e9f91ce203d 100644 --- a/pdns/sodcrypto.cc +++ b/pdns/sodcrypto.cc @@ -20,13 +20,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include +#include + #include "namespaces.hh" #include "noinitvector.hh" #include "misc.hh" #include "base64.hh" #include "sodcrypto.hh" - #ifdef HAVE_LIBSODIUM string newKey() @@ -34,9 +35,10 @@ string newKey() std::string key; key.resize(crypto_secretbox_KEYBYTES); - randombytes_buf(reinterpret_cast(&key.at(0)), key.size()); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + randombytes_buf(reinterpret_cast(key.data()), key.size()); - return "\""+Base64Encode(key)+"\""; + return "\"" + Base64Encode(key) + "\""; } bool sodIsValidKey(const std::string& key) @@ -44,7 +46,7 @@ bool sodIsValidKey(const std::string& key) return key.size() == crypto_secretbox_KEYBYTES; } -std::string sodEncryptSym(const std::string& msg, const std::string& key, SodiumNonce& nonce) +std::string sodEncryptSym(const std::string_view& msg, const std::string& key, SodiumNonce& nonce) { if (!sodIsValidKey(key)) { throw std::runtime_error("Invalid encryption key of size " + std::to_string(key.size()) + ", use setKey() to set a valid key"); @@ -52,17 +54,20 @@ std::string sodEncryptSym(const std::string& msg, const std::string& key, Sodium std::string ciphertext; ciphertext.resize(msg.length() + crypto_secretbox_MACBYTES); - crypto_secretbox_easy(reinterpret_cast(&ciphertext.at(0)), - reinterpret_cast(msg.c_str()), + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + crypto_secretbox_easy(reinterpret_cast(ciphertext.data()), + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + reinterpret_cast(msg.data()), msg.length(), - nonce.value, - reinterpret_cast(key.c_str())); + nonce.value.data(), + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + reinterpret_cast(key.data())); nonce.increment(); return ciphertext; } -std::string sodDecryptSym(const std::string& msg, const std::string& key, SodiumNonce& nonce) +std::string sodDecryptSym(const std::string_view& msg, const std::string& key, SodiumNonce& nonce) { std::string decrypted; @@ -76,18 +81,54 @@ std::string sodDecryptSym(const std::string& msg, const std::string& key, Sodium decrypted.resize(msg.length() - crypto_secretbox_MACBYTES); - if (crypto_secretbox_open_easy(reinterpret_cast(const_cast(decrypted.data())), - reinterpret_cast(msg.c_str()), + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + if (crypto_secretbox_open_easy(reinterpret_cast(decrypted.data()), + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + reinterpret_cast(msg.data()), msg.length(), - nonce.value, - reinterpret_cast(key.c_str())) != 0) { + nonce.value.data(), + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + reinterpret_cast(key.data())) != 0) { throw std::runtime_error("Could not decrypt message, please check that the key configured with setKey() is correct"); } nonce.increment(); return decrypted; } + +void SodiumNonce::init() +{ + randombytes_buf(value.data(), value.size()); +} + +void SodiumNonce::merge(const SodiumNonce& lower, const SodiumNonce& higher) +{ + constexpr size_t halfSize = std::tuple_size{} / 2; + memcpy(value.data(), lower.value.data(), halfSize); + memcpy(value.data() + halfSize, higher.value.data() + halfSize, halfSize); +} + +void SodiumNonce::increment() +{ + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + auto* ptr = reinterpret_cast(value.data()); + uint32_t count = htonl(*ptr); + *ptr = ntohl(++count); +} + #else +void SodiumNonce::init() +{ +} + +void SodiumNonce::merge(const SodiumNonce& lower, const SodiumNonce& higher) +{ +} + +void SodiumNonce::increment() +{ +} + std::string sodEncryptSym(const std::string& msg, const std::string& key, SodiumNonce& nonce) { return msg; @@ -109,9 +150,7 @@ bool sodIsValidKey(const std::string& key) #endif - -#include "base64.hh" -#include +#include namespace anonpdns { static char B64Decode1(char cInChar) diff --git a/pdns/sodcrypto.hh b/pdns/sodcrypto.hh index ca35631455de..8538702fc811 100644 --- a/pdns/sodcrypto.hh +++ b/pdns/sodcrypto.hh @@ -21,58 +21,37 @@ */ #pragma once #include "config.h" +#include #include -#include +#include +#include -#include - -#ifndef HAVE_LIBSODIUM -struct SodiumNonce -{ - void init(){}; - void merge(const SodiumNonce& lower, const SodiumNonce& higher) {}; - void increment(){}; - unsigned char value[1]{0}; -}; -#else +#if defined(HAVE_LIBSODIUM) #include +#endif struct SodiumNonce { - SodiumNonce() - { - memset(&value, 0, sizeof(value)); - } - - void init() - { - 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; - uint32_t count=htonl(*p); - *p=ntohl(++count); - } - - string toString() const - { - return string((const char*)value, crypto_secretbox_NONCEBYTES); - } - - unsigned char value[crypto_secretbox_NONCEBYTES]; -}; + SodiumNonce() = default; + SodiumNonce(const SodiumNonce&) = default; + SodiumNonce(SodiumNonce&&) = default; + SodiumNonce& operator=(const SodiumNonce&) = default; + SodiumNonce& operator=(SodiumNonce&&) = default; + ~SodiumNonce() = default; + + void init(); + void merge(const SodiumNonce& lower, const SodiumNonce& higher); + void increment(); + +#if !defined(HAVE_LIBSODIUM) + std::array value{}; +#else + std::array value{}; #endif +}; + std::string newKeypair(); -std::string sodEncryptSym(const std::string& msg, const std::string& key, SodiumNonce&); -std::string sodDecryptSym(const std::string& msg, const std::string& key, SodiumNonce&); +std::string sodEncryptSym(const std::string_view& msg, const std::string& key, SodiumNonce&); +std::string sodDecryptSym(const std::string_view& msg, const std::string& key, SodiumNonce&); std::string newKey(); bool sodIsValidKey(const std::string& key);