diff options
Diffstat (limited to 'src/libstrongswan/plugins/sshkey/sshkey_builder.c')
-rw-r--r-- | src/libstrongswan/plugins/sshkey/sshkey_builder.c | 89 |
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; } |