From: Michael Tremer Date: Thu, 1 Jun 2023 18:46:21 +0000 (+0000) Subject: keys: Export signing/verification routines in Python X-Git-Tag: 0.9.29~126 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=28ff41a81d4b1e2aa85eab1c129c644340199456;p=pakfire.git keys: Export signing/verification routines in Python Signed-off-by: Michael Tremer --- diff --git a/src/_pakfire/key.c b/src/_pakfire/key.c index 8c23381c3..a1b3f4647 100644 --- a/src/_pakfire/key.c +++ b/src/_pakfire/key.c @@ -133,12 +133,100 @@ static PyObject* Key_export(KeyObject* self, PyObject* args) { Py_RETURN_NONE; } +static PyObject* Key_sign(KeyObject* self, PyObject* args, PyObject* kwargs) { + char* kwlist[] = { "data", "comment", NULL }; + PyObject* object = NULL; + const char* data = NULL; + Py_ssize_t data_length = 0; + const char* comment = NULL; + char* signature = NULL; + size_t signature_length = 0; + int r; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y#|z", kwlist, + &data, &data_length, &comment)) + return NULL; + + // Create buffer to write the signature to + FILE* f = open_memstream(&signature, &signature_length); + if (!f) { + PyErr_SetFromErrno(PyExc_OSError); + goto ERROR; + } + + // Create the signature + r = pakfire_key_sign(self->key, f, data, data_length, comment); + if (r) { + PyErr_SetFromErrno(PyExc_OSError); + goto ERROR; + } + + object = PyUnicode_FromStringAndSize(signature, signature_length); + +ERROR: + if (f) + fclose(f); + if (signature) + free(signature); + + return object; +} + +static PyObject* Key_verify(KeyObject* self, PyObject* args) { + char* signature = NULL; + const char* data = NULL; + Py_ssize_t data_length = 0; + int r; + + if (!PyArg_ParseTuple(args, "sy#", &signature, &data, &data_length)) + return NULL; + + // Map the signature + FILE* f = fmemopen(signature, strlen(signature), "r"); + if (!f) { + PyErr_SetFromErrno(PyExc_OSError); + r = 1; + goto ERROR; + } + + // Verify the signature + r = pakfire_key_verify(self->key, f, data, data_length); + if (r) { + PyErr_SetFromErrno(PyExc_OSError); + goto ERROR; + } + + // Success! + r = 0; + +ERROR: + if (f) + fclose(f); + + if (r) + return NULL; + + Py_RETURN_TRUE; +} + static struct PyMethodDef Key_methods[] = { { "export", (PyCFunction)Key_export, METH_VARARGS, - NULL + NULL, + }, + { + "sign", + (PyCFunction)Key_sign, + METH_VARARGS|METH_KEYWORDS, + NULL, + }, + { + "verify", + (PyCFunction)Key_verify, + METH_VARARGS, + NULL, }, { NULL }, }; diff --git a/src/libpakfire/include/pakfire/key.h b/src/libpakfire/include/pakfire/key.h index 87b9ad17d..5ccc01c43 100644 --- a/src/libpakfire/include/pakfire/key.h +++ b/src/libpakfire/include/pakfire/key.h @@ -53,16 +53,18 @@ int pakfire_key_import(struct pakfire_key** key, struct pakfire* pakfire, FILE* char* pakfire_key_dump(struct pakfire_key* key); +// Sign +int pakfire_key_sign(struct pakfire_key* key, + FILE* f, const void* data, const size_t length, const char* comment); +int pakfire_key_verify(struct pakfire_key* key, + FILE* f, const void* data, const size_t length); + #ifdef PAKFIRE_PRIVATE int pakfire_key_import_from_string(struct pakfire_key** key, struct pakfire* pakfire, const char* data, const size_t length); -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); #endif diff --git a/src/libpakfire/key.c b/src/libpakfire/key.c index 73115ce95..0ab253a7e 100644 --- a/src/libpakfire/key.c +++ b/src/libpakfire/key.c @@ -829,7 +829,7 @@ ERROR: return r; } -int pakfire_key_sign(struct pakfire_key* key, +PAKFIRE_EXPORT int pakfire_key_sign(struct pakfire_key* key, FILE* f, const void* data, const size_t length, const char* comment) { struct pakfire_key_signature signature = { 0 }; char* s = NULL; @@ -1036,7 +1036,8 @@ ERROR: return r; } -int pakfire_key_verify(struct pakfire_key* key, FILE* f, const void* data, const size_t length) { +PAKFIRE_EXPORT int pakfire_key_verify(struct pakfire_key* key, FILE* f, + const void* data, const size_t length) { struct pakfire_key_signature signature = { 0 }; int r; diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index e3fdb613e..a342da8d9 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -135,7 +135,9 @@ global: pakfire_key_get_id; pakfire_key_import; pakfire_key_ref; + pakfire_key_sign; pakfire_key_unref; + pakfire_key_verify; # jail pakfire_jail_bind; diff --git a/tests/python/keys.py b/tests/python/keys.py index 1b2abeed1..4ea76b1c7 100755 --- a/tests/python/keys.py +++ b/tests/python/keys.py @@ -71,6 +71,20 @@ class KeysTests(unittest.TestCase): # Check for the correct key ID self.assertEqual(key.id, 13863674484496905947) + def test_sign(self): + """ + Generate a new key + """ + key = self.pakfire.generate_key(algorithm=pakfire.PAKFIRE_KEY_ALGO_ED25519) + + data = b"Pakfire" + + # Sign! + signature = key.sign(data, comment="This is a comment") + + # Verify! + self.assertTrue(key.verify(signature, data)) + if __name__ == "__main__": unittest.main()