moved PEM parsing functionality to its own plugin

This commit is contained in:
Martin Willi 2009-08-11 16:24:01 +02:00
parent 5672eae131
commit 160f4c225d
12 changed files with 746 additions and 11 deletions

View File

@ -287,6 +287,17 @@ AC_ARG_ENABLE(
pubkey=true
)
AC_ARG_ENABLE(
[pem],
AS_HELP_STRING([--disable-pem],[disable PEM decoding plugin. (default is NO).]),
[if test x$enableval = xyes; then
pem=true
else
pem=false
fi],
pem=true
)
AC_ARG_ENABLE(
[hmac],
AS_HELP_STRING([--disable-hmac],[disable HMAC crypto implementation plugin. (default is NO).]),
@ -1181,6 +1192,10 @@ if test x$pubkey = xtrue; then
libstrongswan_plugins=${libstrongswan_plugins}" pubkey"
pluto_plugins=${pluto_plugins}" pubkey"
fi
if test x$pem = xtrue; then
libstrongswan_plugins=${libstrongswan_plugins}" pem"
pluto_plugins=${pluto_plugins}" pem"
fi
if test x$mysql = xtrue; then
libstrongswan_plugins=${libstrongswan_plugins}" mysql"
fi
@ -1237,6 +1252,7 @@ AM_CONDITIONAL(USE_GMP, test x$gmp = xtrue)
AM_CONDITIONAL(USE_RANDOM, test x$random = xtrue)
AM_CONDITIONAL(USE_X509, test x$x509 = xtrue)
AM_CONDITIONAL(USE_PUBKEY, test x$pubkey = xtrue)
AM_CONDITIONAL(USE_PEM, test x$pem = xtrue)
AM_CONDITIONAL(USE_HMAC, test x$hmac = xtrue)
AM_CONDITIONAL(USE_XCBC, test x$xcbc = xtrue)
AM_CONDITIONAL(USE_MYSQL, test x$mysql = xtrue)
@ -1331,6 +1347,7 @@ AC_OUTPUT(
src/libstrongswan/plugins/xcbc/Makefile
src/libstrongswan/plugins/x509/Makefile
src/libstrongswan/plugins/pubkey/Makefile
src/libstrongswan/plugins/pem/Makefile
src/libstrongswan/plugins/curl/Makefile
src/libstrongswan/plugins/ldap/Makefile
src/libstrongswan/plugins/mysql/Makefile

View File

@ -162,6 +162,10 @@ if USE_PUBKEY
SUBDIRS += plugins/pubkey
endif
if USE_PEM
SUBDIRS += plugins/pem
endif
if USE_CURL
SUBDIRS += plugins/curl
endif

View File

@ -19,9 +19,11 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
"BUILD_FROM_FILE",
"BUILD_AGENT_SOCKET",
"BUILD_BLOB_ASN1_DER",
"BUILD_BLOB_ASN1_PEM",
"BUILD_BLOB_PEM",
"BUILD_BLOB_PGP",
"BUILD_BLOB_RFC_3110",
"BUILD_PASSPHRASE",
"BUILD_PASSPHRASE_CALLBACK",
"BUILD_KEY_SIZE",
"BUILD_SIGNING_KEY",
"BUILD_SIGNING_CERT",

View File

@ -44,12 +44,18 @@ enum builder_part_t {
BUILD_AGENT_SOCKET,
/** DER encoded ASN.1 blob, chunk_t */
BUILD_BLOB_ASN1_DER,
/** PEM encoded ASN.1 blob, null terminated char* */
BUILD_BLOB_ASN1_PEM,
/** PEM encoded ASN.1/PGP blob, chunk_t */
BUILD_BLOB_PEM,
/** OpenPGP key blob, chunk_t */
BUILD_BLOB_PGP,
/** RFC 3110 DNS public key blob, chunk_t */
BUILD_BLOB_RFC_3110,
/** passphrase for e.g. PEM decryption, chunk_t */
BUILD_PASSPHRASE,
/** passphrase callback, chunk_t(*fn)(void *user, int try), void *user.
* The callback is invoked until the returned passphrase is accepted, or
* a zero-length passphrase is returned. Try starts at 1. */
BUILD_PASSPHRASE_CALLBACK,
/** key size in bits, as used for key generation, u_int */
BUILD_KEY_SIZE,
/** private key to use for signing, private_key_t* */

View File

@ -142,7 +142,7 @@ static void* create(private_credential_factory_t *this, credential_type_t type,
builder_t *builder;
builder_part_t part;
va_list args;
void* construct = NULL;
void* construct = NULL, *fn, *data;
enumerator = create_builder_enumerator(this, type, subtype);
while (enumerator->enumerate(enumerator, &builder))
@ -155,9 +155,11 @@ static void* create(private_credential_factory_t *this, credential_type_t type,
{
case BUILD_END:
break;
case BUILD_BLOB_PEM:
case BUILD_BLOB_ASN1_DER:
case BUILD_BLOB_PGP:
case BUILD_BLOB_RFC_3110:
case BUILD_PASSPHRASE:
case BUILD_SERIAL:
builder->add(builder, part, va_arg(args, chunk_t));
continue;
@ -171,7 +173,6 @@ static void* create(private_credential_factory_t *this, credential_type_t type,
case BUILD_NOT_AFTER_TIME:
builder->add(builder, part, va_arg(args, time_t));
continue;
case BUILD_BLOB_ASN1_PEM:
case BUILD_FROM_FILE:
case BUILD_AGENT_SOCKET:
case BUILD_SIGNING_KEY:
@ -188,6 +189,11 @@ static void* create(private_credential_factory_t *this, credential_type_t type,
case BUILD_SMARTCARD_PIN:
builder->add(builder, part, va_arg(args, void*));
continue;
case BUILD_PASSPHRASE_CALLBACK:
fn = va_arg(args, void*);
data = va_arg(args, void*);
builder->add(builder, part, fn, data);
continue;
/* no default to get a compiler warning */
}
break;

View File

@ -0,0 +1,12 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan
AM_CFLAGS = -rdynamic
plugin_LTLIBRARIES = libstrongswan-pem.la
libstrongswan_pem_la_SOURCES = pem_plugin.h pem_plugin.c \
pem_builder.c pem_builder.h
libstrongswan_pem_la_LDFLAGS = -module -avoid-version

View File

@ -0,0 +1,490 @@
/*
* Copyright (C) 2009 Martin Willi
* Copyright (C) 2001-2008 Andreas Steffen
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "pem_builder.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stddef.h>
#include <sys/types.h>
#include <debug.h>
#include <library.h>
#include <utils/lexparser.h>
#include <crypto/hashers/hasher.h>
#include <crypto/crypters/crypter.h>
#define PKCS5_SALT_LEN 8 /* bytes */
typedef struct private_builder_t private_builder_t;
/**
* Builder implementation for PEM decoding
*/
struct private_builder_t {
/** implements the builder interface */
builder_t public;
/** credential type we are building */
credential_type_t type;
/** subtype (keytype, certtype) of the credential we build */
int subtype;
/** PEM encoding of the credential */
chunk_t pem;
/** PEM decryption passphrase, if given */
chunk_t passphrase;
/** supplied callback to read passphrase */
chunk_t (*cb)(void *data, int try);
/** user data to callback */
void *data;
};
/**
* check the presence of a pattern in a character string, skip if found
*/
static bool present(char* pattern, chunk_t* ch)
{
u_int len = strlen(pattern);
if (ch->len >= len && strneq(ch->ptr, pattern, len))
{
*ch = chunk_skip(*ch, len);
return TRUE;
}
return FALSE;
}
/**
* find a boundary of the form -----tag name-----
*/
static bool find_boundary(char* tag, chunk_t *line)
{
chunk_t name = chunk_empty;
if (!present("-----", line) ||
!present(tag, line) ||
*line->ptr != ' ')
{
return FALSE;
}
*line = chunk_skip(*line, 1);
/* extract name */
name.ptr = line->ptr;
while (line->len > 0)
{
if (present("-----", line))
{
DBG2(" -----%s %.*s-----", tag, (int)name.len, name.ptr);
return TRUE;
}
line->ptr++; line->len--; name.len++;
}
return FALSE;
}
/*
* decrypts a passphrase protected encrypted data block
*/
static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg,
size_t key_size, chunk_t iv, chunk_t passphrase)
{
hasher_t *hasher;
crypter_t *crypter;
chunk_t salt = { iv.ptr, PKCS5_SALT_LEN };
chunk_t hash;
chunk_t decrypted;
chunk_t key = {alloca(key_size), key_size};
u_int8_t padding, *last_padding_pos, *first_padding_pos;
/* build key from passphrase and IV */
hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
if (hasher == NULL)
{
DBG1(" MD5 hash algorithm not available");
return NOT_SUPPORTED;
}
hash.len = hasher->get_hash_size(hasher);
hash.ptr = alloca(hash.len);
hasher->get_hash(hasher, passphrase, NULL);
hasher->get_hash(hasher, salt, hash.ptr);
memcpy(key.ptr, hash.ptr, hash.len);
if (key.len > hash.len)
{
hasher->get_hash(hasher, hash, NULL);
hasher->get_hash(hasher, passphrase, NULL);
hasher->get_hash(hasher, salt, hash.ptr);
memcpy(key.ptr + hash.len, hash.ptr, key.len - hash.len);
}
hasher->destroy(hasher);
/* decrypt blob */
crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size);
if (crypter == NULL)
{
DBG1(" %N encryption algorithm not available",
encryption_algorithm_names, alg);
return NOT_SUPPORTED;
}
crypter->set_key(crypter, key);
if (iv.len != crypter->get_block_size(crypter) ||
blob->len % iv.len)
{
crypter->destroy(crypter);
DBG1(" data size is not multiple of block size");
return PARSE_ERROR;
}
crypter->decrypt(crypter, *blob, iv, &decrypted);
crypter->destroy(crypter);
memcpy(blob->ptr, decrypted.ptr, blob->len);
chunk_free(&decrypted);
/* determine amount of padding */
last_padding_pos = blob->ptr + blob->len - 1;
padding = *last_padding_pos;
if (padding > blob->len)
{
first_padding_pos = blob->ptr;
}
else
{
first_padding_pos = last_padding_pos - padding;
}
/* check the padding pattern */
while (--last_padding_pos > first_padding_pos)
{
if (*last_padding_pos != padding)
{
DBG1(" invalid passphrase");
return INVALID_ARG;
}
}
/* remove padding */
blob->len -= padding;
return SUCCESS;
}
/**
* Converts a PEM encoded file into its binary form (RFC 1421, RFC 934)
*/
status_t pem_to_bin(chunk_t *blob, private_builder_t *this, bool *pgp)
{
typedef enum {
PEM_PRE = 0,
PEM_MSG = 1,
PEM_HEADER = 2,
PEM_BODY = 3,
PEM_POST = 4,
PEM_ABORT = 5
} state_t;
encryption_algorithm_t alg = ENCR_UNDEFINED;
size_t key_size = 0;
bool encrypted = FALSE;
state_t state = PEM_PRE;
chunk_t src = *blob;
chunk_t dst = *blob;
chunk_t line = chunk_empty;
chunk_t iv = chunk_empty;
chunk_t passphrase;
int try = 0;
u_char iv_buf[HASH_SIZE_MD5];
dst.len = 0;
iv.ptr = iv_buf;
iv.len = 0;
while (fetchline(&src, &line))
{
if (state == PEM_PRE)
{
if (find_boundary("BEGIN", &line))
{
state = PEM_MSG;
}
continue;
}
else
{
if (find_boundary("END", &line))
{
state = PEM_POST;
break;
}
if (state == PEM_MSG)
{
state = PEM_HEADER;
if (memchr(line.ptr, ':', line.len) == NULL)
{
state = PEM_BODY;
}
}
if (state == PEM_HEADER)
{
err_t ugh = NULL;
chunk_t name = chunk_empty;
chunk_t value = chunk_empty;
/* an empty line separates HEADER and BODY */
if (line.len == 0)
{
state = PEM_BODY;
continue;
}
/* we are looking for a parameter: value pair */
DBG2(" %.*s", (int)line.len, line.ptr);
ugh = extract_parameter_value(&name, &value, &line);
if (ugh != NULL)
{
continue;
}
if (match("Proc-Type", &name) && *value.ptr == '4')
{
encrypted = TRUE;
}
else if (match("DEK-Info", &name))
{
chunk_t dek;
if (!extract_token(&dek, ',', &value))
{
dek = value;
}
if (match("DES-EDE3-CBC", &dek))
{
alg = ENCR_3DES;
key_size = 24;
}
else if (match("AES-128-CBC", &dek))
{
alg = ENCR_AES_CBC;
key_size = 16;
}
else if (match("AES-192-CBC", &dek))
{
alg = ENCR_AES_CBC;
key_size = 24;
}
else if (match("AES-256-CBC", &dek))
{
alg = ENCR_AES_CBC;
key_size = 32;
}
else
{
DBG1(" encryption algorithm '%.s' not supported",
dek.len, dek.ptr);
return NOT_SUPPORTED;
}
eat_whitespace(&value);
iv = chunk_from_hex(value, iv.ptr);
}
}
else /* state is PEM_BODY */
{
chunk_t data;
/* remove any trailing whitespace */
if (!extract_token(&data ,' ', &line))
{
data = line;
}
/* check for PGP armor checksum */
if (*data.ptr == '=')
{
*pgp = TRUE;
data.ptr++;
data.len--;
DBG2(" armor checksum: %.*s", (int)data.len, data.ptr);
continue;
}
if (blob->len - dst.len < data.len / 4 * 3)
{
state = PEM_ABORT;
}
data = chunk_from_base64(data, dst.ptr);
dst.ptr += data.len;
dst.len += data.len;
}
}
}
/* set length to size of binary blob */
blob->len = dst.len;
if (state != PEM_POST)
{
DBG1(" file coded in unknown format, discarded");
return PARSE_ERROR;
}
if (!encrypted)
{
return SUCCESS;
}
if (!this->cb)
{
DBG1(" missing passphrase");
return INVALID_ARG;
}
while (TRUE)
{
passphrase = this->cb(this->data, ++try);
if (!passphrase.len || !passphrase.ptr)
{
return INVALID_ARG;
}
switch (pem_decrypt(blob, alg, key_size, iv, passphrase))
{
case INVALID_ARG:
/* bad passphrase, retry */
continue;
case SUCCESS:
return SUCCESS;
default:
return FAILED;
}
}
}
/**
* Implementation of builder_t.build
*/
static void *build(private_builder_t *this)
{
bool pgp = FALSE;
void *cred = NULL;
chunk_t blob;
builder_part_t part = BUILD_BLOB_ASN1_DER;
if (!this->pem.ptr)
{
free(this);
return NULL;
}
blob = chunk_clone(this->pem);
if (pem_to_bin(&blob, this, &pgp) == SUCCESS)
{
if (pgp)
{
part = BUILD_BLOB_PGP;
}
cred = lib->creds->create(lib->creds, this->type, this->subtype,
part, blob, BUILD_END);
}
chunk_clear(&blob);
free(this);
return cred;
}
/**
* passphrase callback to use if passphrase given
*/
static chunk_t given_passphrase_cb(chunk_t *passphrase, int try)
{
if (try > 1)
{ /* try only once for given passphrases */
return chunk_empty;
}
return *passphrase;
}
/**
* Implementation of builder_t.add
*/
static void add(private_builder_t *this, builder_part_t part, ...)
{
va_list args;
switch (part)
{
case BUILD_BLOB_PEM:
va_start(args, part);
this->pem = va_arg(args, chunk_t);
va_end(args);
break;
case BUILD_PASSPHRASE:
va_start(args, part);
this->passphrase = va_arg(args, chunk_t);
va_end(args);
if (this->passphrase.len && this->passphrase.ptr)
{
this->cb = (void*)given_passphrase_cb;
this->data = &this->passphrase;
}
break;
case BUILD_PASSPHRASE_CALLBACK:
va_start(args, part);
this->cb = va_arg(args, chunk_t(*)(void*,int));
this->data = va_arg(args, void*);
va_end(args);
break;
default:
builder_cancel(&this->public);
break;
}
}
/**
* Generic PEM builder.
*/
static builder_t *pem_builder(credential_type_t type, int subtype)
{
private_builder_t *this = malloc_thing(private_builder_t);
this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
this->public.build = (void*(*)(builder_t *this))build;
this->type = type;
this->subtype = subtype;
this->pem = chunk_empty;
this->passphrase = chunk_empty;
this->cb = NULL;
this->data = NULL;
return &this->public;
}
/**
* Private key PEM builder.
*/
builder_t *private_key_pem_builder(key_type_t type)
{
return pem_builder(CRED_PRIVATE_KEY, type);
}
/**
* Public key PEM builder.
*/
builder_t *public_key_pem_builder(key_type_t type)
{
return pem_builder(CRED_PUBLIC_KEY, type);
}
/**
* Certificate PEM builder.
*/
builder_t *certificate_pem_builder(certificate_type_t type)
{
return pem_builder(CRED_CERTIFICATE, type);
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup pem_builder pem_builder
* @{ @ingroup pem_p
*/
#ifndef PEM_PRIVATE_KEY_H_
#define PEM_PRIVATE_KEY_H_
#include <credentials/certificates/certificate.h>
#include <credentials/credential_factory.h>
/**
* Builder for PEM encoded private keys of all kind.
*
* @param type type of the key
* @return builder instance
*/
builder_t *private_key_pem_builder(key_type_t type);
/**
* Builder for PEM encoded public keys of all kind.
*
* @param type type of the key
* @return builder instance
*/
builder_t *public_key_pem_builder(key_type_t type);
/**
* Builder for PEM encoded certificates of all kind.
*
* @param type type of the key
* @return builder instance
*/
builder_t *certificate_pem_builder(certificate_type_t type);
#endif /** PEM_PRIVATE_KEY_H_ @}*/

View File

@ -0,0 +1,97 @@
/*
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "pem_plugin.h"
#include <library.h>
#include "pem_builder.h"
typedef struct private_pem_plugin_t private_pem_plugin_t;
/**
* private data of pem_plugin
*/
struct private_pem_plugin_t {
/**
* public functions
*/
pem_plugin_t public;
};
/**
* Implementation of pem_plugin_t.pemtroy
*/
static void destroy(private_pem_plugin_t *this)
{
lib->creds->remove_builder(lib->creds,
(builder_constructor_t)private_key_pem_builder);
lib->creds->remove_builder(lib->creds,
(builder_constructor_t)public_key_pem_builder);
lib->creds->remove_builder(lib->creds,
(builder_constructor_t)certificate_pem_builder);
free(this);
}
/*
* see header file
*/
plugin_t *plugin_create()
{
private_pem_plugin_t *this = malloc_thing(private_pem_plugin_t);
this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
/* register private key PEM decoding builders */
lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
(builder_constructor_t)private_key_pem_builder);
lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
(builder_constructor_t)private_key_pem_builder);
lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
(builder_constructor_t)private_key_pem_builder);
lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_DSA,
(builder_constructor_t)private_key_pem_builder);
/* register public key PEM decoding builders */
lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
(builder_constructor_t)public_key_pem_builder);
lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
(builder_constructor_t)public_key_pem_builder);
lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA,
(builder_constructor_t)public_key_pem_builder);
lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_DSA,
(builder_constructor_t)public_key_pem_builder);
/* register certificate PEM decoding builders */
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_ANY,
(builder_constructor_t)certificate_pem_builder);
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509,
(builder_constructor_t)certificate_pem_builder);
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
(builder_constructor_t)certificate_pem_builder);
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
(builder_constructor_t)certificate_pem_builder);
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,
(builder_constructor_t)certificate_pem_builder);
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_AC,
(builder_constructor_t)certificate_pem_builder);
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY,
(builder_constructor_t)certificate_pem_builder);
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PGP,
(builder_constructor_t)certificate_pem_builder);
return &this->public.plugin;
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup pem_p pem
* @ingroup plugins
*
* @defgroup pem_plugin pem_plugin
* @{ @ingroup pem_p
*/
#ifndef PEM_PLUGIN_H_
#define PEM_PLUGIN_H_
#include <plugins/plugin.h>
typedef struct pem_plugin_t pem_plugin_t;
/**
* Plugin providing support to load credentials in PEM format
*/
struct pem_plugin_t {
/**
* implements plugin interface
*/
plugin_t plugin;
};
/**
* Create a pem_plugin instance.
*/
plugin_t *plugin_create();
#endif /** PEM_PLUGIN_H_ @}*/

View File

@ -137,14 +137,13 @@ static void add(private_builder_t *this, builder_part_t part, ...)
va_end(args);
return;
}
case BUILD_BLOB_ASN1_PEM:
case BUILD_BLOB_PEM:
{
bool pgp;
char *pem;
va_start(args, part);
pem = va_arg(args, char *);
blob = chunk_clone(chunk_create(pem, strlen(pem)));
blob = va_arg(args, chunk_t);
blob = chunk_clone(blob);
if (pem_to_bin(&blob, chunk_empty, &pgp) == SUCCESS)
{
this->key = pubkey_public_key_load(chunk_clone(blob));

View File

@ -122,15 +122,18 @@ static bool parse_public_key(private_peer_controller_t *this,
{
public_key_t *public;
identification_t *id;
chunk_t blob;
if (!public_key || *public_key == '\0')
{
request->setf(request, "error=Public key is missing.");
return FALSE;
}
blob = chunk_clone(chunk_create(public_key, strlen(public_key)));
public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
BUILD_BLOB_ASN1_PEM, public_key,
BUILD_BLOB_PEM, blob,
BUILD_END);
chunk_free(&blob);
if (!public)
{
request->setf(request, "error=Parsing public key failed.");