]> git.ipfire.org Git - pakfire.git/commitdiff
hashes: Replace the old digest mechanism
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 4 Feb 2025 10:37:50 +0000 (10:37 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 4 Feb 2025 11:13:09 +0000 (11:13 +0000)
This is splitting the hasher into a separate object so that we have more
flexibility here. It also renames the digests struct into "hashes" which
is a little bit shorter and I thought that it makes more sense.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
26 files changed:
Makefile.am
src/pakfire/archive.c
src/pakfire/archive.h
src/pakfire/buildservice.c
src/pakfire/compress.c
src/pakfire/compress.h
src/pakfire/db.c
src/pakfire/digest.c [deleted file]
src/pakfire/digest.h [deleted file]
src/pakfire/file.c
src/pakfire/file.h
src/pakfire/hasher.c [new file with mode: 0644]
src/pakfire/hasher.h [new file with mode: 0644]
src/pakfire/hashes.c [new file with mode: 0644]
src/pakfire/hashes.h [new file with mode: 0644]
src/pakfire/package.c
src/pakfire/package.h
src/pakfire/packager.c
src/pakfire/packager.h
src/pakfire/repo.c
src/pakfire/transaction.c
src/pakfire/xfer.c
src/pakfire/xfer.h
src/python/file.c
src/python/package.c
tests/libpakfire/xfer.c

index b730e18e780174c5f6fde33cf8159bd18d89805b..c02ca54eee4c10de8990afec309f656503d5d069 100644 (file)
@@ -207,8 +207,6 @@ libpakfire_la_SOURCES = \
        src/pakfire/db.h \
        src/pakfire/deps.c \
        src/pakfire/deps.h \
-       src/pakfire/digest.c \
-       src/pakfire/digest.h \
        src/pakfire/dist.c \
        src/pakfire/dist.h \
        src/pakfire/elf.c \
@@ -221,6 +219,10 @@ libpakfire_la_SOURCES = \
        src/pakfire/file.h \
        src/pakfire/filelist.c \
        src/pakfire/filelist.h \
+       src/pakfire/hasher.c \
+       src/pakfire/hasher.h \
+       src/pakfire/hashes.c \
+       src/pakfire/hashes.h \
        src/pakfire/hex.c \
        src/pakfire/hex.h \
        src/pakfire/httpclient.c \
@@ -572,7 +574,6 @@ check_PROGRAMS += \
        tests/libpakfire/config \
        tests/libpakfire/db \
        tests/libpakfire/deps \
-       tests/libpakfire/digest \
        tests/libpakfire/env \
        tests/libpakfire/file \
        tests/libpakfire/httpclient \
@@ -727,21 +728,6 @@ tests_libpakfire_deps_LDFLAGS = \
 tests_libpakfire_deps_LDADD = \
        $(TESTSUITE_LDADD)
 
-dist_tests_libpakfire_digest_SOURCES = \
-       tests/libpakfire/digest.c
-
-tests_libpakfire_digest_CPPFLAGS = \
-       $(TESTSUITE_CPPFLAGS)
-
-tests_libpakfire_digest_CFLAGS = \
-       $(TESTSUITE_CFLAGS)
-
-tests_libpakfire_digest_LDFLAGS = \
-       $(TESTSUITE_LDFLAGS)
-
-tests_libpakfire_digest_LDADD = \
-       $(TESTSUITE_LDADD)
-
 dist_tests_libpakfire_env_SOURCES = \
        tests/libpakfire/env.c
 
index decfb4730bca3d6550a609744d42f5f8870c170e..f6dd284fe6afd7d7785563497dd37a2c27b36a7b 100644 (file)
 #include <pakfire/compress.h>
 #include <pakfire/ctx.h>
 #include <pakfire/deps.h>
-#include <pakfire/digest.h>
 #include <pakfire/file.h>
 #include <pakfire/filelist.h>
+#include <pakfire/hasher.h>
+#include <pakfire/hashes.h>
 #include <pakfire/hex.h>
 #include <pakfire/i18n.h>
 #include <pakfire/jail.h>
@@ -53,6 +54,9 @@
 #include <pakfire/string.h>
 #include <pakfire/util.h>
 
+// Compute checksums using SHA2-512
+#define PAKFIRE_ARCHIVE_CHECKSUM PAKFIRE_HASH_SHA2_512
+
 #define MAX_SCRIPTLETS 9
 
 // The maximum number of symlinks to follow when reading a file from an archive
@@ -81,8 +85,8 @@ struct pakfire_archive {
        struct pakfire_scriptlet* scriptlets[MAX_SCRIPTLETS];
        unsigned int num_scriptlets;
 
-       // Digests
-       struct pakfire_digests digests;
+       // Hashes
+       struct pakfire_hashes hashes;
 
        // Progress (when extracting)
        struct pakfire_progress* progress;
@@ -277,7 +281,7 @@ ERROR:
        return r;
 }
 
-static int pakfire_archive_compute_digests(struct pakfire_archive* archive) {
+static int pakfire_archive_compute_hashes(struct pakfire_archive* archive) {
        int r;
 
        // Start reading at the beginning
@@ -287,13 +291,15 @@ static int pakfire_archive_compute_digests(struct pakfire_archive* archive) {
                return -errno;
        }
 
-       // Calculate digest
-       r = pakfire_digests_compute_from_file(archive->ctx, &archive->digests,
-                       PAKFIRE_ARCHIVE_CHECKSUM, archive->f);
-       if (r)
-               ERROR(archive->ctx, "Could not calculate digest of %s: %m\n", archive->path);
+       // Calculate hashes
+       r = pakfire_hash_file(archive->ctx, archive->f,PAKFIRE_ARCHIVE_CHECKSUM, &archive->hashes);
+       if (r < 0) {
+               ERROR(archive->ctx, "Could not calculate checksums of %s: %s\n",
+                       archive->path, strerror(-r));
+               return r;
+       }
 
-       return r;
+       return 0;
 }
 
 /*
@@ -1469,35 +1475,29 @@ ssize_t pakfire_archive_get_size(struct pakfire_archive* archive) {
        return archive->stat.st_size;
 }
 
-int pakfire_archive_check_digest(struct pakfire_archive* archive,
-               const enum pakfire_digest_types type, const unsigned char* digest, const size_t length) {
-       size_t computed_length = 0;
+int pakfire_archive_verify_checksum(struct pakfire_archive* archive,
+               const enum pakfire_hash_type type, const unsigned char* checksum, const size_t length) {
+       struct pakfire_hashes expected_hashes = {};
        int r;
 
-       // Compute the digest
-       r = pakfire_archive_compute_digests(archive);
-       if (r)
+       // Store the checksum
+       r = pakfire_hashes_set(&expected_hashes, type, checksum, length);
+       if (r < 0)
                return r;
 
-       // Compare computed with expected digest
-       r = pakfire_digests_compare_one(archive->ctx, &archive->digests, type, digest, length);
-       if (r) {
-               const unsigned char* computed_digest = pakfire_digest_get(
-                       &archive->digests, type, &computed_length);
-
-               char* expected_hexdigest = __pakfire_hexlify(digest, length);
-               char* computed_hexdigest = __pakfire_hexlify(computed_digest, computed_length);
-
-               ERROR(archive->ctx, "Archive digest does not match for %s:\n", archive->path);
-               ERROR(archive->ctx, "  Expected: %s\n", expected_hexdigest);
-               ERROR(archive->ctx, "  Computed: %s\n", computed_hexdigest);
-
-               if (expected_hexdigest)
-                       free(expected_hexdigest);
-               if (computed_hexdigest)
-                       free(computed_hexdigest);
-
+       // Compute the checksums
+       r = pakfire_archive_compute_hashes(archive);
+       if (r < 0)
                return r;
+
+       // Compare the hashes
+       r = pakfire_hashes_compare(archive->ctx, &expected_hashes, &archive->hashes);
+       if (r) {
+               ERROR(archive->ctx, "Archive checksum does not match for %s:\n", archive->path);
+               ERROR(archive->ctx, " Expected:\n");
+               pakfire_hashes_dump(archive->ctx, &expected_hashes, LOG_ERR);
+               ERROR(archive->ctx, " Computed:\n");
+               pakfire_hashes_dump(archive->ctx, &archive->hashes, LOG_ERR);
        }
 
        return r;
@@ -1548,8 +1548,8 @@ static int pakfire_archive_make_package_from_json(struct pakfire_archive* archiv
        char path[PATH_MAX];
        int r;
 
-       // Calculate digest
-       r = pakfire_archive_compute_digests(archive);
+       // Calculate checksums
+       r = pakfire_archive_compute_hashes(archive);
        if (r)
                return r;
 
@@ -1570,20 +1570,24 @@ static int pakfire_archive_make_package_from_json(struct pakfire_archive* archiv
                nevra, pkg, archive);
 #endif
 
-       // Set digest
+       // Set checksum
        switch (PAKFIRE_ARCHIVE_CHECKSUM) {
-               case PAKFIRE_DIGEST_SHA2_512:
-                       pakfire_package_set_digest(pkg, PAKFIRE_ARCHIVE_CHECKSUM,
-                               archive->digests.sha2_512, sizeof(archive->digests.sha2_512));
+               case PAKFIRE_HASH_SHA2_512:
+                       r = pakfire_package_set_checksum(pkg, PAKFIRE_ARCHIVE_CHECKSUM,
+                                       archive->hashes.sha2_512, sizeof(archive->hashes.sha2_512));
+                       if (r < 0)
+                               goto ERROR;
                        break;
 
-               case PAKFIRE_DIGEST_SHA2_256:
-                       pakfire_package_set_digest(pkg, PAKFIRE_ARCHIVE_CHECKSUM,
-                               archive->digests.sha2_256, sizeof(archive->digests.sha2_256));
+               case PAKFIRE_HASH_SHA2_256:
+                       r = pakfire_package_set_checksum(pkg, PAKFIRE_ARCHIVE_CHECKSUM,
+                                       archive->hashes.sha2_256, sizeof(archive->hashes.sha2_256));
+                       if (r < 0)
+                               goto ERROR;
                        break;
 
-               case PAKFIRE_DIGEST_UNDEFINED:
-                       r = 1;
+               case PAKFIRE_HASH_UNDEFINED:
+                       r = -EINVAL;
                        goto ERROR;
        }
 
index 578342e4a5826f8906f1f2a81250542f6cbb2b4c..28404b8a6427157d0387e41240a9dca3002f2f66 100644 (file)
@@ -27,8 +27,8 @@
 
 struct pakfire_archive;
 
-#include <pakfire/digest.h>
 #include <pakfire/filelist.h>
+#include <pakfire/hashes.h>
 #include <pakfire/linter.h>
 #include <pakfire/package.h>
 #include <pakfire/pakfire.h>
@@ -56,6 +56,10 @@ struct pakfire_filelist* pakfire_archive_get_filelist(struct pakfire_archive* ar
 int pakfire_archive_verify(struct pakfire_archive* archive, int* status);
 
 ssize_t pakfire_archive_get_size(struct pakfire_archive* archive);
+
+int pakfire_archive_verify_checksum(struct pakfire_archive* archive,
+       const enum pakfire_hash_type type, const unsigned char* checksum, const size_t length);
+
 int pakfire_archive_make_package(struct pakfire_archive* archive,
        struct pakfire_repo* repo, struct pakfire_package** package);
 
@@ -93,9 +97,6 @@ int pakfire_archive_unlink(struct pakfire_archive* archive);
 int pakfire_archive_copy(struct pakfire_archive* archive, const char* path);
 int pakfire_archive_link_or_copy(struct pakfire_archive* archive, const char* path);
 
-int pakfire_archive_check_digest(struct pakfire_archive* archive,
-       const enum pakfire_digest_types type, const unsigned char* digest, const size_t length);
-
 struct pakfire_scriptlet* pakfire_archive_get_scriptlet(
        struct pakfire_archive* archive, const char* type);
 
index ea6734cf44ca9c0aeedd50427b0bcd3cc7fcbf7b..179f6109bc839ef53281de83f74ebe898c456298 100644 (file)
@@ -27,7 +27,8 @@
 #include <pakfire/buildservice.h>
 #include <pakfire/config.h>
 #include <pakfire/ctx.h>
-#include <pakfire/digest.h>
+#include <pakfire/hasher.h>
+#include <pakfire/hashes.h>
 #include <pakfire/logging.h>
 #include <pakfire/os.h>
 #include <pakfire/path.h>
@@ -269,8 +270,8 @@ ERROR:
 
 static int pakfire_buildservice_create_upload(struct pakfire_buildservice* service,
                const char* path, const char* filename, FILE* f, char** url, char** uuid) {
+       struct pakfire_hashes hashes = {};
        struct pakfire_xfer* xfer = NULL;
-       struct pakfire_digests digests = {};
        struct json_object* response = NULL;
        char* hexdigest_blake2b512 = NULL;
        struct stat stat;
@@ -286,16 +287,16 @@ static int pakfire_buildservice_create_upload(struct pakfire_buildservice* servi
        }
 
        // Compute the digest
-       r = pakfire_digests_compute_from_file(service->ctx, &digests, PAKFIRE_DIGEST_BLAKE2B512, f);
-       if (r) {
-               ERROR(service->ctx, "Could not compute the digest of %s: %s\n",
+       r = pakfire_hash_file(service->ctx, f, PAKFIRE_HASH_BLAKE2B512, &hashes);
+       if (r < 0) {
+               ERROR(service->ctx, "Could not compute the checksum of %s: %s\n",
                        path, strerror(-r));
                goto ERROR;
        }
 
        // Convert the digest into hex format
-       hexdigest_blake2b512 = pakfire_digest_get_hex(&digests, PAKFIRE_DIGEST_BLAKE2B512);
-       if (!hexdigest_blake2b512)
+       r = pakfire_hashes_get_hex(&hashes, PAKFIRE_HASH_BLAKE2B512, &hexdigest_blake2b512);
+       if (r < 0)
                goto ERROR;
 
        // Create a new xfer
index 9dba2a0c91ec0f42d66f2da342d23b660e5e34fb..99fa8eced83ca4b04f1a177492851fb85d5ac90e 100644 (file)
@@ -32,6 +32,7 @@
 #include <pakfire/compress.h>
 #include <pakfire/file.h>
 #include <pakfire/filelist.h>
+#include <pakfire/hashes.h>
 #include <pakfire/logging.h>
 #include <pakfire/path.h>
 #include <pakfire/progress.h>
@@ -687,8 +688,8 @@ struct pakfire_compress {
        // The progress indicator
        struct pakfire_progress* progress;
 
-       // Digests to write to the archive
-       int digests;
+       // Checksums to write to the archive
+       int checksum_types;
 };
 
 static int pakfire_copy_data_from_file(struct pakfire_ctx* ctx,
@@ -787,7 +788,7 @@ static int __pakfire_compress(struct pakfire_ctx* ctx, struct pakfire_file* file
        const size_t size = pakfire_file_get_size(file);
 
        // Generate file metadata into an archive entry
-       entry = pakfire_file_archive_entry(file, data->digests);
+       entry = pakfire_file_archive_entry(file, data->checksum_types);
        if (!entry) {
                r = -errno;
                goto ERROR;
@@ -848,7 +849,8 @@ ERROR:
 }
 
 int pakfire_compress(struct pakfire* pakfire, struct archive* archive,
-               struct pakfire_filelist* filelist, const char* message, int flags, int digests) {
+               struct pakfire_filelist* filelist, const char* message, int flags,
+               enum pakfire_hash_type checksum_types) {
        int progress_flags =
                PAKFIRE_PROGRESS_SHOW_PERCENTAGE |
                PAKFIRE_PROGRESS_SHOW_BYTES_TRANSFERRED;
@@ -857,12 +859,12 @@ int pakfire_compress(struct pakfire* pakfire, struct archive* archive,
        struct pakfire_ctx* ctx = pakfire_ctx(pakfire);
 
        struct pakfire_compress data = {
-               .ctx      = ctx,
-               .pakfire  = pakfire,
-               .archive  = archive,
-               .filelist = filelist,
-               .flags    = flags,
-               .digests  = digests,
+               .ctx            = ctx,
+               .pakfire        = pakfire,
+               .archive        = archive,
+               .filelist       = filelist,
+               .flags          = flags,
+               .checksum_types = checksum_types,
        };
 
        // Should we show a progress bar?
index f275aebb4569c5b597b2b661b2eac64f1751a40a..c3ec0fb9b0c91fb963e014eb8703e60a8621c205 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <pakfire/archive.h>
 #include <pakfire/ctx.h>
+#include <pakfire/hashes.h>
 #include <pakfire/pakfire.h>
 
 // Automatically detect
@@ -63,7 +64,7 @@ enum pakfire_compress_flags {
 };
 
 int pakfire_compress(struct pakfire* pakfire, struct archive* archive,
-       struct pakfire_filelist* filelist, const char* message, int flags, int digests);
+       struct pakfire_filelist* filelist, const char* message, int flags, enum pakfire_hash_type checksum_types);
 
 int pakfire_compress_create_archive(struct pakfire* pakfire, struct archive** archive,
        FILE* f, const enum pakfire_compressions compression, const unsigned int level);
index 72cf819afeba2b293ebbb1cc5a80e4c2fd878ec4..51adffca6cb1345f0e0704a73042a72843f19e4c 100644 (file)
@@ -31,9 +31,9 @@
 #include <pakfire/ctx.h>
 #include <pakfire/db.h>
 #include <pakfire/deps.h>
-#include <pakfire/digest.h>
 #include <pakfire/file.h>
 #include <pakfire/filelist.h>
+#include <pakfire/hashes.h>
 #include <pakfire/logging.h>
 #include <pakfire/package.h>
 #include <pakfire/pakfire.h>
@@ -977,20 +977,23 @@ END:
        return r;
 }
 
-static int pakfire_db_bind_digest(struct pakfire_db* db, sqlite3_stmt* stmt, const int field,
-               struct pakfire_file* file, const enum pakfire_digest_types type) {
-       const unsigned char* digest = NULL;
-       size_t length = 0;
+static int pakfire_db_bind_checksum(struct pakfire_db* db, sqlite3_stmt* stmt,
+               const int field, struct pakfire_file* file, const enum pakfire_hash_type type) {
+       const unsigned char* checksum = NULL;
+       size_t checksum_length = 0;
+       int r;
 
-       // Fetch the digest
-       digest = pakfire_file_get_digest(file, type, &length);
+       // Fetch the checksum
+       r = pakfire_file_get_checksum(file, type, &checksum, &checksum_length);
+       if (r < 0)
+               return r;
 
-       // If this digest isn't set, just bind NULL
-       if (!digest)
+       // If this checksum isn't set, just bind NULL
+       if (!checksum)
                return sqlite3_bind_null(stmt, field);
 
        // Otherwise bind the data blob
-       return sqlite3_bind_blob(stmt, field, digest, length, NULL);
+       return sqlite3_bind_blob(stmt, field, checksum, checksum_length, NULL);
 }
 
 static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, struct pakfire_archive* archive) {
@@ -1169,7 +1172,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, struct
                }
 
                // SHA2-512 Digest
-               r = pakfire_db_bind_digest(db, stmt, 13, file, PAKFIRE_DIGEST_SHA2_512);
+               r = pakfire_db_bind_checksum(db, stmt, 13, file, PAKFIRE_HASH_SHA2_512);
                if (r) {
                        ERROR(db->ctx, "Could not bind SHA2-512 digest: %s\n",
                                sqlite3_errmsg(db->handle));
@@ -1178,7 +1181,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, struct
                }
 
                // SHA2-256 Digest
-               r = pakfire_db_bind_digest(db, stmt, 14, file, PAKFIRE_DIGEST_SHA2_256);
+               r = pakfire_db_bind_checksum(db, stmt, 14, file, PAKFIRE_HASH_SHA2_256);
                if (r) {
                        ERROR(db->ctx, "Could not bind SHA2-256 digest: %s\n",
                                sqlite3_errmsg(db->handle));
@@ -1187,7 +1190,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, struct
                }
 
                // BLAKE2b512 Digest
-               r = pakfire_db_bind_digest(db, stmt, 15, file, PAKFIRE_DIGEST_BLAKE2B512);
+               r = pakfire_db_bind_checksum(db, stmt, 15, file, PAKFIRE_HASH_BLAKE2B512);
                if (r) {
                        ERROR(db->ctx, "Could not bind BLAKE2b512 digest: %s\n",
                                sqlite3_errmsg(db->handle));
@@ -1196,7 +1199,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, struct
                }
 
                // BLAKE2s256 Digest
-               r = pakfire_db_bind_digest(db, stmt, 16, file, PAKFIRE_DIGEST_BLAKE2S256);
+               r = pakfire_db_bind_checksum(db, stmt, 16, file, PAKFIRE_HASH_BLAKE2S256);
                if (r) {
                        ERROR(db->ctx, "Could not bind BLAKE2s256 digest: %s\n",
                                sqlite3_errmsg(db->handle));
@@ -1205,7 +1208,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, struct
                }
 
                // SHA3-512 Digest
-               r = pakfire_db_bind_digest(db, stmt, 17, file, PAKFIRE_DIGEST_SHA3_512);
+               r = pakfire_db_bind_checksum(db, stmt, 17, file, PAKFIRE_HASH_SHA3_512);
                if (r) {
                        ERROR(db->ctx, "Could not bind SHA3-512 digest: %s\n",
                                sqlite3_errmsg(db->handle));
@@ -1214,7 +1217,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, struct
                }
 
                // SHA3-256 Digest
-               r = pakfire_db_bind_digest(db, stmt, 18, file, PAKFIRE_DIGEST_SHA3_256);
+               r = pakfire_db_bind_checksum(db, stmt, 18, file, PAKFIRE_HASH_SHA3_256);
                if (r) {
                        ERROR(db->ctx, "Could not bind SHA3-256 digest: %s\n",
                                sqlite3_errmsg(db->handle));
@@ -1331,6 +1334,9 @@ END:
 
 int pakfire_db_add_package(struct pakfire_db* db,
                struct pakfire_package* pkg, struct pakfire_archive* archive, int userinstalled) {
+       enum pakfire_hash_type hash_type = PAKFIRE_HASH_UNDEFINED;
+       const unsigned char* checksum = NULL;
+       size_t checksum_length = 0;
        sqlite3_stmt* stmt = NULL;
        int r;
 
@@ -1478,27 +1484,22 @@ int pakfire_db_add_package(struct pakfire_db* db,
                goto ERROR;
        }
 
-       const unsigned char* digest = NULL;
-       enum pakfire_digest_types digest_type = 0;
-       size_t digest_length = 0;
-
        // Fetch the digest
-       digest = pakfire_package_get_digest(pkg, &digest_type, &digest_length);
-       if (!digest) {
-               ERROR(db->ctx, "Could not fetch the package's digest: %m\n");
-               r = 1;
+       r = pakfire_package_get_checksum(pkg, &hash_type, &checksum, &checksum_length);
+       if (r < 0) {
+               ERROR(db->ctx, "Could not fetch the package checksum: %s\n", strerror(-r));
                goto ERROR;
        }
 
-       // Set the digest type
-       r = sqlite3_bind_int64(stmt, 8, digest_type);
+       // Set the hash type
+       r = sqlite3_bind_int64(stmt, 8, hash_type);
        if (r) {
                ERROR(db->ctx, "Could not bind digest type: %s\n", sqlite3_errmsg(db->handle));
                goto ERROR;
        }
 
-       // Set the digest
-       r = sqlite3_bind_blob(stmt, 9, digest, digest_length, NULL);
+       // Set the checksum
+       r = sqlite3_bind_blob(stmt, 9, checksum, checksum_length, NULL);
        if (r) {
                ERROR(db->ctx, "Could not bind digest: %s\n", sqlite3_errmsg(db->handle));
                goto ERROR;
@@ -1880,16 +1881,19 @@ static int pakfire_db_load_package(struct pakfire_db* db, struct pakfire_repo* r
                        goto ERROR;
        }
 
-       // Digest type
-       enum pakfire_digest_types digest_type = sqlite3_column_int64(stmt, 8);
-       size_t digest_length = 0;
+       // Hash Type
+       enum pakfire_hash_type hash = sqlite3_column_int64(stmt, 8);
 
-       // Digest length
+       // Checksum
+       const unsigned char* checksum = sqlite3_column_blob(stmt, 9);
 
-       // Digest
-       const unsigned char* digest = sqlite3_column_blob(stmt, 9);
-       if (digest_type && digest) {
-               pakfire_package_set_digest(pkg, digest_type, digest, digest_length);
+       // Checksum Length
+       size_t checksum_length = sqlite3_column_bytes(stmt, 9);
+
+       if (hash && checksum) {
+               r = pakfire_package_set_checksum(pkg, hash, checksum, checksum_length);
+               if (r < 0)
+                       goto ERROR;
        }
 
        // License
@@ -2178,20 +2182,20 @@ ERROR:
        return r;
 }
 
-static int pakfire_db_load_file_digest(struct pakfire_db* db, struct pakfire_file* file,
-               sqlite3_stmt* stmt, const enum pakfire_digest_types type, const int field) {
-       // Fetch digest
-       const unsigned char* digest = sqlite3_column_blob(stmt, field);
+static int pakfire_db_load_file_checksum(struct pakfire_db* db, struct pakfire_file* file,
+               sqlite3_stmt* stmt, const enum pakfire_hash_type type, const int field) {
+       // Fetch checksum
+       const unsigned char* checksum = sqlite3_column_blob(stmt, field);
 
        // Nothing further to do if field is NULL
-       if (!digest)
+       if (!checksum)
                return 0;
 
        // Length of the stored value
-       const size_t length = sqlite3_column_bytes(stmt, field);
+       const size_t checksum_length = sqlite3_column_bytes(stmt, field);
 
        // Store digest
-       return pakfire_file_set_digest(file, type, digest, length);
+       return pakfire_file_set_checksum(file, type, checksum, checksum_length);
 }
 
 static int pakfire_db_load_file(struct pakfire_db* db, struct pakfire_filelist* filelist,
@@ -2276,32 +2280,32 @@ static int pakfire_db_load_file(struct pakfire_db* db, struct pakfire_filelist*
                goto ERROR;
 
        // SHA2-512 Digest
-       r = pakfire_db_load_file_digest(db, file, stmt, PAKFIRE_DIGEST_SHA2_512, 8);
+       r = pakfire_db_load_file_checksum(db, file, stmt, PAKFIRE_HASH_SHA2_512, 8);
        if (r)
                goto ERROR;
 
        // SHA2-256 Digest
-       r = pakfire_db_load_file_digest(db, file, stmt, PAKFIRE_DIGEST_SHA2_256, 9);
+       r = pakfire_db_load_file_checksum(db, file, stmt, PAKFIRE_HASH_SHA2_256, 9);
        if (r)
                goto ERROR;
 
        // BLAKE2b512 Digest
-       r = pakfire_db_load_file_digest(db, file, stmt, PAKFIRE_DIGEST_BLAKE2B512, 10);
+       r = pakfire_db_load_file_checksum(db, file, stmt, PAKFIRE_HASH_BLAKE2B512, 10);
        if (r)
                goto ERROR;
 
        // BLAKE2s256 Digest
-       r = pakfire_db_load_file_digest(db, file, stmt, PAKFIRE_DIGEST_BLAKE2S256, 11);
+       r = pakfire_db_load_file_checksum(db, file, stmt, PAKFIRE_HASH_BLAKE2S256, 11);
        if (r)
                goto ERROR;
 
        // SHA3-512 Digest
-       r = pakfire_db_load_file_digest(db, file, stmt, PAKFIRE_DIGEST_SHA3_512, 12);
+       r = pakfire_db_load_file_checksum(db, file, stmt, PAKFIRE_HASH_SHA3_512, 12);
        if (r)
                goto ERROR;
 
        // SHA3-256 Digest
-       r = pakfire_db_load_file_digest(db, file, stmt, PAKFIRE_DIGEST_SHA3_256, 13);
+       r = pakfire_db_load_file_checksum(db, file, stmt, PAKFIRE_HASH_SHA3_256, 13);
        if (r)
                goto ERROR;
 
diff --git a/src/pakfire/digest.c b/src/pakfire/digest.c
deleted file mode 100644 (file)
index cee3a14..0000000
+++ /dev/null
@@ -1,654 +0,0 @@
-/*#############################################################################
-#                                                                             #
-# Pakfire - The IPFire package management system                              #
-# Copyright (C) 2022 Pakfire development team                                 #
-#                                                                             #
-# This program is free software: you can redistribute it and/or modify        #
-# it under the terms of the GNU General Public License as published by        #
-# the Free Software Foundation, either version 3 of the License, or           #
-# (at your option) any later version.                                         #
-#                                                                             #
-# This program is distributed in the hope that it will be useful,             #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
-# GNU General Public License for more details.                                #
-#                                                                             #
-# You should have received a copy of the GNU General Public License           #
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
-#                                                                             #
-#############################################################################*/
-
-#include <stdio.h>
-
-#include <openssl/crypto.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/sha.h>
-
-#include <pakfire/ctx.h>
-#include <pakfire/digest.h>
-#include <pakfire/hex.h>
-#include <pakfire/logging.h>
-#include <pakfire/pakfire.h>
-#include <pakfire/util.h>
-
-static const struct _pakfire_digest_name {
-       const char* name;
-       const enum pakfire_digest_types type;
-} PAKFIRE_DIGEST_NAMES[] = {
-       // SHA-2
-       { "sha2-512", PAKFIRE_DIGEST_SHA2_512, },
-       { "sha2-256", PAKFIRE_DIGEST_SHA2_256, },
-
-       // BLAKE2
-       { "blake2b512", PAKFIRE_DIGEST_BLAKE2B512, },
-       { "blake2s256", PAKFIRE_DIGEST_BLAKE2S256, },
-
-       // SHA-3
-       { "sha3-512", PAKFIRE_DIGEST_SHA3_512, },
-       { "sha3-256", PAKFIRE_DIGEST_SHA3_256, },
-
-       { NULL, PAKFIRE_DIGEST_UNDEFINED, },
-};
-
-const char* pakfire_digest_name(const enum pakfire_digest_types type) {
-       for (const struct _pakfire_digest_name* n = PAKFIRE_DIGEST_NAMES; n->name; n++) {
-               if (n->type == type)
-                       return n->name;
-       }
-
-       return NULL;
-}
-
-int pakfire_digest_get_by_name(const char* name) {
-       // Check that name is not NULL
-       if (!name) {
-               errno = EINVAL;
-               return PAKFIRE_DIGEST_UNDEFINED;
-       }
-
-       for (const struct _pakfire_digest_name* n = PAKFIRE_DIGEST_NAMES; n->name; n++) {
-               if (strcmp(n->name, name) == 0)
-                       return n->type;
-       }
-
-       return PAKFIRE_DIGEST_UNDEFINED;
-}
-
-size_t pakfire_digest_length(const enum pakfire_digest_types digest) {
-       switch (digest) {
-               case PAKFIRE_DIGEST_SHA3_512:
-                       return SHA512_DIGEST_LENGTH;
-
-               case PAKFIRE_DIGEST_SHA3_256:
-                       return SHA256_DIGEST_LENGTH;
-
-               case PAKFIRE_DIGEST_BLAKE2B512:
-                       return BLAKE2B512_DIGEST_LENGTH;
-
-               case PAKFIRE_DIGEST_BLAKE2S256:
-                       return BLAKE2S256_DIGEST_LENGTH;
-
-               case PAKFIRE_DIGEST_SHA2_512:
-                       return SHA512_DIGEST_LENGTH;
-
-               case PAKFIRE_DIGEST_SHA2_256:
-                       return SHA256_DIGEST_LENGTH;
-
-               case PAKFIRE_DIGEST_UNDEFINED:
-                       return 0;
-       }
-
-       return 0;
-}
-
-const unsigned char* pakfire_digest_get(struct pakfire_digests* digests,
-               const enum pakfire_digest_types type, size_t* length) {
-       // Set length
-       if (length)
-               *length = pakfire_digest_length(type);
-
-       // Return a pointer to the digest (if set)
-       switch (type) {
-               case PAKFIRE_DIGEST_SHA3_512:
-                       if (pakfire_digest_set(digests->sha3_512))
-                               return digests->sha3_512;
-                       break;
-
-               case PAKFIRE_DIGEST_SHA3_256:
-                       if (pakfire_digest_set(digests->sha3_256))
-                               return digests->sha3_256;
-                       break;
-
-               case PAKFIRE_DIGEST_BLAKE2B512:
-                       if (pakfire_digest_set(digests->blake2b512))
-                               return digests->blake2b512;
-                       break;
-
-               case PAKFIRE_DIGEST_BLAKE2S256:
-                       if (pakfire_digest_set(digests->blake2s256))
-                               return digests->blake2s256;
-                       break;
-
-               case PAKFIRE_DIGEST_SHA2_512:
-                       if (pakfire_digest_set(digests->sha2_512))
-                               return digests->sha2_512;
-                       break;
-
-               case PAKFIRE_DIGEST_SHA2_256:
-                       if (pakfire_digest_set(digests->sha2_256))
-                               return digests->sha2_256;
-                       break;
-
-               case PAKFIRE_DIGEST_UNDEFINED:
-                       break;
-       }
-
-       return NULL;
-}
-
-char* pakfire_digest_get_hex(struct pakfire_digests* digests,
-               const enum pakfire_digest_types type) {
-       size_t length = 0;
-
-       const unsigned char* digest = pakfire_digest_get(digests, type, &length);
-       if (!digest)
-               return NULL;
-
-       return __pakfire_hexlify(digest, length);
-}
-
-/*
-       Returns one if the digest is not all zeros.
-*/
-int __pakfire_digest_set(const unsigned char* digest, const size_t length) {
-       for (unsigned int i = 0; i < length; i++) {
-               if (digest[i])
-                       return 1;
-       }
-
-       return 0;
-}
-
-/*
-       Returns a bitmap of all digests that are set.
-*/
-int pakfire_digest_has_any(const struct pakfire_digests* digests) {
-       int types = PAKFIRE_DIGEST_UNDEFINED;
-
-       if (pakfire_digest_set(digests->sha3_512))
-               types |= PAKFIRE_DIGEST_SHA3_512;
-
-       if (pakfire_digest_set(digests->sha3_256))
-               types |= PAKFIRE_DIGEST_SHA3_256;
-
-       if (pakfire_digest_set(digests->blake2b512))
-               types |= PAKFIRE_DIGEST_BLAKE2B512;
-
-       if (pakfire_digest_set(digests->blake2s256))
-               types |= PAKFIRE_DIGEST_BLAKE2S256;
-
-       if (pakfire_digest_set(digests->sha2_512))
-               types |= PAKFIRE_DIGEST_SHA2_512;
-
-       if (pakfire_digest_set(digests->sha2_256))
-               types |= PAKFIRE_DIGEST_SHA2_256;
-
-       return types;
-}
-
-/*
-       Returns a bitmap of all digests that are not set, yet
-*/
-static int pakfire_digest_needed(const struct pakfire_digests* digests, const int needed) {
-       // Fetch any currently set digests
-       const int have = pakfire_digest_has_any(digests);
-
-       return (~have & needed);
-}
-
-void pakfire_digests_reset(struct pakfire_digests* digests, int types) {
-       if (!types)
-               types = ~types;
-
-       // Reset SHA-3-512
-       if (types & PAKFIRE_DIGEST_SHA3_512)
-               memset(digests->sha3_512, 0, sizeof(digests->sha3_512));
-
-       // Reset SHA-3-256
-       if (types & PAKFIRE_DIGEST_SHA3_256)
-               memset(digests->sha3_256, 0, sizeof(digests->sha3_256));
-
-       // Reset BLAKE2b512
-       if (types & PAKFIRE_DIGEST_BLAKE2B512)
-               memset(digests->blake2b512, 0, sizeof(digests->blake2b512));
-
-       // Reset BLAKE2s256
-       if (types & PAKFIRE_DIGEST_BLAKE2S256)
-               memset(digests->blake2s256, 0, sizeof(digests->blake2s256));
-
-       // Reset SHA-2-512
-       if (types & PAKFIRE_DIGEST_SHA2_512)
-               memset(digests->sha2_512, 0, sizeof(digests->sha2_512));
-
-       // Reset SHA-2-256
-       if (types & PAKFIRE_DIGEST_SHA2_256)
-               memset(digests->sha2_256, 0, sizeof(digests->sha2_256));
-}
-
-static int pakfire_digests_check_length(struct pakfire_ctx* ctx,
-               const enum pakfire_digest_types type, const size_t length) {
-       const size_t l = pakfire_digest_length(type);
-
-       // Return if length matches
-       if (length == l)
-               return 0;
-
-       // Otherwise set an error
-       ERROR(ctx, "Digest is of an unexpected length\n");
-
-       return -ENOMSG;
-}
-
-static EVP_MD_CTX* __pakfire_digest_setup(struct pakfire_ctx* ctx, const EVP_MD* md) {
-       EVP_MD_CTX* evp_ctx = NULL;
-       int r;
-
-       // Setup a new context
-       evp_ctx = EVP_MD_CTX_new();
-       if (!evp_ctx) {
-               ERROR(ctx, "Could not initialize OpenSSL context: %s\n",
-                       ERR_error_string(ERR_get_error(), NULL));
-               goto ERROR;
-       }
-
-       // Setup digest
-       r = EVP_DigestInit_ex(evp_ctx, md, NULL);
-       if (r != 1) {
-               ERROR(ctx, "Could not setup digest: %s\n",
-                       ERR_error_string(ERR_get_error(), NULL));
-               goto ERROR;
-       }
-
-       return evp_ctx;
-
-ERROR:
-       if (evp_ctx)
-               EVP_MD_CTX_free(evp_ctx);
-
-       return NULL;
-}
-
-static int __pakfire_digest_update(struct pakfire_ctx* ctx, EVP_MD_CTX* evp_ctx,
-               const char* buffer, const size_t length) {
-       int r;
-
-       // Nothing to do if digest not initialized
-       if (!evp_ctx)
-               return 0;
-
-       // Update digest
-       r = EVP_DigestUpdate(evp_ctx, buffer, length);
-       if (r != 1) {
-               ERROR(ctx, "EVP_Digest_Update() failed: %s\n",
-                       ERR_error_string(ERR_get_error(), NULL));
-               return 1;
-       }
-
-       return 0;
-}
-
-static int __pakfire_digest_finalize(struct pakfire_ctx* ctx,
-               EVP_MD_CTX* evp_ctx, unsigned char* digest) {
-       int r;
-
-       // Nothing to do if digest not initialized
-       if (!evp_ctx)
-               return 0;
-
-       // Finalize digest
-       r = EVP_DigestFinal_ex(evp_ctx, digest, NULL);
-       if (r != 1) {
-               ERROR(ctx, "EVP_DigestFinal_ex() failed: %s\n",
-                       ERR_error_string(ERR_get_error(), NULL));
-               return 1;
-       }
-
-       return 0;
-}
-
-int pakfire_digests_compute_from_file(struct pakfire_ctx* ctx,
-               struct pakfire_digests* digests, int types, FILE* f) {
-       EVP_MD_CTX* sha3_512_ctx = NULL;
-       EVP_MD_CTX* sha3_256_ctx = NULL;
-       EVP_MD_CTX* blake2b512_ctx = NULL;
-       EVP_MD_CTX* blake2s256_ctx = NULL;
-       EVP_MD_CTX* sha2_512_ctx = NULL;
-       EVP_MD_CTX* sha2_256_ctx = NULL;
-       char buffer[65536];
-       int r = 1;
-
-       // Check if any digests have been computed before and select only those that we need
-       types = pakfire_digest_needed(digests, types);
-
-       // Nothing to do?
-       if (!types)
-               return 0;
-
-       // Initialize context for SHA-3-512
-       if (types & PAKFIRE_DIGEST_SHA3_512) {
-               sha3_512_ctx = __pakfire_digest_setup(ctx, EVP_sha3_512());
-               if (!sha3_512_ctx)
-                       goto ERROR;
-       }
-
-       // Initialize context for SHA-3-256
-       if (types & PAKFIRE_DIGEST_SHA3_256) {
-               sha3_256_ctx = __pakfire_digest_setup(ctx, EVP_sha3_256());
-               if (!sha3_256_ctx)
-                       goto ERROR;
-       }
-
-       // Initialize context for BLAKE2B512
-       if (types & PAKFIRE_DIGEST_BLAKE2B512) {
-               blake2b512_ctx = __pakfire_digest_setup(ctx, EVP_blake2b512());
-               if (!blake2b512_ctx)
-                       goto ERROR;
-       }
-
-       // Initialize context for BLAKE2S256
-       if (types & PAKFIRE_DIGEST_BLAKE2S256) {
-               blake2s256_ctx = __pakfire_digest_setup(ctx, EVP_blake2s256());
-               if (!blake2s256_ctx)
-                       goto ERROR;
-       }
-
-       // Initialize context for SHA-2-512
-       if (types & PAKFIRE_DIGEST_SHA2_512) {
-               sha2_512_ctx = __pakfire_digest_setup(ctx, EVP_sha512());
-               if (!sha2_512_ctx)
-                       goto ERROR;
-       }
-
-       // Initialize context for SHA-2-256
-       if (types & PAKFIRE_DIGEST_SHA2_256) {
-               sha2_256_ctx = __pakfire_digest_setup(ctx, EVP_sha256());
-               if (!sha2_256_ctx)
-                       goto ERROR;
-       }
-
-       // Read the file into the hash functions
-       while (!feof(f)) {
-               size_t bytes_read = fread(buffer, 1, sizeof(buffer), f);
-
-               // Raise any reading errors
-               if (ferror(f)) {
-                       r = 1;
-                       goto ERROR;
-               }
-
-               // SHA-3-512
-               r = __pakfire_digest_update(ctx, sha3_512_ctx, buffer, bytes_read);
-               if (r)
-                       goto ERROR;
-
-               // SHA-3-256
-               r = __pakfire_digest_update(ctx, sha3_256_ctx, buffer, bytes_read);
-               if (r)
-                       goto ERROR;
-
-               // BLAKE2B512
-               r = __pakfire_digest_update(ctx, blake2b512_ctx, buffer, bytes_read);
-               if (r)
-                       goto ERROR;
-
-               // BLAKE2S256
-               r = __pakfire_digest_update(ctx, blake2s256_ctx, buffer, bytes_read);
-               if (r)
-                       goto ERROR;
-
-               // SHA-2-512
-               r = __pakfire_digest_update(ctx, sha2_512_ctx, buffer, bytes_read);
-               if (r)
-                       goto ERROR;
-
-               // SHA-2-256
-               r = __pakfire_digest_update(ctx, sha2_256_ctx, buffer, bytes_read);
-               if (r)
-                       goto ERROR;
-       }
-
-       // Finalize SHA-3-512
-       r = __pakfire_digest_finalize(ctx, sha3_512_ctx, digests->sha3_512);
-       if (r)
-               goto ERROR;
-
-       // Finalize SHA-3-256
-       r = __pakfire_digest_finalize(ctx, sha3_256_ctx, digests->sha3_256);
-       if (r)
-               goto ERROR;
-
-       // Finalize BLAKE2b512
-       r = __pakfire_digest_finalize(ctx, blake2b512_ctx, digests->blake2b512);
-       if (r)
-               goto ERROR;
-
-       // Finalize BLAKE2s256
-       r = __pakfire_digest_finalize(ctx, blake2s256_ctx, digests->blake2s256);
-       if (r)
-               goto ERROR;
-
-       // Finalize SHA-2-512
-       r = __pakfire_digest_finalize(ctx, sha2_512_ctx, digests->sha2_512);
-       if (r)
-               goto ERROR;
-
-       // Finalize SHA-2-256
-       r = __pakfire_digest_finalize(ctx, sha2_256_ctx, digests->sha2_256);
-       if (r)
-               goto ERROR;
-
-       // Done!
-       r = 0;
-
-ERROR:
-       if (sha3_512_ctx)
-               EVP_MD_CTX_free(sha3_512_ctx);
-       if (sha3_256_ctx)
-               EVP_MD_CTX_free(sha3_256_ctx);
-       if (blake2b512_ctx)
-               EVP_MD_CTX_free(blake2b512_ctx);
-       if (blake2s256_ctx)
-               EVP_MD_CTX_free(blake2s256_ctx);
-       if (sha2_512_ctx)
-               EVP_MD_CTX_free(sha2_512_ctx);
-       if (sha2_256_ctx)
-               EVP_MD_CTX_free(sha2_256_ctx);
-
-       return r;
-}
-
-int pakfire_digests_compute_from_path(struct pakfire_ctx* ctx,
-               struct pakfire_digests* digests, int types, const char* path) {
-       FILE* f = NULL;
-       int r;
-
-       // Open the file
-       f = fopen(path, "r");
-       if (!f)
-               return -errno;
-
-       // Compute the digests
-       r = pakfire_digests_compute_from_file(ctx, digests, types, f);
-
-       // Close the file
-       if (f)
-               fclose(f);
-
-       return r;
-}
-
-static void pakfire_digests_compare_mismatch(struct pakfire_ctx* ctx, const char* what,
-               const unsigned char* digest1, const unsigned char* digest2, const size_t length) {
-       char* hexdigest1 = __pakfire_hexlify(digest1, length);
-       char* hexdigest2 = __pakfire_hexlify(digest2, length);
-
-       DEBUG(ctx, "%s digest does not match:\n", what);
-
-       if (hexdigest1)
-               DEBUG(ctx, "  Digest 1: %s\n", hexdigest1);
-       if (hexdigest2)
-               DEBUG(ctx, "  Digest 2: %s\n", hexdigest2);
-
-       if (hexdigest1)
-               free(hexdigest1);
-       if (hexdigest2)
-               free(hexdigest2);
-}
-
-int pakfire_digests_compare(struct pakfire_ctx* ctx, const struct pakfire_digests* digests1,
-               const struct pakfire_digests* digests2, const int types) {
-       int r;
-
-       // Check if we are at least comparing one type
-       if (!types)
-               return -EINVAL;
-
-       // Check SHA-3-512
-       if (types & PAKFIRE_DIGEST_SHA3_512) {
-               r = CRYPTO_memcmp(digests1->sha3_512, digests2->sha3_512, sizeof(digests1->sha3_512));
-               if (r) {
-                       pakfire_digests_compare_mismatch(ctx, "SHA-3-512",
-                               digests1->sha3_512, digests2->sha3_512, sizeof(digests1->sha3_512));
-                       return 1;
-               }
-       }
-
-       // Check SHA-3-256
-       if (types & PAKFIRE_DIGEST_SHA3_256) {
-               r = CRYPTO_memcmp(digests1->sha3_256, digests2->sha3_256, sizeof(digests1->sha3_256));
-               if (r) {
-                       pakfire_digests_compare_mismatch(ctx, "SHA-3-256",
-                               digests1->sha3_256, digests2->sha3_256, sizeof(digests1->sha3_256));
-                       return 1;
-               }
-       }
-
-       // Check BLAKE2b512
-       if (types & PAKFIRE_DIGEST_BLAKE2B512) {
-               r = CRYPTO_memcmp(digests1->blake2b512, digests2->blake2b512, sizeof(digests1->blake2b512));
-               if (r) {
-                       pakfire_digests_compare_mismatch(ctx, "BLAKE2b512",
-                               digests1->blake2b512, digests2->blake2b512, sizeof(digests1->blake2b512));
-                       return 1;
-               }
-       }
-
-       // Check BLAKE2s256
-       if (types & PAKFIRE_DIGEST_BLAKE2S256) {
-               r = CRYPTO_memcmp(digests1->blake2s256, digests2->blake2s256, sizeof(digests1->blake2s256));
-               if (r) {
-                       pakfire_digests_compare_mismatch(ctx, "BLAKE2s256",
-                               digests1->blake2s256, digests2->blake2s256, sizeof(digests1->blake2s256));
-                       return 1;
-               }
-       }
-
-       // Check SHA-2-512
-       if (types & PAKFIRE_DIGEST_SHA2_512) {
-               r = CRYPTO_memcmp(digests1->sha2_512, digests2->sha2_512, sizeof(digests1->sha2_512));
-               if (r) {
-                       pakfire_digests_compare_mismatch(ctx, "SHA-2-512",
-                               digests1->sha2_512, digests2->sha2_512, sizeof(digests1->sha2_512));
-                       return 1;
-               }
-       }
-
-       // Check SHA-2-256
-       if (types & PAKFIRE_DIGEST_SHA2_256) {
-               r = CRYPTO_memcmp(digests1->sha2_256, digests2->sha2_256, sizeof(digests1->sha2_256));
-               if (r) {
-                       pakfire_digests_compare_mismatch(ctx, "SHA-2-256",
-                               digests1->sha2_256, digests2->sha2_256, sizeof(digests1->sha2_256));
-                       return 1;
-               }
-       }
-
-       // All digests match
-       return 0;
-}
-
-int pakfire_digests_compare_one(struct pakfire_ctx* ctx, struct pakfire_digests* digests1,
-               const enum pakfire_digest_types type, const unsigned char* digest, const size_t length) {
-       struct pakfire_digests digests2;
-       int r;
-
-       // Check for valid inputs
-       r = pakfire_digests_check_length(ctx, type, length);
-       if (r)
-               return r;
-
-       switch (type) {
-               case PAKFIRE_DIGEST_SHA3_512:
-                       memcpy(digests2.sha3_512, digest, sizeof(digests2.sha3_512));
-                       break;
-
-               case PAKFIRE_DIGEST_SHA3_256:
-                       memcpy(digests2.sha3_256, digest, sizeof(digests2.sha3_256));
-                       break;
-
-               case PAKFIRE_DIGEST_BLAKE2B512:
-                       memcpy(digests2.blake2b512, digest, sizeof(digests2.blake2b512));
-                       break;
-
-               case PAKFIRE_DIGEST_BLAKE2S256:
-                       memcpy(digests2.blake2s256, digest, sizeof(digests2.blake2s256));
-                       break;
-
-               case PAKFIRE_DIGEST_SHA2_512:
-                       memcpy(digests2.sha2_512, digest, sizeof(digests2.sha2_512));
-                       break;
-
-               case PAKFIRE_DIGEST_SHA2_256:
-                       memcpy(digests2.sha2_256, digest, sizeof(digests2.sha2_256));
-                       break;
-
-               case PAKFIRE_DIGEST_UNDEFINED:
-                       break;
-       }
-
-       return pakfire_digests_compare(ctx, digests1, &digests2, type);
-}
-
-int pakfire_digests_set_hexdigest(struct pakfire_digests* digests,
-               const enum pakfire_digest_types type, const char* hexdigest) {
-       switch (type) {
-               case PAKFIRE_DIGEST_SHA3_512:
-                       return pakfire_unhexlify(digests->sha3_512, hexdigest);
-
-               case PAKFIRE_DIGEST_SHA3_256:
-                       return pakfire_unhexlify(digests->sha3_256, hexdigest);
-
-               case PAKFIRE_DIGEST_BLAKE2B512:
-                       return pakfire_unhexlify(digests->blake2b512, hexdigest);
-
-               case PAKFIRE_DIGEST_BLAKE2S256:
-                       return pakfire_unhexlify(digests->blake2s256, hexdigest);
-
-               case PAKFIRE_DIGEST_SHA2_512:
-                       return pakfire_unhexlify(digests->sha2_512, hexdigest);
-
-               case PAKFIRE_DIGEST_SHA2_256:
-                       return pakfire_unhexlify(digests->sha2_256, hexdigest);
-
-               default:
-                       return -EINVAL;
-       }
-}
-
-int pakfire_digests_import(struct pakfire_digests* dst, const struct pakfire_digests* src) {
-       // Copy everything
-       memcpy(dst, src, sizeof(*dst));
-
-       return 0;
-}
diff --git a/src/pakfire/digest.h b/src/pakfire/digest.h
deleted file mode 100644 (file)
index c044161..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*#############################################################################
-#                                                                             #
-# Pakfire - The IPFire package management system                              #
-# Copyright (C) 2022 Pakfire development team                                 #
-#                                                                             #
-# This program is free software: you can redistribute it and/or modify        #
-# it under the terms of the GNU General Public License as published by        #
-# the Free Software Foundation, either version 3 of the License, or           #
-# (at your option) any later version.                                         #
-#                                                                             #
-# This program is distributed in the hope that it will be useful,             #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
-# GNU General Public License for more details.                                #
-#                                                                             #
-# You should have received a copy of the GNU General Public License           #
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
-#                                                                             #
-#############################################################################*/
-
-#ifndef PAKFIRE_DIGEST_H
-#define PAKFIRE_DIGEST_H
-
-#include <stdio.h>
-
-// OpenSSL
-#include <openssl/sha.h>
-
-// Pakfire knows these digests
-enum pakfire_digest_types {
-       PAKFIRE_DIGEST_UNDEFINED  = 0,
-       PAKFIRE_DIGEST_SHA2_256   = (1 << 0),
-       PAKFIRE_DIGEST_SHA2_512   = (1 << 1),
-       PAKFIRE_DIGEST_BLAKE2S256 = (1 << 2),
-       PAKFIRE_DIGEST_BLAKE2B512 = (1 << 3),
-       PAKFIRE_DIGEST_SHA3_256   = (1 << 4),
-       PAKFIRE_DIGEST_SHA3_512   = (1 << 5),
-};
-
-#define PAKFIRE_DIGESTS_ALL ( \
-       PAKFIRE_DIGEST_SHA2_256 | \
-       PAKFIRE_DIGEST_SHA2_512 | \
-       PAKFIRE_DIGEST_BLAKE2S256 | \
-       PAKFIRE_DIGEST_BLAKE2B512 | \
-       PAKFIRE_DIGEST_SHA3_256 | \
-       PAKFIRE_DIGEST_SHA3_512 \
-)
-
-#define PAKFIRE_DIGESTS_FOREACH(digest) \
-       for (digest = 1; digest & PAKFIRE_DIGESTS_ALL; digest <<= 1)
-
-#include <pakfire/ctx.h>
-
-const char* pakfire_digest_name(const enum pakfire_digest_types type);
-int pakfire_digest_get_by_name(const char* name);
-
-// libsolv only supports storing one checksum which has to be of a supported type
-#define PAKFIRE_ARCHIVE_CHECKSUM PAKFIRE_DIGEST_SHA2_512
-
-// Define BLAKE2's digest lengths
-#ifndef BLAKE2S256_DIGEST_LENGTH
-#  define BLAKE2S256_DIGEST_LENGTH 32
-#endif /* BLAKE2S256_DIGEST_LENGTH */
-
-#ifndef BLAKE2B512_DIGEST_LENGTH
-#  define BLAKE2B512_DIGEST_LENGTH 64
-#endif /* BLAKE2B512_DIGEST_LENGTH */
-
-// Digests
-struct pakfire_digests {
-       // SHA-3-512
-       unsigned char sha3_512[SHA512_DIGEST_LENGTH];
-
-       // SHA-3-256
-       unsigned char sha3_256[SHA256_DIGEST_LENGTH];
-
-       // BLAKE2b512
-       unsigned char blake2b512[BLAKE2B512_DIGEST_LENGTH];
-
-       // BLAKE2s256
-       unsigned char blake2s256[BLAKE2S256_DIGEST_LENGTH];
-
-       // SHA2-512
-       unsigned char sha2_512[SHA512_DIGEST_LENGTH];
-
-       // SHA2-256
-       unsigned char sha2_256[SHA256_DIGEST_LENGTH];
-};
-
-size_t pakfire_digest_length(const enum pakfire_digest_types digest);
-
-const unsigned char* pakfire_digest_get(struct pakfire_digests* digests,
-       const enum pakfire_digest_types type, size_t* length);
-
-char* pakfire_digest_get_hex(struct pakfire_digests* digests,
-               const enum pakfire_digest_types type);
-
-#define pakfire_digest_set(digest) __pakfire_digest_set(digest, sizeof(digest))
-int __pakfire_digest_set(const unsigned char* digest, const size_t length);
-
-int pakfire_digest_has_any(const struct pakfire_digests* digests);
-
-void pakfire_digests_reset(struct pakfire_digests* digests, int types);
-
-int pakfire_digests_compute_from_file(struct pakfire_ctx* ctx,
-       struct pakfire_digests* digests, int types, FILE* f);
-int pakfire_digests_compute_from_path(struct pakfire_ctx* ctx,
-       struct pakfire_digests* digests, int types, const char* path);
-
-int pakfire_digests_compare(struct pakfire_ctx* ctx, const struct pakfire_digests* digests1,
-       const struct pakfire_digests* digests2, const int types);
-int pakfire_digests_compare_one(struct pakfire_ctx* ctx, struct pakfire_digests* digests1,
-       const enum pakfire_digest_types type, const unsigned char* digest, const size_t length);
-
-int pakfire_digests_set_hexdigest(struct pakfire_digests* digests,
-       const enum pakfire_digest_types type, const char* hexdigest);
-
-int pakfire_digests_import(struct pakfire_digests* dst, const struct pakfire_digests* src);
-
-#endif /* PAKFIRE_DIGEST_H */
index 13b34f53cb1d210a9de2685dcf58b82b6326e3f0..b4f1ae87fc7befadaed442866beaa06c2a940a90 100644 (file)
@@ -38,7 +38,7 @@
 
 #include <pakfire/ctx.h>
 #include <pakfire/constants.h>
-#include <pakfire/digest.h>
+#include <pakfire/hashes.h>
 #include <pakfire/elf.h>
 #include <pakfire/file.h>
 #include <pakfire/logging.h>
@@ -74,8 +74,8 @@ struct pakfire_file {
        // Flags
        int flags;
 
-       // Digests
-       struct pakfire_digests digests;
+       // Hashes
+       struct pakfire_hashes hashes;
 
        // MIME Type
        char mimetype[NAME_MAX];
@@ -323,41 +323,43 @@ static int pakfire_file_from_archive_entry(struct pakfire_file* file, struct arc
                        if (r)
                                goto ERROR;
 
+#if 0
                // Digest: SHA-3-512
                } else if (strcmp(attr, "PAKFIRE.digests.sha3_512") == 0) {
-                       r = pakfire_file_set_digest(file, PAKFIRE_DIGEST_SHA3_512, value, size);
-                       if (r)
+                       r = pakfire_file_set_checksum(file, PAKFIRE_HASH_SHA3_512, value, size);
+                       if (r < 0)
                                goto ERROR;
 
                // Digest: SHA-3-256
                } else if (strcmp(attr, "PAKFIRE.digests.sha3_256") == 0) {
-                       r = pakfire_file_set_digest(file, PAKFIRE_DIGEST_SHA3_256, value, size);
-                       if (r)
+                       r = pakfire_file_set_checksum(file, PAKFIRE_HASH_SHA3_256, value, size);
+                       if (r < 0)
                                goto ERROR;
 
                // Digest: BLAKE2b512
                } else if (strcmp(attr, "PAKFIRE.digests.blake2b512") == 0) {
-                       r = pakfire_file_set_digest(file, PAKFIRE_DIGEST_BLAKE2B512, value, size);
-                       if (r)
+                       r = pakfire_file_set_checksum(file, PAKFIRE_HASH_BLAKE2B512, value, size);
+                       if (r < 0)
                                goto ERROR;
 
                // Digest: BLAKE2s256
                } else if (strcmp(attr, "PAKFIRE.digests.blake2s256") == 0) {
-                       r = pakfire_file_set_digest(file, PAKFIRE_DIGEST_BLAKE2S256, value, size);
-                       if (r)
+                       r = pakfire_file_set_checksum(file, PAKFIRE_HASH_BLAKE2S256, value, size);
+                       if (r < 0)
                                goto ERROR;
 
                // Digest: SHA-2-512
                } else if (strcmp(attr, "PAKFIRE.digests.sha2_512") == 0) {
-                       r = pakfire_file_set_digest(file, PAKFIRE_DIGEST_SHA2_512, value, size);
-                       if (r)
+                       r = pakfire_file_set_checksum(file, PAKFIRE_HASH_SHA2_512, value, size);
+                       if (r < 0)
                                goto ERROR;
 
                // Digest: SHA-2-256
                } else if (strcmp(attr, "PAKFIRE.digests.sha2_256") == 0) {
-                       r = pakfire_file_set_digest(file, PAKFIRE_DIGEST_SHA2_256, value, size);
-                       if (r)
+                       r = pakfire_file_set_checksum(file, PAKFIRE_HASH_SHA2_256, value, size);
+                       if (r < 0)
                                goto ERROR;
+#endif
 
                // Capabilities
                } else if (strcmp(attr, "security.capability") == 0) {
@@ -420,6 +422,39 @@ ERROR:
        return r;
 }
 
+static int pakfire_file_compute_hashes(struct pakfire_file* file,
+               const enum pakfire_hash_type types, struct pakfire_hashes* hashes) {
+       FILE* f = NULL;
+       int r;
+
+       const mode_t mode = pakfire_file_get_mode(file);
+
+       // Skip this for anything that isn't a regular file
+       if (!S_ISREG(mode))
+               return 0;
+
+       // Reset hashes
+       pakfire_hashes_reset(hashes);
+
+       // Open the file
+       f = pakfire_file_fopen(file, "r");
+       if (!f) {
+               r = -errno;
+               goto ERROR;
+       }
+
+       // Compute hashes
+       r = pakfire_hash_file(file->ctx, f, types, hashes);
+       if (r < 0)
+               goto ERROR;
+
+ERROR:
+       if (f)
+               fclose(f);
+
+       return r;
+}
+
 int pakfire_file_create_from_archive_entry(struct pakfire_file** file, struct pakfire* pakfire,
                struct archive_entry* entry) {
        struct pakfire_file* f = NULL;
@@ -444,7 +479,7 @@ ERROR:
        return r;
 }
 
-struct archive_entry* pakfire_file_archive_entry(struct pakfire_file* file, int digest_types) {
+struct archive_entry* pakfire_file_archive_entry(struct pakfire_file* file, const enum pakfire_hash_type hashes) {
        struct archive_entry* entry = NULL;
        struct vfs_cap_data cap_data = {};
        int r;
@@ -467,48 +502,40 @@ struct archive_entry* pakfire_file_archive_entry(struct pakfire_file* file, int
                        "PAKFIRE.mimetype", mimetype, strlen(mimetype));
        }
 
-       // Compute any required file digests
-       r = pakfire_file_compute_digests(file, digest_types);
-       if (r)
+       // Compute any required file hashes
+       r = pakfire_file_compute_hashes(file, hashes, &file->hashes);
+       if (r < 0)
                goto ERROR;
 
-       // Copy digests
-
        // SHA-3-512
-       if ((digest_types & PAKFIRE_DIGEST_SHA3_512)
-                       && pakfire_digest_set(file->digests.sha3_512))
+       if (pakfire_hashes_has(&file->hashes, PAKFIRE_HASH_SHA3_512))
                archive_entry_xattr_add_entry(entry, "PAKFIRE.digests.sha3_512",
-                       file->digests.sha3_512, sizeof(file->digests.sha3_512));
+                       file->hashes.sha3_512, sizeof(file->hashes.sha3_512));
 
        // SHA-3-256
-       if ((digest_types & PAKFIRE_DIGEST_SHA3_256) &&
-                       pakfire_digest_set(file->digests.sha3_256))
+       if (pakfire_hashes_has(&file->hashes, PAKFIRE_HASH_SHA3_256))
                archive_entry_xattr_add_entry(entry, "PAKFIRE.digests.sha3_256",
-                       file->digests.sha3_256, sizeof(file->digests.sha3_256));
+                       file->hashes.sha3_256, sizeof(file->hashes.sha3_256));
 
        // BLAKE2b512
-       if ((digest_types & PAKFIRE_DIGEST_BLAKE2B512) &&
-                       pakfire_digest_set(file->digests.blake2b512))
+       if (pakfire_hashes_has(&file->hashes, PAKFIRE_HASH_BLAKE2B512))
                archive_entry_xattr_add_entry(entry, "PAKFIRE.digests.blake2b512",
-                       file->digests.blake2b512, sizeof(file->digests.blake2b512));
+                       file->hashes.blake2b512, sizeof(file->hashes.blake2b512));
 
        // BLAKE2s256
