refactor: aggregate crypto handles when computing digests (#6662)

* refactor: aggregate per-crypto-pkg fields instead of using inheritance
This commit is contained in:
Charles Kerr 2024-03-04 16:59:51 -06:00 committed by GitHub
parent 98c4eb8487
commit 50dca24f50
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 392 additions and 585 deletions

View File

@ -3951,6 +3951,7 @@
"-DWIDE_INTEGER_DISABLE_IOSTREAM",
"-DRAPIDJSON_HAS_STDSTRING=1",
"-DHAVE_FLOCK",
"-DWITH_CCRYPTO",
);
PRODUCT_NAME = transmission;
SYSTEM_HEADER_SEARCH_PATHS = (
@ -4137,6 +4138,7 @@
OTHER_CFLAGS = (
"$(inherited)",
"-DFMT_HEADER_ONLY",
"-DWITH_CCRYPTO",
);
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
PRODUCT_BUNDLE_IDENTIFIER = org.m0k.transmission;
@ -4203,6 +4205,7 @@
"-DWIDE_INTEGER_DISABLE_IOSTREAM",
"-DRAPIDJSON_HAS_STDSTRING=1",
"-DHAVE_FLOCK",
"-DWITH_CCRYPTO",
);
PRODUCT_NAME = transmission;
SYSTEM_HEADER_SEARCH_PATHS = (
@ -4343,6 +4346,7 @@
OTHER_CFLAGS = (
"$(inherited)",
"-DFMT_HEADER_ONLY",
"-DWITH_CCRYPTO",
"-DNDEBUG",
);
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
@ -4446,6 +4450,7 @@
OTHER_CFLAGS = (
"$(inherited)",
"-DFMT_HEADER_ONLY",
"-DWITH_CCRYPTO",
);
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
PRODUCT_BUNDLE_IDENTIFIER = org.m0k.transmission;
@ -4529,6 +4534,7 @@
"-DWIDE_INTEGER_DISABLE_IOSTREAM",
"-DRAPIDJSON_HAS_STDSTRING=1",
"-DHAVE_FLOCK",
"-DWITH_CCRYPTO",
);
PRODUCT_NAME = transmission;
SYSTEM_HEADER_SEARCH_PATHS = (

View File

@ -226,6 +226,10 @@ target_compile_definitions(${TR_NAME}
$<$<BOOL:${USE_SYSTEM_B64}>:USE_SYSTEM_B64>
$<$<BOOL:${HAVE_SO_REUSEPORT}>:HAVE_SO_REUSEPORT=1>
PUBLIC
$<$<STREQUAL:${CRYPTO_PKG},ccrypto>:WITH_CCRYPTO>
$<$<STREQUAL:${CRYPTO_PKG},mbedtls>:WITH_MBEDTLS>
$<$<STREQUAL:${CRYPTO_PKG},openssl>:WITH_OPENSSL>
$<$<STREQUAL:${CRYPTO_PKG},wolfssl>:WITH_WOLFSSL>
$<$<NOT:$<BOOL:${ENABLE_NLS}>>:DISABLE_GETTEXT>)
tr_target_compile_definitions_for_headers(${TR_NAME}
@ -275,7 +279,6 @@ target_link_libraries(${TR_NAME}
PRIVATE
Threads::Threads
deflate::deflate
transmission::crypto_impl
CURL::libcurl
FastFloat::fast_float
psl::psl
@ -297,6 +300,7 @@ target_link_libraries(${TR_NAME}
"$<$<BOOL:${APPLE}>:-framework Foundation>"
"$<$<BOOL:${ANDROID}>:${log-lib}>"
PUBLIC
transmission::crypto_impl
fmt::fmt-header-only
small::small
libevent::event)

View File

@ -93,101 +93,72 @@ bool check_ccrypto_result(CCCryptorStatus result, char const* file, long line)
} // namespace
// ---
// --- sha1
namespace
tr_sha1::tr_sha1()
{
class Sha1Impl final : public tr_sha1
{
public:
Sha1Impl()
{
clear();
}
~Sha1Impl() override = default;
void clear() override
{
CC_SHA1_Init(&handle_);
}
void add(void const* data, size_t data_length) override
{
static auto constexpr Max = static_cast<size_t>(std::numeric_limits<CC_LONG>::max());
auto const* sha_data = static_cast<uint8_t const*>(data);
while (data_length > 0)
{
auto const n_bytes = static_cast<CC_LONG>(std::min(data_length, Max));
CC_SHA1_Update(&handle_, sha_data, n_bytes);
data_length -= n_bytes;
sha_data += n_bytes;
}
}
[[nodiscard]] tr_sha1_digest_t finish() override
{
auto digest = tr_sha1_digest_t{};
CC_SHA1_Final(reinterpret_cast<unsigned char*>(std::data(digest)), &handle_);
clear();
return digest;
}
private:
CC_SHA1_CTX handle_ = {};
};
class Sha256Impl final : public tr_sha256
{
public:
Sha256Impl()
{
clear();
}
~Sha256Impl() override = default;
void clear() override
{
CC_SHA256_Init(&handle_);
}
void add(void const* data, size_t data_length) override
{
static auto constexpr Max = static_cast<size_t>(std::numeric_limits<CC_LONG>::max());
auto const* sha_data = static_cast<uint8_t const*>(data);
while (data_length > 0)
{
auto const n_bytes = static_cast<CC_LONG>(std::min(data_length, Max));
CC_SHA256_Update(&handle_, sha_data, n_bytes);
data_length -= n_bytes;
sha_data += n_bytes;
}
}
[[nodiscard]] tr_sha256_digest_t finish() override
{
auto digest = tr_sha256_digest_t{};
CC_SHA256_Final(reinterpret_cast<unsigned char*>(std::data(digest)), &handle_);
clear();
return digest;
}
private:
CC_SHA256_CTX handle_;
};
} // namespace
std::unique_ptr<tr_sha1> tr_sha1::create()
{
return std::make_unique<Sha1Impl>();
clear();
}
std::unique_ptr<tr_sha256> tr_sha256::create()
tr_sha1::~tr_sha1()
{
return std::make_unique<Sha256Impl>();
}
void tr_sha1::clear()
{
CC_SHA1_Init(&handle_);
}
void tr_sha1::add(void const* data, size_t data_length)
{
if (data_length == 0U)
{
return;
}
CC_SHA1_Update(&handle_, data, data_length);
}
tr_sha1_digest_t tr_sha1::finish()
{
auto digest = tr_sha1_digest_t{};
CC_SHA1_Final(reinterpret_cast<unsigned char*>(std::data(digest)), &handle_);
clear();
return digest;
}
// --- sha256
tr_sha256::tr_sha256()
{
clear();
}
tr_sha256::~tr_sha256()
{
}
void tr_sha256::clear()
{
CC_SHA256_Init(&handle_);
}
void tr_sha256::add(void const* data, size_t data_length)
{
if (data_length == 0U)
{
return;
}
CC_SHA256_Update(&handle_, data, data_length);
}
tr_sha256_digest_t tr_sha256::finish()
{
auto digest = tr_sha256_digest_t{};
CC_SHA256_Final(reinterpret_cast<unsigned char*>(std::data(digest)), &handle_);
clear();
return digest;
}
// ---

View File

@ -25,6 +25,10 @@
#define TR_CRYPTO_X509_FALLBACK
#include "libtransmission/crypto-utils-fallback.cc" // NOLINT(bugprone-suspicious-include)
#if !defined(WITH_MBEDTLS)
#error mbedtls module
#endif
namespace
{
void log_mbedtls_error(int error_code, char const* file, int line)
@ -99,120 +103,100 @@ mbedtls_ctr_drbg_context* get_rng()
std::recursive_mutex rng_mutex_;
// ---
class Sha1Impl final : public tr_sha1
{
public:
Sha1Impl()
{
clear();
}
~Sha1Impl() override = default;
void clear() override
{
mbedtls_sha1_init(&handle_);
#if MBEDTLS_VERSION_NUMBER >= 0x02070000
mbedtls_sha1_starts_ret(&handle_);
#else
mbedtls_sha1_starts(&handle_);
#endif
}
void add(void const* data, size_t data_length) override
{
if (data_length > 0U)
{
#if MBEDTLS_VERSION_NUMBER >= 0x02070000
mbedtls_sha1_update_ret(&handle_, static_cast<unsigned char const*>(data), data_length);
#else
mbedtls_sha1_update(&handle_, static_cast<unsigned char const*>(data), data_length);
#endif
}
}
[[nodiscard]] tr_sha1_digest_t finish() override
{
auto digest = tr_sha1_digest_t{};
auto* const digest_as_uchar = reinterpret_cast<unsigned char*>(std::data(digest));
#if MBEDTLS_VERSION_NUMBER >= 0x02070000
mbedtls_sha1_finish_ret(&handle_, digest_as_uchar);
#else
mbedtls_sha1_finish(&handle_, digest_as_uchar);
#endif
mbedtls_sha1_free(&handle_);
return digest;
}
private:
mbedtls_sha1_context handle_ = {};
};
class Sha256Impl final : public tr_sha256
{
public:
Sha256Impl()
{
clear();
}
~Sha256Impl() override = default;
void clear() override
{
mbedtls_sha256_init(&handle_);
#if MBEDTLS_VERSION_NUMBER >= 0x02070000
mbedtls_sha256_starts_ret(&handle_, 0);
#else
mbedtls_sha256_starts(&handle_);
#endif
}
void add(void const* data, size_t data_length) override
{
if (data_length > 0U)
{
#if MBEDTLS_VERSION_NUMBER >= 0x02070000
mbedtls_sha256_update_ret(&handle_, static_cast<unsigned char const*>(data), data_length);
#else
mbedtls_sha256_update(&handle_, static_cast<unsigned char const*>(data), data_length);
#endif
}
}
[[nodiscard]] tr_sha256_digest_t finish() override
{
auto digest = tr_sha256_digest_t{};
auto* const digest_as_uchar = reinterpret_cast<unsigned char*>(std::data(digest));
#if MBEDTLS_VERSION_NUMBER >= 0x02070000
mbedtls_sha256_finish_ret(&handle_, digest_as_uchar);
#else
mbedtls_sha256_finish(&handle_, digest_as_uchar);
#endif
mbedtls_sha256_free(&handle_);
return digest;
}
private:
mbedtls_sha256_context handle_ = {};
};
} // namespace
std::unique_ptr<tr_sha1> tr_sha1::create()
// --- sha1
tr_sha1::tr_sha1()
{
return std::make_unique<Sha1Impl>();
clear();
}
std::unique_ptr<tr_sha256> tr_sha256::create()
tr_sha1::~tr_sha1() = default;
void tr_sha1::clear()
{
return std::make_unique<Sha256Impl>();
mbedtls_sha1_init(&handle_);
#if MBEDTLS_VERSION_NUMBER >= 0x02070000
mbedtls_sha1_starts_ret(&handle_);
#else
mbedtls_sha1_starts(&handle_);
#endif
}
void tr_sha1::add(void const* data, size_t data_length)
{
if (data_length == 0U)
{
return;
}
#if MBEDTLS_VERSION_NUMBER >= 0x02070000
mbedtls_sha1_update_ret(&handle_, static_cast<unsigned char const*>(data), data_length);
#else
mbedtls_sha1_update(&handle_, static_cast<unsigned char const*>(data), data_length);
#endif
}
tr_sha1_digest_t tr_sha1::finish()
{
auto digest = tr_sha1_digest_t{};
auto* const digest_as_uchar = reinterpret_cast<unsigned char*>(std::data(digest));
#if MBEDTLS_VERSION_NUMBER >= 0x02070000
mbedtls_sha1_finish_ret(&handle_, digest_as_uchar);
#else
mbedtls_sha1_finish(&handle_, digest_as_uchar);
#endif
clear();
return digest;
}
// --- sha256
tr_sha256::tr_sha256()
{
clear();
}
tr_sha256::~tr_sha256() = default;
void tr_sha256::clear()
{
mbedtls_sha256_init(&handle_);
#if MBEDTLS_VERSION_NUMBER >= 0x02070000
mbedtls_sha256_starts_ret(&handle_, 0);
#else
mbedtls_sha256_starts(&handle_);
#endif
}
void tr_sha256::add(void const* data, size_t data_length)
{
if (data_length == 0U)
{
return;
}
#if MBEDTLS_VERSION_NUMBER >= 0x02070000
mbedtls_sha256_update_ret(&handle_, static_cast<unsigned char const*>(data), data_length);
#else
mbedtls_sha256_update(&handle_, static_cast<unsigned char const*>(data), data_length);
#endif
}
tr_sha256_digest_t tr_sha256::finish()
{
auto digest = tr_sha256_digest_t{};
auto* const digest_as_uchar = reinterpret_cast<unsigned char*>(std::data(digest));
#if MBEDTLS_VERSION_NUMBER >= 0x02070000
mbedtls_sha256_finish_ret(&handle_, digest_as_uchar);
#else
mbedtls_sha256_finish(&handle_, digest_as_uchar);
#endif
clear();
return digest;
}
// ---

View File

@ -29,37 +29,43 @@
#include "libtransmission/tr-macros.h" // tr_sha1_digest_t, tr_sha25...
#include "libtransmission/utils.h"
#if !defined(WITH_OPENSSL)
#error OPENSSL module
#endif
namespace
{
void log_openssl_error(char const* file, int line)
{
unsigned long const error_code = ERR_get_error();
if (tr_logLevelIsActive(TR_LOG_ERROR))
if (!tr_logLevelIsActive(TR_LOG_ERROR))
{
return;
}
auto const error_code = ERR_get_error();
if (static bool strings_loaded = false; !strings_loaded)
{
if (static bool strings_loaded = false; !strings_loaded)
{
#if OPENSSL_VERSION_NUMBER < 0x10100000 || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000)
ERR_load_crypto_strings();
ERR_load_crypto_strings();
#else
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, nullptr);
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, nullptr);
#endif
strings_loaded = true;
}
auto buf = std::array<char, 512>{};
ERR_error_string_n(error_code, std::data(buf), std::size(buf));
tr_logAddMessage(
file,
line,
TR_LOG_ERROR,
fmt::format(
_("{crypto_library} error: {error} ({error_code})"),
fmt::arg("crypto_library", "OpenSSL"),
fmt::arg("error", std::data(buf)),
fmt::arg("error_code", error_code)));
strings_loaded = true;
}
auto buf = std::array<char, 512>{};
ERR_error_string_n(error_code, std::data(buf), std::size(buf));
tr_logAddMessage(
file,
line,
TR_LOG_ERROR,
fmt::format(
_("{crypto_library} error: {error} ({error_code})"),
fmt::arg("crypto_library", "OpenSSL"),
fmt::arg("error", std::data(buf)),
fmt::arg("error_code", error_code)));
}
#define log_error() log_openssl_error(__FILE__, __LINE__)
@ -78,136 +84,84 @@ bool check_openssl_result(int result, int expected_result, bool expected_equal,
#define check_result(result) check_openssl_result((result), 1, true, __FILE__, __LINE__)
namespace sha_helpers
void digest_add_bytes(EVP_MD_CTX* ctx, void const* data, size_t data_length)
{
class ShaHelper
{
public:
using EvpFunc = decltype((EVP_sha1));
explicit ShaHelper(EvpFunc evp_func)
: evp_func_{ evp_func }
if (data_length != 0U)
{
clear();
EVP_DigestUpdate(ctx, data, data_length);
}
void clear() const
{
EVP_DigestInit_ex(handle_.get(), evp_func_(), nullptr);
}
void update(void const* data, size_t data_length) const
{
if (data_length != 0U)
{
EVP_DigestUpdate(handle_.get(), data, data_length);
}
}
template<typename DigestType>
[[nodiscard]] DigestType digest()
{
TR_ASSERT(handle_ != nullptr);
unsigned int hash_length = 0;
auto digest = DigestType{};
auto* const digest_as_uchar = reinterpret_cast<unsigned char*>(std::data(digest));
[[maybe_unused]] bool const ok = check_result(EVP_DigestFinal_ex(handle_.get(), digest_as_uchar, &hash_length));
TR_ASSERT(!ok || hash_length == std::size(digest));
clear();
return digest;
}
private:
struct MessageDigestDeleter
{
void operator()(EVP_MD_CTX* ctx) const noexcept
{
EVP_MD_CTX_destroy(ctx);
}
};
EvpFunc evp_func_;
std::unique_ptr<EVP_MD_CTX, MessageDigestDeleter> const handle_{ EVP_MD_CTX_create() };
};
class Sha1Impl final : public tr_sha1
{
public:
Sha1Impl() = default;
Sha1Impl(Sha1Impl&&) = delete;
Sha1Impl(Sha1Impl const&) = delete;
~Sha1Impl() override = default;
Sha1Impl& operator=(Sha1Impl&&) = delete;
Sha1Impl& operator=(Sha1Impl const&) = delete;
void clear() override
{
helper_.clear();
}
void add(void const* data, size_t data_length) override
{
helper_.update(data, data_length);
}
[[nodiscard]] tr_sha1_digest_t finish() override
{
return helper_.digest<tr_sha1_digest_t>();
}
private:
ShaHelper helper_{ EVP_sha1 };
};
class Sha256Impl final : public tr_sha256
{
public:
Sha256Impl() = default;
Sha256Impl(Sha256Impl&&) = delete;
Sha256Impl(Sha256Impl const&) = delete;
~Sha256Impl() override = default;
Sha256Impl& operator=(Sha256Impl&&) = delete;
Sha256Impl& operator=(Sha256Impl const&) = delete;
void clear() override
{
helper_.clear();
}
void add(void const* data, size_t data_length) override
{
helper_.update(data, data_length);
}
[[nodiscard]] tr_sha256_digest_t finish() override
{
return helper_.digest<tr_sha256_digest_t>();
}
private:
ShaHelper helper_{ EVP_sha256 };
};
} // namespace sha_helpers
} // namespace
// --- sha
std::unique_ptr<tr_sha1> tr_sha1::create()
{
using namespace sha_helpers;
return std::make_unique<Sha1Impl>();
}
std::unique_ptr<tr_sha256> tr_sha256::create()
template<typename DigestType>
DigestType digest_finish(EVP_MD_CTX* ctx)
{
using namespace sha_helpers;
unsigned int hash_length = 0;
auto digest = DigestType{};
auto* const digest_as_uchar = reinterpret_cast<unsigned char*>(std::data(digest));
[[maybe_unused]] bool const ok = check_result(EVP_DigestFinal_ex(ctx, digest_as_uchar, &hash_length));
TR_ASSERT(!ok || hash_length == std::size(digest));
return digest;
}
} // namespace
return std::make_unique<Sha256Impl>();
// --- sha1
tr_sha1::tr_sha1()
: handle_{ EVP_MD_CTX_create() }
{
clear();
}
tr_sha1::~tr_sha1()
{
EVP_MD_CTX_destroy(handle_);
}
void tr_sha1::clear()
{
EVP_DigestInit_ex(handle_, EVP_sha1(), nullptr);
}
void tr_sha1::add(void const* data, size_t data_length)
{
digest_add_bytes(handle_, data, data_length);
}
tr_sha1_digest_t tr_sha1::finish()
{
auto digest = digest_finish<tr_sha1_digest_t>(handle_);
clear();
return digest;
}
// --- sha256
tr_sha256::tr_sha256()
: handle_{ EVP_MD_CTX_create() }
{
clear();
}
tr_sha256::~tr_sha256()
{
EVP_MD_CTX_destroy(handle_);
}
void tr_sha256::clear()
{
EVP_DigestInit_ex(handle_, EVP_sha256(), nullptr);
}
void tr_sha256::add(void const* data, size_t data_length)
{
digest_add_bytes(handle_, data, data_length);
}
tr_sha256_digest_t tr_sha256::finish()
{
auto digest = digest_finish<tr_sha256_digest_t>(handle_);
clear();
return digest;
}
// --- x509

