From 470f5cf449ac20c7d7bf50ad805c72a5f52d256f Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 18 Dec 2024 19:11:26 +0100 Subject: hashes: Add GnuTLS backend, make it default The GnuTLS backend avoids the need to link in libgcrypt, and gets us another certified library people will be happy with. This should be an intermediate step on the road to OpenSSL. --- CMakeLists.txt | 4 ++- apt-pkg/CMakeLists.txt | 2 ++ apt-pkg/contrib/hashes.cc | 66 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c6977675e..4d2a5414d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,7 +141,9 @@ if (SECCOMP_FOUND) set(HAVE_SECCOMP 1) endif() -find_package(GCRYPT REQUIRED) +if (NOT HAVE_GNUTLS) + find_package(GCRYPT REQUIRED) +endif() find_package(XXHASH REQUIRED) # Mount()ing and stat()ing and friends diff --git a/apt-pkg/CMakeLists.txt b/apt-pkg/CMakeLists.txt index 63052faad..c68b7bddc 100644 --- a/apt-pkg/CMakeLists.txt +++ b/apt-pkg/CMakeLists.txt @@ -56,6 +56,7 @@ target_include_directories(apt-pkg $<$:${UDEV_INCLUDE_DIRS}> $<$:${SYSTEMD_INCLUDE_DIRS}> ${ICONV_INCLUDE_DIRS} + $<$:${GNUTLS_INCLUDE_DIRS}> $<$:${GCRYPT_INCLUDE_DIRS}> $<$:${XXHASH_INCLUDE_DIRS}> ) @@ -71,6 +72,7 @@ target_link_libraries(apt-pkg $<$:${UDEV_LIBRARIES}> $<$:${SYSTEMD_LIBRARIES}> ${ICONV_LIBRARIES} + $<$:${GNUTLS_LIBRARIES}> $<$:${GCRYPT_LIBRARIES}> $<$:${XXHASH_LIBRARIES}> ) diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index a4d5026b4..033cd0845 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -26,10 +26,15 @@ #include #include #include +#include #include #include +#ifdef HAVE_GNUTLS +#include +#else #include +#endif /*}}}*/ const char * HashString::_SupportedHashes[] = @@ -324,6 +329,66 @@ class PrivateHashes unsigned long long FileSize{0}; private: +#ifdef HAVE_GNUTLS + std::array, 4> digs{}; + + public: + struct HashAlgo + { + size_t index; + const char *name; + gnutls_digest_algorithm_t gnuTlsAlgo; + Hashes::SupportedHashes ourAlgo; + }; + + static constexpr std::array Algorithms{ + HashAlgo{0, "MD5Sum", GNUTLS_DIG_MD5, Hashes::MD5SUM}, + HashAlgo{1, "SHA1", GNUTLS_DIG_SHA1, Hashes::SHA1SUM}, + HashAlgo{2, "SHA256", GNUTLS_DIG_SHA256, Hashes::SHA256SUM}, + HashAlgo{3, "SHA512", GNUTLS_DIG_SHA512, Hashes::SHA512SUM}, + }; + + bool Write(unsigned char const *Data, size_t Size) + { + for (auto &dig : digs) + { + if (dig) + gnutls_hash(*dig, Data, Size); + } + return true; + } + + std::string HexDigest(HashAlgo const &algo) + { + auto Size = gnutls_hash_get_len(algo.gnuTlsAlgo); + unsigned char Sum[Size]; + if (auto copy = gnutls_hash_copy(*digs[algo.index])) + gnutls_hash_deinit(copy, &Sum); + return ::HexDigest(std::basic_string_view(Sum, Size)); + } + bool Enable(HashAlgo const &algo) + { + digs[algo.index].emplace(); + if (gnutls_hash_init(&*digs[algo.index], algo.gnuTlsAlgo) == 0) + return true; + digs[algo.index] = std::nullopt; + return false; + } + bool IsEnabled(HashAlgo const &algo) + { + return bool{digs[algo.index]}; + } + + explicit PrivateHashes() {} + ~PrivateHashes() + { + for (auto &dig : digs) + { + if (dig) + gnutls_hash_deinit(*dig, nullptr); + } + } +#else gcry_md_hd_t hd; void maybeInit() @@ -395,6 +460,7 @@ class PrivateHashes { gcry_md_close(hd); } +#endif explicit PrivateHashes(unsigned int const CalcHashes) : PrivateHashes() { -- cgit v1.2.3-70-g09d2