diff options
Diffstat (limited to 'src/libstrongswan/plugins/openssl')
20 files changed, 1014 insertions, 1246 deletions
diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in index e6d7b479b..aa8ecf06c 100644 --- a/src/libstrongswan/plugins/openssl/Makefile.in +++ b/src/libstrongswan/plugins/openssl/Makefile.in @@ -1,8 +1,9 @@ -# Makefile.in generated by automake 1.10.2 from Makefile.am. +# Makefile.in generated by automake 1.11 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -16,8 +17,9 @@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c @@ -35,19 +37,41 @@ host_triplet = @host@ subdir = src/libstrongswan/plugins/openssl DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; -am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +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)" -pluginLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(plugin_LTLIBRARIES) libstrongswan_openssl_la_DEPENDENCIES = am_libstrongswan_openssl_la_OBJECTS = openssl_plugin.lo \ @@ -63,6 +87,7 @@ libstrongswan_openssl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles +am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ @@ -110,25 +135,22 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@ -IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ -LINUX_HEADERS = @LINUX_HEADERS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ @@ -140,11 +162,14 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ +PTHREADLIB = @PTHREADLIB@ RANLIB = @RANLIB@ +RTLIB = @RTLIB@ RUBY = @RUBY@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ @@ -173,9 +198,9 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ -confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ +default_pkcs11 = @default_pkcs11@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -198,7 +223,7 @@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ libstrongswan_plugins = @libstrongswan_plugins@ -linuxdir = @linuxdir@ +linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ @@ -206,6 +231,7 @@ mandir = @mandir@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ @@ -214,10 +240,12 @@ pluto_plugins = @pluto_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +random_device = @random_device@ resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ -simreader = @simreader@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ @@ -225,6 +253,7 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ INCLUDES = -I$(top_srcdir)/src/libstrongswan @@ -256,9 +285,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/openssl/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/libstrongswan/plugins/openssl/Makefile + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/openssl/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libstrongswan/plugins/openssl/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -276,23 +305,28 @@ $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" - @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ if test -f $$p; then \ - f=$(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \ + list2="$$list2 $$p"; \ else :; fi; \ - done + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } uninstall-pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) - @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ - p=$(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \ + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ done clean-pluginLTLIBRARIES: @@ -325,21 +359,21 @@ distclean-compile: .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< @@ -362,7 +396,7 @@ tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) - tags=; \ + set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ @@ -370,29 +404,34 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) - tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ + test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique + $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -413,13 +452,17 @@ distdir: $(DISTFILES) if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @@ -450,6 +493,7 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -471,6 +515,8 @@ dvi-am: html: html-am +html-am: + info: info-am info-am: @@ -479,18 +525,28 @@ install-data-am: install-pluginLTLIBRARIES install-dvi: install-dvi-am +install-dvi-am: + install-exec-am: install-html: install-html-am +install-html-am: + install-info: install-info-am +install-info-am: + install-man: install-pdf: install-pdf-am +install-pdf-am: + install-ps: install-ps-am +install-ps-am: + installcheck-am: maintainer-clean: maintainer-clean-am @@ -529,6 +585,7 @@ uninstall-am: uninstall-pluginLTLIBRARIES 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. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/src/libstrongswan/plugins/openssl/openssl_crypter.c b/src/libstrongswan/plugins/openssl/openssl_crypter.c index 424fec60a..a8923ab56 100644 --- a/src/libstrongswan/plugins/openssl/openssl_crypter.c +++ b/src/libstrongswan/plugins/openssl/openssl_crypter.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2008 Tobias Brunner - * Hochschule fuer Technik Rapperswil + * 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 @@ -23,17 +23,17 @@ typedef struct private_openssl_crypter_t private_openssl_crypter_t; * Private data of openssl_crypter_t */ struct private_openssl_crypter_t { - + /** * Public part of this class. */ openssl_crypter_t public; - + /* * the key */ chunk_t key; - + /* * the cipher to use */ @@ -49,17 +49,17 @@ typedef struct { * Identifier specified in IKEv2 */ int ikev2_id; - + /** * Name of the algorithm, as used in OpenSSL */ char *name; - + /** * Minimum valid key length in bytes */ size_t key_size_min; - + /** * Maximum valid key length in bytes */ @@ -91,7 +91,7 @@ static openssl_algorithm_t encryption_algs[] = { /** * Look up an OpenSSL algorithm name and validate its key size */ -static char* lookup_algorithm(openssl_algorithm_t *openssl_algo, +static char* lookup_algorithm(openssl_algorithm_t *openssl_algo, u_int16_t ikev2_algo, size_t *key_size) { while (openssl_algo->ikev2_id != END_OF_LIST) @@ -104,7 +104,7 @@ static char* lookup_algorithm(openssl_algorithm_t *openssl_algo, { *key_size = openssl_algo->key_size_min; } - + /* validate key size */ if (*key_size < openssl_algo->key_size_min || *key_size > openssl_algo->key_size_max) @@ -123,7 +123,7 @@ static void crypt(private_openssl_crypter_t *this, chunk_t data, { int len; u_char *out; - + out = data.ptr; if (dst) { @@ -144,7 +144,7 @@ static void crypt(private_openssl_crypter_t *this, chunk_t data, /** * Implementation of crypter_t.decrypt. */ -static void decrypt(private_openssl_crypter_t *this, chunk_t data, +static void decrypt(private_openssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) { crypt(this, data, iv, dst, 0); @@ -154,7 +154,7 @@ static void decrypt(private_openssl_crypter_t *this, chunk_t data, /** * Implementation of crypter_t.encrypt. */ -static void encrypt (private_openssl_crypter_t *this, chunk_t data, +static void encrypt (private_openssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) { crypt(this, data, iv, dst, 1); @@ -196,13 +196,13 @@ static void destroy (private_openssl_crypter_t *this) /* * Described in header */ -openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo, +openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo, size_t key_size) { private_openssl_crypter_t *this; - + this = malloc_thing(private_openssl_crypter_t); - + switch (algo) { case ENCR_NULL: @@ -218,7 +218,7 @@ openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo, this->cipher = EVP_get_cipherbyname("aes192"); break; case 32: /* AES-256 */ - this->cipher = EVP_get_cipherbyname("aes256"); + this->cipher = EVP_get_cipherbyname("aes256"); break; default: free(this); @@ -235,7 +235,7 @@ openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo, this->cipher = EVP_get_cipherbyname("camellia192"); break; case 32: /* CAMELLIA 256 */ - this->cipher = EVP_get_cipherbyname("camellia256"); + this->cipher = EVP_get_cipherbyname("camellia256"); break; default: free(this); @@ -258,22 +258,22 @@ openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo, break; } } - + if (!this->cipher) { /* OpenSSL does not support the requested algo */ free(this); return NULL; } - + this->key = chunk_alloc(key_size); - + this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt; this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt; this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *)) get_block_size; this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *)) get_key_size; this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key; this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy; - + return &this->public; } diff --git a/src/libstrongswan/plugins/openssl/openssl_crypter.h b/src/libstrongswan/plugins/openssl/openssl_crypter.h index e5a899418..7e30ae03c 100644 --- a/src/libstrongswan/plugins/openssl/openssl_crypter.h +++ b/src/libstrongswan/plugins/openssl/openssl_crypter.h @@ -29,7 +29,7 @@ typedef struct openssl_crypter_t openssl_crypter_t; * Implementation of crypters using OpenSSL. */ struct openssl_crypter_t { - + /** * The crypter_t interface. */ @@ -38,7 +38,7 @@ struct openssl_crypter_t { /** * Constructor to create openssl_crypter_t. - * + * * @param algo algorithm to implement * @param key_size key size in bytes * @return openssl_crypter_t, NULL if not supported diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c index fe042efdc..80a1ee878 100644 --- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c +++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c @@ -22,7 +22,7 @@ typedef struct modulus_entry_t modulus_entry_t; -/** +/** * Entry of the modulus list. */ struct modulus_entry_t { @@ -30,20 +30,20 @@ struct modulus_entry_t { * Group number as it is defined in file transform_substructure.h. */ diffie_hellman_group_t group; - + /** * Pointer to the function to get the modulus. */ BIGNUM *(*get_prime)(BIGNUM *bn); - - /* + + /* * Optimum length of exponent in bits. - */ + */ long opt_exponent_len; - - /* + + /* * Generator value. - */ + */ u_int16_t generator; }; @@ -71,27 +71,27 @@ struct private_openssl_diffie_hellman_t { * Public openssl_diffie_hellman_t interface. */ openssl_diffie_hellman_t public; - + /** * Diffie Hellman group number. */ u_int16_t group; - + /** * Diffie Hellman object */ DH *dh; - + /** * Other public value */ BIGNUM *pub_key; - + /** * Shared secret */ chunk_t shared_secret; - + /** * True if shared secret is computed */ @@ -123,7 +123,7 @@ static status_t get_shared_secret(private_openssl_diffie_hellman_t *this, /* shared secret should requires a len according the DH group */ *secret = chunk_alloc(DH_size(this->dh)); memset(secret->ptr, 0, secret->len); - memcpy(secret->ptr + secret->len - this->shared_secret.len, + memcpy(secret->ptr + secret->len - this->shared_secret.len, this->shared_secret.ptr, this->shared_secret.len); return SUCCESS; @@ -137,7 +137,7 @@ static void set_other_public_value(private_openssl_diffie_hellman_t *this, chunk_t value) { int len; - + BN_bin2bn(value.ptr, value.len, this->pub_key); chunk_clear(&this->shared_secret); this->shared_secret.ptr = malloc(DH_size(this->dh)); @@ -167,10 +167,10 @@ static status_t set_modulus(private_openssl_diffie_hellman_t *this) { int i; bool ansi_x9_42; - + ansi_x9_42 = lib->settings->get_bool(lib->settings, "libstrongswan.dh_exponent_ansi_x9_42", TRUE); - + for (i = 0; i < (sizeof(modulus_entries) / sizeof(modulus_entry_t)); i++) { if (modulus_entries[i].group == this->group) @@ -205,32 +205,32 @@ static void destroy(private_openssl_diffie_hellman_t *this) openssl_diffie_hellman_t *openssl_diffie_hellman_create(diffie_hellman_group_t group) { private_openssl_diffie_hellman_t *this = malloc_thing(private_openssl_diffie_hellman_t); - + this->public.dh.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret; this->public.dh.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value; this->public.dh.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value; this->public.dh.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group; this->public.dh.destroy = (void (*)(diffie_hellman_t *)) destroy; - + this->dh = DH_new(); if (!this->dh) { free(this); return NULL; } - + this->group = group; this->computed = FALSE; this->pub_key = BN_new(); this->shared_secret = chunk_empty; - + /* find a modulus according to group */ if (set_modulus(this) != SUCCESS) { destroy(this); return NULL; } - + /* generate my public and private values */ if (!DH_generate_key(this->dh)) { @@ -238,6 +238,6 @@ openssl_diffie_hellman_t *openssl_diffie_hellman_create(diffie_hellman_group_t g return NULL; } DBG2("size of DH secret exponent: %d bits", BN_num_bits(this->dh->priv_key)); - + return &this->public; } diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h index bdc153812..6c4b4fe81 100644 --- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h +++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h @@ -29,7 +29,7 @@ typedef struct openssl_diffie_hellman_t openssl_diffie_hellman_t; * Implementation of the Diffie-Hellman algorithm using OpenSSL. */ struct openssl_diffie_hellman_t { - + /** * Implements diffie_hellman_t interface. */ @@ -38,7 +38,7 @@ struct openssl_diffie_hellman_t { /** * Creates a new openssl_diffie_hellman_t object. - * + * * @param group Diffie Hellman group number to use * @return openssl_diffie_hellman_t object, NULL if not supported */ diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c index 082aed9ca..671fa41e2 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c +++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c @@ -31,27 +31,27 @@ struct private_openssl_ec_diffie_hellman_t { * Public openssl_ec_diffie_hellman_t interface. */ openssl_ec_diffie_hellman_t public; - + /** * Diffie Hellman group number. */ u_int16_t group; - + /** * EC private (public) key */ EC_KEY *key; - + /** * EC group */ const EC_GROUP *ec_group; - + /** * Other public key */ EC_POINT *pub_key; - + /** * Shared secret */ @@ -72,13 +72,13 @@ static bool chunk2ecp(const EC_GROUP *group, chunk_t chunk, EC_POINT *point) BN_CTX *ctx; BIGNUM *x, *y; bool ret = FALSE; - + ctx = BN_CTX_new(); if (!ctx) { return FALSE; } - + BN_CTX_start(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); @@ -86,17 +86,17 @@ static bool chunk2ecp(const EC_GROUP *group, chunk_t chunk, EC_POINT *point) { goto error; } - + if (!openssl_bn_split(chunk, x, y)) { goto error; } - + if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) { goto error; } - + ret = TRUE; error: BN_CTX_end(ctx); @@ -114,13 +114,13 @@ static bool ecp2chunk(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx; BIGNUM *x, *y; bool ret = FALSE; - + ctx = BN_CTX_new(); if (!ctx) { return FALSE; } - + BN_CTX_start(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); @@ -128,12 +128,12 @@ static bool ecp2chunk(const EC_GROUP *group, const EC_POINT *point, { goto error; } - + if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) { goto error; } - + if (x_coordinate_only) { y = NULL; @@ -142,7 +142,7 @@ static bool ecp2chunk(const EC_GROUP *group, const EC_POINT *point, { goto error; } - + ret = TRUE; error: BN_CTX_end(ctx); @@ -152,7 +152,7 @@ error: /** * Compute the shared secret. - * + * * We cannot use the function ECDH_compute_key() because that returns only the * x coordinate of the shared secret point (which is defined, for instance, in * 'NIST SP 800-56A'). @@ -166,13 +166,13 @@ static bool compute_shared_key(private_openssl_ec_diffie_hellman_t *this, chunk_ const BIGNUM *priv_key; EC_POINT *secret = NULL; bool x_coordinate_only, ret = FALSE; - + priv_key = EC_KEY_get0_private_key(this->key); if (!priv_key) { goto error; } - + secret = EC_POINT_new(this->ec_group); if (!secret) { @@ -183,7 +183,7 @@ static bool compute_shared_key(private_openssl_ec_diffie_hellman_t *this, chunk_ { goto error; } - + /* * The default setting ecp_x_coordinate_only = TRUE * applies the following errata for RFC 4753: @@ -195,7 +195,7 @@ static bool compute_shared_key(private_openssl_ec_diffie_hellman_t *this, chunk_ { goto error; } - + ret = TRUE; error: if (secret) @@ -215,14 +215,14 @@ static void set_other_public_value(private_openssl_ec_diffie_hellman_t *this, ch DBG1("ECDH public value is malformed"); return; } - + chunk_free(&this->shared_secret); - + if (!compute_shared_key(this, &this->shared_secret)) { DBG1("ECDH shared secret computation failed"); return; } - + this->computed = TRUE; } @@ -272,13 +272,13 @@ static void destroy(private_openssl_ec_diffie_hellman_t *this) openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_group_t group) { private_openssl_ec_diffie_hellman_t *this = malloc_thing(private_openssl_ec_diffie_hellman_t); - + this->public.dh.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret; this->public.dh.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value; this->public.dh.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value; this->public.dh.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group; this->public.dh.destroy = (void (*)(diffie_hellman_t *)) destroy; - + switch (group) { case ECP_192_BIT: @@ -300,34 +300,34 @@ openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_gro this->key = NULL; break; } - + if (!this->key) { free(this); return NULL; } - + /* caching the EC group */ this->ec_group = EC_KEY_get0_group(this->key); - + this->pub_key = EC_POINT_new(this->ec_group); if (!this->pub_key) { free(this); return NULL; } - + /* generate an EC private (public) key */ if (!EC_KEY_generate_key(this->key)) { free(this); return NULL; } - + this->group = group; this->computed = FALSE; - + this->shared_secret = chunk_empty; - + return &this->public; } diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h index 9d17aed57..fd60732b9 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h +++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h @@ -29,7 +29,7 @@ typedef struct openssl_ec_diffie_hellman_t openssl_ec_diffie_hellman_t; * Implementation of the EC Diffie-Hellman algorithm using OpenSSL. */ struct openssl_ec_diffie_hellman_t { - + /** * Implements diffie_hellman_t interface. */ @@ -38,7 +38,7 @@ struct openssl_ec_diffie_hellman_t { /** * Creates a new openssl_ec_diffie_hellman_t object. - * + * * @param group EC Diffie Hellman group number to use * @return openssl_ec_diffie_hellman_t object, NULL if not supported */ diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c index d6b442ae9..89ced5a9a 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2009 Martin Willi * Copyright (C) 2008 Tobias Brunner * Hochschule fuer Technik Rapperswil * @@ -21,6 +22,7 @@ #include <openssl/evp.h> #include <openssl/ecdsa.h> +#include <openssl/x509.h> typedef struct private_openssl_ec_private_key_t private_openssl_ec_private_key_t; @@ -32,175 +34,138 @@ struct private_openssl_ec_private_key_t { * Public interface for this signer. */ openssl_ec_private_key_t public; - + /** * EC key object */ EC_KEY *ec; /** - * Keyid formed as a SHA-1 hash of a privateKey object - */ - identification_t* keyid; - - /** - * Keyid formed as a SHA-1 hash of a privateKeyInfo object - */ - identification_t* keyid_info; - - /** * reference count */ - refcount_t ref; + refcount_t ref; }; -/** - * Mapping from the signature scheme defined in (RFC 4754) to the elliptic - * curve and the hash algorithm - */ -typedef struct { - /** - * Scheme specified in RFC 4754 - */ - int scheme; - - /** - * NID of the hash - */ - int hash; - - /** - * NID of the curve - */ - int curve; -} openssl_ecdsa_scheme_t; - -#define END_OF_LIST -1 +/* from ec public key */ +bool openssl_ec_fingerprint(EC_KEY *ec, key_encoding_type_t type, chunk_t *fp); /** - * Signature schemes + * Build a signature as in RFC 4754 */ -static openssl_ecdsa_scheme_t ecdsa_schemes[] = { - {SIGN_ECDSA_256, NID_sha256, NID_X9_62_prime256v1}, - {SIGN_ECDSA_384, NID_sha384, NID_secp384r1}, - {SIGN_ECDSA_521, NID_sha512, NID_secp521r1}, - {END_OF_LIST, 0, 0}, -}; - -/** - * Look up the hash and curve of a signature scheme - */ -static bool lookup_scheme(int scheme, int *hash, int *curve) +static bool build_signature(private_openssl_ec_private_key_t *this, + chunk_t hash, chunk_t *signature) { - openssl_ecdsa_scheme_t *ecdsa_scheme = ecdsa_schemes; - while (ecdsa_scheme->scheme != END_OF_LIST) + bool built = FALSE; + ECDSA_SIG *sig; + + sig = ECDSA_do_sign(hash.ptr, hash.len, this->ec); + if (sig) { - if (scheme == ecdsa_scheme->scheme) - { - *hash = ecdsa_scheme->hash; - *curve = ecdsa_scheme->curve; - return TRUE; - } - ecdsa_scheme++; + /* concatenate BNs r/s to a signature chunk */ + built = openssl_bn_cat(EC_FIELD_ELEMENT_LEN(EC_KEY_get0_group(this->ec)), + sig->r, sig->s, signature); + ECDSA_SIG_free(sig); } - return FALSE; -} - -/** - * shared functions, implemented in openssl_ec_public_key.c - */ -bool openssl_ec_public_key_build_id(EC_KEY *ec, identification_t **keyid, - identification_t **keyid_info); - -openssl_ec_public_key_t *openssl_ec_public_key_create_from_private_key(EC_KEY *ec); - - -/** - * Convert an ECDSA_SIG to a chunk by concatenating r and s. - * This function allocates memory for the chunk. - */ -static bool sig2chunk(const EC_GROUP *group, ECDSA_SIG *sig, chunk_t *chunk) -{ - return openssl_bn_cat(EC_FIELD_ELEMENT_LEN(group), sig->r, sig->s, chunk); + return built; } /** - * Build the signature + * Build a RFC 4754 signature for a specified curve and hash algorithm */ -static bool build_signature(private_openssl_ec_private_key_t *this, - chunk_t hash, chunk_t *signature) +static bool build_curve_signature(private_openssl_ec_private_key_t *this, + signature_scheme_t scheme, int nid_hash, + int nid_curve, chunk_t data, chunk_t *signature) { - ECDSA_SIG *sig = ECDSA_do_sign(hash.ptr, hash.len, this->ec); - bool success; + const EC_GROUP *my_group; + EC_GROUP *req_group; + chunk_t hash; + bool built; - if (!sig) + req_group = EC_GROUP_new_by_curve_name(nid_curve); + if (!req_group) + { + DBG1("signature scheme %N not supported in EC (required curve " + "not supported)", signature_scheme_names, scheme); + return FALSE; + } + my_group = EC_KEY_get0_group(this->ec); + if (EC_GROUP_cmp(my_group, req_group, NULL) != 0) + { + DBG1("signature scheme %N not supported by private key", + signature_scheme_names, scheme); + return FALSE; + } + EC_GROUP_free(req_group); + if (!openssl_hash_chunk(nid_hash, data, &hash)) { return FALSE; } - success = sig2chunk(EC_KEY_get0_group(this->ec), sig, signature); - ECDSA_SIG_free(sig); - return success; + built = build_signature(this, hash, signature); + chunk_free(&hash); + return built; } /** - * Implementation of private_key_t.get_type. + * Build a DER encoded signature as in RFC 3279 */ -static key_type_t get_type(private_openssl_ec_private_key_t *this) +static bool build_der_signature(private_openssl_ec_private_key_t *this, + int hash_nid, chunk_t data, chunk_t *signature) { - return KEY_ECDSA; + chunk_t hash, sig; + int siglen = 0; + bool built; + + if (!openssl_hash_chunk(hash_nid, data, &hash)) + { + return FALSE; + } + sig = chunk_alloc(ECDSA_size(this->ec)); + built = ECDSA_sign(0, hash.ptr, hash.len, sig.ptr, &siglen, this->ec) == 1; + sig.len = siglen; + if (built) + { + *signature = sig; + } + else + { + free(sig.ptr); + } + free(hash.ptr); + return built; } /** * Implementation of private_key_t.sign. */ -static bool sign(private_openssl_ec_private_key_t *this, signature_scheme_t scheme, - chunk_t data, chunk_t *signature) +static bool sign(private_openssl_ec_private_key_t *this, + signature_scheme_t scheme, chunk_t data, chunk_t *signature) { - bool success; - - if (scheme == SIGN_ECDSA_WITH_NULL) + switch (scheme) { - success = build_signature(this, data, signature); - } - else - { - EC_GROUP *req_group; - const EC_GROUP *my_group; - chunk_t hash = chunk_empty; - int hash_type, curve; - - if (!lookup_scheme(scheme, &hash_type, &curve)) - { - DBG1("signature scheme %N not supported in EC", - signature_scheme_names, scheme); - return FALSE; - } - - req_group = EC_GROUP_new_by_curve_name(curve); - if (!req_group) - { - DBG1("signature scheme %N not supported in EC (required curve not supported)", - signature_scheme_names, scheme); - return FALSE; - } - - my_group = EC_KEY_get0_group(this->ec); - if (EC_GROUP_cmp(my_group, req_group, NULL) != 0) - { - DBG1("signature scheme %N not supported by private key", - signature_scheme_names, scheme); - return FALSE; - } - EC_GROUP_free(req_group); - - if (!openssl_hash_chunk(hash_type, data, &hash)) - { + case SIGN_ECDSA_WITH_NULL: + return build_signature(this, data, signature); + case SIGN_ECDSA_WITH_SHA1_DER: + return build_der_signature(this, NID_sha1, data, signature); + case SIGN_ECDSA_WITH_SHA256_DER: + return build_der_signature(this, NID_sha256, data, signature); + case SIGN_ECDSA_WITH_SHA384_DER: + return build_der_signature(this, NID_sha384, data, signature); + case SIGN_ECDSA_WITH_SHA512_DER: + return build_der_signature(this, NID_sha512, data, signature); + case SIGN_ECDSA_256: + return build_curve_signature(this, scheme, NID_sha256, + NID_X9_62_prime256v1, data, signature); + case SIGN_ECDSA_384: + return build_curve_signature(this, scheme, NID_sha384, + NID_secp384r1, data, signature); + case SIGN_ECDSA_521: + return build_curve_signature(this, scheme, NID_sha512, + NID_secp521r1, data, signature); + default: + DBG1("signature scheme %N not supported", + signature_scheme_names, scheme); return FALSE; - } - success = build_signature(this, hash, signature); - chunk_free(&hash); - } - return success; + } } /** @@ -222,73 +187,70 @@ static size_t get_keysize(private_openssl_ec_private_key_t *this) } /** - * Implementation of private_key_t.get_id. + * Implementation of private_key_t.get_type. */ -static identification_t* get_id(private_openssl_ec_private_key_t *this, - id_type_t type) +static key_type_t get_type(private_openssl_ec_private_key_t *this) { - switch (type) - { - case ID_PUBKEY_INFO_SHA1: - return this->keyid_info; - case ID_PUBKEY_SHA1: - return this->keyid; - default: - return NULL; - } + return KEY_ECDSA; } /** * Implementation of private_key_t.get_public_key. */ -static openssl_ec_public_key_t* get_public_key(private_openssl_ec_private_key_t *this) +static public_key_t* get_public_key(private_openssl_ec_private_key_t *this) { - return openssl_ec_public_key_create_from_private_key(this->ec); + public_key_t *public; + chunk_t key; + u_char *p; + + key = chunk_alloc(i2d_EC_PUBKEY(this->ec, NULL)); + p = key.ptr; + i2d_EC_PUBKEY(this->ec, &p); + + public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA, + BUILD_BLOB_ASN1_DER, key, BUILD_END); + free(key.ptr); + return public; } /** - * Implementation of private_key_t.belongs_to. + * Implementation of private_key_t.get_fingerprint. */ -static bool belongs_to(private_openssl_ec_private_key_t *this, public_key_t *public) +static bool get_fingerprint(private_openssl_ec_private_key_t *this, + key_encoding_type_t type, chunk_t *fingerprint) { - identification_t *keyid; - - if (public->get_type(public) != KEY_ECDSA) - { - return FALSE; - } - keyid = public->get_id(public, ID_PUBKEY_SHA1); - if (keyid && keyid->equals(keyid, this->keyid)) - { - return TRUE; - } - keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1); - if (keyid && keyid->equals(keyid, this->keyid_info)) - { - return TRUE; - } - return FALSE; + return openssl_ec_fingerprint(this->ec, type, fingerprint); } /** * Implementation of private_key_t.get_encoding. */ -static chunk_t get_encoding(private_openssl_ec_private_key_t *this) +static bool get_encoding(private_openssl_ec_private_key_t *this, + key_encoding_type_t type, chunk_t *encoding) { - chunk_t enc = chunk_alloc(i2d_ECPrivateKey(this->ec, NULL)); - u_char *p = enc.ptr; - i2d_ECPrivateKey(this->ec, &p); - return enc; + u_char *p; + + switch (type) + { + case KEY_PRIV_ASN1_DER: + { + *encoding = chunk_alloc(i2d_ECPrivateKey(this->ec, NULL)); + p = encoding->ptr; + i2d_ECPrivateKey(this->ec, &p); + return TRUE; + } + default: + return FALSE; + } } /** * Implementation of private_key_t.get_ref. */ -static private_openssl_ec_private_key_t* get_ref(private_openssl_ec_private_key_t *this) +static private_key_t* get_ref(private_openssl_ec_private_key_t *this) { ref_get(&this->ref); - return this; - + return &this->public.interface; } /** @@ -300,10 +262,9 @@ static void destroy(private_openssl_ec_private_key_t *this) { if (this->ec) { + lib->encoding->clear_cache(lib->encoding, this->ec); EC_KEY_free(this->ec); } - DESTROY_IF(this->keyid); - DESTROY_IF(this->keyid_info); free(this); } } @@ -311,133 +272,121 @@ static void destroy(private_openssl_ec_private_key_t *this) /** * Internal generic constructor */ -static private_openssl_ec_private_key_t *openssl_ec_private_key_create_empty(void) +static private_openssl_ec_private_key_t *create_empty(void) { private_openssl_ec_private_key_t *this = malloc_thing(private_openssl_ec_private_key_t); - + this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type; this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign; this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt; this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize; - this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id; this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key; - this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to; - this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding; + this->public.interface.equals = private_key_equals; + this->public.interface.belongs_to = private_key_belongs_to; + this->public.interface.get_fingerprint = (bool(*)(private_key_t*, key_encoding_type_t type, chunk_t *fp))get_fingerprint; + this->public.interface.has_fingerprint = (bool(*)(private_key_t*, chunk_t fp))private_key_has_fingerprint; + this->public.interface.get_encoding = (bool(*)(private_key_t*, key_encoding_type_t type, chunk_t *encoding))get_encoding; this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref; this->public.interface.destroy = (void (*)(private_key_t *this))destroy; - + this->ec = NULL; - this->keyid = NULL; - this->keyid_info = NULL; this->ref = 1; - + return this; } /** - * load private key from an ASN1 encoded blob + * See header. */ -static openssl_ec_private_key_t *load(chunk_t blob) +openssl_ec_private_key_t *openssl_ec_private_key_gen(key_type_t type, + va_list args) { - u_char *p = blob.ptr; - private_openssl_ec_private_key_t *this = openssl_ec_private_key_create_empty(); - - this->ec = d2i_ECPrivateKey(NULL, (const u_char**)&p, blob.len); - - chunk_clear(&blob); + private_openssl_ec_private_key_t *this; + u_int key_size = 0; - if (!this->ec) + while (TRUE) { - destroy(this); - return NULL; + switch (va_arg(args, builder_part_t)) + { + case BUILD_KEY_SIZE: + key_size = va_arg(args, u_int); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; } - - if (!openssl_ec_public_key_build_id(this->ec, &this->keyid, &this->keyid_info)) + if (!key_size) { - destroy(this); return NULL; } - - if (!EC_KEY_check_key(this->ec)) + this = create_empty(); + switch (key_size) + { + case 256: + this->ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + break; + case 384: + this->ec = EC_KEY_new_by_curve_name(NID_secp384r1); + break; + case 521: + this->ec = EC_KEY_new_by_curve_name(NID_secp521r1); + break; + default: + DBG1("EC private key size %d not supported", key_size); + destroy(this); + return NULL; + } + if (EC_KEY_generate_key(this->ec) != 1) { + DBG1("EC private key generation failed", key_size); destroy(this); return NULL; } - + /* encode as a named curve key (no parameters), uncompressed public key */ + EC_KEY_set_asn1_flag(this->ec, OPENSSL_EC_NAMED_CURVE); + EC_KEY_set_conv_form(this->ec, POINT_CONVERSION_UNCOMPRESSED); return &this->public; } -typedef struct private_builder_t private_builder_t; -/** - * Builder implementation for key loading/generation - */ -struct private_builder_t { - /** implements the builder interface */ - builder_t public; - /** loaded/generated private key */ - openssl_ec_private_key_t *key; -}; - /** - * Implementation of builder_t.build + * See header. */ -static openssl_ec_private_key_t *build(private_builder_t *this) +openssl_ec_private_key_t *openssl_ec_private_key_load(key_type_t type, + va_list args) { - openssl_ec_private_key_t *key = this->key; - - free(this); - return key; -} + private_openssl_ec_private_key_t *this; + chunk_t blob = chunk_empty; -/** - * Implementation of builder_t.add - */ -static void add(private_builder_t *this, builder_part_t part, ...) -{ - if (!this->key) + while (TRUE) { - va_list args; - chunk_t chunk; - - switch (part) + switch (va_arg(args, builder_part_t)) { case BUILD_BLOB_ASN1_DER: - { - va_start(args, part); - chunk = va_arg(args, chunk_t); - this->key = load(chunk_clone(chunk)); - va_end(args); - return; - } - default: + blob = va_arg(args, chunk_t); + continue; + case BUILD_END: break; + default: + return NULL; } + break; } - if (this->key) + + this = create_empty(); + this->ec = d2i_ECPrivateKey(NULL, (const u_char**)&blob.ptr, blob.len); + if (!this->ec) { - destroy((private_openssl_ec_private_key_t*)this->key); + destroy(this); + return NULL; } - builder_cancel(&this->public); -} - -/** - * Builder construction function - */ -builder_t *openssl_ec_private_key_builder(key_type_t type) -{ - private_builder_t *this; - - if (type != KEY_ECDSA) + if (!EC_KEY_check_key(this->ec)) { + destroy(this); return NULL; } - - this = malloc_thing(private_builder_t); - - this->key = NULL; - this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add; - this->public.build = (void*(*)(builder_t *this))build; - return &this->public; } diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h index 6a6f7c867..720c63f90 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h +++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h @@ -21,6 +21,7 @@ #ifndef OPENSSL_EC_PRIVATE_KEY_H_ #define OPENSSL_EC_PRIVATE_KEY_H_ +#include <credentials/builder.h> #include <credentials/keys/private_key.h> typedef struct openssl_ec_private_key_t openssl_ec_private_key_t; @@ -37,11 +38,27 @@ struct openssl_ec_private_key_t { }; /** - * Create the builder for a private key. + * Generate a ECDSA private key using OpenSSL. + * + * Accepts the BUILD_KEY_SIZE argument. + * + * @param type type of the key, must be KEY_ECDSA + * @param args builder_part_t argument list + * @return generated key, NULL on failure + */ +openssl_ec_private_key_t *openssl_ec_private_key_gen(key_type_t type, + va_list args); + +/** + * Load a ECDSA private key using OpenSSL. + * + * Accepts a BUILD_BLOB_ASN1_DER argument. * * @param type type of the key, must be KEY_ECDSA - * @return builder instance + * @param args builder_part_t argument list + * @return loaded key, NULL on failure */ -builder_t *openssl_ec_private_key_builder(key_type_t type); +openssl_ec_private_key_t *openssl_ec_private_key_load(key_type_t type, + va_list args); #endif /** OPENSSL_EC_PRIVATE_KEY_H_ @}*/ diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c index 635a106dd..f37c736b1 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2009 Martin Willi * Copyright (C) 2008 Tobias Brunner * Hochschule fuer Technik Rapperswil * @@ -32,22 +33,12 @@ struct private_openssl_ec_public_key_t { * Public interface for this signer. */ openssl_ec_public_key_t public; - + /** * EC key object */ EC_KEY *ec; - - /** - * Keyid formed as a SHA-1 hash of a publicKeyInfo object - */ - identification_t *keyid_info; - - /** - * Keyid formed as a SHA-1 hash of a publicKey object - */ - identification_t *keyid; - + /** * reference counter */ @@ -55,99 +46,83 @@ struct private_openssl_ec_public_key_t { }; /** - * Convert a chunk to an ECDSA_SIG (which must already exist). r and s - * of the signature have to be concatenated in the chunk. - */ -static bool chunk2sig(const EC_GROUP *group, chunk_t chunk, ECDSA_SIG *sig) -{ - return openssl_bn_split(chunk, sig->r, sig->s); -} - -/** * Verification of a signature as in RFC 4754 */ static bool verify_signature(private_openssl_ec_public_key_t *this, - int hash_type, chunk_t data, chunk_t signature) + chunk_t hash, chunk_t signature) { - chunk_t hash = chunk_empty; - ECDSA_SIG *sig; bool valid = FALSE; - - if (hash_type == NID_undef) - { - hash = data; - } - else + ECDSA_SIG *sig; + + sig = ECDSA_SIG_new(); + if (sig) { - if (!openssl_hash_chunk(hash_type, data, &hash)) + /* split the signature chunk in r and s */ + if (openssl_bn_split(signature, sig->r, sig->s)) { - return FALSE; + valid = (ECDSA_do_verify(hash.ptr, hash.len, sig, this->ec) == 1); } + ECDSA_SIG_free(sig); } - - sig = ECDSA_SIG_new(); - if (!sig) - { - goto error; - } - - if (!chunk2sig(EC_KEY_get0_group(this->ec), signature, sig)) + return valid; +} + +/** + * Verify a RFC 4754 signature for a specified curve and hash algorithm + */ +static bool verify_curve_signature(private_openssl_ec_public_key_t *this, + signature_scheme_t scheme, int nid_hash, + int nid_curve, chunk_t data, chunk_t signature) +{ + const EC_GROUP *my_group; + EC_GROUP *req_group; + chunk_t hash; + bool valid; + + req_group = EC_GROUP_new_by_curve_name(nid_curve); + if (!req_group) { - goto error; + DBG1("signature scheme %N not supported in EC (required curve " + "not supported)", signature_scheme_names, scheme); + return FALSE; } - valid = (ECDSA_do_verify(hash.ptr, hash.len, sig, this->ec) == 1); - -error: - if (sig) + my_group = EC_KEY_get0_group(this->ec); + if (EC_GROUP_cmp(my_group, req_group, NULL) != 0) { - ECDSA_SIG_free(sig); + DBG1("signature scheme %N not supported by private key", + signature_scheme_names, scheme); + return FALSE; } - if (hash_type != NID_undef) + EC_GROUP_free(req_group); + if (!openssl_hash_chunk(nid_hash, data, &hash)) { - chunk_free(&hash); + return FALSE; } + valid = verify_signature(this, hash, signature); + chunk_free(&hash); return valid; } - /** - * Verification of the default signature using SHA-1 + * Verification of a DER encoded signature as in RFC 3279 */ -static bool verify_default_signature(private_openssl_ec_public_key_t *this, - chunk_t data, chunk_t signature) +static bool verify_der_signature(private_openssl_ec_public_key_t *this, + int nid_hash, chunk_t data, chunk_t signature) { + chunk_t hash; bool valid = FALSE; - chunk_t hash = chunk_empty; - u_char *p; - ECDSA_SIG *sig; - + /* remove any preceding 0-bytes from signature */ - while (signature.len && *(signature.ptr) == 0x00) - { - signature.len -= 1; - signature.ptr++; - } - - p = signature.ptr; - sig = d2i_ECDSA_SIG(NULL, (const u_char**)&p, signature.len); - if (!sig) - { - return FALSE; - } - - if (!openssl_hash_chunk(NID_sha1, data, &hash)) + while (signature.len && signature.ptr[0] == 0x00) { - goto error; + signature = chunk_skip(signature, 1); } - - valid = (ECDSA_do_verify(hash.ptr, hash.len, sig, this->ec) == 1); - -error: - if (sig) + if (openssl_hash_chunk(nid_hash, data, &hash)) { - ECDSA_SIG_free(sig); + valid = ECDSA_verify(0, hash.ptr, hash.len, + signature.ptr, signature.len, this->ec); + free(hash.ptr); } - chunk_free(&hash); return valid; } @@ -162,21 +137,30 @@ static key_type_t get_type(private_openssl_ec_public_key_t *this) /** * Implementation of public_key_t.verify. */ -static bool verify(private_openssl_ec_public_key_t *this, signature_scheme_t scheme, - chunk_t data, chunk_t signature) +static bool verify(private_openssl_ec_public_key_t *this, + signature_scheme_t scheme, chunk_t data, chunk_t signature) { switch (scheme) { + case SIGN_ECDSA_WITH_SHA1_DER: + return verify_der_signature(this, NID_sha1, data, signature); + case SIGN_ECDSA_WITH_SHA256_DER: + return verify_der_signature(this, NID_sha256, data, signature); + case SIGN_ECDSA_WITH_SHA384_DER: + return verify_der_signature(this, NID_sha384, data, signature); + case SIGN_ECDSA_WITH_SHA512_DER: + return verify_der_signature(this, NID_sha512, data, signature); case SIGN_ECDSA_WITH_NULL: - return verify_signature(this, NID_undef, data, signature); - case SIGN_ECDSA_WITH_SHA1: - return verify_default_signature(this, data, signature); + return verify_signature(this, data, signature); case SIGN_ECDSA_256: - return verify_signature(this, NID_sha256, data, signature); + return verify_curve_signature(this, scheme, NID_sha256, + NID_X9_62_prime256v1, data, signature); case SIGN_ECDSA_384: - return verify_signature(this, NID_sha384, data, signature); + return verify_curve_signature(this, scheme, NID_sha384, + NID_secp384r1, data, signature); case SIGN_ECDSA_521: - return verify_signature(this, NID_sha512, data, signature); + return verify_curve_signature(this, scheme, NID_sha512, + NID_secp521r1, data, signature); default: DBG1("signature scheme %N not supported in EC", signature_scheme_names, scheme); @@ -187,7 +171,8 @@ static bool verify(private_openssl_ec_public_key_t *this, signature_scheme_t sch /** * Implementation of public_key_t.get_keysize. */ -static bool encrypt_(private_openssl_ec_public_key_t *this, chunk_t crypto, chunk_t *plain) +static bool encrypt_(private_openssl_ec_public_key_t *this, + chunk_t crypto, chunk_t *plain) { DBG1("EC public key encryption not implemented"); return FALSE; @@ -202,64 +187,85 @@ static size_t get_keysize(private_openssl_ec_public_key_t *this) } /** - * Implementation of public_key_t.get_id. + * Calculate fingerprint from a EC_KEY, also used in ec private key. */ -static identification_t *get_id(private_openssl_ec_public_key_t *this, - id_type_t type) +bool openssl_ec_fingerprint(EC_KEY *ec, key_encoding_type_t type, chunk_t *fp) { + hasher_t *hasher; + chunk_t key; + u_char *p; + + if (lib->encoding->get_cache(lib->encoding, type, ec, fp)) + { + return TRUE; + } switch (type) { - case ID_PUBKEY_INFO_SHA1: - return this->keyid_info; - case ID_PUBKEY_SHA1: - return this->keyid; + case KEY_ID_PUBKEY_SHA1: + key = chunk_alloc(i2o_ECPublicKey(ec, NULL)); + p = key.ptr; + i2o_ECPublicKey(ec, &p); + break; + case KEY_ID_PUBKEY_INFO_SHA1: + key = chunk_alloc(i2d_EC_PUBKEY(ec, NULL)); + p = key.ptr; + i2d_EC_PUBKEY(ec, &p); + break; default: - return NULL; + return FALSE; + } + hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); + if (!hasher) + { + DBG1("SHA1 hash algorithm not supported, fingerprinting failed"); + free(key.ptr); + return FALSE; } + hasher->allocate_hash(hasher, key, fp); + hasher->destroy(hasher); + free(key.ptr); + lib->encoding->cache(lib->encoding, type, ec, *fp); + return TRUE; } /** - * Encodes the public key - */ -static chunk_t get_encoding_raw(EC_KEY *ec) + * Implementation of private_key_t.get_fingerprint. + */ +static bool get_fingerprint(private_openssl_ec_public_key_t *this, + key_encoding_type_t type, chunk_t *fingerprint) { - /* since the points can be stored in three different forms this may not - * be correct for all cases */ - const EC_GROUP *group = EC_KEY_get0_group(ec); - const EC_POINT *pub = EC_KEY_get0_public_key(ec); - chunk_t enc = chunk_alloc(EC_POINT_point2oct(group, pub, - POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL)); - EC_POINT_point2oct(group, pub, POINT_CONVERSION_UNCOMPRESSED, - enc.ptr, enc.len, NULL); - return enc; + return openssl_ec_fingerprint(this->ec, type, fingerprint); } /** - * Encodes the public key info (public key with ec parameters) - */ -static chunk_t get_encoding_full(EC_KEY *ec) -{ - chunk_t enc = chunk_alloc(i2d_EC_PUBKEY(ec, NULL)); - u_char *p = enc.ptr; - i2d_EC_PUBKEY(ec, &p); - return enc; -} - -/* - * Implementation of public_key_t.get_encoding. + * Implementation of private_key_t.get_encoding. */ -static chunk_t get_encoding(private_openssl_ec_public_key_t *this) +static bool get_encoding(private_openssl_ec_public_key_t *this, + key_encoding_type_t type, chunk_t *encoding) { - return get_encoding_full(this->ec); + u_char *p; + + switch (type) + { + case KEY_PUB_SPKI_ASN1_DER: + { + *encoding = chunk_alloc(i2d_EC_PUBKEY(this->ec, NULL)); + p = encoding->ptr; + i2d_EC_PUBKEY(this->ec, &p); + return TRUE; + } + default: + return FALSE; + } } /** * Implementation of public_key_t.get_ref. */ -static private_openssl_ec_public_key_t* get_ref(private_openssl_ec_public_key_t *this) +static public_key_t* get_ref(private_openssl_ec_public_key_t *this) { ref_get(&this->ref); - return this; + return &this->public.interface; } /** @@ -271,10 +277,9 @@ static void destroy(private_openssl_ec_public_key_t *this) { if (this->ec) { + lib->encoding->clear_cache(lib->encoding, this->ec); EC_KEY_free(this->ec); } - DESTROY_IF(this->keyid); - DESTROY_IF(this->keyid_info); free(this); } } @@ -282,168 +287,62 @@ static void destroy(private_openssl_ec_public_key_t *this) /** * Generic private constructor */ -static private_openssl_ec_public_key_t *openssl_ec_public_key_create_empty() +static private_openssl_ec_public_key_t *create_empty() { private_openssl_ec_public_key_t *this = malloc_thing(private_openssl_ec_public_key_t); - + this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type; this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify; this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt_; this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize; - this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id; - this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding; + this->public.interface.equals = public_key_equals; + this->public.interface.get_fingerprint = (bool(*)(public_key_t*, key_encoding_type_t type, chunk_t *fp))get_fingerprint; + this->public.interface.has_fingerprint = (bool(*)(public_key_t*, chunk_t fp))public_key_has_fingerprint; + this->public.interface.get_encoding = (bool(*)(public_key_t*, key_encoding_type_t type, chunk_t *encoding))get_encoding; this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref; this->public.interface.destroy = (void (*)(public_key_t *this))destroy; - + this->ec = NULL; - this->keyid = NULL; - this->keyid_info = NULL; this->ref = 1; - + return this; } /** - * Build key identifier from the public key using SHA1 hashed publicKey(Info). - * Also used in openssl_ec_private_key.c. + * See header. */ -bool openssl_ec_public_key_build_id(EC_KEY *ec, identification_t **keyid, - identification_t **keyid_info) +openssl_ec_public_key_t *openssl_ec_public_key_load(key_type_t type, + va_list args) { - chunk_t publicKeyInfo, publicKey, hash; - hasher_t *hasher; - - hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - if (hasher == NULL) - { - DBG1("SHA1 hash algorithm not supported, unable to use EC"); - return FALSE; - } - - publicKey = get_encoding_raw(ec); - - hasher->allocate_hash(hasher, publicKey, &hash); - *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash); - chunk_free(&hash); - - publicKeyInfo = get_encoding_full(ec); - - hasher->allocate_hash(hasher, publicKeyInfo, &hash); - *keyid_info = identification_create_from_encoding(ID_PUBKEY_INFO_SHA1, hash); - chunk_free(&hash); - - hasher->destroy(hasher); - chunk_free(&publicKeyInfo); - chunk_free(&publicKey); - - return TRUE; -} + private_openssl_ec_public_key_t *this; + chunk_t blob = chunk_empty; -/** - * Load a public key from an ASN1 encoded blob - */ -static openssl_ec_public_key_t *load(chunk_t blob) -{ - u_char *p = blob.ptr; - private_openssl_ec_public_key_t *this = openssl_ec_public_key_create_empty(); - - this->ec = d2i_EC_PUBKEY(NULL, (const u_char**)&p, blob.len); - - chunk_clear(&blob); - - if (!this->ec) + if (type != KEY_ECDSA) { - destroy(this); return NULL; } - - if (!openssl_ec_public_key_build_id(this->ec, &this->keyid, &this->keyid_info)) - { - destroy(this); - return NULL; - } - return &this->public; -} - -/** - * Create a public key from BIGNUM values, used in openssl_ec_private_key.c - */ -openssl_ec_public_key_t *openssl_ec_public_key_create_from_private_key(EC_KEY *ec) -{ - return (openssl_ec_public_key_t*)load(get_encoding_full(ec)); -} - -typedef struct private_builder_t private_builder_t; -/** - * Builder implementation for key loading - */ -struct private_builder_t { - /** implements the builder interface */ - builder_t public; - /** loaded public key */ - openssl_ec_public_key_t *key; -}; - -/** - * Implementation of builder_t.build - */ -static openssl_ec_public_key_t *build(private_builder_t *this) -{ - openssl_ec_public_key_t *key = this->key; - - free(this); - return key; -} -/** - * Implementation of builder_t.add - */ -static void add(private_builder_t *this, builder_part_t part, ...) -{ - if (!this->key) + while (TRUE) { - va_list args; - chunk_t chunk; - - switch (part) + switch (va_arg(args, builder_part_t)) { case BUILD_BLOB_ASN1_DER: - { - va_start(args, part); - chunk = va_arg(args, chunk_t); - this->key = load(chunk_clone(chunk)); - va_end(args); - return; - } - default: + blob = va_arg(args, chunk_t); + continue; + case BUILD_END: break; + default: + return NULL; } + break; } - if (this->key) - { - destroy((private_openssl_ec_public_key_t*)this->key); - } - builder_cancel(&this->public); -} - -/** - * Builder construction function - */ -builder_t *openssl_ec_public_key_builder(key_type_t type) -{ - private_builder_t *this; - - if (type != KEY_ECDSA) + this = create_empty(); + this->ec = d2i_EC_PUBKEY(NULL, (const u_char**)&blob.ptr, blob.len); + if (!this->ec) { + destroy(this); return NULL; } - - this = malloc_thing(private_builder_t); - - this->key = NULL; - this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add; - this->public.build = (void*(*)(builder_t *this))build; - return &this->public; } diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h index bdbb2fe6e..29d607d38 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h +++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h @@ -23,6 +23,7 @@ typedef struct openssl_ec_public_key_t openssl_ec_public_key_t; +#include <credentials/builder.h> #include <credentials/keys/public_key.h> /** @@ -37,11 +38,15 @@ struct openssl_ec_public_key_t { }; /** - * Create the builder for a public key. + * Load a ECDSA public key using OpenSSL. + * + * Accepts a BUILD_BLOB_ASN1_DER argument. * * @param type type of the key, must be KEY_ECDSA - * @return builder instance + * @param args builder_part_t argument list + * @return loaded key, NULL on failure */ -builder_t *openssl_ec_public_key_builder(key_type_t type); +openssl_ec_public_key_t *openssl_ec_public_key_load(key_type_t type, + va_list args); #endif /** OPENSSL_EC_PUBLIC_KEY_H_ @}*/ diff --git a/src/libstrongswan/plugins/openssl/openssl_hasher.c b/src/libstrongswan/plugins/openssl/openssl_hasher.c index 90a5229d5..7556bc594 100644 --- a/src/libstrongswan/plugins/openssl/openssl_hasher.c +++ b/src/libstrongswan/plugins/openssl/openssl_hasher.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2008 Tobias Brunner - * Hochschule fuer Technik Rapperswil + * 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 @@ -23,19 +23,19 @@ typedef struct private_openssl_hasher_t private_openssl_hasher_t; * Private data of openssl_hasher_t */ struct private_openssl_hasher_t { - + /** * Public part of this class. */ openssl_hasher_t public; - + /** * the hasher to use */ const EVP_MD *hasher; - + /** - * the current digest context + * the current digest context */ EVP_MD_CTX *ctx; }; @@ -49,7 +49,7 @@ typedef struct { * Identifier specified in IKEv2 */ int ikev2_id; - + /** * Name of the algorithm, as used in OpenSSL */ @@ -76,7 +76,7 @@ static openssl_algorithm_t integrity_algs[] = { /** * Look up an OpenSSL algorithm name */ -static char* lookup_algorithm(openssl_algorithm_t *openssl_algo, +static char* lookup_algorithm(openssl_algorithm_t *openssl_algo, u_int16_t ikev2_algo) { while (openssl_algo->ikev2_id != END_OF_LIST) @@ -133,7 +133,7 @@ static void allocate_hash(private_openssl_hasher_t *this, chunk_t chunk, } else { - get_hash(this, chunk, NULL); + get_hash(this, chunk, NULL); } } @@ -152,7 +152,7 @@ static void destroy (private_openssl_hasher_t *this) openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo) { private_openssl_hasher_t *this; - + char* name = lookup_algorithm(integrity_algs, algo); if (!name) { @@ -161,7 +161,7 @@ openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo) } this = malloc_thing(private_openssl_hasher_t); - + this->hasher = EVP_get_digestbyname(name); if (!this->hasher) { @@ -169,17 +169,17 @@ openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo) free(this); return NULL; } - + this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash; this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash; this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size; this->public.hasher_interface.reset = (void (*) (hasher_t*))reset; this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy; - + this->ctx = EVP_MD_CTX_create(); - + /* initialization */ reset(this); - + return &this->public; } diff --git a/src/libstrongswan/plugins/openssl/openssl_hasher.h b/src/libstrongswan/plugins/openssl/openssl_hasher.h index aec5bc7dd..fd7a043d1 100644 --- a/src/libstrongswan/plugins/openssl/openssl_hasher.h +++ b/src/libstrongswan/plugins/openssl/openssl_hasher.h @@ -29,7 +29,7 @@ typedef struct openssl_hasher_t openssl_hasher_t; * Implementation of hashers using OpenSSL. */ struct openssl_hasher_t { - + /** * The hasher_t interface. */ @@ -38,7 +38,7 @@ struct openssl_hasher_t { /** * Constructor to create openssl_hasher_t. - * + * * @param algo algorithm * @return openssl_hasher_t, NULL if not supported */ diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c index ce6716f5a..548a76bb4 100644 --- a/src/libstrongswan/plugins/openssl/openssl_plugin.c +++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c @@ -18,12 +18,13 @@ #include <openssl/evp.h> #include <openssl/engine.h> #include <openssl/crypto.h> -#include <pthread.h> #include "openssl_plugin.h" #include <library.h> -#include <utils/mutex.h> +#include <threading/thread.h> +#include <threading/mutex.h> +#include "openssl_util.h" #include "openssl_crypter.h" #include "openssl_hasher.h" #include "openssl_diffie_hellman.h" @@ -82,7 +83,7 @@ struct CRYPTO_dynlock_value { static struct CRYPTO_dynlock_value *create_function(const char *file, int line) { struct CRYPTO_dynlock_value *lock; - + lock = malloc_thing(struct CRYPTO_dynlock_value); lock->mutex = mutex_create(MUTEX_TYPE_DEFAULT); return lock; @@ -119,7 +120,7 @@ static void destroy_function(struct CRYPTO_dynlock_value *lock, */ static unsigned long id_function(void) { - return (unsigned long)pthread_self(); + return (unsigned long)thread_current_id(); } /** @@ -130,12 +131,12 @@ static void threading_init() int i, num_locks; CRYPTO_set_id_callback(id_function); - CRYPTO_set_locking_callback(locking_function); - + CRYPTO_set_locking_callback(locking_function); + CRYPTO_set_dynlock_create_callback(create_function); CRYPTO_set_dynlock_lock_callback(lock_function); CRYPTO_set_dynlock_destroy_callback(destroy_function); - + num_locks = CRYPTO_num_locks(); mutex = malloc(sizeof(mutex_t*) * num_locks); for (i = 0; i < num_locks; i++) @@ -150,7 +151,7 @@ static void threading_init() static void threading_cleanup() { int i, num_locks; - + num_locks = CRYPTO_num_locks(); for (i = 0; i < num_locks; i++) { @@ -169,25 +170,31 @@ static void destroy(private_openssl_plugin_t *this) (crypter_constructor_t)openssl_crypter_create); lib->crypto->remove_hasher(lib->crypto, (hasher_constructor_t)openssl_hasher_create); - lib->crypto->remove_dh(lib->crypto, + lib->crypto->remove_dh(lib->crypto, (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->remove_dh(lib->crypto, + lib->crypto->remove_dh(lib->crypto, (dh_constructor_t)openssl_ec_diffie_hellman_create); lib->creds->remove_builder(lib->creds, - (builder_constructor_t)openssl_rsa_private_key_builder); + (builder_function_t)openssl_rsa_private_key_load); + lib->creds->remove_builder(lib->creds, + (builder_function_t)openssl_rsa_private_key_gen); lib->creds->remove_builder(lib->creds, - (builder_constructor_t)openssl_rsa_public_key_builder); + (builder_function_t)openssl_rsa_private_key_connect); lib->creds->remove_builder(lib->creds, - (builder_constructor_t)openssl_ec_private_key_builder); + (builder_function_t)openssl_rsa_public_key_load); lib->creds->remove_builder(lib->creds, - (builder_constructor_t)openssl_ec_public_key_builder); - + (builder_function_t)openssl_ec_private_key_load); + lib->creds->remove_builder(lib->creds, + (builder_function_t)openssl_ec_private_key_gen); + lib->creds->remove_builder(lib->creds, + (builder_function_t)openssl_ec_public_key_load); + ENGINE_cleanup(); EVP_cleanup(); CONF_modules_free(); - + threading_cleanup(); - + free(this); } @@ -197,18 +204,18 @@ static void destroy(private_openssl_plugin_t *this) plugin_t *plugin_create() { private_openssl_plugin_t *this = malloc_thing(private_openssl_plugin_t); - + this->public.plugin.destroy = (void(*)(plugin_t*))destroy; - + threading_init(); - + OPENSSL_config(NULL); OpenSSL_add_all_algorithms(); - + /* activate support for hardware accelerators */ ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); - + /* crypter */ lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC, (crypter_constructor_t)openssl_crypter_create); @@ -230,7 +237,7 @@ plugin_t *plugin_create() (crypter_constructor_t)openssl_crypter_create); lib->crypto->add_crypter(lib->crypto, ENCR_NULL, (crypter_constructor_t)openssl_crypter_create); - + /* hasher */ lib->crypto->add_hasher(lib->crypto, HASH_SHA1, (hasher_constructor_t)openssl_hasher_create); @@ -248,48 +255,53 @@ plugin_t *plugin_create() (hasher_constructor_t)openssl_hasher_create); lib->crypto->add_hasher(lib->crypto, HASH_SHA512, (hasher_constructor_t)openssl_hasher_create); - - /* ec diffie hellman */ - lib->crypto->add_dh(lib->crypto, ECP_192_BIT, - (dh_constructor_t)openssl_ec_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, ECP_224_BIT, - (dh_constructor_t)openssl_ec_diffie_hellman_create); + + /* (ec) diffie hellman */ + lib->crypto->add_dh(lib->crypto, MODP_2048_BIT, + (dh_constructor_t)openssl_diffie_hellman_create); + lib->crypto->add_dh(lib->crypto, MODP_1536_BIT, + (dh_constructor_t)openssl_diffie_hellman_create); lib->crypto->add_dh(lib->crypto, ECP_256_BIT, (dh_constructor_t)openssl_ec_diffie_hellman_create); lib->crypto->add_dh(lib->crypto, ECP_384_BIT, (dh_constructor_t)openssl_ec_diffie_hellman_create); lib->crypto->add_dh(lib->crypto, ECP_521_BIT, (dh_constructor_t)openssl_ec_diffie_hellman_create); - - /* diffie hellman */ - lib->crypto->add_dh(lib->crypto, MODP_2048_BIT, - (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_1536_BIT, - (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_3072_BIT, + lib->crypto->add_dh(lib->crypto, ECP_224_BIT, + (dh_constructor_t)openssl_ec_diffie_hellman_create); + lib->crypto->add_dh(lib->crypto, ECP_192_BIT, + (dh_constructor_t)openssl_ec_diffie_hellman_create); + lib->crypto->add_dh(lib->crypto, MODP_3072_BIT, (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_4096_BIT, + lib->crypto->add_dh(lib->crypto, MODP_4096_BIT, (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_6144_BIT, + lib->crypto->add_dh(lib->crypto, MODP_6144_BIT, (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_8192_BIT, + lib->crypto->add_dh(lib->crypto, MODP_8192_BIT, (dh_constructor_t)openssl_diffie_hellman_create); lib->crypto->add_dh(lib->crypto, MODP_1024_BIT, (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_768_BIT, + lib->crypto->add_dh(lib->crypto, MODP_768_BIT, (dh_constructor_t)openssl_diffie_hellman_create); - + /* rsa */ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, - (builder_constructor_t)openssl_rsa_private_key_builder); + (builder_function_t)openssl_rsa_private_key_load); + lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, + (builder_function_t)openssl_rsa_private_key_gen); + lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, + (builder_function_t)openssl_rsa_private_key_connect); lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, - (builder_constructor_t)openssl_rsa_public_key_builder); - + (builder_function_t)openssl_rsa_public_key_load); + /* ec */ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA, - (builder_constructor_t)openssl_ec_private_key_builder); + (builder_function_t)openssl_ec_private_key_load); + lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA, + (builder_function_t)openssl_ec_private_key_gen); lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA, - (builder_constructor_t)openssl_ec_public_key_builder); - + (builder_function_t)openssl_ec_public_key_load); + return &this->public.plugin; } + diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c index 95c0ffdc8..078f889a6 100644 --- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2009 Martin Willi * Copyright (C) 2008 Tobias Brunner * Hochschule fuer Technik Rapperswil * @@ -37,42 +38,25 @@ struct private_openssl_rsa_private_key_t { * Public interface for this signer. */ openssl_rsa_private_key_t public; - + /** * RSA object from OpenSSL */ RSA *rsa; - + /** * TRUE if the key is from an OpenSSL ENGINE and might not be readable */ bool engine; /** - * Keyid formed as a SHA-1 hash of a privateKey object - */ - identification_t* keyid; - - /** - * Keyid formed as a SHA-1 hash of a privateKeyInfo object - */ - identification_t* keyid_info; - - /** * reference count */ - refcount_t ref; + refcount_t ref; }; -/** - * shared functions, implemented in openssl_rsa_public_key.c - */ -bool openssl_rsa_public_key_build_id(RSA *rsa, identification_t **keyid, - identification_t **keyid_info); - - -openssl_rsa_public_key_t *openssl_rsa_public_key_create_from_n_e(BIGNUM *n, BIGNUM *e); - +/* implemented in rsa public key */ +bool openssl_rsa_fingerprint(RSA *rsa, key_encoding_type_t type, chunk_t *fp); /** * Build an EMPSA PKCS1 signature described in PKCS#1 @@ -104,7 +88,7 @@ static bool build_emsa_pkcs1_signature(private_openssl_rsa_private_key_t *this, { return FALSE; } - + ctx = EVP_MD_CTX_create(); key = EVP_PKEY_new(); if (!ctx || !key) @@ -127,7 +111,7 @@ static bool build_emsa_pkcs1_signature(private_openssl_rsa_private_key_t *this, { success = TRUE; } - + error: if (key) { @@ -156,7 +140,7 @@ static key_type_t get_type(private_openssl_rsa_private_key_t *this) /** * Implementation of openssl_rsa_private_key.sign. */ -static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t scheme, +static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature) { switch (scheme) @@ -201,95 +185,56 @@ static size_t get_keysize(private_openssl_rsa_private_key_t *this) } /** - * Implementation of openssl_rsa_private_key.get_id. - */ -static identification_t* get_id(private_openssl_rsa_private_key_t *this, - id_type_t type) -{ - switch (type) - { - case ID_PUBKEY_INFO_SHA1: - return this->keyid_info; - case ID_PUBKEY_SHA1: - return this->keyid; - default: - return NULL; - } -} - -/** * Implementation of openssl_rsa_private_key.get_public_key. */ -static openssl_rsa_public_key_t* get_public_key(private_openssl_rsa_private_key_t *this) +static public_key_t* get_public_key(private_openssl_rsa_private_key_t *this) { - return openssl_rsa_public_key_create_from_n_e(this->rsa->n, this->rsa->e); + chunk_t enc; + public_key_t *key; + u_char *p; + + enc = chunk_alloc(i2d_RSAPublicKey(this->rsa, NULL)); + p = enc.ptr; + i2d_RSAPublicKey(this->rsa, &p); + key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, + BUILD_BLOB_ASN1_DER, enc, BUILD_END); + free(enc.ptr); + return key; } /** - * Implementation of openssl_rsa_private_key.equals. + * Implementation of public_key_t.get_fingerprint. */ -static bool equals(private_openssl_rsa_private_key_t *this, private_key_t *other) +static bool get_fingerprint(private_openssl_rsa_private_key_t *this, + key_encoding_type_t type, chunk_t *fingerprint) { - identification_t *keyid; - - if (&this->public.interface == other) - { - return TRUE; - } - if (other->get_type(other) != KEY_RSA) - { - return FALSE; - } - keyid = other->get_id(other, ID_PUBKEY_SHA1); - if (keyid && keyid->equals(keyid, this->keyid)) - { - return TRUE; - } - keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1); - if (keyid && keyid->equals(keyid, this->keyid_info)) - { - return TRUE; - } - return FALSE; + return openssl_rsa_fingerprint(this->rsa, type, fingerprint); } -/** - * Implementation of openssl_rsa_private_key.belongs_to. +/* + * Implementation of public_key_t.get_encoding. */ -static bool belongs_to(private_openssl_rsa_private_key_t *this, public_key_t *public) +static bool get_encoding(private_openssl_rsa_private_key_t *this, + key_encoding_type_t type, chunk_t *encoding) { - identification_t *keyid; + u_char *p; - if (public->get_type(public) != KEY_RSA) + if (this->engine) { return FALSE; } - keyid = public->get_id(public, ID_PUBKEY_SHA1); - if (keyid && keyid->equals(keyid, this->keyid)) - { - return TRUE; - } - keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1); - if (keyid && keyid->equals(keyid, this->keyid_info)) - { - return TRUE; - } - return FALSE; -} - -/** - * Implementation of private_key_t.get_encoding. - */ -static chunk_t get_encoding(private_openssl_rsa_private_key_t *this) -{ - chunk_t enc = chunk_empty; - if (!this->engine) + switch (type) { - enc = chunk_alloc(i2d_RSAPrivateKey(this->rsa, NULL)); - u_char *p = enc.ptr; - i2d_RSAPrivateKey(this->rsa, &p); + case KEY_PRIV_ASN1_DER: + { + *encoding = chunk_alloc(i2d_RSAPrivateKey(this->rsa, NULL)); + p = encoding->ptr; + i2d_RSAPrivateKey(this->rsa, &p); + return TRUE; + } + default: + return FALSE; } - return enc; } /** @@ -299,7 +244,6 @@ static private_openssl_rsa_private_key_t* get_ref(private_openssl_rsa_private_ke { ref_get(&this->ref); return this; - } /** @@ -311,10 +255,9 @@ static void destroy(private_openssl_rsa_private_key_t *this) { if (this->rsa) { + lib->encoding->clear_cache(lib->encoding, this->rsa); RSA_free(this->rsa); } - DESTROY_IF(this->keyid); - DESTROY_IF(this->keyid_info); free(this); } } @@ -322,238 +265,215 @@ static void destroy(private_openssl_rsa_private_key_t *this) /** * Internal generic constructor */ -static private_openssl_rsa_private_key_t *openssl_rsa_private_key_create_empty(void) +static private_openssl_rsa_private_key_t *create_empty(void) { private_openssl_rsa_private_key_t *this = malloc_thing(private_openssl_rsa_private_key_t); - + this->public.interface.get_type = (key_type_t (*) (private_key_t*))get_type; this->public.interface.sign = (bool (*) (private_key_t*, signature_scheme_t, chunk_t, chunk_t*))sign; this->public.interface.decrypt = (bool (*) (private_key_t*, chunk_t, chunk_t*))decrypt; this->public.interface.get_keysize = (size_t (*) (private_key_t*))get_keysize; - this->public.interface.get_id = (identification_t* (*) (private_key_t*, id_type_t))get_id; this->public.interface.get_public_key = (public_key_t* (*) (private_key_t*))get_public_key; - this->public.interface.equals = (bool (*) (private_key_t*, private_key_t*))equals; - this->public.interface.belongs_to = (bool (*) (private_key_t*, public_key_t*))belongs_to; - this->public.interface.get_encoding = (chunk_t(*) (private_key_t*))get_encoding; + this->public.interface.equals = private_key_equals; + this->public.interface.belongs_to = private_key_belongs_to; + this->public.interface.get_fingerprint = (bool(*)(private_key_t*, key_encoding_type_t type, chunk_t *fp))get_fingerprint; + this->public.interface.has_fingerprint = (bool(*)(private_key_t*, chunk_t fp))private_key_has_fingerprint; + this->public.interface.get_encoding = (bool(*)(private_key_t*, key_encoding_type_t type, chunk_t *encoding))get_encoding; this->public.interface.get_ref = (private_key_t* (*) (private_key_t*))get_ref; this->public.interface.destroy = (void (*) (private_key_t*))destroy; - + this->engine = FALSE; - this->keyid = NULL; - this->keyid_info = NULL; this->ref = 1; - + return this; } /** - * Generate an RSA key of specified key size + * See header. */ -static openssl_rsa_private_key_t *generate(size_t key_size) +openssl_rsa_private_key_t *openssl_rsa_private_key_gen(key_type_t type, + va_list args) { - private_openssl_rsa_private_key_t *this = openssl_rsa_private_key_create_empty(); - - this->rsa = RSA_generate_key(key_size, PUBLIC_EXPONENT, NULL, NULL); - - if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info)) + private_openssl_rsa_private_key_t *this; + u_int key_size = 0; + + while (TRUE) + { + switch (va_arg(args, builder_part_t)) + { + case BUILD_KEY_SIZE: + key_size = va_arg(args, u_int); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; + } + if (!key_size) { - destroy(this); return NULL; } - + this = create_empty(); + this->rsa = RSA_generate_key(key_size, PUBLIC_EXPONENT, NULL, NULL); + return &this->public; } /** - * load private key from an ASN1 encoded blob + * See header */ -static openssl_rsa_private_key_t *load(chunk_t blob) +openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type, + va_list args) { - u_char *p = blob.ptr; - private_openssl_rsa_private_key_t *this = openssl_rsa_private_key_create_empty(); - - this->rsa = d2i_RSAPrivateKey(NULL, (const u_char**)&p, blob.len); - - chunk_clear(&blob); - - if (!this->rsa) + private_openssl_rsa_private_key_t *this; + chunk_t blob, n, e, d, p, q, exp1, exp2, coeff; + + blob = n = e = d = p = q = exp1 = exp2 = coeff = chunk_empty; + while (TRUE) { - destroy(this); - return NULL; + switch (va_arg(args, builder_part_t)) + { + case BUILD_BLOB_ASN1_DER: + blob = va_arg(args, chunk_t); + continue; + case BUILD_RSA_MODULUS: + n = va_arg(args, chunk_t); + continue; + case BUILD_RSA_PUB_EXP: + e = va_arg(args, chunk_t); + continue; + case BUILD_RSA_PRIV_EXP: + d = va_arg(args, chunk_t); + continue; + case BUILD_RSA_PRIME1: + p = va_arg(args, chunk_t); + continue; + case BUILD_RSA_PRIME2: + q = va_arg(args, chunk_t); + continue; + case BUILD_RSA_EXP1: + exp1 = va_arg(args, chunk_t); + continue; + case BUILD_RSA_EXP2: + exp2 = va_arg(args, chunk_t); + continue; + case BUILD_RSA_COEFF: + coeff = va_arg(args, chunk_t); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; } - - if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info)) + + this = create_empty(); + if (blob.ptr) { - destroy(this); - return NULL; + this->rsa = d2i_RSAPrivateKey(NULL, (const u_char**)&blob.ptr, blob.len); + if (this->rsa && RSA_check_key(this->rsa)) + { + return &this->public; + } } - - if (!RSA_check_key(this->rsa)) + else if (n.ptr && e.ptr && d.ptr && p.ptr && q.ptr && coeff.ptr) { - destroy(this); - return NULL; + this->rsa = RSA_new(); + this->rsa->n = BN_bin2bn((const u_char*)n.ptr, n.len, NULL); + this->rsa->e = BN_bin2bn((const u_char*)e.ptr, e.len, NULL); + this->rsa->d = BN_bin2bn((const u_char*)d.ptr, d.len, NULL); + this->rsa->p = BN_bin2bn((const u_char*)p.ptr, p.len, NULL); + this->rsa->q = BN_bin2bn((const u_char*)q.ptr, q.len, NULL); + if (exp1.ptr) + { + this->rsa->dmp1 = BN_bin2bn((const u_char*)exp1.ptr, exp1.len, NULL); + } + if (exp2.ptr) + { + this->rsa->dmq1 = BN_bin2bn((const u_char*)exp2.ptr, exp2.len, NULL); + } + this->rsa->iqmp = BN_bin2bn((const u_char*)coeff.ptr, coeff.len, NULL); + if (RSA_check_key(this->rsa)) + { + return &this->public; + } } - - return &this->public; + destroy(this); + return NULL; } /** - * load private key from a smart card + * See header. */ -static openssl_rsa_private_key_t *load_from_smartcard(char *keyid, char *pin) +openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type, + va_list args) { - private_openssl_rsa_private_key_t *this = NULL; + private_openssl_rsa_private_key_t *this; + char *keyid = NULL, *pin = NULL; EVP_PKEY *key; - char *engine_id = lib->settings->get_str(lib->settings, + char *engine_id; + ENGINE *engine; + + while (TRUE) + { + switch (va_arg(args, builder_part_t)) + { + case BUILD_SMARTCARD_KEYID: + keyid = va_arg(args, char*); + continue; + case BUILD_SMARTCARD_PIN: + pin = va_arg(args, char*); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; + } + if (!keyid || !pin) + { + return NULL; + } + + engine_id = lib->settings->get_str(lib->settings, "library.plugins.openssl.engine_id", "pkcs11"); - - ENGINE *engine = ENGINE_by_id(engine_id); + engine = ENGINE_by_id(engine_id); if (!engine) { DBG1("engine '%s' is not available", engine_id); return NULL; } - if (!ENGINE_init(engine)) { DBG1("failed to initialize engine '%s'", engine_id); - goto error; + ENGINE_free(engine); + return NULL; } - if (!ENGINE_ctrl_cmd_string(engine, "PIN", pin, 0)) { DBG1("failed to set PIN on engine '%s'", engine_id); - goto error; + ENGINE_free(engine); + return NULL; } - + key = ENGINE_load_private_key(engine, keyid, NULL, NULL); - if (!key) { - DBG1("failed to load private key with ID '%s' from engine '%s'", keyid, - engine_id); - goto error; - } - ENGINE_free(engine); - - this = openssl_rsa_private_key_create_empty(); - this->rsa = EVP_PKEY_get1_RSA(key); - this->engine = TRUE; - - if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info)) - { - destroy(this); + DBG1("failed to load private key with ID '%s' from engine '%s'", + keyid, engine_id); + ENGINE_free(engine); return NULL; } - return &this->public; - -error: ENGINE_free(engine); - return NULL; -} - -typedef struct private_builder_t private_builder_t; -/** - * Builder implementation for key loading/generation - */ -struct private_builder_t { - /** implements the builder interface */ - builder_t public; - /** loaded/generated private key */ - openssl_rsa_private_key_t *key; - /** temporary stored smartcard key ID */ - char *keyid; - /** temporary stored smartcard pin */ - char *pin; -}; -/** - * Implementation of builder_t.build - */ -static openssl_rsa_private_key_t *build(private_builder_t *this) -{ - openssl_rsa_private_key_t *key = this->key; - - if (this->keyid && this->pin) - { - key = load_from_smartcard(this->keyid, this->pin); - } - free(this); - return key; -} - -/** - * Implementation of builder_t.add - */ -static void add(private_builder_t *this, builder_part_t part, ...) -{ - if (!this->key) - { - va_list args; - chunk_t chunk; - - switch (part) - { - case BUILD_BLOB_ASN1_DER: - { - va_start(args, part); - chunk = va_arg(args, chunk_t); - this->key = load(chunk_clone(chunk)); - va_end(args); - return; - } - case BUILD_KEY_SIZE: - { - va_start(args, part); - this->key = generate(va_arg(args, u_int)); - va_end(args); - return; - } - case BUILD_SMARTCARD_KEYID: - { - va_start(args, part); - this->keyid = va_arg(args, char*); - va_end(args); - return; - } - case BUILD_SMARTCARD_PIN: - { - va_start(args, part); - this->pin = va_arg(args, char*); - va_end(args); - return; - } - default: - break; - } - } - if (this->key) - { - destroy((private_openssl_rsa_private_key_t*)this->key); - } - builder_cancel(&this->public); -} + this = create_empty(); + this->rsa = EVP_PKEY_get1_RSA(key); + this->engine = TRUE; -/** - * Builder construction function - */ -builder_t *openssl_rsa_private_key_builder(key_type_t type) -{ - private_builder_t *this; - - if (type != KEY_RSA) - { - return NULL; - } - - this = malloc_thing(private_builder_t); - - this->key = NULL; - this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add; - this->public.build = (void*(*)(builder_t *this))build; - this->keyid = NULL; - this->pin = NULL; - return &this->public; } diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h index 53ec44b28..079dfa46a 100644 --- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h +++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h @@ -21,6 +21,7 @@ #ifndef OPENSSL_RSA_PRIVATE_KEY_H_ #define OPENSSL_RSA_PRIVATE_KEY_H_ +#include <credentials/builder.h> #include <credentials/keys/private_key.h> typedef struct openssl_rsa_private_key_t openssl_rsa_private_key_t; @@ -37,11 +38,40 @@ struct openssl_rsa_private_key_t { }; /** - * Create the builder for a private key. + * Generate a RSA private key using OpenSSL. + * + * Accepts the BUILD_KEY_SIZE argument. + * + * @param type type of the key, must be KEY_RSA + * @param args builder_part_t argument list + * @return generated key, NULL on failure + */ +openssl_rsa_private_key_t *openssl_rsa_private_key_gen(key_type_t type, + va_list args); + +/** + * Load a RSA private key using OpenSSL. + * + * Accepts a BUILD_BLOB_ASN1_DER argument. + * + * @param type type of the key, must be KEY_RSA + * @param args builder_part_t argument list + * @return loaded key, NULL on failure + */ +openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type, + va_list args); + +/** + * Connect to a RSA private key on a smartcard. + * + * Accepts the BUILD_SMARTCARD_KEYID and the BUILD_SMARTCARD_PIN + * arguments. * * @param type type of the key, must be KEY_RSA - * @return builder instance + * @param args builder_part_t argument list + * @return loaded key, NULL on failure */ -builder_t *openssl_rsa_private_key_builder(key_type_t type); +openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type, + va_list args); #endif /** OPENSSL_RSA_PRIVATE_KEY_H_ @}*/ diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c index bc1ba35b6..422262b19 100644 --- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2009 Martin Willi * Copyright (C) 2008 Tobias Brunner * Hochschule fuer Technik Rapperswil * @@ -31,22 +32,12 @@ struct private_openssl_rsa_public_key_t { * Public interface for this signer. */ openssl_rsa_public_key_t public; - + /** * RSA object from OpenSSL */ RSA *rsa; - - /** - * Keyid formed as a SHA-1 hash of a publicKeyInfo object - */ - identification_t *keyid_info; - - /** - * Keyid formed as a SHA-1 hash of a publicKey object - */ - identification_t *keyid; - + /** * reference counter */ @@ -109,7 +100,7 @@ static bool verify_emsa_pkcs1_signature(private_openssl_rsa_public_key_t *this, goto error; } valid = (EVP_VerifyFinal(ctx, signature.ptr, signature.len, key) == 1); - + error: if (key) { @@ -134,7 +125,7 @@ static key_type_t get_type(private_openssl_rsa_public_key_t *this) /** * Implementation of public_key_t.verify. */ -static bool verify(private_openssl_rsa_public_key_t *this, signature_scheme_t scheme, +static bool verify(private_openssl_rsa_public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature) { switch (scheme) @@ -163,41 +154,14 @@ static bool verify(private_openssl_rsa_public_key_t *this, signature_scheme_t sc /** * Implementation of public_key_t.get_keysize. */ -static bool encrypt_(private_openssl_rsa_public_key_t *this, chunk_t crypto, chunk_t *plain) +static bool encrypt_(private_openssl_rsa_public_key_t *this, + chunk_t crypto, chunk_t *plain) { DBG1("RSA public key encryption not implemented"); return FALSE; } /** - * Implementation of public_key_t.equals. - */ -static bool equals(private_openssl_rsa_public_key_t *this, public_key_t *other) -{ - identification_t *keyid; - - if (&this->public.interface == other) - { - return TRUE; - } - if (other->get_type(other) != KEY_RSA) - { - return FALSE; - } - keyid = other->get_id(other, ID_PUBKEY_SHA1); - if (keyid && keyid->equals(keyid, this->keyid)) - { - return TRUE; - } - keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1); - if (keyid && keyid->equals(keyid, this->keyid_info)) - { - return TRUE; - } - return FALSE; -} - -/** * Implementation of public_key_t.get_keysize. */ static size_t get_keysize(private_openssl_rsa_public_key_t *this) @@ -206,79 +170,92 @@ static size_t get_keysize(private_openssl_rsa_public_key_t *this) } /** - * Implementation of public_key_t.get_id. + * Calculate fingerprint from a RSA key, also used in rsa private key. */ -static identification_t *get_id(private_openssl_rsa_public_key_t *this, - id_type_t type) +bool openssl_rsa_fingerprint(RSA *rsa, key_encoding_type_t type, chunk_t *fp) { + hasher_t *hasher; + chunk_t key; + u_char *p; + + if (lib->encoding->get_cache(lib->encoding, type, rsa, fp)) + { + return TRUE; + } switch (type) { - case ID_PUBKEY_INFO_SHA1: - return this->keyid_info; - case ID_PUBKEY_SHA1: - return this->keyid; + case KEY_ID_PUBKEY_SHA1: + key = chunk_alloc(i2d_RSAPublicKey(rsa, NULL)); + p = key.ptr; + i2d_RSAPublicKey(rsa, &p); + break; + case KEY_ID_PUBKEY_INFO_SHA1: + key = chunk_alloc(i2d_RSA_PUBKEY(rsa, NULL)); + p = key.ptr; + i2d_RSA_PUBKEY(rsa, &p); + break; default: - return NULL; + return FALSE; } + hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); + if (!hasher) + { + DBG1("SHA1 hash algorithm not supported, fingerprinting failed"); + free(key.ptr); + return FALSE; + } + hasher->allocate_hash(hasher, key, fp); + free(key.ptr); + hasher->destroy(hasher); + lib->encoding->cache(lib->encoding, type, rsa, *fp); + return TRUE; } /** - * Encodes the public key - */ -static chunk_t get_encoding_raw(RSA *rsa) -{ - chunk_t enc = chunk_alloc(i2d_RSAPublicKey(rsa, NULL)); - u_char *p = enc.ptr; - i2d_RSAPublicKey(rsa, &p); - return enc; -} - -/** - * Encodes the public key with the algorithm used + * Implementation of public_key_t.get_fingerprint. */ -static chunk_t get_encoding_with_algo(RSA *rsa) +static bool get_fingerprint(private_openssl_rsa_public_key_t *this, + key_encoding_type_t type, chunk_t *fingerprint) { - u_char *p; - chunk_t enc; - X509_PUBKEY *pubkey = X509_PUBKEY_new(); - - ASN1_OBJECT_free(pubkey->algor->algorithm); - pubkey->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption); - - if (pubkey->algor->parameter == NULL || - pubkey->algor->parameter->type != V_ASN1_NULL) - { - ASN1_TYPE_free(pubkey->algor->parameter); - pubkey->algor->parameter = ASN1_TYPE_new(); - pubkey->algor->parameter->type = V_ASN1_NULL; - } - - enc = get_encoding_raw(rsa); - M_ASN1_BIT_STRING_set(pubkey->public_key, enc.ptr, enc.len); - chunk_free(&enc); - - enc = chunk_alloc(i2d_X509_PUBKEY(pubkey, NULL)); - p = enc.ptr; - i2d_X509_PUBKEY(pubkey, &p); - X509_PUBKEY_free(pubkey); - return enc; + return openssl_rsa_fingerprint(this->rsa, type, fingerprint); } /* * Implementation of public_key_t.get_encoding. */ -static chunk_t get_encoding(private_openssl_rsa_public_key_t *this) +static bool get_encoding(private_openssl_rsa_public_key_t *this, + key_encoding_type_t type, chunk_t *encoding) { - return get_encoding_raw(this->rsa); + u_char *p; + + switch (type) + { + case KEY_PUB_SPKI_ASN1_DER: + { + *encoding = chunk_alloc(i2d_RSA_PUBKEY(this->rsa, NULL)); + p = encoding->ptr; + i2d_RSA_PUBKEY(this->rsa, &p); + return TRUE; + } + case KEY_PUB_ASN1_DER: + { + *encoding = chunk_alloc(i2d_RSAPublicKey(this->rsa, NULL)); + p = encoding->ptr; + i2d_RSAPublicKey(this->rsa, &p); + return TRUE; + } + default: + return FALSE; + } } /** * Implementation of public_key_t.get_ref. */ -static private_openssl_rsa_public_key_t* get_ref(private_openssl_rsa_public_key_t *this) +static public_key_t* get_ref(private_openssl_rsa_public_key_t *this) { ref_get(&this->ref); - return this; + return &this->public.interface; } /** @@ -290,10 +267,9 @@ static void destroy(private_openssl_rsa_public_key_t *this) { if (this->rsa) { + lib->encoding->clear_cache(lib->encoding, this->rsa); RSA_free(this->rsa); } - DESTROY_IF(this->keyid); - DESTROY_IF(this->keyid_info); free(this); } } @@ -301,179 +277,75 @@ static void destroy(private_openssl_rsa_public_key_t *this) /** * Generic private constructor */ -static private_openssl_rsa_public_key_t *openssl_rsa_public_key_create_empty() +static private_openssl_rsa_public_key_t *create_empty() { private_openssl_rsa_public_key_t *this = malloc_thing(private_openssl_rsa_public_key_t); - + this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type; this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify; this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt_; - this->public.interface.equals = (bool (*) (public_key_t*, public_key_t*))equals; + this->public.interface.equals = public_key_equals; this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize; - this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id; - this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding; + this->public.interface.get_fingerprint = (bool(*)(public_key_t*, key_encoding_type_t type, chunk_t *fp))get_fingerprint; + this->public.interface.has_fingerprint = (bool(*)(public_key_t*, chunk_t fp))public_key_has_fingerprint; + this->public.interface.get_encoding = (bool(*)(public_key_t*, key_encoding_type_t type, chunk_t *encoding))get_encoding; this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref; this->public.interface.destroy = (void (*)(public_key_t *this))destroy; - - this->keyid = NULL; - this->keyid_info = NULL; - this->ref = 1; - - return this; -} - -/** - * Build the RSA key identifier from n and e using SHA1 hashed publicKey(Info). - * Also used in openssl_rsa_private_key.c. - */ -bool openssl_rsa_public_key_build_id(RSA *rsa, identification_t **keyid, - identification_t **keyid_info) -{ - chunk_t publicKeyInfo, publicKey, hash; - hasher_t *hasher; - - hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - if (hasher == NULL) - { - DBG1("SHA1 hash algorithm not supported, unable to use RSA"); - return FALSE; - } - - publicKey = get_encoding_raw(rsa); - - hasher->allocate_hash(hasher, publicKey, &hash); - *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash); - chunk_free(&hash); - - publicKeyInfo = get_encoding_with_algo(rsa); - - hasher->allocate_hash(hasher, publicKeyInfo, &hash); - *keyid_info = identification_create_from_encoding(ID_PUBKEY_INFO_SHA1, hash); - chunk_free(&hash); - - hasher->destroy(hasher); - chunk_free(&publicKeyInfo); - chunk_free(&publicKey); - - return TRUE; -} - -/** - * Create a public key from BIGNUM values, used in openssl_rsa_private_key.c - */ -openssl_rsa_public_key_t *openssl_rsa_public_key_create_from_n_e(BIGNUM *n, BIGNUM *e) -{ - private_openssl_rsa_public_key_t *this = openssl_rsa_public_key_create_empty(); - - this->rsa = RSA_new(); - this->rsa->n = BN_dup(n); - this->rsa->e = BN_dup(e); - - if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info)) - { - destroy(this); - return NULL; - } - return &this->public; -} -/** - * Load a public key from an ASN1 encoded blob - */ -static openssl_rsa_public_key_t *load(chunk_t blob) -{ - u_char *p = blob.ptr; - private_openssl_rsa_public_key_t *this = openssl_rsa_public_key_create_empty(); - - this->rsa = d2i_RSAPublicKey(NULL, (const u_char**)&p, blob.len); - - chunk_clear(&blob); - - if (!this->rsa) - { - destroy(this); - return NULL; - } + this->rsa = NULL; + this->ref = 1; - if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info)) - { - destroy(this); - return NULL; - } - return &this->public; + return this; } -typedef struct private_builder_t private_builder_t; /** - * Builder implementation for key loading + * See header. */ -struct private_builder_t { - /** implements the builder interface */ - builder_t public; - /** loaded public key */ - openssl_rsa_public_key_t *key; -}; - -/** - * Implementation of builder_t.build - */ -static openssl_rsa_public_key_t *build(private_builder_t *this) +openssl_rsa_public_key_t *openssl_rsa_public_key_load(key_type_t type, + va_list args) { - openssl_rsa_public_key_t *key = this->key; - - free(this); - return key; -} + private_openssl_rsa_public_key_t *this; + chunk_t blob, n, e; -/** - * Implementation of builder_t.add - */ -static void add(private_builder_t *this, builder_part_t part, ...) -{ - if (!this->key) + n = e = blob = chunk_empty; + while (TRUE) { - va_list args; - chunk_t chunk; - - switch (part) + switch (va_arg(args, builder_part_t)) { case BUILD_BLOB_ASN1_DER: - { - va_start(args, part); - chunk = va_arg(args, chunk_t); - this->key = load(chunk_clone(chunk)); - va_end(args); - return; - } - default: + blob = va_arg(args, chunk_t); + continue; + case BUILD_RSA_MODULUS: + n = va_arg(args, chunk_t); + continue; + case BUILD_RSA_PUB_EXP: + e = va_arg(args, chunk_t); + continue; + case BUILD_END: break; + default: + return NULL; } + break; } - if (this->key) + + this = create_empty(); + if (blob.ptr) { - destroy((private_openssl_rsa_public_key_t*)this->key); + this->rsa = d2i_RSAPublicKey(NULL, (const u_char**)&blob.ptr, blob.len); + if (this->rsa) + { + return &this->public; + } } - builder_cancel(&this->public); -} - -/** - * Builder construction function - */ -builder_t *openssl_rsa_public_key_builder(key_type_t type) -{ - private_builder_t *this; - - if (type != KEY_RSA) + else if (n.ptr && e.ptr) { - return NULL; + this->rsa = RSA_new(); + this->rsa->n = BN_bin2bn((const u_char*)n.ptr, n.len, NULL); + this->rsa->e = BN_bin2bn((const u_char*)e.ptr, e.len, NULL); + return &this->public; } - - this = malloc_thing(private_builder_t); - - this->key = NULL; - this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add; - this->public.build = (void*(*)(builder_t *this))build; - - return &this->public; + destroy(this); + return NULL; } diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h index ff99ddbc5..620aa51ce 100644 --- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h +++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h @@ -37,11 +37,15 @@ struct openssl_rsa_public_key_t { }; /** - * Create the builder for a public key. + * Load a RSA public key using OpenSSL. + * + * Accepts a BUILD_BLOB_ASN1_DER argument. * * @param type type of the key, must be KEY_RSA - * @return builder instance + * @param args builder_part_t argument list + * @return loaded key, NULL on failure */ -builder_t *openssl_rsa_public_key_builder(key_type_t type); +openssl_rsa_public_key_t *openssl_rsa_public_key_load(key_type_t type, + va_list args); #endif /** OPENSSL_RSA_PUBLIC_KEY_H_ @}*/ diff --git a/src/libstrongswan/plugins/openssl/openssl_util.c b/src/libstrongswan/plugins/openssl/openssl_util.c index c8c453f64..55b18a524 100644 --- a/src/libstrongswan/plugins/openssl/openssl_util.c +++ b/src/libstrongswan/plugins/openssl/openssl_util.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2009 Martin Willi * Copyright (C) 2008 Tobias Brunner * Hochschule fuer Technik Rapperswil * @@ -18,6 +19,7 @@ #include <debug.h> #include <openssl/evp.h> +#include <openssl/x509.h> /** * Described in header. @@ -31,30 +33,30 @@ bool openssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash) { return FALSE; } - - ctx = EVP_MD_CTX_create(); + + ctx = EVP_MD_CTX_create(); if (!ctx) { goto error; } - + if (!EVP_DigestInit_ex(ctx, hasher, NULL)) { goto error; } - + if (!EVP_DigestUpdate(ctx, data.ptr, data.len)) { goto error; } - + *hash = chunk_alloc(hasher->md_size); if (!EVP_DigestFinal_ex(ctx, hash->ptr, NULL)) { chunk_free(hash); goto error; } - + ret = TRUE; error: if (ctx) @@ -70,18 +72,18 @@ error: bool openssl_bn_cat(int len, BIGNUM *a, BIGNUM *b, chunk_t *chunk) { int offset; - + chunk->len = len + (b ? len : 0); chunk->ptr = malloc(chunk->len); memset(chunk->ptr, 0, chunk->len); - + /* convert a */ offset = len - BN_num_bytes(a); if (!BN_bn2bin(a, chunk->ptr + offset)) { goto error; } - + /* optionally convert and concatenate b */ if (b) { @@ -90,8 +92,8 @@ bool openssl_bn_cat(int len, BIGNUM *a, BIGNUM *b, chunk_t *chunk) { goto error; } - } - + } + return TRUE; error: chunk_free(chunk); @@ -105,19 +107,20 @@ error: bool openssl_bn_split(chunk_t chunk, BIGNUM *a, BIGNUM *b) { int len; - + if ((chunk.len % 2) != 0) { return FALSE; } - + len = chunk.len / 2; - + if (!BN_bin2bn(chunk.ptr, len, a) || !BN_bin2bn(chunk.ptr + len, len, b)) { return FALSE; } - + return TRUE; } + diff --git a/src/libstrongswan/plugins/openssl/openssl_util.h b/src/libstrongswan/plugins/openssl/openssl_util.h index 6ba1ff07b..538008f2c 100644 --- a/src/libstrongswan/plugins/openssl/openssl_util.h +++ b/src/libstrongswan/plugins/openssl/openssl_util.h @@ -31,9 +31,9 @@ /** * Creates a hash of a given type of a chunk of data. - * + * * Note: this function allocates memory for the hash - * + * * @param hash_type NID of the hash * @param data the chunk of data to hash * @param hash chunk that contains the hash @@ -44,9 +44,9 @@ bool openssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash); /** * Concatenates two bignums into a chunk, thereby enfocing the length of * a single BIGNUM, if necessary, by pre-pending it with zeros. - * + * * Note: this function allocates memory for the chunk - * + * * @param len the length of a single BIGNUM * @param a first BIGNUM * @param b second BIGNUM @@ -57,7 +57,7 @@ bool openssl_bn_cat(int len, BIGNUM *a, BIGNUM *b, chunk_t *chunk); /** * Splits a chunk into two bignums of equal binary length. - * + * * @param chunk a chunk that contains the two BIGNUMs * @param a first BIGNUM * @param b second BIGNUM |