From ed7d79f96177044949744da10f4431c1d6242241 Mon Sep 17 00:00:00 2001 From: Rene Mayrhofer Date: Tue, 23 Feb 2010 10:34:14 +0000 Subject: [svn-upgrade] Integrating new upstream version, strongswan (4.3.6) --- src/libstrongswan/plugins/gmp/Makefile.in | 143 ++-- src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c | 78 +-- src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h | 4 +- src/libstrongswan/plugins/gmp/gmp_plugin.c | 36 +- src/libstrongswan/plugins/gmp/gmp_plugin.h | 2 +- .../plugins/gmp/gmp_rsa_private_key.c | 746 +++++++-------------- .../plugins/gmp/gmp_rsa_private_key.h | 24 +- src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c | 544 +++------------ src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h | 14 +- 9 files changed, 520 insertions(+), 1071 deletions(-) (limited to 'src/libstrongswan/plugins/gmp') diff --git a/src/libstrongswan/plugins/gmp/Makefile.in b/src/libstrongswan/plugins/gmp/Makefile.in index 8d5dff34b..3077ea7e8 100644 --- a/src/libstrongswan/plugins/gmp/Makefile.in +++ b/src/libstrongswan/plugins/gmp/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/gmp 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_gmp_la_DEPENDENCIES = am_libstrongswan_gmp_la_OBJECTS = gmp_plugin.lo gmp_diffie_hellman.lo \ @@ -59,6 +83,7 @@ libstrongswan_gmp_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) \ @@ -106,25 +131,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@ @@ -136,11 +158,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@ @@ -169,9 +194,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@ @@ -194,7 +219,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@ @@ -202,6 +227,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@ @@ -210,10 +236,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@ @@ -221,6 +249,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 @@ -246,9 +275,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/gmp/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/libstrongswan/plugins/gmp/Makefile + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/gmp/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libstrongswan/plugins/gmp/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -266,23 +295,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: @@ -309,21 +343,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 $@ $< @@ -346,7 +380,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 \ @@ -354,29 +388,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 @@ -397,13 +436,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 @@ -434,6 +477,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" @@ -455,6 +499,8 @@ dvi-am: html: html-am +html-am: + info: info-am info-am: @@ -463,18 +509,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 @@ -513,6 +569,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/gmp/gmp_diffie_hellman.c b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c index a03e83e66..ea7e6fdd2 100644 --- a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c +++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c @@ -282,7 +282,7 @@ static u_int8_t group18_modulus[] = { typedef struct modulus_entry_t modulus_entry_t; -/** +/** * Entry of the modulus list. */ struct modulus_entry_t { @@ -290,25 +290,25 @@ struct modulus_entry_t { * Group number as it is defined in file transform_substructure.h. */ diffie_hellman_group_t group; - + /** * Pointer to first byte of modulus (network order). */ u_int8_t *modulus; - - /* + + /* * Length of modulus in bytes. - */ + */ size_t modulus_len; - - /* + + /* * Optimum length of exponent in bytes. - */ + */ size_t opt_exponent_len; - /* + /* * Generator value. - */ + */ u_int16_t generator; }; @@ -336,47 +336,47 @@ struct private_gmp_diffie_hellman_t { * Public gmp_diffie_hellman_t interface. */ gmp_diffie_hellman_t public; - + /** * Diffie Hellman group number. */ u_int16_t group; - - /* + + /* * Generator value. - */ + */ mpz_t g; - + /** * My private value. */ mpz_t xa; - + /** * My public value. */ mpz_t ya; - + /** * Other public value. - */ + */ mpz_t yb; - + /** * Shared secret. - */ + */ mpz_t zz; /** * Modulus. */ mpz_t p; - + /** * Modulus length. */ size_t p_len; - + /** * Optimal exponent length. */ @@ -394,13 +394,13 @@ struct private_gmp_diffie_hellman_t { static void set_other_public_value(private_gmp_diffie_hellman_t *this, chunk_t value) { mpz_t p_min_1; - + mpz_init(p_min_1); mpz_sub_ui(p_min_1, this->p, 1); - + mpz_import(this->yb, value.len, 1, 1, 1, 0, value.ptr); - - /* check public value: + + /* check public value: * 1. 0 or 1 is invalid as 0^a = 0 and 1^a = 1 * 2. a public value larger or equal the modulus is invalid */ if (mpz_cmp_ui(this->yb, 1) > 0 && @@ -409,7 +409,7 @@ static void set_other_public_value(private_gmp_diffie_hellman_t *this, chunk_t v #ifdef EXTENDED_DH_TEST /* 3. test if y ^ q mod p = 1, where q = (p - 1)/2. */ mpz_t q, one; - + mpz_init(q); mpz_init(one); mpz_fdiv_q_2exp(q, p_min_1, 1); @@ -443,11 +443,11 @@ static void set_other_public_value(private_gmp_diffie_hellman_t *this, chunk_t v static void get_my_public_value(private_gmp_diffie_hellman_t *this,chunk_t *value) { value->len = this->p_len; - value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->ya); - if (value->ptr == NULL) - { - value->len = 0; - } + value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->ya); + if (value->ptr == NULL) + { + value->len = 0; + } } /** @@ -483,7 +483,7 @@ static status_t set_modulus(private_gmp_diffie_hellman_t *this) { int i; status_t status = NOT_FOUND; - + for (i = 0; i < (sizeof(modulus_entries) / sizeof(modulus_entry_t)); i++) { if (modulus_entries[i].group == this->group) @@ -533,7 +533,7 @@ gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group) 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; - + /* private variables */ this->group = group; mpz_init(this->p); @@ -542,10 +542,10 @@ gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group) mpz_init(this->xa); mpz_init(this->zz); mpz_init(this->g); - + this->computed = FALSE; - - /* find a modulus according to group */ + + /* find a modulus according to group */ if (set_modulus(this) != SUCCESS) { destroy(this); @@ -561,7 +561,7 @@ gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group) ansi_x9_42 = lib->settings->get_int(lib->settings, "libstrongswan.dh_exponent_ansi_x9_42", TRUE); - exponent_len = (ansi_x9_42) ? this->p_len : this->opt_exponent_len; + exponent_len = (ansi_x9_42) ? this->p_len : this->opt_exponent_len; rng->allocate_bytes(rng, exponent_len, &random); rng->destroy(rng); @@ -575,7 +575,7 @@ gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group) DBG2("size of DH secret exponent: %u bits", mpz_sizeinbase(this->xa, 2)); mpz_powm(this->ya, this->g, this->xa, this->p); - + return &this->public; } diff --git a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h index 774c31cc2..2a54eebb1 100644 --- a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h +++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h @@ -30,7 +30,7 @@ typedef struct gmp_diffie_hellman_t gmp_diffie_hellman_t; * Implementation of the Diffie-Hellman algorithm, as in RFC2631. Uses libgmp. */ struct gmp_diffie_hellman_t { - + /** * Implements diffie_hellman_t interface. */ @@ -39,7 +39,7 @@ struct gmp_diffie_hellman_t { /** * Creates a new gmp_diffie_hellman_t object. - * + * * @param group Diffie Hellman group number to use * @return gmp_diffie_hellman_t object, NULL if not supported */ diff --git a/src/libstrongswan/plugins/gmp/gmp_plugin.c b/src/libstrongswan/plugins/gmp/gmp_plugin.c index f6ea964c1..b70ff881c 100644 --- a/src/libstrongswan/plugins/gmp/gmp_plugin.c +++ b/src/libstrongswan/plugins/gmp/gmp_plugin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Martin Willi + * Copyright (C) 2008-2009 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -41,9 +41,11 @@ static void destroy(private_gmp_plugin_t *this) lib->crypto->remove_dh(lib->crypto, (dh_constructor_t)gmp_diffie_hellman_create); lib->creds->remove_builder(lib->creds, - (builder_constructor_t)gmp_rsa_private_key_builder); + (builder_function_t)gmp_rsa_private_key_gen); lib->creds->remove_builder(lib->creds, - (builder_constructor_t)gmp_rsa_public_key_builder); + (builder_function_t)gmp_rsa_private_key_load); + lib->creds->remove_builder(lib->creds, + (builder_function_t)gmp_rsa_public_key_load); free(this); } @@ -53,31 +55,33 @@ static void destroy(private_gmp_plugin_t *this) plugin_t *plugin_create() { private_gmp_plugin_t *this = malloc_thing(private_gmp_plugin_t); - + this->public.plugin.destroy = (void(*)(plugin_t*))destroy; - - lib->crypto->add_dh(lib->crypto, MODP_2048_BIT, + + lib->crypto->add_dh(lib->crypto, MODP_2048_BIT, (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_1536_BIT, + lib->crypto->add_dh(lib->crypto, MODP_1536_BIT, (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_3072_BIT, + lib->crypto->add_dh(lib->crypto, MODP_3072_BIT, (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_4096_BIT, + lib->crypto->add_dh(lib->crypto, MODP_4096_BIT, (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_6144_BIT, + lib->crypto->add_dh(lib->crypto, MODP_6144_BIT, (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_8192_BIT, + lib->crypto->add_dh(lib->crypto, MODP_8192_BIT, (dh_constructor_t)gmp_diffie_hellman_create); lib->crypto->add_dh(lib->crypto, MODP_1024_BIT, (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_768_BIT, + lib->crypto->add_dh(lib->crypto, MODP_768_BIT, (dh_constructor_t)gmp_diffie_hellman_create); - + + lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, + (builder_function_t)gmp_rsa_private_key_gen); lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, - (builder_constructor_t)gmp_rsa_private_key_builder); + (builder_function_t)gmp_rsa_private_key_load); lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, - (builder_constructor_t)gmp_rsa_public_key_builder); - + (builder_function_t)gmp_rsa_public_key_load); + return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/gmp/gmp_plugin.h b/src/libstrongswan/plugins/gmp/gmp_plugin.h index d707d78ea..77d53965d 100644 --- a/src/libstrongswan/plugins/gmp/gmp_plugin.h +++ b/src/libstrongswan/plugins/gmp/gmp_plugin.h @@ -16,7 +16,7 @@ /** * @defgroup gmp_p gmp * @ingroup plugins - * + * * @defgroup gmp_plugin gmp_plugin * @{ @ingroup gmp_p */ diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c index 259c8e9ad..1829bd459 100644 --- a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c +++ b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2008 Martin Willi + * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -26,7 +26,6 @@ #include #include #include -#include /** * Public exponent to use for key generation. @@ -43,89 +42,82 @@ struct private_gmp_rsa_private_key_t { * Public interface for this signer. */ gmp_rsa_private_key_t public; - - /** - * Version of key, as encoded in PKCS#1 - */ - u_int version; - + /** * Public modulus. */ mpz_t n; - + /** * Public exponent. */ mpz_t e; - + /** * Private prime 1. */ mpz_t p; - + /** * Private Prime 2. */ mpz_t q; - + /** * Private exponent. */ mpz_t d; - + /** * Private exponent 1. */ mpz_t exp1; - + /** * Private exponent 2. */ mpz_t exp2; - + /** * Private coefficient. */ mpz_t coeff; - + /** * Keysize in bytes. */ size_t k; - /** - * Keyid formed as a SHA-1 hash of a publicKey object - */ - identification_t* keyid; - - /** - * Keyid formed as a SHA-1 hash of a publicKeyInfo object - */ - identification_t* keyid_info; - /** * reference count */ - refcount_t ref; + refcount_t ref; }; /** - * Shared functions defined in gmp_rsa_public_key.c + * Convert a MP integer into a chunk_t */ -extern bool gmp_rsa_public_key_build_id(mpz_t n, mpz_t e, - identification_t **keyid, - identification_t **keyid_info); -extern gmp_rsa_public_key_t *gmp_rsa_public_key_create_from_n_e(mpz_t n, mpz_t e); +chunk_t gmp_mpz_to_chunk(const mpz_t value) +{ + chunk_t n; + + n.len = 1 + mpz_sizeinbase(value, 2) / BITS_PER_BYTE; + n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value); + if (n.ptr == NULL) + { /* if we have zero in "value", gmp returns NULL */ + n.len = 0; + } + return n; +} /** * Auxiliary function overwriting private key material with zero bytes */ -static void mpz_clear_randomized(mpz_t z) +static void mpz_clear_sensitive(mpz_t z) { size_t len = mpz_size(z) * GMP_LIMB_BITS / BITS_PER_BYTE; u_int8_t *random = alloca(len); - + memset(random, 0, len); /* overwrite mpz_t with zero bytes before clearing it */ mpz_import(z, len, 1, 1, 1, 0, random); @@ -140,28 +132,28 @@ static status_t compute_prime(private_gmp_rsa_private_key_t *this, { rng_t *rng; chunk_t random_bytes; - + rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE); if (!rng) { DBG1("no RNG of quality %N found", rng_quality_names, RNG_TRUE); return FAILED; } - + mpz_init(*prime); do { rng->allocate_bytes(rng, prime_size, &random_bytes); /* make sure most significant bit is set */ random_bytes.ptr[0] = random_bytes.ptr[0] | 0x80; - + mpz_import(*prime, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr); mpz_nextprime (*prime, *prime); chunk_clear(&random_bytes); } /* check if it isn't too large */ while (((mpz_sizeinbase(*prime, 2) + 7) / 8) > prime_size); - + rng->destroy(rng); return SUCCESS; } @@ -173,32 +165,32 @@ static chunk_t rsadp(private_gmp_rsa_private_key_t *this, chunk_t data) { mpz_t t1, t2; chunk_t decrypted; - + mpz_init(t1); mpz_init(t2); - + mpz_import(t1, data.len, 1, 1, 1, 0, data.ptr); - + mpz_powm(t2, t1, this->exp1, this->p); /* m1 = c^dP mod p */ mpz_powm(t1, t1, this->exp2, this->q); /* m2 = c^dQ mod Q */ mpz_sub(t2, t2, t1); /* h = qInv (m1 - m2) mod p */ mpz_mod(t2, t2, this->p); mpz_mul(t2, t2, this->coeff); mpz_mod(t2, t2, this->p); - + mpz_mul(t2, t2, this->q); /* m = m2 + h q */ mpz_add(t1, t1, t2); - + decrypted.len = this->k; decrypted.ptr = mpz_export(NULL, NULL, 1, decrypted.len, 1, 0, t1); if (decrypted.ptr == NULL) { decrypted.len = 0; } - - mpz_clear_randomized(t1); - mpz_clear_randomized(t2); - + + mpz_clear_sensitive(t1); + mpz_clear_sensitive(t2); + return decrypted; } @@ -225,7 +217,7 @@ static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this, hasher_t *hasher; chunk_t hash; int hash_oid = hasher_algorithm_to_oid(hash_algorithm); - + if (hash_oid == OID_UNKNOWN) { return FALSE; @@ -238,9 +230,9 @@ static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this, } hasher->allocate_hash(hasher, data, &hash); hasher->destroy(hasher); - + /* build DER-encoded digestInfo */ - digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm", + digestInfo = asn1_wrap(ASN1_SEQUENCE, "mm", asn1_algorithmIdentifier(hash_oid), asn1_simple_object(ASN1_OCTET_STRING, hash) ); @@ -254,15 +246,15 @@ static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this, DBG1("unable to sign %d bytes using a %dbit key", data.len, this->k * 8); return FALSE; } - + /* build chunk to rsa-decrypt: - * EM = 0x00 || 0x01 || PS || 0x00 || T. + * EM = 0x00 || 0x01 || PS || 0x00 || T. * PS = 0xFF padding, with length to fill em * T = encoded_hash */ em.len = this->k; em.ptr = malloc(em.len); - + /* fill em with padding */ memset(em.ptr, 0xFF, em.len); /* set magic bytes */ @@ -274,11 +266,11 @@ static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this, /* build signature */ *signature = rsasp1(this, em); - + free(digestInfo.ptr); free(em.ptr); - - return TRUE; + + return TRUE; } /** @@ -292,7 +284,7 @@ static key_type_t get_type(private_gmp_rsa_private_key_t *this) /** * Implementation of gmp_rsa_private_key.sign. */ -static bool sign(private_gmp_rsa_private_key_t *this, signature_scheme_t scheme, +static bool sign(private_gmp_rsa_private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature) { switch (scheme) @@ -326,7 +318,7 @@ static bool decrypt(private_gmp_rsa_private_key_t *this, chunk_t crypto, { chunk_t em, stripped; bool success = FALSE; - + /* rsa decryption using PKCS#1 RSADP */ stripped = em = rsadp(this, crypto); @@ -365,29 +357,23 @@ static size_t get_keysize(private_gmp_rsa_private_key_t *this) return this->k; } -/** - * Implementation of gmp_rsa_private_key.get_id. - */ -static identification_t* get_id(private_gmp_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 gmp_rsa_private_key.get_public_key. */ -static gmp_rsa_public_key_t* get_public_key(private_gmp_rsa_private_key_t *this) +static public_key_t* get_public_key(private_gmp_rsa_private_key_t *this) { - return gmp_rsa_public_key_create_from_n_e(this->n, this->e); + chunk_t n, e; + public_key_t *public; + + n = gmp_mpz_to_chunk(this->n); + e = gmp_mpz_to_chunk(this->e); + + public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, + BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_END); + chunk_free(&n); + chunk_free(&e); + + return public; } /** @@ -395,27 +381,7 @@ static gmp_rsa_public_key_t* get_public_key(private_gmp_rsa_private_key_t *this) */ static bool equals(private_gmp_rsa_private_key_t *this, private_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; + return private_key_equals(&this->public.interface, other); } /** @@ -423,64 +389,67 @@ static bool equals(private_gmp_rsa_private_key_t *this, private_key_t *other) */ static bool belongs_to(private_gmp_rsa_private_key_t *this, public_key_t *public) { - identification_t *keyid; - - if (public->get_type(public) != KEY_RSA) - { - 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 private_key_belongs_to(&this->public.interface, public); } /** - * Convert a MP integer into a chunk_t + * Implementation of private_key_t.get_encoding */ -chunk_t gmp_mpz_to_chunk(const mpz_t value) +static bool get_encoding(private_gmp_rsa_private_key_t *this, + key_encoding_type_t type, chunk_t *encoding) { - chunk_t n; - - n.len = 1 + mpz_sizeinbase(value, 2) / BITS_PER_BYTE; - n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value); - if (n.ptr == NULL) - { /* if we have zero in "value", gmp returns NULL */ - n.len = 0; - } - return n; -} + chunk_t n, e, d, p, q, exp1, exp2, coeff; + bool success; + + n = gmp_mpz_to_chunk(this->n); + e = gmp_mpz_to_chunk(this->e); + d = gmp_mpz_to_chunk(this->d); + p = gmp_mpz_to_chunk(this->p); + q = gmp_mpz_to_chunk(this->q); + exp1 = gmp_mpz_to_chunk(this->exp1); + exp2 = gmp_mpz_to_chunk(this->exp2); + coeff = gmp_mpz_to_chunk(this->coeff); + + success = lib->encoding->encode(lib->encoding, + type, NULL, encoding, KEY_PART_RSA_MODULUS, n, + KEY_PART_RSA_PUB_EXP, e, KEY_PART_RSA_PRIV_EXP, d, + KEY_PART_RSA_PRIME1, p, KEY_PART_RSA_PRIME2, q, + KEY_PART_RSA_EXP1, exp1, KEY_PART_RSA_EXP2, exp2, + KEY_PART_RSA_COEFF, coeff, KEY_PART_END); + chunk_free(&n); + chunk_free(&e); + chunk_clear(&d); + chunk_clear(&p); + chunk_clear(&q); + chunk_clear(&exp1); + chunk_clear(&exp2); + chunk_clear(&coeff); -/** - * Convert a MP integer into a DER coded ASN.1 object - */ -chunk_t gmp_mpz_to_asn1(const mpz_t value) -{ - return asn1_wrap(ASN1_INTEGER, "m", gmp_mpz_to_chunk(value)); + return success; } /** - * Implementation of private_key_t.get_encoding. + * Implementation of private_key_t.get_fingerprint */ -static chunk_t get_encoding(private_gmp_rsa_private_key_t *this) +static bool get_fingerprint(private_gmp_rsa_private_key_t *this, + key_encoding_type_t type, chunk_t *fp) { - return asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm", - ASN1_INTEGER_0, - gmp_mpz_to_asn1(this->n), - gmp_mpz_to_asn1(this->e), - gmp_mpz_to_asn1(this->d), - gmp_mpz_to_asn1(this->p), - gmp_mpz_to_asn1(this->q), - gmp_mpz_to_asn1(this->exp1), - gmp_mpz_to_asn1(this->exp2), - gmp_mpz_to_asn1(this->coeff)); + chunk_t n, e; + bool success; + + if (lib->encoding->get_cache(lib->encoding, type, this, fp)) + { + return TRUE; + } + n = gmp_mpz_to_chunk(this->n); + e = gmp_mpz_to_chunk(this->e); + + success = lib->encoding->encode(lib->encoding, type, this, fp, + KEY_PART_RSA_MODULUS, n, KEY_PART_RSA_PUB_EXP, e, KEY_PART_END); + chunk_free(&n); + chunk_free(&e); + + return success; } /** @@ -490,7 +459,6 @@ static private_gmp_rsa_private_key_t* get_ref(private_gmp_rsa_private_key_t *thi { ref_get(&this->ref); return this; - } /** @@ -500,16 +468,15 @@ static void destroy(private_gmp_rsa_private_key_t *this) { if (ref_put(&this->ref)) { - mpz_clear_randomized(this->n); - mpz_clear_randomized(this->e); - mpz_clear_randomized(this->p); - mpz_clear_randomized(this->q); - mpz_clear_randomized(this->d); - mpz_clear_randomized(this->exp1); - mpz_clear_randomized(this->exp2); - mpz_clear_randomized(this->coeff); - DESTROY_IF(this->keyid); - DESTROY_IF(this->keyid_info); + mpz_clear_sensitive(this->n); + mpz_clear_sensitive(this->e); + mpz_clear_sensitive(this->p); + mpz_clear_sensitive(this->q); + mpz_clear_sensitive(this->d); + mpz_clear_sensitive(this->exp1); + mpz_clear_sensitive(this->exp2); + mpz_clear_sensitive(this->coeff); + lib->encoding->clear_cache(lib->encoding, this); free(this); } } @@ -521,7 +488,7 @@ static status_t check(private_gmp_rsa_private_key_t *this) { mpz_t t, u, q1; status_t status = SUCCESS; - + /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets. * We actually require more (for security). */ @@ -530,25 +497,25 @@ static status_t check(private_gmp_rsa_private_key_t *this) DBG1("key shorter than 512 bits"); return FAILED; } - + /* we picked a max modulus size to simplify buffer allocation */ if (this->k > 8192 / BITS_PER_BYTE) { DBG1("key larger than 8192 bits"); return FAILED; } - + mpz_init(t); mpz_init(u); mpz_init(q1); - + /* check that n == p * q */ mpz_mul(u, this->p, this->q); if (mpz_cmp(u, this->n) != 0) { status = FAILED; } - + /* check that e divides neither p-1 nor q-1 */ mpz_sub_ui(t, this->p, 1); mpz_mod(t, t, this->e); @@ -556,14 +523,14 @@ static status_t check(private_gmp_rsa_private_key_t *this) { status = FAILED; } - + mpz_sub_ui(t, this->q, 1); mpz_mod(t, t, this->e); if (mpz_cmp_ui(t, 0) == 0) { status = FAILED; } - + /* check that d is e^-1 (mod lcm(p-1, q-1)) */ /* see PKCS#1v2, aka RFC 2437, for the "lcm" */ mpz_sub_ui(q1, this->q, 1); @@ -571,14 +538,14 @@ static status_t check(private_gmp_rsa_private_key_t *this) mpz_gcd(t, u, q1); /* t := gcd(p-1, q-1) */ mpz_mul(u, u, q1); /* u := (p-1) * (q-1) */ mpz_divexact(u, u, t); /* u := lcm(p-1, q-1) */ - + mpz_mul(t, this->d, this->e); mpz_mod(t, t, u); if (mpz_cmp_ui(t, 1) != 0) { status = FAILED; } - + /* check that exp1 is d mod (p-1) */ mpz_sub_ui(u, this->p, 1); mpz_mod(t, this->d, u); @@ -586,7 +553,7 @@ static status_t check(private_gmp_rsa_private_key_t *this) { status = FAILED; } - + /* check that exp2 is d mod (q-1) */ mpz_sub_ui(u, this->q, 1); mpz_mod(t, this->d, u); @@ -594,7 +561,7 @@ static status_t check(private_gmp_rsa_private_key_t *this) { status = FAILED; } - + /* check that coeff is (q^-1) mod p */ mpz_mul(t, this->coeff, this->q); mpz_mod(t, t, this->p); @@ -602,10 +569,10 @@ static status_t check(private_gmp_rsa_private_key_t *this) { status = FAILED; } - - mpz_clear_randomized(t); - mpz_clear_randomized(u); - mpz_clear_randomized(q1); + + mpz_clear_sensitive(t); + mpz_clear_sensitive(u); + mpz_clear_sensitive(q1); if (status != SUCCESS) { DBG1("key integrity tests failed"); @@ -619,63 +586,82 @@ static status_t check(private_gmp_rsa_private_key_t *this) static private_gmp_rsa_private_key_t *gmp_rsa_private_key_create_empty(void) { private_gmp_rsa_private_key_t *this = malloc_thing(private_gmp_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.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->keyid = NULL; - this->keyid_info = NULL; + this->ref = 1; - + return this; } /** - * Generate an RSA key of specified key size + * See header. */ -static gmp_rsa_private_key_t *generate(size_t key_size) +gmp_rsa_private_key_t *gmp_rsa_private_key_gen(key_type_t type, va_list args) { - mpz_t p, q, n, e, d, exp1, exp2, coeff; - mpz_t m, q1, t; - private_gmp_rsa_private_key_t *this = gmp_rsa_private_key_create_empty(); - + mpz_t p, q, n, e, d, exp1, exp2, coeff, m, q1, t; + private_gmp_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) + { + return NULL; + } + + this = gmp_rsa_private_key_create_empty(); key_size = key_size / BITS_PER_BYTE; - + /* Get values of primes p and q */ if (compute_prime(this, key_size/2, &p) != SUCCESS) { free(this); return NULL; - } + } if (compute_prime(this, key_size/2, &q) != SUCCESS) { mpz_clear(p); free(this); return NULL; } - - mpz_init(t); + + mpz_init(t); mpz_init(n); mpz_init(d); mpz_init(exp1); mpz_init(exp2); mpz_init(coeff); - + /* Swapping Primes so p is larger then q */ if (mpz_cmp(p, q) < 0) { mpz_swap(p, q); } - + mpz_mul(n, p, q); /* n = p*q */ mpz_init_set_ui(e, PUBLIC_EXPONENT); /* assign public exponent */ mpz_init_set(m, p); /* m = p */ @@ -696,16 +682,16 @@ static gmp_rsa_private_key_t *generate(size_t key_size) mpz_mod(exp1, d, t); /* exp1 = d mod p-1 */ mpz_sub_ui(t, q, 1); /* t = q-1 */ mpz_mod(exp2, d, t); /* exp2 = d mod q-1 */ - + mpz_invert(coeff, q, p); /* coeff = q^-1 mod p */ if (mpz_cmp_ui(coeff, 0) < 0) /* make coeff d is positive */ { mpz_add(coeff, coeff, p); } - mpz_clear_randomized(q1); - mpz_clear_randomized(m); - mpz_clear_randomized(t); + mpz_clear_sensitive(q1); + mpz_clear_sensitive(m); + mpz_clear_sensitive(t); /* apply values */ *(this->p) = *p; @@ -716,145 +702,60 @@ static gmp_rsa_private_key_t *generate(size_t key_size) *(this->exp1) = *exp1; *(this->exp2) = *exp2; *(this->coeff) = *coeff; - + /* set key size in bytes */ this->k = key_size; - + return &this->public; } /** - * ASN.1 definition of a PKCS#1 RSA private key - */ -static const asn1Object_t privkeyObjects[] = { - { 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ - { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */ - { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */ - { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */ - { 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */ - { 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */ - { 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */ - { 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */ - { 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */ - { 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */ - { 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT | - ASN1_LOOP }, /* 10 */ - { 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */ - { 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */ - { 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */ - { 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */ - { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 15 */ - { 0, "exit", ASN1_EOC, ASN1_EXIT } -}; -#define PRIV_KEY_VERSION 1 -#define PRIV_KEY_MODULUS 2 -#define PRIV_KEY_PUB_EXP 3 -#define PRIV_KEY_PRIV_EXP 4 -#define PRIV_KEY_PRIME1 5 -#define PRIV_KEY_PRIME2 6 -#define PRIV_KEY_EXP1 7 -#define PRIV_KEY_EXP2 8 -#define PRIV_KEY_COEFF 9 - -/** - * load private key from a ASN1 encoded blob + * See header. */ -static gmp_rsa_private_key_t *load_asn1_der(chunk_t blob) +gmp_rsa_private_key_t *gmp_rsa_private_key_load(key_type_t type, va_list args) { - asn1_parser_t *parser; - chunk_t object; - int objectID ; - bool success = FALSE; + chunk_t n, e, d, p, q, exp1, exp2, coeff; + private_gmp_rsa_private_key_t *this; - private_gmp_rsa_private_key_t *this = gmp_rsa_private_key_create_empty(); - - mpz_init(this->n); - mpz_init(this->e); - mpz_init(this->p); - mpz_init(this->q); - mpz_init(this->d); - mpz_init(this->exp1); - mpz_init(this->exp2); - mpz_init(this->coeff); - - parser = asn1_parser_create(privkeyObjects, blob); - parser->set_flags(parser, FALSE, TRUE); - - while (parser->iterate(parser, &objectID, &object)) + n = e = d = p = q = exp1 = exp2 = coeff = chunk_empty; + while (TRUE) { - switch (objectID) + switch (va_arg(args, builder_part_t)) { - case PRIV_KEY_VERSION: - if (object.len > 0 && *object.ptr != 0) - { - DBG1("PKCS#1 private key format is not version 1"); - goto end; - } - break; - case PRIV_KEY_MODULUS: - mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr); - break; - case PRIV_KEY_PUB_EXP: - mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr); - break; - case PRIV_KEY_PRIV_EXP: - mpz_import(this->d, object.len, 1, 1, 1, 0, object.ptr); - break; - case PRIV_KEY_PRIME1: - mpz_import(this->p, object.len, 1, 1, 1, 0, object.ptr); - break; - case PRIV_KEY_PRIME2: - mpz_import(this->q, object.len, 1, 1, 1, 0, object.ptr); - break; - case PRIV_KEY_EXP1: - mpz_import(this->exp1, object.len, 1, 1, 1, 0, object.ptr); - break; - case PRIV_KEY_EXP2: - mpz_import(this->exp2, object.len, 1, 1, 1, 0, object.ptr); - break; - case PRIV_KEY_COEFF: - mpz_import(this->coeff, object.len, 1, 1, 1, 0, object.ptr); + 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; } - success = parser->success(parser); -end: - parser->destroy(parser); - chunk_clear(&blob); + this = gmp_rsa_private_key_create_empty(); - if (!success) - { - destroy(this); - return NULL; - } - - this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; - - if (!gmp_rsa_public_key_build_id(this->n, this->e, - &this->keyid, &this->keyid_info)) - { - destroy(this); - return NULL; - } - if (check(this) != SUCCESS) - { - destroy(this); - return NULL; - } - return &this->public; -} - -/** - * load private key from an OpenPGP blob coded according to section - */ -static gmp_rsa_private_key_t *load_pgp(chunk_t blob) -{ - mpz_t u; - int objectID; - chunk_t packet = blob; - private_gmp_rsa_private_key_t *this = gmp_rsa_private_key_create_empty(); - mpz_init(this->n); mpz_init(this->e); mpz_init(this->p); @@ -864,205 +765,36 @@ static gmp_rsa_private_key_t *load_pgp(chunk_t blob) mpz_init(this->exp2); mpz_init(this->coeff); - for (objectID = PRIV_KEY_MODULUS; objectID <= PRIV_KEY_COEFF; objectID++) - { - chunk_t object; - - switch (objectID) - { - case PRIV_KEY_PRIV_EXP: - { - pgp_sym_alg_t s2k; - - /* string-to-key usage */ - s2k = pgp_length(&packet, 1); - DBG2("L3 - string-to-key: %d", s2k); - - if (s2k == 255 || s2k == 254) - { - DBG1("string-to-key specifiers not supported"); - goto end; - } - DBG2(" %N", pgp_sym_alg_names, s2k); - - if (s2k != PGP_SYM_ALG_PLAIN) - { - DBG1("%N encryption not supported", pgp_sym_alg_names, s2k); - goto end; - } - break; - } - case PRIV_KEY_EXP1: - case PRIV_KEY_EXP2: - /* not contained in OpenPGP secret key payload */ - continue; - default: - break; - } - - DBG2("L3 - %s:", privkeyObjects[objectID].name); - object.len = pgp_length(&packet, 2); - - if (object.len == PGP_INVALID_LENGTH) - { - DBG1("OpenPGP length is invalid"); - goto end; - } - object.len = (object.len + 7) / BITS_PER_BYTE; - if (object.len > packet.len) - { - DBG1("OpenPGP field is too short"); - goto end; - } - object.ptr = packet.ptr; - packet.ptr += object.len; - packet.len -= object.len; - DBG4("%B", &object); - - switch (objectID) - { - case PRIV_KEY_MODULUS: - mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr); - break; - case PRIV_KEY_PUB_EXP: - mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr); - break; - case PRIV_KEY_PRIV_EXP: - mpz_import(this->d, object.len, 1, 1, 1, 0, object.ptr); - break; - case PRIV_KEY_PRIME1: - mpz_import(this->q, object.len, 1, 1, 1, 0, object.ptr); - break; - case PRIV_KEY_PRIME2: - mpz_import(this->p, object.len, 1, 1, 1, 0, object.ptr); - break; - case PRIV_KEY_COEFF: - mpz_import(this->coeff, object.len, 1, 1, 1, 0, object.ptr); - break; - } - } - - /* auxiliary variable */ - mpz_init(u); - - /* exp1 = d mod (p-1) */ - mpz_sub_ui(u, this->p, 1); - mpz_mod(this->exp1, this->d, u); - - /* exp2 = d mod (q-1) */ - mpz_sub_ui(u, this->q, 1); - mpz_mod(this->exp2, this->d, u); - - mpz_clear(u); - chunk_clear(&blob); - - this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; - - if (!gmp_rsa_public_key_build_id(this->n, this->e, - &this->keyid, &this->keyid_info)) - { - destroy(this); - return NULL; + mpz_import(this->n, n.len, 1, 1, 1, 0, n.ptr); + mpz_import(this->e, e.len, 1, 1, 1, 0, e.ptr); + mpz_import(this->d, d.len, 1, 1, 1, 0, d.ptr); + mpz_import(this->p, p.len, 1, 1, 1, 0, p.ptr); + mpz_import(this->q, q.len, 1, 1, 1, 0, q.ptr); + mpz_import(this->coeff, coeff.len, 1, 1, 1, 0, coeff.ptr); + if (!exp1.len) + { /* exp1 missing in key, recalculate: exp1 = d mod (p-1) */ + mpz_sub_ui(this->exp1, this->p, 1); + mpz_mod(this->exp1, this->d, this->exp1); } - if (check(this) != SUCCESS) + else { - destroy(this); - return NULL; + mpz_import(this->exp1, exp1.len, 1, 1, 1, 0, exp1.ptr); } - return &this->public; - -end: - chunk_clear(&blob); - destroy(this); - 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 */ - gmp_rsa_private_key_t *key; -}; - -/** - * Implementation of builder_t.build - */ -static gmp_rsa_private_key_t *build(private_builder_t *this) -{ - gmp_rsa_private_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) - { - 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_asn1_der(chunk_clone(chunk)); - va_end(args); - return; - } - case BUILD_BLOB_PGP: - { - va_start(args, part); - chunk = va_arg(args, chunk_t); - this->key = load_pgp(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; - } - default: - break; - } + if (!exp2.len) + { /* exp2 missing in key, recalculate: exp2 = d mod (q-1) */ + mpz_sub_ui(this->exp2, this->q, 1); + mpz_mod(this->exp2, this->d, this->exp2); } - if (this->key) + else { - destroy((private_gmp_rsa_private_key_t*)this->key); + mpz_import(this->exp2, exp2.len, 1, 1, 1, 0, exp2.ptr); } - builder_cancel(&this->public); -} - -/** - * Builder construction function - */ -builder_t *gmp_rsa_private_key_builder(key_type_t type) -{ - private_builder_t *this; - - if (type != KEY_RSA) + this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; + if (check(this) != SUCCESS) { + 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/gmp/gmp_rsa_private_key.h b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.h index d47e2583d..db1fcf535 100644 --- a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.h +++ b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2008 Martin Willi + * Copyright (C) 2005-2009 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -21,6 +21,7 @@ #ifndef GMP_RSA_PRIVATE_KEY_H_ #define GMP_RSA_PRIVATE_KEY_H_ +#include #include typedef struct gmp_rsa_private_key_t gmp_rsa_private_key_t; @@ -37,12 +38,25 @@ struct gmp_rsa_private_key_t { }; /** - * Create the builder for a private key. + * Generated a RSA private keys using libgmp. + * + * Accepts the BUILD_KEY_SIZE argument. * * @param type type of the key, must be KEY_RSA - * @return builder instance + * @param args builder_part_t argument list + * @return generated key, NULL on failure */ -builder_t *gmp_rsa_private_key_builder(key_type_t type); +gmp_rsa_private_key_t *gmp_rsa_private_key_gen(key_type_t type, va_list args); -#endif /** GMP_RSA_PRIVATE_KEY_H_ @}*/ +/** + * Loaded a RSA private keys using libgmp. + * + * Accepts BUILD_RSA_* components. + * + * @param type type of the key, must be KEY_RSA + * @param args builder_part_t argument list + * @return loaded key, NULL on failure + */ +gmp_rsa_private_key_t *gmp_rsa_private_key_load(key_type_t type, va_list args); +#endif /** GMP_RSA_PRIVATE_KEY_H_ @}*/ diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c index c26187c64..5fea69131 100644 --- a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c +++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2008 Martin Willi + * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -13,7 +13,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ - + #include #include #include @@ -26,9 +26,7 @@ #include #include #include -#include #include -#include typedef struct private_gmp_rsa_public_key_t private_gmp_rsa_public_key_t; @@ -40,32 +38,22 @@ struct private_gmp_rsa_public_key_t { * Public interface for this signer. */ gmp_rsa_public_key_t public; - + /** * Public modulus. */ mpz_t n; - + /** * Public exponent. */ mpz_t e; - + /** * Keysize in bytes. */ size_t k; - - /** - * 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 */ @@ -76,7 +64,6 @@ struct private_gmp_rsa_public_key_t { * Shared functions defined in gmp_rsa_private_key.c */ extern chunk_t gmp_mpz_to_chunk(const mpz_t value); -extern chunk_t gmp_mpz_to_asn1(const mpz_t value); /** * RSAEP algorithm specified in PKCS#1. @@ -85,12 +72,12 @@ static chunk_t rsaep(private_gmp_rsa_public_key_t *this, chunk_t data) { mpz_t m, c; chunk_t encrypted; - + mpz_init(c); mpz_init(m); - + mpz_import(m, data.len, 1, 1, 1, 0, data.ptr); - + mpz_powm(c, m, this->e, this->n); encrypted.len = this->k; @@ -99,10 +86,10 @@ static chunk_t rsaep(private_gmp_rsa_public_key_t *this, chunk_t data) { encrypted.len = 0; } - + mpz_clear(c); mpz_clear(m); - + return encrypted; } @@ -136,34 +123,34 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this, { chunk_t em_ori, em; bool success = FALSE; - + /* remove any preceding 0-bytes from signature */ while (signature.len && *(signature.ptr) == 0x00) { signature = chunk_skip(signature, 1); } - + if (signature.len == 0 || signature.len > this->k) { return INVALID_ARG; } - + /* unpack signature */ em_ori = em = rsavp1(this, signature); - + /* result should look like this: - * EM = 0x00 || 0x01 || PS || 0x00 || T. + * EM = 0x00 || 0x01 || PS || 0x00 || T. * PS = 0xFF padding, with length to fill em * T = oid || hash */ - + /* check magic bytes */ if (*(em.ptr) != 0x00 || *(em.ptr+1) != 0x01) { goto end; } em = chunk_skip(em, 2); - + /* find magic 0x00 */ while (em.len > 0) { @@ -240,7 +227,7 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this, { chunk_t hash; hasher_t *hasher; - + hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm); if (hasher == NULL) { @@ -290,7 +277,7 @@ static key_type_t get_type(private_gmp_rsa_public_key_t *this) /** * Implementation of public_key_t.verify. */ -static bool verify(private_gmp_rsa_public_key_t *this, signature_scheme_t scheme, +static bool verify(private_gmp_rsa_public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature) { switch (scheme) @@ -316,7 +303,7 @@ static bool verify(private_gmp_rsa_public_key_t *this, signature_scheme_t scheme } } -#define MIN_PS_PADDING 8 +#define MIN_PS_PADDING 8 /** * Implementation of public_key_t.encrypt. @@ -327,7 +314,7 @@ static bool encrypt_(private_gmp_rsa_public_key_t *this, chunk_t plain, chunk_t em; u_char *pos; int padding, i; - rng_t *rng; + rng_t *rng; rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); if (rng == NULL) @@ -338,7 +325,7 @@ static bool encrypt_(private_gmp_rsa_public_key_t *this, chunk_t plain, /* number of pseudo-random padding octets */ padding = this->k - plain.len - 3; - if (padding < MIN_PS_PADDING) + if (padding < MIN_PS_PADDING) { DBG1("pseudo-random padding must be at least %d octets", MIN_PS_PADDING); return FALSE; @@ -346,9 +333,9 @@ static bool encrypt_(private_gmp_rsa_public_key_t *this, chunk_t plain, /* padding according to PKCS#1 7.2.1 (RSAES-PKCS1-v1.5-ENCRYPT) */ DBG2("padding %u bytes of data to the rsa modulus size of %u bytes", - plain.len, this->k); + plain.len, this->k); em.len = this->k; - em.ptr = malloc(em.len); + em.ptr = malloc(em.len); pos = em.ptr; *pos++ = 0x00; *pos++ = 0x02; @@ -373,7 +360,7 @@ static bool encrypt_(private_gmp_rsa_public_key_t *this, chunk_t plain, /* now add the data */ memcpy(pos, plain.ptr, plain.len); DBG3("padded data before rsa encryption: %B", &em); - + /* rsa encryption using PKCS#1 RSAEP */ *crypto = rsaep(this, em); DBG3("rsa encrypted data: %B", crypto); @@ -386,27 +373,7 @@ static bool encrypt_(private_gmp_rsa_public_key_t *this, chunk_t plain, */ static bool equals(private_gmp_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; + return public_key_equals(&this->public.interface, other); } /** @@ -418,72 +385,47 @@ static size_t get_keysize(private_gmp_rsa_public_key_t *this) } /** - * Build the PGP version 3 RSA key identifier from n and e using - * MD5 hashed modulus and exponent. + * Implementation of public_key_t.get_encoding */ -static identification_t* gmp_rsa_build_pgp_v3_keyid(mpz_t n, mpz_t e) +static bool get_encoding(private_gmp_rsa_public_key_t *this, + key_encoding_type_t type, chunk_t *encoding) { - identification_t *keyid; - chunk_t modulus, mod, exponent, exp, hash; - hasher_t *hasher; - - hasher= lib->crypto->create_hasher(lib->crypto, HASH_MD5); - if (hasher == NULL) - { - DBG1("computation of PGP V3 keyid failed, no MD5 hasher is available"); - return NULL; - } - mod = modulus = gmp_mpz_to_chunk(n); - exp = exponent = gmp_mpz_to_chunk(e); + chunk_t n, e; + bool success; - /* remove leading zero bytes before hashing modulus and exponent */ - while (mod.len > 0 && *mod.ptr == 0x00) - { - mod.ptr++; - mod.len--; - } - while (exp.len > 0 && *exp.ptr == 0x00) - { - exp.ptr++; - exp.len--; - } - hasher->allocate_hash(hasher, mod, NULL); - hasher->allocate_hash(hasher, exp, &hash); - hasher->destroy(hasher); - keyid = identification_create_from_encoding(ID_KEY_ID, hash); - free(hash.ptr); - free(modulus.ptr); - free(exponent.ptr); - return keyid; + n = gmp_mpz_to_chunk(this->n); + e = gmp_mpz_to_chunk(this->e); + + success = lib->encoding->encode(lib->encoding, type, NULL, encoding, + KEY_PART_RSA_MODULUS, n, KEY_PART_RSA_PUB_EXP, e, KEY_PART_END); + chunk_free(&n); + chunk_free(&e); + + return success; } /** - * Implementation of public_key_t.get_id. + * Implementation of public_key_t.get_fingerprint */ -static identification_t *get_id(private_gmp_rsa_public_key_t *this, - id_type_t type) +static bool get_fingerprint(private_gmp_rsa_public_key_t *this, + key_encoding_type_t type, chunk_t *fp) { - switch (type) + chunk_t n, e; + bool success; + + if (lib->encoding->get_cache(lib->encoding, type, this, fp)) { - case ID_PUBKEY_INFO_SHA1: - return this->keyid_info; - case ID_PUBKEY_SHA1: - return this->keyid; - case ID_KEY_ID: - return gmp_rsa_build_pgp_v3_keyid(this->n, this->e); - default: - return NULL; + return TRUE; } -} + n = gmp_mpz_to_chunk(this->n); + e = gmp_mpz_to_chunk(this->e); -/* - * Implementation of public_key_t.get_encoding. - */ -static chunk_t get_encoding(private_gmp_rsa_public_key_t *this) -{ - return asn1_wrap(ASN1_SEQUENCE, "mm", - gmp_mpz_to_asn1(this->n), - gmp_mpz_to_asn1(this->e)); + success = lib->encoding->encode(lib->encoding, type, this, fp, + KEY_PART_RSA_MODULUS, n, KEY_PART_RSA_PUB_EXP, e, KEY_PART_END); + chunk_free(&n); + chunk_free(&e); + + return success; } /** @@ -504,369 +446,65 @@ static void destroy(private_gmp_rsa_public_key_t *this) { mpz_clear(this->n); mpz_clear(this->e); - DESTROY_IF(this->keyid); - DESTROY_IF(this->keyid_info); + lib->encoding->clear_cache(lib->encoding, this); free(this); } } /** - * Generic private constructor + * See header. */ -static private_gmp_rsa_public_key_t *gmp_rsa_public_key_create_empty() +gmp_rsa_public_key_t *gmp_rsa_public_key_load(key_type_t type, va_list args) { - private_gmp_rsa_public_key_t *this = malloc_thing(private_gmp_rsa_public_key_t); - - this->public.interface.get_type = (key_type_t (*) (public_key_t*))get_type; - this->public.interface.verify = (bool (*) (public_key_t*, signature_scheme_t, chunk_t, chunk_t))verify; - this->public.interface.encrypt = (bool (*) (public_key_t*, chunk_t, chunk_t*))encrypt_; - this->public.interface.equals = (bool (*) (public_key_t*, public_key_t*))equals; - this->public.interface.get_keysize = (size_t (*) (public_key_t*))get_keysize; - this->public.interface.get_id = (identification_t* (*) (public_key_t*, id_type_t))get_id; - this->public.interface.get_encoding = (chunk_t(*) (public_key_t*))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; -} + private_gmp_rsa_public_key_t *this; + chunk_t n, e; -/** - * Build the RSA key identifier from n and e using SHA1 hashed publicKey(Info). - * Also used in rsa_private_key.c. - */ -bool gmp_rsa_public_key_build_id(mpz_t n, mpz_t e, 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 = asn1_wrap(ASN1_SEQUENCE, "mm", - gmp_mpz_to_asn1(n), - gmp_mpz_to_asn1(e)); - hasher->allocate_hash(hasher, publicKey, &hash); - *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash); - chunk_free(&hash); - - publicKeyInfo = asn1_wrap(ASN1_SEQUENCE, "cm", - asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), - asn1_bitstring("m", publicKey)); - 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); - - return TRUE; -} - -/** - * Create a public key from mpz values, used in gmp_rsa_private_key - */ -gmp_rsa_public_key_t *gmp_rsa_public_key_create_from_n_e(mpz_t n, mpz_t e) -{ - private_gmp_rsa_public_key_t *this = gmp_rsa_public_key_create_empty(); - - mpz_init_set(this->n, n); - mpz_init_set(this->e, e); - - this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; - if (!gmp_rsa_public_key_build_id(this->n, this->e, - &this->keyid, &this->keyid_info)) + n = e = chunk_empty; + while (TRUE) { - destroy(this); - return NULL; - } - return &this->public; -} - -/** - * ASN.1 definition of RSApublicKey - */ -static const asn1Object_t pubkeyObjects[] = { - { 0, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */ - { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 1 */ - { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 2 */ - { 0, "exit", ASN1_EOC, ASN1_EXIT } -}; -#define PUB_KEY_RSA_PUBLIC_KEY 0 -#define PUB_KEY_MODULUS 1 -#define PUB_KEY_EXPONENT 2 - -/** - * Load a public key from an ASN.1 encoded blob - */ -static gmp_rsa_public_key_t *load_asn1_der(chunk_t blob) -{ - asn1_parser_t *parser; - chunk_t object; - int objectID; - bool success = FALSE; - - private_gmp_rsa_public_key_t *this = gmp_rsa_public_key_create_empty(); - - mpz_init(this->n); - mpz_init(this->e); - - parser = asn1_parser_create(pubkeyObjects, blob); - - while (parser->iterate(parser, &objectID, &object)) - { - switch (objectID) + switch (va_arg(args, builder_part_t)) { - case PUB_KEY_MODULUS: - mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr); - break; - case PUB_KEY_EXPONENT: - mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr); + 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; } - success = parser->success(parser); - free(blob.ptr); - parser->destroy(parser); - - if (!success) + if (!e.ptr || !n.ptr) { - destroy(this); return NULL; } - - this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; - if (!gmp_rsa_public_key_build_id(this->n, this->e, - &this->keyid, &this->keyid_info)) - { - destroy(this); - return NULL; - } - return &this->public; -} + this = malloc_thing(private_gmp_rsa_public_key_t); -/** - * Load a public key from an OpenPGP blob - */ -static gmp_rsa_public_key_t* load_pgp(chunk_t blob) -{ - int objectID; - chunk_t packet = blob; - private_gmp_rsa_public_key_t *this = gmp_rsa_public_key_create_empty(); - - mpz_init(this->n); - mpz_init(this->e); - - for (objectID = PUB_KEY_MODULUS; objectID <= PUB_KEY_EXPONENT; objectID++) - { - chunk_t object; - - DBG2("L3 - %s:", pubkeyObjects[objectID].name); - object.len = pgp_length(&packet, 2); - - if (object.len == PGP_INVALID_LENGTH) - { - DBG1("OpenPGP length is invalid"); - goto end; - } - object.len = (object.len + 7) / BITS_PER_BYTE; - if (object.len > packet.len) - { - DBG1("OpenPGP field is too short"); - goto end; - } - object.ptr = packet.ptr; - packet.ptr += object.len; - packet.len -= object.len; - DBG4("%B", &object); - - switch (objectID) - { - case PUB_KEY_MODULUS: - mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr); - break; - case PUB_KEY_EXPONENT: - mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr); - break; - } - } - - this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; - free(blob.ptr); - - if (!gmp_rsa_public_key_build_id(this->n, this->e, - &this->keyid, &this->keyid_info)) - { - destroy(this); - return NULL; - } - return &this->public; + this->public.interface.get_type = (key_type_t (*) (public_key_t*))get_type; + this->public.interface.verify = (bool (*) (public_key_t*, signature_scheme_t, chunk_t, chunk_t))verify; + this->public.interface.encrypt = (bool (*) (public_key_t*, chunk_t, chunk_t*))encrypt_; + this->public.interface.equals = (bool (*) (public_key_t*, public_key_t*))equals; + this->public.interface.get_keysize = (size_t (*) (public_key_t*))get_keysize; + 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; -end: - free(blob.ptr); - destroy(this); - return NULL; -} + this->ref = 1; -/** - * Load a public key from an RFC 3110 encoded blob - */ -static gmp_rsa_public_key_t *load_rfc_3110(chunk_t blob) -{ - chunk_t exponent, modulus; - u_char *pos = blob.ptr; - size_t len = blob.len; - private_gmp_rsa_public_key_t *this = gmp_rsa_public_key_create_empty(); - mpz_init(this->n); mpz_init(this->e); - if (blob.len < 3) - { - DBG1("RFC 3110 public key blob too short for exponent length"); - goto end; - } - if (pos[0] != 0x00) - { - exponent = chunk_create(pos + 1, pos[0]); - pos++; - len--; - } - else - { - exponent = chunk_create(pos + 3, 256*pos[1] + pos[2]); - pos += 3; - len -= 3; - } - if (exponent.len > len) - { - DBG1("RFC 3110 public key blob too short for exponent"); - goto end; - } - pos += exponent.len; - len -= exponent.len; - - if (len == 0) - { - DBG1("RFC 3110 public key blob has zero length modulus"); - goto end; - } - modulus = chunk_create(pos, len); + mpz_import(this->n, n.len, 1, 1, 1, 0, n.ptr); + mpz_import(this->e, e.len, 1, 1, 1, 0, e.ptr); - mpz_import(this->n, modulus.len, 1, 1, 1, 0, modulus.ptr); - mpz_import(this->e, exponent.len, 1, 1, 1, 0, exponent.ptr); - this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; - free(blob.ptr); + this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; - if (!gmp_rsa_public_key_build_id(this->n, this->e, - &this->keyid, &this->keyid_info)) - { - destroy(this); - return NULL; - } - return &this->public; - -end: - free(blob.ptr); - destroy(this); - return NULL; -} - -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 */ - gmp_rsa_public_key_t *key; -}; - -/** - * Implementation of builder_t.build - */ -static gmp_rsa_public_key_t *build(private_builder_t *this) -{ - gmp_rsa_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) - { - 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_asn1_der(chunk_clone(chunk)); - va_end(args); - return; - } - case BUILD_BLOB_PGP: - { - va_start(args, part); - chunk = va_arg(args, chunk_t); - this->key = load_pgp(chunk_clone(chunk)); - va_end(args); - return; - } - case BUILD_BLOB_RFC_3110: - { - va_start(args, part); - chunk = va_arg(args, chunk_t); - this->key = load_rfc_3110(chunk_clone(chunk)); - va_end(args); - return; - } - default: - break; - } - } - if (this->key) - { - destroy((private_gmp_rsa_public_key_t*)this->key); - } - builder_cancel(&this->public); -} - -/** - * Builder construction function - */ -builder_t *gmp_rsa_public_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; - return &this->public; } diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h index ed7b9429f..807f0bb7c 100644 --- a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h +++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h @@ -22,10 +22,11 @@ #ifndef GMP_RSA_PUBLIC_KEY_H_ #define GMP_RSA_PUBLIC_KEY_H_ -typedef struct gmp_rsa_public_key_t gmp_rsa_public_key_t; - +#include #include +typedef struct gmp_rsa_public_key_t gmp_rsa_public_key_t; + /** * public_key_t implementation of RSA algorithm using libgmp. */ @@ -38,11 +39,14 @@ struct gmp_rsa_public_key_t { }; /** - * Create the builder for a public key. + * Load a RSA public key using libgmp. + * + * Accepts BUILD_RSA_* components. * * @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 *gmp_rsa_public_key_builder(key_type_t type); +gmp_rsa_public_key_t *gmp_rsa_public_key_load(key_type_t type, va_list args); #endif /** GMP_RSA_PUBLIC_KEY_H_ @}*/ -- cgit v1.2.3