sshkey: Add support for parsing keys from files
This commit is contained in:
@@ -13,6 +13,10 @@
|
|||||||
* for more details.
|
* for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "sshkey_builder.h"
|
#include "sshkey_builder.h"
|
||||||
|
|
||||||
#include <asn1/oid.h>
|
#include <asn1/oid.h>
|
||||||
@@ -124,12 +128,85 @@ static sshkey_public_key_t *parse_public_key(chunk_t blob)
|
|||||||
return NULL;
|
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.
|
* See header.
|
||||||
*/
|
*/
|
||||||
sshkey_public_key_t *sshkey_public_key_load(key_type_t type, va_list args)
|
sshkey_public_key_t *sshkey_public_key_load(key_type_t type, va_list args)
|
||||||
{
|
{
|
||||||
chunk_t blob = chunk_empty;
|
chunk_t blob = chunk_empty;
|
||||||
|
char *file = NULL;
|
||||||
|
int fd = -1;
|
||||||
|
|
||||||
while (TRUE)
|
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:
|
case BUILD_BLOB_SSHKEY:
|
||||||
blob = va_arg(args, chunk_t);
|
blob = va_arg(args, chunk_t);
|
||||||
continue;
|
continue;
|
||||||
|
case BUILD_FROM_FILE:
|
||||||
|
file = va_arg(args, char*);
|
||||||
|
continue;
|
||||||
|
case BUILD_FROM_FD:
|
||||||
|
fd = va_arg(args, int);
|
||||||
|
continue;
|
||||||
case BUILD_END:
|
case BUILD_END:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -145,9 +228,17 @@ sshkey_public_key_t *sshkey_public_key_load(key_type_t type, va_list args)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (blob.ptr && type == KEY_ANY)
|
if (blob.ptr)
|
||||||
{
|
{
|
||||||
return parse_public_key(blob);
|
return parse_public_key(blob);
|
||||||
}
|
}
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
return load_from_file(file);
|
||||||
|
}
|
||||||
|
if (fd != -1)
|
||||||
|
{
|
||||||
|
return load_from_fd(fd);
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user