summaryrefslogtreecommitdiff
path: root/src/pubkey.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pubkey.cpp')
-rw-r--r--src/pubkey.cpp95
1 files changed, 95 insertions, 0 deletions
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> PublicKey::load(const Ref & ref)
return nullopt;
}
+Ref PublicKey::store(const Storage & st) const
+{
+ vector<Record::Item> items;
+
+ items.emplace_back("type", "ed25519");
+
+ vector<uint8_t> 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<EVP_PKEY_CTX, void(*)(EVP_PKEY_CTX*)>
+ 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<EVP_PKEY> seckey(pkey, EVP_PKEY_free);
+
+ vector<uint8_t> 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> SecretKey::load(const Stored<PublicKey> & 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<uint8_t> SecretKey::sign(const Digest & dgst) 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_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<uint8_t> 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> Signature::load(const Ref & ref)
{
auto rec = ref->asRecord();
@@ -43,6 +128,16 @@ optional<Signature> Signature::load(const Ref & ref)
};
}
+Ref Signature::store(const Storage & st) const
+{
+ vector<Record::Item> 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<EVP_MD_CTX, void(*)(EVP_MD_CTX*)>