From eae92b214a34d4811127f5fd24566a63f9f83d61 Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 26 Jan 2020 01:22:07 +0300 Subject: [PATCH] Really fix too long TLS-proxy domain. GitOrigin-RevId: a07726e8bb75b467d26043d6c9b4ad834a961567 --- td/mtproto/ProxySecret.cpp | 14 +++++++++----- td/mtproto/ProxySecret.h | 8 ++++++-- td/mtproto/TlsInit.cpp | 6 ++++-- td/telegram/net/Proxy.h | 2 +- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/td/mtproto/ProxySecret.cpp b/td/mtproto/ProxySecret.cpp index 1d53b30fe..571cd8f77 100644 --- a/td/mtproto/ProxySecret.cpp +++ b/td/mtproto/ProxySecret.cpp @@ -12,7 +12,7 @@ namespace td { namespace mtproto { -Result ProxySecret::from_link(Slice encoded_secret) { +Result ProxySecret::from_link(Slice encoded_secret, bool truncate_if_needed) { auto r_decoded = hex_decode(encoded_secret); if (r_decoded.is_error()) { r_decoded = base64url_decode(encoded_secret); @@ -20,12 +20,16 @@ Result ProxySecret::from_link(Slice encoded_secret) { if (r_decoded.is_error()) { return Status::Error(400, "Wrong proxy secret"); } - return from_binary(r_decoded.ok()); + return from_binary(r_decoded.ok(), truncate_if_needed); } -Result ProxySecret::from_binary(Slice raw_unchecked_secret) { - if (raw_unchecked_secret.size() > 17 + 255) { - return Status::Error(400, "Too long secret"); +Result ProxySecret::from_binary(Slice raw_unchecked_secret, bool truncate_if_needed) { + if (raw_unchecked_secret.size() > 17 + MAX_DOMAIN_LENGTH) { + if (truncate_if_needed) { + raw_unchecked_secret.truncate(17 + MAX_DOMAIN_LENGTH); + } else { + return Status::Error(400, "Too long secret"); + } } if (raw_unchecked_secret.size() == 16 || (raw_unchecked_secret.size() == 17 && static_cast(raw_unchecked_secret[0]) == 0xdd) || diff --git a/td/mtproto/ProxySecret.h b/td/mtproto/ProxySecret.h index c4aade6cf..199d02a6e 100644 --- a/td/mtproto/ProxySecret.h +++ b/td/mtproto/ProxySecret.h @@ -15,8 +15,12 @@ namespace mtproto { class ProxySecret { public: - static Result from_link(Slice encoded_secret); - static Result from_binary(Slice raw_unchecked_secret); + static constexpr size_t MAX_DOMAIN_LENGTH = 182; // must be small enough to not overflow TLS-hello length + + static Result from_link(Slice encoded_secret, bool truncate_if_needed = false); + + static Result from_binary(Slice raw_unchecked_secret, bool truncate_if_needed = false); + static ProxySecret from_raw(Slice raw_secret) { ProxySecret result; result.secret_ = raw_secret.str(); diff --git a/td/mtproto/TlsInit.cpp b/td/mtproto/TlsInit.cpp index d36b94f39..4e956a6a9 100644 --- a/td/mtproto/TlsInit.cpp +++ b/td/mtproto/TlsInit.cpp @@ -6,6 +6,8 @@ // #include "td/mtproto/TlsInit.h" +#include "td/mtproto/ProxySecret.h" + #include "td/utils/as.h" #include "td/utils/BigNum.h" #include "td/utils/common.h" @@ -157,7 +159,7 @@ class TlsHelloContext { return grease_.size(); } Slice get_domain() const { - return Slice(domain_).substr(0, 255); + return Slice(domain_).substr(0, ProxySecret::MAX_DOMAIN_LENGTH); } private: @@ -225,7 +227,7 @@ class TlsHelloCalcLength { } Result finish() { - if (size_ > 515) { + if (size_ > 514) { on_error(Status::Error("Too long for zero padding")); } if (size_ < 11 + 32) { diff --git a/td/telegram/net/Proxy.h b/td/telegram/net/Proxy.h index a9dca8a4d..947930c39 100644 --- a/td/telegram/net/Proxy.h +++ b/td/telegram/net/Proxy.h @@ -134,7 +134,7 @@ class Proxy { } else if (type_ == Proxy::Type::Mtproto) { parse(server_, parser); parse(port_, parser); - secret_ = mtproto::ProxySecret::from_link(parser.template fetch_string()).move_as_ok(); + secret_ = mtproto::ProxySecret::from_link(parser.template fetch_string(), true).move_as_ok(); } else { CHECK(type_ == Proxy::Type::None); }