summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/sshkey/sshkey_builder.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/plugins/sshkey/sshkey_builder.c')
-rw-r--r--src/libstrongswan/plugins/sshkey/sshkey_builder.c89
1 files changed, 86 insertions, 3 deletions
diff --git a/src/libstrongswan/plugins/sshkey/sshkey_builder.c b/src/libstrongswan/plugins/sshkey/sshkey_builder.c
index d6a7c645a..569b0b738 100644
--- a/src/libstrongswan/plugins/sshkey/sshkey_builder.c
+++ b/src/libstrongswan/plugins/sshkey/sshkey_builder.c
@@ -13,6 +13,10 @@
* for more details.
*/
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+
#include "sshkey_builder.h"
#include <asn1/oid.h>
@@ -125,17 +129,88 @@ static sshkey_public_key_t *parse_public_key(chunk_t blob)
}
/**
+ * Load SSH key from a FILE stream, closes the stream
+ */
+static sshkey_public_key_t *load_from_stream(FILE *file)
+{
+ sshkey_public_key_t *public = NULL;
+ chunk_t blob = chunk_empty;
+ enumerator_t *enumerator;
+ char line[1024], *token;
+
+ while (!public && fgets(line, sizeof(line), file))
+ { /* the format is: ssh-[rsa|ecdsa-...] <key(base64)> <identifier> */
+ if (!strpfx(line, "ssh-"))
+ {
+ continue;
+ }
+ enumerator = enumerator_create_token(line, " ", " ");
+ if (enumerator->enumerate(enumerator, &token) &&
+ enumerator->enumerate(enumerator, &token))
+ {
+ blob = chunk_from_base64(chunk_from_str(token), NULL);
+ }
+ enumerator->destroy(enumerator);
+ if (blob.ptr)
+ {
+ public = parse_public_key(blob);
+ chunk_free(&blob);
+ }
+ }
+ fclose(file);
+ return public;
+}
+
+/**
+ * Load SSH key from a blob of data (most likely the content of a file)
+ */
+static sshkey_public_key_t *load_from_blob(chunk_t blob)
+{
+ FILE *stream;
+
+ stream = fmemopen(blob.ptr, blob.len, "r");
+ if (!stream)
+ {
+ return NULL;
+ }
+ return load_from_stream(stream);
+}
+
+/**
+ * Load SSH key from file
+ */
+static sshkey_public_key_t *load_from_file(char *file)
+{
+ FILE *stream;
+
+ stream = fopen(file, "r");
+ if (!stream)
+ {
+ DBG1(DBG_LIB, " opening '%s' failed: %s", file, strerror(errno));
+ return NULL;
+ }
+ return load_from_stream(stream);
+}
+
+/**
* See header.
*/
sshkey_public_key_t *sshkey_public_key_load(key_type_t type, va_list args)
{
- chunk_t blob = chunk_empty;
+ chunk_t sshkey = chunk_empty, blob = chunk_empty;
+ char *file = NULL;
while (TRUE)
{
switch (va_arg(args, builder_part_t))
{
case BUILD_BLOB_SSHKEY:
+ sshkey = va_arg(args, chunk_t);
+ continue;
+ case BUILD_FROM_FILE:
+ file = va_arg(args, char*);
+ continue;
+ case BUILD_BLOB:
blob = va_arg(args, chunk_t);
continue;
case BUILD_END:
@@ -145,9 +220,17 @@ sshkey_public_key_t *sshkey_public_key_load(key_type_t type, va_list args)
}
break;
}
- if (blob.ptr && type == KEY_ANY)
+ if (sshkey.ptr)
+ {
+ return parse_public_key(sshkey);
+ }
+ if (file)
+ {
+ return load_from_file(file);
+ }
+ if (blob.ptr)
{
- return parse_public_key(blob);
+ return load_from_blob(blob);
}
return NULL;
}