#pragma once #include "storage.h" #include using std::nullopt; using std::optional; using std::shared_ptr; namespace erebos { class PublicKey { PublicKey(EVP_PKEY * key): key(key, EVP_PKEY_free) {} public: static optional load(const Ref &); const shared_ptr key; }; class SecretKey { SecretKey(EVP_PKEY * key, const Stored & pub): key(key, EVP_PKEY_free), pub(pub) {} private: const shared_ptr key; Stored pub; }; class Signature { public: static optional load(const Ref &); bool verify(const Ref &) const; Stored key; vector sig; }; template class Signed { public: static optional> load(const Ref &); bool isSignedBy(const Stored &) const; const Stored data; const vector> sigs; }; template optional> Signed::load(const Ref & ref) { auto rec = ref->asRecord(); if (!rec) return nullopt; auto data = rec->item("SDATA").as(); if (!data) return nullopt; vector> sigs; for (auto item : rec->items("sig")) if (auto sig = item.as()) if (sig.value()->verify(data.value().ref)) sigs.push_back(sig.value()); return Signed { .data = data.value(), .sigs = sigs, }; } template bool Signed::isSignedBy(const Stored & key) const { for (const auto & sig : sigs) if (sig->key == key) return true; return false; } }