View File

@ -22,6 +22,10 @@
#include "libtransmission/tr-assert.h"
#include "libtransmission/utils.h"
#ifndef WITH_WOLFSSL
#error wolfssl module
#endif
#if LIBWOLFSSL_VERSION_HEX >= 0x04000000 // 4.0.0
using TR_WC_RNG = WC_RNG;
#else
@ -85,88 +89,66 @@ TR_WC_RNG* get_rng()
std::mutex rng_mutex_;
// ---
class Sha1Impl final : public tr_sha1
{
public:
Sha1Impl()
{
clear();
}
~Sha1Impl() override = default;
void clear() override
{
wc_InitSha(&handle_);
}
void add(void const* data, size_t data_length) override
{
if (data_length > 0U)
{
wc_ShaUpdate(&handle_, static_cast<byte const*>(data), data_length);
}
}
[[nodiscard]] tr_sha1_digest_t finish() override
{
auto digest = tr_sha1_digest_t{};
wc_ShaFinal(&handle_, reinterpret_cast<byte*>(std::data(digest)));
clear();
return digest;
}
private:
wc_Sha handle_ = {};
};
class Sha256Impl final : public tr_sha256
{
public:
Sha256Impl()
{
clear();
}
~Sha256Impl() override = default;
void clear() override
{
wc_InitSha256(&handle_);
}
void add(void const* data, size_t data_length) override
{
if (data_length > 0U)
{
wc_Sha256Update(&handle_, static_cast<byte const*>(data), data_length);
}
}
[[nodiscard]] tr_sha256_digest_t finish() override
{
auto digest = tr_sha256_digest_t{};
wc_Sha256Final(&handle_, reinterpret_cast<byte*>(std::data(digest)));
clear();
return digest;
}
private:
wc_Sha256 handle_ = {};
};
} // namespace
std::unique_ptr<tr_sha1> tr_sha1::create()
// --- sha1
tr_sha1::tr_sha1()
{
return std::make_unique<Sha1Impl>();
clear();
}
std::unique_ptr<tr_sha256> tr_sha256::create()
tr_sha1::~tr_sha1() = default;
void tr_sha1::clear()
{
return std::make_unique<Sha256Impl>();
wc_InitSha(&handle_);
}
void tr_sha1::add(void const* data, size_t data_length)
{
if (data_length > 0U)
{
wc_ShaUpdate(&handle_, static_cast<byte const*>(data), data_length);
}
}
tr_sha1_digest_t tr_sha1::finish()
{
auto digest = tr_sha1_digest_t{};
wc_ShaFinal(&handle_, reinterpret_cast<byte*>(std::data(digest)));
clear();
return digest;
}
// --- sha256
tr_sha256::tr_sha256()
{
clear();
}
tr_sha256::~tr_sha256() = default;
void tr_sha256::clear()
{
wc_InitSha256(&handle_);
}
void tr_sha256::add(void const* data, size_t data_length)
{
if (data_length > 0U)
{
wc_Sha256Update(&handle_, static_cast<byte const*>(data), data_length);
}
}
tr_sha256_digest_t tr_sha256::finish()
{
auto digest = tr_sha256_digest_t{};
wc_Sha256Final(&handle_, reinterpret_cast<byte*>(std::data(digest)));
clear();
return digest;
}
// ---

