diff options
author | Roman Smrž <roman.smrz@seznam.cz> | 2019-12-11 22:14:12 +0100 |
---|---|---|
committer | Roman Smrž <roman.smrz@seznam.cz> | 2019-12-18 22:26:28 +0100 |
commit | d084c069be38b6f3ad74912ca629403d9fdaec58 (patch) | |
tree | 957e9e2340b291cdff6dac60480d1f4060c106a3 /src/pubkey.cpp | |
parent | 361891f25ca735fd85db64a14823cc55b8a0619a (diff) |
Identity loading and validation
Diffstat (limited to 'src/pubkey.cpp')
-rw-r--r-- | src/pubkey.cpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/pubkey.cpp b/src/pubkey.cpp new file mode 100644 index 0000000..3247ce2 --- /dev/null +++ b/src/pubkey.cpp @@ -0,0 +1,59 @@ +#include "pubkey.h" + +#include <stdexcept> + +using std::unique_ptr; +using std::runtime_error; +using std::string; + +using namespace erebos; + +optional<PublicKey> PublicKey::load(const Ref & ref) +{ + auto rec = ref->asRecord(); + if (!rec) + return nullopt; + + if (auto ktype = rec->item("type").asText()) + if (ktype.value() != "ed25519") + throw runtime_error("unsupported key type " + ktype.value()); + + if (auto pubkey = rec->item("pubkey").asBinary()) + return PublicKey(EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, nullptr, + pubkey.value().data(), pubkey.value().size())); + + return nullopt; +} + +optional<Signature> Signature::load(const Ref & ref) +{ + auto rec = ref->asRecord(); + if (!rec) + return nullopt; + + auto key = rec->item("key").as<PublicKey>(); + auto sig = rec->item("sig").asBinary(); + + if (!key || !sig) + return nullopt; + + return Signature { + .key = key.value(), + .sig = sig.value(), + }; +} + +bool Signature::verify(const Ref & ref) const +{ + unique_ptr<EVP_MD_CTX, void(*)(EVP_MD_CTX*)> + mdctx(EVP_MD_CTX_create(), &EVP_MD_CTX_free); + if (!mdctx) + throw runtime_error("failed to create EVP_MD_CTX"); + + if (EVP_DigestVerifyInit(mdctx.get(), nullptr, EVP_md_null(), + nullptr, key->key.get()) != 1) + throw runtime_error("failed to initialize EVP_MD_CTX"); + + return EVP_DigestVerify(mdctx.get(), sig.data(), sig.size(), + ref.digest().arr().data(), Digest::size) == 1; +} |