From 764ab42ad1db4da9db818bdbf7276736b292c0fb Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Thu, 1 Jun 2023 15:53:02 +0000 Subject: [PATCH] repos: Implement creating a detached signature for databases Signed-off-by: Michael Tremer --- src/_pakfire/pakfire.c | 7 +-- src/libpakfire/include/pakfire/key.h | 1 + src/libpakfire/include/pakfire/repo.h | 2 +- src/libpakfire/key.c | 20 +++++++++ src/libpakfire/repo.c | 61 +++++++++++++++++++++++++-- tests/libpakfire/repo.c | 2 +- 6 files changed, 85 insertions(+), 8 deletions(-) diff --git a/src/_pakfire/pakfire.c b/src/_pakfire/pakfire.c index f41ccaec2..8154a59cd 100644 --- a/src/_pakfire/pakfire.c +++ b/src/_pakfire/pakfire.c @@ -1403,13 +1403,14 @@ static PyObject* Pakfire_open(PakfireObject* self, PyObject* args) { } static PyObject* Pakfire_repo_compose(PakfireObject* self, PyObject* args, PyObject* kwargs) { - char* kwlist[] = { "path", "files", NULL }; + char* kwlist[] = { "path", "files", "key", NULL }; const char* path = NULL; PyObject* list = NULL; + KeyObject* key = NULL; PyObject* ret = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO", kwlist, &path, &list)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|O!", kwlist, &path, &list, &KeyType, &key)) return NULL; // List must be a sequence @@ -1451,7 +1452,7 @@ static PyObject* Pakfire_repo_compose(PakfireObject* self, PyObject* args, PyObj Py_BEGIN_ALLOW_THREADS - int r = pakfire_repo_compose(self->pakfire, path, files); + int r = pakfire_repo_compose(self->pakfire, path, (key) ? key->key : NULL, files); if (r) { Py_BLOCK_THREADS PyErr_SetFromErrno(PyExc_OSError); diff --git a/src/libpakfire/include/pakfire/key.h b/src/libpakfire/include/pakfire/key.h index ecc6c98bd..286e35637 100644 --- a/src/libpakfire/include/pakfire/key.h +++ b/src/libpakfire/include/pakfire/key.h @@ -60,6 +60,7 @@ int pakfire_key_import_from_string(struct pakfire_key** key, int pakfire_key_sign(struct pakfire_key* key, FILE* f, const void* data, const size_t length, const char* comment); +int pakfire_key_signf(struct pakfire_key* key, FILE* s, FILE* f, const char* comment); int pakfire_key_verify(struct pakfire_key* key, FILE* f, const void* data, const size_t length); diff --git a/src/libpakfire/include/pakfire/repo.h b/src/libpakfire/include/pakfire/repo.h index 44096f9fd..982e51ca4 100644 --- a/src/libpakfire/include/pakfire/repo.h +++ b/src/libpakfire/include/pakfire/repo.h @@ -90,7 +90,7 @@ int pakfire_repo_refresh(struct pakfire_repo* repo, int force); // Compose int pakfire_repo_compose(struct pakfire* pakfire, const char* path, - const char** files); + struct pakfire_key* key, const char** files); #ifdef PAKFIRE_PRIVATE diff --git a/src/libpakfire/key.c b/src/libpakfire/key.c index 803045637..d78b2ca36 100644 --- a/src/libpakfire/key.c +++ b/src/libpakfire/key.c @@ -871,6 +871,26 @@ ERROR: return r; } +int pakfire_key_signf(struct pakfire_key* key, FILE* s, FILE* f, const char* comment) { + char* buffer = NULL; + size_t length = 0; + int r; + + // Load the entire content into memory + r = pakfire_read_file_into_buffer(f, &buffer, &length); + if (r) + goto ERROR; + + // Sign! + r = pakfire_key_sign(key, s, buffer, length, comment); + +ERROR: + if (buffer) + free(buffer); + + return r; +} + static int pakfire_key_read_signature(struct pakfire_key* key, struct pakfire_key_signature* signature, FILE* f) { void* buffer = NULL; diff --git a/src/libpakfire/repo.c b/src/libpakfire/repo.c index f9c099a6d..1055ce180 100644 --- a/src/libpakfire/repo.c +++ b/src/libpakfire/repo.c @@ -1439,7 +1439,51 @@ ERROR: return r; } -static int pakfire_repo_write_metadata(struct pakfire_repo* repo) { +static int pakfire_repo_sign_database(struct pakfire_repo* repo, struct pakfire_key* key, + const char* database_path) { + char signature_path[PATH_MAX]; + FILE* f = NULL; + FILE* s = NULL; + int r; + + // Compose the signature path + r = pakfire_string_format(signature_path, "%s.sig", database_path); + if (r) + return r; + + // Open the signature file for writing + s = fopen(signature_path, "w"); + if (!s) { + ERROR(repo->pakfire, "Could not open %s for writing: %m\n", signature_path); + r = 1; + goto ERROR; + } + + // Open the database for reading + f = fopen(database_path, "r"); + if (!f) { + ERROR(repo->pakfire, "Could not open %s for reading: %m\n", database_path); + r = 1; + goto ERROR; + } + + // Create the signature + r = pakfire_key_signf(key, s, f, "Database Signature"); + if (r) { + ERROR(repo->pakfire, "Could not sign the database: %m\n"); + goto ERROR; + } + +ERROR: + if (f) + fclose(f); + if (s) + fclose(s); + + return r; +} + +static int pakfire_repo_write_metadata(struct pakfire_repo* repo, struct pakfire_key* key) { struct json_object* repomd = NULL; FILE* f = NULL; int r = 1; @@ -1462,6 +1506,15 @@ static int pakfire_repo_write_metadata(struct pakfire_repo* repo) { if (r) return r; + // Sign the database + if (key) { + r = pakfire_repo_sign_database(repo, key, database); + if (r) { + ERROR(repo->pakfire, "Could not sign the database: %m\n"); + goto ERROR; + } + } + // Compose JSON object repomd = json_object_new_object(); if (!repomd) { @@ -1550,7 +1603,7 @@ ERROR: } PAKFIRE_EXPORT int pakfire_repo_compose(struct pakfire* pakfire, const char* path, - const char** files) { + struct pakfire_key* key, const char** files) { struct pakfire_repo* repo = NULL; char realpath[PATH_MAX]; char baseurl[PATH_MAX]; @@ -1562,6 +1615,8 @@ PAKFIRE_EXPORT int pakfire_repo_compose(struct pakfire* pakfire, const char* pat return 1; } + // XXX Check if the key is a secret key + size_t num_files = 0; // Count files @@ -1662,7 +1717,7 @@ OUT: } // Write metadata to disk - r = pakfire_repo_write_metadata(repo); + r = pakfire_repo_write_metadata(repo, key); if (r) goto ERROR; diff --git a/tests/libpakfire/repo.c b/tests/libpakfire/repo.c index 7bd32d7d9..1b6928076 100644 --- a/tests/libpakfire/repo.c +++ b/tests/libpakfire/repo.c @@ -90,7 +90,7 @@ static int test_compose(const struct test* t) { // Compose the repository ASSERT_SUCCESS( - pakfire_repo_compose(t->pakfire, path, files) + pakfire_repo_compose(t->pakfire, path, NULL, files) ); // Everything passed -- 2.39.5