diff options
author | Martin Willi <martin@revosec.ch> | 2012-11-26 12:40:23 +0100 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2012-12-19 10:32:07 +0100 |
commit | 9de6a7a85cc64da9951d28b1cf7728ba93a3c97b (patch) | |
tree | 16930a063735d2292eb4efe73d5ad28b00b53592 /src/libstrongswan | |
parent | bd20f040fd76832995b6ccffb96cde63baefcd44 (diff) | |
download | strongswan-9de6a7a85cc64da9951d28b1cf7728ba93a3c97b.tar.bz2 strongswan-9de6a7a85cc64da9951d28b1cf7728ba93a3c97b.tar.xz |
Implement generic PKCS#7 contentInfo parsing
Diffstat (limited to 'src/libstrongswan')
-rw-r--r-- | src/libstrongswan/plugins/pkcs7/Makefile.am | 1 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pkcs7/pkcs7_generic.c | 111 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pkcs7/pkcs7_generic.h | 38 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pkcs7/pkcs7_plugin.c | 3 |
4 files changed, 153 insertions, 0 deletions
diff --git a/src/libstrongswan/plugins/pkcs7/Makefile.am b/src/libstrongswan/plugins/pkcs7/Makefile.am index fce51e335..f133851df 100644 --- a/src/libstrongswan/plugins/pkcs7/Makefile.am +++ b/src/libstrongswan/plugins/pkcs7/Makefile.am @@ -10,6 +10,7 @@ plugin_LTLIBRARIES = libstrongswan-pkcs7.la endif libstrongswan_pkcs7_la_SOURCES = \ + pkcs7_generic.h pkcs7_generic.c \ pkcs7_plugin.h pkcs7_plugin.c libstrongswan_pkcs7_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/pkcs7/pkcs7_generic.c b/src/libstrongswan/plugins/pkcs7/pkcs7_generic.c new file mode 100644 index 000000000..9e6bc3306 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs7/pkcs7_generic.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2002-2008 Andreas Steffen + * Copyright (C) 2005 Jan Hutter, Martin Willi + * Hochschule fuer Technik Rapperswil, Switzerland + * + * 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 "pkcs7_generic.h" + +#include <utils/debug.h> +#include <asn1/oid.h> +#include <asn1/asn1.h> +#include <asn1/asn1_parser.h> + +/** + * ASN.1 definition of the PKCS#7 ContentInfo type + */ +static const asn1Object_t contentInfoObjects[] = { + { 0, "contentInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "contentType", ASN1_OID, ASN1_BODY }, /* 1 */ + { 1, "content", ASN1_CONTEXT_C_0, ASN1_OPT | + ASN1_BODY }, /* 2 */ + { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define PKCS7_INFO_TYPE 1 +#define PKCS7_INFO_CONTENT 2 + +/** + * Parse PKCS#7 contentInfo object + */ +static pkcs7_t* parse_contentInfo(chunk_t blob) +{ + asn1_parser_t *parser; + chunk_t object, content = chunk_empty; + int objectID, type = OID_UNKNOWN; + bool success = FALSE; + + parser = asn1_parser_create(contentInfoObjects, blob); + parser->set_top_level(parser, 0); + + while (parser->iterate(parser, &objectID, &object)) + { + if (objectID == PKCS7_INFO_TYPE) + { + type = asn1_known_oid(object); + if (type < OID_PKCS7_DATA || type > OID_PKCS7_ENCRYPTED_DATA) + { + DBG1(DBG_ASN, "unknown pkcs7 content type"); + goto end; + } + } + else if (objectID == PKCS7_INFO_CONTENT) + { + content = object; + } + } + success = parser->success(parser); + +end: + parser->destroy(parser); + + if (success) + { + switch (type) + { + default: + DBG1(DBG_ASN, "pkcs7 content type %d not supported", type); + return NULL; + } + } + return NULL; +} + + +pkcs7_t *pkcs7_generic_load(container_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; + } + if (blob.len) + { + return parse_contentInfo(blob); + } + return NULL; +} diff --git a/src/libstrongswan/plugins/pkcs7/pkcs7_generic.h b/src/libstrongswan/plugins/pkcs7/pkcs7_generic.h new file mode 100644 index 000000000..8bdc62b36 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs7/pkcs7_generic.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * + * 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 pkcs7_generic pkcs7_generic + * @{ @ingroup pkcs7 + */ + +#ifndef PKCS7_GENERIC_H_ +#define PKCS7_GENERIC_H_ + +#include <credentials/builder.h> +#include <credentials/containers/pkcs7.h> + +/** + * Load a generic PKCS#7 container. + * + * The argument list must contain a single BUILD_BLOB_ASN1_DER argument. + * + * @param type type of the container, CONTAINER_PKCS7 + * @param args builder_part_t argument list + * @return container, NULL on failure + */ +pkcs7_t *pkcs7_generic_load(container_type_t type, va_list args); + +#endif /** PKCS7_GENERIC_H_ @}*/ diff --git a/src/libstrongswan/plugins/pkcs7/pkcs7_plugin.c b/src/libstrongswan/plugins/pkcs7/pkcs7_plugin.c index 1615ede90..e4e5764cf 100644 --- a/src/libstrongswan/plugins/pkcs7/pkcs7_plugin.c +++ b/src/libstrongswan/plugins/pkcs7/pkcs7_plugin.c @@ -14,6 +14,7 @@ */ #include "pkcs7_plugin.h" +#include "pkcs7_generic.h" #include <library.h> @@ -40,6 +41,8 @@ METHOD(plugin_t, get_features, int, private_pkcs7_plugin_t *this, plugin_feature_t *features[]) { static plugin_feature_t f[] = { + PLUGIN_REGISTER(CONTAINER_DECODE, pkcs7_generic_load, TRUE), + PLUGIN_PROVIDE(CONTAINER_DECODE, CONTAINER_PKCS7), }; *features = f; return countof(f); |