]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Fix DNSCrypt support when building with libsodium < 1.0.3 4926/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 20 Jan 2017 09:43:30 +0000 (10:43 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 20 Jan 2017 09:43:30 +0000 (10:43 +0100)
The precomputed interface was added in 1.0.3, fall back to computing
the key twice with earlier versions.

m4/pdns_check_libsodium.m4
pdns/dnscrypt.cc
pdns/dnscrypt.hh

index 92a52f623ba6a06e91afaa1a4e837c5964bc99d5..ff8d997837fbb5638ea6ad0f8cf3e37cf61f83ac 100644 (file)
@@ -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])
     ])
index 98ed0ef642eb9cbd87cb164368deabadae818947..30ce1e9ad02e48ba48addc7076b1b6bff599b979 100644 (file)
@@ -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<DnsCryptQuery> 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<DnsCryptQuery> 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);
index 89fc7a40e41f66a2ab41c743ac5c85e832e981db..f889d9cac513be1e5dd6042b2784780876eb20e7 100644 (file)
@@ -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