diff --git a/CMakeLists.txt b/CMakeLists.txt index 73c31c2f3..aabad071e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -499,6 +499,7 @@ set(TDLIB_SOURCE td/telegram/FullMessageId.h td/telegram/Game.h td/telegram/Global.h + td/telegram/GroupCallId.h td/telegram/GroupCallManager.h td/telegram/GroupCallParticipant.h td/telegram/HashtagHints.h diff --git a/benchmark/bench_crypto.cpp b/benchmark/bench_crypto.cpp index ce880b8db..7b87b477d 100644 --- a/benchmark/bench_crypto.cpp +++ b/benchmark/bench_crypto.cpp @@ -28,6 +28,7 @@ static constexpr int DATA_SIZE = 8 << 10; static constexpr int SHORT_DATA_SIZE = 64; +#if OPENSSL_VERSION_NUMBER <= 0x10100000L class SHA1Bench : public td::Benchmark { public: alignas(64) unsigned char data[DATA_SIZE]; @@ -50,6 +51,7 @@ class SHA1Bench : public td::Benchmark { } } }; +#endif class AesEcbBench : public td::Benchmark { public: @@ -433,7 +435,9 @@ int main() { td::bench(SslRandBench()); #endif td::bench(SslRandBufBench()); +#if OPENSSL_VERSION_NUMBER <= 0x10100000L td::bench(SHA1Bench()); +#endif td::bench(Crc32Bench()); td::bench(Crc64Bench()); } diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 2110576b0..517bb81a8 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3229,7 +3229,7 @@ messageStatistics message_interaction_graph:StatisticalGraph = MessageStatistics point x:double y:double = Point; -//@class VectorPathCommand @description Reperesents a vector path command +//@class VectorPathCommand @description Represents a vector path command //@description A straight line to a given point @end_point The end point of the straight line vectorPathCommandLine end_point:point = VectorPathCommand; @@ -3892,12 +3892,12 @@ getMessageLinkInfo url:string = MessageLinkInfo; //@reply_markup Markup for replying to the message; for bots only @input_message_content The content of the message to be sent sendMessage chat_id:int53 message_thread_id:int53 reply_to_message_id:int53 options:messageSendOptions reply_markup:ReplyMarkup input_message_content:InputMessageContent = Message; -//@description Sends messages grouped together into an album. Currently only audio, document, photo and video messages can be grouped into an album. Documents and audio files can be only grouped in an album with messages of the same type. Returns sent messages +//@description Sends 2-10 messages grouped together into an album. Currently only audio, document, photo and video messages can be grouped into an album. Documents and audio files can be only grouped in an album with messages of the same type. Returns sent messages //@chat_id Target chat //@message_thread_id If not 0, a message thread identifier in which the messages will be sent //@reply_to_message_id Identifier of a message to reply to or 0 //@options Options to be used to send the messages -//@input_message_contents Contents of messages to be sent +//@input_message_contents Contents of messages to be sent. At most 10 messages can be added to an album sendMessageAlbum chat_id:int53 message_thread_id:int53 reply_to_message_id:int53 options:messageSendOptions input_message_contents:vector = Messages; //@description Invites a bot to a chat (if it is not yet a member) and sends it the /start command. Bots can't be invited to a private chat other than the chat with the bot. Bots can't be invited to channels (although they can be added as admins) and secret chats. Returns the sent message @@ -3914,7 +3914,9 @@ sendBotStartMessage bot_user_id:int32 chat_id:int53 parameter:string = Message; sendInlineQueryResultMessage chat_id:int53 message_thread_id:int53 reply_to_message_id:int53 options:messageSendOptions query_id:int64 result_id:string hide_via_bot:Bool = Message; //@description Forwards previously sent messages. Returns the forwarded messages in the same order as the message identifiers passed in message_ids. If a message can't be forwarded, null will be returned instead of the message -//@chat_id Identifier of the chat to which to forward messages @from_chat_id Identifier of the chat from which to forward messages @message_ids Identifiers of the messages to forward. Message identifiers must be in a strictly increasing order +//@chat_id Identifier of the chat to which to forward messages +//@from_chat_id Identifier of the chat from which to forward messages +//@message_ids Identifiers of the messages to forward. Message identifiers must be in a strictly increasing order. At most 100 messages can be forwarded simultaneously //@options Options to be used to send the messages //@send_copy True, if content of the messages needs to be copied without links to the original messages. Always true if the messages are forwarded to a secret chat //@remove_caption True, if media caption of message copies needs to be removed. Ignored if send_copy is false diff --git a/td/mtproto/RSA.cpp b/td/mtproto/RSA.cpp index a5825c2a6..57287c42a 100644 --- a/td/mtproto/RSA.cpp +++ b/td/mtproto/RSA.cpp @@ -20,8 +20,11 @@ #include #include +#include #include +#if OPENSSL_VERSION_NUMBER < 0x30000000L #include +#endif namespace td { @@ -44,25 +47,55 @@ Result RSA::from_pem_public_key(Slice pem) { BIO_free(bio); }; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY *rsa = PEM_read_bio_PUBKEY(bio, nullptr, nullptr, nullptr); +#else auto rsa = PEM_read_bio_RSAPublicKey(bio, nullptr, nullptr, nullptr); +#endif if (rsa == nullptr) { - return Status::Error("Error while reading rsa pubkey"); + return Status::Error("Error while reading RSA public key"); } SCOPE_EXIT { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY_free(rsa); +#else RSA_free(rsa); +#endif }; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (!EVP_PKEY_is_a(rsa, "RSA")) { + return Status::Error("Key is not an RSA key"); + } + if (EVP_PKEY_size(rsa) != 256) { + return Status::Error("EVP_PKEY_size != 256"); + } +#else if (RSA_size(rsa) != 256) { return Status::Error("RSA_size != 256"); } +#endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + BIGNUM *n_num = nullptr; + BIGNUM *e_num = nullptr; + + int res = EVP_PKEY_get_bn_param(rsa, "n", &n_num); + CHECK(res == 1 && n_num != nullptr); + res = EVP_PKEY_get_bn_param(rsa, "e", &e_num); + CHECK(res == 1 && e_num != nullptr); + + auto n = static_cast(n_num); + auto e = static_cast(e_num); +#else const BIGNUM *n_num; const BIGNUM *e_num; -#if OPENSSL_VERSION_NUMBER < 0x10100000L + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + RSA_get0_key(rsa, &n_num, &e_num, nullptr); +#else n_num = rsa->n; e_num = rsa->e; -#else - RSA_get0_key(rsa, &n_num, &e_num, nullptr); #endif auto n = static_cast(BN_dup(n_num)); @@ -70,6 +103,7 @@ Result RSA::from_pem_public_key(Slice pem) { if (n == nullptr || e == nullptr) { return Status::Error("Cannot dup BIGNUM"); } +#endif return RSA(BigNum::from_raw(n), BigNum::from_raw(e)); } @@ -104,6 +138,7 @@ size_t RSA::encrypt(unsigned char *from, size_t from_len, size_t max_from_len, u CHECK(chunks * 256 <= to_len); Random::secure_bytes(from + from_len, pad); + size_t result = chunks * 256; BigNumContext ctx; BigNum y; while (chunks-- > 0) { @@ -112,7 +147,7 @@ size_t RSA::encrypt(unsigned char *from, size_t from_len, size_t max_from_len, u MutableSlice(to, 256).copy_from(y.to_binary(256)); to += 256; } - return chunks * 256; + return result; } void RSA::decrypt_signature(Slice from, MutableSlice to) const { diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index dbc2e4f82..610fbbb27 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -19,7 +19,6 @@ #include "td/telegram/files/FileType.h" #include "td/telegram/FolderId.h" #include "td/telegram/Global.h" -#include "td/telegram/GroupCallManager.h" #include "td/telegram/InlineQueriesManager.h" #include "td/telegram/InputGroupCallId.h" #include "td/telegram/logevent/LogEvent.h" diff --git a/td/telegram/GroupCallManager.cpp b/td/telegram/GroupCallManager.cpp index 8d50a1751..379c0ea27 100644 --- a/td/telegram/GroupCallManager.cpp +++ b/td/telegram/GroupCallManager.cpp @@ -6,21 +6,25 @@ // #include "td/telegram/GroupCallManager.h" +#include "td/telegram/AccessRights.h" #include "td/telegram/AuthManager.h" #include "td/telegram/ContactsManager.h" #include "td/telegram/DialogParticipant.h" #include "td/telegram/Global.h" +#include "td/telegram/MessageId.h" #include "td/telegram/MessagesManager.h" #include "td/telegram/misc.h" #include "td/telegram/net/NetQuery.h" #include "td/telegram/Td.h" #include "td/telegram/UpdatesManager.h" -#include "td/actor/MultiPromise.h" - +#include "td/utils/buffer.h" #include "td/utils/JsonBuilder.h" +#include "td/utils/misc.h" #include "td/utils/Random.h" +#include +#include #include #include diff --git a/td/telegram/GroupCallManager.h b/td/telegram/GroupCallManager.h index 8fec9b725..fbd0dca24 100644 --- a/td/telegram/GroupCallManager.h +++ b/td/telegram/GroupCallManager.h @@ -18,6 +18,8 @@ #include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" +#include "td/utils/common.h" +#include "td/utils/logging.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/GroupCallParticipant.cpp b/td/telegram/GroupCallParticipant.cpp index 95a3cbb7a..4e0dbb70f 100644 --- a/td/telegram/GroupCallParticipant.cpp +++ b/td/telegram/GroupCallParticipant.cpp @@ -8,6 +8,8 @@ #include "td/telegram/ContactsManager.h" +#include "td/utils/logging.h" + namespace td { GroupCallParticipant::GroupCallParticipant(const tl_object_ptr &participant) { diff --git a/td/telegram/InputGroupCallId.cpp b/td/telegram/InputGroupCallId.cpp index 977585ad7..87e418321 100644 --- a/td/telegram/InputGroupCallId.cpp +++ b/td/telegram/InputGroupCallId.cpp @@ -6,9 +6,6 @@ // #include "td/telegram/InputGroupCallId.h" -#include "td/utils/logging.h" -#include "td/utils/misc.h" - namespace td { InputGroupCallId::InputGroupCallId(const tl_object_ptr &input_group_call) diff --git a/td/telegram/PollManager.cpp b/td/telegram/PollManager.cpp index db9340335..2385c5b0e 100644 --- a/td/telegram/PollManager.cpp +++ b/td/telegram/PollManager.cpp @@ -844,26 +844,34 @@ void PollManager::on_set_poll_answer(PollId poll_id, uint64 generation, poll->was_saved = false; } if (result.is_ok()) { - td_->updates_manager_->on_get_updates(result.move_as_ok(), Promise()); - - for (auto &promise : promises) { - promise.set_value(Unit()); - } + td_->updates_manager_->on_get_updates( + result.move_as_ok(), PromiseCreator::lambda([actor_id = actor_id(this), poll_id, + promises = std::move(promises)](Result &&result) mutable { + send_closure(actor_id, &PollManager::on_set_poll_answer_finished, poll_id, Unit(), std::move(promises)); + })); } else { - for (auto &promise : promises) { - promise.set_error(result.error().clone()); + on_set_poll_answer_finished(poll_id, result.move_as_error(), std::move(promises)); + } +} + +void PollManager::on_set_poll_answer_finished(PollId poll_id, Result &&result, vector> &&promises) { + if (!G()->close_flag()) { + auto poll = get_poll(poll_id); + if (poll != nullptr && !poll->was_saved) { + // no updates was sent during updates processing, so send them + // poll wasn't changed, so there is no reason to actually save it + if (!(poll->is_closed && poll->is_updated_after_close)) { + LOG(INFO) << "Schedule updating of " << poll_id << " soon"; + update_poll_timeout_.set_timeout_in(poll_id.get(), 0.0); + } + + notify_on_poll_update(poll_id); + poll->was_saved = true; } } - if (poll != nullptr && !poll->was_saved) { - // no updates was sent during updates processing, so send them - // poll wasn't changed, so there is no reason to actually save it - if (!(poll->is_closed && poll->is_updated_after_close)) { - LOG(INFO) << "Schedule updating of " << poll_id << " soon"; - update_poll_timeout_.set_timeout_in(poll_id.get(), 0.0); - } - notify_on_poll_update(poll_id); - poll->was_saved = true; + for (auto &promise : promises) { + promise.set_result(result.clone()); } } diff --git a/td/telegram/PollManager.h b/td/telegram/PollManager.h index 6d8c63ff7..3af448a92 100644 --- a/td/telegram/PollManager.h +++ b/td/telegram/PollManager.h @@ -186,6 +186,8 @@ class PollManager : public Actor { void on_set_poll_answer(PollId poll_id, uint64 generation, Result> &&result); + void on_set_poll_answer_finished(PollId poll_id, Result &&result, vector> &&promises); + void invalidate_poll_voters(const Poll *poll, PollId poll_id); void invalidate_poll_option_voters(const Poll *poll, PollId poll_id, size_t option_index); diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 2df89deab..b00a8968d 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -47,6 +47,8 @@ #include "td/utils/PathView.h" #include "td/utils/Random.h" #include "td/utils/Slice.h" +#include "td/utils/StackAllocator.h" +#include "td/utils/StringBuilder.h" #include "td/utils/Time.h" #include "td/utils/tl_helpers.h" #include "td/utils/utf8.h" @@ -1503,7 +1505,7 @@ vector> StickersManager::get_sticke case 'm': case 'M': pos--; - // falltrough + // fallthrough case 'z': case 'Z': if (x != start_x || y != start_y) { diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 7c34c14fd..c1b85874c 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -43,6 +43,7 @@ #include "td/telegram/FolderId.h" #include "td/telegram/FullMessageId.h" #include "td/telegram/Global.h" +#include "td/telegram/GroupCallId.h" #include "td/telegram/GroupCallManager.h" #include "td/telegram/HashtagHints.h" #include "td/telegram/InlineQueriesManager.h" diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 812cadc27..c0ffbe72d 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -1119,17 +1119,24 @@ void UpdatesManager::on_get_difference(tl_object_ptrseq_; if (!pending_seq_updates_.empty()) { LOG(WARNING) << "Drop " << pending_seq_updates_.size() << " pending seq updates after receive empty difference"; - for (auto &pending_update : pending_seq_updates_) { + auto pending_seq_updates = std::move(pending_seq_updates_); + pending_seq_updates_.clear(); + + for (auto &pending_update : pending_seq_updates) { pending_update.second.promise.set_value(Unit()); } - pending_seq_updates_.clear(); } if (!pending_qts_updates_.empty()) { LOG(WARNING) << "Drop " << pending_qts_updates_.size() << " pending qts updates after receive empty difference"; - for (auto &pending_update : pending_qts_updates_) { - pending_update.second.promise.set_value(Unit()); - } + auto pending_qts_updates = std::move(pending_qts_updates_); pending_qts_updates_.clear(); + + for (auto &pending_update : pending_qts_updates) { + auto promises = std::move(pending_update.second.promises); + for (auto &promise : promises) { + promise.set_value(Unit()); + } + } } break; } @@ -1258,7 +1265,7 @@ void UpdatesManager::on_pending_updates(vectorsecond.promise.set_value(Unit()); // TODO - } + LOG_IF(WARNING, pending_seq_updates_.find(seq_begin) != pending_seq_updates_.end()) + << "Already have pending updates with seq = " << seq_begin << ", but receive it again from " << source; pending_seq_updates_.emplace(seq_begin, PendingUpdates(seq_begin, seq_end, date, std::move(updates), mpas.get_promise())); @@ -1492,10 +1497,9 @@ void UpdatesManager::add_pending_qts_update(tl_object_ptr auto &pending_update = pending_qts_updates_[qts]; if (pending_update.update != nullptr) { LOG(WARNING) << "Receive duplicate update with qts = " << qts; - pending_update.promise.set_value(Unit()); // TODO } pending_update.update = std::move(update); - pending_update.promise = std::move(promise); + pending_update.promises.push_back(std::move(promise)); return; } @@ -1620,6 +1624,7 @@ void UpdatesManager::process_pending_seq_updates() { LOG_IF(ERROR, update_it->second.seq_end > seq_) << "Strange updates coming with seq_begin = " << seq_begin << ", seq_end = " << update_it->second.seq_end << ", but seq = " << seq_; + update_it->second.promise.set_value(Unit()); } pending_seq_updates_.erase(update_it); } @@ -1643,8 +1648,15 @@ void UpdatesManager::process_pending_qts_updates() { if (qts > get_qts() + 1) { break; } + auto promise = PromiseCreator::lambda([promises = std::move(update_it->second.promises)](Unit) mutable { + for (auto &promise : promises) { + promise.set_value(Unit()); + } + }); if (qts == get_qts() + 1) { - process_qts_update(std::move(update_it->second.update), qts, std::move(update_it->second.promise)); + process_qts_update(std::move(update_it->second.update), qts, std::move(promise)); + } else { + promise.set_value(Unit()); } pending_qts_updates_.erase(update_it); } diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index 6ed66e9c5..c98a6737f 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -103,7 +103,7 @@ class UpdatesManager : public Actor { class PendingQtsUpdate { public: tl_object_ptr update; - Promise promise; + vector> promises; }; Td *td_; diff --git a/td/telegram/logevent/LogEventHelper.cpp b/td/telegram/logevent/LogEventHelper.cpp index 7c4efbb13..ced436ceb 100644 --- a/td/telegram/logevent/LogEventHelper.cpp +++ b/td/telegram/logevent/LogEventHelper.cpp @@ -9,7 +9,7 @@ #include "td/telegram/Global.h" #include "td/telegram/TdDb.h" -#include "tddb/td/db/binlog/BinlogHelper.h" +#include "td/db/binlog/BinlogHelper.h" #include "td/utils/logging.h" #include "td/utils/Status.h" diff --git a/tdactor/td/actor/ConcurrentScheduler.cpp b/tdactor/td/actor/ConcurrentScheduler.cpp index 1b1e70093..e6b45aec2 100644 --- a/tdactor/td/actor/ConcurrentScheduler.cpp +++ b/tdactor/td/actor/ConcurrentScheduler.cpp @@ -9,6 +9,7 @@ #include "td/utils/ExitGuard.h" #include "td/utils/MpscPollableQueue.h" #include "td/utils/port/thread_local.h" +#include "td/utils/ScopeGuard.h" #include @@ -137,10 +138,12 @@ void ConcurrentScheduler::finish() { #endif if (ExitGuard::is_exited()) { +#if !TD_THREAD_UNSUPPORTED && !TD_EVENTFD_UNSUPPORTED // prevent closing of schedulers from already killed by OS threads for (auto &thread : threads_) { thread.detach(); } +#endif #if TD_PORT_WINDOWS iocp_->interrupt_loop(); diff --git a/tdactor/td/actor/PromiseFuture.h b/tdactor/td/actor/PromiseFuture.h index e6ffbc8f5..8afcadf6e 100644 --- a/tdactor/td/actor/PromiseFuture.h +++ b/tdactor/td/actor/PromiseFuture.h @@ -12,6 +12,7 @@ #include "td/utils/Closure.h" #include "td/utils/common.h" #include "td/utils/invoke.h" // for tuple_for_each +#include "td/utils/MovableValue.h" #include "td/utils/ScopeGuard.h" #include "td/utils/Status.h" diff --git a/tdtl/td/tl/tl_config.cpp b/tdtl/td/tl/tl_config.cpp index bfe03875c..9e49a146a 100644 --- a/tdtl/td/tl/tl_config.cpp +++ b/tdtl/td/tl/tl_config.cpp @@ -4,7 +4,7 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_config.h" +#include "td/tl/tl_config.h" #include #include diff --git a/tdtl/td/tl/tl_config.h b/tdtl/td/tl/tl_config.h index afc3cb442..b05b31686 100644 --- a/tdtl/td/tl/tl_config.h +++ b/tdtl/td/tl/tl_config.h @@ -6,8 +6,8 @@ // #pragma once -#include "tl_core.h" -#include "tl_simple_parser.h" +#include "td/tl/tl_core.h" +#include "td/tl/tl_simple_parser.h" #include #include diff --git a/tdtl/td/tl/tl_core.cpp b/tdtl/td/tl/tl_core.cpp index 9e1c2bf61..f59f27d07 100644 --- a/tdtl/td/tl/tl_core.cpp +++ b/tdtl/td/tl/tl_core.cpp @@ -4,7 +4,7 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_core.h" +#include "td/tl/tl_core.h" #include diff --git a/tdtl/td/tl/tl_file_outputer.cpp b/tdtl/td/tl/tl_file_outputer.cpp index d27574a0f..9a57f07ba 100644 --- a/tdtl/td/tl/tl_file_outputer.cpp +++ b/tdtl/td/tl/tl_file_outputer.cpp @@ -4,7 +4,7 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_file_outputer.h" +#include "td/tl/tl_file_outputer.h" #include diff --git a/tdtl/td/tl/tl_file_outputer.h b/tdtl/td/tl/tl_file_outputer.h index d58b658ad..0ff34bbf0 100644 --- a/tdtl/td/tl/tl_file_outputer.h +++ b/tdtl/td/tl/tl_file_outputer.h @@ -6,7 +6,7 @@ // #pragma once -#include "tl_outputer.h" +#include "td/tl/tl_outputer.h" #include #include diff --git a/tdtl/td/tl/tl_file_utils.cpp b/tdtl/td/tl/tl_file_utils.cpp index b31a8d8b9..9ffc646a0 100644 --- a/tdtl/td/tl/tl_file_utils.cpp +++ b/tdtl/td/tl/tl_file_utils.cpp @@ -4,7 +4,7 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_file_utils.h" +#include "td/tl/tl_file_utils.h" #include #include diff --git a/tdtl/td/tl/tl_generate.cpp b/tdtl/td/tl/tl_generate.cpp index 9e3647431..9120e5e52 100644 --- a/tdtl/td/tl/tl_generate.cpp +++ b/tdtl/td/tl/tl_generate.cpp @@ -4,14 +4,14 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_generate.h" +#include "td/tl/tl_generate.h" -#include "tl_config.h" -#include "tl_core.h" -#include "tl_file_utils.h" -#include "tl_outputer.h" -#include "tl_string_outputer.h" -#include "tl_writer.h" +#include "td/tl/tl_config.h" +#include "td/tl/tl_core.h" +#include "td/tl/tl_file_utils.h" +#include "td/tl/tl_outputer.h" +#include "td/tl/tl_string_outputer.h" +#include "td/tl/tl_writer.h" #include #include diff --git a/tdtl/td/tl/tl_generate.h b/tdtl/td/tl/tl_generate.h index 96e3d8c35..795d38524 100644 --- a/tdtl/td/tl/tl_generate.h +++ b/tdtl/td/tl/tl_generate.h @@ -6,9 +6,9 @@ // #pragma once -#include "tl_config.h" -#include "tl_outputer.h" -#include "tl_writer.h" +#include "td/tl/tl_config.h" +#include "td/tl/tl_outputer.h" +#include "td/tl/tl_writer.h" #include diff --git a/tdtl/td/tl/tl_outputer.cpp b/tdtl/td/tl/tl_outputer.cpp index 3fae22107..b6e9f9bd1 100644 --- a/tdtl/td/tl/tl_outputer.cpp +++ b/tdtl/td/tl/tl_outputer.cpp @@ -4,7 +4,7 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_outputer.h" +#include "td/tl/tl_outputer.h" namespace td { namespace tl { diff --git a/tdtl/td/tl/tl_string_outputer.cpp b/tdtl/td/tl/tl_string_outputer.cpp index 0894b084b..cdafc2fca 100644 --- a/tdtl/td/tl/tl_string_outputer.cpp +++ b/tdtl/td/tl/tl_string_outputer.cpp @@ -4,7 +4,7 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_string_outputer.h" +#include "td/tl/tl_string_outputer.h" namespace td { namespace tl { diff --git a/tdtl/td/tl/tl_string_outputer.h b/tdtl/td/tl/tl_string_outputer.h index b343f49e2..ac9ce98e7 100644 --- a/tdtl/td/tl/tl_string_outputer.h +++ b/tdtl/td/tl/tl_string_outputer.h @@ -6,7 +6,7 @@ // #pragma once -#include "tl_outputer.h" +#include "td/tl/tl_outputer.h" #include diff --git a/tdtl/td/tl/tl_writer.cpp b/tdtl/td/tl/tl_writer.cpp index ad918d222..63581ba36 100644 --- a/tdtl/td/tl/tl_writer.cpp +++ b/tdtl/td/tl/tl_writer.cpp @@ -4,9 +4,9 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_writer.h" +#include "td/tl/tl_writer.h" -#include "tl_core.h" +#include "td/tl/tl_core.h" #include #include diff --git a/tdtl/td/tl/tl_writer.h b/tdtl/td/tl/tl_writer.h index e2b9a88a1..08d3dc0c0 100644 --- a/tdtl/td/tl/tl_writer.h +++ b/tdtl/td/tl/tl_writer.h @@ -6,7 +6,7 @@ // #pragma once -#include "tl_core.h" +#include "td/tl/tl_core.h" #include #include diff --git a/tdutils/CMakeLists.txt b/tdutils/CMakeLists.txt index f83b25c9e..b4c7481df 100644 --- a/tdutils/CMakeLists.txt +++ b/tdutils/CMakeLists.txt @@ -123,6 +123,7 @@ set(TDUTILS_SOURCE td/utils/port/EventFd.h td/utils/port/EventFdBase.h td/utils/port/FileFd.h + td/utils/port/FromApp.h td/utils/port/IPAddress.h td/utils/port/IoSlice.h td/utils/port/MemoryMapping.h diff --git a/tdutils/td/utils/BigNum.cpp b/tdutils/td/utils/BigNum.cpp index 7b3e2ed82..cadf7d074 100644 --- a/tdutils/td/utils/BigNum.cpp +++ b/tdutils/td/utils/BigNum.cpp @@ -147,7 +147,12 @@ bool BigNum::is_bit_set(int num) const { } bool BigNum::is_prime(BigNumContext &context) const { - int result = BN_is_prime_ex(impl_->big_num, BN_prime_checks, context.impl_->big_num_context, nullptr); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + int result = BN_check_prime(impl_->big_num, context.impl_->big_num_context, nullptr); +#else + int result = + BN_is_prime_ex(impl_->big_num, get_num_bits() > 2048 ? 128 : 64, context.impl_->big_num_context, nullptr); +#endif LOG_IF(FATAL, result == -1); return result == 1; } diff --git a/tdutils/td/utils/crypto.cpp b/tdutils/td/utils/crypto.cpp index febab300d..cf1c0effe 100644 --- a/tdutils/td/utils/crypto.cpp +++ b/tdutils/td/utils/crypto.cpp @@ -28,11 +28,17 @@ #include #include #include +#include #include #include #include #endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#include +#endif + #if TD_HAVE_ZLIB #include #endif @@ -674,21 +680,47 @@ void AesCtrState::decrypt(Slice from, MutableSlice to) { encrypt(from, to); } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +static void make_digest(Slice data, MutableSlice output, const EVP_MD *evp_md) { + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + LOG_IF(FATAL, ctx == nullptr); + int res = EVP_DigestInit_ex(ctx, evp_md, nullptr); + LOG_IF(FATAL, res != 1); + res = EVP_DigestUpdate(ctx, data.ubegin(), data.size()); + LOG_IF(FATAL, res != 1); + res = EVP_DigestFinal_ex(ctx, output.ubegin(), nullptr); + LOG_IF(FATAL, res != 1); + EVP_MD_CTX_free(ctx); +} +#endif + void sha1(Slice data, unsigned char output[20]) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + make_digest(data, MutableSlice(output, 20), EVP_sha1()); +#else auto result = SHA1(data.ubegin(), data.size(), output); CHECK(result == output); +#endif } void sha256(Slice data, MutableSlice output) { CHECK(output.size() >= 32); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + make_digest(data, output, EVP_sha256()); +#else auto result = SHA256(data.ubegin(), data.size(), output.ubegin()); CHECK(result == output.ubegin()); +#endif } void sha512(Slice data, MutableSlice output) { CHECK(output.size() >= 64); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + make_digest(data, output, EVP_sha512()); +#else auto result = SHA512(data.ubegin(), data.size(), output.ubegin()); CHECK(result == output.ubegin()); +#endif } string sha256(Slice data) { @@ -705,7 +737,27 @@ string sha512(Slice data) { class Sha256State::Impl { public: +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_MD_CTX *ctx_; + + Impl() { + ctx_ = EVP_MD_CTX_new(); + LOG_IF(FATAL, ctx_ == nullptr); + } + ~Impl() { + CHECK(ctx_ != nullptr); + EVP_MD_CTX_free(ctx_); + } +#else SHA256_CTX ctx_; + Impl() = default; + ~Impl() = default; +#endif + + Impl(const Impl &from) = delete; + Impl &operator=(const Impl &from) = delete; + Impl(Impl &&from) = delete; + Impl &operator=(Impl &&from) = delete; }; Sha256State::Sha256State() = default; @@ -737,7 +789,11 @@ void Sha256State::init() { impl_ = make_unique(); } CHECK(!is_inited_); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + int err = EVP_DigestInit_ex(impl_->ctx_, EVP_sha256(), nullptr); +#else int err = SHA256_Init(&impl_->ctx_); +#endif LOG_IF(FATAL, err != 1); is_inited_ = true; } @@ -745,7 +801,11 @@ void Sha256State::init() { void Sha256State::feed(Slice data) { CHECK(impl_); CHECK(is_inited_); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + int err = EVP_DigestUpdate(impl_->ctx_, data.ubegin(), data.size()); +#else int err = SHA256_Update(&impl_->ctx_, data.ubegin(), data.size()); +#endif LOG_IF(FATAL, err != 1); } @@ -753,7 +813,11 @@ void Sha256State::extract(MutableSlice output, bool destroy) { CHECK(output.size() >= 32); CHECK(impl_); CHECK(is_inited_); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + int err = EVP_DigestFinal_ex(impl_->ctx_, output.ubegin(), nullptr); +#else int err = SHA256_Final(output.ubegin(), &impl_->ctx_); +#endif LOG_IF(FATAL, err != 1); is_inited_ = false; if (destroy) { @@ -762,9 +826,13 @@ void Sha256State::extract(MutableSlice output, bool destroy) { } void md5(Slice input, MutableSlice output) { - CHECK(output.size() >= MD5_DIGEST_LENGTH); + CHECK(output.size() >= 16); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + make_digest(input, output, EVP_md5()); +#else auto result = MD5(input.ubegin(), input.size(), output.ubegin()); CHECK(result == output.ubegin()); +#endif } static void pbkdf2_impl(Slice password, Slice salt, int iteration_count, MutableSlice dest, const EVP_MD *evp_md) { @@ -812,22 +880,58 @@ void pbkdf2_sha512(Slice password, Slice salt, int iteration_count, MutableSlice pbkdf2_impl(password, salt, iteration_count, dest, EVP_sha512()); } -void hmac_sha256(Slice key, Slice message, MutableSlice dest) { - CHECK(dest.size() == 256 / 8); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +static void hmac_impl(const char *digest, Slice key, Slice message, MutableSlice dest) { + EVP_MAC *hmac = EVP_MAC_fetch(nullptr, "HMAC", nullptr); + LOG_IF(FATAL, hmac == nullptr); + + EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(hmac); + LOG_IF(FATAL, ctx == nullptr); + + OSSL_PARAM params[3]; + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, const_cast(digest), 0); + params[1] = + OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, const_cast(key.ubegin()), key.size()); + params[2] = OSSL_PARAM_construct_end(); + + int res = EVP_MAC_CTX_set_params(ctx, params); + LOG_IF(FATAL, res != 1); + res = EVP_MAC_init(ctx); + LOG_IF(FATAL, res != 1); + res = EVP_MAC_update(ctx, message.ubegin(), message.size()); + LOG_IF(FATAL, res != 1); + res = EVP_MAC_final(ctx, dest.ubegin(), nullptr, dest.size()); + LOG_IF(FATAL, res != 1); + + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(hmac); +} +#else +static void hmac_impl(const EVP_MD *evp_md, Slice key, Slice message, MutableSlice dest) { unsigned int len = 0; - auto result = HMAC(EVP_sha256(), key.ubegin(), narrow_cast(key.size()), message.ubegin(), + auto result = HMAC(evp_md, key.ubegin(), narrow_cast(key.size()), message.ubegin(), narrow_cast(message.size()), dest.ubegin(), &len); CHECK(result == dest.ubegin()); CHECK(len == dest.size()); } +#endif + +void hmac_sha256(Slice key, Slice message, MutableSlice dest) { + CHECK(dest.size() == 256 / 8); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + hmac_impl("SHA256", key, message, dest); +#else + hmac_impl(EVP_sha256(), key, message, dest); +#endif +} void hmac_sha512(Slice key, Slice message, MutableSlice dest) { CHECK(dest.size() == 512 / 8); - unsigned int len = 0; - auto result = HMAC(EVP_sha512(), key.ubegin(), narrow_cast(key.size()), message.ubegin(), - narrow_cast(message.size()), dest.ubegin(), &len); - CHECK(result == dest.ubegin()); - CHECK(len == dest.size()); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + hmac_impl("SHA512", key, message, dest); +#else + hmac_impl(EVP_sha512(), key, message, dest); +#endif } static int get_evp_pkey_type(EVP_PKEY *pkey) { diff --git a/tdutils/td/utils/logging.cpp b/tdutils/td/utils/logging.cpp index 9be298019..e99ec327a 100644 --- a/tdutils/td/utils/logging.cpp +++ b/tdutils/td/utils/logging.cpp @@ -204,19 +204,19 @@ class DefaultLog : public LogInterface { #elif TD_TIZEN switch (log_level) { case VERBOSITY_NAME(FATAL): - dlog_print(DLOG_ERROR, DLOG_TAG, slice.c_str()); + dlog_print(DLOG_ERROR, DLOG_TAG, "%s", slice.c_str()); break; case VERBOSITY_NAME(ERROR): - dlog_print(DLOG_ERROR, DLOG_TAG, slice.c_str()); + dlog_print(DLOG_ERROR, DLOG_TAG, "%s", slice.c_str()); break; case VERBOSITY_NAME(WARNING): - dlog_print(DLOG_WARN, DLOG_TAG, slice.c_str()); + dlog_print(DLOG_WARN, DLOG_TAG, "%s", slice.c_str()); break; case VERBOSITY_NAME(INFO): - dlog_print(DLOG_INFO, DLOG_TAG, slice.c_str()); + dlog_print(DLOG_INFO, DLOG_TAG, "%s", slice.c_str()); break; default: - dlog_print(DLOG_DEBUG, DLOG_TAG, slice.c_str()); + dlog_print(DLOG_DEBUG, DLOG_TAG, "%s", slice.c_str()); break; } #elif TD_EMSCRIPTEN diff --git a/tdutils/td/utils/port/FileFd.cpp b/tdutils/td/utils/port/FileFd.cpp index 634dacb64..274595b87 100644 --- a/tdutils/td/utils/port/FileFd.cpp +++ b/tdutils/td/utils/port/FileFd.cpp @@ -7,6 +7,7 @@ #include "td/utils/port/FileFd.h" #if TD_PORT_WINDOWS +#include "td/utils/port/FromApp.h" #include "td/utils/port/Stat.h" #include "td/utils/port/wstring_convert.h" #endif @@ -211,7 +212,8 @@ Result FileFd::open(CSlice filepath, int32 flags, int32 mode) { extended_parameters.dwSize = sizeof(extended_parameters); extended_parameters.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; extended_parameters.dwFileFlags = native_flags; - auto handle = CreateFile2(w_filepath.c_str(), desired_access, share_mode, creation_disposition, &extended_parameters); + auto handle = td::CreateFile2FromAppW(w_filepath.c_str(), desired_access, share_mode, creation_disposition, + &extended_parameters); #endif if (handle == INVALID_HANDLE_VALUE) { return OS_ERROR(PSLICE() << "File \"" << filepath << "\" can't be " << PrintFlags{flags}); diff --git a/tdutils/td/utils/port/FromApp.h b/tdutils/td/utils/port/FromApp.h new file mode 100644 index 000000000..16627b6e0 --- /dev/null +++ b/tdutils/td/utils/port/FromApp.h @@ -0,0 +1,90 @@ +#pragma once + +#include "td/utils/common.h" + +#ifdef TD_PORT_WINDOWS + +namespace td { + +#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) +inline HMODULE GetKernelModule() { + static const auto kernel_module = []() -> HMODULE { + MEMORY_BASIC_INFORMATION mbi; + if (VirtualQuery(VirtualQuery, &mbi, sizeof(MEMORY_BASIC_INFORMATION))) { + return reinterpret_cast(mbi.AllocationBase); + } + return nullptr; + }(); + return kernel_module; +} + +inline HMODULE LoadLibrary(LPCTSTR lpFileName) { + using pLoadLibrary = HMODULE(WINAPI *)(_In_ LPCTSTR); + static const auto proc_load_library = + reinterpret_cast(GetProcAddress(GetKernelModule(), "LoadLibraryW")); + return proc_load_library(lpFileName); +} + +inline HMODULE GetFromAppModule() { + static const HMODULE from_app_module = LoadLibrary(L"api-ms-win-core-file-fromapp-l1-1-0.dll"); + return from_app_module; +} +#endif + +template +T *get_from_app_function(const char *name, T *original_func) { +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) + return original_func; +#else + static T *func = [name, original_func]() -> T * { + auto func_pointer = GetProcAddress(GetFromAppModule(), name); + if (func_pointer == nullptr) { + return original_func; + } + return reinterpret_cast(func_pointer); + }(); + return func; +#endif +} + +inline HANDLE CreateFile2FromAppW(_In_ LPCWSTR lpFileName, _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode, + _In_ DWORD dwCreationDisposition, + _In_opt_ LPCREATEFILE2_EXTENDED_PARAMETERS pCreateExParams) { + auto func = get_from_app_function<0>("CreateFile2FromAppW", &CreateFile2); + return func(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, pCreateExParams); +} + +inline BOOL CreateDirectoryFromAppW(_In_ LPCWSTR lpPathName, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes) { + auto func = get_from_app_function<1>("CreateDirectoryFromAppW", &CreateDirectory); + return func(lpPathName, lpSecurityAttributes); +} + +inline BOOL RemoveDirectoryFromAppW(_In_ LPCWSTR lpPathName) { + auto func = get_from_app_function<2>("RemoveDirectoryFromAppW", &RemoveDirectory); + return func(lpPathName); +} + +inline BOOL DeleteFileFromAppW(_In_ LPCWSTR lpFileName) { + auto func = get_from_app_function<3>("DeleteFileFromAppW", &DeleteFile); + return func(lpFileName); +} + +inline BOOL MoveFileExFromAppW(_In_ LPCWSTR lpExistingFileName, _In_ LPCWSTR lpNewFileName, _In_ DWORD dwFlags) { + auto func = get_from_app_function<4>("MoveFileFromAppW", &MoveFileEx); + if (func != &MoveFileEx && (dwFlags & MOVEFILE_REPLACE_EXISTING) != 0) { + td::DeleteFileFromAppW(lpNewFileName); + } + return func(lpExistingFileName, lpNewFileName, dwFlags); +} + +inline HANDLE FindFirstFileExFromAppW(_In_ LPCWSTR lpFileName, _In_ FINDEX_INFO_LEVELS fInfoLevelId, + _Out_writes_bytes_(sizeof(WIN32_FIND_DATAW)) LPVOID lpFindFileData, + _In_ FINDEX_SEARCH_OPS fSearchOp, _Reserved_ LPVOID lpSearchFilter, + _In_ DWORD dwAdditionalFlags) { + auto func = get_from_app_function<5>("FindFirstFileExFromAppW", &FindFirstFileEx); + return func(lpFileName, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags); +} + +} // namespace td + +#endif diff --git a/tdutils/td/utils/port/StdStreams.cpp b/tdutils/td/utils/port/StdStreams.cpp index 30603e1de..45823cc67 100644 --- a/tdutils/td/utils/port/StdStreams.cpp +++ b/tdutils/td/utils/port/StdStreams.cpp @@ -127,11 +127,13 @@ class BufferedStdinImpl : public Iocp::Callback { break; } writer_.confirm_append(r_size.ok()); - if (iocp_ref_.post(0, this, nullptr)) { - inc_refcnt(); + inc_refcnt(); + if (!iocp_ref_.post(0, this, nullptr)) { + dec_refcnt(); } } if (!iocp_ref_.post(0, this, nullptr)) { + read_thread_.detach(); dec_refcnt(); } } diff --git a/tdutils/td/utils/port/path.cpp b/tdutils/td/utils/port/path.cpp index 5935d5ed1..58bfb1792 100644 --- a/tdutils/td/utils/port/path.cpp +++ b/tdutils/td/utils/port/path.cpp @@ -14,6 +14,7 @@ #include "td/utils/ScopeGuard.h" #if TD_PORT_WINDOWS +#include "td/utils/port/FromApp.h" #include "td/utils/port/wstring_convert.h" #include "td/utils/Random.h" #endif @@ -390,7 +391,7 @@ Status WalkPath::do_run(CSlice path, const detail::WalkFunction &func) { Status mkdir(CSlice dir, int32 mode) { TRY_RESULT(wdir, to_wstring(dir)); - auto status = CreateDirectoryW(wdir.c_str(), nullptr); + auto status = td::CreateDirectoryFromAppW(wdir.c_str(), nullptr); if (status == 0 && GetLastError() != ERROR_ALREADY_EXISTS) { return OS_ERROR(PSLICE() << "Can't create directory \"" << dir << '"'); } @@ -400,7 +401,7 @@ Status mkdir(CSlice dir, int32 mode) { Status rename(CSlice from, CSlice to) { TRY_RESULT(wfrom, to_wstring(from)); TRY_RESULT(wto, to_wstring(to)); - auto status = MoveFileExW(wfrom.c_str(), wto.c_str(), MOVEFILE_REPLACE_EXISTING); + auto status = td::MoveFileExFromAppW(wfrom.c_str(), wto.c_str(), MOVEFILE_REPLACE_EXISTING); if (status == 0) { return OS_ERROR(PSLICE() << "Can't rename \"" << from << "\" to \"" << to << '\"'); } @@ -443,7 +444,7 @@ Status chdir(CSlice dir) { Status rmdir(CSlice dir) { TRY_RESULT(wdir, to_wstring(dir)); - int status = RemoveDirectoryW(wdir.c_str()); + int status = td::RemoveDirectoryFromAppW(wdir.c_str()); if (!status) { return OS_ERROR(PSLICE() << "Can't delete directory \"" << dir << '"'); } @@ -452,7 +453,7 @@ Status rmdir(CSlice dir) { Status unlink(CSlice path) { TRY_RESULT(wpath, to_wstring(path)); - int status = DeleteFileW(wpath.c_str()); + int status = td::DeleteFileFromAppW(wpath.c_str()); if (!status) { return OS_ERROR(PSLICE() << "Can't unlink \"" << path << '"'); } @@ -549,7 +550,8 @@ static Result walk_path_dir(const std::wstring &dir_name, const std::function &func) { std::wstring name = dir_name + L"\\*"; WIN32_FIND_DATA file_data; - auto handle = FindFirstFileExW(name.c_str(), FindExInfoStandard, &file_data, FindExSearchNameMatch, nullptr, 0); + auto handle = + td::FindFirstFileExFromAppW(name.c_str(), FindExInfoStandard, &file_data, FindExSearchNameMatch, nullptr, 0); if (handle == INVALID_HANDLE_VALUE) { return OS_ERROR(PSLICE() << "FindFirstFileEx" << tag("name", from_wstring(name).ok())); } diff --git a/tdutils/test/crypto.cpp b/tdutils/test/crypto.cpp index cfa46d1a6..907806694 100644 --- a/tdutils/test/crypto.cpp +++ b/tdutils/test/crypto.cpp @@ -303,6 +303,32 @@ TEST(Crypto, md5) { ASSERT_STREQ(answers[i], td::base64_encode(output)); } } + +TEST(Crypto, hmac_sha256) { + td::vector answers{ + "t33rfT85UOe6N00BhsNwobE+f2TnW331HhdvQ4GdJp8=", "BQl5HF2jqhCz4JTqhAs+H364oxboh7QlluOMHuuRVh8=", + "NCCPuZBsAPBd/qr3SyeYE+e1RNgzkKJCS/+eXDBw8zU=", "mo3ahTkyLKfoQoYA0s7vRZULuH++vqwFJD0U5n9HHw0="}; + + for (std::size_t i = 0; i < strings.size(); i++) { + td::string output(32, '\0'); + td::hmac_sha256("cucumber", strings[i], output); + ASSERT_STREQ(answers[i], td::base64_encode(output)); + } +} + +TEST(Crypto, hmac_sha512) { + td::vector answers{ + "o28hTN1m/TGlm/VYxDIzOdUE4wMpQzO8hVcTkiP2ezEJXtrOvCjRnl20aOV1S8axA5Te0TzIjfIoEAtpzamIsA==", + "32X3GslSz0HDznSrCNt++ePRcFVSUSD+tfOVannyxS+yLt/om11qILCE64RFTS8/B84gByMzC3FuAlfcIam/KA==", + "BVqe5rK1Fg1i+C7xXTAzT9vDPcf3kQQpTtse6rT/EVDzKo9AUo4ZwyUyJ0KcLHoffIjul/TuJoBg+wLz7Z7r7g==", + "WASmeku5Pcfz7N0Kp4Q3I9sxtO2MiaBXA418CY0HvjdtmAo7QY+K3E0o9UemgGzz41KqeypzRC92MwOAOnXJLA=="}; + + for (std::size_t i = 0; i < strings.size(); i++) { + td::string output(64, '\0'); + td::hmac_sha512("cucumber", strings[i], output); + ASSERT_STREQ(answers[i], td::base64_encode(output)); + } +} #endif #if TD_HAVE_ZLIB diff --git a/test/mtproto.cpp b/test/mtproto.cpp index 873933291..8aca9dccd 100644 --- a/test/mtproto.cpp +++ b/test/mtproto.cpp @@ -711,3 +711,22 @@ TEST(Mtproto, TlsTransport) { } sched.finish(); } + +TEST(Mtproto, RSA) { + auto pem = td::Slice( + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIIBCgKCAQEAr4v4wxMDXIaMOh8bayF/NyoYdpcysn5EbjTIOZC0RkgzsRj3SGlu\n" + "52QSz+ysO41dQAjpFLgxPVJoOlxXokaOq827IfW0bGCm0doT5hxtedu9UCQKbE8j\n" + "lDOk+kWMXHPZFJKWRgKgTu9hcB3y3Vk+JFfLpq3d5ZB48B4bcwrRQnzkx5GhWOFX\n" + "x73ZgjO93eoQ2b/lDyXxK4B4IS+hZhjzezPZTI5upTRbs5ljlApsddsHrKk6jJNj\n" + "8Ygs/ps8e6ct82jLXbnndC9s8HjEvDvBPH9IPjv5JUlmHMBFZ5vFQIfbpo0u0+1P\n" + "n6bkEi5o7/ifoyVv2pAZTRwppTz0EuXD8QIDAQAB\n" + "-----END RSA PUBLIC KEY-----"); + auto rsa = RSA::from_pem_public_key(pem).move_as_ok(); + ASSERT_EQ(-7596991558377038078, rsa.get_fingerprint()); + ASSERT_EQ(256u, rsa.size()); + + string s(255, '\0'); + string to(256, '\0'); + ASSERT_EQ(256u, rsa.encrypt(MutableSlice(s).ubegin(), 10, 255, MutableSlice(to).ubegin(), 256)); +} diff --git a/test/tdclient.cpp b/test/tdclient.cpp index 46f731d4e..0ad3cebda 100644 --- a/test/tdclient.cpp +++ b/test/tdclient.cpp @@ -162,7 +162,7 @@ class TestClient : public td::Actor { td::Promise<> close_promise_; }; -class Task : public TestClient::Listener { +class TestClinetTask : public TestClient::Listener { public: void on_update(std::shared_ptr update) override { auto it = sent_queries_.find(update->id); @@ -198,7 +198,7 @@ class Task : public TestClient::Listener { } }; -class DoAuthentication : public Task { +class DoAuthentication : public TestClinetTask { public: DoAuthentication(td::string name, td::string phone, td::string code, td::Promise<> promise) : name_(std::move(name)), phone_(std::move(phone)), code_(std::move(code)), promise_(std::move(promise)) { @@ -274,7 +274,7 @@ class DoAuthentication : public Task { } }; -class SetUsername : public Task { +class SetUsername : public TestClinetTask { public: SetUsername(td::string username, td::Promise<> promise) : username_(std::move(username)), promise_(std::move(promise)) { @@ -339,7 +339,7 @@ class SetUsername : public Task { } }; -class CheckTestA : public Task { +class CheckTestA : public TestClinetTask { public: CheckTestA(td::string tag, td::Promise<> promise) : tag_(std::move(tag)), promise_(std::move(promise)) { } @@ -371,7 +371,7 @@ class CheckTestA : public Task { } }; -class TestA : public Task { +class TestA : public TestClinetTask { public: TestA(td::string tag, td::string username) : tag_(std::move(tag)), username_(std::move(username)) { } @@ -397,7 +397,7 @@ class TestA : public Task { td::string username_; }; -class TestSecretChat : public Task { +class TestSecretChat : public TestClinetTask { public: TestSecretChat(td::string tag, td::string username) : tag_(std::move(tag)), username_(std::move(username)) { } @@ -448,7 +448,7 @@ class TestSecretChat : public Task { td::int64 chat_id_ = 0; }; -class TestFileGenerated : public Task { +class TestFileGenerated : public TestClinetTask { public: TestFileGenerated(td::string tag, td::string username) : tag_(std::move(tag)), username_(std::move(username)) { } @@ -514,7 +514,7 @@ class TestFileGenerated : public Task { class GenerateFile : public td::Actor { public: - GenerateFile(Task *parent, td::int64 id, td::string original_path, td::string destination_path, + GenerateFile(TestClinetTask *parent, td::int64 id, td::string original_path, td::string destination_path, td::string conversion) : parent_(parent) , id_(id) @@ -524,7 +524,7 @@ class TestFileGenerated : public Task { } private: - Task *parent_; + TestClinetTask *parent_; td::int64 id_; td::string original_path_; td::string destination_path_; @@ -589,7 +589,7 @@ class TestFileGenerated : public Task { td::int64 chat_id_ = 0; }; -class CheckTestC : public Task { +class CheckTestC : public TestClinetTask { public: CheckTestC(td::string username, td::string tag, td::Promise<> promise) : username_(std::move(username)), tag_(std::move(tag)), promise_(std::move(promise)) { diff --git a/test/tqueue.cpp b/test/tqueue.cpp index 828491a2e..5d6eff2ac 100644 --- a/test/tqueue.cpp +++ b/test/tqueue.cpp @@ -10,18 +10,16 @@ #include "td/db/TQueue.h" #include "td/utils/buffer.h" +#include "td/utils/common.h" #include "td/utils/int_types.h" -#include "td/utils/misc.h" -#include "td/utils/port/path.h" +#include "td/utils/logging.h" #include "td/utils/Random.h" #include "td/utils/Slice.h" #include "td/utils/Span.h" -#include "td/utils/Status.h" #include "td/utils/tests.h" -#include "td/utils/VectorQueue.h" -#include -#include +#include +#include TEST(TQueue, hands) { td::TQueue::Event events[100];