From 7ec83fa56f3d3257a9e9a42ffee041ae4aeec1f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com>
Date: Tue, 25 May 2021 14:23:10 -0400
Subject: [PATCH] dhtrunner: add putEncrypted with long ID or pulic key

---
 include/opendht/dhtrunner.h | 21 +++++++++++++++
 include/opendht/securedht.h |  8 ++++++
 src/dhtrunner.cpp           | 49 +++++++++++++++++++++++++++++++++++
 src/securedht.cpp           | 51 ++++++++++++++++++++++++++++++++++---
 4 files changed, 126 insertions(+), 3 deletions(-)

diff --git a/include/opendht/dhtrunner.h b/include/opendht/dhtrunner.h
index b4511797..84765d38 100644
--- a/include/opendht/dhtrunner.h
+++ b/include/opendht/dhtrunner.h
@@ -258,6 +258,27 @@ public:
     }
     void putEncrypted(const std::string& key, InfoHash to, Value&& value, DoneCallback cb={}, bool permanent = false);
 
+    void putEncrypted(InfoHash hash, PkId to, std::shared_ptr<Value> value, DoneCallback cb={}, bool permanent = false);
+    void putEncrypted(InfoHash hash, PkId to, std::shared_ptr<Value> value, DoneCallbackSimple cb, bool permanent = false) {
+        putEncrypted(hash, to, value, bindDoneCb(cb), permanent);
+    }
+
+    void putEncrypted(InfoHash hash, PkId to, Value&& value, DoneCallback cb={}, bool permanent = false);
+    void putEncrypted(InfoHash hash, PkId to, Value&& value, DoneCallbackSimple cb, bool permanent = false) {
+        putEncrypted(hash, to, std::forward<Value>(value), bindDoneCb(cb), permanent);
+    }
+
+    void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, std::shared_ptr<Value> value, DoneCallback cb={}, bool permanent = false);
+    void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, std::shared_ptr<Value> value, DoneCallbackSimple cb, bool permanent = false) {
+        putEncrypted(hash, to, value, bindDoneCb(cb), permanent);
+    }
+
+    void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, Value&& value, DoneCallback cb={}, bool permanent = false);
+    void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, Value&& value, DoneCallbackSimple cb, bool permanent = false) {
+        putEncrypted(hash, to, std::forward<Value>(value), bindDoneCb(cb), permanent);
+    }
+
+
     /**
      * Insert known nodes to the routing table, without necessarly ping them.
      * Usefull to restart a node and get things running fast without putting load on the network.
diff --git a/include/opendht/securedht.h b/include/opendht/securedht.h
index 7cffdcf8..70a5863b 100644
--- a/include/opendht/securedht.h
+++ b/include/opendht/securedht.h
@@ -115,6 +115,14 @@ public:
     void putEncrypted(const InfoHash& hash, const InfoHash& to, Value&& v, DoneCallback callback, bool permanent = false) {
         putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
     }
+    void putEncrypted(const InfoHash& hash, const PkId& to, Sp<Value> val, DoneCallback callback, bool permanent = false);
+    void putEncrypted(const InfoHash& hash, const PkId& to, Value&& v, DoneCallback callback, bool permanent = false) {
+        putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
+    }
+    void putEncrypted(const InfoHash& hash, const crypto::PublicKey& to, Sp<Value> val, DoneCallback callback, bool permanent = false);
+    void putEncrypted(const InfoHash& hash, const crypto::PublicKey& to, Value&& v, DoneCallback callback, bool permanent = false) {
+        putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
+    }
 
     /**
      * Take ownership of the value and sign it using our private key.
diff --git a/src/dhtrunner.cpp b/src/dhtrunner.cpp
index 6c948fe1..a1c4f8de 100644
--- a/src/dhtrunner.cpp
+++ b/src/dhtrunner.cpp
@@ -954,6 +954,55 @@ DhtRunner::putEncrypted(const std::string& key, InfoHash to, Value&& value, Done
     putEncrypted(InfoHash::get(key), to, std::forward<Value>(value), std::move(cb), permanent);
 }
 
+
+void
+DhtRunner::putEncrypted(InfoHash hash, PkId to, std::shared_ptr<Value> value, DoneCallback cb, bool permanent)
+{
+    if (running != State::Running) {
+        if (cb) cb(false, {});
+        return;
+    }
+    std::lock_guard<std::mutex> lck(storage_mtx);
+    ongoing_ops++;
+    pending_ops.emplace([=,
+        cb = std::move(cb),
+        value = std::move(value)
+    ] (SecureDht& dht) mutable {
+        dht.putEncrypted(hash, to, value, bindOpDoneCallback(std::move(cb)), permanent);
+    });
+    cv.notify_all();
+}
+
+void
+DhtRunner::putEncrypted(InfoHash hash, PkId to, Value&& value, DoneCallback cb, bool permanent)
+{
+    putEncrypted(hash, to, std::make_shared<Value>(std::move(value)), std::move(cb), permanent);
+}
+
+void
+DhtRunner::putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, std::shared_ptr<Value> value, DoneCallback cb, bool permanent)
+{
+    if (running != State::Running) {
+        if (cb) cb(false, {});
+        return;
+    }
+    std::lock_guard<std::mutex> lck(storage_mtx);
+    ongoing_ops++;
+    pending_ops.emplace([=,
+        cb = std::move(cb),
+        value = std::move(value)
+    ] (SecureDht& dht) mutable {
+        dht.putEncrypted(hash, *to, value, bindOpDoneCallback(std::move(cb)), permanent);
+    });
+    cv.notify_all();
+}
+
+void
+DhtRunner::putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, Value&& value, DoneCallback cb, bool permanent)
+{
+    putEncrypted(hash, to, std::make_shared<Value>(std::move(value)), std::move(cb), permanent);
+}
+
 void
 DhtRunner::bootstrap(const std::string& host, const std::string& service)
 {
diff --git a/src/securedht.cpp b/src/securedht.cpp
index b044ae6e..8dafbc49 100644
--- a/src/securedht.cpp
+++ b/src/securedht.cpp
@@ -200,8 +200,6 @@ SecureDht::findCertificate(const InfoHash& node, const std::function<void(const
 
     auto found = std::make_shared<bool>(false);
     dht_->get(node, [cb,node,found,this](const std::vector<Sp<Value>>& vals) {
-        if (*found)
-            return false;
         for (const auto& v : vals) {
             if (auto cert = registerCertificate(node, v->data)) {
                 *found = true;
@@ -212,7 +210,7 @@ SecureDht::findCertificate(const InfoHash& node, const std::function<void(const
                 return false;
             }
         }
-        return true;
+        return !*found;
     }, [cb,found](bool) {
         if (!*found and cb)
             cb(nullptr);
@@ -529,6 +527,53 @@ SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, Sp<Value> val,
     });
 }
 
+void
+SecureDht::putEncrypted(const InfoHash& hash, const PkId& to, Sp<Value> val, DoneCallback callback, bool permanent)
+{
+    if (not key_)  {
+        if (callback)
+            callback(false, {});
+        return;
+    }
+    findPublicKey(to, [this, hash, val = std::move(val), callback = std::move(callback), permanent](const Sp<crypto::PublicKey>& pk) {
+        if(!pk || !*pk) {
+            if (callback)
+                callback(false, {});
+            return;
+        }
+        if (logger_)
+            logger_->w("Encrypting data for PK: %s", pk->getLongId().toString().c_str());
+        try {
+            dht_->put(hash, encrypt(*val, *pk), callback, time_point::max(), permanent);
+        } catch (const std::exception& e) {
+            if (logger_)
+                logger_->e("Error putting encrypted data: %s", e.what());
+            if (callback)
+                callback(false, {});
+        }
+    });
+}
+
+void
+SecureDht::putEncrypted(const InfoHash& hash, const crypto::PublicKey& pk, Sp<Value> val, DoneCallback callback, bool permanent)
+{
+    if (not key_)  {
+        if (callback)
+            callback(false, {});
+        return;
+    }
+    if (logger_)
+        logger_->w("Encrypting data for PK: %s", pk.getLongId().to_c_str());
+    try {
+        dht_->put(hash, encrypt(*val, pk), callback, time_point::max(), permanent);
+    } catch (const std::exception& e) {
+        if (logger_)
+            logger_->e("Error putting encrypted data: %s", e.what());
+        if (callback)
+            callback(false, {});
+    }
+}
+
 void
 SecureDht::sign(Value& v) const
 {
-- 
GitLab