diff options
author | Tobias Brunner <tobias@strongswan.org> | 2012-01-18 19:14:56 +0100 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2012-02-01 18:27:45 +0100 |
commit | 9255aa87ec6332bc54d4eb23aad14ec1aa45bd2f (patch) | |
tree | 9a84c5c7d9d71f189889c107979756c92fe6bfac /src | |
parent | 5ec525c1d107ddc761fc017b764e542fd28e209c (diff) | |
download | strongswan-9255aa87ec6332bc54d4eb23aad14ec1aa45bd2f.tar.bz2 strongswan-9255aa87ec6332bc54d4eb23aad14ec1aa45bd2f.tar.xz |
Parse RSA private keys from PKCS#8 encoded blobs.
Diffstat (limited to 'src')
-rw-r--r-- | src/libstrongswan/plugins/pkcs8/Makefile.am | 3 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pkcs8/pkcs8_builder.c | 111 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pkcs8/pkcs8_builder.h | 36 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c | 2 |
4 files changed, 151 insertions, 1 deletions
diff --git a/src/libstrongswan/plugins/pkcs8/Makefile.am b/src/libstrongswan/plugins/pkcs8/Makefile.am index c840c2dc5..bcaf2c6a5 100644 --- a/src/libstrongswan/plugins/pkcs8/Makefile.am +++ b/src/libstrongswan/plugins/pkcs8/Makefile.am @@ -10,6 +10,7 @@ plugin_LTLIBRARIES = libstrongswan-pkcs8.la endif libstrongswan_pkcs8_la_SOURCES = \ - pkcs8_plugin.h pkcs8_plugin.c + pkcs8_plugin.h pkcs8_plugin.c \ + pkcs8_builder.h pkcs8_builder.c libstrongswan_pkcs8_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c new file mode 100644 index 000000000..f79925a02 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 "pkcs8_builder.h" + +#include <debug.h> +#include <asn1/oid.h> +#include <asn1/asn1.h> +#include <asn1/asn1_parser.h> +#include <credentials/keys/private_key.h> + +/** + * ASN.1 definition of a privateKeyInfo structure + */ +static const asn1Object_t pkinfoObjects[] = { + { 0, "privateKeyInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */ + { 1, "privateKeyAlgorithm", ASN1_EOC, ASN1_RAW }, /* 2 */ + { 1, "privateKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */ + { 1, "attributes", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */ + { 1, "end opt", ASN1_EOC, ASN1_END }, /* 5 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define PKINFO_PRIVATE_KEY_ALGORITHM 2 +#define PKINFO_PRIVATE_KEY 3 + +/** + * Load a generic private key from an ASN.1 encoded blob + */ +static private_key_t *parse_private_key(chunk_t blob) +{ + asn1_parser_t *parser; + chunk_t object; + int objectID; + private_key_t *key = NULL; + key_type_t type = KEY_ANY; + + parser = asn1_parser_create(pkinfoObjects, blob); + parser->set_flags(parser, FALSE, TRUE); + + while (parser->iterate(parser, &objectID, &object)) + { + switch (objectID) + { + case PKINFO_PRIVATE_KEY_ALGORITHM: + { + int oid = asn1_parse_algorithmIdentifier(object, + parser->get_level(parser) + 1, NULL); + + if (oid == OID_RSA_ENCRYPTION) + { + type = KEY_RSA; + } + else + { /* key type not supported */ + goto end; + } + break; + } + case PKINFO_PRIVATE_KEY: + { + DBG2(DBG_ASN, "-- > --"); + key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type, + BUILD_BLOB_ASN1_DER, object, BUILD_END); + DBG2(DBG_ASN, "-- < --"); + break; + } + } + } + +end: + parser->destroy(parser); + return key; +} + +/** + * See header. + */ +private_key_t *pkcs8_private_key_load(key_type_t type, va_list args) +{ + chunk_t blob = chunk_empty; + + while (TRUE) + { + switch (va_arg(args, builder_part_t)) + { + case BUILD_BLOB_ASN1_DER: + blob = va_arg(args, chunk_t); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; + } + return parse_private_key(blob); +} + diff --git a/src/libstrongswan/plugins/pkcs8/pkcs8_builder.h b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.h new file mode 100644 index 000000000..31965fa19 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 pkcs8_builder pkcs8_builder + * @{ @ingroup pkcs8 + */ + +#ifndef PKCS8_BUILDER_H_ +#define PKCS8_BUILDER_H_ + +#include <credentials/builder.h> +#include <credentials/keys/private_key.h> + +/** + * Load an RSA private key from PKCS#8 data. + * + * @param type type of the key, KEY_RSA + * @param args builder_part_t argument list + * @return private key, NULL on failure + */ +private_key_t *pkcs8_private_key_load(key_type_t type, va_list args); + +#endif /** PKCS8_BUILDER_H_ @}*/ diff --git a/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c b/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c index 8b4ec87f2..433da09b6 100644 --- a/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c +++ b/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c @@ -42,6 +42,8 @@ METHOD(plugin_t, get_features, int, private_pkcs8_plugin_t *this, plugin_feature_t *features[]) { static plugin_feature_t f[] = { + PLUGIN_REGISTER(PRIVKEY, pkcs8_private_key_load, FALSE), + PLUGIN_PROVIDE(PRIVKEY, KEY_RSA), }; *features = f; return countof(f); |