added file loading support to pem plugin, using mmap()

This commit is contained in:
Martin Willi
2009-08-26 11:23:48 +02:00
parent 160f4c225d
commit c9db16b7dd
+79 -15
View File
@@ -22,11 +22,15 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <stddef.h> #include <stddef.h>
#include <fcntl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <debug.h> #include <debug.h>
#include <library.h> #include <library.h>
#include <utils/lexparser.h> #include <utils/lexparser.h>
#include <asn1/asn1.h>
#include <crypto/hashers/hasher.h> #include <crypto/hashers/hasher.h>
#include <crypto/crypters/crypter.h> #include <crypto/crypters/crypter.h>
@@ -44,6 +48,8 @@ struct private_builder_t {
credential_type_t type; credential_type_t type;
/** subtype (keytype, certtype) of the credential we build */ /** subtype (keytype, certtype) of the credential we build */
int subtype; int subtype;
/** path to file, if we are reading from a file */
char *file;
/** PEM encoding of the credential */ /** PEM encoding of the credential */
chunk_t pem; chunk_t pem;
/** PEM decryption passphrase, if given */ /** PEM decryption passphrase, if given */
@@ -366,32 +372,84 @@ status_t pem_to_bin(chunk_t *blob, private_builder_t *this, bool *pgp)
} }
} }
/**
* build the credential from a blob
*/
static void *build_from_blob(private_builder_t *this, chunk_t blob)
{
void *cred = NULL;
bool pgp = FALSE;
blob = chunk_clone(blob);
if (!is_asn1(blob))
{
if (pem_to_bin(&blob, this, &pgp) != SUCCESS)
{
chunk_clear(&blob);
return NULL;
}
}
cred = lib->creds->create(lib->creds, this->type, this->subtype,
pgp ? BUILD_BLOB_PGP : BUILD_BLOB_ASN1_DER, blob,
BUILD_END);
chunk_clear(&blob);
return cred;
}
/**
* build the credential from a file
*/
static void *build_from_file(private_builder_t *this, char *file)
{
void *cred = NULL;
struct stat sb;
void *addr;
int fd;
fd = open(file, O_RDONLY);
if (fd == -1)
{
DBG1(" opening '%s' failed: %s", file, strerror(errno));
return NULL;
}
if (fstat(fd, &sb) == -1)
{
DBG1(" getting file size of '%s' failed: %s", file, strerror(errno));
close(fd);
return NULL;
}
addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (addr == MAP_FAILED)
{
DBG1(" mapping '%s' failed: %s", file, strerror(errno));
close(fd);
return NULL;
}
cred = build_from_blob(this, chunk_create(addr, sb.st_size));
munmap(addr, sb.st_size);
close(fd);
return cred;
}
/** /**
* Implementation of builder_t.build * Implementation of builder_t.build
*/ */
static void *build(private_builder_t *this) static void *build(private_builder_t *this)
{ {
bool pgp = FALSE;
void *cred = NULL; void *cred = NULL;
chunk_t blob;
builder_part_t part = BUILD_BLOB_ASN1_DER;
if (!this->pem.ptr) if (this->pem.ptr)
{ {
free(this); cred = build_from_blob(this, this->pem);
return NULL;
} }
blob = chunk_clone(this->pem); else if (this->file)
if (pem_to_bin(&blob, this, &pgp) == SUCCESS)
{ {
if (pgp) cred = build_from_file(this, this->file);
{
part = BUILD_BLOB_PGP;
}
cred = lib->creds->create(lib->creds, this->type, this->subtype,
part, blob, BUILD_END);
} }
chunk_clear(&blob);
free(this); free(this);
return cred; return cred;
} }
@@ -417,6 +475,11 @@ static void add(private_builder_t *this, builder_part_t part, ...)
switch (part) switch (part)
{ {
case BUILD_FROM_FILE:
va_start(args, part);
this->file = va_arg(args, char*);
va_end(args);
break;
case BUILD_BLOB_PEM: case BUILD_BLOB_PEM:
va_start(args, part); va_start(args, part);
this->pem = va_arg(args, chunk_t); this->pem = va_arg(args, chunk_t);
@@ -456,6 +519,7 @@ static builder_t *pem_builder(credential_type_t type, int subtype)
this->type = type; this->type = type;
this->subtype = subtype; this->subtype = subtype;
this->file = NULL;
this->pem = chunk_empty; this->pem = chunk_empty;
this->passphrase = chunk_empty; this->passphrase = chunk_empty;
this->cb = NULL; this->cb = NULL;