mtproto_dc_key_creator.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "mtproto/core_types.h"
  9. #include "mtproto/mtproto_auth_key.h"
  10. #include "mtproto/connection_abstract.h"
  11. #include "base/basic_types.h"
  12. #include "base/expected.h"
  13. namespace MTP {
  14. class DcOptions;
  15. } // namespace MTP
  16. namespace MTP::details {
  17. struct DcKeyRequest {
  18. TimeId temporaryExpiresIn = 0;
  19. bool persistentNeeded = false;
  20. };
  21. enum class DcKeyError {
  22. UnknownPublicKey,
  23. Other,
  24. };
  25. struct DcKeyResult {
  26. AuthKeyPtr persistentKey;
  27. AuthKeyPtr temporaryKey;
  28. uint64 temporaryServerSalt = 0;
  29. uint64 persistentServerSalt = 0;
  30. };
  31. class DcKeyCreator final {
  32. public:
  33. struct Delegate {
  34. Fn<void(base::expected<DcKeyResult, DcKeyError>)> done;
  35. Fn<void(uint64)> sentSome;
  36. Fn<void()> receivedSome;
  37. };
  38. DcKeyCreator(
  39. DcId dcId,
  40. int16 protocolDcId,
  41. not_null<AbstractConnection*> connection,
  42. not_null<DcOptions*> dcOptions,
  43. Delegate delegate,
  44. DcKeyRequest request);
  45. ~DcKeyCreator();
  46. private:
  47. enum class Stage {
  48. None,
  49. WaitingPQ,
  50. WaitingDH,
  51. WaitingDone,
  52. Ready,
  53. };
  54. struct Data {
  55. Data()
  56. : new_nonce(*(MTPint256*)((uchar*)new_nonce_buf.data()))
  57. , auth_key_aux_hash(*(MTPlong*)((uchar*)new_nonce_buf.data() + 33)) {
  58. }
  59. MTPint128 nonce, server_nonce;
  60. // 32 bytes new_nonce + 1 check byte + 8 bytes of auth_key_aux_hash.
  61. bytes::array<41> new_nonce_buf{};
  62. MTPint256 &new_nonce;
  63. MTPlong &auth_key_aux_hash;
  64. MTPlong retry_id;
  65. int32 g = 0;
  66. bytes::array<32> aesKey;
  67. bytes::array<32> aesIV;
  68. MTPlong auth_key_hash;
  69. uint64 doneSalt = 0;
  70. };
  71. struct Attempt {
  72. ~Attempt();
  73. Data data;
  74. bytes::vector dhPrime;
  75. bytes::vector g_a;
  76. AuthKey::Data authKey = { { gsl::byte{} } };
  77. TimeId expiresIn = 0;
  78. uint32 retries = 0;
  79. Stage stage = Stage::None;
  80. };
  81. template <typename RequestType>
  82. void sendNotSecureRequest(const RequestType &request);
  83. template <
  84. typename RequestType,
  85. typename Response = typename RequestType::ResponseType>
  86. [[nodiscard]] std::optional<Response> readNotSecureResponse(
  87. gsl::span<const mtpPrime> answer);
  88. Attempt *attemptByNonce(const MTPint128 &nonce);
  89. void answered();
  90. void handleAnswer(gsl::span<const mtpPrime> answer);
  91. void pqSend(not_null<Attempt*> attempt, TimeId expiresIn);
  92. void pqAnswered(
  93. not_null<Attempt*> attempt,
  94. const MTPresPQ &data);
  95. void dhParamsAnswered(
  96. not_null<Attempt*> attempt,
  97. const MTPserver_DH_Params &data);
  98. void dhClientParamsSend(not_null<Attempt*> attempt);
  99. void dhClientParamsAnswered(
  100. not_null<Attempt*> attempt,
  101. const MTPset_client_DH_params_answer &data);
  102. void stopReceiving();
  103. void failed(DcKeyError error = DcKeyError::Other);
  104. void done();
  105. const not_null<AbstractConnection*> _connection;
  106. const not_null<DcOptions*> _dcOptions;
  107. const DcId _dcId = 0;
  108. const int16 _protocolDcId = 0;
  109. const DcKeyRequest _request;
  110. Delegate _delegate;
  111. Attempt _temporary;
  112. Attempt _persistent;
  113. };
  114. } // namespace MTP::details