From 81731139e97fba4164a227e2f2fe05bf4e14c90b Mon Sep 17 00:00:00 2001 From: John Preston Date: Sat, 28 Jul 2018 13:50:28 +0300 Subject: [PATCH] Add tests for storage encrypted file. Also fix some bugs found by the tests. --- .../SourceFiles/platform/win/windows_dlls.cpp | 6 +- .../storage/storage_encrypted_file.cpp | 14 +++- .../storage/storage_encrypted_file.h | 3 + .../storage/storage_encrypted_file_tests.cpp | 70 +++++++++++++++++++ .../storage/storage_encryption.cpp | 32 +++++++-- .../SourceFiles/storage/storage_encryption.h | 2 + .../SourceFiles/storage/storage_file_lock.h | 4 ++ .../storage/storage_file_lock_posix.cpp | 3 + Telegram/gyp/Telegram.gyp | 1 + Telegram/gyp/lib_storage.gyp | 1 + Telegram/gyp/openssl.gypi | 55 +++++++++++++++ Telegram/gyp/telegram_mac.gypi | 6 -- Telegram/gyp/telegram_win.gypi | 11 --- Telegram/gyp/tests/tests.gyp | 25 ++++++- 14 files changed, 202 insertions(+), 31 deletions(-) create mode 100644 Telegram/SourceFiles/storage/storage_encrypted_file_tests.cpp create mode 100644 Telegram/gyp/openssl.gypi diff --git a/Telegram/SourceFiles/platform/win/windows_dlls.cpp b/Telegram/SourceFiles/platform/win/windows_dlls.cpp index 22e477ecf..e8f776b75 100644 --- a/Telegram/SourceFiles/platform/win/windows_dlls.cpp +++ b/Telegram/SourceFiles/platform/win/windows_dlls.cpp @@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "platform/win/windows_dlls.h" +#include + namespace Platform { namespace Dlls { @@ -69,10 +71,6 @@ void start() { load(LibShell32, "SHChangeNotify", SHChangeNotify); load(LibShell32, "SetCurrentProcessExplicitAppUserModelID", SetCurrentProcessExplicitAppUserModelID); - if (cBetaVersion() == 10020001 && SHChangeNotify) { // Temp - app icon was changed - SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr); - } - LibUxTheme = LoadLibrary(L"UXTHEME.DLL"); load(LibUxTheme, "SetWindowTheme", SetWindowTheme); diff --git a/Telegram/SourceFiles/storage/storage_encrypted_file.cpp b/Telegram/SourceFiles/storage/storage_encrypted_file.cpp index 11a3d4900..d26cd2f8a 100644 --- a/Telegram/SourceFiles/storage/storage_encrypted_file.cpp +++ b/Telegram/SourceFiles/storage/storage_encrypted_file.cpp @@ -28,12 +28,12 @@ File::Result File::open( const QString &path, Mode mode, const EncryptionKey &key) { + close(); + _data.setFileName(QFileInfo(path).absoluteFilePath()); const auto result = attemptOpen(mode, key); if (result != Result::Success) { - _state = base::none; - _data.close(); - _lock.unlock(); + close(); } return result; @@ -198,4 +198,12 @@ size_type File::write(bytes::span bytes) { return count; } +void File::close() { + _lock.unlock(); + _data.close(); + _data.setFileName(QString()); + _offset = 0; + _state = base::none; +} + } // namespace Storage diff --git a/Telegram/SourceFiles/storage/storage_encrypted_file.h b/Telegram/SourceFiles/storage/storage_encrypted_file.h index 9ad85f2a4..7ecf21989 100644 --- a/Telegram/SourceFiles/storage/storage_encrypted_file.h +++ b/Telegram/SourceFiles/storage/storage_encrypted_file.h @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/storage_file_lock.h" #include "storage/storage_encryption.h" #include "base/bytes.h" +#include "base/optional.h" namespace Storage { @@ -31,6 +32,8 @@ public: size_type read(bytes::span bytes); size_type write(bytes::span bytes); + void close(); + private: enum class Format : uint32 { Format_0, diff --git a/Telegram/SourceFiles/storage/storage_encrypted_file_tests.cpp b/Telegram/SourceFiles/storage/storage_encrypted_file_tests.cpp new file mode 100644 index 000000000..0aaa69c22 --- /dev/null +++ b/Telegram/SourceFiles/storage/storage_encrypted_file_tests.cpp @@ -0,0 +1,70 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "catch.hpp" + +#include "storage/storage_encrypted_file.h" + +const auto key = Storage::EncryptionKey(bytes::make_vector( + bytes::make_span("\ +abcdefgh01234567abcdefgh01234567abcdefgh01234567abcdefgh01234567\ +abcdefgh01234567abcdefgh01234567abcdefgh01234567abcdefgh01234567\ +abcdefgh01234567abcdefgh01234567abcdefgh01234567abcdefgh01234567\ +abcdefgh01234567abcdefgh01234567abcdefgh01234567abcdefgh01234567\ +").subspan(0, Storage::EncryptionKey::kSize))); + +TEST_CASE("simple encrypted file", "[storage_encrypted_file]") { + const auto name = QString("simple.test"); + const auto test = bytes::make_span("testbytetestbyte").subspan(0, 16); + + SECTION("writing file") { + Storage::File file; + const auto result = file.open( + name, + Storage::File::Mode::Write, + key); + REQUIRE(result == Storage::File::Result::Success); + + auto data = bytes::make_vector(test); + const auto written = file.write(data); + REQUIRE(written == data.size()); + } + SECTION("reading and writing file") { + Storage::File file; + const auto result = file.open( + name, + Storage::File::Mode::ReadAppend, + key); + REQUIRE(result == Storage::File::Result::Success); + + auto data = bytes::vector(16); + const auto read = file.read(data); + REQUIRE(read == data.size()); + REQUIRE(data == bytes::make_vector(test)); + + const auto written = file.write(data); + REQUIRE(written == data.size()); + } + SECTION("reading file") { + Storage::File file; + + const auto result = file.open( + name, + Storage::File::Mode::Read, + key); + REQUIRE(result == Storage::File::Result::Success); + + auto data = bytes::vector(32); + const auto read = file.read(data); + REQUIRE(read == data.size()); + REQUIRE(data == bytes::concatenate(test, test)); + } +} + +TEST_CASE("two process encrypted file", "[storage_encrypted_file]") { + +} diff --git a/Telegram/SourceFiles/storage/storage_encryption.cpp b/Telegram/SourceFiles/storage/storage_encryption.cpp index 4751fce08..2e383feb2 100644 --- a/Telegram/SourceFiles/storage/storage_encryption.cpp +++ b/Telegram/SourceFiles/storage/storage_encryption.cpp @@ -30,25 +30,47 @@ void CtrState::process(bytes::span data, index_type offset, Method method) { _key.size() * CHAR_BIT, &aes); - unsigned char ecountBuf[kBlockSize]; - unsigned int blockNumber = offset / kBlockSize; + unsigned char ecountBuf[kBlockSize] = { 0 }; + unsigned int offsetInBlock = 0; + const auto blockIndex = offset / kBlockSize; + auto iv = incrementedIv(blockIndex); + CRYPTO_ctr128_encrypt( reinterpret_cast(data.data()), reinterpret_cast(data.data()), data.size(), &aes, - reinterpret_cast(_iv.data()), + reinterpret_cast(iv.data()), ecountBuf, - &blockNumber, + &offsetInBlock, (block128_f)method); } +auto CtrState::incrementedIv(index_type blockIndex) +-> bytes::array { + Expects(blockIndex >= 0); + + if (!blockIndex) { + return _iv; + } + auto result = _iv; + auto digits = kIvSize; + auto increment = uint64(blockIndex); + do { + --digits; + increment += static_cast(result[digits]); + result[digits] = static_cast(increment & 0xFFULL); + increment >>= 8; + } while (digits != 0 && increment != 0); + return result; +} + void CtrState::encrypt(bytes::span data, index_type offset) { return process(data, offset, AES_encrypt); } void CtrState::decrypt(bytes::span data, index_type offset) { - return process(data, offset, AES_decrypt); + return process(data, offset, AES_encrypt); } EncryptionKey::EncryptionKey(bytes::vector &&data) diff --git a/Telegram/SourceFiles/storage/storage_encryption.h b/Telegram/SourceFiles/storage/storage_encryption.h index 5481c2987..001a1a3ae 100644 --- a/Telegram/SourceFiles/storage/storage_encryption.h +++ b/Telegram/SourceFiles/storage/storage_encryption.h @@ -28,6 +28,8 @@ private: template void process(bytes::span data, index_type offset, Method method); + bytes::array incrementedIv(index_type blockIndex); + static constexpr auto EcountSize = kBlockSize; bytes::array _key; diff --git a/Telegram/SourceFiles/storage/storage_file_lock.h b/Telegram/SourceFiles/storage/storage_file_lock.h index 3172db092..48488716b 100644 --- a/Telegram/SourceFiles/storage/storage_file_lock.h +++ b/Telegram/SourceFiles/storage/storage_file_lock.h @@ -7,6 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +#include "core/basic_types.h" + +#include + namespace Storage { class FileLock { diff --git a/Telegram/SourceFiles/storage/storage_file_lock_posix.cpp b/Telegram/SourceFiles/storage/storage_file_lock_posix.cpp index e5fedd715..5e45d9ed1 100644 --- a/Telegram/SourceFiles/storage/storage_file_lock_posix.cpp +++ b/Telegram/SourceFiles/storage/storage_file_lock_posix.cpp @@ -71,6 +71,9 @@ FileLock::Lock::Result FileLock::Lock::Acquire(const QFile &file) { } } +FileLock::Lock::Lock(int descriptor) : _descriptor(descriptor) { +} + FileLock::Lock::~Lock() { struct flock unlock; unlock.l_type = F_UNLCK; diff --git a/Telegram/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp index 407a6884b..e7bd00df5 100644 --- a/Telegram/gyp/Telegram.gyp +++ b/Telegram/gyp/Telegram.gyp @@ -61,6 +61,7 @@ 'telegram_win.gypi', 'telegram_mac.gypi', 'telegram_linux.gypi', + 'openssl.gypi', 'qt.gypi', 'qt_moc.gypi', 'qt_rcc.gypi', diff --git a/Telegram/gyp/lib_storage.gyp b/Telegram/gyp/lib_storage.gyp index d68ecbd8b..fba1dc511 100644 --- a/Telegram/gyp/lib_storage.gyp +++ b/Telegram/gyp/lib_storage.gyp @@ -13,6 +13,7 @@ 'type': 'static_library', 'includes': [ 'common.gypi', + 'openssl.gypi', 'qt.gypi', 'telegram_win.gypi', 'telegram_mac.gypi', diff --git a/Telegram/gyp/openssl.gypi b/Telegram/gyp/openssl.gypi new file mode 100644 index 000000000..ce8ae3784 --- /dev/null +++ b/Telegram/gyp/openssl.gypi @@ -0,0 +1,55 @@ +# This file is part of Telegram Desktop, +# the official desktop application for the Telegram messaging service. +# +# For license and copyright information please follow this link: +# https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL + +{ + 'conditions': [ + [ 'build_win', { + 'libraries': [ + '-llibeay32', + '-lssleay32', + '-lCrypt32', + ], + 'configurations': { + 'Debug': { + 'include_dirs': [ + '<(libs_loc)/openssl/Debug/include', + ], + 'library_dirs': [ + '<(libs_loc)/openssl/Debug/lib', + ], + }, + 'Release': { + 'include_dirs': [ + '<(libs_loc)/openssl/Release/include', + ], + 'library_dirs': [ + '<(libs_loc)/openssl/Release/lib', + ], + }, + }, + }], [ 'build_macold', { + 'xcode_settings': { + 'OTHER_LDFLAGS': [ + '<(libs_loc)/macold/openssl/libssl.a', + '<(libs_loc)/macold/openssl/libcrypto.a', + ], + }, + 'include_dirs': [ + '<(libs_loc)/macold/openssl/include', + ], + }], [ 'build_mac', { + 'xcode_settings': { + 'OTHER_LDFLAGS': [ + '<(libs_loc)/openssl/libssl.a', + '<(libs_loc)/openssl/libcrypto.a', + ], + }, + 'include_dirs': [ + '<(libs_loc)/openssl/include', + ], + }], + ], +} diff --git a/Telegram/gyp/telegram_mac.gypi b/Telegram/gyp/telegram_mac.gypi index e1707f6af..15f03c467 100644 --- a/Telegram/gyp/telegram_mac.gypi +++ b/Telegram/gyp/telegram_mac.gypi @@ -55,14 +55,11 @@ '/usr/local/macold/lib/libexif.a', '/usr/local/macold/lib/libc++.a', '/usr/local/macold/lib/libc++abi.a', - '<(libs_loc)/macold/openssl/libssl.a', - '<(libs_loc)/macold/openssl/libcrypto.a', ], }, 'include_dirs': [ '/usr/local/macold', '/usr/local/macold/include/c++/v1', - '<(libs_loc)/macold/openssl/include', '<(libs_loc)/macold/libexif-0.6.20', '<(libs_loc)/macold/crashpad', '<(libs_loc)/macold/crashpad/third_party/mini_chromium/mini_chromium', @@ -122,14 +119,11 @@ '/usr/local/lib/libavutil.a', '/usr/local/lib/libswscale.a', '/usr/local/lib/libswresample.a', - '<(libs_loc)/openssl/libssl.a', - '<(libs_loc)/openssl/libcrypto.a', ], }, 'include_dirs': [ '<(libs_loc)/crashpad', '<(libs_loc)/crashpad/third_party/mini_chromium/mini_chromium', - '<(libs_loc)/openssl/include' ], 'configurations': { 'Debug': { diff --git a/Telegram/gyp/telegram_win.gypi b/Telegram/gyp/telegram_win.gypi index 4c0851034..126d3b2c1 100644 --- a/Telegram/gyp/telegram_win.gypi +++ b/Telegram/gyp/telegram_win.gypi @@ -14,9 +14,6 @@ '<(libs_loc)/ffmpeg', ], 'libraries': [ - '-llibeay32', - '-lssleay32', - '-lCrypt32', '-lzlibstat', '-lLzmaLib', '-lUxTheme', @@ -41,11 +38,7 @@ }, 'configurations': { 'Debug': { - 'include_dirs': [ - '<(libs_loc)/openssl/Debug/include', - ], 'library_dirs': [ - '<(libs_loc)/openssl/Debug/lib', '<(libs_loc)/lzma/C/Util/LzmaLib/Debug', '<(libs_loc)/opus/win32/VS2015/Win32/Debug', '<(libs_loc)/openal-soft/build/Debug', @@ -54,11 +47,7 @@ ], }, 'Release': { - 'include_dirs': [ - '<(libs_loc)/openssl/Release/include', - ], 'library_dirs': [ - '<(libs_loc)/openssl/Release/lib', '<(libs_loc)/lzma/C/Util/LzmaLib/Release', '<(libs_loc)/opus/win32/VS2015/Win32/Release', '<(libs_loc)/openal-soft/build/Release', diff --git a/Telegram/gyp/tests/tests.gyp b/Telegram/gyp/tests/tests.gyp index 4bb9be165..9473b6645 100644 --- a/Telegram/gyp/tests/tests.gyp +++ b/Telegram/gyp/tests/tests.gyp @@ -23,6 +23,7 @@ ], 'dependencies': [ '