Really fix too long TLS-proxy domain.

GitOrigin-RevId: a07726e8bb75b467d26043d6c9b4ad834a961567
This commit is contained in:
levlam 2020-01-26 01:22:07 +03:00
parent 182e8d29f0
commit eae92b214a
4 changed files with 20 additions and 10 deletions

View File

@ -12,7 +12,7 @@
namespace td {
namespace mtproto {
Result<ProxySecret> ProxySecret::from_link(Slice encoded_secret) {
Result<ProxySecret> 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> 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> ProxySecret::from_binary(Slice raw_unchecked_secret) {
if (raw_unchecked_secret.size() > 17 + 255) {
return Status::Error(400, "Too long secret");
Result<ProxySecret> 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<unsigned char>(raw_unchecked_secret[0]) == 0xdd) ||

View File

@ -15,8 +15,12 @@ namespace mtproto {
class ProxySecret {
public:
static Result<ProxySecret> from_link(Slice encoded_secret);
static Result<ProxySecret> 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<ProxySecret> from_link(Slice encoded_secret, bool truncate_if_needed = false);
static Result<ProxySecret> 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();

View File

@ -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<size_t> finish() {
if (size_ > 515) {
if (size_ > 514) {
on_error(Status::Error("Too long for zero padding"));
}
if (size_ < 11 + 32) {

View File

@ -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<Slice>()).move_as_ok();
secret_ = mtproto::ProxySecret::from_link(parser.template fetch_string<Slice>(), true).move_as_ok();
} else {
CHECK(type_ == Proxy::Type::None);
}