mtproto_tls_socket.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932
  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. #include "mtproto/details/mtproto_tls_socket.h"
  8. #include "mtproto/details/mtproto_tcp_socket.h"
  9. #include "base/openssl_help.h"
  10. #include "base/bytes.h"
  11. #include "base/invoke_queued.h"
  12. #include "base/unixtime.h"
  13. #include <QtCore/QtEndian>
  14. #include <range/v3/algorithm/reverse.hpp>
  15. namespace MTP::details {
  16. namespace {
  17. constexpr auto kMaxGrease = 8;
  18. constexpr auto kClientHelloLength = 517;
  19. constexpr auto kHelloDigestLength = 32;
  20. constexpr auto kLengthSize = sizeof(uint16);
  21. const auto kServerHelloPart1 = qstr("\x16\x03\x03");
  22. const auto kServerHelloPart3 = qstr("\x14\x03\x03\x00\x01\x01\x17\x03\x03");
  23. constexpr auto kServerHelloDigestPosition = 11;
  24. const auto kServerHeader = qstr("\x17\x03\x03");
  25. constexpr auto kClientPartSize = 2878;
  26. const auto kClientPrefix = qstr("\x14\x03\x03\x00\x01\x01");
  27. const auto kClientHeader = qstr("\x17\x03\x03");
  28. using BigNum = openssl::BigNum;
  29. using BigNumContext = openssl::Context;
  30. [[nodiscard]] MTPTlsClientHello PrepareClientHelloRules() {
  31. using Scope = QVector<MTPTlsBlock>;
  32. using Permutation = std::vector<Scope>;
  33. using StackElement = std::variant<Scope, Permutation>;
  34. auto stack = std::vector<StackElement>();
  35. const auto pushToBack = [&](MTPTlsBlock &&block) {
  36. Expects(!stack.empty());
  37. if (const auto scope = std::get_if<Scope>(&stack.back())) {
  38. scope->push_back(std::move(block));
  39. } else {
  40. auto &permutation = v::get<Permutation>(stack.back());
  41. Assert(!permutation.empty());
  42. permutation.back().push_back(std::move(block));
  43. }
  44. };
  45. const auto S = [&](QByteArray data) {
  46. pushToBack(MTP_tlsBlockString(MTP_bytes(data)));
  47. };
  48. const auto Z = [&](int length) {
  49. pushToBack(MTP_tlsBlockZero(MTP_int(length)));
  50. };
  51. const auto G = [&](int seed) {
  52. pushToBack(MTP_tlsBlockGrease(MTP_int(seed)));
  53. };
  54. const auto R = [&](int length) {
  55. pushToBack(MTP_tlsBlockRandom(MTP_int(length)));
  56. };
  57. const auto D = [&] {
  58. pushToBack(MTP_tlsBlockDomain());
  59. };
  60. const auto K = [&] {
  61. pushToBack(MTP_tlsBlockPublicKey());
  62. };
  63. const auto OpenScope = [&] {
  64. stack.emplace_back(Scope());
  65. };
  66. const auto CloseScope = [&] {
  67. Expects(stack.size() > 1);
  68. Expects(v::is<Scope>(stack.back()));
  69. const auto blocks = std::move(v::get<Scope>(stack.back()));
  70. stack.pop_back();
  71. pushToBack(MTP_tlsBlockScope(MTP_vector<MTPTlsBlock>(blocks)));
  72. };
  73. const auto OpenPermutation = [&] {
  74. stack.emplace_back(Permutation());
  75. };
  76. const auto ClosePermutation = [&] {
  77. Expects(stack.size() > 1);
  78. Expects(v::is<Permutation>(stack.back()));
  79. const auto list = std::move(v::get<Permutation>(stack.back()));
  80. stack.pop_back();
  81. const auto wrapped = list | ranges::views::transform([](
  82. const QVector<MTPTlsBlock> &elements) {
  83. return MTP_vector<MTPTlsBlock>(elements);
  84. }) | ranges::to<QVector<MTPVector<MTPTlsBlock>>>();
  85. pushToBack(MTP_tlsBlockPermutation(
  86. MTP_vector<MTPVector<MTPTlsBlock>>(wrapped)));
  87. };
  88. const auto StartPermutationElement = [&] {
  89. Expects(stack.size() > 1);
  90. Expects(v::is<Permutation>(stack.back()));
  91. v::get<Permutation>(stack.back()).emplace_back();
  92. };
  93. const auto Finish = [&] {
  94. Expects(stack.size() == 1);
  95. Expects(v::is<Scope>(stack.back()));
  96. return v::get<Scope>(stack.back());
  97. };
  98. stack.emplace_back(Scope());
  99. S("\x16\x03\x01\x02\x00\x01\x00\x01\xfc\x03\x03"_q);
  100. Z(32);
  101. S("\x20"_q);
  102. R(32);
  103. S("\x00\x20"_q);
  104. G(0);
  105. S(""
  106. "\x13\x01\x13\x02\x13\x03\xc0\x2b\xc0\x2f\xc0\x2c\xc0\x30\xcc\xa9"
  107. "\xcc\xa8\xc0\x13\xc0\x14\x00\x9c\x00\x9d\x00\x2f\x00\x35\x01\x00"
  108. "\x01\x93"_q);
  109. G(2);
  110. S("\x00\x00"_q);
  111. OpenPermutation(); {
  112. StartPermutationElement(); {
  113. S("\x00\x00"_q);
  114. OpenScope();
  115. OpenScope();
  116. S("\x00"_q);
  117. OpenScope();
  118. D();
  119. CloseScope();
  120. CloseScope();
  121. CloseScope();
  122. }
  123. StartPermutationElement(); {
  124. S("\x00\x05\x00\x05\x01\x00\x00\x00\x00"_q);
  125. }
  126. StartPermutationElement(); {
  127. S("\x00\x0a\x00\x0a\x00\x08"_q);
  128. G(4);
  129. S("\x00\x1d\x00\x17\x00\x18"_q);
  130. }
  131. StartPermutationElement(); {
  132. S("\x00\x0b\x00\x02\x01\x00"_q);
  133. }
  134. StartPermutationElement(); {
  135. S(""
  136. "\x00\x0d\x00\x12\x00\x10\x04\x03\x08\x04\x04\x01\x05\x03"
  137. "\x08\x05\x05\x01\x08\x06\x06\x01"_q);
  138. }
  139. StartPermutationElement(); {
  140. S(""
  141. "\x00\x10\x00\x0e\x00\x0c\x02\x68\x32\x08\x68\x74\x74\x70"
  142. "\x2f\x31\x2e\x31"_q);
  143. }
  144. StartPermutationElement(); {
  145. S("\x00\x12\x00\x00"_q);
  146. }
  147. StartPermutationElement(); {
  148. S("\x00\x17\x00\x00"_q);
  149. }
  150. StartPermutationElement(); {
  151. S("\x00\x1b\x00\x03\x02\x00\x02"_q);
  152. }
  153. StartPermutationElement(); {
  154. S("\x00\x23\x00\x00"_q);
  155. }
  156. StartPermutationElement(); {
  157. S("\x00\x2b\x00\x07\x06"_q);
  158. G(6);
  159. S("\x03\x04\x03\x03"_q);
  160. }
  161. StartPermutationElement(); {
  162. S("\x00\x2d\x00\x02\x01\x01"_q);
  163. }
  164. StartPermutationElement(); {
  165. S("\x00\x33\x00\x2b\x00\x29"_q);
  166. G(4);
  167. S("\x00\x01\x00\x00\x1d\x00\x20"_q);
  168. K();
  169. }
  170. StartPermutationElement(); {
  171. S("\x44\x69\x00\x05\x00\x03\x02\x68\x32"_q);
  172. }
  173. StartPermutationElement(); {
  174. S("\xff\x01\x00\x01\x00"_q);
  175. }
  176. } ClosePermutation();
  177. G(3);
  178. S("\x00\x01\x00\x00\x15"_q);
  179. return MTP_tlsClientHello(MTP_vector<MTPTlsBlock>(Finish()));
  180. }
  181. [[nodiscard]] bytes::vector PrepareGreases() {
  182. auto result = bytes::vector(kMaxGrease);
  183. bytes::set_random(result);
  184. for (auto &byte : result) {
  185. byte = bytes::type((uchar(byte) & 0xF0) + 0x0A);
  186. }
  187. static_assert(kMaxGrease % 2 == 0);
  188. for (auto i = 0; i != kMaxGrease; i += 2) {
  189. if (result[i] == result[i + 1]) {
  190. result[i + 1] = bytes::type(uchar(result[i + 1]) ^ 0x10);
  191. }
  192. }
  193. return result;
  194. }
  195. // Returns y^2 = x^3 + 486662 * x^2 + x.
  196. [[nodiscard]] BigNum GenerateY2(
  197. const BigNum &x,
  198. const BigNum &mod,
  199. const BigNumContext &context) {
  200. auto coef = BigNum(486662);
  201. auto y = BigNum::ModAdd(x, coef, mod, context);
  202. y.setModMul(y, x, mod, context);
  203. coef.setWord(1);
  204. y.setModAdd(y, coef, mod, context);
  205. return BigNum::ModMul(y, x, mod, context);
  206. }
  207. // Returns x_2 = (x^2 - 1)^2/(4*y^2).
  208. [[nodiscard]] BigNum GenerateX2(
  209. const BigNum &x,
  210. const BigNum &mod,
  211. const BigNumContext &context) {
  212. auto denominator = GenerateY2(x, mod, context);
  213. auto coef = BigNum(4);
  214. denominator.setModMul(denominator, coef, mod, context);
  215. auto numerator = BigNum::ModMul(x, x, mod, context);
  216. coef.setWord(1);
  217. numerator.setModSub(numerator, coef, mod, context);
  218. numerator.setModMul(numerator, numerator, mod, context);
  219. denominator.setModInverse(denominator, mod, context);
  220. return BigNum::ModMul(numerator, denominator, mod, context);
  221. }
  222. [[nodiscard]] bytes::vector GeneratePublicKey() {
  223. const auto context = BigNumContext();
  224. const char modBytes[] = ""
  225. "\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
  226. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xed";
  227. const char powBytes[] = ""
  228. "\x3f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
  229. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf6";
  230. const auto mod = BigNum(bytes::make_span(modBytes).subspan(0, 32));
  231. const auto pow = BigNum(bytes::make_span(powBytes).subspan(0, 32));
  232. auto x = BigNum();
  233. do {
  234. while (true) {
  235. auto random = bytes::vector(32);
  236. bytes::set_random(random);
  237. random[31] &= bytes::type(0x7FU);
  238. x.setBytes(random);
  239. x.setModMul(x, x, mod, context);
  240. auto y = GenerateY2(x, mod, context);
  241. if (BigNum::ModExp(y, pow, mod, context).isOne()) {
  242. break;
  243. }
  244. }
  245. for (auto i = 0; i != 3; ++i) {
  246. x = GenerateX2(x, mod, context);
  247. }
  248. const auto xBytes = x.getBytes();
  249. Assert(!xBytes.empty());
  250. Assert(xBytes.size() <= 32);
  251. } while (x.bytesSize() == 32);
  252. const auto xBytes = x.getBytes();
  253. auto result = bytes::vector(32, bytes::type());
  254. bytes::copy(
  255. bytes::make_span(result).subspan(32 - xBytes.size()),
  256. xBytes);
  257. ranges::reverse(result);
  258. //auto string = QString();
  259. //string.reserve(64);
  260. //for (const auto byte : result) {
  261. // const auto code = uchar(byte);
  262. // const auto hex = [](uchar value) -> char {
  263. // if (value >= 0 && value <= 9) {
  264. // return '0' + value;
  265. // } else if (value >= 10 && value <= 15) {
  266. // return 'a' + (value - 10);
  267. // }
  268. // return '-';
  269. // };
  270. // string.append(hex(code / 16)).append(hex(code % 16));
  271. //}
  272. //LOG(("KEY: %1").arg(string));
  273. return result;
  274. }
  275. struct ClientHello {
  276. QByteArray data;
  277. QByteArray digest;
  278. };
  279. class Generator {
  280. public:
  281. Generator(
  282. const MTPTlsClientHello &rules,
  283. bytes::const_span domain,
  284. bytes::const_span key);
  285. [[nodiscard]] ClientHello take();
  286. private:
  287. class Part final {
  288. public:
  289. explicit Part(
  290. bytes::const_span domain,
  291. const bytes::vector &greases);
  292. [[nodiscard]] bytes::span grow(int size);
  293. void writeBlocks(const QVector<MTPTlsBlock> &blocks);
  294. void writeBlock(const MTPTlsBlock &data);
  295. void writeBlock(const MTPDtlsBlockString &data);
  296. void writeBlock(const MTPDtlsBlockZero &data);
  297. void writeBlock(const MTPDtlsBlockGrease &data);
  298. void writeBlock(const MTPDtlsBlockRandom &data);
  299. void writeBlock(const MTPDtlsBlockDomain &data);
  300. void writeBlock(const MTPDtlsBlockPublicKey &data);
  301. void writeBlock(const MTPDtlsBlockScope &data);
  302. void writeBlock(const MTPDtlsBlockPermutation &data);
  303. void finalize(bytes::const_span key);
  304. [[nodiscard]] QByteArray extractDigest() const;
  305. [[nodiscard]] bool error() const;
  306. [[nodiscard]] QByteArray take();
  307. private:
  308. void writePadding();
  309. void writeDigest(bytes::const_span key);
  310. void injectTimestamp();
  311. bytes::const_span _domain;
  312. const bytes::vector &_greases;
  313. QByteArray _result;
  314. const char *_data = nullptr;
  315. int _digestPosition = -1;
  316. bool _error = false;
  317. };
  318. bytes::vector _greases;
  319. Part _result;
  320. QByteArray _digest;
  321. };
  322. Generator::Part::Part(
  323. bytes::const_span domain,
  324. const bytes::vector &greases)
  325. : _domain(domain)
  326. , _greases(greases) {
  327. _result.reserve(kClientHelloLength);
  328. _data = _result.constData();
  329. }
  330. bool Generator::Part::error() const {
  331. return _error;
  332. }
  333. QByteArray Generator::Part::take() {
  334. Expects(_error || _result.constData() == _data);
  335. return _error ? QByteArray() : std::move(_result);
  336. }
  337. bytes::span Generator::Part::grow(int size) {
  338. if (_error
  339. || size <= 0
  340. || _result.size() + size > kClientHelloLength) {
  341. _error = true;
  342. return bytes::span();
  343. }
  344. const auto offset = _result.size();
  345. _result.resize(offset + size);
  346. return bytes::make_detached_span(_result).subspan(offset);
  347. }
  348. void Generator::Part::writeBlocks(const QVector<MTPTlsBlock> &blocks) {
  349. for (const auto &block : blocks) {
  350. writeBlock(block);
  351. }
  352. }
  353. void Generator::Part::writeBlock(const MTPTlsBlock &data) {
  354. data.match([&](const auto &data) {
  355. writeBlock(data);
  356. });
  357. }
  358. void Generator::Part::writeBlock(const MTPDtlsBlockString &data) {
  359. const auto &bytes = data.vdata().v;
  360. const auto storage = grow(bytes.size());
  361. if (storage.empty()) {
  362. return;
  363. }
  364. bytes::copy(storage, bytes::make_span(bytes));
  365. }
  366. void Generator::Part::writeBlock(const MTPDtlsBlockZero &data) {
  367. const auto length = data.vlength().v;
  368. const auto already = _result.size();
  369. const auto storage = grow(length);
  370. if (storage.empty()) {
  371. return;
  372. }
  373. if (length == kHelloDigestLength && _digestPosition < 0) {
  374. _digestPosition = already;
  375. }
  376. bytes::set_with_const(storage, bytes::type(0));
  377. }
  378. void Generator::Part::writeBlock(const MTPDtlsBlockGrease &data) {
  379. const auto seed = data.vseed().v;
  380. if (seed < 0 || seed >= _greases.size()) {
  381. _error = true;
  382. return;
  383. }
  384. const auto storage = grow(2);
  385. if (storage.empty()) {
  386. return;
  387. }
  388. bytes::set_with_const(storage, _greases[seed]);
  389. }
  390. void Generator::Part::writeBlock(const MTPDtlsBlockRandom &data) {
  391. const auto length = data.vlength().v;
  392. const auto storage = grow(length);
  393. if (storage.empty()) {
  394. return;
  395. }
  396. bytes::set_random(storage);
  397. }
  398. void Generator::Part::writeBlock(const MTPDtlsBlockDomain &data) {
  399. const auto storage = grow(_domain.size());
  400. if (storage.empty()) {
  401. return;
  402. }
  403. bytes::copy(storage, _domain);
  404. }
  405. void Generator::Part::writeBlock(const MTPDtlsBlockPublicKey &data) {
  406. const auto key = GeneratePublicKey();
  407. const auto storage = grow(key.size());
  408. if (storage.empty()) {
  409. return;
  410. }
  411. bytes::copy(storage, key);
  412. }
  413. void Generator::Part::writeBlock(const MTPDtlsBlockScope &data) {
  414. const auto storage = grow(kLengthSize);
  415. if (storage.empty()) {
  416. return;
  417. }
  418. const auto already = _result.size();
  419. writeBlocks(data.ventries().v);
  420. const auto length = qToBigEndian(uint16(_result.size() - already));
  421. bytes::copy(storage, bytes::object_as_span(&length));
  422. }
  423. void Generator::Part::writeBlock(const MTPDtlsBlockPermutation &data) {
  424. auto list = std::vector<QByteArray>();
  425. list.reserve(data.ventries().v.size());
  426. for (const auto &inner : data.ventries().v) {
  427. auto part = Part(_domain, _greases);
  428. part.writeBlocks(inner.v);
  429. if (part.error()) {
  430. _error = true;
  431. return;
  432. }
  433. list.push_back(part.take());
  434. }
  435. ranges::shuffle(list);
  436. for (const auto &element : list) {
  437. const auto storage = grow(element.size());
  438. if (storage.empty()) {
  439. return;
  440. }
  441. bytes::copy(storage, bytes::make_span(element));
  442. }
  443. }
  444. void Generator::Part::finalize(bytes::const_span key) {
  445. if (_error) {
  446. return;
  447. } else if (_digestPosition < 0) {
  448. _error = true;
  449. return;
  450. }
  451. writePadding();
  452. writeDigest(key);
  453. injectTimestamp();
  454. }
  455. QByteArray Generator::Part::extractDigest() const {
  456. if (_digestPosition < 0) {
  457. return {};
  458. }
  459. return _result.mid(_digestPosition, kHelloDigestLength);
  460. }
  461. void Generator::Part::writePadding() {
  462. Expects(_result.size() <= kClientHelloLength - kLengthSize);
  463. const auto padding = kClientHelloLength - kLengthSize - _result.size();
  464. writeBlock(MTP_tlsBlockScope(
  465. MTP_vector<MTPTlsBlock>(1, MTP_tlsBlockZero(MTP_int(padding)))));
  466. }
  467. void Generator::Part::writeDigest(bytes::const_span key) {
  468. Expects(_digestPosition >= 0);
  469. bytes::copy(
  470. bytes::make_detached_span(_result).subspan(_digestPosition),
  471. openssl::HmacSha256(key, bytes::make_span(_result)));
  472. }
  473. void Generator::Part::injectTimestamp() {
  474. Expects(_digestPosition >= 0);
  475. const auto storage = bytes::make_detached_span(_result).subspan(
  476. _digestPosition + kHelloDigestLength - sizeof(int32),
  477. sizeof(int32));
  478. auto already = int32();
  479. bytes::copy(bytes::object_as_span(&already), storage);
  480. already ^= qToLittleEndian(int32(base::unixtime::http_now()));
  481. bytes::copy(storage, bytes::object_as_span(&already));
  482. }
  483. Generator::Generator(
  484. const MTPTlsClientHello &rules,
  485. bytes::const_span domain,
  486. bytes::const_span key)
  487. : _greases(PrepareGreases())
  488. , _result(domain, _greases) {
  489. _result.writeBlocks(rules.match([&](const MTPDtlsClientHello &data) {
  490. return data.vblocks().v;
  491. }));
  492. _result.finalize(key);
  493. }
  494. ClientHello Generator::take() {
  495. auto digest = _result.extractDigest();
  496. return { _result.take(), std::move(digest) };
  497. }
  498. [[nodiscard]] ClientHello PrepareClientHello(
  499. const MTPTlsClientHello &rules,
  500. bytes::const_span domain,
  501. bytes::const_span key) {
  502. return Generator(rules, domain, key).take();
  503. }
  504. [[nodiscard]] bool CheckPart(bytes::const_span data, QLatin1String check) {
  505. if (data.size() < check.size()) {
  506. return false;
  507. }
  508. return !bytes::compare(
  509. data.subspan(0, check.size()),
  510. bytes::make_span(check.data(), check.size()));
  511. }
  512. [[nodiscard]] int ReadPartLength(bytes::const_span data, int offset) {
  513. const auto storage = data.subspan(offset, kLengthSize);
  514. return qFromBigEndian(
  515. *reinterpret_cast<const uint16*>(storage.data()));
  516. }
  517. } // namespace
  518. TlsSocket::TlsSocket(
  519. not_null<QThread*> thread,
  520. const bytes::vector &secret,
  521. const QNetworkProxy &proxy,
  522. bool protocolForFiles)
  523. : AbstractSocket(thread)
  524. , _secret(secret) {
  525. Expects(_secret.size() >= 21 && _secret[0] == bytes::type(0xEE));
  526. _socket.moveToThread(thread);
  527. _socket.setProxy(proxy);
  528. if (protocolForFiles) {
  529. _socket.setSocketOption(
  530. QAbstractSocket::SendBufferSizeSocketOption,
  531. kFilesSendBufferSize);
  532. _socket.setSocketOption(
  533. QAbstractSocket::ReceiveBufferSizeSocketOption,
  534. kFilesReceiveBufferSize);
  535. }
  536. const auto wrap = [&](auto handler) {
  537. return [=](auto &&...args) {
  538. InvokeQueued(this, [=] { handler(args...); });
  539. };
  540. };
  541. using Error = QAbstractSocket::SocketError;
  542. connect(
  543. &_socket,
  544. &QTcpSocket::connected,
  545. wrap([=] { plainConnected(); }));
  546. connect(
  547. &_socket,
  548. &QTcpSocket::disconnected,
  549. wrap([=] { plainDisconnected(); }));
  550. connect(
  551. &_socket,
  552. &QTcpSocket::readyRead,
  553. wrap([=] { plainReadyRead(); }));
  554. connect(
  555. &_socket,
  556. &QAbstractSocket::errorOccurred,
  557. wrap([=](Error e) { handleError(e); }));
  558. }
  559. bytes::const_span TlsSocket::domainFromSecret() const {
  560. return bytes::make_span(_secret).subspan(17);
  561. }
  562. bytes::const_span TlsSocket::keyFromSecret() const {
  563. return bytes::make_span(_secret).subspan(1, 16);
  564. }
  565. void TlsSocket::plainConnected() {
  566. if (_state != State::Connecting) {
  567. return;
  568. }
  569. static const auto kClientHelloRules = PrepareClientHelloRules();
  570. const auto hello = PrepareClientHello(
  571. kClientHelloRules,
  572. domainFromSecret(),
  573. keyFromSecret());
  574. if (hello.data.isEmpty()) {
  575. logError(888, "Could not generate Client Hello.");
  576. _state = State::Error;
  577. _error.fire({});
  578. } else {
  579. _state = State::WaitingHello;
  580. _incoming = hello.digest;
  581. _socket.write(hello.data);
  582. }
  583. }
  584. void TlsSocket::plainDisconnected() {
  585. _state = State::NotConnected;
  586. _incoming = QByteArray();
  587. _serverHelloLength = 0;
  588. _incomingGoodDataOffset = 0;
  589. _incomingGoodDataLimit = 0;
  590. _disconnected.fire({});
  591. }
  592. void TlsSocket::plainReadyRead() {
  593. switch (_state) {
  594. case State::WaitingHello: return readHello();
  595. case State::Connected: return readData();
  596. }
  597. }
  598. bool TlsSocket::requiredHelloPartReady() const {
  599. return _incoming.size() >= kHelloDigestLength + _serverHelloLength;
  600. }
  601. void TlsSocket::readHello() {
  602. const auto parts1Size = kServerHelloPart1.size() + kLengthSize;
  603. if (!_serverHelloLength) {
  604. _serverHelloLength = parts1Size;
  605. }
  606. while (!requiredHelloPartReady()) {
  607. if (!_socket.bytesAvailable()) {
  608. return;
  609. }
  610. _incoming.append(_socket.readAll());
  611. }
  612. checkHelloParts12(parts1Size);
  613. }
  614. void TlsSocket::checkHelloParts12(int parts1Size) {
  615. const auto data = bytes::make_span(_incoming).subspan(
  616. kHelloDigestLength,
  617. parts1Size);
  618. const auto part2Size = ReadPartLength(data, parts1Size - kLengthSize);
  619. const auto parts123Size = parts1Size
  620. + part2Size
  621. + kServerHelloPart3.size()
  622. + kLengthSize;
  623. if (_serverHelloLength == parts1Size) {
  624. const auto part1Offset = parts1Size
  625. - kLengthSize
  626. - kServerHelloPart1.size();
  627. if (!CheckPart(data.subspan(part1Offset), kServerHelloPart1)) {
  628. logError(888, "Bad Server Hello part1.");
  629. handleError();
  630. return;
  631. }
  632. _serverHelloLength = parts123Size;
  633. if (!requiredHelloPartReady()) {
  634. readHello();
  635. return;
  636. }
  637. }
  638. checkHelloParts34(parts123Size);
  639. }
  640. void TlsSocket::checkHelloParts34(int parts123Size) {
  641. const auto data = bytes::make_span(_incoming).subspan(
  642. kHelloDigestLength,
  643. parts123Size);
  644. const auto part4Size = ReadPartLength(data, parts123Size - kLengthSize);
  645. const auto full = parts123Size + part4Size;
  646. if (_serverHelloLength == parts123Size) {
  647. const auto part3Offset = parts123Size
  648. - kLengthSize
  649. - kServerHelloPart3.size();
  650. if (!CheckPart(data.subspan(part3Offset), kServerHelloPart3)) {
  651. logError(888, "Bad Server Hello part.");
  652. handleError();
  653. return;
  654. }
  655. _serverHelloLength = full;
  656. if (!requiredHelloPartReady()) {
  657. readHello();
  658. return;
  659. }
  660. }
  661. checkHelloDigest();
  662. }
  663. void TlsSocket::checkHelloDigest() {
  664. const auto fulldata = bytes::make_detached_span(_incoming).subspan(
  665. 0,
  666. kHelloDigestLength + _serverHelloLength);
  667. const auto digest = fulldata.subspan(
  668. kHelloDigestLength + kServerHelloDigestPosition,
  669. kHelloDigestLength);
  670. const auto digestCopy = bytes::make_vector(digest);
  671. bytes::set_with_const(digest, bytes::type(0));
  672. const auto check = openssl::HmacSha256(keyFromSecret(), fulldata);
  673. if (bytes::compare(digestCopy, check) != 0) {
  674. logError(888, "Bad Server Hello digest.");
  675. handleError();
  676. return;
  677. }
  678. shiftIncomingBy(fulldata.size());
  679. if (!_incoming.isEmpty()) {
  680. InvokeQueued(this, [=] {
  681. if (!checkNextPacket()) {
  682. handleError();
  683. }
  684. });
  685. }
  686. _incomingGoodDataOffset = _incomingGoodDataLimit = 0;
  687. _state = State::Connected;
  688. _connected.fire({});
  689. }
  690. void TlsSocket::readData() {
  691. if (!isConnected()) {
  692. return;
  693. }
  694. _incoming.append(_socket.readAll());
  695. if (!checkNextPacket()) {
  696. handleError();
  697. } else if (hasBytesAvailable()) {
  698. _readyRead.fire({});
  699. }
  700. }
  701. bool TlsSocket::checkNextPacket() {
  702. auto offset = 0;
  703. const auto incoming = bytes::make_span(_incoming);
  704. while (!_incomingGoodDataLimit) {
  705. const auto fullHeader = kServerHeader.size() + kLengthSize;
  706. if (incoming.size() <= offset + fullHeader) {
  707. return true;
  708. }
  709. if (!CheckPart(incoming.subspan(offset), kServerHeader)) {
  710. logError(888, "Bad packet header.");
  711. return false;
  712. }
  713. const auto length = ReadPartLength(
  714. incoming,
  715. offset + kServerHeader.size());
  716. if (length > 0) {
  717. if (offset > 0) {
  718. shiftIncomingBy(offset);
  719. }
  720. _incomingGoodDataOffset = fullHeader;
  721. _incomingGoodDataLimit = length;
  722. } else {
  723. offset += kServerHeader.size() + kLengthSize + length;
  724. }
  725. }
  726. return true;
  727. }
  728. void TlsSocket::shiftIncomingBy(int amount) {
  729. Expects(_incomingGoodDataOffset == 0);
  730. Expects(_incomingGoodDataLimit == 0);
  731. const auto incoming = bytes::make_detached_span(_incoming);
  732. if (incoming.size() > amount) {
  733. bytes::move(incoming, incoming.subspan(amount));
  734. _incoming.chop(amount);
  735. } else {
  736. _incoming.clear();
  737. }
  738. }
  739. void TlsSocket::connectToHost(const QString &address, int port) {
  740. Expects(_state == State::NotConnected);
  741. _state = State::Connecting;
  742. _socket.connectToHost(address, port);
  743. }
  744. bool TlsSocket::isGoodStartNonce(bytes::const_span nonce) {
  745. return true;
  746. }
  747. void TlsSocket::timedOut() {
  748. _syncTimeRequests.fire({});
  749. }
  750. bool TlsSocket::isConnected() {
  751. return (_state == State::Connected);
  752. }
  753. bool TlsSocket::hasBytesAvailable() {
  754. return (_incomingGoodDataLimit > 0)
  755. && (_incomingGoodDataOffset < _incoming.size());
  756. }
  757. int64 TlsSocket::read(bytes::span buffer) {
  758. auto written = int64(0);
  759. while (_incomingGoodDataLimit) {
  760. const auto available = std::min(
  761. _incomingGoodDataLimit,
  762. int(_incoming.size()) - _incomingGoodDataOffset);
  763. if (available <= 0) {
  764. return written;
  765. }
  766. const auto write = std::min(std::size_t(available), buffer.size());
  767. if (write <= 0) {
  768. return written;
  769. }
  770. bytes::copy(
  771. buffer,
  772. bytes::make_span(_incoming).subspan(
  773. _incomingGoodDataOffset,
  774. write));
  775. written += write;
  776. buffer = buffer.subspan(write);
  777. _incomingGoodDataLimit -= write;
  778. _incomingGoodDataOffset += write;
  779. if (_incomingGoodDataLimit) {
  780. return written;
  781. }
  782. shiftIncomingBy(base::take(_incomingGoodDataOffset));
  783. if (!checkNextPacket()) {
  784. _state = State::Error;
  785. InvokeQueued(this, [=] { handleError(); });
  786. return written;
  787. }
  788. }
  789. return written;
  790. }
  791. void TlsSocket::write(bytes::const_span prefix, bytes::const_span buffer) {
  792. Expects(!buffer.empty());
  793. if (!isConnected()) {
  794. return;
  795. }
  796. if (!prefix.empty()) {
  797. _socket.write(kClientPrefix.data(), kClientPrefix.size());
  798. }
  799. while (!buffer.empty()) {
  800. const auto write = std::min(
  801. kClientPartSize - prefix.size(),
  802. buffer.size());
  803. _socket.write(kClientHeader.data(), kClientHeader.size());
  804. const auto size = qToBigEndian(uint16(prefix.size() + write));
  805. _socket.write(reinterpret_cast<const char*>(&size), sizeof(size));
  806. if (!prefix.empty()) {
  807. _socket.write(
  808. reinterpret_cast<const char*>(prefix.data()),
  809. prefix.size());
  810. prefix = bytes::const_span();
  811. }
  812. _socket.write(
  813. reinterpret_cast<const char*>(buffer.data()),
  814. write);
  815. buffer = buffer.subspan(write);
  816. }
  817. }
  818. int32 TlsSocket::debugState() {
  819. return _socket.state();
  820. }
  821. QString TlsSocket::debugPostfix() const {
  822. return u"_ee"_q;
  823. }
  824. void TlsSocket::handleError(int errorCode) {
  825. if (_state != State::Connected) {
  826. _syncTimeRequests.fire({});
  827. }
  828. if (errorCode) {
  829. logError(errorCode, _socket.errorString());
  830. }
  831. _state = State::Error;
  832. _error.fire({});
  833. }
  834. } // namespace MTP::details