From 71b1dbce7a49be6b17b090a29adb6977c3aa7b79 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 27 Dec 2018 21:38:43 +0300 Subject: [PATCH] Add FileEncryptionKey.cpp. GitOrigin-RevId: d6c07f75fffd007afaeaec92016639f26fffc5c3 --- CMakeLists.txt | 1 + td/telegram/files/FileDownloader.cpp | 1 + td/telegram/files/FileEncryptionKey.cpp | 101 ++++++++++++++++++++++ td/telegram/files/FileEncryptionKey.h | 108 ++++++------------------ td/telegram/files/FileManager.cpp | 1 + td/telegram/files/FileUploader.cpp | 1 + 6 files changed, 133 insertions(+), 80 deletions(-) create mode 100644 td/telegram/files/FileEncryptionKey.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4603576ec..a4804284c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -361,6 +361,7 @@ set(TDLIB_SOURCE td/telegram/files/FileBitmask.cpp td/telegram/files/FileDb.cpp td/telegram/files/FileDownloader.cpp + td/telegram/files/FileEncryptionKey.cpp td/telegram/files/FileFromBytes.cpp td/telegram/files/FileGcParameters.cpp td/telegram/files/FileGcWorker.cpp diff --git a/td/telegram/files/FileDownloader.cpp b/td/telegram/files/FileDownloader.cpp index 6f7488153..bcd0fac09 100644 --- a/td/telegram/files/FileDownloader.cpp +++ b/td/telegram/files/FileDownloader.cpp @@ -11,6 +11,7 @@ #include "td/telegram/files/FileLoaderUtils.h" #include "td/telegram/Global.h" #include "td/telegram/net/DcId.h" +#include "td/telegram/SecureStorage.h" #include "td/telegram/UniqueId.h" #include "td/utils/as.h" diff --git a/td/telegram/files/FileEncryptionKey.cpp b/td/telegram/files/FileEncryptionKey.cpp new file mode 100644 index 000000000..4fb036733 --- /dev/null +++ b/td/telegram/files/FileEncryptionKey.cpp @@ -0,0 +1,101 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/files/FileEncryptionKey.h" + +#include "td/telegram/SecureStorage.h" + +#include "td/utils/as.h" +#include "td/utils/crypto.h" +#include "td/utils/Random.h" + +namespace td { + +FileEncryptionKey::FileEncryptionKey(Slice key, Slice iv) : key_iv_(key.size() + iv.size(), '\0'), type_(Type::Secret) { + if (key.size() != 32 || iv.size() != 32) { + LOG(ERROR) << "Wrong key/iv sizes: " << key.size() << " " << iv.size(); + type_ = Type::None; + return; + } + CHECK(key_iv_.size() == 64); + MutableSlice(key_iv_).copy_from(key); + MutableSlice(key_iv_).substr(key.size()).copy_from(iv); +} + +FileEncryptionKey::FileEncryptionKey(const secure_storage::Secret &secret) : type_(Type::Secure) { + key_iv_ = secret.as_slice().str(); +} + +FileEncryptionKey FileEncryptionKey::create() { + FileEncryptionKey res; + res.key_iv_.resize(64); + Random::secure_bytes(res.key_iv_); + res.type_ = Type::Secret; + return res; +} +FileEncryptionKey FileEncryptionKey::create_secure_key() { + return FileEncryptionKey(secure_storage::Secret::create_new()); +} + +const UInt256 &FileEncryptionKey::key() const { + CHECK(is_secret()); + CHECK(key_iv_.size() == 64); + return *reinterpret_cast(key_iv_.data()); +} +Slice FileEncryptionKey::key_slice() const { + CHECK(is_secret()); + CHECK(key_iv_.size() == 64); + return Slice(key_iv_.data(), 32); +} +secure_storage::Secret FileEncryptionKey::secret() const { + CHECK(is_secure()); + return secure_storage::Secret::create(Slice(key_iv_).truncate(32)).move_as_ok(); +} + +bool FileEncryptionKey::has_value_hash() const { + CHECK(is_secure()); + return key_iv_.size() > secure_storage::Secret::size(); +} + +void FileEncryptionKey::set_value_hash(const secure_storage::ValueHash &value_hash) { + key_iv_.resize(secure_storage::Secret::size() + value_hash.as_slice().size()); + MutableSlice(key_iv_).remove_prefix(secure_storage::Secret::size()).copy_from(value_hash.as_slice()); +} + +secure_storage::ValueHash FileEncryptionKey::value_hash() const { + CHECK(has_value_hash()); + return secure_storage::ValueHash::create(Slice(key_iv_).remove_prefix(secure_storage::Secret::size())).move_as_ok(); +} + +UInt256 &FileEncryptionKey::mutable_iv() { + CHECK(is_secret()); + CHECK(key_iv_.size() == 64); + return *reinterpret_cast(&key_iv_[0] + 32); +} +Slice FileEncryptionKey::iv_slice() const { + CHECK(is_secret()); + CHECK(key_iv_.size() == 64); + return Slice(key_iv_.data() + 32, 32); +} + +int32 FileEncryptionKey::calc_fingerprint() const { + CHECK(is_secret()); + char buf[16]; + md5(key_iv_, {buf, sizeof(buf)}); + return as(buf) ^ as(buf + 4); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const FileEncryptionKey &key) { + if (key.is_secret()) { + return string_builder << "SecretKey{" << key.size() << "}"; + } + if (key.is_secret()) { + return string_builder << "SecureKey{" << key.size() << "}"; + } + return string_builder << "NoKey{}"; +} + +} // namespace td diff --git a/td/telegram/files/FileEncryptionKey.h b/td/telegram/files/FileEncryptionKey.h index 4e83d1235..e585b8ea5 100644 --- a/td/telegram/files/FileEncryptionKey.h +++ b/td/telegram/files/FileEncryptionKey.h @@ -6,13 +6,8 @@ // #pragma once -#include "td/telegram/SecureStorage.h" - -#include "td/utils/as.h" #include "td/utils/common.h" -#include "td/utils/crypto.h" #include "td/utils/logging.h" -#include "td/utils/Random.h" #include "td/utils/Slice.h" #include "td/utils/StringBuilder.h" #include "td/utils/tl_helpers.h" @@ -20,93 +15,54 @@ namespace td { +namespace secure_storage { +class Secret; +class ValueHash; +}; // namespace secure_storage + struct FileEncryptionKey { enum class Type : int32 { None, Secret, Secure }; - FileEncryptionKey() = default; - FileEncryptionKey(Slice key, Slice iv) : key_iv_(key.size() + iv.size(), '\0'), type_(Type::Secret) { - if (key.size() != 32 || iv.size() != 32) { - LOG(ERROR) << "Wrong key/iv sizes: " << key.size() << " " << iv.size(); - type_ = Type::None; - return; - } - CHECK(key_iv_.size() == 64); - MutableSlice(key_iv_).copy_from(key); - MutableSlice(key_iv_).substr(key.size()).copy_from(iv); - } - explicit FileEncryptionKey(const secure_storage::Secret &secret) : type_(Type::Secure) { - key_iv_ = secret.as_slice().str(); - } + FileEncryptionKey() = default; + + FileEncryptionKey(Slice key, Slice iv); + + explicit FileEncryptionKey(const secure_storage::Secret &secret); bool is_secret() const { return type_ == Type::Secret; } + bool is_secure() const { return type_ == Type::Secure; } - static FileEncryptionKey create() { - FileEncryptionKey res; - res.key_iv_.resize(64); - Random::secure_bytes(res.key_iv_); - res.type_ = Type::Secret; - return res; - } - static FileEncryptionKey create_secure_key() { - return FileEncryptionKey(secure_storage::Secret::create_new()); - } + static FileEncryptionKey create(); - const UInt256 &key() const { - CHECK(is_secret()); - CHECK(key_iv_.size() == 64); - return *reinterpret_cast(key_iv_.data()); - } - Slice key_slice() const { - CHECK(is_secret()); - CHECK(key_iv_.size() == 64); - return Slice(key_iv_.data(), 32); - } - secure_storage::Secret secret() const { - CHECK(is_secure()); - return secure_storage::Secret::create(Slice(key_iv_).truncate(32)).move_as_ok(); - } + static FileEncryptionKey create_secure_key(); - bool has_value_hash() const { - CHECK(is_secure()); - return key_iv_.size() > secure_storage::Secret::size(); - } + const UInt256 &key() const; - void set_value_hash(const secure_storage::ValueHash &value_hash) { - key_iv_.resize(secure_storage::Secret::size() + value_hash.as_slice().size()); - MutableSlice(key_iv_).remove_prefix(secure_storage::Secret::size()).copy_from(value_hash.as_slice()); - } + Slice key_slice() const; - secure_storage::ValueHash value_hash() const { - CHECK(has_value_hash()); - return secure_storage::ValueHash::create(Slice(key_iv_).remove_prefix(secure_storage::Secret::size())).move_as_ok(); - } + secure_storage::Secret secret() const; - UInt256 &mutable_iv() { - CHECK(is_secret()); - CHECK(key_iv_.size() == 64); - return *reinterpret_cast(&key_iv_[0] + 32); - } - Slice iv_slice() const { - CHECK(is_secret()); - CHECK(key_iv_.size() == 64); - return Slice(key_iv_.data() + 32, 32); - } + bool has_value_hash() const; - int32 calc_fingerprint() const { - CHECK(is_secret()); - char buf[16]; - md5(key_iv_, {buf, sizeof(buf)}); - return as(buf) ^ as(buf + 4); - } + void set_value_hash(const secure_storage::ValueHash &value_hash); + + secure_storage::ValueHash value_hash() const; + + UInt256 &mutable_iv(); + + Slice iv_slice() const; + + int32 calc_fingerprint() const; bool empty() const { return key_iv_.empty(); } + size_t size() const { return key_iv_.size(); } @@ -142,14 +98,6 @@ inline bool operator!=(const FileEncryptionKey &lhs, const FileEncryptionKey &rh return !(lhs == rhs); } -inline StringBuilder &operator<<(StringBuilder &string_builder, const FileEncryptionKey &key) { - if (key.is_secret()) { - return string_builder << "SecretKey{" << key.size() << "}"; - } - if (key.is_secret()) { - return string_builder << "SecureKey{" << key.size() << "}"; - } - return string_builder << "NoKey{}"; -} +StringBuilder &operator<<(StringBuilder &string_builder, const FileEncryptionKey &key); } // namespace td diff --git a/td/telegram/files/FileManager.cpp b/td/telegram/files/FileManager.cpp index 386285b34..39e57cb1b 100644 --- a/td/telegram/files/FileManager.cpp +++ b/td/telegram/files/FileManager.cpp @@ -13,6 +13,7 @@ #include "td/telegram/files/FileLocation.h" #include "td/telegram/Global.h" #include "td/telegram/misc.h" +#include "td/telegram/SecureStorage.h" #include "td/utils/base64.h" #include "td/utils/format.h" diff --git a/td/telegram/files/FileUploader.cpp b/td/telegram/files/FileUploader.cpp index 3894e7511..c6a7a0396 100644 --- a/td/telegram/files/FileUploader.cpp +++ b/td/telegram/files/FileUploader.cpp @@ -13,6 +13,7 @@ #include "td/telegram/Global.h" #include "td/telegram/net/DcId.h" #include "td/telegram/net/NetQueryDispatcher.h" +#include "td/telegram/SecureStorage.h" #include "td/utils/buffer.h" #include "td/utils/crypto.h"