From 426c6b6e6d328112a28059790c92722f152753b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com> Date: Tue, 14 Jun 2016 18:13:02 -0400 Subject: [PATCH] value: add common crypto ops --- include/opendht/securedht.h | 9 +++----- include/opendht/value.h | 45 ++++++++++++++++++++++++++++++++++++- src/securedht.cpp | 19 +++++----------- src/value.cpp | 5 +++-- 4 files changed, 55 insertions(+), 23 deletions(-) diff --git a/include/opendht/securedht.h b/include/opendht/securedht.h index a41ecf26..d5b5e6d0 100644 --- a/include/opendht/securedht.h +++ b/include/opendht/securedht.h @@ -126,16 +126,13 @@ public: Value decrypt(const Value& v); void findCertificate(const InfoHash& node, std::function<void(const std::shared_ptr<crypto::Certificate>)> cb); - void findPublicKey(const InfoHash& node, std::function<void(const std::shared_ptr<crypto::PublicKey>)> cb); + void findPublicKey(const InfoHash& node, std::function<void(const std::shared_ptr<const crypto::PublicKey>)> cb); const std::shared_ptr<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert); void registerCertificate(std::shared_ptr<crypto::Certificate>& cert); const std::shared_ptr<crypto::Certificate> getCertificate(const InfoHash& node) const; - const std::shared_ptr<crypto::PublicKey> getPublicKey(const InfoHash& node) const; - - - + const std::shared_ptr<const crypto::PublicKey> getPublicKey(const InfoHash& node) const; /** * Allows to set a custom callback called by the library to find a locally-stored certificate. @@ -161,7 +158,7 @@ private: // our certificate cache std::map<InfoHash, std::shared_ptr<crypto::Certificate>> nodesCertificates_ {}; - std::map<InfoHash, std::shared_ptr<crypto::PublicKey>> nodesPubKeys_ {}; + std::map<InfoHash, std::shared_ptr<const crypto::PublicKey>> nodesPubKeys_ {}; std::uniform_int_distribution<Value::Id> rand_id {}; }; diff --git a/include/opendht/value.h b/include/opendht/value.h index 9990147d..58351e70 100644 --- a/include/opendht/value.h +++ b/include/opendht/value.h @@ -248,6 +248,43 @@ struct Value return owner and not signature.empty(); } + /** + * Sign the value using the provided private key. + * Afterward, checkSignature() will return true and owner will + * be set to the corresponding public key. + */ + void sign(const crypto::PrivateKey& key) { + if (isEncrypted()) + throw DhtException("Can't sign encrypted data."); + owner = std::make_shared<const crypto::PublicKey>(key.getPublicKey()); + signature = key.sign(getToSign()); + } + + /** + * Check that the value is signed and that the signature matches. + * If true, the owner field will contain the signer public key. + */ + bool checkSignature() const { + return isSigned() and owner->checkSignature(getToSign(), signature); + } + + std::shared_ptr<const crypto::PublicKey> getOwner() const { + return std::static_pointer_cast<const crypto::PublicKey>(owner); + } + + /** + * Sign the value with from and returns the encrypted version for to. + */ + Value encrypt(const crypto::PrivateKey& from, const crypto::PublicKey& to) { + if (isEncrypted()) + throw DhtException("Data is already encrypted."); + setRecipient(to.getId()); + sign(from); + Value nv {id}; + nv.setCypher(to.encrypt(getToEncrypt())); + return nv; + } + Value() {} Value (Id id) : id(id) {} @@ -380,13 +417,19 @@ struct Value void msgpack_unpack(msgpack::object o); void msgpack_unpack_body(const msgpack::object& o); + Blob getPacked() const { + msgpack::sbuffer buffer; + msgpack::packer<msgpack::sbuffer> pk(&buffer); + pk.pack(*this); + return {buffer.data(), buffer.data()+buffer.size()}; + } Id id {INVALID_ID}; /** * Public key of the signer. */ - std::shared_ptr<crypto::PublicKey> owner {}; + std::shared_ptr<const crypto::PublicKey> owner {}; /** * Hash of the recipient (optional). diff --git a/src/securedht.cpp b/src/securedht.cpp index f1718ee9..aafda7ee 100644 --- a/src/securedht.cpp +++ b/src/securedht.cpp @@ -141,7 +141,7 @@ SecureDht::getCertificate(const InfoHash& node) const return it->second; } -const std::shared_ptr<crypto::PublicKey> +const std::shared_ptr<const crypto::PublicKey> SecureDht::getPublicKey(const InfoHash& node) const { if (node == getId()) @@ -226,7 +226,7 @@ SecureDht::findCertificate(const InfoHash& node, std::function<void(const std::s } void -SecureDht::findPublicKey(const InfoHash& node, std::function<void(const std::shared_ptr<crypto::PublicKey>)> cb) +SecureDht::findPublicKey(const InfoHash& node, std::function<void(const std::shared_ptr<const crypto::PublicKey>)> cb) { auto pk = getPublicKey(node); if (pk && *pk) { @@ -342,7 +342,7 @@ SecureDht::putSigned(const InfoHash& hash, std::shared_ptr<Value> val, DoneCallb void SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, std::shared_ptr<Value> val, DoneCallback callback, bool permanent) { - findPublicKey(to, [=](const std::shared_ptr<crypto::PublicKey> pk) { + findPublicKey(to, [=](const std::shared_ptr<const crypto::PublicKey> pk) { if(!pk || !*pk) { if (callback) callback(false, {}); @@ -362,22 +362,13 @@ SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, std::shared_pt void SecureDht::sign(Value& v) const { - if (v.isEncrypted()) - throw DhtException("Can't sign encrypted data."); - v.owner = std::make_shared<crypto::PublicKey>(key_->getPublicKey()); - v.signature = key_->sign(v.getToSign()); + v.sign(*key_); } Value SecureDht::encrypt(Value& v, const crypto::PublicKey& to) const { - if (v.isEncrypted()) - throw DhtException("Data is already encrypted."); - v.setRecipient(to.getId()); - sign(v); - Value nv {v.id}; - nv.setCypher(to.encrypt(v.getToEncrypt())); - return nv; + return v.encrypt(*key_, to); } Value diff --git a/src/value.cpp b/src/value.cpp index a2c4d1e6..58a86556 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -142,8 +142,9 @@ Value::msgpack_unpack_body(const msgpack::object& o) seq = rseq->as<decltype(seq)>(); else throw msgpack::type_error(); - owner = std::make_shared<crypto::PublicKey>(); - owner->msgpack_unpack(*rowner); + crypto::PublicKey new_owner; + new_owner.msgpack_unpack(*rowner); + owner = std::make_shared<const crypto::PublicKey>(std::move(new_owner)); if (auto rrecipient = findMapValue(*rbody, "to")) { recipient = rrecipient->as<InfoHash>(); } -- GitLab