View File

@ -19,6 +19,28 @@
#include "libtransmission/tr-macros.h" // tr_sha1_digest_t, tr_sha256_d...
#include "libtransmission/tr-strbuf.h"
#if defined(WITH_CCRYPTO)
#include <CommonCrypto/CommonDigest.h>
using tr_sha1_context_t = CC_SHA1_CTX;
using tr_sha256_context_t = CC_SHA256_CTX;
#elif defined(WITH_MBEDTLS)
#include <mbedtls/sha1.h>
#include <mbedtls/sha256.h>
using tr_sha1_context_t = mbedtls_sha1_context;
using tr_sha256_context_t = mbedtls_sha256_context;
#elif defined(WITH_OPENSSL)
#include <openssl/evp.h>
using tr_sha1_context_t = EVP_MD_CTX*;
using tr_sha256_context_t = EVP_MD_CTX*;
#elif defined(WITH_WOLFSSL)
#include <wolfssl/wolfcrypt/sha.h>
#include <wolfssl/wolfcrypt/sha256.h>
using tr_sha1_context_t = wc_Sha;
using tr_sha256_context_t = wc_Sha256;
#else
#error no crypto library specified
#endif
/**
* @addtogroup utils Utilities
* @{
@ -27,39 +49,53 @@
class tr_sha1
{
public:
static std::unique_ptr<tr_sha1> create();
virtual ~tr_sha1() = default;
tr_sha1();
tr_sha1(tr_sha1&&) = delete;
tr_sha1(tr_sha1 const&) = delete;
tr_sha1& operator=(tr_sha1&&) = delete;
tr_sha1& operator=(tr_sha1 const&) = delete;
~tr_sha1();
virtual void clear() = 0;
virtual void add(void const* data, size_t data_length) = 0;
[[nodiscard]] virtual tr_sha1_digest_t finish() = 0;
void add(void const* data, size_t data_length);
[[nodiscard]] tr_sha1_digest_t finish();
void clear();
template<typename... T>
[[nodiscard]] static tr_sha1_digest_t digest(T const&... args)
[[nodiscard]] static auto digest(T const&... args)
{
auto context = tr_sha1::create();
(context->add(std::data(args), std::size(args)), ...);
return context->finish();
auto context = tr_sha1{};
(context.add(std::data(args), std::size(args)), ...);
return context.finish();
}
private:
tr_sha1_context_t handle_;
};
class tr_sha256
{
public:
static std::unique_ptr<tr_sha256> create();
virtual ~tr_sha256() = default;
tr_sha256();
tr_sha256(tr_sha256&&) = delete;
tr_sha256(tr_sha256 const&) = delete;
tr_sha256& operator=(tr_sha256&&) = delete;
tr_sha256& operator=(tr_sha256 const&) = delete;
~tr_sha256();
virtual void clear() = 0;
virtual void add(void const* data, size_t data_length) = 0;
[[nodiscard]] virtual tr_sha256_digest_t finish() = 0;
void add(void const* data, size_t data_length);
[[nodiscard]] tr_sha256_digest_t finish();
void clear();
template<typename... T>
[[nodiscard]] static tr_sha256_digest_t digest(T const&... args)
[[nodiscard]] static auto digest(T const&... args)
{
auto context = tr_sha256::create();
(context->add(std::data(args), std::size(args)), ...);
return context->finish();
auto context = tr_sha256{};
(context.add(std::data(args), std::size(args)), ...);
return context.finish();
}
private:
tr_sha256_context_t handle_;
};
/** @brief Opaque SSL context type. */

