}
static PyObject* Package_get_hexdigest(PackageObject* self, enum pakfire_package_digests type) {
- const char* hexdigest = pakfire_package_get_hexdigest(self->package, type);
+ enum pakfire_package_digests digest = PAKFIRE_PACKAGE_DIGEST_NONE;
+
+ const char* hexdigest = pakfire_package_get_hexdigest(self->package, &digest);
if (!hexdigest)
Py_RETURN_NONE;
+ // Is this the requested type?
+ if (digest != type)
+ Py_RETURN_NONE;
+
return PyUnicode_FromString(hexdigest);
}
return buf.st_size;
}
+static int pakfire_archive_calculate_digest(struct pakfire_archive* archive,
+ enum pakfire_package_digests digest, unsigned char* output, size_t* length) {
+ int r = 1;
+
+ const EVP_MD* md = NULL;
+
+ // Select hash function
+ switch (digest) {
+ case PAKFIRE_PACKAGE_DIGEST_SHA512:
+ md = EVP_sha512();
+ break;
+
+ case PAKFIRE_PACKAGE_DIGEST_SHA256:
+ md = EVP_sha256();
+ break;
+
+ default:
+ errno = ENOTSUP;
+ return 1;
+ }
+
+ // Initialize context
+ EVP_MD_CTX* ctx = EVP_MD_CTX_new();
+ if (!ctx) {
+ ERROR(archive->pakfire, "Could not initialize EVP context: %m\n");
+ goto ERROR;
+ }
+
+ r = EVP_DigestInit_ex(ctx, md, NULL);
+ if (r != 1) {
+ ERROR(archive->pakfire, "EVP_DigestInit_ex failed: %s\n",
+ ERR_error_string(ERR_get_error(), NULL));
+ r = 1;
+ goto ERROR;
+ }
+
+ char buffer[64 * 1024];
+
+ // Feed archive into the hash functions
+ while (!feof(archive->f)) {
+ size_t bytes_read = fread(buffer, 1, sizeof(buffer), archive->f);
+
+ if (ferror(archive->f)) {
+ ERROR(archive->pakfire, "Error reading from file: %m\n");
+ goto ERROR;
+ }
+
+ r = EVP_DigestUpdate(ctx, buffer, bytes_read);
+ if (r != 1) {
+ ERROR(archive->pakfire, "EVP_DigestUpdate failed: %s\n",
+ ERR_error_string(ERR_get_error(), NULL));
+ r = 1;
+ goto ERROR;
+ }
+ }
+
+ // Finalise hash function
+ r = EVP_DigestFinal_ex(ctx, output, (unsigned int*)length);
+ if (r != 1) {
+ ERROR(archive->pakfire, "EVP_DigestFinal_ex failed: %s\n",
+ ERR_error_string(ERR_get_error(), NULL));
+ r = 1;
+ goto ERROR;
+ }
+
+ // Success
+ r = 0;
+
+ERROR:
+ // Cleanup
+ if (ctx)
+ EVP_MD_CTX_free(ctx);
+
+ rewind(archive->f);
+
+ return r;
+}
+
/*
Copy all metadata from this archive to the package object
*/
PAKFIRE_EXPORT int pakfire_archive_make_package(struct pakfire_archive* archive,
struct pakfire_repo* repo, struct pakfire_package** package) {
struct pakfire_repo* dummy = NULL;
+ unsigned char digest[EVP_MAX_MD_SIZE];
+ size_t digest_length = 0;
+ int r;
+
+ // Calculate digest
+ r = pakfire_archive_calculate_digest(archive, PAKFIRE_PACKAGE_DIGEST_SHA512,
+ digest, &digest_length);
+ if (r)
+ return r;
// Use dummy repo if no repository was passed
if (!repo) {
pakfire_filelist_unref(filelist);
}
+ // Set digests
+ pakfire_package_set_digest(pkg, PAKFIRE_PACKAGE_DIGEST_SHA512, digest);
+
*package = pkg;
// Cleanup
goto ROLLBACK;
}
- // Bind digest_sha512
- const char* digest_sha512 = pakfire_package_get_hexdigest(pkg, PAKFIRE_PACKAGE_DIGEST_SHA512);
+ enum pakfire_package_digests digest = PAKFIRE_PACKAGE_DIGEST_NONE;
- r = sqlite3_bind_text(stmt, 8, digest_sha512, -1, NULL);
- if (r) {
- ERROR(db->pakfire, "Could not bind digest_sha512: %s\n", sqlite3_errmsg(db->handle));
- goto ROLLBACK;
- }
+ const char* hexdigest = pakfire_package_get_hexdigest(pkg, &digest);
+ switch (digest) {
+ case PAKFIRE_PACKAGE_DIGEST_SHA512:
+ r = sqlite3_bind_text(stmt, 8, hexdigest, -1, NULL);
+ if (r) {
+ ERROR(db->pakfire, "Could not bind digest_sha512: %s\n", sqlite3_errmsg(db->handle));
+ goto ROLLBACK;
+ }
+ break;
- // Bind digest_sha256
- const char* digest_sha256 = pakfire_package_get_hexdigest(pkg, PAKFIRE_PACKAGE_DIGEST_SHA256);
+ case PAKFIRE_PACKAGE_DIGEST_SHA256:
+ r = sqlite3_bind_text(stmt, 9, hexdigest, -1, NULL);
+ if (r) {
+ ERROR(db->pakfire, "Could not bind digest_sha256: %s\n", sqlite3_errmsg(db->handle));
+ goto ROLLBACK;
+ }
- r = sqlite3_bind_text(stmt, 9, digest_sha256, -1, NULL);
- if (r) {
- ERROR(db->pakfire, "Could not bind digest_sha256: %s\n", sqlite3_errmsg(db->handle));
- goto ROLLBACK;
+ case PAKFIRE_PACKAGE_DIGEST_NONE:
+ break;
}
// Bind license
#include <pakfire/repo.h>
enum pakfire_package_digests {
- PAKFIRE_PACKAGE_DIGEST_SHA256,
- PAKFIRE_PACKAGE_DIGEST_SHA512,
+ PAKFIRE_PACKAGE_DIGEST_NONE = 0,
+ PAKFIRE_PACKAGE_DIGEST_SHA256 = 1 << 0,
+ PAKFIRE_PACKAGE_DIGEST_SHA512 = 1 << 1,
};
struct pakfire_package* pakfire_package_create(struct pakfire* pakfire, struct pakfire_repo* repo,
const char* pakfire_package_get_uuid(struct pakfire_package* pkg);
void pakfire_package_set_uuid(struct pakfire_package* pkg, const char* uuid);
const unsigned char* pakfire_package_get_digest(struct pakfire_package* pkg,
- enum pakfire_package_digests type);
+ enum pakfire_package_digests* type);
const char* pakfire_package_get_hexdigest(struct pakfire_package* pkg,
- enum pakfire_package_digests type);
+ enum pakfire_package_digests* type);
int pakfire_package_set_digest(struct pakfire_package* pkg,
enum pakfire_package_digests type, const unsigned char* digest);
int pakfire_package_set_hexdigest(struct pakfire_package* pkg,
pakfire_package_set_string(pkg, SOLVABLE_PKGID, uuid);
}
-static Id pakfire_package_digest2id(enum pakfire_package_digests type) {
- Id id = 0;
+static enum pakfire_package_digests pakfire_package_id2digest(Id id) {
+ switch (id) {
+ case REPOKEY_TYPE_SHA512:
+ return PAKFIRE_PACKAGE_DIGEST_SHA512;
- switch (type) {
- case PAKFIRE_PACKAGE_DIGEST_SHA256:
- id = REPOKEY_TYPE_SHA256;
- break;
-
- case PAKFIRE_PACKAGE_DIGEST_SHA512:
- id = REPOKEY_TYPE_SHA512;
- break;
+ case REPOKEY_TYPE_SHA256:
+ return PAKFIRE_PACKAGE_DIGEST_SHA256;
}
- // Type is invalid
- if (!id)
- errno = EINVAL;
-
- return id;
+ return PAKFIRE_PACKAGE_DIGEST_NONE;
}
PAKFIRE_EXPORT const unsigned char* pakfire_package_get_digest(
- struct pakfire_package* pkg, enum pakfire_package_digests type) {
+ struct pakfire_package* pkg, enum pakfire_package_digests* type) {
Solvable* s = get_solvable(pkg);
+ Id id;
- Id id = pakfire_package_digest2id(type);
- if (!id)
- return NULL;
+ const unsigned char* checksum = solvable_lookup_bin_checksum(s, SOLVABLE_CHECKSUM, &id);
- return solvable_lookup_bin_checksum(s, SOLVABLE_CHECKSUM, &id);
+ // Convert ID to digest type
+ *type = pakfire_package_id2digest(id);
+ if (!*type) {
+ errno = ENOTSUP;
+ checksum = NULL;
+ }
+
+ return checksum;
}
PAKFIRE_EXPORT const char* pakfire_package_get_hexdigest(
- struct pakfire_package* pkg, enum pakfire_package_digests type) {
+ struct pakfire_package* pkg, enum pakfire_package_digests* type) {
Solvable* s = get_solvable(pkg);
+ Id id;
- Id id = pakfire_package_digest2id(type);
- if (!id)
- return NULL;
+ const char* checksum = solvable_lookup_checksum(s, SOLVABLE_CHECKSUM, &id);
- return solvable_lookup_checksum(s, SOLVABLE_CHECKSUM, &id);
+ // Convert ID to digest type
+ *type = pakfire_package_id2digest(id);
+ if (!*type) {
+ errno = ENOTSUP;
+ checksum = NULL;
+ }
+
+ return checksum;
}
PAKFIRE_EXPORT int pakfire_package_set_digest(struct pakfire_package* pkg,
enum pakfire_package_digests type, const unsigned char* digest) {
Solvable* s = get_solvable(pkg);
Pool* pool = s->repo->pool;
+ Id id;
int r = 1;
- Id id = pakfire_package_digest2id(type);
- if (!id)
- return 1;
+ switch (type) {
+ case PAKFIRE_PACKAGE_DIGEST_SHA256:
+ id = REPOKEY_TYPE_SHA256;
+ break;
+
+ case PAKFIRE_PACKAGE_DIGEST_SHA512:
+ id = REPOKEY_TYPE_SHA512;
+ break;
+
+ default:
+ errno = ENOTSUP;
+ return 1;
+ }
struct pakfire_repo* repo = pakfire_package_get_repo(pkg);
static size_t pakfire_package_digest_length(enum pakfire_package_digests digest) {
switch (digest) {
+ case PAKFIRE_PACKAGE_DIGEST_SHA512:
+ return 64;
+
case PAKFIRE_PACKAGE_DIGEST_SHA256:
return 32;
- case PAKFIRE_PACKAGE_DIGEST_SHA512:
- return 64;
+ case PAKFIRE_PACKAGE_DIGEST_NONE:
+ return 0;
}
return 0;
static int pakfire_package_make_cache_path(struct pakfire_package* pkg) {
const char* filename = pakfire_package_get_filename(pkg);
- const char* checksum = pakfire_package_get_hexdigest(pkg, PAKFIRE_PACKAGE_DIGEST_SHA256);
- if (!checksum || strlen(checksum) < 3)
+ enum pakfire_package_digests digest = PAKFIRE_PACKAGE_DIGEST_NONE;
+ const char* hexdigest = pakfire_package_get_hexdigest(pkg, &digest);
+
+ if (!hexdigest || strlen(hexdigest) < 3)
return 1;
return pakfire_make_cache_path(pkg->pakfire, pkg->path,
- "%c%c/%s/%s", checksum[0], checksum[1], checksum + 2, filename);
+ "%c%c/%s/%s", hexdigest[0], hexdigest[1], hexdigest + 2, filename);
}
PAKFIRE_EXPORT const char* pakfire_package_get_path(struct pakfire_package* pkg) {
if (build_id)
pakfire_package_dump_add_line(&string, _("Build ID"), build_id);
- // Digest SHA512
- const char* digest_sha512 = pakfire_package_get_hexdigest(pkg, PAKFIRE_PACKAGE_DIGEST_SHA512);
- if (digest_sha512)
- pakfire_package_dump_add_line(&string, _("SHA512 Digest"), digest_sha512);
+ enum pakfire_package_digests digest = PAKFIRE_PACKAGE_DIGEST_NONE;
+
+ // Digest
+ const char* hexdigest = pakfire_package_get_hexdigest(pkg, &digest);
+ switch (digest) {
+ case PAKFIRE_PACKAGE_DIGEST_SHA512:
+ pakfire_package_dump_add_line(&string, _("SHA512 Digest"), hexdigest);
+ break;
- // Digest SHA256
- const char* digest_sha256 = pakfire_package_get_hexdigest(pkg, PAKFIRE_PACKAGE_DIGEST_SHA256);
- if (digest_sha256)
- pakfire_package_dump_add_line(&string, _("SHA256 Digest"), digest_sha256);
+ case PAKFIRE_PACKAGE_DIGEST_SHA256:
+ pakfire_package_dump_add_line(&string, _("SHA256 Digest"), hexdigest);
+ break;
+
+ case PAKFIRE_PACKAGE_DIGEST_NONE:
+ break;
+ }
// Build time
time_t build_time = pakfire_package_get_build_time(pkg);