]> git.ipfire.org Git - pakfire.git/commitdiff
package: Refactor checksums/digests
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 20 Sep 2021 09:27:35 +0000 (09:27 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 20 Sep 2021 09:29:06 +0000 (09:29 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/package.c
src/libpakfire/db.c
src/libpakfire/include/pakfire/package.h
src/libpakfire/libpakfire.sym
src/libpakfire/package.c

index 694041840c0d6cea6379724fd116332ecfd8c892..b308dca0df3105f6b98a87c927f5e260a0f2c115 100644 (file)
@@ -193,18 +193,35 @@ static void Package_set_uuid(PackageObject* self, PyObject* value) {
        pakfire_package_set_uuid(self->package, uuid);
 }
 
-static PyObject* Package_get_checksum(PackageObject* self) {
-       const char* checksum = pakfire_package_get_checksum(self->package);
-       if (!checksum)
+static PyObject* Package_get_hexdigest(PackageObject* self, enum pakfire_package_digests type) {
+       const char* hexdigest = pakfire_package_get_hexdigest(self->package, type);
+       if (!hexdigest)
                Py_RETURN_NONE;
 
-       return PyUnicode_FromString(checksum);
+       return PyUnicode_FromString(hexdigest);
 }
 
-static void Package_set_checksum(PackageObject* self, PyObject* value) {
-       const char* checksum = PyUnicode_FromValue(value);
+static PyObject* Package_get_hexdigest_sha256(PackageObject* self) {
+       return Package_get_hexdigest(self, PAKFIRE_PACKAGE_DIGEST_SHA256);
+}
+
+static PyObject* Package_get_hexdigest_sha512(PackageObject* self) {
+       return Package_get_hexdigest(self, PAKFIRE_PACKAGE_DIGEST_SHA512);
+}
+
+static int Package_set_hexdigest(PackageObject* self,
+               enum pakfire_package_digests type, PyObject* value) {
+       const char* hexdigest = PyUnicode_FromValue(value);
+
+       return pakfire_package_set_hexdigest(self->package, type, hexdigest);
+}
 
-       pakfire_package_set_checksum(self->package, checksum);
+static int Package_set_hexdigest_sha256(PackageObject* self, PyObject* value) {
+       return Package_set_hexdigest(self, PAKFIRE_PACKAGE_DIGEST_SHA256, value);
+}
+
+static int Package_set_hexdigest_sha512(PackageObject* self, PyObject* value) {
+       return Package_set_hexdigest(self, PAKFIRE_PACKAGE_DIGEST_SHA512, value);
 }
 
 static PyObject* Package_get_summary(PackageObject* self) {
@@ -690,9 +707,16 @@ static struct PyGetSetDef Package_getsetters[] = {
                NULL
        },
        {
-               "checksum",
-               (getter)Package_get_checksum,
-               (setter)Package_set_checksum,
+               "hexdigest_sha256",
+               (getter)Package_get_hexdigest_sha256,
+               (setter)Package_set_hexdigest_sha256,
+               NULL,
+               NULL
+       },
+       {
+               "hexdigest_sha512",
+               (getter)Package_get_hexdigest_sha512,
+               (setter)Package_set_hexdigest_sha512,
                NULL,
                NULL
        },
index a7976014466c1d2f4a455f190b175d3d31e84764..445254f80659ad992f89565fd8d89ad524776e34 100644 (file)
@@ -244,7 +244,8 @@ static int pakfire_db_create_schema(struct pakfire_db* db) {
                        "filename       TEXT, "
                        "size           INTEGER, "
                        "inst_size      INTEGER, "
-                       "hash1          TEXT, "
+                       "digest_sha512  TEXT, "
+                       "digest_sha256  TEXT, "
                        "license        TEXT, "
                        "summary        TEXT, "
                        "description    TEXT, "
@@ -1010,9 +1011,9 @@ int pakfire_db_add_package(struct pakfire_db* db,
                goto ROLLBACK;
 
        const char* sql = "INSERT INTO packages(name, evr, arch, groups, filename, size, "
-               "inst_size, hash1, license, summary, description, uuid, vendor, build_host, "
-               "build_time, installed, repository, userinstalled) "
-               "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, ?, ?)";
+               "inst_size, digest_sha512, digest_sha256, license, summary, description, uuid, "
+               "vendor, build_host, build_time, installed, repository, userinstalled) "
+               "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, ?, ?)";
 
        // Prepare the statement
        r = sqlite3_prepare_v2(db->handle, sql, strlen(sql), &stmt, NULL);
@@ -1095,19 +1096,28 @@ int pakfire_db_add_package(struct pakfire_db* db,
                goto ROLLBACK;
        }
 
-       // Bind hash1
-       const char* hash1 = pakfire_package_get_checksum(pkg);
+       // Bind digest_sha512
+       const char* digest_sha512 = pakfire_package_get_hexdigest(pkg, PAKFIRE_PACKAGE_DIGEST_SHA512);
+
+       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;
+       }
+
+       // Bind digest_sha256
+       const char* digest_sha256 = pakfire_package_get_hexdigest(pkg, PAKFIRE_PACKAGE_DIGEST_SHA256);
 
-       r = sqlite3_bind_text(stmt, 8, hash1, -1, NULL);
+       r = sqlite3_bind_text(stmt, 9, digest_sha256, -1, NULL);
        if (r) {
-               ERROR(db->pakfire, "Could not bind hash1: %s\n", sqlite3_errmsg(db->handle));
+               ERROR(db->pakfire, "Could not bind digest_sha256: %s\n", sqlite3_errmsg(db->handle));
                goto ROLLBACK;
        }
 
        // Bind license
        const char* license = pakfire_package_get_license(pkg);
 
-       r = sqlite3_bind_text(stmt, 9, license, -1, NULL);
+       r = sqlite3_bind_text(stmt, 10, license, -1, NULL);
        if (r) {
                ERROR(db->pakfire, "Could not bind license: %s\n", sqlite3_errmsg(db->handle));
                goto ROLLBACK;
@@ -1116,7 +1126,7 @@ int pakfire_db_add_package(struct pakfire_db* db,
        // Bind summary
        const char* summary = pakfire_package_get_summary(pkg);
 
-       r = sqlite3_bind_text(stmt, 10, summary, -1, NULL);
+       r = sqlite3_bind_text(stmt, 11, summary, -1, NULL);
        if (r) {
                ERROR(db->pakfire, "Could not bind summary: %s\n", sqlite3_errmsg(db->handle));
                goto ROLLBACK;
@@ -1125,7 +1135,7 @@ int pakfire_db_add_package(struct pakfire_db* db,
        // Bind description
        const char* description = pakfire_package_get_description(pkg);
 
-       r = sqlite3_bind_text(stmt, 11, description, -1, NULL);
+       r = sqlite3_bind_text(stmt, 12, description, -1, NULL);
        if (r) {
                ERROR(db->pakfire, "Could not bind description: %s\n", sqlite3_errmsg(db->handle));
                goto ROLLBACK;
@@ -1134,7 +1144,7 @@ int pakfire_db_add_package(struct pakfire_db* db,
        // Bind uuid
        const char* uuid = pakfire_package_get_uuid(pkg);
 
-       r = sqlite3_bind_text(stmt, 12, uuid, -1, NULL);
+       r = sqlite3_bind_text(stmt, 13, uuid, -1, NULL);
        if (r) {
                ERROR(db->pakfire, "Could not bind uuid: %s\n", sqlite3_errmsg(db->handle));
                goto ROLLBACK;
@@ -1143,7 +1153,7 @@ int pakfire_db_add_package(struct pakfire_db* db,
        // Bind vendor
        const char* vendor = pakfire_package_get_vendor(pkg);
 
-       r = sqlite3_bind_text(stmt, 13, vendor, -1, NULL);
+       r = sqlite3_bind_text(stmt, 14, vendor, -1, NULL);
        if (r) {
                ERROR(db->pakfire, "Could not bind vendor: %s\n", sqlite3_errmsg(db->handle));
                goto ROLLBACK;
@@ -1152,7 +1162,7 @@ int pakfire_db_add_package(struct pakfire_db* db,
        // Bind build_host
        const char* build_host = pakfire_package_get_build_host(pkg);
 
-       r = sqlite3_bind_text(stmt, 14, build_host, -1, NULL);
+       r = sqlite3_bind_text(stmt, 15, build_host, -1, NULL);
        if (r) {
                ERROR(db->pakfire, "Could not bind build_host: %s\n", sqlite3_errmsg(db->handle));
                goto ROLLBACK;
@@ -1161,7 +1171,7 @@ int pakfire_db_add_package(struct pakfire_db* db,
        // Bind build_time
        time_t build_time = pakfire_package_get_build_time(pkg);
 
-       r = sqlite3_bind_int64(stmt, 15, build_time);
+       r = sqlite3_bind_int64(stmt, 16, build_time);
        if (r) {
                ERROR(db->pakfire, "Could not bind build_time: %s\n", sqlite3_errmsg(db->handle));
                goto ROLLBACK;
@@ -1173,19 +1183,19 @@ int pakfire_db_add_package(struct pakfire_db* db,
                const char* repo_name = pakfire_repo_get_name(repo);
                pakfire_repo_unref(repo);
 
-               r = sqlite3_bind_text(stmt, 16, repo_name, -1, NULL);
+               r = sqlite3_bind_text(stmt, 17, repo_name, -1, NULL);
                if (r)
                        goto ROLLBACK;
 
        // No repository?
        } else {
-               r = sqlite3_bind_null(stmt, 16);
+               r = sqlite3_bind_null(stmt, 17);
                if (r)
                        goto ROLLBACK;
        }
 
        // installed by the user?
-       r = sqlite3_bind_int(stmt, 17, userinstalled);
+       r = sqlite3_bind_int(stmt, 18, userinstalled);
        if (r) {
                ERROR(db->pakfire, "Could not bind userinstalled: %s\n", sqlite3_errmsg(db->handle));
                goto ROLLBACK;
@@ -1411,67 +1421,73 @@ static int pakfire_db_load_package(struct pakfire_db* db, struct pakfire_repo* r
                pakfire_package_set_installsize(pkg, size);
        }
 
-       // Hash 1
-       const char* hash1 = (const char*)sqlite3_column_text(stmt, 8);
-       if (hash1) {
-               pakfire_package_set_checksum(pkg, hash1);
+       // Digest SHA512
+       const char* digest_sha512 = (const char*)sqlite3_column_text(stmt, 8);
+       if (digest_sha512) {
+               pakfire_package_set_hexdigest(pkg, PAKFIRE_PACKAGE_DIGEST_SHA512, digest_sha512);
+       }
+
+       // Digest SHA256
+       const char* digest_sha256 = (const char*)sqlite3_column_text(stmt, 9);
+       if (digest_sha256) {
+               pakfire_package_set_hexdigest(pkg, PAKFIRE_PACKAGE_DIGEST_SHA256, digest_sha256);
        }
 
        // License
-       const char* license = (const char*)sqlite3_column_text(stmt, 9);
+       const char* license = (const char*)sqlite3_column_text(stmt, 10);
        if (license) {
                pakfire_package_set_license(pkg, license);
        }
 
        // Summary
-       const char* summary = (const char*)sqlite3_column_text(stmt, 10);
+       const char* summary = (const char*)sqlite3_column_text(stmt, 11);
        if (summary) {
                pakfire_package_set_summary(pkg, summary);
        }
 
        // Description
-       const char* description = (const char*)sqlite3_column_text(stmt, 11);
+       const char* description = (const char*)sqlite3_column_text(stmt, 12);
        if (description) {
                pakfire_package_set_description(pkg, description);
        }
 
        // UUID
-       const char* uuid = (const char*)sqlite3_column_text(stmt, 12);
+       const char* uuid = (const char*)sqlite3_column_text(stmt, 13);
        if (uuid) {
                pakfire_package_set_uuid(pkg, uuid);
        }
 
        // Vendor
-       const char* vendor = (const char*)sqlite3_column_text(stmt, 13);
+       const char* vendor = (const char*)sqlite3_column_text(stmt, 14);
        if (vendor) {
                pakfire_package_set_vendor(pkg, vendor);
        }
 
        // Build Host
-       const char* build_host = (const char*)sqlite3_column_text(stmt, 14);
+       const char* build_host = (const char*)sqlite3_column_text(stmt, 15);
        if (build_host) {
                pakfire_package_set_build_host(pkg, build_host);
        }
 
        // Build Time
-       time_t build_time = sqlite3_column_int64(stmt, 15);
+       time_t build_time = sqlite3_column_int64(stmt, 16);
        if (build_time) {
                pakfire_package_set_build_time(pkg, build_time);
        }
 
        // Install Time
-       time_t install_time = sqlite3_column_int64(stmt, 16);
+       time_t install_time = sqlite3_column_int64(stmt, 17);
        if (install_time) {
                pakfire_package_set_install_time(pkg, install_time);
        }
 
        // installed by user?
-       int userinstalled = sqlite3_column_int(stmt, 17);
+       int userinstalled = sqlite3_column_int(stmt, 18);
        if (userinstalled)
                pakfire_db_add_userinstalled(db->pakfire, name);
 
        // Files
-       const char* files = (const char*)sqlite3_column_text(stmt, 18);
+       const char* files = (const char*)sqlite3_column_text(stmt, 19);
        if (files) {
                r = pakfire_package_set_filelist_from_string(pkg, files);
                if (r)
@@ -1484,15 +1500,15 @@ static int pakfire_db_load_package(struct pakfire_db* db, struct pakfire_repo* r
                unsigned int field;
                void (*func)(struct pakfire_package* pkg, const char* dep);
        } dependencies[] = {
-               { 19, pakfire_package_add_provides },
-               { 20, pakfire_package_add_prerequires },
-               { 21, pakfire_package_add_requires },
-               { 22, pakfire_package_add_conflicts },
-               { 23, pakfire_package_add_obsoletes },
-               { 24, pakfire_package_add_recommends },
-               { 25, pakfire_package_add_suggests },
-               { 26, pakfire_package_add_supplements },
-               { 27, pakfire_package_add_enhances },
+               { 20, pakfire_package_add_provides },
+               { 21, pakfire_package_add_prerequires },
+               { 22, pakfire_package_add_requires },
+               { 23, pakfire_package_add_conflicts },
+               { 24, pakfire_package_add_obsoletes },
+               { 25, pakfire_package_add_recommends },
+               { 26, pakfire_package_add_suggests },
+               { 27, pakfire_package_add_supplements },
+               { 28, pakfire_package_add_enhances },
                { 0, NULL },
        };
 
@@ -1528,9 +1544,9 @@ int pakfire_db_load(struct pakfire_db* db, struct pakfire_repo* repo) {
 
        const char* sql =
                "SELECT "
-                       "name, evr, arch, id, groups, filename, size, inst_size, hash1, license, "
-                       "summary, description, uuid, vendor, build_host, build_time, "
-                       "strftime('%s', installed) AS installed, userinstalled, "
+                       "name, evr, arch, id, groups, filename, size, inst_size, "
+                       "digest_sha512, digest_sha256, license, summary, description, uuid, vendor, "
+                       "build_host, build_time, strftime('%s', installed) AS installed, userinstalled, "
                        "("
                                "SELECT group_concat(path, '\n') FROM files WHERE files.pkg = packages.id"
                        ") AS files, "
index 61b802ebcdc0a472e14ccb7ccbc15bf38fc0be69..990f69243c2a3e3fa7034a8f456a92e2b86b537a 100644 (file)
@@ -30,6 +30,11 @@ struct pakfire_package;
 #include <pakfire/pakfire.h>
 #include <pakfire/repo.h>
 
+enum pakfire_package_digests {
+       PAKFIRE_PACKAGE_DIGEST_SHA256,
+       PAKFIRE_PACKAGE_DIGEST_SHA512,
+};
+
 struct pakfire_package* pakfire_package_create(struct pakfire* pakfire, struct pakfire_repo* repo,
        const char* name, const char* evr, const char* arch);
 
@@ -51,8 +56,14 @@ void pakfire_package_set_arch(struct pakfire_package* pkg, const char* arch);
 
 const char* pakfire_package_get_uuid(struct pakfire_package* pkg);
 void pakfire_package_set_uuid(struct pakfire_package* pkg, const char* uuid);
-const char* pakfire_package_get_checksum(struct pakfire_package* pkg);
-void pakfire_package_set_checksum(struct pakfire_package* pkg, const char* checksum);
+const unsigned char* pakfire_package_get_digest(struct pakfire_package* pkg,
+       enum pakfire_package_digests type);
+const char* pakfire_package_get_hexdigest(struct pakfire_package* pkg,
+       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,
+       enum pakfire_package_digests type, const char* hexdigest);
 const char* pakfire_package_get_summary(struct pakfire_package* pkg);
 void pakfire_package_set_summary(struct pakfire_package* pkg, const char* summary);
 const char* pakfire_package_get_description(struct pakfire_package* pkg);
index 8302a91e38ffb4cf5b3d7c1c439deabfbb45f586..aadbb9fb2f84f7c6481678ed3d849fc9428be53b 100644 (file)
@@ -140,15 +140,16 @@ global:
        pakfire_package_get_build_id;
        pakfire_package_get_build_time;
        pakfire_package_get_cache_path;
-       pakfire_package_get_checksum;
        pakfire_package_get_conflicts;
        pakfire_package_get_description;
+       pakfire_package_get_digest;
        pakfire_package_get_downloadsize;
        pakfire_package_get_enhances;
        pakfire_package_get_evr;
        pakfire_package_get_filelist;
        pakfire_package_get_filename;
        pakfire_package_get_groups;
+       pakfire_package_get_hexdigest;
        pakfire_package_get_license;
        pakfire_package_get_location;
        pakfire_package_get_installsize;
@@ -185,6 +186,7 @@ global:
        pakfire_package_set_filelist;
        pakfire_package_set_filename;
        pakfire_package_set_groups;
+       pakfire_package_set_hexdigest;
        pakfire_package_set_installsize;
        pakfire_package_set_install_time;
        pakfire_package_set_license;
index 6595779bd0257e5aa6ba1429ca60b72707eb1280..0fcd6353c323e8532f6781ac2cc49a87f038ef92 100644 (file)
@@ -375,12 +375,105 @@ PAKFIRE_EXPORT void pakfire_package_set_uuid(struct pakfire_package* pkg, const
        pakfire_package_set_string(pkg, SOLVABLE_PKGID, uuid);
 }
 
-PAKFIRE_EXPORT const char* pakfire_package_get_checksum(struct pakfire_package* pkg) {
-       return pakfire_package_get_string(pkg, SOLVABLE_CHECKSUM);
+static Id pakfire_package_digest2id(enum pakfire_package_digests type) {
+       Id id = 0;
+
+       switch (type) {
+               case PAKFIRE_PACKAGE_DIGEST_SHA256:
+                       id = REPOKEY_TYPE_SHA256;
+                       break;
+
+               case PAKFIRE_PACKAGE_DIGEST_SHA512:
+                       id = REPOKEY_TYPE_SHA512;
+                       break;
+       }
+
+       // Type is invalid
+       if (!id)
+               errno = EINVAL;
+
+       return id;
+}
+
+PAKFIRE_EXPORT const unsigned char* pakfire_package_get_digest(
+               struct pakfire_package* pkg, enum pakfire_package_digests type) {
+       Solvable* s = get_solvable(pkg);
+
+       Id id = pakfire_package_digest2id(type);
+       if (!id)
+               return NULL;
+
+       return solvable_lookup_bin_checksum(s, SOLVABLE_CHECKSUM, &id);
+}
+
+PAKFIRE_EXPORT const char* pakfire_package_get_hexdigest(
+               struct pakfire_package* pkg, enum pakfire_package_digests type) {
+       Solvable* s = get_solvable(pkg);
+
+       Id id = pakfire_package_digest2id(type);
+       if (!id)
+               return NULL;
+
+       return solvable_lookup_checksum(s, SOLVABLE_CHECKSUM, &id);
+}
+
+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;
+       int r = 1;
+
+       Id id = pakfire_package_digest2id(type);
+       if (!id)
+               return 1;
+
+       struct pakfire_repo* repo = pakfire_package_get_repo(pkg);
+
+       Repodata* data = pakfire_repo_get_repodata(repo);
+       if (!data)
+               goto ERROR;
+
+       repodata_set_bin_checksum(data, s - pool->solvables, SOLVABLE_CHECKSUM, id, digest);
+
+       // Success
+       r = 0;
+
+ERROR:
+       pakfire_repo_unref(repo);
+
+       return r;
 }
 
-PAKFIRE_EXPORT void pakfire_package_set_checksum(struct pakfire_package* pkg, const char* checksum) {
-       pakfire_package_set_string(pkg, SOLVABLE_CHECKSUM, checksum);
+static size_t pakfire_package_digest_length(enum pakfire_package_digests digest) {
+       switch (digest) {
+               case PAKFIRE_PACKAGE_DIGEST_SHA256:
+                       return 32;
+
+               case PAKFIRE_PACKAGE_DIGEST_SHA512:
+                       return 64;
+       }
+
+       return 0;
+}
+
+PAKFIRE_EXPORT int pakfire_package_set_hexdigest(struct pakfire_package* pkg,
+               enum pakfire_package_digests type, const char* hexdigest) {
+       size_t digest_length = pakfire_package_digest_length(type);
+
+       if (!digest_length) {
+               errno = EINVAL;
+               return 1;
+       }
+
+       // Allocate a buffer for the binary representation of the digest
+       unsigned char* digest = alloca(digest_length);
+       if (!digest)
+               return 1;
+
+       // Convert from hex to binary
+       __pakfire_unhexlify(digest, digest_length, hexdigest);
+
+       return pakfire_package_set_digest(pkg, type, digest);
 }
 
 PAKFIRE_EXPORT const char* pakfire_package_get_summary(struct pakfire_package* pkg) {
@@ -461,9 +554,9 @@ PAKFIRE_EXPORT void pakfire_package_set_maintainer(struct pakfire_package* pkg,
 
 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_checksum(pkg);
+       const char* checksum = pakfire_package_get_hexdigest(pkg, PAKFIRE_PACKAGE_DIGEST_SHA256);
 
-       if (strlen(checksum) < 3)
+       if (!checksum || strlen(checksum) < 3)
                return 1;
 
        return pakfire_make_cache_path(pkg->pakfire, pkg->path,
@@ -905,6 +998,16 @@ PAKFIRE_EXPORT char* pakfire_package_dump(struct pakfire_package* pkg, int flags
                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);
+
+               // 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);
+
                // Build time
                time_t build_time = pakfire_package_get_build_time(pkg);
                pakfire_package_dump_add_line_date(&string, _("Build Time"), build_time);