]> git.ipfire.org Git - pakfire.git/commitdiff
keys: Export signing/verification routines in Python
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 1 Jun 2023 18:46:21 +0000 (18:46 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 1 Jun 2023 18:46:21 +0000 (18:46 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/key.c
src/libpakfire/include/pakfire/key.h
src/libpakfire/key.c
src/libpakfire/libpakfire.sym
tests/python/keys.py

index 8c23381c38de810c139aeeb7682ae074bfbc3a47..a1b3f4647fa486c6b948552688fbb5dd804ead8e 100644 (file)
@@ -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 },
 };
index 87b9ad17dac73dc151a7180b88e08c5e63c85d7d..5ccc01c4307ffcb98b3b5b6bdb3110582655e960 100644 (file)
@@ -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
 
index 73115ce9520ecd7e2cd3c82fd0f9ad0b09ae672b..0ab253a7e95bde0b2b4ccfeac9877b422798d4c9 100644 (file)
@@ -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;
 
index e3fdb613e270aa3b400563af7dd6fdaf3efea84b..a342da8d92b8ee84678147c92d9c2b0da3918bfb 100644 (file)
@@ -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;
index 1b2abeed1ff0fe042657a4a1b934630d9bf23898..4ea76b1c77cd30864a422d38ea64b0309882d43c 100755 (executable)
@@ -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()