diff options
| author | Julian Andres Klode <julian.klode@canonical.com> | 2024-12-18 19:11:26 +0100 |
|---|---|---|
| committer | Julian Andres Klode <julian.klode@canonical.com> | 2024-12-21 13:31:06 +0100 |
| commit | 470f5cf449ac20c7d7bf50ad805c72a5f52d256f (patch) | |
| tree | 59ab3c90456ff7ae26391c000a3d8a43957d0025 /apt-pkg | |
| parent | ef435a3ed9c3e835c799df651f160b658eeee56a (diff) | |
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.
Diffstat (limited to 'apt-pkg')
| -rw-r--r-- | apt-pkg/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | apt-pkg/contrib/hashes.cc | 66 |
2 files changed, 68 insertions, 0 deletions
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 $<$<BOOL:${UDEV_FOUND}>:${UDEV_INCLUDE_DIRS}> $<$<BOOL:${SYSTEMD_FOUND}>:${SYSTEMD_INCLUDE_DIRS}> ${ICONV_INCLUDE_DIRS} + $<$<BOOL:${GNUTLS_FOUND}>:${GNUTLS_INCLUDE_DIRS}> $<$<BOOL:${GCRYPT_FOUND}>:${GCRYPT_INCLUDE_DIRS}> $<$<BOOL:${XXHASH_FOUND}>:${XXHASH_INCLUDE_DIRS}> ) @@ -71,6 +72,7 @@ target_link_libraries(apt-pkg $<$<BOOL:${UDEV_FOUND}>:${UDEV_LIBRARIES}> $<$<BOOL:${SYSTEMD_FOUND}>:${SYSTEMD_LIBRARIES}> ${ICONV_LIBRARIES} + $<$<BOOL:${GNUTLS_FOUND}>:${GNUTLS_LIBRARIES}> $<$<BOOL:${GCRYPT_FOUND}>:${GCRYPT_LIBRARIES}> $<$<BOOL:${XXHASH_FOUND}>:${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 <cstddef> #include <cstdlib> #include <iostream> +#include <optional> #include <string> #include <unistd.h> +#ifdef HAVE_GNUTLS +#include <gnutls/crypto.h> +#else #include <gcrypt.h> +#endif /*}}}*/ const char * HashString::_SupportedHashes[] = @@ -324,6 +329,66 @@ class PrivateHashes unsigned long long FileSize{0}; private: +#ifdef HAVE_GNUTLS + std::array<std::optional<gnutls_hash_hd_t>, 4> digs{}; + + public: + struct HashAlgo + { + size_t index; + const char *name; + gnutls_digest_algorithm_t gnuTlsAlgo; + Hashes::SupportedHashes ourAlgo; + }; + + static constexpr std::array<HashAlgo, 4> 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<unsigned char>(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() { |