View File

@ -33,7 +33,7 @@
tr_logAddTrace(msg, fmt::format("handshake {}", (handshake)->peer_io_->display_name()))
using namespace std::literals;
using DH = tr_message_stream_encryption::DH;
using key_bigend_t = tr_message_stream_encryption::DH::key_bigend_t;
// --- Outgoing Connections
@ -60,7 +60,7 @@ ReadState tr_handshake::read_yb(tr_peerIo* peer_io)
return READ_NOW;
}
auto peer_public_key = DH::key_bigend_t{};
auto peer_public_key = key_bigend_t{};
tr_logAddTraceHand(
this,
fmt::format("in read_yb... need {}, have {}", std::size(peer_public_key), peer_io->read_buffer_size()));
@ -354,7 +354,7 @@ ReadState tr_handshake::read_ya(tr_peerIo* peer_io)
return READ_NOW;
}
auto peer_public_key = DH::key_bigend_t{};
auto peer_public_key = key_bigend_t{};
tr_logAddTraceHand(
this,
fmt::format("in read_ya... need {}, have {}", std::size(peer_public_key), peer_io->read_buffer_size()));

View File

@ -207,7 +207,7 @@ std::optional<tr_sha1_digest_t> recalculate_hash(tr_torrent const& tor, tr_piece
{
TR_ASSERT(piece < tor.piece_count());
auto sha = tr_sha1::create();
auto sha = tr_sha1{};
auto buffer = std::array<uint8_t, tr_block_info::BlockSize>{};
auto& cache = tor.session->cache;
@ -236,12 +236,12 @@ std::optional<tr_sha1_digest_t> recalculate_hash(tr_torrent const& tor, tr_piece
end -= (block_loc.byte + block_len - end_byte);
}
sha->add(begin, end - begin);
sha.add(begin, end - begin);
n_bytes_checked += (end - begin);
}
TR_ASSERT(tor.piece_size(piece) == n_bytes_checked);
return sha->finish();
return sha.finish();
}
} // namespace

