From 23e27a223f131a93e681a973891554b958847c97 Mon Sep 17 00:00:00 2001 From: Arseny Smirnov Date: Tue, 2 Jul 2019 17:14:13 +0200 Subject: [PATCH] TlsInit: check hash in server response GitOrigin-RevId: 00d0b679020173be7ef8e06db3bc4e64a61d3fbf --- td/mtproto/TlsInit.cpp | 11 ++++++++++- td/mtproto/TlsInit.h | 1 + test/mtproto.cpp | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/td/mtproto/TlsInit.cpp b/td/mtproto/TlsInit.cpp index 03a8d4942..51ffb02b7 100644 --- a/td/mtproto/TlsInit.cpp +++ b/td/mtproto/TlsInit.cpp @@ -346,6 +346,7 @@ class TlsObfusaction { void TlsInit::send_hello() { auto hello = TlsObfusaction::generate_header(username_, password_, static_cast(Clocks::system())); // TODO correct time + hello_rand_ = Slice(hello).substr(11, 32).str(); fd_.output_buffer().append(hello); state_ = State::WaitHelloResponse; } @@ -372,7 +373,15 @@ Status TlsInit::wait_hello_response() { it.advance(skip_size); } - fd_.input_buffer() = std::move(it); + auto response = fd_.input_buffer().cut_head(it.begin().clone()).read_as_buffer_slice(); + auto response_rand_slice = response.as_slice().substr(11, 32); + auto response_rand = response_rand_slice.str(); + std::fill(response_rand_slice.begin(), response_rand_slice.end(), 0); + std::string hash_dest(32, 0); + hmac_sha256(password_, PSLICE() << hello_rand_ << response_rand_slice, hash_dest); + if (hash_dest != response_rand) { + return td::Status::Error("response hash mismatch"); + } stop(); return Status::OK(); diff --git a/td/mtproto/TlsInit.h b/td/mtproto/TlsInit.h index 2b8323e75..ab6a862b2 100644 --- a/td/mtproto/TlsInit.h +++ b/td/mtproto/TlsInit.h @@ -27,6 +27,7 @@ class TlsInit : public TransparentProxy { SendHello, WaitHelloResponse, } state_ = State::SendHello; + std::string hello_rand_; void send_hello(); Status wait_hello_response(); diff --git a/test/mtproto.cpp b/test/mtproto.cpp index e5eaed462..ece6ba43a 100644 --- a/test/mtproto.cpp +++ b/test/mtproto.cpp @@ -610,7 +610,7 @@ TEST(Mtproto, TlsObfusaction) { class Callback : public TransparentProxy::Callback { public: void set_result(Result result) override { - result.ensure(); + CHECK(result.is_error() && result.error().message() == "response hash mismatch"); Scheduler::instance()->finish(); } void on_connected() override {