diff options
Diffstat (limited to 'src/libstrongswan/plugins/pem')
-rw-r--r-- | src/libstrongswan/plugins/pem/Makefile.am | 11 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pem/Makefile.in | 58 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pem/pem_builder.c | 35 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pem/pem_builder.h | 6 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pem/pem_encoder.c | 138 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pem/pem_encoder.h | 33 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pem/pem_plugin.c | 7 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pem/pem_plugin.h | 5 |
8 files changed, 245 insertions, 48 deletions
diff --git a/src/libstrongswan/plugins/pem/Makefile.am b/src/libstrongswan/plugins/pem/Makefile.am index 98f356aaf..b815b1e0b 100644 --- a/src/libstrongswan/plugins/pem/Makefile.am +++ b/src/libstrongswan/plugins/pem/Makefile.am @@ -3,10 +3,15 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan AM_CFLAGS = -rdynamic +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-pem.la +else plugin_LTLIBRARIES = libstrongswan-pem.la +endif -libstrongswan_pem_la_SOURCES = pem_plugin.h pem_plugin.c \ - pem_builder.c pem_builder.h +libstrongswan_pem_la_SOURCES = \ + pem_plugin.h pem_plugin.c \ + pem_builder.c pem_builder.h \ + pem_encoder.c pem_encoder.h libstrongswan_pem_la_LDFLAGS = -module -avoid-version - diff --git a/src/libstrongswan/plugins/pem/Makefile.in b/src/libstrongswan/plugins/pem/Makefile.in index e81b4f78f..4e39c8f7b 100644 --- a/src/libstrongswan/plugins/pem/Makefile.in +++ b/src/libstrongswan/plugins/pem/Makefile.in @@ -72,13 +72,16 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(plugindir)" -LTLIBRARIES = $(plugin_LTLIBRARIES) +LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) libstrongswan_pem_la_LIBADD = -am_libstrongswan_pem_la_OBJECTS = pem_plugin.lo pem_builder.lo +am_libstrongswan_pem_la_OBJECTS = pem_plugin.lo pem_builder.lo \ + pem_encoder.lo libstrongswan_pem_la_OBJECTS = $(am_libstrongswan_pem_la_OBJECTS) libstrongswan_pem_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libstrongswan_pem_la_LDFLAGS) $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_pem_la_rpath = -rpath $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_pem_la_rpath = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -217,6 +220,7 @@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ +libhydra_plugins = @libhydra_plugins@ libstrongswan_plugins = @libstrongswan_plugins@ linux_headers = @linux_headers@ localedir = @localedir@ @@ -253,9 +257,12 @@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ 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 +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-pem.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-pem.la +libstrongswan_pem_la_SOURCES = \ + pem_plugin.h pem_plugin.c \ + pem_builder.c pem_builder.h \ + pem_encoder.c pem_encoder.h libstrongswan_pem_la_LDFLAGS = -module -avoid-version all: all-am @@ -292,6 +299,15 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" @@ -324,7 +340,7 @@ clean-pluginLTLIBRARIES: rm -f "$${dir}/so_locations"; \ done libstrongswan-pem.la: $(libstrongswan_pem_la_OBJECTS) $(libstrongswan_pem_la_DEPENDENCIES) - $(libstrongswan_pem_la_LINK) -rpath $(plugindir) $(libstrongswan_pem_la_OBJECTS) $(libstrongswan_pem_la_LIBADD) $(LIBS) + $(libstrongswan_pem_la_LINK) $(am_libstrongswan_pem_la_rpath) $(libstrongswan_pem_la_OBJECTS) $(libstrongswan_pem_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -333,6 +349,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pem_builder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pem_encoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pem_plugin.Plo@am__quote@ .c.o: @@ -478,8 +495,8 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ - mostlyclean-am +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-pluginLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) @@ -550,18 +567,19 @@ uninstall-am: uninstall-pluginLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-pluginLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-pluginLTLIBRARIES \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-pluginLTLIBRARIES + clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \ + ctags distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-pluginLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/src/libstrongswan/plugins/pem/pem_builder.c b/src/libstrongswan/plugins/pem/pem_builder.c index 2f285e9bc..65be9501b 100644 --- a/src/libstrongswan/plugins/pem/pem_builder.c +++ b/src/libstrongswan/plugins/pem/pem_builder.c @@ -73,7 +73,7 @@ static bool find_boundary(char* tag, chunk_t *line) { if (present("-----", line)) { - DBG2(" -----%s %.*s-----", tag, (int)name.len, name.ptr); + DBG2(DBG_LIB, " -----%s %.*s-----", tag, (int)name.len, name.ptr); return TRUE; } line->ptr++; line->len--; name.len++; @@ -99,7 +99,7 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5); if (hasher == NULL) { - DBG1(" MD5 hash algorithm not available"); + DBG1(DBG_LIB, " MD5 hash algorithm not available"); return NOT_SUPPORTED; } hash.len = hasher->get_hash_size(hasher); @@ -121,7 +121,7 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size); if (crypter == NULL) { - DBG1(" %N encryption algorithm not available", + DBG1(DBG_LIB, " %N encryption algorithm not available", encryption_algorithm_names, alg); return NOT_SUPPORTED; } @@ -131,7 +131,7 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, blob->len % iv.len) { crypter->destroy(crypter); - DBG1(" data size is not multiple of block size"); + DBG1(DBG_LIB, " data size is not multiple of block size"); return PARSE_ERROR; } crypter->decrypt(crypter, *blob, iv, &decrypted); @@ -155,7 +155,7 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, { if (*last_padding_pos != padding) { - DBG1(" invalid passphrase"); + DBG1(DBG_LIB, " invalid passphrase"); return INVALID_ARG; } } @@ -234,7 +234,7 @@ static status_t pem_to_bin(chunk_t *blob, chunk_t(*cb)(void*,int), void *cb_data } /* we are looking for a parameter: value pair */ - DBG2(" %.*s", (int)line.len, line.ptr); + DBG2(DBG_LIB, " %.*s", (int)line.len, line.ptr); ugh = extract_parameter_value(&name, &value, &line); if (ugh != NULL) { @@ -274,8 +274,8 @@ static status_t pem_to_bin(chunk_t *blob, chunk_t(*cb)(void*,int), void *cb_data } else { - DBG1(" encryption algorithm '%.*s' not supported", - dek.len, dek.ptr); + DBG1(DBG_LIB, " encryption algorithm '%.*s'" + " not supported", dek.len, dek.ptr); return NOT_SUPPORTED; } eat_whitespace(&value); @@ -298,7 +298,8 @@ static status_t pem_to_bin(chunk_t *blob, chunk_t(*cb)(void*,int), void *cb_data *pgp = TRUE; data.ptr++; data.len--; - DBG2(" armor checksum: %.*s", (int)data.len, data.ptr); + DBG2(DBG_LIB, " armor checksum: %.*s", (int)data.len, + data.ptr); continue; } @@ -318,7 +319,7 @@ static status_t pem_to_bin(chunk_t *blob, chunk_t(*cb)(void*,int), void *cb_data if (state != PEM_POST) { - DBG1(" file coded in unknown format, discarded"); + DBG1(DBG_LIB, " file coded in unknown format, discarded"); return PARSE_ERROR; } if (!encrypted) @@ -327,7 +328,7 @@ static status_t pem_to_bin(chunk_t *blob, chunk_t(*cb)(void*,int), void *cb_data } if (!cb) { - DBG1(" missing passphrase"); + DBG1(DBG_LIB, " missing passphrase"); return INVALID_ARG; } while (TRUE) @@ -404,13 +405,14 @@ static void *load_from_file(char *file, credential_type_t type, int subtype, fd = open(file, O_RDONLY); if (fd == -1) { - DBG1(" opening '%s' failed: %s", file, strerror(errno)); + DBG1(DBG_LIB, " opening '%s' failed: %s", file, strerror(errno)); return NULL; } if (fstat(fd, &sb) == -1) { - DBG1(" getting file size of '%s' failed: %s", file, strerror(errno)); + DBG1(DBG_LIB, " getting file size of '%s' failed: %s", file, + strerror(errno)); close(fd); return NULL; } @@ -418,7 +420,7 @@ static void *load_from_file(char *file, credential_type_t type, int subtype, addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) { - DBG1(" mapping '%s' failed: %s", file, strerror(errno)); + DBG1(DBG_LIB, " mapping '%s' failed: %s", file, strerror(errno)); close(fd); return NULL; } @@ -447,7 +449,8 @@ static void *load_from_fd(int fd, credential_type_t type, int subtype, len = read(fd, pos, buf + sizeof(buf) - pos); if (len < 0) { - DBG1("reading from file descriptor failed: %s", strerror(errno)); + DBG1(DBG_LIB, "reading from file descriptor failed: %s", + strerror(errno)); return NULL; } if (len == 0) @@ -457,7 +460,7 @@ static void *load_from_fd(int fd, credential_type_t type, int subtype, total += len; if (total == sizeof(buf)) { - DBG1("buffer too small to read from file descriptor"); + DBG1(DBG_LIB, "buffer too small to read from file descriptor"); return NULL; } } diff --git a/src/libstrongswan/plugins/pem/pem_builder.h b/src/libstrongswan/plugins/pem/pem_builder.h index 189a5430f..87f5a2c69 100644 --- a/src/libstrongswan/plugins/pem/pem_builder.h +++ b/src/libstrongswan/plugins/pem/pem_builder.h @@ -18,8 +18,8 @@ * @{ @ingroup pem_p */ -#ifndef PEM_PRIVATE_KEY_H_ -#define PEM_PRIVATE_KEY_H_ +#ifndef PEM_BUILDER_H_ +#define PEM_BUILDER_H_ #include <credentials/builder.h> #include <credentials/credential_factory.h> @@ -53,5 +53,5 @@ public_key_t *pem_public_key_load(key_type_t type, va_list args); */ certificate_t *pem_certificate_load(certificate_type_t type, va_list args); -#endif /** PEM_PRIVATE_KEY_H_ @}*/ +#endif /** PEM_BUILDER_H_ @}*/ diff --git a/src/libstrongswan/plugins/pem/pem_encoder.c b/src/libstrongswan/plugins/pem/pem_encoder.c new file mode 100644 index 000000000..13c99a958 --- /dev/null +++ b/src/libstrongswan/plugins/pem/pem_encoder.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2010 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_encoder.h" + +#define BYTES_PER_LINE 48 + +/** + * See header. + */ +bool pem_encoder_encode(key_encoding_type_t type, chunk_t *encoding, + va_list args) +{ + chunk_t asn1; + char *label; + u_char *pos; + size_t len, written, pem_chars, pem_lines; + chunk_t n, e, d, p, q, exp1, exp2, coeff, to_free = chunk_empty; + + switch (type) + { + case KEY_PUB_PEM: + label ="PUBLIC KEY"; + /* direct PKCS#1 PEM encoding */ + if (key_encoding_args(args, KEY_PART_RSA_PUB_ASN1_DER, + &asn1, KEY_PART_END) || + key_encoding_args(args, KEY_PART_ECDSA_PUB_ASN1_DER, + &asn1, KEY_PART_END)) + { + break; + } + /* indirect PEM encoding from components */ + if (key_encoding_args(args, KEY_PART_RSA_MODULUS, &n, + KEY_PART_RSA_PUB_EXP, &e, KEY_PART_END)) + { + if (lib->encoding->encode(lib->encoding, KEY_PUB_SPKI_ASN1_DER, + NULL, &asn1, KEY_PART_RSA_MODULUS, n, + KEY_PART_RSA_PUB_EXP, e, KEY_PART_END)) + { + to_free = asn1; + break; + } + } + return FALSE; + case KEY_PRIV_PEM: + label ="RSA PRIVATE KEY"; + /* direct PKCS#1 PEM encoding */ + if (key_encoding_args(args, KEY_PART_RSA_PRIV_ASN1_DER, + &asn1, KEY_PART_END)) + { + break; + } + /* indirect PEM encoding from components */ + if (key_encoding_args(args, KEY_PART_RSA_MODULUS, &n, + KEY_PART_RSA_PUB_EXP, &e, KEY_PART_RSA_PRIV_EXP, &d, + KEY_PART_RSA_PRIME1, &p, KEY_PART_RSA_PRIME2, &q, + KEY_PART_RSA_EXP1, &exp1, KEY_PART_RSA_EXP2, &exp2, + KEY_PART_RSA_COEFF, &coeff, KEY_PART_END)) + { + if (lib->encoding->encode(lib->encoding, KEY_PRIV_ASN1_DER, NULL, + &asn1, KEY_PART_RSA_MODULUS, n, + KEY_PART_RSA_PUB_EXP, e, KEY_PART_RSA_PRIV_EXP, d, + KEY_PART_RSA_PRIME1, p, KEY_PART_RSA_PRIME2, q, + KEY_PART_RSA_EXP1, exp1, KEY_PART_RSA_EXP2, exp2, + KEY_PART_RSA_COEFF, coeff, KEY_PART_END)) + { + to_free = asn1; + break; + } + } + if (key_encoding_args(args, KEY_PART_ECDSA_PRIV_ASN1_DER, + &asn1, KEY_PART_END)) + { + label ="EC PRIVATE KEY"; + break; + } + return FALSE; + default: + return FALSE; + } + + /* compute and allocate maximum size of PEM object */ + pem_chars = 4*(asn1.len + 2)/3; + pem_lines = (asn1.len + BYTES_PER_LINE - 1) / BYTES_PER_LINE; + *encoding = chunk_alloc(5 + 2*(6 + strlen(label) + 6) + 3 + pem_chars + pem_lines); + pos = encoding->ptr; + len = encoding->len; + + /* write PEM header */ + written = snprintf(pos, len, "-----BEGIN %s-----\n", label); + pos += written; + len -= written; + + /* write PEM body */ + while (pem_lines--) + { + chunk_t asn1_line, pem_line; + + asn1_line = chunk_create(asn1.ptr, min(asn1.len, BYTES_PER_LINE)); + asn1.ptr += asn1_line.len; + asn1.len -= asn1_line.len; + pem_line = chunk_to_base64(asn1_line, pos); + pos += pem_line.len; + len -= pem_line.len; + *pos = '\n'; + pos++; + len--; + } + + chunk_clear(&to_free); + + /* write PEM trailer */ + written = snprintf(pos, len, "-----END %s-----", label); + pos += written; + len -= written; + + /* replace termination null character with newline */ + *pos = '\n'; + pos++; + len--; + + /* compute effective length of PEM object */ + encoding->len = pos - encoding->ptr; + return TRUE; +} + diff --git a/src/libstrongswan/plugins/pem/pem_encoder.h b/src/libstrongswan/plugins/pem/pem_encoder.h new file mode 100644 index 000000000..a181133b7 --- /dev/null +++ b/src/libstrongswan/plugins/pem/pem_encoder.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2010 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. + */ + +/** + * @defgroup pem_encoder pem_encoder + * @{ @ingroup pem_p + */ + +#ifndef PEM_ENCODER_H_ +#define PEM_ENCODER_H_ + +#include <credentials/keys/key_encoding.h> + +/** + * Encoding from ASN.1 to PEM format. + */ +bool pem_encoder_encode(key_encoding_type_t type, chunk_t *encoding, + va_list args); + +#endif /** PEM_ENCODER_H_ @}*/ + diff --git a/src/libstrongswan/plugins/pem/pem_plugin.c b/src/libstrongswan/plugins/pem/pem_plugin.c index 5a5149ca8..810901b7a 100644 --- a/src/libstrongswan/plugins/pem/pem_plugin.c +++ b/src/libstrongswan/plugins/pem/pem_plugin.c @@ -16,7 +16,9 @@ #include "pem_plugin.h" #include <library.h> + #include "pem_builder.h" +#include "pem_encoder.h" typedef struct private_pem_plugin_t private_pem_plugin_t; @@ -48,7 +50,7 @@ static void destroy(private_pem_plugin_t *this) /* * see header file */ -plugin_t *plugin_create() +plugin_t *pem_plugin_create() { private_pem_plugin_t *this = malloc_thing(private_pem_plugin_t); @@ -100,6 +102,9 @@ plugin_t *plugin_create() lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CRL, (builder_function_t)pem_certificate_load); + /* register PEM encoder */ + lib->encoding->add_encoder(lib->encoding, pem_encoder_encode); + return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/pem/pem_plugin.h b/src/libstrongswan/plugins/pem/pem_plugin.h index 75616c496..944a3fc85 100644 --- a/src/libstrongswan/plugins/pem/pem_plugin.h +++ b/src/libstrongswan/plugins/pem/pem_plugin.h @@ -39,9 +39,4 @@ struct pem_plugin_t { plugin_t plugin; }; -/** - * Create a pem_plugin instance. - */ -plugin_t *plugin_create(); - #endif /** PEM_PLUGIN_H_ @}*/ |