]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
move to symmetric crypto, plus document how it works
authorbert hubert <bert.hubert@netherlabs.nl>
Thu, 26 Feb 2015 18:10:33 +0000 (19:10 +0100)
committerbert hubert <bert.hubert@netherlabs.nl>
Thu, 26 Feb 2015 18:10:33 +0000 (19:10 +0100)
pdns/README-dnsdist.md
pdns/dnsdist.cc
pdns/dnsdistconf.lua
pdns/sodcrypto.cc
pdns/sodcrypto.hh

index d8729445cfc3e83a86f9229b1d7d7ca8cebeb8da..7d190c8da570b78ed5a3fb1e4705be8992aaf883 100644 (file)
@@ -25,7 +25,7 @@ newServer2 {address="2620:0:ccc::2", qps=10}
 newServer2 {address="2620:0:ccd::2", qps=10}
 newServer("192.168.1.2")
 
-$ dnsdist --local=0.0.0.0:5200 
+$ dnsdist --local=0.0.0.0:5200 --daemon=no
 Marking downstream [2001:4860:4860::8888]:53 as 'up'
 Marking downstream [2001:4860:4860::8844]:53 as 'up'
 Marking downstream [2620:0:ccc::2]:53 as 'up'
@@ -150,3 +150,20 @@ setServerPolicy(luaroundrobin)
 Incidentally, this is similar to setting: `setServerPolicy(roundrobin)`
 which uses the C++ based roundrobin policy.
 
+Running it for real
+-------------------
+First run on the command line, and generate a key:
+
+```
+# dnsdist --daemon-no
+> makeKey()
+setKey("sepuCcHcQnSAZgNbNPCCpDWbujZ5esZJmrt/wh6ldkQ=")
+```
+
+Now add this setKey line to `dnsdistconf.lua`, followed by:
+
+```
+# dnsdist
+# dnsdist --client
+> 
+```
index a07a7a3fb3020036c798808483fce4022649c22a..1937659dfdb40c755edacda35410bb27d0f3f96f 100644 (file)
@@ -712,22 +712,26 @@ void* maintThread()
   return 0;
 }
 
-struct {
-  string pub;
-  string sec;
-} g_accessKeys, g_serverKeys;
+string g_key;
 
 void controlClientThread(int fd, ComboAddress client)
 try
 {
+  SodiumNonce theirs;
+  readn2(fd, (char*)theirs.value, sizeof(theirs.value));
+  SodiumNonce ours;
+  ours.init();
+  writen2(fd, (char*)ours.value, sizeof(ours.value));
+
   for(;;) {
     uint16_t len;
-    getMsgLen(fd, &len);
+    if(!getMsgLen(fd, &len))
+      break;
     char msg[len];
     readn2(fd, msg, len);
     
     string line(msg, len);
-    line = sodDecrypt(line, g_accessKeys.pub, g_serverKeys.sec);
+    line = sodDecryptSym(line, g_key, theirs);
     //    cerr<<"Have decrypted line: "<<line<<endl;
     string response;
     try {
@@ -739,7 +743,7 @@ try
     catch(std::exception& e) {
       cerr<<"Error: "<<e.what()<<endl;
     }
-    response = sodEncrypt(response, g_serverKeys.sec, g_accessKeys.pub);
+    response = sodEncryptSym(response, g_key, ours);
     putMsgLen(fd, response.length());
     writen2(fd, response.c_str(), (uint16_t)response.length());
   }
@@ -937,31 +941,23 @@ void setupLua(bool client)
       g_abuseDSS=dss;
     });
 