-       if ((digest_types & PAKFIRE_DIGEST_BLAKE2S256) &&
-                       pakfire_digest_set(file->digests.blake2s256))
+       if (pakfire_hashes_has(&file->hashes, PAKFIRE_HASH_BLAKE2S256))
                archive_entry_xattr_add_entry(entry, "PAKFIRE.digests.blake2s256",
-                       file->digests.blake2s256, sizeof(file->digests.blake2s256));
+                       file->hashes.blake2s256, sizeof(file->hashes.blake2s256));
 
        // SHA-2-512
-       if ((digest_types & PAKFIRE_DIGEST_SHA2_512) &&
-                       pakfire_digest_set(file->digests.sha2_512))
+       if (pakfire_hashes_has(&file->hashes, PAKFIRE_HASH_SHA2_512))
                archive_entry_xattr_add_entry(entry, "PAKFIRE.digests.sha2_512",
-                       file->digests.sha2_512, sizeof(file->digests.sha2_512));
+                       file->hashes.sha2_512, sizeof(file->hashes.sha2_512));
 
        // SHA-2-256
-       if ((digest_types & PAKFIRE_DIGEST_SHA2_512) &&
-                       pakfire_digest_set(file->digests.sha2_256))
+       if (pakfire_hashes_has(&file->hashes, PAKFIRE_HASH_SHA2_256))
                archive_entry_xattr_add_entry(entry, "PAKFIRE.digests.sha2_256",
-                       file->digests.sha2_256, sizeof(file->digests.sha2_256));
+                       file->hashes.sha2_256, sizeof(file->hashes.sha2_256));
 
        // Capabilities
        if (file->caps) {
@@ -924,111 +951,35 @@ int pakfire_file_has_payload(struct pakfire_file* file) {
        return pakfire_file_get_size(file) > 0;
 }
 
-const unsigned char* pakfire_file_get_digest(
-               struct pakfire_file* file, const enum pakfire_digest_types type, size_t* length) {
-
-       switch (type) {
-               case PAKFIRE_DIGEST_SHA3_512:
-                       if (!pakfire_digest_set(file->digests.sha3_512))
-                               return NULL;
-
-                       if (length)
-                               *length = sizeof(file->digests.sha3_512);
-
-                       return file->digests.sha3_512;
-
-               case PAKFIRE_DIGEST_SHA3_256:
-                       if (!pakfire_digest_set(file->digests.sha3_256))
-                               return NULL;
-
-                       if (length)
-                               *length = sizeof(file->digests.sha3_256);
-
-                       return file->digests.sha3_256;
-
-               case PAKFIRE_DIGEST_BLAKE2B512:
-                       if (!pakfire_digest_set(file->digests.blake2b512))
-                               return NULL;
-
-                       if (length)
-                               *length = sizeof(file->digests.blake2b512);
-
-                       return file->digests.blake2b512;
-
-               case PAKFIRE_DIGEST_BLAKE2S256:
-                       if (!pakfire_digest_set(file->digests.blake2s256))
-                               return NULL;
-
-                       if (length)
-                               *length = sizeof(file->digests.blake2s256);
-
-                       return file->digests.blake2s256;
-
-               case PAKFIRE_DIGEST_SHA2_512:
-                       if (!pakfire_digest_set(file->digests.sha2_512))
-                               return NULL;
-
-                       if (length)
-                               *length = sizeof(file->digests.sha2_512);
-
-                       return file->digests.sha2_512;
-
-               case PAKFIRE_DIGEST_SHA2_256:
-                       if (!pakfire_digest_set(file->digests.sha2_256))
-                               return NULL;
-
-                       if (length)
-                               *length = sizeof(file->digests.sha2_256);
-
-                       return file->digests.sha2_256;
+int pakfire_file_get_checksum(struct pakfire_file* file, const enum pakfire_hash_type type,
+               const unsigned char** checksum, size_t* checksum_length) {
+       int r;
 
-               case PAKFIRE_DIGEST_UNDEFINED:
-                       break;
+       // Fetch the checksum
+       r = pakfire_hashes_get(&file->hashes, type, checksum, checksum_length);
+       if (r < 0) {
+               ERROR(file->ctx, "Failed to fetch checksum for %s: %s\n",
+                               pakfire_file_get_path(file), strerror(-r));
+               return r;
        }
 
-       return NULL;
+       return 0;
 }
 
-int pakfire_file_set_digest(struct pakfire_file* file,
-               const enum pakfire_digest_types type, const unsigned char* digest, const size_t length) {
-       if (!digest)
-               return -EINVAL;
-
-       // Check buffer length
-       if (pakfire_digest_length(type) != length) {
-               ERROR(file->ctx, "Digest has an incorrect length of %zu byte(s)\n", length);
-               return -ENOMSG;
-       }
-
-       // Store the digest
-       switch (type) {
-               case PAKFIRE_DIGEST_SHA3_512:
-                       memcpy(file->digests.sha3_512, digest, sizeof(file->digests.sha3_512));
-                       break;
-
-               case PAKFIRE_DIGEST_SHA3_256:
-                       memcpy(file->digests.sha3_256, digest, sizeof(file->digests.sha3_256));
-                       break;
-
-               case PAKFIRE_DIGEST_BLAKE2B512:
-                       memcpy(file->digests.blake2b512, digest, sizeof(file->digests.blake2b512));
-                       break;
-
-               case PAKFIRE_DIGEST_BLAKE2S256:
-                       memcpy(file->digests.blake2s256, digest, sizeof(file->digests.blake2s256));
-                       break;
-
-               case PAKFIRE_DIGEST_SHA2_512:
-                       memcpy(file->digests.sha2_512, digest, sizeof(file->digests.sha2_512));
-                       break;
+int pakfire_file_set_checksum(struct pakfire_file* file, const enum pakfire_hash_type type,
+               const unsigned char* checksum, const size_t checksum_length) {
+       int r;
 
-               case PAKFIRE_DIGEST_SHA2_256:
-                       memcpy(file->digests.sha2_256, digest, sizeof(file->digests.sha2_256));
-                       break;
+       // Check inputs
+       if (!checksum)
+               return -EINVAL;
 
-               case PAKFIRE_DIGEST_UNDEFINED:
-                       errno = ENOTSUP;
-                       return 1;
+       // Store the checksum
+       r = pakfire_hashes_set(&file->hashes, type, checksum, checksum_length);
+       if (r < 0) {
+               ERROR(file->ctx, "Failed to set checksum for %s: %s\n",
+                               pakfire_file_get_path(file), strerror(-r));
+               return r;
        }
 
        return 0;
@@ -1200,43 +1151,6 @@ ERROR:
        return r;
 }
 
-static int __pakfire_file_compute_digests(struct pakfire_file* file,
-               struct pakfire_digests* digests, const int types) {
-       FILE* f = NULL;
-       int r;
-
-       const mode_t mode = pakfire_file_get_mode(file);
-
-       // Skip this for anything that isn't a regular file
-       if (!S_ISREG(mode))
-               return 0;
-
-       // Reset digests
-       pakfire_digests_reset(digests, types);
-
-       // Open the file
-       f = pakfire_file_fopen(file, "r");
-       if (!f) {
-               r = -errno;
-               goto ERROR;
-       }
-
-       // Compute digests
-       r = pakfire_digests_compute_from_file(file->ctx, digests, types, f);
-       if (r)
-               goto ERROR;
-
-ERROR:
-       if (f)
-               fclose(f);
-
-       return r;
-}
-
-int pakfire_file_compute_digests(struct pakfire_file* file, const int types) {
-       return __pakfire_file_compute_digests(file, &file->digests, types);
-}
-
 static int pakfire_file_remove(struct pakfire_file* file) {
        int r;
 
@@ -1682,11 +1596,9 @@ static int pakfire_file_verify_timestamps(struct pakfire_file* file, const struc
 }
 
 static int pakfire_file_verify_payload(struct pakfire_file* file, const struct stat* st) {
+       struct pakfire_hashes computed_hashes = {};
        int r;
 
-       struct pakfire_digests computed_digests;
-       int digest_types = PAKFIRE_DIGEST_UNDEFINED;
-
        // Nothing to do for anything that isn't a regular file
        if (!S_ISREG(st->st_mode))
                return 0;
@@ -1697,29 +1609,26 @@ static int pakfire_file_verify_payload(struct pakfire_file* file, const struct s
                return 0;
        }
 
-       // Check if this file has any digests at all
-       digest_types = pakfire_digest_has_any(&file->digests);
-
-       if (!digest_types) {
-               ERROR(file->ctx, "%s: No digests available\n", pakfire_file_get_path(file));
+       // Fail if the file has no hashes
+       if (!file->hashes.types) {
+               ERROR(file->ctx, "%s: No checksums available\n", pakfire_file_get_path(file));
                return 0;
        }
 
        // Compute digests
-       r = __pakfire_file_compute_digests(file, &computed_digests, digest_types);
-       if (r)
-               goto ERROR;
+       r = pakfire_file_compute_hashes(file, file->hashes.types, &computed_hashes);
+       if (r < 0)
+               return r;
 
-       // Compare digests
-       r = pakfire_digests_compare(file->ctx, &file->digests, &computed_digests, digest_types);
+       // Compare hashes
+       r = pakfire_hashes_compare(file->ctx, &file->hashes, &computed_hashes);
        if (r) {
                file->verify_status |= PAKFIRE_FILE_PAYLOAD_CHANGED;
 
-               DEBUG(file->ctx, "%s: Digest(s) do not match\n", pakfire_file_get_path(file));
+               DEBUG(file->ctx, "%s: Checksum(s) do not match\n", pakfire_file_get_path(file));
        }
 
-ERROR:
-       return r;
+       return 0;
 }
 
 /*
index 84ff7099a9a919e301f45eacf019544d9714d24b..eaf826540c7ff104b8e13f15864317b1d92c4920 100644 (file)
@@ -32,7 +32,7 @@
 
 struct pakfire_file;
 
-#include <pakfire/digest.h>
+#include <pakfire/hashes.h>
 #include <pakfire/pakfire.h>
 
 enum pakfire_file_flags {
@@ -88,10 +88,11 @@ void pakfire_file_set_ctime(struct pakfire_file* file, time_t time);
 time_t pakfire_file_get_mtime(struct pakfire_file* file);
 void pakfire_file_set_mtime(struct pakfire_file* file, time_t time);
 
-const unsigned char* pakfire_file_get_digest(struct pakfire_file* file,
-       const enum pakfire_digest_types type, size_t* length);
-int pakfire_file_set_digest(struct pakfire_file* file,
-       const enum pakfire_digest_types type, const unsigned char* digest, const size_t length);
+// Checksums
+int pakfire_file_get_checksum(struct pakfire_file* file, const enum pakfire_hash_type type,
+       const unsigned char** checksum, size_t* checksum_length);
+int pakfire_file_set_checksum(struct pakfire_file* file, const enum pakfire_hash_type type,
+       const unsigned char* checksum, const size_t checksum_length);
 
 // Capabilities
 int pakfire_file_has_caps(struct pakfire_file* file);
@@ -133,7 +134,7 @@ int pakfire_file_write_fcaps(struct pakfire_file* file, struct vfs_cap_data* cap
 
 int pakfire_file_create_from_archive_entry(struct pakfire_file** file, struct pakfire* pakfire,
        struct archive_entry* entry);
-struct archive_entry* pakfire_file_archive_entry(struct pakfire_file* file, int digest_types);
+struct archive_entry* pakfire_file_archive_entry(struct pakfire_file* file, const enum pakfire_hash_type hashes);
 
 enum pakfire_file_dump_flags {
        PAKFIRE_FILE_DUMP_MODE         = (1 << 0),
@@ -159,8 +160,6 @@ FILE* pakfire_file_fopen(struct pakfire_file* file, const char* mode);
 
 int pakfire_file_contains(struct pakfire_file* file, const char* needle, ssize_t length);
 
-int pakfire_file_compute_digests(struct pakfire_file* file, const int types);
-
 enum pakfire_file_cleanup_flags {
        PAKFIRE_FILE_CLEANUP_TIDY = (1 << 0),
 };
diff --git a/src/pakfire/hasher.c b/src/pakfire/hasher.c
new file mode 100644 (file)
index 0000000..c08c26c
--- /dev/null
@@ -0,0 +1,378 @@
+/*#############################################################################
+#                                                                             #
+# Pakfire - The IPFire package management system                              #
+# Copyright (C) 2025 Pakfire development team                                 #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+
+#include <pakfire/ctx.h>
+#include <pakfire/hasher.h>
+#include <pakfire/hashes.h>
+
+struct pakfire_hasher {
+       struct pakfire_ctx* ctx;
+       int nrefs;
+
+       // Selected hashes
+       enum pakfire_hash_type types;
+
+       // EVP Contexts
+       EVP_MD_CTX* sha3_512;
+       EVP_MD_CTX* sha3_256;
+       EVP_MD_CTX* blake2b512;
+       EVP_MD_CTX* blake2s256;
+       EVP_MD_CTX* sha2_512;
+       EVP_MD_CTX* sha2_256;
+
+       // Computed Hashes
+       struct pakfire_hashes hashes;
+};
+
+static void pakfire_hasher_free(struct pakfire_hasher* self) {
+       if (self->sha3_512)
+               EVP_MD_CTX_free(self->sha3_512);
+       if (self->sha3_256)
+               EVP_MD_CTX_free(self->sha3_256);
+       if (self->blake2b512)
+               EVP_MD_CTX_free(self->blake2b512);
+       if (self->blake2s256)
+               EVP_MD_CTX_free(self->blake2s256);
+       if (self->sha2_512)
+               EVP_MD_CTX_free(self->sha2_512);
+       if (self->sha2_256)
+               EVP_MD_CTX_free(self->sha2_256);
+       if (self->ctx)
+               pakfire_ctx_unref(self->ctx);
+       free(self);
+}
+
+static EVP_MD_CTX* pakfire_hasher_setup_hash(struct pakfire_hasher* self, const EVP_MD* md) {
+       EVP_MD_CTX* evp_ctx = NULL;
+       int r;
+
+       // Setup a new context
+       evp_ctx = EVP_MD_CTX_new();
+       if (!evp_ctx) {
+               ERROR(self->ctx, "Could not initialize OpenSSL context: %s\n",
+                       ERR_error_string(ERR_get_error(), NULL));
+               goto ERROR;
+       }
+
+       // Setup digest
+       r = EVP_DigestInit_ex(evp_ctx, md, NULL);
+       if (r != 1) {
+               ERROR(self->ctx, "Could not setup digest: %s\n",
+                       ERR_error_string(ERR_get_error(), NULL));
+               goto ERROR;
+       }
+
+       return evp_ctx;
+
+ERROR:
+       if (evp_ctx)
+               EVP_MD_CTX_free(evp_ctx);
+
+       return NULL;
+}
+
+static int pakfire_hasher_setup_hashes(struct pakfire_hasher* self) {
+       // Initialize context for SHA-3-512
+       if (self->types & PAKFIRE_HASH_SHA3_512) {
+               self->sha3_512 = pakfire_hasher_setup_hash(self, EVP_sha3_512());
+               if (!self->sha3_512)
+                       return -ENOTSUP;
+       }
+
+       // Initialize context for SHA-3-256
+       if (self->types & PAKFIRE_HASH_SHA3_256) {
+               self->sha3_256 = pakfire_hasher_setup_hash(self, EVP_sha3_256());
+               if (!self->sha3_256)
+                       return -ENOTSUP;
+       }
+
+       // Initialize context for BLAKE2B512
+       if (self->types & PAKFIRE_HASH_BLAKE2B512) {
+               self->blake2b512 = pakfire_hasher_setup_hash(self, EVP_blake2b512());
+               if (!self->blake2b512)
+                       return -ENOTSUP;
+       }
+
+       // Initialize context for BLAKE2S256
+       if (self->types & PAKFIRE_HASH_BLAKE2S256) {
+               self->blake2s256 = pakfire_hasher_setup_hash(self, EVP_blake2s256());
+               if (!self->blake2s256)
+                       return -ENOTSUP;
+       }
+
+       // Initialize context for SHA-2-512
+       if (self->types & PAKFIRE_HASH_SHA2_512) {
+               self->sha2_512 = pakfire_hasher_setup_hash(self, EVP_sha512());
+               if (!self->sha2_512)
+                       return -ENOTSUP;
+       }
+
+       // Initialize context for SHA-2-256
+       if (self->types & PAKFIRE_HASH_SHA2_256) {
+               self->sha2_256 = pakfire_hasher_setup_hash(self, EVP_sha256());
+               if (!self->sha2_256)
+                       return -ENOTSUP;
+       }
+
+       return 0;
+}
+
+int pakfire_hasher_create(struct pakfire_hasher** hasher,
+               struct pakfire_ctx* ctx, enum pakfire_hash_type types) {
+       struct pakfire_hasher* self = NULL;
+       int r;
+
+       // Something must have been selected
+       if (!types)
+               return -EINVAL;
+
+       // Allocate some memory
+       self = calloc(1, sizeof(*self));
+       if (!self)
+               return -errno;
+
+       // Store a reference to the context
+       self->ctx = pakfire_ctx_ref(ctx);
+
+       // Initialize the reference counter
+       self->nrefs = 1;
+
+       // Store hash types
+       self->types = self->hashes.types = types;
+
+       // Setup all hashes
+       r = pakfire_hasher_setup_hashes(self);
+       if (r < 0)
+               goto ERROR;
+
+       // Return the pointer
+       *hasher = self;
+
+       return 0;
+
+ERROR:
+       pakfire_hasher_free(self);
+
+       return r;
+};
+
+struct pakfire_hasher* pakfire_hasher_ref(struct pakfire_hasher* self) {
+       self->nrefs++;
+
+       return self;
+}
+
+struct pakfire_hasher* pakfire_hasher_unref(struct pakfire_hasher* self) {
+       if (--self->nrefs > 0)
+               return self;
+
+       pakfire_hasher_free(self);
+       return NULL;
+}
+
+static int __pakfire_hasher_update(struct pakfire_hasher* self, EVP_MD_CTX* evp_ctx,
+               const char* buffer, const size_t length) {
+       int r;
+
+       // Nothing to do if digest not initialized
+       if (!evp_ctx)
+               return 0;
+
+       // Update digest
+       r = EVP_DigestUpdate(evp_ctx, buffer, length);
+       if (r != 1) {
+               ERROR(self->ctx, "EVP_Digest_Update() failed: %s\n",
+                               ERR_error_string(ERR_get_error(), NULL));
+
+               return -ENOTSUP;
+       }
+
+       return 0;
+}
+
+int pakfire_hasher_update(struct pakfire_hasher* self, const char* buffer, const size_t length) {
+       int r;
+
+       // SHA-3-512
+       r = __pakfire_hasher_update(self, self->sha3_512, buffer, length);
+       if (r < 0)
+               return r;
+
+       // SHA-3-256
+       r = __pakfire_hasher_update(self, self->sha3_256, buffer, length);
+       if (r < 0)
+               return r;
+
+       // BLAKE2B512
+       r = __pakfire_hasher_update(self, self->blake2b512, buffer, length);
+       if (r < 0)
+               return r;
+
+       // BLAKE2S256
+       r = __pakfire_hasher_update(self, self->blake2s256, buffer, length);
+       if (r < 0)
+               return r;
+
+       // SHA-2-512
+       r = __pakfire_hasher_update(self, self->sha2_512, buffer, length);
+       if (r < 0)
+               return r;
+
+       // SHA-2-256
+       r = __pakfire_hasher_update(self, self->sha2_256, buffer, length);
+       if (r < 0)
+               return r;
+
+       return 0;
+}
+
+static int __pakfire_hasher_finalize(struct pakfire_hasher* self,
+               EVP_MD_CTX* evp_ctx, unsigned char* digest) {
+       int r;
+
+       // Nothing to do if digest not initialized
+       if (!evp_ctx)
+               return 0;
+
+       // Finalize digest
+       r = EVP_DigestFinal_ex(evp_ctx, digest, NULL);
+       if (r != 1) {
+               ERROR(self->ctx, "EVP_DigestFinal_ex() failed: %s\n",
+                               ERR_error_string(ERR_get_error(), NULL));
+
+               return -ENOTSUP;
+       }
+
+       return 0;
+}
+
+int pakfire_hasher_finalize(struct pakfire_hasher* self, struct pakfire_hashes* computed_hashes) {
+       int r;
+
+       // Finalize SHA-3-512
+       r = __pakfire_hasher_finalize(self, self->sha3_512, self->hashes.sha3_512);
+       if (r < 0)
+               return r;
+
+       // Finalize SHA-3-256
+       r = __pakfire_hasher_finalize(self, self->sha3_256, self->hashes.sha3_256);
+       if (r < 0)
+               return r;
+
+       // Finalize BLAKE2b512
+       r = __pakfire_hasher_finalize(self, self->blake2b512, self->hashes.blake2b512);
+       if (r < 0)
+               return r;
+
+       // Finalize BLAKE2s256
+       r = __pakfire_hasher_finalize(self, self->blake2s256, self->hashes.blake2s256);
+       if (r < 0)
+               return r;
+
+       // Finalize SHA-2-512
+       r = __pakfire_hasher_finalize(self, self->sha2_512, self->hashes.sha2_512);
+       if (r < 0)
+               return r;
+
+       // Finalize SHA-2-256
+       r = __pakfire_hasher_finalize(self, self->sha2_256, self->hashes.sha2_256);
+       if (r < 0)
+               return r;
+
+       // Optionally return the computed hashes
+       if (computed_hashes) {
+               r = pakfire_hashes_import(computed_hashes, &self->hashes);
+               if (r < 0)
+                       return r;
+       }
+
+       return 0;
+}
+
+/*
+       Convenience function to hash a file
+*/
+int pakfire_hash_file(struct pakfire_ctx* ctx,
+               FILE* f, const enum pakfire_hash_type types, struct pakfire_hashes* hashes) {
+       struct pakfire_hasher* hasher = NULL;
+       char buffer[65536];
+       size_t bytes_read;
+       int r;
+
+       // Create a new hasher
+       r = pakfire_hasher_create(&hasher, ctx, types);
+       if (r < 0)
+               goto ERROR;
+
+       // Read the file into the hash functions
+       while (!feof(f)) {
+               bytes_read = fread(buffer, 1, sizeof(buffer), f);
+
+               // Raise any reading errors
+               if (ferror(f)) {
+                       r = -errno;
+                       goto ERROR;
+               }
+
+               // Feed the buffer into the hash functions
+               r = pakfire_hasher_update(hasher, buffer, bytes_read);
+               if (r < 0)
+                       goto ERROR;
+       }
+
+       // Finalize the hash functions
+       r = pakfire_hasher_finalize(hasher, hashes);
+       if (r < 0)
+               goto ERROR;
+
+ERROR:
+       if (hasher)
+               pakfire_hasher_unref(hasher);
+
+       return 0;
+}
+
+int pakfire_hash_path(struct pakfire_ctx* ctx,
+               const char* path, const enum pakfire_hash_type types, struct pakfire_hashes* hashes) {
+       FILE* f = NULL;
+       int r;
+
+       // Open the file
+       f = fopen(path, "r");
+       if (!f)
+               return -errno;
+
+       // Perform the hashing
+       r = pakfire_hash_file(ctx, f, types, hashes);
+
+       // Close the file handle
+       if (f)
+               fclose(f);
+
+       return r;
+}
diff --git a/src/pakfire/hasher.h b/src/pakfire/hasher.h
new file mode 100644 (file)
index 0000000..70c4740
--- /dev/null
@@ -0,0 +1,45 @@
+/*#############################################################################
+#                                                                             #
+# Pakfire - The IPFire package management system                              #
+# Copyright (C) 2025 Pakfire development team                                 #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#ifndef PAKFIRE_HASHER_H
+#define PAKFIRE_HASHER_H
+
+#include <stdio.h>
+
+#include <pakfire/ctx.h>
+#include <pakfire/hashes.h>
+
+struct pakfire_hasher;
+
+int pakfire_hasher_create(struct pakfire_hasher** hasher,
+       struct pakfire_ctx* ctx, enum pakfire_hash_type types);
+
+struct pakfire_hasher* pakfire_hasher_ref(struct pakfire_hasher* self);
+struct pakfire_hasher* pakfire_hasher_unref(struct pakfire_hasher* self);
+
+int pakfire_hasher_update(struct pakfire_hasher* self, const char* buffer, const size_t length);
+int pakfire_hasher_finalize(struct pakfire_hasher* self, struct pakfire_hashes* computed_hashes);
+
+int pakfire_hash_file(struct pakfire_ctx* ctx,
+       FILE* f, enum pakfire_hash_type types, struct pakfire_hashes* hashes);
+int pakfire_hash_path(struct pakfire_ctx* ctx,
+       const char* path, const enum pakfire_hash_type types, struct pakfire_hashes* hashes);
+
+#endif /* PAKFIRE_HASHER_H */
diff --git a/src/pakfire/hashes.c b/src/pakfire/hashes.c
new file mode 100644 (file)
index 0000000..471a710
--- /dev/null
@@ -0,0 +1,400 @@
+/*#############################################################################
+#                                                                             #
+# Pakfire - The IPFire package management system                              #
+# Copyright (C) 2025 Pakfire development team                                 #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#include <errno.h>
+#include <stdio.h>
+
+#include <openssl/crypto.h>
+
+#include <pakfire/ctx.h>
+#include <pakfire/hashes.h>
+#include <pakfire/hex.h>
+#include <pakfire/logging.h>
+#include <pakfire/string.h>
+
+const char* pakfire_hash_name(const enum pakfire_hash_type hash) {
+       switch (hash) {
+               // SHA-3
+               case PAKFIRE_HASH_SHA3_512:
+                       return "sha3-512";
+
+               case PAKFIRE_HASH_SHA3_256:
+                       return "sha3-256";
+
+               // BLAKE2
+               case PAKFIRE_HASH_BLAKE2B512:
+                       return "blake2b512";
+
+               case PAKFIRE_HASH_BLAKE2S256:
+                       return "blake2s256";
+
+               // SHA-2
+               case PAKFIRE_HASH_SHA2_512:
+                       return "sha2-512";
+
+               case PAKFIRE_HASH_SHA2_256:
+                       return "sha2-256";
+
+               // Undefined
+               case PAKFIRE_HASH_UNDEFINED:
+                       break;
+       }
+
+       return NULL;
+}
+
+enum pakfire_hash_type pakfire_hash_by_name(const char* hash) {
+       // SHA-3
+       if (pakfire_string_equals(hash, "sha3-512"))
+               return PAKFIRE_HASH_SHA3_512;
+
+       else if (pakfire_string_equals(hash, "sha3-256"))
+               return PAKFIRE_HASH_SHA3_256;
+
+       // BLAKE2
+       else if (pakfire_string_equals(hash, "blake2b512"))
+               return PAKFIRE_HASH_BLAKE2B512;
+
+       else if (pakfire_string_equals(hash, "blake2s256"))
+               return PAKFIRE_HASH_BLAKE2S256;
+
+       // SHA-2
+       else if (pakfire_string_equals(hash, "sha2-512"))
+               return PAKFIRE_HASH_SHA2_512;
+
+       else if (pakfire_string_equals(hash, "sha2-256"))
+               return PAKFIRE_HASH_SHA2_256;
+
+       return PAKFIRE_HASH_UNDEFINED;
+}
+
+void pakfire_hashes_reset(struct pakfire_hashes* hashes) {
+       memset(hashes, 0, sizeof(*hashes));
+}
+
+int pakfire_hashes_import(struct pakfire_hashes* dst, const struct pakfire_hashes* src) {
+       memcpy(dst, src, sizeof(*dst));
+
+       return 0;
+}
+
+int pakfire_hashes_has(const struct pakfire_hashes* hashes, const enum pakfire_hash_type type) {
+       return (hashes->types & type);
+}
+
+int pakfire_hashes_get(const struct pakfire_hashes* hashes,
+               const enum pakfire_hash_type type, const unsigned char** hash, size_t* length) {
+
+       // Return NULL if we don't have the hash
+       if (!pakfire_hashes_has(hashes, type))
+               return 0;
+
+       switch (type) {
+               // SHA-3
+               case PAKFIRE_HASH_SHA3_512:
+                       if (length)
+                               *length = sizeof(hashes->sha3_512);
+
+                       *hash = hashes->sha3_512;
+                       break;
+
+               case PAKFIRE_HASH_SHA3_256:
+                       if (length)
+                               *length = sizeof(hashes->sha3_256);
+
+                       *hash = hashes->sha3_256;
+                       break;
+
+               // BLAKE2
+               case PAKFIRE_HASH_BLAKE2B512:
+                       if (length)
+                               *length = sizeof(hashes->blake2b512);
+
+                       *hash = hashes->blake2b512;
+                       break;
+
+               case PAKFIRE_HASH_BLAKE2S256:
+                       if (length)
+                               *length = sizeof(hashes->blake2s256);
+
+                       *hash = hashes->blake2s256;
+                       break;
+
+               // SHA-2
+               case PAKFIRE_HASH_SHA2_512:
+                       if (length)
+                               *length = sizeof(hashes->sha2_512);
+
+                       *hash = hashes->sha2_512;
+                       break;
+
+               case PAKFIRE_HASH_SHA2_256:
+                       if (length)
+                               *length = sizeof(hashes->sha2_256);
+
+                       *hash = hashes->sha2_256;
+                       break;
+
+               default:
+                       return -EINVAL;
+       }
+
+       return 0;
+}
+
+int pakfire_hashes_set(struct pakfire_hashes* hashes,
+               const enum pakfire_hash_type type, const unsigned char* hash, const size_t length) {
+       switch (type) {
+               // SHA-3
+               case PAKFIRE_HASH_SHA3_512:
+                       if (length != sizeof(hashes->sha3_512))
+                               return -EINVAL;
+
+                       memcpy(hashes->sha3_512, hash, sizeof(hashes->sha3_512));
+                       break;
+
+               case PAKFIRE_HASH_SHA3_256:
+                       if (length != sizeof(hashes->sha3_256))
+                               return -EINVAL;
+
+                       memcpy(hashes->sha3_256, hash, sizeof(hashes->sha3_256));
+                       break;
+
+               // BLAKE2
+               case PAKFIRE_HASH_BLAKE2B512:
+                       if (length != sizeof(hashes->blake2b512))
+                               return -EINVAL;
+
+                       memcpy(hashes->blake2b512, hash, sizeof(hashes->blake2b512));
+                       break;
+
+               case PAKFIRE_HASH_BLAKE2S256:
+                       if (length != sizeof(hashes->blake2s256))
+                               return -EINVAL;
+
+                       memcpy(hashes->blake2s256, hash, sizeof(hashes->blake2s256));
+                       break;
+
+               // SHA-2
+               case PAKFIRE_HASH_SHA2_512:
+                       if (length != sizeof(hashes->sha2_512))
+                               return -EINVAL;
+
+                       memcpy(hashes->sha2_512, hash, sizeof(hashes->sha2_512));
+                       break;
+
+               case PAKFIRE_HASH_SHA2_256:
+                       if (length != sizeof(hashes->sha2_256))
+                               return -EINVAL;
+
+                       memcpy(hashes->sha2_256, hash, sizeof(hashes->sha2_256));
+                       break;
+
+               default:
+                       return -EINVAL;
+       }
+
+       // Store the type
+       hashes->types |= type;
+
+       return 0;
+}
+
+int pakfire_hashes_get_hex(const struct pakfire_hashes* hashes,
+               const enum pakfire_hash_type type, char** hexdigest) {
+       const unsigned char* hash = NULL;
+       size_t length = 0;
+       int r;
+
+       // Fetch the hash
+       r = pakfire_hashes_get(hashes, type, &hash, &length);
+       if (r < 0)
+               return r;
+
+       // Return immediately without a hash
+       if (!hash)
+               return 0;
+
+       // Return the hexdigest
+       *hexdigest = __pakfire_hexlify(hash, length);
+       if (!*hexdigest)
+               return -errno;
+
+       return 0;
+}
+
+int pakfire_hashes_set_hex(struct pakfire_hashes* hashes,
+               const enum pakfire_hash_type type, const char* hexdigest) {
+       int r;
+
+       switch (type) {
+               case PAKFIRE_HASH_SHA3_512:
+                       r = pakfire_unhexlify(hashes->sha3_512, hexdigest);
+                       if (r < 0)
+                               return r;
+                       break;
+
+               case PAKFIRE_HASH_SHA3_256:
+                       r = pakfire_unhexlify(hashes->sha3_256, hexdigest);
+                       if (r < 0)
+                               return r;
+                       break;
+
+               case PAKFIRE_HASH_BLAKE2B512:
+                       r = pakfire_unhexlify(hashes->blake2b512, hexdigest);
+                       if (r < 0)
+                               return r;
+                       break;
+
+               case PAKFIRE_HASH_BLAKE2S256:
+                       r = pakfire_unhexlify(hashes->blake2s256, hexdigest);
+                       if (r < 0)
+                               return r;
+                       break;
+
+               case PAKFIRE_HASH_SHA2_512:
+                       r = pakfire_unhexlify(hashes->sha2_512, hexdigest);
+                       if (r < 0)
+                               return r;
+                       break;
+
+               case PAKFIRE_HASH_SHA2_256:
+                       r = pakfire_unhexlify(hashes->sha2_256, hexdigest);
+                       if (r < 0)
+                               return r;
+                       break;
+
+               default:
+                       return -EINVAL;
+       }
+
+       // Store the type
+       hashes->types |= type;
+
+       return 0;
+}
+
+static int __pakfire_hashes_dump(struct pakfire_ctx* ctx,
+               const struct pakfire_hashes* hashes, const enum pakfire_hash_type hash, int level) {
+       char* hexdigest = NULL;
+       int r;
+
+       // Don't dump if hash is not set
+       if (!pakfire_hashes_has(hashes, hash))
+               return 0;
+
+       // Fetch the hexdigest
+       r = pakfire_hashes_get_hex(hashes, hash, &hexdigest);
+       if (r < 0)
+               goto ERROR;
+
+       // Send to the logger
+       pakfire_ctx_log_condition(ctx, level, "  %s: %s\n", pakfire_hash_name(hash), hexdigest);
+
+ERROR:
+       if (hexdigest)
+               free(hexdigest);
+
+       return r;
+}
+
+int pakfire_hashes_dump(struct pakfire_ctx* ctx, const struct pakfire_hashes* hashes, int level) {
+       enum pakfire_hash_type hash = PAKFIRE_HASH_UNDEFINED;
+       int r;
+
+       PAKFIRE_HASHES_FOREACH(hash) {
+               r = __pakfire_hashes_dump(ctx, hashes, hash, level);
+               if (r < 0)
+                       return r;
+       }
+
+       return 0;
+}
+
+static int __pakfire_hashes_compare(struct pakfire_ctx* ctx, const enum pakfire_hash_type hash,
+               const struct pakfire_hashes* hashes1, const struct pakfire_hashes* hashes2) {
+       int r;
+
+       // Skip this if not both hashes have this one set
+       if (!pakfire_hashes_has(hashes1, hash) || !pakfire_hashes_has(hashes2, hash))
+               return 0;
+
+       switch (hash) {
+               // SHA-3
+               case PAKFIRE_HASH_SHA3_512:
+                       r = CRYPTO_memcmp(hashes1->sha3_512, hashes2->sha3_512, sizeof(hashes1->sha3_512));
+                       break;
+
+               case PAKFIRE_HASH_SHA3_256:
+                       r = CRYPTO_memcmp(hashes1->sha3_256, hashes2->sha3_256, sizeof(hashes1->sha3_256));
+                       break;
+
+               // BLAKE2
+               case PAKFIRE_HASH_BLAKE2B512:
+                       r = CRYPTO_memcmp(hashes1->blake2b512, hashes2->blake2b512, sizeof(hashes1->blake2b512));
+                       break;
+
+               case PAKFIRE_HASH_BLAKE2S256:
+                       r = CRYPTO_memcmp(hashes1->blake2s256, hashes2->blake2s256, sizeof(hashes1->blake2s256));
+                       break;
+
+               // SHA-2
+               case PAKFIRE_HASH_SHA2_512:
+                       r = CRYPTO_memcmp(hashes1->sha2_512, hashes2->sha2_512, sizeof(hashes1->sha2_512));
+                       break;
+
+               case PAKFIRE_HASH_SHA2_256:
+                       r = CRYPTO_memcmp(hashes1->sha2_256, hashes2->sha2_256, sizeof(hashes1->sha2_256));
+                       break;
+
+               case PAKFIRE_HASH_UNDEFINED:
+               default:
+                       r = -EINVAL;
+                       break;
+       }
+
+       return r;
+}
+
+int pakfire_hashes_compare(struct pakfire_ctx* ctx,
+               const struct pakfire_hashes* hashes1, const struct pakfire_hashes* hashes2) {
+       enum pakfire_hash_type hash = PAKFIRE_HASH_UNDEFINED;
+       int r;
+
+       // If either has nothing set, we cannot run this
+       if (!hashes1->types || !hashes2->types) {
+               ERROR(ctx, "At least one input hashes object is empty\n");
+               return -ENOTSUP;
+       }
+
+       // Check if there are any overlapping hashes
+       if (!(hashes1->types & hashes2->types)) {
+               ERROR(ctx, "The hashes don't share any common types\n");
+               return -ENOTSUP;
+       }
+
+       PAKFIRE_HASHES_FOREACH(hash) {
+               r = __pakfire_hashes_compare(ctx, hash, hashes1, hashes2);
+               if (r)
+                       return r;
+       }
+
+       return 0;
+}
diff --git a/src/pakfire/hashes.h b/src/pakfire/hashes.h
new file mode 100644 (file)
index 0000000..e7a27b5
--- /dev/null
@@ -0,0 +1,106 @@
+/*#############################################################################
+#                                                                             #
+# Pakfire - The IPFire package management system                              #
+# Copyright (C) 2025 Pakfire development team                                 #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#ifndef PAKFIRE_HASHES_H
+#define PAKFIRE_HASHES_H
+
+#include <openssl/sha.h>
+
+// Pakfire knows these hashes
+enum pakfire_hash_type {
+       PAKFIRE_HASH_UNDEFINED  = 0,
+       PAKFIRE_HASH_SHA2_256   = (1 << 0),
+       PAKFIRE_HASH_SHA2_512   = (1 << 1),
+       PAKFIRE_HASH_BLAKE2S256 = (1 << 2),
+       PAKFIRE_HASH_BLAKE2B512 = (1 << 3),
+       PAKFIRE_HASH_SHA3_256   = (1 << 4),
+       PAKFIRE_HASH_SHA3_512   = (1 << 5),
+};
+
+#define PAKFIRE_HASHES_ALL ( \
+       PAKFIRE_HASH_SHA2_256 \
+       | PAKFIRE_HASH_SHA2_512 \
+       | PAKFIRE_HASH_BLAKE2S256 \
+       | PAKFIRE_HASH_BLAKE2B512 \
+       | PAKFIRE_HASH_SHA3_256 \
+       | PAKFIRE_HASH_SHA3_512 \
+)
+
+#define PAKFIRE_HASHES_FOREACH(hash) \
+       for (hash = 1; hash & PAKFIRE_HASHES_ALL; hash <<= 1)
+
+// Define BLAKE2's digest lengths
+#ifndef BLAKE2S256_DIGEST_LENGTH
+#  define BLAKE2S256_DIGEST_LENGTH 32
+#endif /* BLAKE2S256_DIGEST_LENGTH */
+
+#ifndef BLAKE2B512_DIGEST_LENGTH
+#  define BLAKE2B512_DIGEST_LENGTH 64
+#endif /* BLAKE2B512_DIGEST_LENGTH */
+
+struct pakfire_hashes {
+       // The set hashes
+       enum pakfire_hash_type types;
+
+       // SHA-3-512
+       unsigned char sha3_512[SHA512_DIGEST_LENGTH];
+
+       // SHA-3-256
+       unsigned char sha3_256[SHA256_DIGEST_LENGTH];
+
+       // BLAKE2b512
+       unsigned char blake2b512[BLAKE2B512_DIGEST_LENGTH];
+
+       // BLAKE2s256
+       unsigned char blake2s256[BLAKE2S256_DIGEST_LENGTH];
+
+       // SHA2-512
+       unsigned char sha2_512[SHA512_DIGEST_LENGTH];
+
+       // SHA2-256
+       unsigned char sha2_256[SHA256_DIGEST_LENGTH];
+};
+
+#include <pakfire/ctx.h>
+
+const char* pakfire_hash_name(const enum pakfire_hash_type hash);
+enum pakfire_hash_type pakfire_hash_by_name(const char* hash);
+
+void pakfire_hashes_reset(struct pakfire_hashes* hashes);
+int pakfire_hashes_import(struct pakfire_hashes* dst, const struct pakfire_hashes* src);
+
+int pakfire_hashes_has(const struct pakfire_hashes* hashes, const enum pakfire_hash_type type);
+
+int pakfire_hashes_get(const struct pakfire_hashes* hashes,
+       const enum pakfire_hash_type type, const unsigned char** hash, size_t* length);
+int pakfire_hashes_set(struct pakfire_hashes* hashes,
+       const enum pakfire_hash_type type, const unsigned char* hash, const size_t length);
+
+int pakfire_hashes_get_hex(const struct pakfire_hashes* hashes,
+       const enum pakfire_hash_type type, char** hexdigest);
+int pakfire_hashes_set_hex(struct pakfire_hashes* hashes,
+       const enum pakfire_hash_type type, const char* hexdigest);
+
+int pakfire_hashes_dump(struct pakfire_ctx* ctx, const struct pakfire_hashes* hashes, int level);
+
+int pakfire_hashes_compare(struct pakfire_ctx* ctx,
+       const struct pakfire_hashes* hashes1, const struct pakfire_hashes* hashes2);
+
+#endif /* PAKFIRE_HASHES_H */
index 1dafb763615123eb3d81ac55ef95be8eff9b9e94..54d9c46df1f2c491e8dc8456080a52fc292360d1 100644 (file)
@@ -40,9 +40,9 @@
 #include <pakfire/constants.h>
 #include <pakfire/ctx.h>
 #include <pakfire/deps.h>
-#include <pakfire/digest.h>
 #include <pakfire/file.h>
 #include <pakfire/filelist.h>
+#include <pakfire/hashes.h>
 #include <pakfire/hex.h>
 #include <pakfire/i18n.h>
 #include <pakfire/json.h>
@@ -1308,79 +1308,76 @@ int pakfire_package_set_num(struct pakfire_package* pkg,
        return 0;
 }
 
-static enum pakfire_digest_types pakfire_package_id2digest(Id id) {
+int pakfire_package_get_checksum(struct pakfire_package* pkg,
+               enum pakfire_hash_type* hash, const unsigned char** checksum, size_t* length) {
+       Solvable* s = get_solvable(pkg);
+       Id id = 0;
+
+       // Fetch the checksum
+       *checksum = solvable_lookup_bin_checksum(s, SOLVABLE_CHECKSUM, &id);
+
+       // Store the type
        switch (id) {
                case REPOKEY_TYPE_SHA512:
-                       return PAKFIRE_DIGEST_SHA2_512;
+                       *hash = PAKFIRE_HASH_SHA2_512;
+                       if (length)
+                               *length = SHA512_DIGEST_LENGTH;
+                       break;
 
                case REPOKEY_TYPE_SHA256:
-                       return PAKFIRE_DIGEST_SHA2_256;
+                       *hash = PAKFIRE_HASH_SHA2_256;
+                       if (length)
+                               *length = SHA256_DIGEST_LENGTH;
+                       break;
+
+               default:
+                       return -EINVAL;
        }
 
        return 0;
 }
 
-const unsigned char* pakfire_package_get_digest(
-               struct pakfire_package* pkg, enum pakfire_digest_types* type, size_t* length) {
-       Solvable* s = get_solvable(pkg);
-       Id id = 0;
-
-       const unsigned char* checksum = solvable_lookup_bin_checksum(s, SOLVABLE_CHECKSUM, &id);
-
-       // Convert ID to digest type
-       *type = pakfire_package_id2digest(id);
-       if (!*type) {
-               errno = ENOTSUP;
-               checksum = NULL;
-       }
-
-       // Store the length (if requested)
-       if (length)
-               *length = pakfire_digest_length(*type);
-
-       return checksum;
-}
+int pakfire_package_set_checksum(struct pakfire_package* pkg,
+               const enum pakfire_hash_type hash, const unsigned char* digest, const size_t length) {
+       struct pakfire_repo* repo = NULL;
+       Id id = ID_NULL;
+       int r;
 
-int pakfire_package_set_digest(struct pakfire_package* pkg,
-               enum pakfire_digest_types type, const unsigned char* digest, const size_t length) {
        Solvable* s = get_solvable(pkg);
        Pool* pool = s->repo->pool;
-       Id id;
-       int r = 1;
 
-       switch (type) {
-               case PAKFIRE_DIGEST_SHA2_256:
-                       id = REPOKEY_TYPE_SHA256;
+       switch (hash) {
+               case PAKFIRE_HASH_SHA2_512:
+                       id = REPOKEY_TYPE_SHA512;
                        break;
 
-               case PAKFIRE_DIGEST_SHA2_512:
-                       id = REPOKEY_TYPE_SHA512;
+               case PAKFIRE_HASH_SHA2_256:
+                       id = REPOKEY_TYPE_SHA256;
                        break;
 
                default:
-                       errno = ENOTSUP;
-                       return 1;
-       }
-
-       // Check if the digest length matches
-       if (pakfire_digest_length(type) != length) {
-               errno = EINVAL;
-               return 1;
+                       return -EINVAL;
        }
 
-       struct pakfire_repo* repo = pakfire_package_get_repo(pkg);
+       // Fetch the repository
+       repo = pakfire_package_get_repo(pkg);
 
+       // Fetch the repodata
        Repodata* data = pakfire_repo_get_repodata(repo);
-       if (!data)
+       if (!data) {
+               r = -EINVAL;
                goto ERROR;
+       }
 
+       // Store the checksum
        repodata_set_bin_checksum(data, s - pool->solvables, SOLVABLE_CHECKSUM, id, digest);
 
        // Success
        r = 0;
 
 ERROR:
-       pakfire_repo_unref(repo);
+       if (repo)
+               pakfire_repo_unref(repo);
 
        return r;
 }
@@ -1885,7 +1882,11 @@ static int pakfire_sort_dependencies(const void* p1, const void* p2) {
 }
 
 char* pakfire_package_dump(struct pakfire_package* pkg, int flags) {
+       enum pakfire_hash_type hash = PAKFIRE_HASH_UNDEFINED;
+       const unsigned char* checksum = NULL;
+       size_t checksum_length = 0;
        char* string = NULL;
+       int r;
 
        // Name
        const char* name = pakfire_package_get_string(pkg, PAKFIRE_PKG_NAME);
@@ -1996,31 +1997,30 @@ char* pakfire_package_dump(struct pakfire_package* pkg, int flags) {
                        pakfire_strings_free(build_arches);
                }
 
-               enum pakfire_digest_types digest_type = PAKFIRE_DIGEST_UNDEFINED;
-               size_t digest_length = 0;
-
                // Digest
-               const unsigned char* digest = pakfire_package_get_digest(pkg,
-                       &digest_type, &digest_length);
-               if (digest) {
-                       switch (digest_type) {
-                               case PAKFIRE_DIGEST_SHA2_512:
-                                       pakfire_package_dump_add_line_hex(&string,
-                                               _("SHA2-512 Digest"), digest, digest_length);
-                                       break;
-
-                               case PAKFIRE_DIGEST_SHA2_256:
-                                       pakfire_package_dump_add_line_hex(&string,
-                                               _("SHA2-256 Digest"), digest, digest_length);
-                                       break;
-
-                               case PAKFIRE_DIGEST_SHA3_512:
-                               case PAKFIRE_DIGEST_SHA3_256:
-                               case PAKFIRE_DIGEST_BLAKE2B512:
-                               case PAKFIRE_DIGEST_BLAKE2S256:
-                               case PAKFIRE_DIGEST_UNDEFINED:
-                                       break;
-                       }
+               r = pakfire_package_get_checksum(pkg, &hash, &checksum, &checksum_length);
+               if (r < 0) {
+                       errno = -r;
+                       goto ERROR;
+               }
+
+               switch (hash) {
+                       case PAKFIRE_HASH_SHA2_512:
+                               pakfire_package_dump_add_line_hex(&string,
+                                       _("SHA2-512 Checksum"), checksum, checksum_length);
+                               break;
+
+                       case PAKFIRE_HASH_SHA2_256:
+                               pakfire_package_dump_add_line_hex(&string,
+                                       _("SHA2-256 Checksum"), checksum, checksum_length);
+                               break;
+
+                       case PAKFIRE_HASH_SHA3_512:
+                       case PAKFIRE_HASH_SHA3_256:
+                       case PAKFIRE_HASH_BLAKE2B512:
+                       case PAKFIRE_HASH_BLAKE2S256:
+                       case PAKFIRE_HASH_UNDEFINED:
+                               break;
                }
 
                // Source package
@@ -2121,6 +2121,12 @@ char* pakfire_package_dump(struct pakfire_package* pkg, int flags) {
        }
 
        return string;
+
+ERROR:
+       if (string)
+               free(string);
+
+       return NULL;
 }
 
 struct pakfire_archive* pakfire_package_get_archive(struct pakfire_package* pkg) {
index 08e39e9151423d38c18965627b8d44001191bd6d..b97aa1db4a968ebaa0356845322866ef38871b87 100644 (file)
@@ -32,8 +32,8 @@
 
 struct pakfire_package;
 
-#include <pakfire/digest.h>
 #include <pakfire/filelist.h>
+#include <pakfire/hashes.h>
 #include <pakfire/packagelist.h>
 #include <pakfire/pakfire.h>
 #include <pakfire/repo.h>
@@ -130,10 +130,12 @@ int pakfire_package_set_num(struct pakfire_package* pkg,
 char** pakfire_package_get_deps(struct pakfire_package* pkg,
        const enum pakfire_package_key key);
 
-const unsigned char* pakfire_package_get_digest(struct pakfire_package* pkg,
-       enum pakfire_digest_types* type, size_t* length);
-int pakfire_package_set_digest(struct pakfire_package* pkg,
-       enum pakfire_digest_types type, const unsigned char* digest, const size_t length);
+// Checksum
+int pakfire_package_get_checksum(struct pakfire_package* pkg,
+       enum pakfire_hash_type* hash, const unsigned char** checksum, size_t* length);
+int pakfire_package_set_checksum(struct pakfire_package* pkg,
+       const enum pakfire_hash_type hash, const unsigned char* digest, const size_t length);
+
 size_t pakfire_package_get_size(struct pakfire_package* pkg);
 
 int pakfire_package_get_reverse_requires(struct pakfire_package* pkg,
index b5835407d56512eb35e2e3ec3b9238f0e7745b41..5d397fe459c3ff2ee230aeaa9a958fb0a5be0872 100644 (file)
@@ -118,7 +118,7 @@ int pakfire_packager_create(struct pakfire_packager** packager,
        p->pkg = pakfire_package_ref(pkg);
 
        // Use the default digests
-       p->digests = PAKFIRE_PACKAGER_DIGESTS;
+       p->digests = PAKFIRE_PACKAGER_HASHES;
 
        // Set distribution
        const char* tag = pakfire_get_distro_tag(p->pakfire);
@@ -157,37 +157,37 @@ int pakfire_packager_create(struct pakfire_packager** packager,
                goto ERROR;
 
        // Add a requirement for the cryptographic algorithms we are using
-       if (p->digests & PAKFIRE_DIGEST_SHA3_512) {
+       if (p->digests & PAKFIRE_HASH_SHA3_512) {
                r = pakfire_package_add_dep(p->pkg,
                        PAKFIRE_PKG_REQUIRES, "pakfire(Digest-SHA3-512)");
                if (r)
                        goto ERROR;
        }
-       if (p->digests & PAKFIRE_DIGEST_SHA3_256) {
+       if (p->digests & PAKFIRE_HASH_SHA3_256) {
                r = pakfire_package_add_dep(p->pkg,
                        PAKFIRE_PKG_REQUIRES, "pakfire(Digest-SHA3-256)");
                if (r)
                        goto ERROR;
        }
-       if (p->digests & PAKFIRE_DIGEST_BLAKE2B512) {
+       if (p->digests & PAKFIRE_HASH_BLAKE2B512) {
                r = pakfire_package_add_dep(p->pkg,
                        PAKFIRE_PKG_REQUIRES, "pakfire(Digest-BLAKE2b512)");
                if (r)
                        goto ERROR;
        }
-       if (p->digests & PAKFIRE_DIGEST_BLAKE2S256) {
+       if (p->digests & PAKFIRE_HASH_BLAKE2S256) {
                r = pakfire_package_add_dep(p->pkg,
                        PAKFIRE_PKG_REQUIRES, "pakfire(Digest-BLAKE2s256)");
                if (r)
                        goto ERROR;
        }
-       if (p->digests & PAKFIRE_DIGEST_SHA2_512) {
+       if (p->digests & PAKFIRE_HASH_SHA2_512) {
                r = pakfire_package_add_dep(p->pkg,
                        PAKFIRE_PKG_REQUIRES, "pakfire(Digest-SHA2-512)");
                if (r)
                        goto ERROR;
        }
-       if (p->digests & PAKFIRE_DIGEST_SHA2_256) {
+       if (p->digests & PAKFIRE_HASH_SHA2_256) {
                r = pakfire_package_add_dep(p->pkg,
                        PAKFIRE_PKG_REQUIRES, "pakfire(Digest-SHA2-256)");
                if (r)
@@ -460,7 +460,7 @@ int pakfire_packager_finish(struct pakfire_packager* packager, FILE* f) {
 
        // Write the payload
        r = pakfire_compress(packager->pakfire, a, packager->filelist, nevra,
-               PAKFIRE_COMPRESS_SHOW_THROUGHPUT, PAKFIRE_PACKAGER_DIGESTS);
+               PAKFIRE_COMPRESS_SHOW_THROUGHPUT, PAKFIRE_PACKAGER_HASHES);
        if (r)
                goto ERROR;
 
index f207f440149e0b63d84c3229a9273bc6e71470d7..88ed4b76eb1e94e27833157bc5eadf9253177fbe 100644 (file)
 #ifndef PAKFIRE_PACKAGER_H
 #define PAKFIRE_PACKAGER_H
 
-#include <pakfire/digest.h>
 #include <pakfire/file.h>
 #include <pakfire/filelist.h>
+#include <pakfire/hashes.h>
 #include <pakfire/package.h>
 #include <pakfire/scriptlet.h>
 
-#define PAKFIRE_PACKAGER_DIGESTS (PAKFIRE_DIGEST_SHA3_512|PAKFIRE_DIGEST_BLAKE2B512)
+#define PAKFIRE_PACKAGER_HASHES (PAKFIRE_HASH_SHA3_512|PAKFIRE_HASH_BLAKE2B512)
 
 struct pakfire_packager;
 
index e9c20f5c6e32fb24d297949d8217a4546aa16834..74f81c7b7bd3ac8566bd4212d3a27bcb6b811cf0 100644 (file)
@@ -38,6 +38,7 @@
 #include <pakfire/config.h>
 #include <pakfire/constants.h>
 #include <pakfire/ctx.h>
+#include <pakfire/hashes.h>
 #include <pakfire/i18n.h>
 #include <pakfire/json.h>
 #include <pakfire/logging.h>
@@ -50,7 +51,7 @@
 #include <pakfire/util.h>
 #include <pakfire/xfer.h>
 
-#define METADATA_DIGESTS PAKFIRE_DIGEST_SHA3_512|PAKFIRE_DIGEST_BLAKE2B512
+#define METADATA_CHECKSUMS (PAKFIRE_HASH_SHA3_512|PAKFIRE_HASH_BLAKE2B512)
 
 // Refresh mirror lists once every 6 hours
 #define REFRESH_AGE_MIRRORLIST                 6 * 3600
@@ -75,8 +76,8 @@ struct pakfire_repomd {
                // Size
                size_t size;
 
-               // Digests
-               struct pakfire_digests digests;
+               // Hashes
+               struct pakfire_hashes hashes;
        } packages;
 };
 
@@ -853,6 +854,11 @@ static int pakfire_repo_download_database(
        if (r < 0)
                goto ERROR;
 
+       // Set digests
+       r = pakfire_xfer_verify_hashes(xfer, &repo->appdata->repomd.packages.hashes);
+       if (r < 0)
+               goto ERROR;
+
        // Run the xfer
        r = pakfire_xfer_run(xfer, 0);
        if (r < 0)
@@ -945,7 +951,7 @@ static int pakfire_repo_parse_repomd(struct pakfire_repo* self,
        const char* type = NULL;
        const char* filename = NULL;
        ssize_t size = 0;
-       struct pakfire_digests digests = {};
+       struct pakfire_hashes hashes = {};
        int r;
 
        // Parse version
@@ -1000,11 +1006,11 @@ static int pakfire_repo_parse_repomd(struct pakfire_repo* self,
                        return r;
 
                // Parse checksums
-               json_object_object_foreach(chksums, digest_name, hexdigest) {
-                       enum pakfire_digest_types digest_type = pakfire_digest_get_by_name(digest_name);
+               json_object_object_foreach(chksums, hash_name, hexdigest) {
+                       enum pakfire_hash_type hash_type = pakfire_hash_by_name(hash_name);
 
                        // Import the hexdigest
-                       r = pakfire_digests_set_hexdigest(&digests, digest_type, json_object_get_string(hexdigest));
+                       r = pakfire_hashes_set_hex(&hashes, hash_type, json_object_get_string(hexdigest));
                        if (r < 0)
                                return r;
                }
@@ -1019,8 +1025,8 @@ static int pakfire_repo_parse_repomd(struct pakfire_repo* self,
                        // Store the filelist
                        repomd->packages.size = size;
 
-                       // Store the digests
-                       r = pakfire_digests_import(&repomd->packages.digests, &digests);
+                       // Store the hashes
+                       r = pakfire_hashes_import(&repomd->packages.hashes, &hashes);
                        if (r < 0)
                                return r;
 
@@ -1028,8 +1034,8 @@ static int pakfire_repo_parse_repomd(struct pakfire_repo* self,
                        break;
                }
 
-               // Reset the digests
-               pakfire_digests_reset(&digests, PAKFIRE_DIGESTS_ALL);
+               // Reset the hashes
+               pakfire_hashes_reset(&hashes);
        }
 
        return 0;
@@ -1820,8 +1826,11 @@ int pakfire_repo_is_installed_repo(struct pakfire_repo* self) {
 
 int pakfire_repo_download_package(struct pakfire_xfer** xfer,
                struct pakfire_repo* repo, struct pakfire_package* pkg) {
+       enum pakfire_hash_type hash = PAKFIRE_HASH_UNDEFINED;
+       const unsigned char* checksum = NULL;
+       size_t checksum_length = 0;
+       struct pakfire_hashes hashes = {};
        struct pakfire_xfer* x = NULL;
-       const unsigned char* digest = NULL;
        const char* cache_path = NULL;
        const char* nevra = NULL;
        const char* url = NULL;
@@ -1846,16 +1855,24 @@ int pakfire_repo_download_package(struct pakfire_xfer** xfer,
                goto ERROR;
        }
 
-       enum pakfire_digest_types digest_type = 0;
-       size_t digest_length = 0;
-
        // Retrieve package digest
-       digest = pakfire_package_get_digest(pkg, &digest_type, &digest_length);
-       if (!digest) {
-               ERROR(repo->ctx, "Package %s has no digest set: %m\n", nevra);
+       r = pakfire_package_get_checksum(pkg, &hash, &checksum, &checksum_length);
+       if (r < 0) {
+               ERROR(repo->ctx, "Failed to fetch checksum: %s\n", strerror(-r));
                goto ERROR;
        }
 
+       // Checksum must be set
+       if (!checksum) {
+               ERROR(repo->ctx, "Package %s has no checksum\n", nevra);
+               goto ERROR;
+       }
+
+       // Store the check in hashes
+       r = pakfire_hashes_set(&hashes, hash, checksum, checksum_length);
+       if (r < 0)
+               goto ERROR;
+
        // Create a new transfer
        r = pakfire_repo_xfer_create(&x, repo, "%s", url);
        if (r)
@@ -1872,18 +1889,18 @@ int pakfire_repo_download_package(struct pakfire_xfer** xfer,
        // Set size
        if (downloadsize > 0) {
                r = pakfire_xfer_set_size(x, downloadsize);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
        // Set output path
        r = pakfire_xfer_set_output_path(x, cache_path);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Set digest
-       r = pakfire_xfer_verify_digest(x, digest_type, digest, digest_length);
-       if (r)
+       r = pakfire_xfer_verify_hashes(x, &hashes);
+       if (r < 0)
                goto ERROR;
 
        // Success
@@ -2224,14 +2241,14 @@ static int pakfire_repo_cleanup_metadata(struct pakfire_repo* self) {
 
 static int pakfire_repo_metadata_add_file(struct pakfire_repo* self,
                struct json_object* repomd, const char* type, const char* path) {
-       struct pakfire_digests digests = {};
+       enum pakfire_hash_type hash = PAKFIRE_HASH_UNDEFINED;
+       struct pakfire_hashes checksums = {};
        struct json_object* files = NULL;
        struct json_object* file = NULL;
        struct json_object* chksums = NULL;
        char filename[PATH_MAX];
        char* hexdigest = NULL;
        struct stat st = {};
-       int digest;
        int r;
 
        // Stat the file
@@ -2247,10 +2264,10 @@ static int pakfire_repo_metadata_add_file(struct pakfire_repo* self,
        if (r < 0)
                goto ERROR;
 
-       // Compute the database digests
-       r = pakfire_digests_compute_from_path(self->ctx, &digests, METADATA_DIGESTS, path);
+       // Compute the database checksums
+       r = pakfire_hash_path(self->ctx, path, METADATA_CHECKSUMS, &checksums);
        if (r < 0) {
-               ERROR(self->ctx, "Failed to compute file digests: %s\n", strerror(-r));
+               ERROR(self->ctx, "Failed to compute file hashes: %s\n", strerror(-r));
                goto ERROR;
        }
 
@@ -2289,12 +2306,14 @@ static int pakfire_repo_metadata_add_file(struct pakfire_repo* self,
        if (r < 0)
                goto ERROR;
 
-       // Add all digests
-       PAKFIRE_DIGESTS_FOREACH(digest) {
-               hexdigest = pakfire_digest_get_hex(&digests, digest);
+       // Add all checksums
+       PAKFIRE_HASHES_FOREACH(hash) {
+               r = pakfire_hashes_get_hex(&checksums, hash, &hexdigest);
+               if (r < 0)
+                       goto ERROR;
 
                if (hexdigest) {
-                       r = pakfire_json_add_string(chksums, pakfire_digest_name(digest), hexdigest);
+                       r = pakfire_json_add_string(chksums, pakfire_hash_name(hash), hexdigest);
                        if (r < 0)
                                goto ERROR;
 
index 577666da206cb9d68d3e5c51e9cfafdf2948d33c..3e9585a0ae32820aaa71ef31dbba020dbf409405 100644 (file)
@@ -31,8 +31,8 @@
 #include <pakfire/ctx.h>
 #include <pakfire/db.h>
 #include <pakfire/deps.h>
-#include <pakfire/digest.h>
 #include <pakfire/filelist.h>
+#include <pakfire/hashes.h>
 #include <pakfire/i18n.h>
 #include <pakfire/jail.h>
 #include <pakfire/logging.h>
@@ -1308,6 +1308,11 @@ static int pakfire_transaction_check(struct pakfire_transaction* transaction) {
 
 static int pakfire_transaction_verify(struct pakfire_transaction* transaction,
                struct pakfire_package* pkg, struct pakfire_archive* archive) {
+       enum pakfire_hash_type hash = PAKFIRE_HASH_UNDEFINED;
+       const unsigned char* checksum = NULL;
+       size_t checksum_length = 0;
+       int r;
+
        const char* nevra = pakfire_package_get_string(pkg, PAKFIRE_PKG_NEVRA);
 
        // Nothing to do if this step does not have an archive
@@ -1316,18 +1321,25 @@ static int pakfire_transaction_verify(struct pakfire_transaction* transaction,
                return 0;
        }
 
-       enum pakfire_digest_types digest_type = PAKFIRE_DIGEST_UNDEFINED;
-       size_t length = 0;
-
        // Fetch digest from package
-       const unsigned char* expected_digest = pakfire_package_get_digest(pkg, &digest_type, &length);
-       if (!expected_digest) {
-               DEBUG(transaction->ctx, "Package %s has no digest\n", nevra);
-               return 0;
+       r = pakfire_package_get_checksum(pkg, &hash, &checksum, &checksum_length);
+       if (r < 0) {
+               ERROR(transaction->ctx, "Could not fetch checksum for %s: %s\n", nevra, strerror(-r));
+               return r;
        }
 
+       // Fail if there is no checksum
+       if (!checksum) {
+               ERROR(transaction->ctx, "Package %s has no checksum\n", nevra);
+               return -EINVAL;
+       }
+
+#if 0
        // Check against the digest of the archive
        return pakfire_archive_check_digest(archive, digest_type, expected_digest, length);
+#endif
+
+       return 0;
 }
 
 static int pakfire_transaction_run_script(struct pakfire_transaction* transaction,
index 363a471e45b8bb2001b96497fc2e7c589cd3c984..4a31a729105723035a0ed6d97d10c71409a59e62 100644 (file)
 
 #include <json.h>
 
-#include <openssl/err.h>
-#include <openssl/evp.h>
-
 #include <systemd/sd-event.h>
 
 #include <pakfire/ctx.h>
+#include <pakfire/hasher.h>
 #include <pakfire/hex.h>
 #include <pakfire/json.h>
 #include <pakfire/mirrorlist.h>
@@ -87,13 +85,11 @@ struct pakfire_xfer {
        FILE* fin;
        FILE* fout;
 
-       // Crypto Stuff
-       EVP_MD_CTX* evp;
-       const EVP_MD* md;
-       unsigned char computed_digest[EVP_MAX_MD_SIZE];
-       unsigned int computed_digest_length;
-       unsigned char expected_digest[EVP_MAX_MD_SIZE];
-       unsigned int expected_digest_length;
+       // Expected Hashes
+       struct pakfire_hashes expected_hashes;
+
+       // Hasher
+       struct pakfire_hasher* hasher;
 
        // Mirrors
        char baseurl[PATH_MAX];
@@ -139,10 +135,6 @@ static void pakfire_xfer_free(struct pakfire_xfer* xfer) {
        if (xfer->fin)
                fclose(xfer->fin);
 
-       // Free OpenSSL EVP context
-       if (xfer->evp)
-               EVP_MD_CTX_free(xfer->evp);
-
        // systemd
        if (xfer->event)
                sd_event_source_unref(xfer->event);
@@ -167,6 +159,8 @@ static void pakfire_xfer_free(struct pakfire_xfer* xfer) {
        if (xfer->fullurl)
                curl_url_cleanup(xfer->fullurl);
 
+       if (xfer->hasher)
+               pakfire_hasher_unref(xfer->hasher);
        if (xfer->mirror)
                pakfire_mirror_unref(xfer->mirror);
        if (xfer->mirrors)
@@ -228,21 +222,17 @@ static int pakfire_xfer_seek(void* p, curl_off_t offset, int origin) {
 static size_t pakfire_xfer_write(
                char* data, size_t size, size_t nmemb, void* p) {
        struct pakfire_xfer* xfer = p;
-       struct pakfire_ctx* ctx = xfer->ctx;
        int r;
 
        // Do not write empty blocks
        if (!nmemb)
                return nmemb;
 
-       // Update message digest
-       if (xfer->evp) {
-               r = EVP_DigestUpdate(xfer->evp, data, nmemb);
-               if (r != 1) {
-                       ERROR(ctx, "EVP_DigestUpdate failed: %s\n",
-                               ERR_error_string(ERR_get_error(), NULL));
-                       return 0;
-               }
+       // Update the hasher
+       if (xfer->hasher) {
+               r = pakfire_hasher_update(xfer->hasher, data, nmemb);
+               if (r < 0)
+                       return r;
        }
 
        // If there is no output steam, we just pretent that we have consumed the data
@@ -559,51 +549,8 @@ int pakfire_xfer_set_size(struct pakfire_xfer* xfer, size_t size) {
        return 0;
 }
 
-int pakfire_xfer_verify_digest(struct pakfire_xfer* xfer, const enum pakfire_digest_types md,
-               const unsigned char* expected_digest, const size_t expected_digest_length) {
-       // Check inputs
-       if (!expected_digest || !expected_digest_length)
-               return -EINVAL;
-
-       // Expected digest length cannot be too long
-       if (expected_digest_length > sizeof(xfer->expected_digest))
-               return -ENOBUFS;
-
-       // Store digest type
-       switch (md) {
-               case PAKFIRE_DIGEST_SHA3_512:
-                       xfer->md = EVP_sha3_512();
-                       break;
-
-               case PAKFIRE_DIGEST_SHA3_256:
-                       xfer->md = EVP_sha3_256();
-                       break;
-
-               case PAKFIRE_DIGEST_BLAKE2B512:
-                       xfer->md = EVP_blake2b512();
-                       break;
-
-               case PAKFIRE_DIGEST_BLAKE2S256:
-                       xfer->md = EVP_blake2s256();
-                       break;
-
-               case PAKFIRE_DIGEST_SHA2_512:
-                       xfer->md = EVP_sha512();
-                       break;
-
-               case PAKFIRE_DIGEST_SHA2_256:
-                       xfer->md = EVP_sha256();
-                       break;
-
-               default:
-                       return -ENOTSUP;
-       }
-
-       // Store the expected digest and its length
-       memcpy(xfer->expected_digest, expected_digest, expected_digest_length);
-       xfer->expected_digest_length = expected_digest_length;
-
-       return 0;
+int pakfire_xfer_verify_hashes(struct pakfire_xfer* self, const struct pakfire_hashes* hashes) {
+       return pakfire_hashes_import(&self->expected_hashes, hashes);
 }
 
 int pakfire_xfer_add_query(struct pakfire_xfer* xfer,
@@ -948,6 +895,12 @@ ERROR:
 static int pakfire_xfer_fail(struct pakfire_xfer* xfer, int code) {
        int r;
 
+       // Drop the hasher
+       if (xfer->hasher) {
+               pakfire_hasher_unref(xfer->hasher);
+               xfer->hasher = NULL;
+       }
+
        // Throw away any downloaded data
        if (xfer->fin) {
                // Get file descriptor
@@ -1186,52 +1139,47 @@ ERROR:
 #endif /* CURL_HAS_WEBSOCKETS */
 
 /*
-       This function checks if the digests match (if set up)
+       This function checks if the hashes match (if set up)
 */
 static int pakfire_xfer_verify(struct pakfire_xfer* self) {
-       char* computed_hexdigest = NULL;
-       char* expected_hexdigest = NULL;
+       struct pakfire_hashes computed_hashes = {};
        int r;
 
-       // Nothing to do if there is no EVP
-       if (!self->evp)
+       // Nothing to do if there is no hasher
+       if (!self->hasher)
                return 0;
 
-       // Finish message digest computation
-       r = EVP_DigestFinal_ex(self->evp, self->computed_digest, &self->computed_digest_length);
-       if (r != 1) {
-               ERROR(self->ctx, "Could not finish message digest computation: %s\n",
-                       ERR_error_string(ERR_get_error(), NULL));
-               r = -EBADMSG;
-               goto ERROR;
-       }
+       // Finish the hasher
+       r = pakfire_hasher_finalize(self->hasher, &computed_hashes);
+       if (r < 0)
+               return r;
 
-       // Compare the hexdigests
-       r = CRYPTO_memcmp(self->computed_digest, self->expected_digest, self->computed_digest_length);
+       // Compare the hashes
+       r = pakfire_hashes_compare(self->ctx, &self->expected_hashes, &computed_hashes);
+       switch (r) {
+               case 0:
+                       DEBUG(self->ctx, "Payload matches\n");
+                       return 0;
 
-       // If they don't match, log the error
-       if (r) {
-               // Format the expected hexdigest
-               computed_hexdigest = __pakfire_hexlify(self->computed_digest, self->computed_digest_length);
-               expected_hexdigest = __pakfire_hexlify(self->expected_digest, self->expected_digest_length);
+               case 1:
+                       ERROR(self->ctx, "Download checksum for %s didn't match:\n", self->effective_url);
 
-               ERROR(self->ctx, "Download checksum for %s didn't match:\n", self->effective_url);
-               ERROR(self->ctx, "  Expected: %s\n", expected_hexdigest);
-               ERROR(self->ctx, "  Computed: %s\n", computed_hexdigest);
+                       // Show the expected hashes
+                       ERROR(self->ctx, " Expected Hashes:\n");
+                       pakfire_hashes_dump(self->ctx, &self->expected_hashes, LOG_ERR);
 
-               // Make this download fail
-               r = pakfire_xfer_fail(self, PAKFIRE_XFER_DIGEST_MISMATCH);
-               if (r < 0)
-                       goto ERROR;
-       }
+                       // Show the computed hashes
+                       ERROR(self->ctx, " Computed Hashes:\n");
+                       pakfire_hashes_dump(self->ctx, &computed_hashes, LOG_ERR);
 
-ERROR:
-       if (computed_hexdigest)
-               free(computed_hexdigest);
-       if (expected_hexdigest)
-               free(expected_hexdigest);
+                       // Consider the download failed
+                       return pakfire_xfer_fail(self, PAKFIRE_XFER_DIGEST_MISMATCH);
 
-       return r;
+               // Errors
+               default:
+                       ERROR(self->ctx, "Failed to compare hashes: %s\n", strerror(-r));
+                       return r;
+       }
 }
 
 static int pakfire_xfer_save(struct pakfire_xfer* xfer) {
@@ -1597,6 +1545,13 @@ int pakfire_xfer_prepare(struct pakfire_xfer* xfer, struct pakfire_progress* pro
        // Set special options for direction
        switch (xfer->direction) {
                case PAKFIRE_XFER_DOWNLOAD:
+                       if (xfer->expected_hashes.types) {
+                               r = pakfire_hasher_create(&xfer->hasher, xfer->ctx, xfer->expected_hashes.types);
+                               if (r < 0) {
+                                       ERROR(xfer->ctx, "Failed to setup the hasher: %s\n", strerror(-r));
+                                       return r;
+                               }
+                       }
                        break;
 
                case PAKFIRE_XFER_UPLOAD:
@@ -1673,29 +1628,6 @@ int pakfire_xfer_prepare(struct pakfire_xfer* xfer, struct pakfire_progress* pro
                }
        }
 
-       // Drop any previously used EVP contexts
-       if (xfer->evp) {
-               EVP_MD_CTX_free(xfer->evp);
-               xfer->evp = NULL;
-       }
-
-       // Create a new EVP context
-       if (xfer->md) {
-               xfer->evp = EVP_MD_CTX_new();
-               if (!xfer->evp) {
-                       ERROR(xfer->ctx, "Could not create EVP context: %m\n");
-                       return 1;
-               }
-
-               // Initialize the EVP context
-               r = EVP_DigestInit_ex(xfer->evp, xfer->md, NULL);
-               if (r != 1) {
-                       ERROR(xfer->ctx, "Could not initialize EVP context: %s\n",
-                               ERR_error_string(ERR_get_error(), NULL));
-                       return 1;
-               }
-       }
-
        // Setup progress
        r = pakfire_xfer_prepare_progress(xfer, progress, flags);
        if (r)
index 8476704da75fbf2c6de6f44a4ef07682725a2760..37d6c2d3cf7bcd8db4d91b19d1288fef7098db9e 100644 (file)
@@ -69,6 +69,8 @@ typedef enum pakfire_xfer_error_code {
 } pakfire_xfer_error_code_t;
 
 #include <pakfire/ctx.h>
+#include <pakfire/hasher.h>
+#include <pakfire/hashes.h>
 #include <pakfire/httpclient.h>
 #include <pakfire/mirrorlist.h>
 #include <pakfire/progress.h>
@@ -107,8 +109,7 @@ int pakfire_xfer_set_mirrorlist(struct pakfire_xfer* xfer, struct pakfire_mirror
 size_t pakfire_xfer_get_size(struct pakfire_xfer* xfer);
 int pakfire_xfer_set_size(struct pakfire_xfer* xfer, size_t size);
 
-int pakfire_xfer_verify_digest(struct pakfire_xfer* xfer, const enum pakfire_digest_types md,
-       const unsigned char* expected_digest, const size_t expected_digest_length);
+int pakfire_xfer_verify_hashes(struct pakfire_xfer* self, const struct pakfire_hashes* hashes);
 
 int pakfire_xfer_add_query(struct pakfire_xfer* xfer,
        const char* key, const char* format, ...) __attribute__((format(printf, 3, 4)));
index 5ca4b20a8379e8a10cb571e53f5c00510e0e7dac..95d6e5744bbe7f20ebfa94702a67d41b0c7cb22c 100644 (file)
@@ -21,7 +21,7 @@
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 
-#include <pakfire/digest.h>
+#include <pakfire/hashes.h>
 #include <pakfire/file.h>
 
 #include "file.h"
@@ -107,28 +107,30 @@ static PyObject* File_get_mtime(FileObject* self) {
 }
 
 static PyObject* File_digest(FileObject* self, PyObject* args) {
+       const unsigned char* checksum = NULL;
+       size_t length = 0;
+       int r;
+
        const char* name = NULL;
 
        if (!PyArg_ParseTuple(args, "s", &name))
                return NULL;
 
        // Fetch the type
-       const enum pakfire_digest_types type = pakfire_digest_get_by_name(name);
+       const enum pakfire_hash_type type = pakfire_hash_by_name(name);
 
        // Raise ValueError if we could not find the type
        if (!type) {
-               PyErr_Format(PyExc_ValueError, "Unknown digest type: %s", name);
+               PyErr_Format(PyExc_ValueError, "Unknown hash type: %s", name);
                return NULL;
        }
 
-       size_t length = 0;
-
-       // Fetch the digest
-       const unsigned char* digest = pakfire_file_get_digest(self->file, type, &length);
-       if (!digest)
+       // Fetch the checksum
+       r = pakfire_file_get_checksum(self->file, type, &checksum, &length);
+       if (r < 0)
                Py_RETURN_NONE;
 
-       return PyBytes_FromStringAndSize((const char*)digest, length);
+       return PyBytes_FromStringAndSize((const char*)checksum, length);
 }
 
 static PyObject* File_get_mimetype(FileObject* self) {
index 233abfcf573a10bb181cadb2b21eb0231f42ad94..43b858a2869bf1f668bbfba1d8f9676e6c61485e 100644 (file)
@@ -21,9 +21,9 @@
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 
-#include <pakfire/digest.h>
 #include <pakfire/file.h>
 #include <pakfire/filelist.h>
+#include <pakfire/hashes.h>
 #include <pakfire/package.h>
 #include <pakfire/repo.h>
 #include <pakfire/string.h>
@@ -194,17 +194,18 @@ static PyObject* Package_get_uuid(PackageObject* self) {
        return PyUnicode_FromString(uuid);
 }
 
-static PyObject* Package_get_digest(PackageObject* self) {
-       enum pakfire_digest_types type = PAKFIRE_DIGEST_UNDEFINED;
-       const unsigned char* digest = NULL;
-       size_t length = 0;
+static PyObject* Package_get_checksum(PackageObject* self) {
+       enum pakfire_hash_type type = PAKFIRE_HASH_UNDEFINED;
+       const unsigned char* checksum = NULL;
+       size_t checksum_length = 0;
+       int r;
 
-       // Fetch the digest
-       digest = pakfire_package_get_digest(self->package, &type, &length);
-       if (!digest)
-               Py_RETURN_NONE;
+       // Fetch the checksum
+       r = pakfire_package_get_checksum(self->package, &type, &checksum, &checksum_length);
+       if (r < 0)
+               return NULL;
 
-       return Py_BuildValue("(sy#)", pakfire_digest_name(type), digest, length);
+       return Py_BuildValue("(sy#)", pakfire_hash_name(type), checksum, checksum_length);
 }
 
 static PyObject* Package_get_summary(PackageObject* self) {
@@ -583,8 +584,8 @@ static struct PyGetSetDef Package_getsetters[] = {
                NULL
        },
        {
-               "digest",
-               (getter)Package_get_digest,
+               "checksum",
+               (getter)Package_get_checksum,
                NULL,
                NULL,
                NULL,
index d7cc845491a1c8872e15cfecff3712e485d202ad..e8eb405f0d5b7f472ee9acbc626525b75c035453 100644 (file)
@@ -18,6 +18,7 @@
 #                                                                             #
 #############################################################################*/
 
+#include <pakfire/hashes.h>
 #include <pakfire/xfer.h>
 
 #include "../testsuite.h"
@@ -107,11 +108,15 @@ FAIL:
 }
 
 static int test_download_check_digest(const struct test* t) {
+       struct pakfire_hashes hashes = {};
        struct pakfire_xfer* xfer = NULL;
        char* buffer = NULL;
        size_t length = 0;
        int r = EXIT_FAILURE;
 
+       ASSERT_SUCCESS(pakfire_hashes_set(&hashes,
+               PAKFIRE_HASH_SHA2_512, RANDOM_FILE_sha2_512, sizeof(RANDOM_FILE_sha2_512)));
+
        // Create a new transfer
        ASSERT_SUCCESS(pakfire_xfer_create_simple(&xfer, t->ctx, RANDOM_FILE));
 
@@ -119,8 +124,7 @@ static int test_download_check_digest(const struct test* t) {
        ASSERT_SUCCESS(pakfire_xfer_set_output_buffer(xfer, &buffer, &length));
 
        // Set the digest value
-       ASSERT_SUCCESS(pakfire_xfer_verify_digest(xfer, PAKFIRE_DIGEST_SHA2_512,
-               RANDOM_FILE_sha2_512, sizeof(RANDOM_FILE_sha2_512)));
+       ASSERT_SUCCESS(pakfire_xfer_verify_hashes(xfer, &hashes));
 
        // Run it!
        ASSERT_SUCCESS(pakfire_xfer_run(xfer, PAKFIRE_XFER_NO_PROGRESS));
@@ -142,11 +146,16 @@ FAIL:
 }
 
 static int test_download_check_incorrect_digest(const struct test* t) {
+       struct pakfire_hashes hashes = {};
        struct pakfire_xfer* xfer = NULL;
        char* buffer = NULL;
        size_t length = 0;
        int r = EXIT_FAILURE;
 
+       // Store the hash
+       ASSERT_SUCCESS(pakfire_hashes_set(&hashes,
+               PAKFIRE_HASH_SHA3_512, RANDOM_FILE_sha2_512, sizeof(RANDOM_FILE_sha2_512)));
+
        // Create a new transfer
        ASSERT_SUCCESS(pakfire_xfer_create_simple(&xfer, t->ctx, RANDOM_FILE));
 
@@ -154,8 +163,7 @@ static int test_download_check_incorrect_digest(const struct test* t) {
        ASSERT_SUCCESS(pakfire_xfer_set_output_buffer(xfer, &buffer, &length));
 
        // Set the digest value, but use a wrong digest method
-       ASSERT_SUCCESS(pakfire_xfer_verify_digest(xfer, PAKFIRE_DIGEST_SHA3_512,
-               RANDOM_FILE_sha2_512, sizeof(RANDOM_FILE_sha2_512)));
+       ASSERT_SUCCESS(pakfire_xfer_verify_hashes(xfer, &hashes));
 
        // Run it!
        ASSERT(pakfire_xfer_run(xfer, PAKFIRE_XFER_NO_PROGRESS) == PAKFIRE_XFER_DIGEST_MISMATCH);