1 // 2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 // 7 #pragma once 8 9 #include "td/utils/BigNum.h" 10 #include "td/utils/common.h" 11 #include "td/utils/Slice.h" 12 #include "td/utils/Status.h" 13 14 #include <utility> 15 16 namespace td { 17 namespace mtproto { 18 19 class DhCallback; 20 21 class DhHandshake { 22 public: 23 void set_config(int32 g_int, Slice prime_str); 24 25 static Status check_config(int32 g_int, Slice prime_str, DhCallback *callback); 26 has_config()27 bool has_config() const { 28 return has_config_; 29 } 30 void set_g_a_hash(Slice g_a_hash); 31 void set_g_a(Slice g_a_str); has_g_a()32 bool has_g_a() const { 33 return has_g_a_; 34 } 35 string get_g_a() const; 36 string get_g_b() const; 37 string get_g_b_hash() const; 38 Status run_checks(bool skip_config_check, DhCallback *callback) TD_WARN_UNUSED_RESULT; 39 40 BigNum get_g() const; 41 BigNum get_p() const; 42 BigNum get_b() const; 43 BigNum get_g_ab(); 44 45 std::pair<int64, string> gen_key(); 46 47 static int64 calc_key_id(Slice auth_key); 48 49 enum Flags { HasConfig = 1, HasGA = 2 }; 50 51 template <class StorerT> store(StorerT & storer)52 void store(StorerT &storer) const { 53 auto flags = 0; 54 if (has_config_) { 55 flags |= HasConfig; 56 } 57 if (has_g_a_) { 58 flags |= HasGA; 59 } 60 storer.store_int(flags); 61 62 if (has_config_) { 63 // prime_, prime_str_, b_, g_, g_int_, g_b_ 64 storer.store_string(prime_str_); 65 storer.store_string(b_.to_binary()); 66 storer.store_int(g_int_); 67 storer.store_string(g_b_.to_binary()); 68 } 69 if (has_g_a_) { 70 storer.store_string(g_a_.to_binary()); 71 } 72 } 73 template <class ParserT> parse(ParserT & parser)74 void parse(ParserT &parser) { 75 auto flags = parser.fetch_int(); 76 if (flags & HasConfig) { 77 has_config_ = true; 78 } 79 if (flags & HasGA) { 80 has_g_a_ = true; 81 } 82 if (has_config_) { 83 // prime_, prime_str_, b_, g_, g_int_, g_b_ 84 prime_str_ = parser.template fetch_string<std::string>(); 85 prime_ = BigNum::from_binary(prime_str_); 86 87 b_ = BigNum::from_binary(parser.template fetch_string<string>()); 88 89 g_int_ = parser.fetch_int(); 90 g_.set_value(g_int_); 91 92 g_b_ = BigNum::from_binary(parser.template fetch_string<string>()); 93 } 94 if (has_g_a_) { 95 g_a_ = BigNum::from_binary(parser.template fetch_string<string>()); 96 } 97 } 98 99 private: 100 static Status check_config(Slice prime_str, const BigNum &prime, int32 g_int, BigNumContext &ctx, 101 DhCallback *callback) TD_WARN_UNUSED_RESULT; 102 103 static Status dh_check(const BigNum &prime, const BigNum &g_a, const BigNum &g_b) TD_WARN_UNUSED_RESULT; 104 105 string prime_str_; 106 BigNum prime_; 107 BigNum g_; 108 int32 g_int_ = 0; 109 BigNum b_; 110 BigNum g_b_; 111 BigNum g_a_; 112 113 string g_a_hash_; 114 bool has_g_a_hash_{false}; 115 bool ok_g_a_hash_{false}; 116 117 bool has_config_ = false; 118 bool has_g_a_ = false; 119 120 BigNumContext ctx_; 121 }; 122 123 } // namespace mtproto 124 } // namespace td 125