From f94443c63dfd63300e5bd29889935fd1f451175e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Sat, 21 Dec 2019 21:42:20 +0100 Subject: Identity storage and modification --- src/pubkey.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) (limited to 'src/pubkey.cpp') diff --git a/src/pubkey.cpp b/src/pubkey.cpp index 3247ce2..e26bead 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -25,6 +25,91 @@ optional PublicKey::load(const Ref & ref) return nullopt; } +Ref PublicKey::store(const Storage & st) const +{ + vector items; + + items.emplace_back("type", "ed25519"); + + vector keyData; + size_t keyLen; + EVP_PKEY_get_raw_public_key(key.get(), nullptr, &keyLen); + keyData.resize(keyLen); + EVP_PKEY_get_raw_public_key(key.get(), keyData.data(), &keyLen); + items.emplace_back("pubkey", keyData); + + return st.storeObject(Record(std::move(items))); +} + +SecretKey SecretKey::generate(const Storage & st) +{ + unique_ptr + pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL), &EVP_PKEY_CTX_free); + if (!pctx) + throw runtime_error("failed to generate key"); + + if (EVP_PKEY_keygen_init(pctx.get()) != 1) + throw runtime_error("failed to generate key"); + + EVP_PKEY *pkey = NULL; + if (EVP_PKEY_keygen(pctx.get(), &pkey) != 1) + throw runtime_error("failed to generate key"); + shared_ptr seckey(pkey, EVP_PKEY_free); + + vector keyData; + size_t keyLen; + + EVP_PKEY_get_raw_public_key(seckey.get(), nullptr, &keyLen); + keyData.resize(keyLen); + EVP_PKEY_get_raw_public_key(seckey.get(), keyData.data(), &keyLen); + auto pubkey = st.store(PublicKey(EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, nullptr, + keyData.data(), keyData.size()))); + + EVP_PKEY_get_raw_private_key(seckey.get(), nullptr, &keyLen); + keyData.resize(keyLen); + EVP_PKEY_get_raw_private_key(seckey.get(), keyData.data(), &keyLen); + st.storeKey(pubkey.ref, keyData); + + return SecretKey(std::move(seckey), pubkey); +} + +optional SecretKey::load(const Stored & pub) +{ + auto keyData = pub.ref.storage().loadKey(pub.ref); + if (!keyData) + return nullopt; + + EVP_PKEY * key = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, nullptr, + keyData->data(), keyData->size()); + if (!key) + throw runtime_error("falied to parse secret key"); + return SecretKey(key, pub); +} + +vector SecretKey::sign(const Digest & dgst) const +{ + unique_ptr + mdctx(EVP_MD_CTX_create(), &EVP_MD_CTX_free); + if (!mdctx) + throw runtime_error("failed to create EVP_MD_CTX"); + + if (EVP_DigestSignInit(mdctx.get(), nullptr, EVP_md_null(), + nullptr, key.get()) != 1) + throw runtime_error("failed to initialize EVP_MD_CTX"); + + size_t sigLen; + if (EVP_DigestSign(mdctx.get(), nullptr, &sigLen, + dgst.arr().data(), Digest::size) != 1) + throw runtime_error("failed to sign data"); + + vector sigData(sigLen); + if (EVP_DigestSign(mdctx.get(), sigData.data(), &sigLen, + dgst.arr().data(), Digest::size) != 1) + throw runtime_error("failed to sign data"); + + return sigData; +} + optional Signature::load(const Ref & ref) { auto rec = ref->asRecord(); @@ -43,6 +128,16 @@ optional Signature::load(const Ref & ref) }; } +Ref Signature::store(const Storage & st) const +{ + vector items; + + items.emplace_back("key", key); + items.emplace_back("sig", sig); + + return st.storeObject(Record(std::move(items))); +} + bool Signature::verify(const Ref & ref) const { unique_ptr -- cgit v1.2.3