sshkey: Add support for parsing keys from files

This commit is contained in:
Tobias Brunner
2013-09-13 15:23:49 +02:00
parent b2a5317596
commit 075e80368b
@@ -13,6 +13,10 @@
* for more details.
*/
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include "sshkey_builder.h"
#include <asn1/oid.h>
@@ -124,12 +128,85 @@ static sshkey_public_key_t *parse_public_key(chunk_t blob)
return NULL;
}
/**
* 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 FD
*/
static sshkey_public_key_t *load_from_fd(int fd)
{
FILE *stream;
/* dup the FD as it gets closed in fclose() */
fd = dup(fd);
if (fd == -1)
{
return NULL;
}
stream = fdopen(fd, "r");
if (!stream)
{
close(fd);
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;
char *file = NULL;
int fd = -1;
while (TRUE)
{
@@ -138,6 +215,12 @@ sshkey_public_key_t *sshkey_public_key_load(key_type_t type, va_list args)
case BUILD_BLOB_SSHKEY:
blob = va_arg(args, chunk_t);
continue;
case BUILD_FROM_FILE:
file = va_arg(args, char*);
continue;
case BUILD_FROM_FD:
fd = va_arg(args, int);
continue;
case BUILD_END:
break;
default:
@@ -145,9 +228,17 @@ sshkey_public_key_t *sshkey_public_key_load(key_type_t type, va_list args)
}
break;
}
if (blob.ptr && type == KEY_ANY)
if (blob.ptr)
{
return parse_public_key(blob);
}
if (file)
{
return load_from_file(file);
}
if (fd != -1)
{
return load_from_fd(fd);
}
return NULL;
}