Skip to content

Commit c5639ab

Browse files
authored
Merge pull request #1877 from birydrad/testnet
update tdutils (mostly from tdlib)
1 parent e99f5e8 commit c5639ab

File tree

99 files changed

+4896
-867
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+4896
-867
lines changed

CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,9 +424,12 @@ add_subdirectory(tolk)
424424
add_subdirectory(tonlib)
425425
#END tonlib
426426

427+
# Temporary (?) move those two targets in TONLIB targets
428+
add_subdirectory(common)
429+
add_subdirectory(http)
430+
427431
#BEGIN internal
428432
if (NOT TON_ONLY_TONLIB)
429-
add_subdirectory(common)
430433
add_subdirectory(tdfec)
431434
add_subdirectory(keyring)
432435
add_subdirectory(fec)
@@ -444,7 +447,6 @@ add_subdirectory(validator-engine-console)
444447
add_subdirectory(create-hardfork)
445448
add_subdirectory(dht-server)
446449
add_subdirectory(utils)
447-
add_subdirectory(http)
448450
add_subdirectory(rldp-http-proxy)
449451
endif()
450452
#END internal

crypto/Ed25519.cpp

Lines changed: 134 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,23 @@
1616
1717
Copyright 2017-2020 Telegram Systems LLP
1818
*/
19-
#include <openssl/evp.h>
2019
#include <openssl/opensslv.h>
21-
#include <openssl/pem.h>
22-
#include <openssl/x509.h>
2320

2421
#include "crypto/Ed25519.h"
2522
#include "td/utils/BigNum.h"
2623
#include "td/utils/ScopeGuard.h"
2724
#include "td/utils/base64.h"
28-
#include "td/utils/format.h"
29-
#include "td/utils/logging.h"
3025
#include "td/utils/misc.h"
3126

