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;
}