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 \
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 \
tests/libpakfire/config \
tests/libpakfire/db \
tests/libpakfire/deps \
- tests/libpakfire/digest \
tests/libpakfire/env \
tests/libpakfire/file \
tests/libpakfire/httpclient \
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
#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>
#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
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;
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
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;
}
/*
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;
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;
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;
}
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>
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);
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);
#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>
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;
}
// 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
#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>
// 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,
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;
}
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;
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?
#include <pakfire/archive.h>
#include <pakfire/ctx.h>
+#include <pakfire/hashes.h>
#include <pakfire/pakfire.h>
// Automatically detect
};
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);
#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>
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) {
}
// 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));
}
// 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));
}
// 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));
}
// 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));
}
// 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));
}
// 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));
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;
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;
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
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,
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;
+++ /dev/null
-/*#############################################################################
-# #
-# 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;
-}
+++ /dev/null
-/*#############################################################################
-# #
-# 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 */
#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>
// Flags
int flags;
- // Digests
- struct pakfire_digests digests;
+ // Hashes
+ struct pakfire_hashes hashes;
// MIME Type
char mimetype[NAME_MAX];
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) {
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;
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;
"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) {
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;
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;
}
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;
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;
}
/*
struct pakfire_file;
-#include <pakfire/digest.h>
+#include <pakfire/hashes.h>
#include <pakfire/pakfire.h>
enum pakfire_file_flags {
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);
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),
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),
};
--- /dev/null
+/*#############################################################################
+# #
+# 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;
+}
--- /dev/null
+/*#############################################################################
+# #
+# 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 */
--- /dev/null
+/*#############################################################################
+# #
+# 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;
+}
--- /dev/null
+/*#############################################################################
+# #
+# 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 */
#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>
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;
}
}
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);
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
}
return string;
+
+ERROR:
+ if (string)
+ free(string);
+
+ return NULL;
}
struct pakfire_archive* pakfire_package_get_archive(struct pakfire_package* pkg) {
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>
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,
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);
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)
// 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;
#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;
#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>
#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
// Size
size_t size;
- // Digests
- struct pakfire_digests digests;
+ // Hashes
+ struct pakfire_hashes hashes;
} packages;
};
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)
const char* type = NULL;
const char* filename = NULL;
ssize_t size = 0;
- struct pakfire_digests digests = {};
+ struct pakfire_hashes hashes = {};
int r;
// Parse version
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;
}
// 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;
break;
}
- // Reset the digests
- pakfire_digests_reset(&digests, PAKFIRE_DIGESTS_ALL);
+ // Reset the hashes
+ pakfire_hashes_reset(&hashes);
}
return 0;
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;
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)
// 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
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
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;
}
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;
#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>
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
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,
#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>
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];
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);
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)
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
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,
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
#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) {
// 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:
}
}
- // 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)
} 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>
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)));
#define PY_SSIZE_T_CLEAN
#include <Python.h>
-#include <pakfire/digest.h>
+#include <pakfire/hashes.h>
#include <pakfire/file.h>
#include "file.h"
}
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) {
#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>
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) {
NULL
},
{
- "digest",
- (getter)Package_get_digest,
+ "checksum",
+ (getter)Package_get_checksum,
NULL,
NULL,
NULL,
# #
#############################################################################*/
+#include <pakfire/hashes.h>
#include <pakfire/xfer.h>
#include "../testsuite.h"
}
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));
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));
}
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));
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);