diff --git a/include/opendht/default_types.h b/include/opendht/default_types.h index a3e8ce4cbf13cf0cecf7904a61bf8d162dd1cfcc..ea0f6a155c641218f0167612beab7dd5b3242ff6 100644 --- a/include/opendht/default_types.h +++ b/include/opendht/default_types.h @@ -66,7 +66,8 @@ private: public: virtual void unpackValue(const Value& v) override { - from = v.owner.getId(); + if (v.owner) + from = v.owner->getId(); BaseClass::unpackValue(v); } diff --git a/include/opendht/value.h b/include/opendht/value.h index a3f34dc54e5d0d7d35562d4e69b8201781c36015..fa903a05196a284401606637d5927d250808cd49 100644 --- a/include/opendht/value.h +++ b/include/opendht/value.h @@ -255,7 +255,7 @@ struct Value return not cypher.empty(); } bool isSigned() const { - return not signature.empty(); + return owner and not signature.empty(); } Value() {} @@ -301,7 +301,7 @@ struct Value inline bool operator== (const Value& o) { return id == o.id && (isEncrypted() ? cypher == o.cypher : - (owner == o.owner && type == o.type && data == o.data && user_type == o.user_type && signature == o.signature)); + ((owner == o.owner || *owner == *o.owner) && type == o.type && data == o.data && user_type == o.user_type && signature == o.signature)); } void setRecipient(const InfoHash& r) { @@ -347,10 +347,11 @@ struct Value template <typename Packer> void msgpack_pack_to_sign(Packer& pk) const { - pk.pack_map((user_type.empty()?0:1) + (owner?(recipient == InfoHash() ? 4 : 5):2)); - if (owner) { // isSigned + bool has_owner = owner && *owner; + pk.pack_map((user_type.empty()?0:1) + (has_owner?(recipient == InfoHash() ? 4 : 5):2)); + if (has_owner) { // isSigned pk.pack(std::string("seq")); pk.pack(seq); - pk.pack(std::string("owner")); owner.msgpack_pack(pk); + pk.pack(std::string("owner")); owner->msgpack_pack(pk); if (recipient != InfoHash()) { pk.pack(std::string("to")); pk.pack(recipient); } @@ -395,7 +396,7 @@ struct Value /** * Public key of the signer. */ - crypto::PublicKey owner {}; + std::shared_ptr<crypto::PublicKey> owner {}; /** * Hash of the recipient (optional). diff --git a/src/securedht.cpp b/src/securedht.cpp index 39b343c2369f68c12ccfb5a451c1725f2ed57c72..9ace496b6c2199f19b46cf686c10a3d67b088546 100644 --- a/src/securedht.cpp +++ b/src/securedht.cpp @@ -94,7 +94,7 @@ SecureDht::secureType(ValueType&& type) { type.storePolicy = [this,type](InfoHash id, std::shared_ptr<Value>& v, InfoHash nid, const sockaddr* a, socklen_t al) { if (v->isSigned()) { - if (!v->owner.checkSignature(v->getToSign(), v->signature)) { + if (!v->owner or !v->owner->checkSignature(v->getToSign(), v->signature)) { DHT_LOG.WARN("Signature verification failed"); return false; } @@ -110,7 +110,7 @@ SecureDht::secureType(ValueType&& type) DHT_LOG.WARN("Edition forbidden: owner changed."); return false; } - if (!o->owner.checkSignature(n->getToSign(), n->signature)) { + if (!o->owner or !o->owner->checkSignature(n->getToSign(), n->signature)) { DHT_LOG.WARN("Edition forbidden: signature verification failed."); return false; } @@ -152,7 +152,7 @@ SecureDht::registerCertificate(const InfoHash& node, const Blob& data) } InfoHash h = crt->getPublicKey().getId(); if (node == h) { - DHT_LOG.DEBUG("Registering public key for %s", h.toString().c_str()); + DHT_LOG.DEBUG("Registering certificate for %s", h.toString().c_str()); auto it = nodesCertificates_.find(h); if (it == nodesCertificates_.end()) std::tie(it, std::ignore) = nodesCertificates_.emplace(h, std::move(crt)); @@ -177,7 +177,7 @@ SecureDht::findCertificate(const InfoHash& node, std::function<void(const std::s { std::shared_ptr<crypto::Certificate> b = getCertificate(node); if (b && *b) { - DHT_LOG.DEBUG("Using public key from cache for %s", node.toString().c_str()); + DHT_LOG.DEBUG("Using certificate from cache for %s", node.toString().c_str()); if (cb) cb(b); return; @@ -185,7 +185,7 @@ SecureDht::findCertificate(const InfoHash& node, std::function<void(const std::s if (localQueryMethod_) { auto res = localQueryMethod_(node); if (not res.empty()) { - DHT_LOG.DEBUG("Registering public key from local store for %s", node.toString().c_str()); + DHT_LOG.DEBUG("Registering certificate from local store for %s", node.toString().c_str()); nodesCertificates_.emplace(node, res.front()); if (cb) cb(res.front()); @@ -200,7 +200,7 @@ SecureDht::findCertificate(const InfoHash& node, std::function<void(const std::s for (const auto& v : vals) { if (auto cert = registerCertificate(node, v->data)) { *found = true; - DHT_LOG.DEBUG("Found public key for %s", node.toString().c_str()); + DHT_LOG.DEBUG("Found certificate for %s", node.toString().c_str()); if (cb) cb(cert); return false; @@ -237,7 +237,7 @@ SecureDht::getCallbackFilter(GetCallback cb, Value::Filter&& filter) } // Check signed values else if (v->isSigned()) { - if (v->owner.checkSignature(v->getToSign(), v->signature)) { + if (v->owner and v->owner->checkSignature(v->getToSign(), v->signature)) { if (not filter or filter(*v)) tmpvals.push_back(v); } @@ -290,7 +290,7 @@ SecureDht::putSigned(const InfoHash& hash, std::shared_ptr<Value> val, DoneCallb for (const auto& v : vals) { if (!v->isSigned()) DHT_LOG.ERROR("Existing non-signed value seems to exists at this location."); - else if (v->owner.getId() != getId()) + else if (not v->owner or v->owner->getId() != getId()) DHT_LOG.ERROR("Existing signed value belonging to someone else seems to exists at this location."); else if (val->seq <= v->seq) val->seq = v->seq + 1; @@ -330,7 +330,7 @@ SecureDht::sign(Value& v) const { if (v.isEncrypted()) throw DhtException("Can't sign encrypted data."); - v.owner = key_->getPublicKey(); + v.owner = std::make_shared<crypto::PublicKey>(key_->getPublicKey()); v.signature = key_->sign(v.getToSign()); } @@ -360,7 +360,7 @@ SecureDht::decrypt(const Value& v) if (ret.recipient != getId()) throw crypto::DecryptError("Recipient mismatch"); - if (not ret.owner.checkSignature(ret.getToSign(), ret.signature)) + if (not ret.owner or not ret.owner->checkSignature(ret.getToSign(), ret.signature)) throw crypto::DecryptError("Signature mismatch"); return ret; diff --git a/src/value.cpp b/src/value.cpp index 6431678a06cf90dcde76443090857a43131df249..a2c4d1e6e12c48910b533a2a981d726c6681e972 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -142,7 +142,8 @@ Value::msgpack_unpack_body(const msgpack::object& o) seq = rseq->as<decltype(seq)>(); else throw msgpack::type_error(); - owner.msgpack_unpack(*rowner); + owner = std::make_shared<crypto::PublicKey>(); + owner->msgpack_unpack(*rowner); if (auto rrecipient = findMapValue(*rbody, "to")) { recipient = rrecipient->as<InfoHash>(); }