summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2024-12-18 19:11:26 +0100
committerJulian Andres Klode <julian.klode@canonical.com>2024-12-21 13:31:06 +0100
commit470f5cf449ac20c7d7bf50ad805c72a5f52d256f (patch)
tree59ab3c90456ff7ae26391c000a3d8a43957d0025 /apt-pkg
parentef435a3ed9c3e835c799df651f160b658eeee56a (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.txt2
-rw-r--r--apt-pkg/contrib/hashes.cc66
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()
{