View File

@ -165,7 +165,7 @@ bool tr_metainfo_builder::blocking_make_checksums(tr_error* error)
auto hashes = std::vector<std::byte>(std::size(tr_sha1_digest_t{}) * piece_count());
auto* walk = std::data(hashes);
auto sha = tr_sha1::create();
auto sha = tr_sha1{};
auto file_index = tr_file_index_t{ 0U };
auto piece_index = tr_piece_index_t{ 0U };
@ -229,10 +229,10 @@ bool tr_metainfo_builder::blocking_make_checksums(tr_error* error)
TR_ASSERT(bufptr - std::data(buf) == (int)piece_size);
TR_ASSERT(left_in_piece == 0);
sha->add(std::data(buf), std::size(buf));
auto const digest = sha->finish();
sha.add(std::data(buf), std::size(buf));
auto const digest = sha.finish();
walk = std::copy(std::begin(digest), std::end(digest), walk);
sha->clear();
sha.clear();
total_remain -= piece_size;
++piece_index;

View File

@ -45,7 +45,7 @@ void tr_verify_worker::verify_torrent(
tr_file_index_t prev_file_index = ~file_index;
tr_piece_index_t piece = 0U;
auto buffer = std::vector<std::byte>(1024U * 256U);
auto sha = tr_sha1::create();
auto sha = tr_sha1{};
auto last_slept_at = current_time_secs();
auto const& metainfo = verify_mediator.metainfo();
@ -74,7 +74,7 @@ void tr_verify_worker::verify_torrent(
if (tr_sys_file_read_at(fd, std::data(buffer), bytes_this_pass, file_pos, &num_read) && num_read > 0U)
{
bytes_this_pass = num_read;
sha->add(std::data(buffer), bytes_this_pass);
sha.add(std::data(buffer), bytes_this_pass);
}
}
@ -87,7 +87,7 @@ void tr_verify_worker::verify_torrent(
/* if we're finishing a piece... */
if (left_in_piece == 0U)
{
auto const has_piece = sha->finish() == metainfo.piece_hash(piece);
auto const has_piece = sha.finish() == metainfo.piece_hash(piece);
verify_mediator.on_piece_checked(piece, has_piece);
if (sleep_per_seconds_during_verify > std::chrono::milliseconds::zero())
@ -101,7 +101,7 @@ void tr_verify_worker::verify_torrent(
}
}
sha->clear();
sha.clear();
++piece;
piece_pos = 0U;
}

View File

@ -1,6 +1,6 @@
#!/usr/bin/env pwsh
$global:OpenSslVersion = '3.1.4'
$global:OpenSslVersion = '3.1.5'
$global:OpenSslDeps = @()

View File

@ -1,6 +1,6 @@
#!/usr/bin/env pwsh
$global:Qt6Version = '6.6.0'
$global:Qt6Version = '6.6.2'
$global:Qt6Deps = @(
'DBus'

View File

@ -15,7 +15,6 @@ target_sources(libtransmission-test
clients-test.cc
completion-test.cc
copy-test.cc
crypto-test-ref.h
crypto-test.cc
error-test.cc
dht-test.cc

View File

@ -1,116 +0,0 @@
// This file Copyright (C) 2015-2022 Mnemosyne LLC.
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
// or any future license endorsed by Mnemosyne LLC.
// License text can be found in the licenses/ folder.
#ifndef TR_CRYPTO_TEST_REF_H
#define TR_CRYPTO_TEST_REF_H
/* #define CRYPTO_REFERENCE_CHECK */
#ifdef CRYPTO_REFERENCE_CHECK
#define tr_base64_decode tr_base64_decode_
#define tr_base64_decode_impl tr_base64_decode_impl_
#define tr_base64_encode tr_base64_encode_
#define tr_base64_encode_impl tr_base64_encode_impl_
#define tr_rand_buffer tr_rand_buffer_
#define tr_rand_buffer_crypto tr_rand_buffer_crypto_
#define tr_rand_buffer_std tr_rand_buffer_std_
#define tr_rand_int tr_rand_int_
#define tr_rand_obj tr_rand_obj_
#define tr_salt_shaker tr_salt_shaker_
#define tr_sha1 tr_sha1_
#define tr_sha1_from_string tr_sha1_from_string_
#define tr_sha1_to_string tr_sha1_to_string_
#define tr_sha256 tr_sha256_
#define tr_sha256_from_string tr_sha256_from_string_
#define tr_sha256_to_string tr_sha256_to_string_
#define tr_ssha1 tr_ssha1_
#define tr_ssha1_matches tr_ssha1_matches_
#define tr_ssha1_test tr_ssha1_test_
#define tr_ssl_ctx_t tr_ssl_ctx_t_
#define tr_ssl_get_x509_store tr_ssl_get_x509_store_
#define tr_urbg tr_urbg_
#define tr_x509_cert_free tr_x509_cert_free_
#define tr_x509_cert_new tr_x509_cert_new_
#define tr_x509_cert_t tr_x509_cert_t_
#define tr_x509_store_add tr_x509_store_add_
#define tr_x509_store_t tr_x509_store_t_
#undef TR_ENCRYPTION_H
#undef TR_CRYPTO_UTILS_H
#include <libtransmission/crypto-utils.h>
#include <libtransmission/crypto-utils.cc>
#include <libtransmission/crypto-utils-openssl.cc>
#undef tr_base64_decode
#undef tr_base64_decode_impl
#undef tr_base64_encode
#undef tr_base64_encode_impl
#undef tr_rand_buffer
#undef tr_rand_buffer_crypto
#undef tr_rand_buffer_std
#undef tr_rand_int
#undef tr_rand_obj
#undef tr_salt_shaker
#undef tr_sha1
#undef tr_sha1_from_string
#undef tr_sha1_to_string
#undef tr_sha256
#undef tr_sha256_from_string
#undef tr_sha256_to_string
#undef tr_ssha1
#undef tr_ssha1_matches
#undef tr_ssha1_test
#undef tr_ssl_ctx_t
#undef tr_ssl_get_x509_store
#undef tr_urbg
#undef tr_x509_cert_free
#undef tr_x509_cert_new
#undef tr_x509_cert_t
#undef tr_x509_store_add
#undef tr_x509_store_t
#else /* CRYPTO_REFERENCE_CHECK */
#define tr_base64_decode_ tr_base64_decode
#define tr_base64_decode_impl_ tr_base64_decode_impl
#define tr_base64_encode_ tr_base64_encode
#define tr_base64_encode_impl_ tr_base64_encode_impl
#define tr_rand_buffer_ tr_rand_buffer
#define tr_rand_buffer_crypto_ tr_rand_buffer_crypto
#define tr_rand_buffer_std_ tr_rand_buffer_std
#define tr_rand_int_ tr_rand_int
#define tr_rand_obj_ tr_rand_obj
#define tr_salt_shaker_ tr_salt_shaker
#define tr_sha1_ tr_sha1
#define tr_sha1_ctx_t_ tr_sha1_ctx_t
#define tr_sha1_final_ tr_sha1_final
#define tr_sha1_from_string_ tr_sha1_from_string
#define tr_sha1_init_ tr_sha1_init
#define tr_sha1_to_string_ tr_sha1_to_string
#define tr_sha1_update_ tr_sha1_update
#define tr_sha256_ tr_sha256
#define tr_sha256_ctx_t_ tr_sha256_ctx_t
#define tr_sha256_final_ tr_sha256_final
#define tr_sha256_from_string_ tr_sha256_from_string
#define tr_sha256_init_ tr_sha256_init
#define tr_sha256_to_string_ tr_sha256_to_string
#define tr_sha256_update_ tr_sha256_update
#define tr_ssha1_ tr_ssha1
#define tr_ssha1_matches_ tr_ssha1_matches
#define tr_ssha1_test_ tr_ssha1_test
#define tr_ssl_ctx_t_ tr_ssl_ctx_t
#define tr_ssl_get_x509_store_ tr_ssl_get_x509_store
#define tr_urbg_ tr_urbg
#define tr_x509_cert_free_ tr_x509_cert_free
#define tr_x509_cert_new_ tr_x509_cert_new
#define tr_x509_cert_t_ tr_x509_cert_t
#define tr_x509_store_add_ tr_x509_store_add
#define tr_x509_store_t_ tr_x509_store_t
#endif /* CRYPTO_REFERENCE_CHECK */
#endif /* TR_CRYPTO_TEST_REF_H */

View File

@ -18,8 +18,6 @@
#include <libtransmission/tr-macros.h>
#include <libtransmission/utils.h>
#include "crypto-test-ref.h"
#include "gtest/gtest.h"
using namespace std::literals;
@ -150,19 +148,11 @@ TEST(Crypto, ssha1)
hashes.reserve(HashCount);
EXPECT_TRUE(tr_ssha1_matches(ssha1, plain_text));
EXPECT_TRUE(tr_ssha1_matches_(ssha1, plain_text));
using ssha1_func = std::string (*)(std::string_view plain_text);
static auto constexpr Ssha1Funcs = std::array<ssha1_func, 2>{ tr_ssha1, tr_ssha1_ };
for (size_t j = 0; j < HashCount; ++j)
{
auto const hash = Ssha1Funcs[j % 2](plain_text);
// phrase matches each of generated hashes
auto const hash = tr_ssha1(plain_text);
EXPECT_TRUE(tr_ssha1_matches(hash, plain_text));
EXPECT_TRUE(tr_ssha1_matches_(hash, plain_text));
hashes.insert(hash);
}
@ -171,15 +161,12 @@ TEST(Crypto, ssha1)
/* exchange two first chars */
auto phrase = std::string{ plain_text };
phrase[0] ^= phrase[1];
phrase[1] ^= phrase[0];
phrase[0] ^= phrase[1];
std::swap(phrase[0], phrase[1]);
for (auto const& hash : hashes)
{
/* changed phrase doesn't match the hashes */
EXPECT_FALSE(tr_ssha1_matches(hash, phrase));
EXPECT_FALSE(tr_ssha1_matches_(hash, phrase));
}
}