diff options
| author | Arseny Smirnov <arseny30@gmail.com> | 2024-10-04 01:19:51 +0200 |
|---|---|---|
| committer | Arseny Smirnov <arseny30@gmail.com> | 2025-04-10 17:18:46 +0300 |
| commit | 6a46f51bdf5e5052ddae26b61cdf9d4864238442 (patch) | |
| tree | bd7d1af6a2b68689cb97fc9391eeaee8851dada6 /tdutils | |
| parent | 6571af5d49bf9b05361187599b156e93face92df (diff) | |
Add tde2e library
Diffstat (limited to 'tdutils')
| -rw-r--r-- | tdutils/td/utils/Ed25519.cpp | 45 | ||||
| -rw-r--r-- | tdutils/td/utils/Ed25519.h | 8 |
2 files changed, 48 insertions, 5 deletions
diff --git a/tdutils/td/utils/Ed25519.cpp b/tdutils/td/utils/Ed25519.cpp index ed52f6f05..7128a9cb6 100644 --- a/tdutils/td/utils/Ed25519.cpp +++ b/tdutils/td/utils/Ed25519.cpp @@ -172,16 +172,39 @@ Result<Ed25519::PrivateKey> Ed25519::PrivateKey::from_pem(Slice pem, Slice passw #endif } -Result<SecureString> Ed25519::PrivateKey::sign(Slice data) const { +struct Ed25519::PreparedPrivateKey { +#if OPENSSL_VERSION_NUMBER >= 0x10101000L + explicit PreparedPrivateKey(EVP_PKEY *pkey) : pkey_(pkey) { + } + EVP_PKEY *pkey_ = nullptr; + PreparedPrivateKey(const PreparedPrivateKey &) = delete; + PreparedPrivateKey(const PreparedPrivateKey &&) = delete; + PreparedPrivateKey &operator=(const PreparedPrivateKey &) = delete; + PreparedPrivateKey &operator=(const PreparedPrivateKey &&) = delete; + ~PreparedPrivateKey() { + if (pkey_ != nullptr) { + EVP_PKEY_free(pkey_); + pkey_ = nullptr; + } + } +#endif +}; + +Result<std::shared_ptr<const Ed25519::PreparedPrivateKey>> Ed25519::PrivateKey::prepare() const { #if OPENSSL_VERSION_NUMBER >= 0x10101000L auto pkey = detail::X25519_key_to_PKEY(octet_string_, true); if (pkey == nullptr) { return Status::Error("Can't import private key"); } - SCOPE_EXIT { - EVP_PKEY_free(pkey); - }; + return std::make_shared<Ed25519::PreparedPrivateKey>(pkey); +#else + return Status::Error("Unsupported"); +#endif +} +Result<SecureString> Ed25519::PrivateKey::sign(const PreparedPrivateKey &prepared_private_key, Slice data) { +#if OPENSSL_VERSION_NUMBER >= 0x10101000L + CHECK(prepared_private_key.pkey_ != nullptr); EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); if (md_ctx == nullptr) { return Status::Error("Can't create EVP_MD_CTX"); @@ -190,7 +213,7 @@ Result<SecureString> Ed25519::PrivateKey::sign(Slice data) const { EVP_MD_CTX_free(md_ctx); }; - if (EVP_DigestSignInit(md_ctx, nullptr, nullptr, nullptr, pkey) <= 0) { + if (EVP_DigestSignInit(md_ctx, nullptr, nullptr, nullptr, prepared_private_key.pkey_) <= 0) { return Status::Error("Can't init DigestSign"); } @@ -205,6 +228,18 @@ Result<SecureString> Ed25519::PrivateKey::sign(Slice data) const { #endif } +Result<SecureString> Ed25519::PrivateKey::sign(Slice data) const { +#if OPENSSL_VERSION_NUMBER >= 0x10101000L + auto pkey = detail::X25519_key_to_PKEY(octet_string_, true); + if (pkey == nullptr) { + return Status::Error("Can't import private key"); + } + return sign(PreparedPrivateKey(pkey), data); +#else + return Status::Error("Unsupported"); +#endif +} + Status Ed25519::PublicKey::verify_signature(Slice data, Slice signature) const { #if OPENSSL_VERSION_NUMBER >= 0x10101000L auto pkey = detail::X25519_key_to_PKEY(octet_string_, false); diff --git a/tdutils/td/utils/Ed25519.h b/tdutils/td/utils/Ed25519.h index ae9a5fa8b..f03b3d1b1 100644 --- a/tdutils/td/utils/Ed25519.h +++ b/tdutils/td/utils/Ed25519.h @@ -12,6 +12,8 @@ #include "td/utils/Status.h" #include "td/utils/UInt.h" +#include <memory> + #if TD_HAVE_OPENSSL namespace td { @@ -65,18 +67,24 @@ class Ed25519 { SecureString octet_string_; }; + struct PreparedPrivateKey; + class PrivateKey { public: static constexpr size_t LENGTH = 32; explicit PrivateKey(SecureString octet_string); + Result<std::shared_ptr<const PreparedPrivateKey>> prepare() const; + SecureString as_octet_string() const; Result<PublicKey> get_public_key() const; Result<SecureString> sign(Slice data) const; + static Result<SecureString> sign(const PreparedPrivateKey &prepared_private_key, Slice data); + Result<SecureString> as_pem(Slice password) const; static Result<PrivateKey> from_pem(Slice pem, Slice password); |