-  g_lua.writeFunction("newKeypair", newKeypair);
-  g_lua.writeFunction("makeKeys", []() {
-      string server(newKeypair()), client(newKeypair());
-      return "serverKeys("+server+")\naccessKeys("+client+")";
+  g_lua.writeFunction("makeKey", []() {
+      return "setKey("+newKey()+")";
     });
   
-  g_lua.writeFunction("accessKeys", [](std::unordered_map<int, std::string> params) {
-      if(B64Decode(params[1], g_accessKeys.pub)) 
-       throw std::runtime_error("Unable to decode "+params[1]+" as Base64");
-      if(B64Decode(params[2], g_accessKeys.sec))
-       throw std::runtime_error("Unable to decode "+params[2]+" as Base64");
-    });
-
-  g_lua.writeFunction("serverKeys", [](std::unordered_map<int, std::string> params) {
-      if(B64Decode(params[1], g_serverKeys.pub))
-       throw std::runtime_error("Unable to decode "+params[1]+" as Base64");
-      if(B64Decode(params[2], g_serverKeys.sec))
-       throw std::runtime_error("Unable to decode "+params[2]+" as Base64");
+  g_lua.writeFunction("setKey", [](const std::string& key) {
+      if(B64Decode(key, g_key)) 
+       throw std::runtime_error("Unable to decode "+key+" as Base64");
     });
 
   
   g_lua.writeFunction("testCrypto", [](string testmsg)
    {
-     string encrypted = sodEncrypt(testmsg, g_accessKeys.sec, g_serverKeys.pub);
-     string decrypted = sodDecrypt(encrypted, g_accessKeys.pub, g_serverKeys.sec);
+     SodiumNonce sn, sn2;
+     sn.init();
+     sn2=sn;
+     string encrypted = sodEncryptSym(testmsg, g_key, sn);
+     string decrypted = sodDecryptSym(encrypted, g_key, sn2);
      
      if(testmsg == decrypted)
        cerr<<"Everything is ok!"<<endl;
@@ -982,6 +978,12 @@ void doClient(ComboAddress server)
   int fd=socket(server.sin4.sin_family, SOCK_STREAM, 0);
   SConnect(fd, server);
 
+  SodiumNonce theirs, ours;
+  ours.init();
+
+  writen2(fd, (const char*)ours.value, sizeof(ours.value));
+  readn2(fd, (char*)theirs.value, sizeof(theirs.value));
+
   set<string> dupper;
   {
     ifstream history(".history");
@@ -1009,7 +1011,7 @@ void doClient(ComboAddress server)
       break;
 
     string response;
-    string msg=sodEncrypt(line, g_accessKeys.sec, g_serverKeys.pub);
+    string msg=sodEncryptSym(line, g_key, ours);
     putMsgLen(fd, msg.length());
     writen2(fd, msg);
     uint16_t len;
@@ -1017,11 +1019,9 @@ void doClient(ComboAddress server)
     char resp[len];
     readn2(fd, resp, len);
     msg.assign(resp, len);
-    msg=sodDecrypt(msg, g_serverKeys.pub, g_accessKeys.sec);
+    msg=sodDecryptSym(msg, g_key, theirs);
     cout<<msg<<endl;
   }
-
-
 }
 
 void doConsole()
@@ -1076,8 +1076,7 @@ void doConsole()
     }
     catch(std::exception& e) {
       cerr<<"Error: "<<e.what()<<endl;
-    }
-   
+    }   
   }
 }
 
@@ -1140,7 +1139,6 @@ try
     vinfolog("Running in the foreground");
   }
 
-
   setupLua(false);
   if(g_vm.count("remotes")) {
     for(const auto& address : g_vm["remotes"].as<vector<string>>()) {
@@ -1150,8 +1148,6 @@ try
     }
   }
 
