]> git.ipfire.org Git - pakfire.git/commitdiff
keys: Refactor importing keys
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 1 Jun 2023 14:10:10 +0000 (14:10 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 1 Jun 2023 14:51:05 +0000 (14:51 +0000)
This is now using the base64 decoder and insists on reading the comment
line.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/key.c

index d7a07c95e5dffbe2b59ea0e5be18881ec5cc6249..47e546fdd09d023fbc88b137fc38d3c7dcacbb55 100644 (file)
@@ -364,66 +364,81 @@ ERROR:
 
 PAKFIRE_EXPORT int pakfire_key_import(struct pakfire_key** key,
                struct pakfire* pakfire, FILE* f) {
-       BIO* bio = NULL;
-       BIO* b64 = NULL;
-       char buffer[4096];
-       size_t bytes_read = 0;
+       void* buffer = NULL;
+       size_t buffer_length = 0;
        int r;
 
-       // Setup the base64 decoder
-       b64 = BIO_new(BIO_f_base64());
-       if (!b64) {
-               ERROR(pakfire, "Could not setup the base64 decoder\n");
-               r = 1;
-               goto ERROR;
-       }
-
-       bio = BIO_new_fp(f, BIO_NOCLOSE);
-       if (!bio) {
-               ERROR(pakfire, "Could not open BIO\n");
-               r = 1;
-               goto ERROR;
-       }
-
-       BIO_push(b64, bio);
-
-       // Try to read everything into the buffer
-       r = BIO_read_ex(b64, buffer, sizeof(buffer), &bytes_read);
-       if (r < 0) {
-               ERROR(pakfire, "Could not read data\n");
-               r = 1;
-               goto ERROR;
-       }
-
-       const struct pakfire_key_private_key* private_key =
-               (const struct pakfire_key_private_key*)buffer;
-       const struct pakfire_key_public_key* public_key =
-               (const struct pakfire_key_public_key*)buffer;
+       char* line = NULL;
+       size_t length = 0;
+       size_t lineno = 0;
 
-       // Try to find what we have read
-       switch (bytes_read) {
-
-               // Import a private key
-               case sizeof(*private_key):
-                       r = pakfire_key_import_secret_key(key, pakfire, private_key);
+       for (;;) {
+               ssize_t bytes_read = getline(&line, &length, f);
+               if (bytes_read < 0)
                        break;
 
-               // Import a public key
-               case sizeof(*public_key):
-                       r = pakfire_key_import_public_key(key, pakfire, public_key);
-                       break;
-
-               default:
-                       ERROR(pakfire, "Unsupported key type\n");
-                       r = 1;
-                       goto ERROR;
+               // Increment the line counter
+               lineno++;
+
+               switch (lineno) {
+                       // The first line must start with "untrusted comment:"
+                       case 1:
+                               if (!pakfire_string_startswith(line, "untrusted comment:")) {
+                                       ERROR(pakfire, "The first line must start with 'untrusted comment:'\n");
+                                       errno = EINVAL;
+                                       r = 1;
+                                       goto ERROR;
+                               }
+                               break;
+
+                       // The second line should hold the key
+                       case 2:
+                               // Decode the key
+                               r = pakfire_b64decode(pakfire, &buffer, &buffer_length, line);
+                               if (r) {
+                                       ERROR(pakfire, "Could not decode the key: %m\n");
+                                       errno = EINVAL;
+                                       r = 1;
+                                       goto ERROR;
+                               }
+
+                               // What kind of key do we have?
+                               switch (buffer_length) {
+                                       // Public Key
+                                       case sizeof(struct pakfire_key_public_key):
+                                               r = pakfire_key_import_public_key(key, pakfire,
+                                                       (struct pakfire_key_public_key*)buffer);
+                                               break;
+
+                                       // Private Key
+                                       case sizeof(struct pakfire_key_private_key):
+                                               r = pakfire_key_import_secret_key(key, pakfire,
+                                                       (struct pakfire_key_private_key*)buffer);
+                                               break;
+
+                                       // Unknown key
+                                       default:
+                                               ERROR(pakfire, "Unsupported key type\n");
+                                               errno = ENOTSUP;
+                                               r = 1;
+                                               goto ERROR;
+                               }
+                               break;
+
+                       // Ignore any further data
+                       default:
+                               break;
+               }
        }
 
+       // Success!
+       r = 0;
+
 ERROR:
-       if (b64)
-               BIO_free(b64);
-       if (bio)
-               BIO_free(bio);
+       if (buffer)
+               free(buffer);
+       if (line)
+               free(line);
 
        return r;
 }