aboutsummaryrefslogtreecommitdiffstats
path: root/src/libstrongswan
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2009-08-12 13:26:02 +0200
committerMartin Willi <martin@strongswan.org>2009-08-26 11:23:48 +0200
commitc9db16b7dd1b988b57927538476592153f33b9c4 (patch)
tree56fbd7b1956f24017f53bb2db9889d23c2db5f0e /src/libstrongswan
parent160f4c225db0deacc3670c4cff0609bda8e29f73 (diff)
downloadstrongswan-c9db16b7dd1b988b57927538476592153f33b9c4.tar.bz2
strongswan-c9db16b7dd1b988b57927538476592153f33b9c4.tar.xz
added file loading support to pem plugin, using mmap()
Diffstat (limited to 'src/libstrongswan')
-rw-r--r--src/libstrongswan/plugins/pem/pem_builder.c94
1 files changed, 79 insertions, 15 deletions
diff --git a/src/libstrongswan/plugins/pem/pem_builder.c b/src/libstrongswan/plugins/pem/pem_builder.c
index d5bd1bd2d..dd335cca3 100644
--- a/src/libstrongswan/plugins/pem/pem_builder.c
+++ b/src/libstrongswan/plugins/pem/pem_builder.c
@@ -22,11 +22,15 @@
#include <errno.h>
#include <string.h>
#include <stddef.h>
+#include <fcntl.h>
#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
#include <debug.h>
#include <library.h>
#include <utils/lexparser.h>
+#include <asn1/asn1.h>
#include <crypto/hashers/hasher.h>
#include <crypto/crypters/crypter.h>
@@ -44,6 +48,8 @@ struct private_builder_t {
credential_type_t type;
/** subtype (keytype, certtype) of the credential we build */
int subtype;
+ /** path to file, if we are reading from a file */
+ char *file;
/** PEM encoding of the credential */
chunk_t pem;
/** PEM decryption passphrase, if given */
@@ -367,31 +373,83 @@ status_t pem_to_bin(chunk_t *blob, private_builder_t *this, bool *pgp)
}
/**
- * Implementation of builder_t.build
+ * build the credential from a blob
*/
-static void *build(private_builder_t *this)
+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;
- chunk_t blob;
- builder_part_t part = BUILD_BLOB_ASN1_DER;
+ struct stat sb;
+ void *addr;
+ int fd;
- if (!this->pem.ptr)
+ fd = open(file, O_RDONLY);
+ if (fd == -1)
{
- free(this);
+ DBG1(" opening '%s' failed: %s", file, strerror(errno));
return NULL;
}
- blob = chunk_clone(this->pem);
- if (pem_to_bin(&blob, this, &pgp) == SUCCESS)
+
+ if (fstat(fd, &sb) == -1)
{
- if (pgp)
- {
- part = BUILD_BLOB_PGP;
- }
- cred = lib->creds->create(lib->creds, this->type, this->subtype,
- part, blob, BUILD_END);
+ 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
+ */
+static void *build(private_builder_t *this)
+{
+ void *cred = NULL;
+
+ if (this->pem.ptr)
+ {
+ cred = build_from_blob(this, this->pem);
+ }
+ else if (this->file)
+ {
+ cred = build_from_file(this, this->file);
}
- chunk_clear(&blob);
free(this);
return cred;
}
@@ -417,6 +475,11 @@ static void add(private_builder_t *this, builder_part_t 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:
va_start(args, part);
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->subtype = subtype;
+ this->file = NULL;
this->pem = chunk_empty;
this->passphrase = chunk_empty;
this->cb = NULL;