Skip to content
Snippets Groups Projects
Commit 33f29e95 authored by Adrien Béraud's avatar Adrien Béraud
Browse files

value: add common crypto ops

parent fdfa10bd
No related branches found
No related tags found
No related merge requests found
...@@ -126,16 +126,13 @@ public: ...@@ -126,16 +126,13 @@ public:
Value decrypt(const Value& v); Value decrypt(const Value& v);
void findCertificate(const InfoHash& node, std::function<void(const std::shared_ptr<crypto::Certificate>)> cb); 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); const std::shared_ptr<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
void registerCertificate(std::shared_ptr<crypto::Certificate>& 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::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. * Allows to set a custom callback called by the library to find a locally-stored certificate.
...@@ -161,7 +158,7 @@ private: ...@@ -161,7 +158,7 @@ private:
// our certificate cache // our certificate cache
std::map<InfoHash, std::shared_ptr<crypto::Certificate>> nodesCertificates_ {}; 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 {}; std::uniform_int_distribution<Value::Id> rand_id {};
}; };
......
...@@ -248,6 +248,43 @@ struct Value ...@@ -248,6 +248,43 @@ struct Value
return owner and not signature.empty(); 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() {}
Value (Id id) : id(id) {} Value (Id id) : id(id) {}
...@@ -380,13 +417,19 @@ struct Value ...@@ -380,13 +417,19 @@ struct Value
void msgpack_unpack(msgpack::object o); void msgpack_unpack(msgpack::object o);
void msgpack_unpack_body(const 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}; Id id {INVALID_ID};
/** /**
* Public key of the signer. * Public key of the signer.
*/ */
std::shared_ptr<crypto::PublicKey> owner {}; std::shared_ptr<const crypto::PublicKey> owner {};
/** /**
* Hash of the recipient (optional). * Hash of the recipient (optional).
......
...@@ -141,7 +141,7 @@ SecureDht::getCertificate(const InfoHash& node) const ...@@ -141,7 +141,7 @@ SecureDht::getCertificate(const InfoHash& node) const
return it->second; return it->second;
} }
const std::shared_ptr<crypto::PublicKey> const std::shared_ptr<const crypto::PublicKey>
SecureDht::getPublicKey(const InfoHash& node) const SecureDht::getPublicKey(const InfoHash& node) const
{ {
if (node == getId()) if (node == getId())
...@@ -226,7 +226,7 @@ SecureDht::findCertificate(const InfoHash& node, std::function<void(const std::s ...@@ -226,7 +226,7 @@ SecureDht::findCertificate(const InfoHash& node, std::function<void(const std::s
} }
void 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); auto pk = getPublicKey(node);
if (pk && *pk) { if (pk && *pk) {
...@@ -342,7 +342,7 @@ SecureDht::putSigned(const InfoHash& hash, std::shared_ptr<Value> val, DoneCallb ...@@ -342,7 +342,7 @@ SecureDht::putSigned(const InfoHash& hash, std::shared_ptr<Value> val, DoneCallb
void void
SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, std::shared_ptr<Value> val, DoneCallback callback, bool permanent) 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(!pk || !*pk) {
if (callback) if (callback)
callback(false, {}); callback(false, {});
...@@ -362,22 +362,13 @@ SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, std::shared_pt ...@@ -362,22 +362,13 @@ SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, std::shared_pt
void void
SecureDht::sign(Value& v) const SecureDht::sign(Value& v) const
{ {
if (v.isEncrypted()) v.sign(*key_);
throw DhtException("Can't sign encrypted data.");
v.owner = std::make_shared<crypto::PublicKey>(key_->getPublicKey());
v.signature = key_->sign(v.getToSign());
} }
Value Value
SecureDht::encrypt(Value& v, const crypto::PublicKey& to) const SecureDht::encrypt(Value& v, const crypto::PublicKey& to) const
{ {
if (v.isEncrypted()) return v.encrypt(*key_, to);
throw DhtException("Data is already encrypted.");
v.setRecipient(to.getId());
sign(v);
Value nv {v.id};
nv.setCypher(to.encrypt(v.getToEncrypt()));
return nv;
} }
Value Value
......
...@@ -142,8 +142,9 @@ Value::msgpack_unpack_body(const msgpack::object& o) ...@@ -142,8 +142,9 @@ Value::msgpack_unpack_body(const msgpack::object& o)
seq = rseq->as<decltype(seq)>(); seq = rseq->as<decltype(seq)>();
else else
throw msgpack::type_error(); throw msgpack::type_error();
owner = std::make_shared<crypto::PublicKey>(); crypto::PublicKey new_owner;
owner->msgpack_unpack(*rowner); new_owner.msgpack_unpack(*rowner);
owner = std::make_shared<const crypto::PublicKey>(std::move(new_owner));
if (auto rrecipient = findMapValue(*rbody, "to")) { if (auto rrecipient = findMapValue(*rbody, "to")) {
recipient = rrecipient->as<InfoHash>(); recipient = rrecipient->as<InfoHash>();
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment