My Project 2.4.4
C++ Distributed Hash Table
Loading...
Searching...
No Matches
securedht.h
1/*
2 * Copyright (C) 2014-2022 Savoir-faire Linux Inc.
3 * Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
4 * Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
5 * Sébastien Blin <sebastien.blin@savoirfairelinux.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#pragma once
22
23#include "dht.h"
24#include "crypto.h"
25
26#include <map>
27#include <vector>
28#include <memory>
29#include <random>
30
31namespace dht {
32
33class OPENDHT_PUBLIC SecureDht final : public DhtInterface {
34public:
35
36 typedef std::function<void(bool)> SignatureCheckCallback;
37
38 using Config = SecureDhtConfig;
39
40 static dht::Config getConfig(const SecureDht::Config& conf)
41 {
42 auto c = conf.node_config;
43 if (not c.node_id and conf.id.second)
44 c.node_id = InfoHash::get("node:"+conf.id.second->getId().toString());
45 return c;
46 }
47
54 SecureDht(std::unique_ptr<DhtInterface> dht, Config config, IdentityAnnouncedCb iacb = {}, const std::shared_ptr<Logger>& l = {});
55
56 virtual ~SecureDht();
57
58 InfoHash getId() const {
59 return key_ ? key_->getPublicKey().getId() : InfoHash();
60 }
61 PkId getLongId() const {
62 return key_ ? key_->getPublicKey().getLongId() : PkId();
63 }
64 Sp<crypto::PublicKey> getPublicKey() const {
65 return key_ ? key_->getSharedPublicKey() : Sp<crypto::PublicKey>{};
66 }
67
68 ValueType secureType(ValueType&& type);
69
70 ValueType secureType(const ValueType& type) {
71 ValueType tmp_type = type;
72 return secureType(std::move(tmp_type));
73 }
74
75 void registerType(const ValueType& type) override {
76 if (dht_)
77 dht_->registerType(secureType(type));
78 }
79 void registerType(ValueType&& type) {
80 if (dht_)
81 dht_->registerType(secureType(std::forward<ValueType>(type)));
82 }
83 void registerInsecureType(const ValueType& type) {
84 if (dht_)
85 dht_->registerType(type);
86 }
87
93 void get(const InfoHash& id, GetCallback cb, DoneCallback donecb={}, Value::Filter&& = {}, Where&& w = {}) override;
94 void get(const InfoHash& id, GetCallback cb, DoneCallbackSimple donecb={}, Value::Filter&& f = {}, Where&& w = {}) override {
95 get(id, cb, bindDoneCb(donecb), std::forward<Value::Filter>(f), std::forward<Where>(w));
96 }
97 void get(const InfoHash& key, GetCallbackSimple cb, DoneCallback donecb={}, Value::Filter&& f={}, Where&& w = {}) override {
98 get(key, bindGetCb(cb), donecb, std::forward<Value::Filter>(f), std::forward<Where>(w));
99 }
100 void get(const InfoHash& key, GetCallbackSimple cb, DoneCallbackSimple donecb, Value::Filter&& f={}, Where&& w = {}) override {
101 get(key, bindGetCb(cb), bindDoneCb(donecb), std::forward<Value::Filter>(f), std::forward<Where>(w));
102 }
103
107 void putSigned(const InfoHash& hash, Sp<Value> val, DoneCallback callback, bool permanent = false);
108 void putSigned(const InfoHash& hash, Value&& v, DoneCallback callback, bool permanent = false) {
109 putSigned(hash, std::make_shared<Value>(std::move(v)), callback, permanent);
110 }
111
117 void putEncrypted(const InfoHash& hash, const InfoHash& to, Sp<Value> val, DoneCallback callback, bool permanent = false);
118 void putEncrypted(const InfoHash& hash, const InfoHash& to, Value&& v, DoneCallback callback, bool permanent = false) {
119 putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
120 }
121 void putEncrypted(const InfoHash& hash, const crypto::PublicKey& to, Sp<Value> val, DoneCallback callback, bool permanent = false);
122 void putEncrypted(const InfoHash& hash, const crypto::PublicKey& to, Value&& v, DoneCallback callback, bool permanent = false) {
123 putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
124 }
125
129 void sign(Value& v) const;
130
131 Value encrypt(Value& v, const crypto::PublicKey& to) const;
132
133 Value decrypt(const Value& v);
134
135 void findCertificate(const InfoHash& node, const std::function<void(const Sp<crypto::Certificate>)>& cb);
136 void findPublicKey(const InfoHash& node, const std::function<void(const Sp<crypto::PublicKey>)>& cb);
137
138 Sp<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
139 void registerCertificate(Sp<crypto::Certificate>& cert);
140
141 Sp<crypto::Certificate> getCertificate(const InfoHash& node) const;
142 Sp<crypto::PublicKey> getPublicKey(const InfoHash& node) const;
143
149 void setLocalCertificateStore(CertificateStoreQuery&& query_method) {
150 localQueryMethod_ = std::move(query_method);
151 }
152
156 void shutdown(ShutdownCallback cb, bool stop = false) override {
157 dht_->shutdown(cb, stop);
158 }
159 void dumpTables() const override {
160 dht_->dumpTables();
161 }
162 inline const InfoHash& getNodeId() const override { return dht_->getNodeId(); }
163
164 std::pair<size_t, size_t> getStoreSize() const override {
165 return dht_->getStoreSize();
166 }
167 std::string getStorageLog() const override {
168 return dht_->getStorageLog();
169 }
170 std::string getStorageLog(const InfoHash& h) const override {
171 return dht_->getStorageLog(h);
172 }
173 void setStorageLimit(size_t limit = DEFAULT_STORAGE_LIMIT) override {
174 dht_->setStorageLimit(limit);
175 }
176 size_t getStorageLimit() const override {
177 return dht_->getStorageLimit();
178 }
179
180 std::vector<NodeExport> exportNodes() const override {
181 return dht_->exportNodes();
182 }
183 std::vector<ValuesExport> exportValues() const override {
184 return dht_->exportValues();
185 }
186 void importValues(const std::vector<ValuesExport>& v) override {
187 dht_->importValues(v);
188 }
189 NodeStats getNodesStats(sa_family_t af) const override {
190 return dht_->getNodesStats(af);
191 }
192 std::vector<unsigned> getNodeMessageStats(bool in = false) override {
193 return dht_->getNodeMessageStats(in);
194 }
195 std::string getRoutingTablesLog(sa_family_t af) const override {
196 return dht_->getRoutingTablesLog(af);
197 }
198 std::string getSearchesLog(sa_family_t af) const override {
199 return dht_->getSearchesLog(af);
200 }
201 std::string getSearchLog(const InfoHash& h, sa_family_t af = AF_UNSPEC) const override {
202 return dht_->getSearchLog(h, af);
203 }
204 std::vector<SockAddr> getPublicAddress(sa_family_t family = 0) override {
205 return dht_->getPublicAddress(family);
206 }
207 time_point periodic(const uint8_t *buf, size_t buflen, SockAddr sa, const time_point& now) override {
208 return dht_->periodic(buf, buflen, std::move(sa), now);
209 }
210 time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen, const time_point& now) override {
211 return dht_->periodic(buf, buflen, from, fromlen, now);
212 }
213 NodeStatus updateStatus(sa_family_t af) override {
214 return dht_->updateStatus(af);
215 }
216 NodeStatus getStatus(sa_family_t af) const override {
217 return dht_->getStatus(af);
218 }
219 NodeStatus getStatus() const override {
220 return dht_->getStatus();
221 }
222 net::DatagramSocket* getSocket() const override {
223 return dht_->getSocket();
224 };
225 bool isRunning(sa_family_t af = 0) const override {
226 return dht_->isRunning(af);
227 }
228 const ValueType& getType(ValueType::Id type_id) const override {
229 return dht_->getType(type_id);
230 }
231 void addBootstrap(const std::string& host, const std::string& service) override {
232 dht_->addBootstrap(host, service);
233 }
234 void clearBootstrap() override {
235 dht_->clearBootstrap();
236 }
237 void insertNode(const InfoHash& id, const SockAddr& sa) override {
238 dht_->insertNode(id, sa);
239 }
240 void insertNode(const NodeExport& n) override {
241 dht_->insertNode(n);
242 }
243 void pingNode(SockAddr sa, DoneCallbackSimple&& cb={}) override {
244 dht_->pingNode(std::move(sa), std::move(cb));
245 }
246 void query(const InfoHash& key, QueryCallback cb, DoneCallback done_cb = {}, Query&& q = {}) override {
247 dht_->query(key, cb, done_cb, std::move(q));
248 }
249 void query(const InfoHash& key, QueryCallback cb, DoneCallbackSimple done_cb = {}, Query&& q = {}) override {
250 dht_->query(key, cb, done_cb, std::move(q));
251 }
252 std::vector<Sp<Value>> getLocal(const InfoHash& key, const Value::Filter& f = {}) const override {
253 return dht_->getLocal(key, f);
254 }
255 Sp<Value> getLocalById(const InfoHash& key, Value::Id vid) const override {
256 return dht_->getLocalById(key, vid);
257 }
258 void put(const InfoHash& key,
259 Sp<Value> v,
260 DoneCallback cb=nullptr,
261 time_point created=time_point::max(),
262 bool permanent = false) override
263 {
264 dht_->put(key, v, cb, created, permanent);
265 }
266 void put(const InfoHash& key,
267 const Sp<Value>& v,
268 DoneCallbackSimple cb,
269 time_point created=time_point::max(),
270 bool permanent = false) override
271 {
272 dht_->put(key, v, cb, created, permanent);
273 }
274
275 void put(const InfoHash& key,
276 Value&& v,
277 DoneCallback cb=nullptr,
278 time_point created=time_point::max(),
279 bool permanent = false) override
280 {
281 dht_->put(key, std::move(v), cb, created, permanent);
282 }
283 void put(const InfoHash& key,
284 Value&& v,
285 DoneCallbackSimple cb,
286 time_point created=time_point::max(),
287 bool permanent = false) override
288 {
289 dht_->put(key, std::move(v), cb, created, permanent);
290 }
291 std::vector<Sp<Value>> getPut(const InfoHash& h) const override {
292 return dht_->getPut(h);
293 }
294 Sp<Value> getPut(const InfoHash& h, const Value::Id& vid) const override {
295 return dht_->getPut(h, vid);
296 }
297 bool cancelPut(const InfoHash& h, const Value::Id& vid) override {
298 return dht_->cancelPut(h, vid);
299 }
300
301 size_t listen(const InfoHash& key, ValueCallback, Value::Filter={}, Where={}) override;
302 size_t listen(const InfoHash& key, GetCallback cb, Value::Filter = {}, Where w = {}) override;
303 size_t listen(const InfoHash& key, GetCallbackSimple cb, Value::Filter f={}, Where w = {}) override {
304 return listen(key, bindGetCb(cb), f, w);
305 }
306 bool cancelListen(const InfoHash& h, size_t token) override {
307 return dht_->cancelListen(h, token);
308 }
309 void connectivityChanged(sa_family_t af) override {
310 dht_->connectivityChanged(af);
311 }
312 void connectivityChanged() override {
313 dht_->connectivityChanged();
314 }
315
316 void forwardAllMessages(bool forward) {
317 forward_all_ = forward;
318 }
319
320 void setPushNotificationToken(const std::string& token = "") override {
321 dht_->setPushNotificationToken(token);
322 }
323
328 void pushNotificationReceived(const std::map<std::string, std::string>& notification) override {
329 dht_->pushNotificationReceived(notification);
330 }
331
332 void setLogger(const Logger& logger) override {
333 DhtInterface::setLogger(logger);
334 dht_->setLogger(logger);
335 }
336
337 void setLogger(const std::shared_ptr<Logger>& logger) override {
338 DhtInterface::setLogger(logger);
339 dht_->setLogger(logger);
340 }
341
345 void setLogFilter(const InfoHash& f) override {
346 DhtInterface::setLogFilter(f);
347 dht_->setLogFilter(f);
348 }
349
350private:
351 std::unique_ptr<DhtInterface> dht_;
352 // prevent copy
353 SecureDht(const SecureDht&) = delete;
354 SecureDht& operator=(const SecureDht&) = delete;
355
356 Sp<Value> checkValue(const Sp<Value>& v);
357 ValueCallback getCallbackFilter(const ValueCallback&, Value::Filter&&);
358 GetCallback getCallbackFilter(const GetCallback&, Value::Filter&&);
359
360 Sp<crypto::PrivateKey> key_ {};
361 Sp<crypto::Certificate> certificate_ {};
362
363 // method to query the local certificate store
364 CertificateStoreQuery localQueryMethod_ {};
365
366 // our certificate cache
367 std::map<InfoHash, Sp<crypto::Certificate>> nodesCertificates_ {};
368 std::map<InfoHash, Sp<crypto::PublicKey>> nodesPubKeys_ {};
369
370 std::atomic_bool forward_all_ {false};
371 bool enableCache_ {false};
372};
373
374const ValueType CERTIFICATE_TYPE = {
375 8, "Certificate", std::chrono::hours(24 * 7),
376 // A certificate can only be stored at its public key ID.
377 [](InfoHash id, Sp<Value>& v, const InfoHash&, const SockAddr&) {
378 try {
379 crypto::Certificate crt(v->data);
380 // TODO check certificate signature
381 return crt.getPublicKey().getId() == id;
382 } catch (const std::exception& e) {}
383 return false;
384 },
385 [](InfoHash, const Sp<Value>& o, Sp<Value>& n, const InfoHash&, const SockAddr&) {
386 try {
387 return crypto::Certificate(o->data).getPublicKey().getId() == crypto::Certificate(n->data).getPublicKey().getId();
388 } catch (const std::exception& e) {}
389 return false;
390 }
391};
392
393}
void putSigned(const InfoHash &hash, Sp< Value > val, DoneCallback callback, bool permanent=false)
size_t listen(const InfoHash &key, GetCallback cb, Value::Filter={}, Where w={}) override
bool isRunning(sa_family_t af=0) const override
Definition: securedht.h:225
void insertNode(const InfoHash &id, const SockAddr &sa) override
Definition: securedht.h:237
void query(const InfoHash &key, QueryCallback cb, DoneCallback done_cb={}, Query &&q={}) override
Definition: securedht.h:246
void get(const InfoHash &id, GetCallback cb, DoneCallback donecb={}, Value::Filter &&={}, Where &&w={}) override
void sign(Value &v) const
SecureDht(std::unique_ptr< DhtInterface > dht, Config config, IdentityAnnouncedCb iacb={}, const std::shared_ptr< Logger > &l={})
void setLogFilter(const InfoHash &f) override
Definition: securedht.h:345
void shutdown(ShutdownCallback cb, bool stop=false) override
Definition: securedht.h:156
std::vector< NodeExport > exportNodes() const override
Definition: securedht.h:180
std::vector< Sp< Value > > getLocal(const InfoHash &key, const Value::Filter &f={}) const override
Definition: securedht.h:252
void pushNotificationReceived(const std::map< std::string, std::string > &notification) override
Definition: securedht.h:328
bool cancelPut(const InfoHash &h, const Value::Id &vid) override
Definition: securedht.h:297
std::vector< Sp< Value > > getPut(const InfoHash &h) const override
Definition: securedht.h:291
void put(const InfoHash &key, Sp< Value > v, DoneCallback cb=nullptr, time_point created=time_point::max(), bool permanent=false) override
Definition: securedht.h:258
std::pair< size_t, size_t > getStoreSize() const override
Definition: securedht.h:164
Sp< Value > getLocalById(const InfoHash &key, Value::Id vid) const override
Definition: securedht.h:255
void setStorageLimit(size_t limit=DEFAULT_STORAGE_LIMIT) override
Definition: securedht.h:173
Sp< Value > getPut(const InfoHash &h, const Value::Id &vid) const override
Definition: securedht.h:294
void putEncrypted(const InfoHash &hash, const InfoHash &to, Sp< Value > val, DoneCallback callback, bool permanent=false)
const InfoHash & getNodeId() const override
Definition: securedht.h:162
NodeStatus updateStatus(sa_family_t af) override
Definition: securedht.h:213
void setLocalCertificateStore(CertificateStoreQuery &&query_method)
Definition: securedht.h:149
void connectivityChanged(sa_family_t af) override
Definition: securedht.h:309
Definition: callbacks.h:35
std::vector< uint8_t > Blob
Definition: utils.h:151
NodeStatus
Definition: callbacks.h:42
InfoHash node_id
Definition: callbacks.h:107
Describes a query destined to another peer.
Definition: value.h:925
Serializable dht::Value filter.
Definition: value.h:801