-  
-
   for(auto& dss : g_dstates) {
     if(dss->availability==DownstreamState::Availability::Auto) {
       bool newState=upCheck(dss->remote);
index 5c360494d9c31fa05f308be0c66fcbc8eac3326c..81737c78d666863a4102874e8abd7e305a407b4f 100644 (file)
@@ -1,7 +1,5 @@
-serverKeys({"oYhvA4N2a+PfWJ1aBVG3OFD/BBO/8sdkzRgGQoDxVz0=","2JjfJbIH/2g+1cIxj7IXhv4j38+rCiXbpdjtn91p/04="})
-accessKeys({"9RM9r+olHDJU+87hBXT9DCCej/DUS1XjIKWTq84AfTs=","ghv/LTqRTOgVvK8A/XEWrFks+F5fng1Wn14Xe9Rblgg="})
-
 controlSocket("0.0.0.0")
+setKey("MXNeLFWHUe4363BBKrY06cAsH8NWNb+Se2eXU5+Bb74=")
 
 -- define the good servers
 newServer("8.8.8.8", 2)  -- 2 qps
index f9c63a518452e1fbcb5101f74fc128aee5a8e15f..7c0c4f41313817cb10d0836a80bf05cb343930e3 100644 (file)
@@ -3,92 +3,35 @@
 #include "namespaces.hh"
 #include "misc.hh"
 #include "base64.hh"
+#include "sodcrypto.hh"
 
-string newKeypair()
-{
-  unsigned char alice_publickey[crypto_box_PUBLICKEYBYTES];
-  unsigned char alice_secretkey[crypto_box_SECRETKEYBYTES];
-  crypto_box_keypair(alice_publickey, alice_secretkey);
-  
-  string ret("{\"");
-  ret+=Base64Encode(string((char*)alice_publickey, crypto_box_PUBLICKEYBYTES));
-  ret+="\",\"";
-  ret+=Base64Encode(string((char*)alice_secretkey, crypto_box_SECRETKEYBYTES));
-  ret+="\"}";
-  return ret;
-}
 
-// return: nonce + ciphertext
-
-std::string sodEncrypt(const std::string& msg, const std::string& secretSource,
-                 const std::string& publicDest)
+string newKey()
 {
-  unsigned char nonce[crypto_box_NONCEBYTES];
-  unsigned char ciphertext[msg.length() + crypto_box_MACBYTES];
-  randombytes_buf(nonce, sizeof nonce);
-  /*
-  cerr<<"Encrypt plen: "<<msg.length()<<endl;
-  cerr<<"Encrypt nonce: "<<makeHexDump(string((const char*)nonce, sizeof nonce))<<endl;
-  cerr<<"keylen: "<<secretSource.length()<<", "<<publicDest.length()<<endl;
-  */
-  crypto_box_easy(ciphertext, (const unsigned char*)msg.c_str(), msg.length(), 
-                 nonce,  (const unsigned char*)publicDest.c_str(),   // bob_pub
-                 (const unsigned char*) secretSource.c_str());       // alice_sec
-  //  cerr<<"MAC: "<<makeHexDump(string((const char*)ciphertext, crypto_box_MACBYTES))<<endl;
-  string ret((const char*)nonce, crypto_box_NONCEBYTES);
-  ret.append((const char*)ciphertext, sizeof(ciphertext));
-  return ret;
+  unsigned char key[crypto_secretbox_KEYBYTES];
+  randombytes_buf(key, sizeof key);
+  return "\""+Base64Encode(string((char*)key, sizeof key))+"\"";
 }
 
-std::string sodDecrypt(const std::string& msg, const std::string& publicSource,
-                 const std::string& secretDest)
+std::string sodEncryptSym(const std::string& msg, const std::string& key, SodiumNonce& nonce)
 {
-  auto plen = msg.size() - crypto_box_NONCEBYTES - crypto_box_MACBYTES;
-  /*
-  cerr<<"Payload len: "<<plen<<endl;
-  cerr<<"Nonce: "<<makeHexDump(msg.substr(0, crypto_box_NONCEBYTES))<<endl;
-  cerr<<"MAC: "<<makeHexDump(msg.substr(crypto_box_NONCEBYTES, crypto_box_MACBYTES))<<endl;
-  cerr<<"keylen: "<<publicSource.length()<<", "<<secretDest.length()<<endl;
-  */
-  unsigned char decrypted[plen];
-  if (crypto_box_open_easy(decrypted, (const unsigned char*)msg.c_str() + crypto_box_NONCEBYTES, plen + crypto_box_MACBYTES, (const unsigned char*)msg.c_str(),
-                          (const unsigned char*)publicSource.c_str(),   // alice_pub
-                          (const unsigned char*)secretDest.c_str()) != 0) {  // bob_sec
-    /* message for Bob pretending to be from Alice has been forged! */
-    throw runtime_error("Could not decrypt!");
-  }
+  unsigned char ciphertext[msg.length() + crypto_secretbox_MACBYTES];
+  crypto_secretbox_easy(ciphertext, (unsigned char*)msg.c_str(), msg.length(), nonce.value, (unsigned char*)key.c_str());
 
-  return string((char*)decrypted, plen);
+  nonce.increment();
+  return string((char*)ciphertext, sizeof(ciphertext));
 }
 
-
-void sodTest()
+std::string sodDecryptSym(const std::string& msg, const std::string& key, SodiumNonce& nonce)
 {
-#define MESSAGE (const unsigned char *) "test"
-#define MESSAGE_LEN 4
-#define CIPHERTEXT_LEN (crypto_box_MACBYTES + MESSAGE_LEN)
+  unsigned char decrypted[msg.length() - crypto_secretbox_MACBYTES];
 
-  unsigned char alice_publickey[crypto_box_PUBLICKEYBYTES];
-  unsigned char alice_secretkey[crypto_box_SECRETKEYBYTES];
-  crypto_box_keypair(alice_publickey, alice_secretkey);
-  
-  unsigned char bob_publickey[crypto_box_PUBLICKEYBYTES];
-  unsigned char bob_secretkey[crypto_box_SECRETKEYBYTES];
-  crypto_box_keypair(bob_publickey, bob_secretkey);
-  
-  unsigned char nonce[crypto_box_NONCEBYTES];
-  unsigned char ciphertext[CIPHERTEXT_LEN];
-  randombytes_buf(nonce, sizeof nonce);
-  crypto_box_easy(ciphertext, MESSAGE, MESSAGE_LEN, nonce,
-                 bob_publickey, alice_secretkey);
-  
-  unsigned char decrypted[MESSAGE_LEN];
-  if (crypto_box_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce,
-                          alice_publickey, bob_secretkey) != 0) {
-    /* message for Bob pretending to be from Alice has been forged! */
-    cerr<<"BAD!"<<endl;
+  if (crypto_secretbox_open_easy(decrypted, (const unsigned char*)msg.c_str(), 
+                                msg.length(), nonce.value, (const unsigned char*)key.c_str()) != 0) {
+    throw std::runtime_error("Could not decrypt message");
   }
-  else 
-    cerr<<"Decrypted: "<<string((char*)decrypted, MESSAGE_LEN)<<endl;
+  nonce.increment();
+  return string((char*)decrypted, sizeof(decrypted));
 }
+
+
index e314c663aa94c77c1beb415be4ee8a62734c6a15..64ed46e368fdc357db5e186210b1ad1553e7d692 100644 (file)
@@ -1,14 +1,40 @@
 #pragma once
 #include <string>
+#include <stdint.h>
 
 void sodTest();
 std::string newKeypair();
 
-std::string sodEncrypt(const std::string& msg, const std::string& secretSource,
+std::string sodEncryptAsym(const std::string& msg, const std::string& secretSource,
                       const std::string& publicDest);
 
 
-std::string sodDecrypt(const std::string& msg, const std::string& publicSource,
+std::string sodDecryptAsym(const std::string& msg, const std::string& publicSource,
                       const std::string& secretDest);
 
 
+
+struct SodiumNonce
+{
+  void init()
+  {
+    randombytes_buf(value, sizeof value);
+  }
+  
+  void increment()
+  {
+    uint64_t* p = (uint64_t*)value;
+    (*p)++;
+  }
+
+  string toString() const
+  {
+    return string((const char*)value, crypto_secretbox_NONCEBYTES);
+  }
+
+  unsigned char value[crypto_secretbox_NONCEBYTES];
+};
+
+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 newKey();