From: Remi Gacogne Date: Fri, 20 Jan 2017 09:43:30 +0000 (+0100) Subject: dnsdist: Fix DNSCrypt support when building with libsodium < 1.0.3 X-Git-Tag: rec-4.1.0-alpha1~312^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=00ffb1c27962991d5a302d6bb6263401a87db405;p=thirdparty%2Fpdns.git dnsdist: Fix DNSCrypt support when building with libsodium < 1.0.3 The precomputed interface was added in 1.0.3, fall back to computing the key twice with earlier versions. --- diff --git a/m4/pdns_check_libsodium.m4 b/m4/pdns_check_libsodium.m4 index 92a52f623b..ff8d997837 100644 --- a/m4/pdns_check_libsodium.m4 +++ b/m4/pdns_check_libsodium.m4 @@ -12,6 +12,13 @@ AC_DEFUN([PDNS_CHECK_LIBSODIUM], [ AM_COND_IF([LIBSODIUM], [ PKG_CHECK_MODULES([LIBSODIUM], [libsodium], [ AC_DEFINE([HAVE_LIBSODIUM], [1], [Define to 1 if you have libsodium]) + save_CFLAGS=$CFLAGS + save_LIBS=$LIBS + CFLAGS="$LIBSODIUM_CFLAGS $CFLAGS" + LIBS="$LIBSODIUM_LIBS $LIBS" + AC_CHECK_FUNCS([crypto_box_easy_afternm]) + CFLAGS=$save_CFLAGS + LIBS=$save_LIBS ],[ AC_MSG_ERROR([libsodium requested but not available]) ]) diff --git a/pdns/dnscrypt.cc b/pdns/dnscrypt.cc index 98ed0ef642..30ce1e9ad0 100644 --- a/pdns/dnscrypt.cc +++ b/pdns/dnscrypt.cc @@ -59,6 +59,7 @@ DnsCryptPrivateKey::~DnsCryptPrivateKey() sodium_munlock(key, sizeof(key)); } +#ifdef HAVE_CRYPTO_BOX_EASY_AFTERNM DnsCryptQuery::~DnsCryptQuery() { if (sharedKeyComputed) { @@ -87,7 +88,11 @@ int DnsCryptQuery::computeSharedKey(const DnsCryptPrivateKey& privateKey) sharedKeyComputed = true; return res; } - +#else +DnsCryptQuery::~DnsCryptQuery() +{ +} +#endif /* HAVE_CRYPTO_BOX_EASY_AFTERNM */ void DnsCryptContext::generateProviderKeys(unsigned char publicKey[DNSCRYPT_PROVIDER_PUBLIC_KEY_SIZE], unsigned char privateKey[DNSCRYPT_PROVIDER_PRIVATE_KEY_SIZE]) { @@ -321,6 +326,7 @@ void DnsCryptContext::getDecryptedQuery(std::shared_ptr query, bo memcpy(nonce, &query->header.clientNonce, sizeof(query->header.clientNonce)); memset(nonce + sizeof(query->header.clientNonce), 0, sizeof(nonce) - sizeof(query->header.clientNonce)); +#ifdef HAVE_CRYPTO_BOX_EASY_AFTERNM int res = query->computeSharedKey(query->useOldCert ? oldPrivateKey : privateKey); if (res != 0) { vinfolog("Dropping encrypted query we can't compute the shared key for"); @@ -332,6 +338,14 @@ void DnsCryptContext::getDecryptedQuery(std::shared_ptr query, bo packetSize - sizeof(DnsCryptQueryHeader), nonce, query->sharedKey); +#else + int res = crypto_box_open_easy((unsigned char*) packet, + (unsigned char*) packet + sizeof(DnsCryptQueryHeader), + packetSize - sizeof(DnsCryptQueryHeader), + nonce, + query->header.clientPK, + query->useOldCert ? oldPrivateKey.key : privateKey.key); +#endif /* HAVE_CRYPTO_BOX_EASY_AFTERNM */ if (res != 0) { vinfolog("Dropping encrypted query we can't decrypt"); @@ -482,6 +496,7 @@ int DnsCryptContext::encryptResponse(char* response, uint16_t responseLen, uint1 pos += (paddingSize - 1); /* encrypting */ +#ifdef HAVE_CRYPTO_BOX_EASY_AFTERNM int res = query->computeSharedKey(query->useOldCert ? oldPrivateKey : privateKey); if (res != 0) { return res; @@ -492,6 +507,14 @@ int DnsCryptContext::encryptResponse(char* response, uint16_t responseLen, uint1 responseLen + paddingSize, header.nonce, query->sharedKey); +#else + int res = crypto_box_easy((unsigned char*) (response + sizeof(header)), + (unsigned char*) (response + toEncryptPos), + responseLen + paddingSize, + header.nonce, + query->header.clientPK, + query->useOldCert ? oldPrivateKey.key : privateKey.key); +#endif /* HAVE_CRYPTO_BOX_EASY_AFTERNM */ if (res == 0) { assert(pos == requiredSize); diff --git a/pdns/dnscrypt.hh b/pdns/dnscrypt.hh index 89fc7a40e4..f889d9cac5 100644 --- a/pdns/dnscrypt.hh +++ b/pdns/dnscrypt.hh @@ -112,12 +112,16 @@ public: { } ~DnsCryptQuery(); +#ifdef HAVE_CRYPTO_BOX_EASY_AFTERNM int computeSharedKey(const DnsCryptPrivateKey& privateKey); +#endif /* HAVE_CRYPTO_BOX_EASY_AFTERNM */ static const size_t minUDPLength = 256; DnsCryptQueryHeader header; +#ifdef HAVE_CRYPTO_BOX_EASY_AFTERNM unsigned char sharedKey[crypto_box_BEFORENMBYTES]; +#endif /* HAVE_CRYPTO_BOX_EASY_AFTERNM */ DNSName qname; DnsCryptContext* ctx; uint16_t id{0}; @@ -126,7 +130,9 @@ public: bool useOldCert{false}; bool encrypted{false}; bool valid{false}; +#ifdef HAVE_CRYPTO_BOX_EASY_AFTERNM bool sharedKeyComputed{false}; +#endif /* HAVE_CRYPTO_BOX_EASY_AFTERNM */ }; class DnsCryptContext