diff options
author | Martin Willi <martin@strongswan.org> | 2009-08-12 13:26:02 +0200 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2009-08-26 11:23:48 +0200 |
commit | c9db16b7dd1b988b57927538476592153f33b9c4 (patch) | |
tree | 56fbd7b1956f24017f53bb2db9889d23c2db5f0e /src/libstrongswan | |
parent | 160f4c225db0deacc3670c4cff0609bda8e29f73 (diff) | |
download | strongswan-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.c | 94 |
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; |