aboutsummaryrefslogtreecommitdiffhomepage
path: root/tdutils
diff options
context:
space:
mode:
authorArseny Smirnov <arseny30@gmail.com>2024-10-04 01:19:51 +0200
committerArseny Smirnov <arseny30@gmail.com>2025-04-10 17:18:46 +0300
commit6a46f51bdf5e5052ddae26b61cdf9d4864238442 (patch)
treebd7d1af6a2b68689cb97fc9391eeaee8851dada6 /tdutils
parent6571af5d49bf9b05361187599b156e93face92df (diff)
Add tde2e library
Diffstat (limited to 'tdutils')
-rw-r--r--tdutils/td/utils/Ed25519.cpp45
-rw-r--r--tdutils/td/utils/Ed25519.h8
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);