]> git.ipfire.org Git - pakfire.git/commitdiff
key: Refactor generating keys
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 7 Jul 2021 18:15:58 +0000 (18:15 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 7 Jul 2021 18:15:58 +0000 (18:15 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/pakfire.c
src/libpakfire/include/pakfire/key.h
src/libpakfire/key.c
src/scripts/pakfire.in

index d38cebb68c749a47643a566abbae17e787be91e0..56facb85ea601efb2d0da28b296f45e2b8127c2e 100644 (file)
@@ -450,14 +450,21 @@ static PyObject* Pakfire_get_key(PakfireObject* self, PyObject* args) {
        return new_key(&KeyType, key);
 }
 
-static PyObject* Pakfire_generate_key(PakfireObject* self, PyObject* args) {
+static PyObject* Pakfire_generate_key(PakfireObject* self, PyObject* args, PyObject* kwds) {
+       char* kwlist[] = { "userid", "algorithm", NULL };
+       struct pakfire_key* key = NULL;
        const char* userid = NULL;
+       const char* algo = NULL;
 
-       if (!PyArg_ParseTuple(args, "s", &userid))
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|$z", kwlist, &userid, &algo))
                return NULL;
 
-       struct pakfire_key* key = pakfire_key_generate(self->pakfire, userid);
-       assert(key);
+       // Generate a new key
+       int r = pakfire_key_generate(&key, self->pakfire, algo, userid);
+       if (r) {
+               PyErr_SetFromErrno(PyExc_OSError);
+               return NULL;
+       }
 
        return new_key(&KeyType, key);
 }
@@ -1003,7 +1010,7 @@ static struct PyMethodDef Pakfire_methods[] = {
        {
                "generate_key",
                (PyCFunction)Pakfire_generate_key,
-               METH_VARARGS,
+               METH_VARARGS|METH_KEYWORDS,
                NULL
        },
        {
index 4a93e31feba211aac0572151913b2154f452270f..49329952163e42879a79b0c8c9654febb606d19f 100644 (file)
@@ -49,7 +49,8 @@ time_t pakfire_key_get_created(struct pakfire_key* key);
 time_t pakfire_key_get_expires(struct pakfire_key* key);
 int pakfire_key_is_revoked(struct pakfire_key* key);
 
-struct pakfire_key* pakfire_key_generate(Pakfire pakfire, const char* userid);
+int pakfire_key_generate(struct pakfire_key** key, Pakfire pakfire,
+       const char* algo, const char* userid);
 char* pakfire_key_export(struct pakfire_key* key, pakfire_key_export_mode_t mode);
 struct pakfire_key** pakfire_key_import(Pakfire pakfire, const char* data);
 
index 21f22c343f8f2982bb9b7a5bb67333bbcd28604d..5659efaa7d51ae754229d587404ee6ae6ca747a0 100644 (file)
@@ -34,8 +34,6 @@
 #include <pakfire/private.h>
 #include <pakfire/util.h>
 
-#define DEFAULT_KEY_SIZE "rsa4096"
-
 struct pakfire_key {
        Pakfire pakfire;
        int nrefs;
@@ -189,34 +187,44 @@ PAKFIRE_EXPORT int pakfire_key_is_revoked(struct pakfire_key* key) {
        return key->gpgkey->subkeys->revoked;
 }
 
-PAKFIRE_EXPORT struct pakfire_key* pakfire_key_generate(Pakfire pakfire, const char* userid) {
-       gpgme_ctx_t gpgctx = pakfire_get_gpgctx(pakfire);
-
-       unsigned int flags = 0;
+PAKFIRE_EXPORT int pakfire_key_generate(struct pakfire_key** key, Pakfire pakfire,
+               const char* algo, const char* userid) {
+       // Reset key
+       *key = NULL;
 
-       // Key should be able to be used to sign
-       flags |= GPGME_CREATE_SIGN;
-
-       // Don't set a password
-       flags |= GPGME_CREATE_NOPASSWD;
+       // Fetch GPGME context
+       gpgme_ctx_t gpgctx = pakfire_get_gpgctx(pakfire);
+       if (!gpgctx)
+               return 1;
 
-       // The key should never expire
-       flags |= GPGME_CREATE_NOEXPIRE;
+       const unsigned int flags =
+               // Key should be able to be used to sign
+               GPGME_CREATE_SIGN |
+               // Don't set a password
+               GPGME_CREATE_NOPASSWD |
+               // The key should never expire
+               GPGME_CREATE_NOEXPIRE;
 
        // Generate the key
        gpgme_error_t error = gpgme_op_createkey(gpgctx, userid,
-               DEFAULT_KEY_SIZE, 0, 0, NULL, flags);
+               algo, 0, 0, NULL, flags);
 
        if (error != GPG_ERR_NO_ERROR) {
                ERROR(pakfire, "%s\n", gpgme_strerror(error));
-               return NULL;
+               return 1;
        }
 
        // Retrieve the result
        gpgme_genkey_result_t result = gpgme_op_genkey_result(gpgctx);
 
        // Retrieve the key by its fingerprint
-       return pakfire_key_get(pakfire, result->fpr);
+       *key = pakfire_key_get(pakfire, result->fpr);
+       if (!*key) {
+               errno = ENOENT;
+               return 1;
+       }
+
+       return 0;
 }
 
 PAKFIRE_EXPORT char* pakfire_key_export(struct pakfire_key* key, pakfire_key_export_mode_t mode) {
index 0c7466b2248fa91dd689c0717093142ad182ba2d..2b88ce78a96c875525ff8b9b8ac65efc3c4d966d 100644 (file)
@@ -77,6 +77,17 @@ class Cli(object):
                execute.add_argument("command", nargs=argparse.REMAINDER)
                execute.set_defaults(func=self._execute)
 
+               # generate-key
+               generate_key = subparsers.add_parser("generate-key",
+                       help=_("Generate a new key"))
+               generate_key.add_argument("--realname", required=True,
+                       help=_("The real name of the owner of this key"))
+               generate_key.add_argument("--email", required=True,
+                       help=_("The email address of the owner of this key"))
+               generate_key.add_argument("--algorithm",
+                       help=_("Algorithm to use for this key"))
+               generate_key.set_defaults(func=self._generate_key)
+
                # info
                info = subparsers.add_parser("info",
                        help=_("Print some information about the given package(s)"))
@@ -223,6 +234,16 @@ class Cli(object):
 
                return p.execute(args.command, logging_callback=logging_callback)
 
+       def _generate_key(self, p, args):
+               # Generate a new key
+               key = p.generate_key(
+                       "%s <%s>" % (args.realname, args.email),
+                       algorithm=args.algorithm,
+               )
+
+               # Print the generated key
+               print(key)
+
        def _info(self, p, args):
                for pkg in p.search(args.package, name_only=True):
                        s = pkg.dump(long=args.long)