27+
#if TD_HAVE_OPENSSL
28+
29+
#include <openssl/evp.h>
30+
#include <openssl/opensslv.h>
31+
#include <openssl/pem.h>
32+
#include <openssl/x509.h>
33+
34+
#include "td/utils/ThreadSafeCounter.h"
35+
3236
namespace td {
3337

3438
Ed25519::PublicKey::PublicKey(SecureString octet_string) : octet_string_(std::move(octet_string)) {
@@ -45,6 +49,7 @@ SecureString Ed25519::PrivateKey::as_octet_string() const {
4549
return octet_string_.copy();
4650
}
4751

52+
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
4853
namespace detail {
4954

5055
static Result<SecureString> X25519_key_from_PKEY(EVP_PKEY *pkey, bool is_private) {
@@ -67,14 +72,17 @@ static EVP_PKEY *X25519_key_to_PKEY(Slice key, bool is_private) {
6772
return func(EVP_PKEY_ED25519, nullptr, key.ubegin(), key.size());
6873
}
6974

70-
static Result<SecureString> X25519_pem_from_PKEY(EVP_PKEY *pkey, bool is_private, Slice password) {
75+
static Result<SecureString> X25519_pem_from_PKEY(EVP_PKEY *pkey, bool is_private, std::optional<Slice> o_password) {
7176
BIO *mem_bio = BIO_new(BIO_s_mem());
7277
SCOPE_EXIT {
7378
BIO_vfree(mem_bio);
7479
};
7580
if (is_private) {
76-
PEM_write_bio_PrivateKey(mem_bio, pkey, EVP_aes_256_cbc(), const_cast<unsigned char *>(password.ubegin()),
77-
narrow_cast<int>(password.size()), nullptr, nullptr);
81+
auto *chipher = o_password ? EVP_aes_256_cbc() : nullptr;
82+
const unsigned char *password = o_password ? o_password->ubegin() : nullptr;
83+
size_t password_size = o_password ? o_password->size() : 0;
84+
PEM_write_bio_PrivateKey(mem_bio, pkey, chipher, const_cast<unsigned char *>(password),
85+
narrow_cast<int>(password_size), nullptr, nullptr);
7886
} else {
7987
PEM_write_bio_PUBKEY(mem_bio, pkey);
8088
}
@@ -105,8 +113,10 @@ static EVP_PKEY *X25519_pem_to_PKEY(Slice pem, Slice password) {
105113
}
106114

107115
} // namespace detail
116+
#endif
108117

109118
Result<Ed25519::PrivateKey> Ed25519::generate_private_key() {
119+
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
110120
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(NID_ED25519, nullptr);
111121
if (pctx == nullptr) {
112122
return Status::Error("Can't create EVP_PKEY_CTX");
@@ -129,9 +139,13 @@ Result<Ed25519::PrivateKey> Ed25519::generate_private_key() {
129139

130140
TRY_RESULT(private_key, detail::X25519_key_from_PKEY(pkey, true));
131141
return std::move(private_key);
142+
#else
143+
return Status::Error("Unsupported");
144+
#endif
132145
}
133146

134147
Result<Ed25519::PublicKey> Ed25519::PrivateKey::get_public_key() const {
148+
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
135149
auto pkey = detail::X25519_key_to_PKEY(octet_string_, true);
136150
if (pkey == nullptr) {
137151
return Status::Error("Can't import private key");
@@ -142,9 +156,19 @@ Result<Ed25519::PublicKey> Ed25519::PrivateKey::get_public_key() const {
142156

143157
TRY_RESULT(key, detail::X25519_key_from_PKEY(pkey, false));
144158
return Ed25519::PublicKey(std::move(key));
159+
#else
160+
return Status::Error("Unsupported");
161+
#endif
145162
}
146163

147164
Result<SecureString> Ed25519::PrivateKey::as_pem(Slice password) const {
165+
return as_pem(std::optional<td::Slice>(password));
166+
}
167+
Result<SecureString> Ed25519::PrivateKey::as_pem() const {
168+
return as_pem(std::nullopt);
169+
}
170+
Result<SecureString> Ed25519::PrivateKey::as_pem(std::optional<td::Slice> o_password) const {
171+
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
148172
auto pkey = detail::X25519_key_to_PKEY(octet_string_, true);
149173
if (pkey == nullptr) {
150174
return Status::Error("Can't import private key");
@@ -153,27 +177,58 @@ Result<SecureString> Ed25519::PrivateKey::as_pem(Slice password) const {
153177
EVP_PKEY_free(pkey);
154178
};
155179

156-
return detail::X25519_pem_from_PKEY(pkey, true, password);
180+
return detail::X25519_pem_from_PKEY(pkey, true, o_password);
181+
#else
182+
return Status::Error("Unsupported");
183+
#endif
157184
}
158185

159186
Result<Ed25519::PrivateKey> Ed25519::PrivateKey::from_pem(Slice pem, Slice password) {
187+
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
160188
auto pkey = detail::X25519_pem_to_PKEY(pem, password);
161189
if (pkey == nullptr) {
162190
return Status::Error("Can't import private key from pem");
163191
}
164192
TRY_RESULT(key, detail::X25519_key_from_PKEY(pkey, true));
165193
return Ed25519::PrivateKey(std::move(key));
194+
#else
195+
return Status::Error("Unsupported");
196+
#endif
166197
}
167198

168-
Result<SecureString> Ed25519::PrivateKey::sign(Slice data) const {
199+
struct Ed25519::PreparedPrivateKey {
200+
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
201+
explicit PreparedPrivateKey(EVP_PKEY *pkey) : pkey_(pkey) {
202+
}
203+
EVP_PKEY *pkey_ = nullptr;
204+
PreparedPrivateKey(const PreparedPrivateKey &) = delete;
205+
PreparedPrivateKey(const PreparedPrivateKey &&) = delete;
206+
PreparedPrivateKey &operator=(const PreparedPrivateKey &) = delete;
207+
PreparedPrivateKey &operator=(const PreparedPrivateKey &&) = delete;
208+
~PreparedPrivateKey() {
209+
if (pkey_ != nullptr) {
210+
EVP_PKEY_free(pkey_);
211+
pkey_ = nullptr;
212+
}
213+
}
214+
#endif
215+
};
216+
217+
Result<std::shared_ptr<const Ed25519::PreparedPrivateKey>> Ed25519::PrivateKey::prepare() const {
218+
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
169219
auto pkey = detail::X25519_key_to_PKEY(octet_string_, true);
170220
if (pkey == nullptr) {
171221
return Status::Error("Can't import private key");
172222
}
173-
SCOPE_EXIT {
174-
EVP_PKEY_free(pkey);
175-
};
223+
return std::make_shared<Ed25519::PreparedPrivateKey>(pkey);
224+
#else
225+
return Status::Error("Unsupported");
226+
#endif
227+
}
176228

229+
Result<SecureString> Ed25519::PrivateKey::sign(const PreparedPrivateKey &prepared_private_key, Slice data) {
230+
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
231+
CHECK(prepared_private_key.pkey_ != nullptr);
177232
EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
178233
if (md_ctx == nullptr) {
179234
return Status::Error("Can't create EVP_MD_CTX");
@@ -182,7 +237,7 @@ Result<SecureString> Ed25519::PrivateKey::sign(Slice data) const {
182237
EVP_MD_CTX_free(md_ctx);
183238
};
184239

185-
if (EVP_DigestSignInit(md_ctx, nullptr, nullptr, nullptr, pkey) <= 0) {
240+
if (EVP_DigestSignInit(md_ctx, nullptr, nullptr, nullptr, prepared_private_key.pkey_) <= 0) {
186241
return Status::Error("Can't init DigestSign");
187242
}
188243

@@ -192,9 +247,26 @@ Result<SecureString> Ed25519::PrivateKey::sign(Slice data) const {
192247
return Status::Error("Can't sign data");
193248
}
194249
return std::move(res);
250+
#else
251+
return Status::Error("Unsupported");
252+
#endif
253+
}
254+
255+
Result<SecureString> Ed25519::PrivateKey::sign(Slice data) const {
256+
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
257+
auto pkey = detail::X25519_key_to_PKEY(octet_string_, true);
258+
if (pkey == nullptr) {
259+
return Status::Error("Can't import private key");
260+
}
261+
return sign(PreparedPrivateKey(pkey), data);
262+
#else
263+
return Status::Error("Unsupported");
264+
#endif
195265
}
196266

197267
Status Ed25519::PublicKey::verify_signature(Slice data, Slice signature) const {
268+
TD_PERF_COUNTER(Ed25519_verify_signature);
269+
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
198270
auto pkey = detail::X25519_key_to_PKEY(octet_string_, false);
199271
if (pkey == nullptr) {
200272
return Status::Error("Can't import public key");
@@ -219,12 +291,20 @@ Status Ed25519::PublicKey::verify_signature(Slice data, Slice signature) const {
219291
return Status::OK();
220292
}
221293
return Status::Error("Wrong signature");
294+
#else
295+
return Status::Error("Unsupported");
296+
#endif
222297
}
223298

224299
Result<SecureString> Ed25519::compute_shared_secret(const PublicKey &public_key, const PrivateKey &private_key) {
300+
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
225301
BigNum p = BigNum::from_hex("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed").move_as_ok();
226302
auto public_y = public_key.as_octet_string();
227-
public_y.as_mutable_slice()[31] = static_cast<char>(public_y[31] & 127);
303+
MutableSlice pub_slc = public_y.as_mutable_slice();
304+
if (pub_slc.size() != PublicKey::LENGTH) {
305+
return Status::Error("Wrong public key");
306+
}
307+
pub_slc[31] = static_cast<char>(public_y[31] & 127);
228308
BigNum y = BigNum::from_le_binary(public_y);
229309
BigNum y2 = y.clone();
230310
y += 1;
@@ -241,8 +321,11 @@ Result<SecureString> Ed25519::compute_shared_secret(const PublicKey &public_key,
241321
BigNum::mod_mul(u, y, inverse_y_plus_1, p, context);
242322

243323
auto pr_key = private_key.as_octet_string();
324+
if (pr_key.size() != PrivateKey::LENGTH) {
325+
return Status::Error("Wrong private key");
326+
}
244327
unsigned char buf[64];
245-
SHA512(Slice(pr_key).ubegin(), 32, buf);
328+
SHA512(Slice(pr_key).ubegin(), pr_key.size(), buf);
246329
buf[0] &= 248;
247330
buf[31] &= 127;
248331
buf[31] |= 64;
@@ -254,17 +337,15 @@ Result<SecureString> Ed25519::compute_shared_secret(const PublicKey &public_key,
254337
SCOPE_EXIT {
255338
EVP_PKEY_free(pkey_private);
256339
};
257-
// LOG(ERROR) << buffer_to_hex(Slice(buf, 32));
258340

259-
auto pub_key = u.to_le_binary(32);
341+
auto pub_key = u.to_le_binary(PublicKey::LENGTH);
260342
auto pkey_public = EVP_PKEY_new_raw_public_key(EVP_PKEY_X25519, nullptr, Slice(pub_key).ubegin(), pub_key.size());
261343
if (pkey_public == nullptr) {
262344
return Status::Error("Can't import public key");
263345
}
264346
SCOPE_EXIT {
265347
EVP_PKEY_free(pkey_public);
266348
};
267-
// LOG(ERROR) << buffer_to_hex(pub_key);
268349

269350
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey_private, nullptr);
270351
if (ctx == nullptr) {
@@ -294,10 +375,44 @@ Result<SecureString> Ed25519::compute_shared_secret(const PublicKey &public_key,
294375
return Status::Error("Failed to compute shared secret");
295376
}
296377
return std::move(result);
378+
#else
379+
return Status::Error("Unsupported");
380+
#endif
381+
}
382+
383+
Result<SecureString> Ed25519::get_public_key(Slice private_key) {
384+
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
385+
if (private_key.size() != PrivateKey::LENGTH) {
386+
return Status::Error("Invalid X25519 private key");
387+
}
388+
auto pkey_private = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, nullptr, private_key.ubegin(), private_key.size());
389+
if (pkey_private == nullptr) {
390+
return Status::Error("Invalid X25519 private key");
391+
}
392+
SCOPE_EXIT {
393+
EVP_PKEY_free(pkey_private);
394+
};
395+
396+
size_t len = 0;
397+
if (EVP_PKEY_get_raw_public_key(pkey_private, nullptr, &len) == 0) {
398+
return Status::Error("Failed to get raw key length");
399+
}
400+
CHECK(len == PublicKey::LENGTH);
401+
402+
SecureString result(len);
403+
if (EVP_PKEY_get_raw_public_key(pkey_private, result.as_mutable_slice().ubegin(), &len) == 0) {
404+
return Status::Error("Failed to get raw key");
405+
}
406+
return std::move(result);
407+
#else
408+
return Status::Error("Unsupported");
409+
#endif
297410
}
298411

299412
int Ed25519::version() {
300413
return OPENSSL_VERSION_NUMBER;
301414
}
302415

303416
} // namespace td
417+
418+
#endif

0 commit comments

Comments
 (0)