diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2008-03-30 08:38:54 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2008-03-30 08:38:54 +0000 |
commit | 113868f64840631a2b10a2e8987268f2c6566552 (patch) | |
tree | 087c05184fd083ca653d1b85bd10c3c51361bb4a /src | |
parent | c9e3aaf0657e98bc047486ba87edf1489a39ba94 (diff) | |
download | vyos-strongswan-113868f64840631a2b10a2e8987268f2c6566552.tar.gz vyos-strongswan-113868f64840631a2b10a2e8987268f2c6566552.zip |
- New upstream release.
Diffstat (limited to 'src')
64 files changed, 3072 insertions, 918 deletions
diff --git a/src/Makefile.in b/src/Makefile.in index f2e6dcefe..17fc6f746 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -183,11 +183,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ diff --git a/src/_copyright/Makefile.in b/src/_copyright/Makefile.in index 6516a22fa..84ac628e6 100644 --- a/src/_copyright/Makefile.in +++ b/src/_copyright/Makefile.in @@ -186,11 +186,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ diff --git a/src/_updown/Makefile.in b/src/_updown/Makefile.in index 52f1109e5..4579ace58 100644 --- a/src/_updown/Makefile.in +++ b/src/_updown/Makefile.in @@ -168,11 +168,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ diff --git a/src/_updown_espmark/Makefile.in b/src/_updown_espmark/Makefile.in index e30555c1b..c205632dd 100644 --- a/src/_updown_espmark/Makefile.in +++ b/src/_updown_espmark/Makefile.in @@ -168,11 +168,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ diff --git a/src/charon/Makefile.am b/src/charon/Makefile.am index 9111191b6..1d7022336 100644 --- a/src/charon/Makefile.am +++ b/src/charon/Makefile.am @@ -104,7 +104,8 @@ endif INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon -I$(top_srcdir)/src/stroke AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_PIDDIR=\"${piddir}\" \ - -DIPSEC_EAPDIR=\"${eapdir}\" -DIPSEC_BACKENDDIR=\"${backenddir}\" -DIPSEC_INTERFACEDIR=\"${interfacedir}\" + -DIPSEC_EAPDIR=\"${eapdir}\" -DIPSEC_BACKENDDIR=\"${backenddir}\" -DIPSEC_INTERFACEDIR=\"${interfacedir}\" \ + -DSIM_READER_LIB=\"${simreader}\" charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lgmp -lpthread -lm -ldl if USE_LIBCURL @@ -126,6 +127,10 @@ if USE_EAP_SIM eap_LTLIBRARIES += libcharon-eapsim.la libcharon_eapsim_la_SOURCES = sa/authenticators/eap/eap_sim.h sa/authenticators/eap/eap_sim.c libcharon_eapsim_la_LDFLAGS = -module + + plugin_LTLIBRARIES = libcharon-eapsim-file.la + libcharon_eapsim_file_la_SOURCES = sa/authenticators/eap/sim/eap_sim_file.c + libcharon_eapsim_file_la_LDFLAGS = -module endif if USE_EAP_MD5 diff --git a/src/charon/Makefile.in b/src/charon/Makefile.in index bbae1270a..41f1690e2 100644 --- a/src/charon/Makefile.in +++ b/src/charon/Makefile.in @@ -72,12 +72,14 @@ am__vpath_adj = case $$p in \ esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(backenddir)" "$(DESTDIR)$(eapdir)" \ - "$(DESTDIR)$(interfacedir)" "$(DESTDIR)$(ipsecdir)" + "$(DESTDIR)$(interfacedir)" "$(DESTDIR)$(plugindir)" \ + "$(DESTDIR)$(ipsecdir)" backendLTLIBRARIES_INSTALL = $(INSTALL) eapLTLIBRARIES_INSTALL = $(INSTALL) interfaceLTLIBRARIES_INSTALL = $(INSTALL) +pluginLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(backend_LTLIBRARIES) $(eap_LTLIBRARIES) \ - $(interface_LTLIBRARIES) + $(interface_LTLIBRARIES) $(plugin_LTLIBRARIES) am__DEPENDENCIES_1 = @USE_LIBDBUS_TRUE@libcharon_dbus_la_DEPENDENCIES = \ @USE_LIBDBUS_TRUE@ $(am__DEPENDENCIES_1) @@ -123,6 +125,18 @@ libcharon_eapmd5_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libcharon_eapmd5_la_LDFLAGS) $(LDFLAGS) -o $@ @USE_EAP_MD5_TRUE@am_libcharon_eapmd5_la_rpath = -rpath $(eapdir) +libcharon_eapsim_file_la_LIBADD = +am__libcharon_eapsim_file_la_SOURCES_DIST = \ + sa/authenticators/eap/sim/eap_sim_file.c +@USE_EAP_SIM_TRUE@am_libcharon_eapsim_file_la_OBJECTS = \ +@USE_EAP_SIM_TRUE@ eap_sim_file.lo +libcharon_eapsim_file_la_OBJECTS = \ + $(am_libcharon_eapsim_file_la_OBJECTS) +libcharon_eapsim_file_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libcharon_eapsim_file_la_LDFLAGS) $(LDFLAGS) -o $@ +@USE_EAP_SIM_TRUE@am_libcharon_eapsim_file_la_rpath = -rpath \ +@USE_EAP_SIM_TRUE@ $(plugindir) libcharon_eapsim_la_LIBADD = am__libcharon_eapsim_la_SOURCES_DIST = \ sa/authenticators/eap/eap_sim.h \ @@ -349,14 +363,16 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libcharon_dbus_la_SOURCES) $(libcharon_eapaka_la_SOURCES) \ $(libcharon_eapidentity_la_SOURCES) \ - $(libcharon_eapmd5_la_SOURCES) $(libcharon_eapsim_la_SOURCES) \ - $(libcharon_local_la_SOURCES) $(libcharon_sqlite_la_SOURCES) \ - $(libcharon_stroke_la_SOURCES) $(libcharon_xml_la_SOURCES) \ - $(charon_SOURCES) + $(libcharon_eapmd5_la_SOURCES) \ + $(libcharon_eapsim_file_la_SOURCES) \ + $(libcharon_eapsim_la_SOURCES) $(libcharon_local_la_SOURCES) \ + $(libcharon_sqlite_la_SOURCES) $(libcharon_stroke_la_SOURCES) \ + $(libcharon_xml_la_SOURCES) $(charon_SOURCES) DIST_SOURCES = $(am__libcharon_dbus_la_SOURCES_DIST) \ $(am__libcharon_eapaka_la_SOURCES_DIST) \ $(am__libcharon_eapidentity_la_SOURCES_DIST) \ $(am__libcharon_eapmd5_la_SOURCES_DIST) \ + $(am__libcharon_eapsim_file_la_SOURCES_DIST) \ $(am__libcharon_eapsim_la_SOURCES_DIST) \ $(am__libcharon_local_la_SOURCES_DIST) \ $(am__libcharon_sqlite_la_SOURCES_DIST) \ @@ -484,11 +500,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ @@ -601,7 +619,8 @@ INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libstrongswan \ -I$(top_srcdir)/src/charon -I$(top_srcdir)/src/stroke \ $(am__append_13) $(am__append_15) AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_PIDDIR=\"${piddir}\" \ - -DIPSEC_EAPDIR=\"${eapdir}\" -DIPSEC_BACKENDDIR=\"${backenddir}\" -DIPSEC_INTERFACEDIR=\"${interfacedir}\" + -DIPSEC_EAPDIR=\"${eapdir}\" -DIPSEC_BACKENDDIR=\"${backenddir}\" -DIPSEC_INTERFACEDIR=\"${interfacedir}\" \ + -DSIM_READER_LIB=\"${simreader}\" charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \ -lgmp -lpthread -lm -ldl $(am__append_4) @@ -614,6 +633,9 @@ eap_LTLIBRARIES = $(am__append_5) $(am__append_6) $(am__append_7) \ @USE_EAP_IDENTITY_TRUE@libcharon_eapidentity_la_LDFLAGS = -module @USE_EAP_SIM_TRUE@libcharon_eapsim_la_SOURCES = sa/authenticators/eap/eap_sim.h sa/authenticators/eap/eap_sim.c @USE_EAP_SIM_TRUE@libcharon_eapsim_la_LDFLAGS = -module +@USE_EAP_SIM_TRUE@plugin_LTLIBRARIES = libcharon-eapsim-file.la +@USE_EAP_SIM_TRUE@libcharon_eapsim_file_la_SOURCES = sa/authenticators/eap/sim/eap_sim_file.c +@USE_EAP_SIM_TRUE@libcharon_eapsim_file_la_LDFLAGS = -module @USE_EAP_MD5_TRUE@libcharon_eapmd5_la_SOURCES = sa/authenticators/eap/eap_md5.h sa/authenticators/eap/eap_md5.c @USE_EAP_MD5_TRUE@libcharon_eapmd5_la_LDFLAGS = -module @USE_EAP_AKA_TRUE@libcharon_eapaka_la_SOURCES = sa/authenticators/eap/eap_aka.h sa/authenticators/eap/eap_aka.c @@ -754,6 +776,33 @@ clean-interfaceLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \ + else :; fi; \ + done + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done libcharon-dbus.la: $(libcharon_dbus_la_OBJECTS) $(libcharon_dbus_la_DEPENDENCIES) $(libcharon_dbus_la_LINK) $(am_libcharon_dbus_la_rpath) $(libcharon_dbus_la_OBJECTS) $(libcharon_dbus_la_LIBADD) $(LIBS) libcharon-eapaka.la: $(libcharon_eapaka_la_OBJECTS) $(libcharon_eapaka_la_DEPENDENCIES) @@ -762,6 +811,8 @@ libcharon-eapidentity.la: $(libcharon_eapidentity_la_OBJECTS) $(libcharon_eapide $(libcharon_eapidentity_la_LINK) $(am_libcharon_eapidentity_la_rpath) $(libcharon_eapidentity_la_OBJECTS) $(libcharon_eapidentity_la_LIBADD) $(LIBS) libcharon-eapmd5.la: $(libcharon_eapmd5_la_OBJECTS) $(libcharon_eapmd5_la_DEPENDENCIES) $(libcharon_eapmd5_la_LINK) $(am_libcharon_eapmd5_la_rpath) $(libcharon_eapmd5_la_OBJECTS) $(libcharon_eapmd5_la_LIBADD) $(LIBS) +libcharon-eapsim-file.la: $(libcharon_eapsim_file_la_OBJECTS) $(libcharon_eapsim_file_la_DEPENDENCIES) + $(libcharon_eapsim_file_la_LINK) $(am_libcharon_eapsim_file_la_rpath) $(libcharon_eapsim_file_la_OBJECTS) $(libcharon_eapsim_file_la_LIBADD) $(LIBS) libcharon-eapsim.la: $(libcharon_eapsim_la_OBJECTS) $(libcharon_eapsim_la_DEPENDENCIES) $(libcharon_eapsim_la_LINK) $(am_libcharon_eapsim_la_rpath) $(libcharon_eapsim_la_OBJECTS) $(libcharon_eapsim_la_LIBADD) $(LIBS) libcharon-local.la: $(libcharon_local_la_OBJECTS) $(libcharon_local_la_DEPENDENCIES) @@ -838,6 +889,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_method.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_payload.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_sim.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_sim_file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encodings.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encryption_payload.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/endpoint_notify.Po@am__quote@ @@ -957,6 +1009,13 @@ eap_md5.lo: sa/authenticators/eap/eap_md5.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eap_md5.lo `test -f 'sa/authenticators/eap/eap_md5.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_md5.c +eap_sim_file.lo: sa/authenticators/eap/sim/eap_sim_file.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eap_sim_file.lo -MD -MP -MF $(DEPDIR)/eap_sim_file.Tpo -c -o eap_sim_file.lo `test -f 'sa/authenticators/eap/sim/eap_sim_file.c' || echo '$(srcdir)/'`sa/authenticators/eap/sim/eap_sim_file.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/eap_sim_file.Tpo $(DEPDIR)/eap_sim_file.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/eap/sim/eap_sim_file.c' object='eap_sim_file.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eap_sim_file.lo `test -f 'sa/authenticators/eap/sim/eap_sim_file.c' || echo '$(srcdir)/'`sa/authenticators/eap/sim/eap_sim_file.c + eap_sim.lo: sa/authenticators/eap/eap_sim.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eap_sim.lo -MD -MP -MF $(DEPDIR)/eap_sim.Tpo -c -o eap_sim.lo `test -f 'sa/authenticators/eap/eap_sim.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_sim.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/eap_sim.Tpo $(DEPDIR)/eap_sim.Plo @@ -2294,7 +2353,7 @@ check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) installdirs: - for dir in "$(DESTDIR)$(backenddir)" "$(DESTDIR)$(eapdir)" "$(DESTDIR)$(interfacedir)" "$(DESTDIR)$(ipsecdir)"; do \ + for dir in "$(DESTDIR)$(backenddir)" "$(DESTDIR)$(eapdir)" "$(DESTDIR)$(interfacedir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(ipsecdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -2325,7 +2384,7 @@ clean: clean-am clean-am: clean-backendLTLIBRARIES clean-eapLTLIBRARIES clean-generic \ clean-interfaceLTLIBRARIES clean-ipsecPROGRAMS clean-libtool \ - mostlyclean-am + clean-pluginLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) @@ -2344,7 +2403,8 @@ info: info-am info-am: install-data-am: install-backendLTLIBRARIES install-eapLTLIBRARIES \ - install-interfaceLTLIBRARIES install-ipsecPROGRAMS + install-interfaceLTLIBRARIES install-ipsecPROGRAMS \ + install-pluginLTLIBRARIES install-dvi: install-dvi-am @@ -2381,28 +2441,30 @@ ps: ps-am ps-am: uninstall-am: uninstall-backendLTLIBRARIES uninstall-eapLTLIBRARIES \ - uninstall-interfaceLTLIBRARIES uninstall-ipsecPROGRAMS + uninstall-interfaceLTLIBRARIES uninstall-ipsecPROGRAMS \ + uninstall-pluginLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean \ clean-backendLTLIBRARIES clean-eapLTLIBRARIES clean-generic \ clean-interfaceLTLIBRARIES clean-ipsecPROGRAMS clean-libtool \ - ctags distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am \ + clean-pluginLTLIBRARIES ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ install-backendLTLIBRARIES install-data install-data-am \ install-dvi install-dvi-am install-eapLTLIBRARIES install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-interfaceLTLIBRARIES \ install-ipsecPROGRAMS install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-backendLTLIBRARIES \ - uninstall-eapLTLIBRARIES uninstall-interfaceLTLIBRARIES \ - uninstall-ipsecPROGRAMS + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-backendLTLIBRARIES uninstall-eapLTLIBRARIES \ + uninstall-interfaceLTLIBRARIES uninstall-ipsecPROGRAMS \ + 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. diff --git a/src/charon/control/interface_manager.c b/src/charon/control/interface_manager.c index c14903c7d..4d5aa2ea6 100644 --- a/src/charon/control/interface_manager.c +++ b/src/charon/control/interface_manager.c @@ -171,14 +171,11 @@ static bool initiate_listener(interface_bus_listener_t *this, signal_t signal, static status_t initiate_execute(interface_job_t *job) { ike_sa_t *ike_sa; - ike_cfg_t *ike_cfg; interface_bus_listener_t *listener = &job->listener; peer_cfg_t *peer_cfg = listener->peer_cfg; - ike_cfg = peer_cfg->get_ike_cfg(peer_cfg); - ike_sa = charon->ike_sa_manager->checkout_by_peer(charon->ike_sa_manager, - ike_cfg->get_my_host(ike_cfg), ike_cfg->get_other_host(ike_cfg), - peer_cfg->get_my_id(peer_cfg), peer_cfg->get_other_id(peer_cfg)); + ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager, + peer_cfg); listener->ike_sa = ike_sa; if (ike_sa->get_peer_cfg(ike_sa) == NULL) @@ -435,15 +432,11 @@ static bool route_listener(interface_bus_listener_t *this, signal_t signal, static status_t route_execute(interface_job_t *job) { ike_sa_t *ike_sa; - ike_cfg_t *ike_cfg; interface_bus_listener_t *listener = &job->listener; peer_cfg_t *peer_cfg = listener->peer_cfg; - ike_cfg = peer_cfg->get_ike_cfg(peer_cfg); - - ike_sa = charon->ike_sa_manager->checkout_by_peer(charon->ike_sa_manager, - ike_cfg->get_my_host(ike_cfg), ike_cfg->get_other_host(ike_cfg), - peer_cfg->get_my_id(peer_cfg), peer_cfg->get_other_id(peer_cfg)); + ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager, + peer_cfg); listener->ike_sa = ike_sa; if (ike_sa->get_peer_cfg(ike_sa) == NULL) diff --git a/src/charon/control/interfaces/stroke_interface.c b/src/charon/control/interfaces/stroke_interface.c index b51d53ebd..3b4b246bd 100755 --- a/src/charon/control/interfaces/stroke_interface.c +++ b/src/charon/control/interfaces/stroke_interface.c @@ -535,6 +535,24 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out) iterator = charon->backends->create_iterator(charon->backends); while (iterator->iterate(iterator, (void**)&peer_cfg)) { + host_t *my_vip_conf, *other_vip_conf; + bool my_vip_equals = FALSE, other_vip_equals = FALSE; + + my_vip_conf = peer_cfg->get_my_virtual_ip(peer_cfg); + if ((my_vip && my_vip_conf && my_vip->equals(my_vip, my_vip_conf)) || + (!my_vip_conf && !my_vip)) + { + my_vip_equals = TRUE; + } + DESTROY_IF(my_vip_conf); + other_vip_conf = peer_cfg->get_other_virtual_ip(peer_cfg, NULL); + if ((other_vip && other_vip_conf && other_vip->equals(other_vip, other_vip_conf)) || + (!other_vip_conf && !other_vip)) + { + other_vip_equals = TRUE; + } + DESTROY_IF(other_vip_conf); + ike_cfg = peer_cfg->get_ike_cfg(peer_cfg); if (my_id->equals(my_id, peer_cfg->get_my_id(peer_cfg)) && other_id->equals(other_id, peer_cfg->get_other_id(peer_cfg)) @@ -545,7 +563,8 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out) && peer_cfg->get_ike_version(peer_cfg) == (msg->add_conn.ikev2 ? 2 : 1) && peer_cfg->get_auth_method(peer_cfg) == msg->add_conn.auth_method && peer_cfg->get_eap_type(peer_cfg, &vendor) == msg->add_conn.eap_type - && vendor == msg->add_conn.eap_vendor) + && vendor == msg->add_conn.eap_vendor + && my_vip_equals && other_vip_equals) { DBG1(DBG_CFG, "reusing existing configuration '%s'", peer_cfg->get_name(peer_cfg)); diff --git a/src/charon/encoding/payloads/eap_payload.c b/src/charon/encoding/payloads/eap_payload.c index 345114af0..da2498c5e 100644 --- a/src/charon/encoding/payloads/eap_payload.c +++ b/src/charon/encoding/payloads/eap_payload.c @@ -312,13 +312,13 @@ eap_payload_t *eap_payload_create_data(chunk_t data) /* * Described in header */ -eap_payload_t *eap_payload_create_code(eap_code_t code) +eap_payload_t *eap_payload_create_code(eap_code_t code, u_int8_t identifier) { eap_payload_t *this = eap_payload_create(); chunk_t data = chunk_alloca(4); *(data.ptr + 0) = code; - *(data.ptr + 1) = 0; + *(data.ptr + 1) = identifier; *(u_int16_t*)(data.ptr + 2) = htons(data.len); this->set_data(this, data); @@ -328,13 +328,13 @@ eap_payload_t *eap_payload_create_code(eap_code_t code) /* * Described in header */ -eap_payload_t *eap_payload_create_nak() +eap_payload_t *eap_payload_create_nak(u_int8_t identifier) { eap_payload_t *this = eap_payload_create(); chunk_t data = chunk_alloca(5); *(data.ptr + 0) = EAP_RESPONSE; - *(data.ptr + 1) = 0; + *(data.ptr + 1) = identifier; *(u_int16_t*)(data.ptr + 2) = htons(data.len); *(data.ptr + 4) = EAP_NAK; diff --git a/src/charon/encoding/payloads/eap_payload.h b/src/charon/encoding/payloads/eap_payload.h index 3addbb838..e4f8663c2 100644 --- a/src/charon/encoding/payloads/eap_payload.h +++ b/src/charon/encoding/payloads/eap_payload.h @@ -132,19 +132,22 @@ eap_payload_t *eap_payload_create_data(chunk_t data); * Could should be either EAP_SUCCESS/EAP_FAILURE, use * constructor above otherwise. * - * @return eap_payload_t object + * @param code EAP status code + * @param identifier EAP identifier to use in payload + * @return eap_payload_t object * * @ingroup payloads */ -eap_payload_t *eap_payload_create_code(eap_code_t code); +eap_payload_t *eap_payload_create_code(eap_code_t code, u_int8_t identifier); /** * @brief Creates an eap_payload_t EAP_RESPONSE containing an EAP_NAK. * - * @return eap_payload_t object + * @param identifier EAP identifier to use in payload + * @return eap_payload_t object * * @ingroup payloads */ -eap_payload_t *eap_payload_create_nak(); +eap_payload_t *eap_payload_create_nak(u_int8_t identifier); #endif /* EAP_PAYLOAD_H_ */ diff --git a/src/charon/encoding/payloads/id_payload.c b/src/charon/encoding/payloads/id_payload.c index eee5e92db..aef8f6b7e 100644 --- a/src/charon/encoding/payloads/id_payload.c +++ b/src/charon/encoding/payloads/id_payload.c @@ -9,6 +9,7 @@ * Copyright (C) 2007 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter + * * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -49,7 +50,7 @@ struct private_id_payload_t { /** * Next payload type. */ - payload_type_t next_payload; + u_int8_t next_payload; /** * Critical flag. diff --git a/src/charon/sa/authenticators/eap/eap_sim.c b/src/charon/sa/authenticators/eap/eap_sim.c index c9eb5ce8f..90898fb46 100644 --- a/src/charon/sa/authenticators/eap/eap_sim.c +++ b/src/charon/sa/authenticators/eap/eap_sim.c @@ -29,6 +29,21 @@ #define MAX_TRIES 3 +/* number of triplets for one authentication */ +#define TRIPLET_COUNT 3 + +typedef enum sim_subtype_t sim_subtype_t; + +/** + * Subtypes of SIM messages + */ +enum sim_subtype_t { + SIM_START = 10, + SIM_CHALLENGE = 11, + SIM_NOTIFICATION = 12, + SIM_CLIENT_ERROR = 14, +}; + ENUM(sim_subtype_names, SIM_START, SIM_CLIENT_ERROR, "SIM_START", "SIM_CHALLENGE", @@ -37,6 +52,40 @@ ENUM(sim_subtype_names, SIM_START, SIM_CLIENT_ERROR, "SIM_CLIENT_ERROR", ); +typedef enum sim_attribute_t sim_attribute_t; + +/** + * Attributes in SIM messages + */ +enum sim_attribute_t { + /** defines the end of attribute list */ + AT_END = -1, + AT_RAND = 1, + AT_AUTN = 2, + AT_RES = 3, + AT_AUTS = 4, + AT_PADDING = 6, + AT_NONCE_MT = 7, + AT_PERMANENT_ID_REQ = 10, + AT_MAC = 11, + AT_NOTIFICATION = 12, + AT_ANY_ID_REQ = 13, + AT_IDENTITY = 14, + AT_VERSION_LIST = 15, + AT_SELECTED_VERSION = 16, + AT_FULLAUTH_ID_REQ = 17, + AT_COUNTER = 19, + AT_COUNTER_TOO_SMALL = 20, + AT_NONCE_S = 21, + AT_CLIENT_ERROR_CODE = 22, + AT_IV = 129, + AT_ENCR_DATA = 130, + AT_NEXT_PSEUDONYM = 132, + AT_NEXT_REAUTH_ID = 133, + AT_CHECKCODE = 134, + AT_RESULT_IND = 135, +}; + ENUM_BEGIN(sim_attribute_names, AT_END, AT_CLIENT_ERROR_CODE, "AT_END", "AT_0", @@ -96,6 +145,11 @@ struct private_eap_sim_t { sim_algo_t alg; /** + * libraries get_triplet() function returning a triplet + */ + sim_get_triplet_t get_triplet; + + /** * handle of the loaded library */ void *handle; @@ -106,6 +160,16 @@ struct private_eap_sim_t { int tries; /** + * unique EAP identifier + */ + u_int8_t identifier; + + /** + * EAP message type this role sends + */ + u_int8_t type; + + /** * version this implementation uses */ chunk_t version; @@ -121,6 +185,11 @@ struct private_eap_sim_t { chunk_t nonce; /** + * concatenated SRES values + */ + chunk_t sreses; + + /** * k_encr key derived from MK */ chunk_t k_encr; @@ -147,6 +216,10 @@ struct private_eap_sim_t { #define MAC_LEN 16 /** length of the AT_RAND value */ #define RAND_LEN 16 +/** length of Kc */ +#define KC_LEN 8 +/** length of SRES */ +#define SRES_LEN 4 /** length of the k_encr key */ #define KENCR_LEN 16 /** length of the k_auth key */ @@ -156,6 +229,7 @@ struct private_eap_sim_t { /** length of the EMSK */ #define EMSK_LEN 64 +static char version[] = {0x00,0x01}; /* client error codes used in AT_CLIENT_ERROR_CODE */ char client_error_general_buf[] = {0x00, 0x01}; char client_error_unsupported_buf[] = {0x00, 0x02}; @@ -229,7 +303,7 @@ static eap_payload_t *build_payload(private_eap_sim_t *this, u_int8_t identifier chunk_t mac_data = chunk_empty; /* write EAP header, skip length bytes */ - *pos.ptr++ = EAP_RESPONSE; + *pos.ptr++ = this->type; *pos.ptr++ = identifier; pos.ptr += 2; pos.len -= 4; @@ -263,6 +337,7 @@ static eap_payload_t *build_payload(private_eap_sim_t *this, u_int8_t identifier break; } case AT_IDENTITY: + case AT_VERSION_LIST: { u_int16_t act_len = data.len; /* align up to four byte */ @@ -346,8 +421,8 @@ static eap_payload_t *build_payload(private_eap_sim_t *this, u_int8_t identifier /** * process an EAP-SIM/Request/Start message */ -static status_t process_start(private_eap_sim_t *this, eap_payload_t *in, - eap_payload_t **out) +static status_t peer_process_start(private_eap_sim_t *this, eap_payload_t *in, + eap_payload_t **out) { chunk_t message, data; sim_attribute_t attribute, include_id = AT_END; @@ -440,18 +515,56 @@ static status_t process_start(private_eap_sim_t *this, eap_payload_t *in, } /** + * derive EAP keys from kc + */ +static void derive_keys(private_eap_sim_t *this, chunk_t kcs) +{ + chunk_t tmp, mk; + hasher_t *hasher; + prf_t *prf; + int i; + + /* build MK = SHA1(Identity|n*Kc|NONCE_MT|Version List|Selected Version) */ + tmp = chunk_cata("ccccc", this->peer->get_encoding(this->peer), kcs, + this->nonce, this->version_list, this->version); + hasher = hasher_create(HASH_SHA1); + mk = chunk_alloca(hasher->get_hash_size(hasher)); + hasher->get_hash(hasher, tmp, mk.ptr); + hasher->destroy(hasher); + DBG3(DBG_IKE, "MK = SHA1(%B\n) = %B", &tmp, &mk); + + /* K_encr | K_auth | MSK | EMSK = prf() | prf() | prf() | prf() + * FIPS PRF has 320 bit block size, we need 160 byte for keys + * => run prf four times */ + prf = prf_create(PRF_FIPS_SHA1_160); + prf->set_key(prf, mk); + tmp = chunk_alloca(prf->get_block_size(prf) * 4); + for (i = 0; i < 4; i++) + { + prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * i); + } + prf->destroy(prf); + chunk_free(&this->k_encr); + chunk_free(&this->k_auth); + chunk_free(&this->msk); + chunk_free(&this->emsk); + chunk_split(tmp, "aaaa", KENCR_LEN, &this->k_encr, KAUTH_LEN, &this->k_auth, + MSK_LEN, &this->msk, EMSK_LEN, &this->emsk); + DBG3(DBG_IKE, "K_encr %B\nK_auth %B\nMSK %B\nEMSK %B", + &this->k_encr, &this->k_auth, &this->msk, &this->emsk); +} + +/** * process an EAP-SIM/Request/Challenge message */ -static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in, - eap_payload_t **out) +static status_t peer_process_challenge(private_eap_sim_t *this, + eap_payload_t *in, eap_payload_t **out) { - chunk_t message, data, tmp, kcs, kc, sreses, sres, mk; + chunk_t message, data, tmp, kcs, kc, sreses, sres; sim_attribute_t attribute; - u_int8_t identifier, i; + u_int8_t identifier; chunk_t mac = chunk_empty, rands = chunk_empty; signer_t *signer; - hasher_t *hasher; - prf_t *prf; if (this->tries-- <= 0) { @@ -541,7 +654,7 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in, if (this->alg(rands.ptr, RAND_LEN, sres.ptr, &sres_len, kc.ptr, &kc_len)) { - DBG1(DBG_IKE, "unable to get triplets from SIM"); + DBG1(DBG_IKE, "unable to get EAP-SIM triplet"); *out = build_payload(this, identifier, SIM_CLIENT_ERROR, AT_CLIENT_ERROR_CODE, client_error_general, AT_END); @@ -554,34 +667,7 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in, rands = chunk_skip(rands, RAND_LEN); } - /* build MK = SHA1(Identity|n*Kc|NONCE_MT|Version List|Selected Version) */ - tmp = chunk_cata("ccccc", this->peer->get_encoding(this->peer), kcs, - this->nonce, this->version_list, this->version); - hasher = hasher_create(HASH_SHA1); - mk = chunk_alloca(hasher->get_hash_size(hasher)); - hasher->get_hash(hasher, tmp, mk.ptr); - hasher->destroy(hasher); - DBG3(DBG_IKE, "MK = SHA1(%B\n) = %B", &tmp, &mk); - - /* K_encr | K_auth | MSK | EMSK = prf() | prf() | prf() | prf() - * FIPS PRF has 320 bit block size, we need 160 byte for keys - * => run prf four times */ - prf = prf_create(PRF_FIPS_SHA1_160); - prf->set_key(prf, mk); - tmp = chunk_alloca(prf->get_block_size(prf) * 4); - for (i = 0; i < 4; i++) - { - prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * i); - } - prf->destroy(prf); - chunk_free(&this->k_encr); - chunk_free(&this->k_auth); - chunk_free(&this->msk); - chunk_free(&this->emsk); - chunk_split(tmp, "aaaa", KENCR_LEN, &this->k_encr, KAUTH_LEN, &this->k_auth, - MSK_LEN, &this->msk, EMSK_LEN, &this->emsk); - DBG3(DBG_IKE, "K_encr %B\nK_auth %B\nMSK %B\nEMSK %B", - &this->k_encr, &this->k_auth, &this->msk, &this->emsk); + derive_keys(this, kcs); /* verify AT_MAC attribute, signature is over "EAP packet | NONCE_MT" */ signer = signer_create(AUTH_HMAC_SHA1_128); @@ -606,10 +692,144 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in, } /** + * process an EAP-SIM/Response/Challenge message + */ +static status_t server_process_challenge(private_eap_sim_t *this, + eap_payload_t *in, eap_payload_t **out) +{ + chunk_t message, data; + sim_attribute_t attribute; + chunk_t mac = chunk_empty, tmp; + signer_t *signer; + + message = in->get_data(in); + read_header(&message); + + while ((attribute = read_attribute(&message, &data)) != AT_END) + { + switch (attribute) + { + case AT_MAC: + /* MAC has two reserved bytes */ + if (data.len == MAC_LEN + 2) + { /* clone and zero MAC for verification */ + mac = chunk_clonea(chunk_skip(data, 2)); + memset(data.ptr, 0, data.len); + } + break; + default: + DBG1(DBG_IKE, "ignoring EAP_SIM attribute %N", + sim_attribute_names, attribute); + break; + } + } + if (!mac.ptr) + { + DBG1(DBG_IKE, "no valid AT_MAC attribute received"); + return FAILED; + } + /* verify AT_MAC attribute, signature is over "EAP packet | n*SRES" */ + signer = signer_create(AUTH_HMAC_SHA1_128); + signer->set_key(signer, this->k_auth); + tmp = chunk_cata("cc", in->get_data(in), this->sreses); + if (!signer->verify_signature(signer, tmp, mac)) + { + DBG1(DBG_IKE, "AT_MAC verification failed"); + signer->destroy(signer); + return FAILED; + } + signer->destroy(signer); + return SUCCESS; +} + +/** + * process an EAP-SIM/Response/Start message + */ +static status_t server_process_start(private_eap_sim_t *this, + eap_payload_t *in, eap_payload_t **out) +{ + chunk_t message, data; + sim_attribute_t attribute; + bool supported = FALSE; + chunk_t rands, rand, kcs, kc, sreses, sres; + char id[64]; + int len, i, rand_len, kc_len, sres_len; + + message = in->get_data(in); + read_header(&message); + + while ((attribute = read_attribute(&message, &data)) != AT_END) + { + switch (attribute) + { + case AT_NONCE_MT: + if (data.len == NONCE_LEN + 2) + { + this->nonce = chunk_clone(chunk_skip(data, 2)); + } + break; + case AT_SELECTED_VERSION: + if (chunk_equals(data, this->version)) + { + supported = TRUE; + } + break; + default: + DBG1(DBG_IKE, "ignoring EAP_SIM attribute %N", + sim_attribute_names, attribute); + break; + } + } + if (!supported || !this->nonce.ptr) + { + DBG1(DBG_IKE, "received incomplete EAP-SIM/Response/Start"); + return FAILED; + } + len = snprintf(id, sizeof(id), "%D", this->peer); + if (len > sizeof(id) || len < 0) + { + return FAILED; + } + + /* read triplets from provider */ + rand = rands = chunk_alloca(RAND_LEN * TRIPLET_COUNT); + kc = kcs = chunk_alloca(KC_LEN * TRIPLET_COUNT); + sres = sreses = chunk_alloca(SRES_LEN * TRIPLET_COUNT); + rands.len = 0; + kcs.len = 0; + sreses.len = 0; + for (i = 0; i < TRIPLET_COUNT; i++) + { + rand_len = RAND_LEN; + kc_len = KC_LEN; + sres_len = SRES_LEN; + if (this->get_triplet(id, rand.ptr, &rand_len, sres.ptr, &sres_len, + kc.ptr, &kc_len)) + { + DBG1(DBG_IKE, "getting EAP-SIM triplet %d failed", i); + return FAILED; + } + rands.len += rand_len; + kcs.len += kc_len; + sreses.len += sres_len; + rand = chunk_skip(rand, rand_len); + kc = chunk_skip(kc, kc_len); + sres = chunk_skip(sres, sres_len); + } + derive_keys(this, kcs); + + /* build MAC over "EAP packet | NONCE_MT" */ + *out = build_payload(this, this->identifier++, SIM_CHALLENGE, AT_RAND, + rands, AT_MAC, this->nonce, AT_END); + this->sreses = chunk_clone(sreses); + return NEED_MORE; +} + +/** * process an EAP-SIM/Request/Notification message */ -static status_t process_notification(private_eap_sim_t *this, eap_payload_t *in, - eap_payload_t **out) +static status_t peer_process_notification(private_eap_sim_t *this, + eap_payload_t *in, eap_payload_t **out) { chunk_t message, data; sim_attribute_t attribute; @@ -656,12 +876,44 @@ static status_t process_notification(private_eap_sim_t *this, eap_payload_t *in, return NEED_MORE; } +/** + * Process a client error + */ +static status_t server_process_client_error(private_eap_sim_t *this, + eap_payload_t *in, eap_payload_t **out) +{ + chunk_t message, data; + sim_attribute_t attribute; + + message = in->get_data(in); + read_header(&message); + + while ((attribute = read_attribute(&message, &data)) != AT_END) + { + if (attribute == AT_CLIENT_ERROR_CODE) + { + u_int16_t code = 0; + if (data.len == 2) + { + code = ntohs(*(u_int16_t*)data.ptr); + } + DBG1(DBG_IKE, "received %N error %d", + sim_attribute_names, attribute, code); + } + else + { + DBG1(DBG_IKE, "ignoring EAP_SIM attribute %N", + sim_attribute_names, attribute); + } + } + return FAILED; +} /** * Implementation of eap_method_t.process for the peer */ -static status_t process(private_eap_sim_t *this, - eap_payload_t *in, eap_payload_t **out) +static status_t peer_process(private_eap_sim_t *this, + eap_payload_t *in, eap_payload_t **out) { sim_subtype_t type; chunk_t message; @@ -672,11 +924,11 @@ static status_t process(private_eap_sim_t *this, switch (type) { case SIM_START: - return process_start(this, in, out); + return peer_process_start(this, in, out); case SIM_CHALLENGE: - return process_challenge(this, in, out); + return peer_process_challenge(this, in, out); case SIM_NOTIFICATION: - return process_notification(this, in, out); + return peer_process_notification(this, in, out); default: DBG1(DBG_IKE, "unable to process EAP_SIM subtype %N", sim_subtype_names, type); @@ -687,15 +939,55 @@ static status_t process(private_eap_sim_t *this, } /** + * Implementation of eap_method_t.process for the server + */ +static status_t server_process(private_eap_sim_t *this, + eap_payload_t *in, eap_payload_t **out) +{ + sim_subtype_t type; + chunk_t message; + + message = in->get_data(in); + type = read_header(&message); + + switch (type) + { + case SIM_START: + return server_process_start(this, in, out); + case SIM_CHALLENGE: + return server_process_challenge(this, in, out); + case SIM_CLIENT_ERROR: + return server_process_client_error(this, in, out); + default: + DBG1(DBG_IKE, "unable to process EAP_SIM subtype %N", + sim_subtype_names, type); + return FAILED; + } +} + +/** * Implementation of eap_method_t.initiate for the peer */ -static status_t initiate(private_eap_sim_t *this, eap_payload_t **out) +static status_t peer_initiate(private_eap_sim_t *this, eap_payload_t **out) { /* peer never initiates */ return FAILED; } /** + * Implementation of eap_method_t.initiate for the server + */ +static status_t server_initiate(private_eap_sim_t *this, eap_payload_t **out) +{ + /* version_list to derive MK, no padding */ + this->version_list = chunk_clone(this->version); + /* build_payloads adds padding itself */ + *out = build_payload(this, this->identifier++, SIM_START, + AT_VERSION_LIST, this->version, AT_END); + return NEED_MORE; +} + +/** * Implementation of eap_method_t.get_type. */ static eap_type_t get_type(private_eap_sim_t *this, u_int32_t *vendor) @@ -732,6 +1024,7 @@ static void destroy(private_eap_sim_t *this) { dlclose(this->handle); chunk_free(&this->nonce); + chunk_free(&this->sreses); chunk_free(&this->version_list); chunk_free(&this->k_auth); chunk_free(&this->k_encr); @@ -748,60 +1041,85 @@ eap_sim_t *eap_create(eap_role_t role, { private_eap_sim_t *this; randomizer_t *randomizer; - static char version[] = {0x00,0x01}; - - if (role != EAP_PEER) - { - return NULL; - } - this = malloc_thing(private_eap_sim_t); + void *symbol; + char *name; + + this = malloc_thing(private_eap_sim_t); + this->alg = NULL; + this->get_triplet = NULL; + this->nonce = chunk_empty; + this->sreses = chunk_empty; + this->peer = peer; + this->tries = MAX_TRIES; + this->version.ptr = version; + this->version.len = sizeof(version); + this->version_list = chunk_empty; + this->k_auth = chunk_empty; + this->k_encr = chunk_empty; + this->msk = chunk_empty; + this->emsk = chunk_empty; + this->identifier = random(); this->handle = dlopen(SIM_READER_LIB, RTLD_LAZY); if (this->handle == NULL) { - DBG1(DBG_IKE, "unable to open SIM reader '%s'", SIM_READER_LIB); + DBG1(DBG_IKE, "unable to open SIM reader '%s'", SIM_READER_LIB); free(this); return NULL; } - this->alg = dlsym(this->handle, SIM_READER_ALG); - if (this->alg == NULL) + switch (role) { - DBG1(DBG_IKE, "unable to open SIM reader function '%s' in '%s'", - SIM_READER_ALG, SIM_READER_LIB); + case EAP_PEER: + name = SIM_READER_ALG; + break; + case EAP_SERVER: + name = SIM_READER_GET_TRIPLET; + break; + default: + free(this); + return NULL; + } + symbol = dlsym(this->handle, name); + if (symbol == NULL) + { + DBG1(DBG_IKE, "unable to open SIM function '%s' in '%s'", + name, SIM_READER_LIB); dlclose(this->handle); free(this); return NULL; } - - randomizer = randomizer_create(); - if (randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_LEN, - &this->nonce)) + switch (role) { - DBG1(DBG_IKE, "unable to generate NONCE for EAP_SIM"); - randomizer->destroy(randomizer); - free(this); - return NULL; + case EAP_SERVER: + this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))server_initiate; + this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))server_process; + this->get_triplet = symbol; + this->type = EAP_REQUEST; + break; + case EAP_PEER: + this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))peer_initiate; + this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))peer_process; + this->alg = symbol; + this->type = EAP_RESPONSE; + randomizer = randomizer_create(); + if (randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_LEN, + &this->nonce)) + { + DBG1(DBG_IKE, "unable to generate NONCE for EAP_SIM"); + randomizer->destroy(randomizer); + free(this); + return NULL; + } + randomizer->destroy(randomizer); + break; + default: + free(this); + return NULL; } - randomizer->destroy(randomizer); - - /* public functions */ - this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate; - this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process; this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type; this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual; this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk; this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy; - /* private data */ - this->peer = peer; - this->tries = MAX_TRIES; - this->version.ptr = version; - this->version.len = sizeof(version); - this->version_list = chunk_empty; - this->k_auth = chunk_empty; - this->k_encr = chunk_empty; - this->msk = chunk_empty; - this->emsk = chunk_empty; - return &this->public; } diff --git a/src/charon/sa/authenticators/eap/eap_sim.h b/src/charon/sa/authenticators/eap/eap_sim.h index 10640babe..d50cf7397 100644 --- a/src/charon/sa/authenticators/eap/eap_sim.h +++ b/src/charon/sa/authenticators/eap/eap_sim.h @@ -24,59 +24,13 @@ #define EAP_SIM_H_ typedef struct eap_sim_t eap_sim_t; -typedef enum sim_subtype_t sim_subtype_t; -typedef enum sim_attribute_t sim_attribute_t; #include <sa/authenticators/eap/eap_method.h> -/** - * Subtypes of SIM messages - */ -enum sim_subtype_t { - SIM_START = 10, - SIM_CHALLENGE = 11, - SIM_NOTIFICATION = 12, - SIM_CLIENT_ERROR = 14, -}; - -/** - * enum names for sim_subtype_t - */ -extern enum_name_t *sim_subtype_names; - -enum sim_attribute_t { - /** defines the end of attribute list */ - AT_END = -1, - AT_RAND = 1, - AT_AUTN = 2, - AT_RES = 3, - AT_AUTS = 4, - AT_PADDING = 6, - AT_NONCE_MT = 7, - AT_PERMANENT_ID_REQ = 10, - AT_MAC = 11, - AT_NOTIFICATION = 12, - AT_ANY_ID_REQ = 13, - AT_IDENTITY = 14, - AT_VERSION_LIST = 15, - AT_SELECTED_VERSION = 16, - AT_FULLAUTH_ID_REQ = 17, - AT_COUNTER = 19, - AT_COUNTER_TOO_SMALL = 20, - AT_NONCE_S = 21, - AT_CLIENT_ERROR_CODE = 22, - AT_IV = 129, - AT_ENCR_DATA = 130, - AT_NEXT_PSEUDONYM = 132, - AT_NEXT_REAUTH_ID = 133, - AT_CHECKCODE = 134, - AT_RESULT_IND = 135, -}; - -/** - * enum names for sim_subtype_t - */ -extern enum_name_t *sim_attribute_names; +/** the library containing with the triplet functions */ +#ifndef SIM_READER_LIB +#error SIM_READER_LIB not specified, use --with-sim-reader option +#endif /* SIM_READER_LIB */ /** * @brief Cardreaders SIM function. @@ -93,24 +47,42 @@ typedef int (*sim_algo_t)(const unsigned char *rand, int rand_length, unsigned char *sres, int *sres_length, unsigned char *kc, int *kc_length); -#ifndef SIM_READER_LIB -/** the library containing the cardreader with the SIM function */ -#error SIM_READER_LIB not specified, use --with-sim-reader option -#endif /* SIM_READER_LIB */ - #ifndef SIM_READER_ALG /** the SIM_READER_LIB's algorithm, uses sim_algo_t signature */ #define SIM_READER_ALG "sim_run_alg" #endif /* SIM_READER_ALG */ +/** + * @brief Function to get a SIM triplet. + * + * @param identity identity (imsi) to get a triplet for + * @param rand buffer to get RAND + * @param rand_length size of buffer in rand, returns bytes written to RAND + * @param sres buffer to get SRES + * @param sres_length size of buffer in sres, returns bytes written to SRES + * @param kc buffer to get Kc + * @param kc_length size of buffer in Kc, returns bytes written to Kc + * @return zero on success + */ +typedef int (*sim_get_triplet_t)(char *identity, + unsigned char *rand, int *rand_length, + unsigned char *sres, int *sres_length, + unsigned char *kc, int *kc_length); + +#ifndef SIM_READER_GET_TRIPLET +/** the SIM_READER_LIB's get-triplet function, uses sim_get_triplet_t signature */ +#define SIM_READER_GET_TRIPLET "sim_get_triplet" +#endif /* SIM_READER_GET_TRIPLET */ /** * @brief Implementation of the eap_method_t interface using EAP-SIM. * * This EAP-SIM client implementation uses another pluggable library to - * access the SIM card. This module is specified using the SIM_READER_LIB - * definition. The function to run the algorithm has the sim_algo_t type and - * is named as SIM_READER_ALG is defined. + * access the SIM card/triplet provider. This module is specified using the + * SIM_READER_LIB definition. It has to privde a sim_run_alg() function to + * calculate a triplet (client), and/or a sim_get_triplet() function to get + * a triplet (server). These functions are named to the SIM_READER_ALG and + * the SIM_READER_GET_TRIPLET definitions. * * @b Constructors: * - eap_create() of this module @@ -129,6 +101,7 @@ struct eap_sim_t { /** * @brief Creates the EAP method EAP-SIM. * + * @param role role of the module, client/server * @param server ID of the EAP server * @param peer ID of the EAP client * @return eap_sim_t object diff --git a/src/charon/sa/authenticators/eap/sim/eap_sim_file.c b/src/charon/sa/authenticators/eap/sim/eap_sim_file.c new file mode 100644 index 000000000..2ab45a578 --- /dev/null +++ b/src/charon/sa/authenticators/eap/sim/eap_sim_file.c @@ -0,0 +1,288 @@ +/**
+ * @file eap_sim.h
+ *
+ * @brief Interface of eap_sim_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <daemon.h>
+
+#define IMSI_LEN 64
+#define RAND_LEN 16
+#define SRES_LEN 4
+#define KC_LEN 8
+
+typedef struct triplet_t triplet_t;
+
+struct triplet_t {
+ unsigned char imsi[IMSI_LEN];
+ unsigned char rand[RAND_LEN];
+ unsigned char sres[SRES_LEN];
+ unsigned char kc[KC_LEN];
+};
+
+static triplet_t *triplets = NULL;
+static int triplet_count = 0;
+
+#define TRIPLET_FILE IPSEC_CONFDIR "/ipsec.d/triplets.dat"
+
+/**
+ * convert a single HEX char to its integer value
+ */
+static int hexchr(char chr)
+{
+ switch (chr)
+ {
+ case '0'...'9':
+ return chr - '0';
+ case 'A'...'F':
+ return 10 + chr - 'A';
+ case 'a'...'f':
+ return 10 + chr - 'a';
+ }
+ return 0;
+}
+
+/**
+ * convert a HEX string into a char array bin, limited by array length len
+ */
+static void hex2bin(char *hex, unsigned char *bin, size_t len)
+{
+ char *pos;
+ int i, even = 1;
+
+ pos = hex - 1;
+ /* find the end, as we convert bottom up */
+ while (TRUE)
+ {
+ switch (*(pos+1))
+ {
+ case '0'...'9':
+ case 'A'...'F':
+ case 'a'...'f':
+ pos++;
+ continue;
+ }
+ break;
+ }
+ /* convert two hex chars into a single bin byte */
+ for (i = 0; pos >= hex && i < len; pos--)
+ {
+ if (even)
+ {
+ bin[len - 1 - i] = hexchr(*pos);
+ }
+ else
+ {
+ bin[len - 1 - i] |= 16 * hexchr(*pos);
+ i++;
+ }
+ even = !even;
+ }
+}
+
+/**
+ * free up allocated triplets
+ */
+static void __attribute__ ((destructor)) free_triplets()
+{
+ free(triplets);
+}
+
+/**
+ * read the triplets from the file, using freeradius triplet file syntax:
+ * http://www.freeradius.org/radiusd/doc/rlm_sim_triplets
+ */
+static void __attribute__ ((constructor)) read_triplets()
+{
+ char line[512], *data[4], *pos;
+ FILE *file;
+ int i, nr = 0;
+ triplet_t *triplet;
+
+ file = fopen(TRIPLET_FILE, "r");
+ if (file == NULL)
+ {
+ DBG1(DBG_CFG, "opening triplet file %s failed: %s",
+ TRIPLET_FILE, strerror(errno));
+ return;
+ }
+
+ if (triplets)
+ {
+ free(triplets);
+ triplets = NULL;
+ triplet_count = 0;
+ }
+
+ /* read line by line */
+ while (fgets(line, sizeof(line), file))
+ {
+ nr++;
+ /* skip comments, empty lines */
+ switch (line[0])
+ {
+ case '\n':
+ case '\r':
+ case '#':
+ case '\0':
+ continue;
+ default:
+ break;
+ }
+ /* read comma separated values */
+ pos = line;
+ for (i = 0; i < 4; i++)
+ {
+ data[i] = pos;
+ pos = strchr(pos, ',');
+ if (pos)
+ {
+ *pos = '\0';
+ pos++;
+ }
+ else if (i != 3)
+ {
+ DBG1(DBG_CFG, "error in triplet file, line %d", nr);
+ fclose(file);
+ return;
+ }
+ }
+ /* allocate new triplet */
+ triplet_count++;
+ triplets = realloc(triplets, triplet_count * sizeof(triplet_t));
+ triplet = &triplets[triplet_count - 1];
+ memset(triplet, 0, sizeof(triplet_t));
+
+ /* convert/copy triplet data */
+ for (i = 0; i < IMSI_LEN - 1; i++)
+ {
+ switch (data[0][i])
+ {
+ case '\n':
+ case '\r':
+ case '\0':
+ break;
+ default:
+ triplet->imsi[i] = data[0][i];
+ continue;
+ }
+ break;
+ }
+ hex2bin(data[1], triplet->rand, RAND_LEN);
+ hex2bin(data[2], triplet->sres, SRES_LEN);
+ hex2bin(data[3], triplet->kc, KC_LEN);
+
+ DBG4(DBG_CFG, "triplet: imsi %b\nrand %b\nsres %b\nkc %b",
+ triplet->imsi, IMSI_LEN, triplet->rand, RAND_LEN,
+ triplet->sres, SRES_LEN, triplet->kc, KC_LEN);
+ }
+ fclose(file);
+ DBG2(DBG_CFG, "read %d triplets from %s", triplet_count, TRIPLET_FILE);
+}
+
+/**
+ * Run the sim algorithm, see eap_sim.h
+ */
+int sim_run_alg(const unsigned char *rand, int rand_length,
+ unsigned char *sres, int *sres_length,
+ unsigned char *kc, int *kc_length)
+{
+ int current;
+
+ if (rand_length != RAND_LEN ||
+ *sres_length < SRES_LEN ||
+ *kc_length < KC_LEN)
+ {
+ return 1;
+ }
+
+ for (current = 0; current < triplet_count; current++)
+ {
+ if (memcmp(triplets[current].rand, rand, RAND_LEN) == 0)
+ {
+ memcpy(sres, triplets[current].sres, SRES_LEN);
+ memcpy(kc, triplets[current].kc, KC_LEN);
+ *sres_length = SRES_LEN;
+ *kc_length = KC_LEN;
+ return 0;
+ }
+ }
+ return 2;
+}
+
+/**
+ * Get a single triplet, see_eap_sim.h
+ */
+int sim_get_triplet(char *imsi,
+ unsigned char *rand, int *rand_length,
+ unsigned char *sres, int *sres_length,
+ unsigned char *kc, int *kc_length)
+{
+ int current;
+ triplet_t *triplet;
+ static int skip = -1;
+
+ DBG2(DBG_CFG, "getting triplet for %s", imsi);
+
+ if (*rand_length < RAND_LEN ||
+ *sres_length < SRES_LEN ||
+ *kc_length < KC_LEN)
+ {
+ return 1;
+ }
+ if (triplet_count == 0)
+ {
+ return 2;
+ }
+ for (current = 0; current < triplet_count; current++)
+ {
+ triplet = &triplets[current];
+
+ if (streq(imsi, triplet->imsi))
+ {
+ /* skip triplet if already used */
+ if (skip >= current)
+ {
+ continue;
+ }
+ *rand_length = RAND_LEN;
+ *sres_length = SRES_LEN;
+ *kc_length = KC_LEN;
+ memcpy(rand, triplet->rand, RAND_LEN);
+ memcpy(sres, triplet->sres, SRES_LEN);
+ memcpy(kc, triplet->kc, KC_LEN);
+ /* remember used triplet */
+ skip = current;
+ return 0;
+ }
+ }
+ if (skip > -1)
+ {
+ /* no triplet left, reuse triplets */
+ skip = -1;
+ return sim_get_triplet(imsi, rand, rand_length,
+ sres, sres_length, kc, kc_length);
+ }
+ return 2;
+}
+
diff --git a/src/charon/sa/authenticators/eap_authenticator.c b/src/charon/sa/authenticators/eap_authenticator.c index 6250604a6..edd75da43 100644 --- a/src/charon/sa/authenticators/eap_authenticator.c +++ b/src/charon/sa/authenticators/eap_authenticator.c @@ -147,7 +147,7 @@ static status_t initiate(private_eap_authenticator_t *this, eap_type_t type, { DBG1(DBG_IKE, "client requested EAP authentication, but configuration forbids it"); - *out = eap_payload_create_code(EAP_FAILURE); + *out = eap_payload_create_code(EAP_FAILURE, 0); return FAILED; } @@ -169,14 +169,14 @@ static status_t initiate(private_eap_authenticator_t *this, eap_type_t type, DBG1(DBG_IKE, "configured EAP server method not supported, sending %N", eap_code_names, EAP_FAILURE); - *out = eap_payload_create_code(EAP_FAILURE); + *out = eap_payload_create_code(EAP_FAILURE, 0); return FAILED; } if (this->method->initiate(this->method, out) != NEED_MORE) { DBG1(DBG_IKE, "failed to initiate EAP exchange, sending %N", eap_type_names, type, eap_code_names, EAP_FAILURE); - *out = eap_payload_create_code(EAP_FAILURE); + *out = eap_payload_create_code(EAP_FAILURE, 0); return FAILED; } return NEED_MORE; @@ -234,7 +234,7 @@ static status_t process_peer(private_eap_authenticator_t *this, { DBG1(DBG_IKE, "EAP server requested unsupported " "EAP method, sending EAP_NAK"); - *out = eap_payload_create_nak(); + *out = eap_payload_create_nak(in->get_identifier(in)); return NEED_MORE; } } @@ -303,7 +303,7 @@ static status_t process_server(private_eap_authenticator_t *this, DBG1(DBG_IKE, "EAP method %N succeded, %sMSK established", eap_type_names, type, this->msk.ptr ? "" : "no "); } - *out = eap_payload_create_code(EAP_SUCCESS); + *out = eap_payload_create_code(EAP_SUCCESS, in->get_identifier(in)); return SUCCESS; case FAILED: default: @@ -319,7 +319,7 @@ static status_t process_server(private_eap_authenticator_t *this, eap_type_names, type, this->ike_sa->get_other_id(this->ike_sa)); } - *out = eap_payload_create_code(EAP_FAILURE); + *out = eap_payload_create_code(EAP_FAILURE, in->get_identifier(in)); return FAILED; } } @@ -346,7 +346,8 @@ static status_t process(private_eap_authenticator_t *this, eap_payload_t *in, { DBG1(DBG_IKE, "received %N, sending %N", eap_code_names, code, eap_code_names, EAP_FAILURE); - *out = eap_payload_create_code(EAP_FAILURE); + *out = eap_payload_create_code(EAP_FAILURE, + in->get_identifier(in)); return FAILED; } } diff --git a/src/charon/sa/connect_manager.c b/src/charon/sa/connect_manager.c index d0f3cde8d..06755fa9c 100644 --- a/src/charon/sa/connect_manager.c +++ b/src/charon/sa/connect_manager.c @@ -27,6 +27,7 @@ #include <daemon.h> #include <utils/linked_list.h> +#include <crypto/hashers/hasher.h> #include <processing/jobs/callback_job.h> #include <processing/jobs/initiate_mediation_job.h> @@ -493,29 +494,18 @@ static initiate_data_t *initiate_data_create(check_list_t *checklist, initiated_ /** * Find an initiated connection by the peers' ids */ +static bool match_initiated_by_ids(initiated_t *current, identification_t *id, + identification_t *peer_id) +{ + return id->equals(id, current->id) && peer_id->equals(peer_id, current->peer_id); +} + static status_t get_initiated_by_ids(private_connect_manager_t *this, identification_t *id, identification_t *peer_id, initiated_t **initiated) { - iterator_t *iterator; - initiated_t *current; - status_t status = NOT_FOUND; - - iterator = this->initiated->create_iterator(this->initiated, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) - { - if (id->equals(id, current->id) && peer_id->equals(peer_id, current->peer_id)) - { - if (initiated) - { - *initiated = current; - } - status = SUCCESS; - break; - } - } - iterator->destroy(iterator); - - return status; + return this->initiated->find_first(this->initiated, + (linked_list_match_t)match_initiated_by_ids, + (void**)initiated, id, peer_id); } /** @@ -541,56 +531,32 @@ static void remove_initiated(private_connect_manager_t *this, initiated_t *initi /** * Finds a waiting sa */ -static status_t get_waiting_sa(initiated_t *initiated, ike_sa_id_t *ike_sa_id, waiting_sa_t **waiting_sa) +static bool match_waiting_sa(waiting_sa_t *current, ike_sa_id_t *ike_sa_id) { - iterator_t *iterator; - waiting_sa_t *current; - status_t status = NOT_FOUND; - - iterator = initiated->mediated->create_iterator(initiated->mediated, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) - { - if (ike_sa_id->equals(ike_sa_id, current->ike_sa_id)) - { - if (waiting_sa) - { - *waiting_sa = current; - } - status = SUCCESS; - break; - } - } - iterator->destroy(iterator); + return ike_sa_id->equals(ike_sa_id, current->ike_sa_id); +} - return status; +static status_t get_waiting_sa(initiated_t *initiated, ike_sa_id_t *ike_sa_id, waiting_sa_t **waiting_sa) +{ + return initiated->mediated->find_first(initiated->mediated, + (linked_list_match_t)match_waiting_sa, + (void**)waiting_sa, ike_sa_id); } /** * Find the checklist with a specific session ID */ +static bool match_checklist_by_id(check_list_t *current, chunk_t *session_id) +{ + return chunk_equals(*session_id, current->session_id); +} + static status_t get_checklist_by_id(private_connect_manager_t *this, chunk_t session_id, check_list_t **check_list) { - iterator_t *iterator; - check_list_t *current; - status_t status = NOT_FOUND; - - iterator = this->checklists->create_iterator(this->checklists, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) - { - if (chunk_equals(session_id, current->session_id)) - { - if (check_list) - { - *check_list = current; - } - status = SUCCESS; - break; - } - } - iterator->destroy(iterator); - - return status; + return this->checklists->find_first(this->checklists, + (linked_list_match_t)match_checklist_by_id, + (void**)check_list, &session_id); } /** @@ -616,28 +582,16 @@ static void remove_checklist(private_connect_manager_t *this, check_list_t *chec /** * Checks if a list of endpoint_notify_t contains a certain host_t */ +static bool match_endpoint_by_host(endpoint_notify_t *current, host_t *host) +{ + return host->equals(host, current->get_host(current)); +} + static status_t endpoints_contain(linked_list_t *endpoints, host_t *host, endpoint_notify_t **endpoint) { - iterator_t *iterator; - endpoint_notify_t *current; - status_t status = NOT_FOUND; - - iterator = endpoints->create_iterator(endpoints, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) - { - if (host->equals(host, current->get_host(current))) - { - if (endpoint) - { - *endpoint = current; - } - status = SUCCESS; - break; - } - } - iterator->destroy(iterator); - - return status; + return endpoints->find_first(endpoints, + (linked_list_match_t)match_endpoint_by_host, + (void**)endpoint, host); } /** @@ -715,88 +669,56 @@ static void insert_pair_by_priority(linked_list_t *pairs, endpoint_pair_t *pair) /** * Searches a list of endpoint_pair_t for a pair with specific host_ts */ +static bool match_pair_by_hosts(endpoint_pair_t *current, host_t *local, host_t *remote) +{ + return local->equals(local, current->local) && remote->equals(remote, current->remote); +} + static status_t get_pair_by_hosts(linked_list_t *pairs, host_t *local, host_t *remote, endpoint_pair_t **pair) { - iterator_t *iterator; - endpoint_pair_t *current; - status_t status = NOT_FOUND; - - iterator = pairs->create_iterator(pairs, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) - { - if (local->equals(local, current->local) && - remote->equals(remote, current->remote)) - { - if (pair) - { - *pair = current; - } - status = SUCCESS; - break; - } - } - iterator->destroy(iterator); - - return status; + return pairs->find_first(pairs, + (linked_list_match_t)match_pair_by_hosts, + (void**)pair, local, remote); } /** * Searches for a pair with a specific id */ +static bool match_pair_by_id(endpoint_pair_t *current, u_int32_t *id) +{ + return current->id == *id; +} + static status_t get_pair_by_id(check_list_t *checklist, u_int32_t id, endpoint_pair_t **pair) { - iterator_t *iterator; - endpoint_pair_t *current; - status_t status = NOT_FOUND; - - iterator = checklist->pairs->create_iterator(checklist->pairs, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) - { - if (current->id == id) - { - if (pair) - { - *pair = current; - } - status = SUCCESS; - break; - } - } - iterator->destroy(iterator); - - return status; + return checklist->pairs->find_first(checklist->pairs, + (linked_list_match_t)match_pair_by_id, + (void**)pair, &id); } /** * Returns the best pair of state CHECK_SUCCEEDED from a checklist. */ +static bool match_succeeded_pair(endpoint_pair_t *current) +{ + return current->state == CHECK_SUCCEEDED; +} + static status_t get_best_valid_pair(check_list_t *checklist, endpoint_pair_t **pair) { - iterator_t *iterator; - endpoint_pair_t *current; - status_t status = NOT_FOUND; - - iterator = checklist->pairs->create_iterator(checklist->pairs, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) - { - if (current->state == CHECK_SUCCEEDED) - { - if (pair) - { - *pair = current; - } - status = SUCCESS; - break; - } - } - iterator->destroy(iterator); - - return status; + return checklist->pairs->find_first(checklist->pairs, + (linked_list_match_t)match_succeeded_pair, + (void**)pair); } /** - * Returns and removes the first triggered pair in state CHECK_WAITING. + * Returns and *removes* the first triggered pair in state CHECK_WAITING. */ +static bool match_waiting_pair(endpoint_pair_t *current) +{ + return current->state == CHECK_WAITING; +} + static status_t get_triggered_pair(check_list_t *checklist, endpoint_pair_t **pair) { iterator_t *iterator; @@ -1148,21 +1070,8 @@ static job_requeue_t sender(sender_data_t *data) { DBG1(DBG_IKE, "no triggered check queued, sending an ordinary check"); - iterator_t *iterator; - bool found_one = FALSE; - - iterator = checklist->pairs->create_iterator(checklist->pairs, TRUE); - while (iterator->iterate(iterator, (void**)&pair)) - { - if (pair->state == CHECK_WAITING) - { - found_one = TRUE; - break; - } - } - iterator->destroy(iterator); - - if (!found_one) + if (checklist->pairs->find_first(checklist->pairs, + (linked_list_match_t)match_waiting_pair, (void**)&pair) != SUCCESS) { pthread_mutex_unlock(&(this->mutex)); DBG1(DBG_IKE, "no pairs in waiting state, aborting"); diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c index 9cada2cb5..93aa08965 100644 --- a/src/charon/sa/ike_sa.c +++ b/src/charon/sa/ike_sa.c @@ -2090,7 +2090,14 @@ static status_t inherit(private_ike_sa_t *this, private_ike_sa_t *other) { this->dns_servers->insert_first(this->dns_servers, ip); } - + + /* inherit NAT-T conditions */ + this->conditions = other->conditions; + if (this->conditions & COND_NAT_HERE) + { + send_keepalive(this); + } + /* adopt all children */ while (other->child_sas->remove_last(other->child_sas, (void**)&child_sa) == SUCCESS) diff --git a/src/charon/sa/ike_sa_manager.c b/src/charon/sa/ike_sa_manager.c index 5014ea0e2..5e7f78af0 100644 --- a/src/charon/sa/ike_sa_manager.c +++ b/src/charon/sa/ike_sa_manager.c @@ -483,16 +483,23 @@ static ike_sa_t* checkout_by_message(private_ike_sa_manager_t* this, } /** - * Implementation of of ike_sa_manager.checkout_by_peer. + * Implementation of of ike_sa_manager.checkout_by_config. */ -static ike_sa_t* checkout_by_peer(private_ike_sa_manager_t *this, - host_t *my_host, host_t *other_host, - identification_t *my_id, - identification_t *other_id) +static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this, + peer_cfg_t *peer_cfg) { iterator_t *iterator; entry_t *entry; ike_sa_t *ike_sa = NULL; + identification_t *my_id, *other_id; + host_t *my_host, *other_host; + ike_cfg_t *ike_cfg; + + ike_cfg = peer_cfg->get_ike_cfg(peer_cfg); + my_host = ike_cfg->get_my_host(ike_cfg); + other_host = ike_cfg->get_other_host(ike_cfg); + my_id = peer_cfg->get_my_id(peer_cfg); + other_id = peer_cfg->get_other_id(peer_cfg); pthread_mutex_lock(&(this->mutex)); @@ -535,7 +542,9 @@ static ike_sa_t* checkout_by_peer(private_ike_sa_manager_t *this, (other_host->is_anyaddr(other_host) || other_host->ip_equals(other_host, found_other_host)) && found_my_id->matches(found_my_id, my_id, &wc) && - found_other_id->matches(found_other_id, other_id, &wc)) + found_other_id->matches(found_other_id, other_id, &wc) && + streq(peer_cfg->get_name(peer_cfg), + entry->ike_sa->get_name(entry->ike_sa))) { /* looks good, we take this one */ DBG2(DBG_MGR, "found an existing IKE_SA for %H[%D]...%H[%D]", @@ -902,7 +911,7 @@ ike_sa_manager_t *ike_sa_manager_create() this->public.checkout = (ike_sa_t*(*)(ike_sa_manager_t*, ike_sa_id_t*))checkout; this->public.checkout_new = (ike_sa_t*(*)(ike_sa_manager_t*,bool))checkout_new; this->public.checkout_by_message = (ike_sa_t*(*)(ike_sa_manager_t*,message_t*))checkout_by_message; - this->public.checkout_by_peer = (ike_sa_t*(*)(ike_sa_manager_t*,host_t*,host_t*,identification_t*,identification_t*))checkout_by_peer; + this->public.checkout_by_config = (ike_sa_t*(*)(ike_sa_manager_t*,peer_cfg_t*))checkout_by_config; this->public.checkout_by_id = (ike_sa_t*(*)(ike_sa_manager_t*,u_int32_t,bool))checkout_by_id; this->public.checkout_by_name = (ike_sa_t*(*)(ike_sa_manager_t*,char*,bool))checkout_by_name; this->public.create_iterator = (iterator_t*(*)(ike_sa_manager_t*))create_iterator; diff --git a/src/charon/sa/ike_sa_manager.h b/src/charon/sa/ike_sa_manager.h index 1125e5d16..a73a106ba 100644 --- a/src/charon/sa/ike_sa_manager.h +++ b/src/charon/sa/ike_sa_manager.h @@ -29,6 +29,7 @@ typedef struct ike_sa_manager_t ike_sa_manager_t; #include <library.h> #include <sa/ike_sa.h> #include <encoding/message.h> +#include <config/peer_cfg.h> /** * @brief The IKE_SA-Manager is responsible for managing all initiated and responded IKE_SA's. @@ -94,25 +95,21 @@ struct ike_sa_manager_t { ike_sa_t* (*checkout_by_message) (ike_sa_manager_t* this, message_t *message); /** - * @brief Checkout an existing IKE_SA by hosts and identifications. + * @brief Checkout an IKE_SA for initiation by a peer_config. * - * Allows the lookup of an IKE_SA by user IDs and hosts. It returns the - * first found occurence, if there are multiple candidates. Supplied IDs - * may contain wildcards, hosts may be %any. + * To initiate, a CHILD_SA may be established within an existing IKE_SA. + * This call checks for an existing IKE_SA by comparing the configuration. + * If the CHILD_SA can be created in an existing IKE_SA, the matching SA + * is returned. * If no IKE_SA is found, a new one is created. This is also the case when * the found IKE_SA is in the DELETING state. * * @param this the manager object - * @param my_host address of our host - * @param other_id address of remote host - * @param my_id ID used by us - * @param other_id ID used by remote + * @param peer_cfg configuration used to find an existing IKE_SA * @return checked out/created IKE_SA */ - ike_sa_t* (*checkout_by_peer) (ike_sa_manager_t* this, - host_t *my_host, host_t* other_host, - identification_t *my_id, - identification_t *other_id); + ike_sa_t* (*checkout_by_config) (ike_sa_manager_t* this, + peer_cfg_t *peer_cfg); /** * @brief Check out an IKE_SA a unique ID. diff --git a/src/dumm/Makefile.in b/src/dumm/Makefile.in index 94ad6003a..3431641d5 100644 --- a/src/dumm/Makefile.in +++ b/src/dumm/Makefile.in @@ -198,11 +198,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ diff --git a/src/include/Makefile.in b/src/include/Makefile.in index 656073f87..2659b44ba 100644 --- a/src/include/Makefile.in +++ b/src/include/Makefile.in @@ -160,11 +160,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ diff --git a/src/ipsec/Makefile.in b/src/ipsec/Makefile.in index a784572d6..b11c73060 100644 --- a/src/ipsec/Makefile.in +++ b/src/ipsec/Makefile.in @@ -168,11 +168,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ diff --git a/src/libcrypto/Makefile.in b/src/libcrypto/Makefile.in index 4d0cca10e..ecfca64c4 100644 --- a/src/libcrypto/Makefile.in +++ b/src/libcrypto/Makefile.in @@ -187,11 +187,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ diff --git a/src/libfreeswan/Makefile.in b/src/libfreeswan/Makefile.in index 04ae60340..dacd7e76b 100644 --- a/src/libfreeswan/Makefile.in +++ b/src/libfreeswan/Makefile.in @@ -200,11 +200,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index e8859ad4c..fc642c615 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -35,6 +35,7 @@ crypto/hmac.c crypto/hmac.h \ crypto/ietf_attr_list.c crypto/ietf_attr_list.h \ crypto/ocsp.c crypto/ocsp.h \ crypto/pkcs7.c crypto/pkcs7.h \ +crypto/pkcs9.c crypto/pkcs9.h \ crypto/prfs/fips_prf.c crypto/prfs/fips_prf.h \ crypto/prfs/hmac_prf.c crypto/prfs/hmac_prf.h \ crypto/prfs/prf.c crypto/prfs/prf.h \ diff --git a/src/libstrongswan/Makefile.in b/src/libstrongswan/Makefile.in index 75d3dddd4..c8a471e00 100644 --- a/src/libstrongswan/Makefile.in +++ b/src/libstrongswan/Makefile.in @@ -75,17 +75,18 @@ am__libstrongswan_la_SOURCES_DIST = credential_store.h library.c \ crypto/hashers/md5_hasher.c crypto/hashers/md5_hasher.h \ crypto/hmac.c crypto/hmac.h crypto/ietf_attr_list.c \ crypto/ietf_attr_list.h crypto/ocsp.c crypto/ocsp.h \ - crypto/pkcs7.c crypto/pkcs7.h crypto/prfs/fips_prf.c \ - crypto/prfs/fips_prf.h crypto/prfs/hmac_prf.c \ - crypto/prfs/hmac_prf.h crypto/prfs/prf.c crypto/prfs/prf.h \ - crypto/prf_plus.h crypto/prf_plus.c \ - crypto/rsa/rsa_private_key.c crypto/rsa/rsa_private_key.h \ - crypto/rsa/rsa_public_key.h crypto/rsa/rsa_public_key.c \ - crypto/signers/hmac_signer.c crypto/signers/hmac_signer.h \ - crypto/signers/signer.c crypto/signers/signer.h crypto/x509.c \ - crypto/x509.h utils/fetcher.c utils/fetcher.h utils/host.c \ - utils/host.h utils/identification.c utils/identification.h \ - utils/iterator.h utils/leak_detective.c utils/leak_detective.h \ + crypto/pkcs7.c crypto/pkcs7.h crypto/pkcs9.c crypto/pkcs9.h \ + crypto/prfs/fips_prf.c crypto/prfs/fips_prf.h \ + crypto/prfs/hmac_prf.c crypto/prfs/hmac_prf.h \ + crypto/prfs/prf.c crypto/prfs/prf.h crypto/prf_plus.h \ + crypto/prf_plus.c crypto/rsa/rsa_private_key.c \ + crypto/rsa/rsa_private_key.h crypto/rsa/rsa_public_key.h \ + crypto/rsa/rsa_public_key.c crypto/signers/hmac_signer.c \ + crypto/signers/hmac_signer.h crypto/signers/signer.c \ + crypto/signers/signer.h crypto/x509.c crypto/x509.h \ + utils/fetcher.c utils/fetcher.h utils/host.c utils/host.h \ + utils/identification.c utils/identification.h utils/iterator.h \ + utils/leak_detective.c utils/leak_detective.h \ utils/lexparser.c utils/lexparser.h utils/linked_list.c \ utils/linked_list.h utils/enumerator.c utils/enumerator.h \ utils/optionsfrom.c utils/optionsfrom.h utils/randomizer.c \ @@ -100,14 +101,14 @@ am__libstrongswan_la_SOURCES_DIST = credential_store.h library.c \ @USE_INTEGRITY_TEST_FALSE@ hasher.lo sha1_hasher.lo \ @USE_INTEGRITY_TEST_FALSE@ sha2_hasher.lo md5_hasher.lo hmac.lo \ @USE_INTEGRITY_TEST_FALSE@ ietf_attr_list.lo ocsp.lo pkcs7.lo \ -@USE_INTEGRITY_TEST_FALSE@ fips_prf.lo hmac_prf.lo prf.lo \ -@USE_INTEGRITY_TEST_FALSE@ prf_plus.lo rsa_private_key.lo \ -@USE_INTEGRITY_TEST_FALSE@ rsa_public_key.lo hmac_signer.lo \ -@USE_INTEGRITY_TEST_FALSE@ signer.lo x509.lo fetcher.lo host.lo \ -@USE_INTEGRITY_TEST_FALSE@ identification.lo leak_detective.lo \ -@USE_INTEGRITY_TEST_FALSE@ lexparser.lo linked_list.lo \ -@USE_INTEGRITY_TEST_FALSE@ enumerator.lo optionsfrom.lo \ -@USE_INTEGRITY_TEST_FALSE@ randomizer.lo +@USE_INTEGRITY_TEST_FALSE@ pkcs9.lo fips_prf.lo hmac_prf.lo \ +@USE_INTEGRITY_TEST_FALSE@ prf.lo prf_plus.lo \ +@USE_INTEGRITY_TEST_FALSE@ rsa_private_key.lo rsa_public_key.lo \ +@USE_INTEGRITY_TEST_FALSE@ hmac_signer.lo signer.lo x509.lo \ +@USE_INTEGRITY_TEST_FALSE@ fetcher.lo host.lo identification.lo \ +@USE_INTEGRITY_TEST_FALSE@ leak_detective.lo lexparser.lo \ +@USE_INTEGRITY_TEST_FALSE@ linked_list.lo enumerator.lo \ +@USE_INTEGRITY_TEST_FALSE@ optionsfrom.lo randomizer.lo @USE_INTEGRITY_TEST_TRUE@am_libstrongswan_la_OBJECTS = \ @USE_INTEGRITY_TEST_TRUE@ fips_canister_start.lo fips.lo \ @USE_INTEGRITY_TEST_TRUE@ library.lo chunk.lo debug.lo enum.lo \ @@ -118,8 +119,8 @@ am__libstrongswan_la_SOURCES_DIST = credential_store.h library.c \ @USE_INTEGRITY_TEST_TRUE@ hasher.lo sha1_hasher.lo \ @USE_INTEGRITY_TEST_TRUE@ sha2_hasher.lo md5_hasher.lo hmac.lo \ @USE_INTEGRITY_TEST_TRUE@ ietf_attr_list.lo ocsp.lo pkcs7.lo \ -@USE_INTEGRITY_TEST_TRUE@ fips_prf.lo hmac_prf.lo prf.lo \ -@USE_INTEGRITY_TEST_TRUE@ prf_plus.lo rsa_private_key.lo \ +@USE_INTEGRITY_TEST_TRUE@ pkcs9.lo fips_prf.lo hmac_prf.lo \ +@USE_INTEGRITY_TEST_TRUE@ prf.lo prf_plus.lo rsa_private_key.lo \ @USE_INTEGRITY_TEST_TRUE@ rsa_public_key.lo hmac_signer.lo \ @USE_INTEGRITY_TEST_TRUE@ signer.lo x509.lo fetcher.lo host.lo \ @USE_INTEGRITY_TEST_TRUE@ identification.lo leak_detective.lo \ @@ -269,11 +270,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ @@ -314,6 +317,7 @@ lib_LTLIBRARIES = libstrongswan.la @USE_INTEGRITY_TEST_FALSE@ crypto/ietf_attr_list.h \ @USE_INTEGRITY_TEST_FALSE@ crypto/ocsp.c crypto/ocsp.h \ @USE_INTEGRITY_TEST_FALSE@ crypto/pkcs7.c crypto/pkcs7.h \ +@USE_INTEGRITY_TEST_FALSE@ crypto/pkcs9.c crypto/pkcs9.h \ @USE_INTEGRITY_TEST_FALSE@ crypto/prfs/fips_prf.c \ @USE_INTEGRITY_TEST_FALSE@ crypto/prfs/fips_prf.h \ @USE_INTEGRITY_TEST_FALSE@ crypto/prfs/hmac_prf.c \ @@ -378,7 +382,8 @@ lib_LTLIBRARIES = libstrongswan.la @USE_INTEGRITY_TEST_TRUE@ crypto/ietf_attr_list.c \ @USE_INTEGRITY_TEST_TRUE@ crypto/ietf_attr_list.h crypto/ocsp.c \ @USE_INTEGRITY_TEST_TRUE@ crypto/ocsp.h crypto/pkcs7.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/pkcs7.h crypto/prfs/fips_prf.c \ +@USE_INTEGRITY_TEST_TRUE@ crypto/pkcs7.h crypto/pkcs9.c \ +@USE_INTEGRITY_TEST_TRUE@ crypto/pkcs9.h crypto/prfs/fips_prf.c \ @USE_INTEGRITY_TEST_TRUE@ crypto/prfs/fips_prf.h \ @USE_INTEGRITY_TEST_TRUE@ crypto/prfs/hmac_prf.c \ @USE_INTEGRITY_TEST_TRUE@ crypto/prfs/hmac_prf.h \ @@ -533,6 +538,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/optionsfrom.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs7.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs9.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prf_plus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printf_hook.Plo@am__quote@ @@ -706,6 +712,13 @@ pkcs7.lo: crypto/pkcs7.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pkcs7.lo `test -f 'crypto/pkcs7.c' || echo '$(srcdir)/'`crypto/pkcs7.c +pkcs9.lo: crypto/pkcs9.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pkcs9.lo -MD -MP -MF $(DEPDIR)/pkcs9.Tpo -c -o pkcs9.lo `test -f 'crypto/pkcs9.c' || echo '$(srcdir)/'`crypto/pkcs9.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/pkcs9.Tpo $(DEPDIR)/pkcs9.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/pkcs9.c' object='pkcs9.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pkcs9.lo `test -f 'crypto/pkcs9.c' || echo '$(srcdir)/'`crypto/pkcs9.c + fips_prf.lo: crypto/prfs/fips_prf.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fips_prf.lo -MD -MP -MF $(DEPDIR)/fips_prf.Tpo -c -o fips_prf.lo `test -f 'crypto/prfs/fips_prf.c' || echo '$(srcdir)/'`crypto/prfs/fips_prf.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fips_prf.Tpo $(DEPDIR)/fips_prf.Plo diff --git a/src/libstrongswan/asn1/asn1.c b/src/libstrongswan/asn1/asn1.c index 3191c89bd..3f0b829a9 100644 --- a/src/libstrongswan/asn1/asn1.c +++ b/src/libstrongswan/asn1/asn1.c @@ -1,6 +1,15 @@ -/* Simple ASN.1 parser - * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur - * Copyright (C) 2006 Martin Will, Hochschule fuer Technik Rapperswil +/** + * @file asn1.c + * + * @brief Simple ASN.1 parser + * + */ + +/* + * Copyright (C) 2006 Martin Will + * Copyright (C) 2000-2008 Andreas Steffen + * + * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -12,7 +21,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: asn1.c 3299 2007-10-12 19:29:00Z andreas $ + * RCSID $Id: asn1.c 3451 2008-02-05 19:27:05Z andreas $ */ #include <stdio.h> @@ -77,6 +86,13 @@ static u_char ASN1_sha512_id_str[] = { 0x05,0x00 }; +static u_char ASN1_md2WithRSA_id_str[] = { + 0x30, 0x0D, + 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x02, + 0x05, 0x00 +}; + static u_char ASN1_md5WithRSA_id_str[] = { 0x30, 0x0D, 0x06, 0x09, @@ -91,6 +107,27 @@ static u_char ASN1_sha1WithRSA_id_str[] = { 0x05, 0x00 }; +static u_char ASN1_sha256WithRSA_id_str[] = { + 0x30, 0x0D, + 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, + 0x05, 0x00 +}; + +static u_char ASN1_sha384WithRSA_id_str[] = { + 0x30, 0x0D, + 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0C, + 0x05, 0x00 +}; + +static u_char ASN1_sha512WithRSA_id_str[] = { + 0x30, 0x0D, + 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0D, + 0x05, 0x00 +}; + static u_char ASN1_rsaEncryption_id_str[] = { 0x30, 0x0D, 0x06, 0x09, @@ -98,15 +135,19 @@ static u_char ASN1_rsaEncryption_id_str[] = { 0x05, 0x00 }; -const chunk_t ASN1_md2_id = chunk_from_buf(ASN1_md2_id_str); -const chunk_t ASN1_md5_id = chunk_from_buf(ASN1_md5_id_str); -const chunk_t ASN1_sha1_id = chunk_from_buf(ASN1_sha1_id_str); -const chunk_t ASN1_sha256_id = chunk_from_buf(ASN1_sha256_id_str); -const chunk_t ASN1_sha384_id = chunk_from_buf(ASN1_sha384_id_str); -const chunk_t ASN1_sha512_id = chunk_from_buf(ASN1_sha512_id_str); -const chunk_t ASN1_rsaEncryption_id = chunk_from_buf(ASN1_rsaEncryption_id_str); -const chunk_t ASN1_md5WithRSA_id = chunk_from_buf(ASN1_md5WithRSA_id_str); -const chunk_t ASN1_sha1WithRSA_id = chunk_from_buf(ASN1_sha1WithRSA_id_str); +static const chunk_t ASN1_md2_id = chunk_from_buf(ASN1_md2_id_str); +static const chunk_t ASN1_md5_id = chunk_from_buf(ASN1_md5_id_str); +static const chunk_t ASN1_sha1_id = chunk_from_buf(ASN1_sha1_id_str); +static const chunk_t ASN1_sha256_id = chunk_from_buf(ASN1_sha256_id_str); +static const chunk_t ASN1_sha384_id = chunk_from_buf(ASN1_sha384_id_str); +static const chunk_t ASN1_sha512_id = chunk_from_buf(ASN1_sha512_id_str); +static const chunk_t ASN1_rsaEncryption_id = chunk_from_buf(ASN1_rsaEncryption_id_str); +static const chunk_t ASN1_md2WithRSA_id = chunk_from_buf(ASN1_md2WithRSA_id_str); +static const chunk_t ASN1_md5WithRSA_id = chunk_from_buf(ASN1_md5WithRSA_id_str); +static const chunk_t ASN1_sha1WithRSA_id = chunk_from_buf(ASN1_sha1WithRSA_id_str); +static const chunk_t ASN1_sha256WithRSA_id = chunk_from_buf(ASN1_sha256WithRSA_id_str); +static const chunk_t ASN1_sha384WithRSA_id = chunk_from_buf(ASN1_sha384WithRSA_id_str); +static const chunk_t ASN1_sha512WithRSA_id = chunk_from_buf(ASN1_sha512WithRSA_id_str); /* ASN.1 definiton of an algorithmIdentifier */ static const asn1Object_t algorithmIdentifierObjects[] = { @@ -128,14 +169,30 @@ chunk_t asn1_algorithmIdentifier(int oid) { case OID_RSA_ENCRYPTION: return ASN1_rsaEncryption_id; + case OID_MD2_WITH_RSA: + return ASN1_md2WithRSA_id; case OID_MD5_WITH_RSA: return ASN1_md5WithRSA_id; case OID_SHA1_WITH_RSA: return ASN1_sha1WithRSA_id; + case OID_SHA256_WITH_RSA: + return ASN1_sha256WithRSA_id; + case OID_SHA384_WITH_RSA: + return ASN1_sha384WithRSA_id; + case OID_SHA512_WITH_RSA: + return ASN1_sha512WithRSA_id; + case OID_MD2: + return ASN1_md2_id; case OID_MD5: return ASN1_md5_id; case OID_SHA1: return ASN1_sha1_id; + case OID_SHA256: + return ASN1_sha256_id; + case OID_SHA384: + return ASN1_sha384_id; + case OID_SHA512: + return ASN1_sha512_id; default: return chunk_empty; } @@ -620,13 +677,23 @@ bool is_asn1(chunk_t blob) DBG2(" file content is not binary ASN.1"); return FALSE; } + len = asn1_length(&blob); - if (len != blob.len) + + /* exact match */ + if (len == blob.len) { - DBG2(" file size does not match ASN.1 coded length"); - return FALSE; + return TRUE; } - return TRUE; + + /* some websites append a surplus newline character to the blob */ + if (len + 1 == blob.len && *(blob.ptr + len) == '\n') + { + return TRUE; + } + + DBG2(" file size does not match ASN.1 coded length"); + return FALSE; } /** @@ -706,6 +773,23 @@ chunk_t asn1_simple_object(asn1_t tag, chunk_t content) } /** + * Build an ASN.1 BITSTRING object + */ +chunk_t asn1_bitstring(const char *mode, chunk_t content) +{ + chunk_t object; + u_char *pos = build_asn1_object(&object, ASN1_BIT_STRING, 1 + content.len); + + *pos++ = 0x00; + memcpy(pos, content.ptr, content.len); + if (*mode == 'm') + { + free(content.ptr); + } + return object; +} + +/** * Build an ASN.1 object from a variable number of individual chunks. * Depending on the mode, chunks either are moved ('m') or copied ('c'). */ @@ -736,17 +820,12 @@ chunk_t asn1_wrap(asn1_t type, const char *mode, ...) { chunk_t ch = va_arg(chunks, chunk_t); - switch (*mode++) + memcpy(pos, ch.ptr, ch.len); + pos += ch.len; + + if (*mode++ == 'm') { - case 'm': - memcpy(pos, ch.ptr, ch.len); - pos += ch.len; - free(ch.ptr); - break; - case 'c': - default: - memcpy(pos, ch.ptr, ch.len); - pos += ch.len; + free(ch.ptr); } } va_end(chunks); diff --git a/src/libstrongswan/asn1/asn1.h b/src/libstrongswan/asn1/asn1.h index 18742d18d..d9d85ba44 100644 --- a/src/libstrongswan/asn1/asn1.h +++ b/src/libstrongswan/asn1/asn1.h @@ -1,6 +1,15 @@ -/* Simple ASN.1 parser - * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur - * Copyright (C) 2006 Martin Will, Hochschule fuer Technik Rapperswil +/** + * @file asn1.h + * + * @brief Simple ASN.1 parser + * + */ + +/* + * Copyright (C) 2006 Martin Will + * Copyright (C) 2000-2008 Andreas Steffen + * + * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -12,7 +21,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: asn1.h 3299 2007-10-12 19:29:00Z andreas $ + * RCSID $Id: asn1.h 3423 2008-01-22 10:32:37Z andreas $ */ #ifndef _ASN1_H @@ -114,19 +123,9 @@ extern const chunk_t ASN1_INTEGER_0; extern const chunk_t ASN1_INTEGER_1; extern const chunk_t ASN1_INTEGER_2; -/* some popular algorithmIdentifiers */ -extern const chunk_t ASN1_md2_id; -extern const chunk_t ASN1_md5_id; -extern const chunk_t ASN1_sha1_id; -extern const chunk_t ASN1_sha256_id; -extern const chunk_t ASN1_sha384_id; -extern const chunk_t ASN1_sha512_id; - -extern const chunk_t ASN1_rsaEncryption_id; -extern const chunk_t ASN1_md5WithRSA_id; -extern const chunk_t ASN1_sha1WithRSA_id; - +/* returns some popular algorithmIdentifiers */ extern chunk_t asn1_algorithmIdentifier(int oid); + extern int known_oid(chunk_t object); extern u_int asn1_length(chunk_t *blob); extern bool is_printablestring(chunk_t str); @@ -144,6 +143,7 @@ extern void code_asn1_length(size_t length, chunk_t *code); extern u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen); extern chunk_t asn1_integer_from_mpz(const mpz_t value); extern chunk_t asn1_simple_object(asn1_t tag, chunk_t content); +extern chunk_t asn1_bitstring(const char *mode, chunk_t content); extern chunk_t asn1_wrap(asn1_t type, const char *mode, ...); #endif /* _ASN1_H */ diff --git a/src/libstrongswan/asn1/oid.c b/src/libstrongswan/asn1/oid.c index 28a915433..63896be6b 100644 --- a/src/libstrongswan/asn1/oid.c +++ b/src/libstrongswan/asn1/oid.c @@ -1,5 +1,5 @@ /* List of some useful object identifiers (OIDs) - * Copyright (C) 2003-2004 Andreas Steffen, Zuercher Hochschule Winterthur + * Copyright (C) 2003-2008 Andreas Steffen, Hochschule fuer Technik Rapperswil * * This file has been automatically generated by the script oid.pl * Do not edit manually! @@ -62,7 +62,7 @@ const oid_t oid_names[] = { { 0x25, 50, 0, "extendedKeyUsage" }, /* 49 */ { 0x37, 51, 0, "targetInformation" }, /* 50 */ { 0x38, 0, 0, "noRevAvail" }, /* 51 */ - {0x2A, 94, 1, "" }, /* 52 */ + {0x2A, 95, 1, "" }, /* 52 */ { 0x86, 0, 1, "" }, /* 53 */ { 0x48, 0, 1, "" }, /* 54 */ { 0x86, 0, 1, "" }, /* 55 */ @@ -73,7 +73,7 @@ const oid_t oid_names[] = { { 0x00, 0, 0, "entrustVersInfo" }, /* 60 */ { 0xF7, 0, 1, "" }, /* 61 */ { 0x0D, 0, 1, "RSADSI" }, /* 62 */ - { 0x01, 89, 1, "PKCS" }, /* 63 */ + { 0x01, 90, 1, "PKCS" }, /* 63 */ { 0x01, 72, 1, "PKCS-1" }, /* 64 */ { 0x01, 66, 0, "rsaEncryption" }, /* 65 */ { 0x02, 67, 0, "md2WithRSAEncryption" }, /* 66 */ @@ -98,111 +98,112 @@ const oid_t oid_names[] = { { 0x06, 86, 0, "counterSignature" }, /* 85 */ { 0x07, 87, 0, "challengePassword" }, /* 86 */ { 0x08, 88, 0, "unstructuredAddress" }, /* 87 */ - { 0x0E, 0, 0, "extensionRequest" }, /* 88 */ - { 0x02, 92, 1, "digestAlgorithm" }, /* 89 */ - { 0x02, 91, 0, "md2" }, /* 90 */ - { 0x05, 0, 0, "md5" }, /* 91 */ - { 0x03, 0, 1, "encryptionAlgorithm" }, /* 92 */ - { 0x07, 0, 0, "3des-ede-cbc" }, /* 93 */ - {0x2B, 160, 1, "" }, /* 94 */ - { 0x06, 147, 1, "dod" }, /* 95 */ - { 0x01, 0, 1, "internet" }, /* 96 */ - { 0x04, 115, 1, "private" }, /* 97 */ - { 0x01, 0, 1, "enterprise" }, /* 98 */ - { 0x82, 108, 1, "" }, /* 99 */ - { 0x37, 0, 1, "Microsoft" }, /* 100 */ - { 0x0A, 105, 1, "" }, /* 101 */ - { 0x03, 0, 1, "" }, /* 102 */ - { 0x03, 104, 0, "msSGC" }, /* 103 */ - { 0x04, 0, 0, "msEncryptingFileSystem" }, /* 104 */ - { 0x14, 0, 1, "msEnrollmentInfrastructure"}, /* 105 */ - { 0x02, 0, 1, "msCertificateTypeExtension"}, /* 106 */ - { 0x02, 0, 0, "msSmartcardLogon" }, /* 107 */ - { 0x89, 0, 1, "" }, /* 108 */ - { 0x31, 0, 1, "" }, /* 109 */ - { 0x01, 0, 1, "" }, /* 110 */ - { 0x01, 0, 1, "" }, /* 111 */ - { 0x02, 0, 1, "" }, /* 112 */ - { 0x02, 114, 0, "" }, /* 113 */ - { 0x4B, 0, 0, "TCGID" }, /* 114 */ - { 0x05, 0, 1, "security" }, /* 115 */ - { 0x05, 0, 1, "mechanisms" }, /* 116 */ - { 0x07, 0, 1, "id-pkix" }, /* 117 */ - { 0x01, 120, 1, "id-pe" }, /* 118 */ - { 0x01, 0, 0, "authorityInfoAccess" }, /* 119 */ - { 0x03, 130, 1, "id-kp" }, /* 120 */ - { 0x01, 122, 0, "serverAuth" }, /* 121 */ - { 0x02, 123, 0, "clientAuth" }, /* 122 */ - { 0x03, 124, 0, "codeSigning" }, /* 123 */ - { 0x04, 125, 0, "emailProtection" }, /* 124 */ - { 0x05, 126, 0, "ipsecEndSystem" }, /* 125 */ - { 0x06, 127, 0, "ipsecTunnel" }, /* 126 */ - { 0x07, 128, 0, "ipsecUser" }, /* 127 */ - { 0x08, 129, 0, "timeStamping" }, /* 128 */ - { 0x09, 0, 0, "ocspSigning" }, /* 129 */ - { 0x08, 132, 1, "id-otherNames" }, /* 130 */ - { 0x05, 0, 0, "xmppAddr" }, /* 131 */ - { 0x0A, 137, 1, "id-aca" }, /* 132 */ - { 0x01, 134, 0, "authenticationInfo" }, /* 133 */ - { 0x02, 135, 0, "accessIdentity" }, /* 134 */ - { 0x03, 136, 0, "chargingIdentity" }, /* 135 */ - { 0x04, 0, 0, "group" }, /* 136 */ - { 0x30, 0, 1, "id-ad" }, /* 137 */ - { 0x01, 146, 1, "ocsp" }, /* 138 */ - { 0x01, 140, 0, "basic" }, /* 139 */ - { 0x02, 141, 0, "nonce" }, /* 140 */ - { 0x03, 142, 0, "crl" }, /* 141 */ - { 0x04, 143, 0, "response" }, /* 142 */ - { 0x05, 144, 0, "noCheck" }, /* 143 */ - { 0x06, 145, 0, "archiveCutoff" }, /* 144 */ - { 0x07, 0, 0, "serviceLocator" }, /* 145 */ - { 0x02, 0, 0, "caIssuers" }, /* 146 */ - { 0x0E, 153, 1, "oiw" }, /* 147 */ - { 0x03, 0, 1, "secsig" }, /* 148 */ - { 0x02, 0, 1, "algorithms" }, /* 149 */ - { 0x07, 151, 0, "des-cbc" }, /* 150 */ - { 0x1A, 152, 0, "sha-1" }, /* 151 */ - { 0x1D, 0, 0, "sha-1WithRSASignature" }, /* 152 */ - { 0x24, 0, 1, "TeleTrusT" }, /* 153 */ - { 0x03, 0, 1, "algorithm" }, /* 154 */ - { 0x03, 0, 1, "signatureAlgorithm" }, /* 155 */ - { 0x01, 0, 1, "rsaSignature" }, /* 156 */ - { 0x02, 158, 0, "rsaSigWithripemd160" }, /* 157 */ - { 0x03, 159, 0, "rsaSigWithripemd128" }, /* 158 */ - { 0x04, 0, 0, "rsaSigWithripemd256" }, /* 159 */ - {0x60, 0, 1, "" }, /* 160 */ - { 0x86, 0, 1, "" }, /* 161 */ - { 0x48, 0, 1, "" }, /* 162 */ - { 0x01, 0, 1, "organization" }, /* 163 */ - { 0x65, 171, 1, "gov" }, /* 164 */ - { 0x03, 0, 1, "csor" }, /* 165 */ - { 0x04, 0, 1, "nistalgorithm" }, /* 166 */ - { 0x02, 0, 1, "hashalgs" }, /* 167 */ - { 0x01, 169, 0, "id-SHA-256" }, /* 168 */ - { 0x02, 170, 0, "id-SHA-384" }, /* 169 */ - { 0x03, 0, 0, "id-SHA-512" }, /* 170 */ - { 0x86, 0, 1, "" }, /* 171 */ - { 0xf8, 0, 1, "" }, /* 172 */ - { 0x42, 185, 1, "netscape" }, /* 173 */ - { 0x01, 180, 1, "" }, /* 174 */ - { 0x01, 176, 0, "nsCertType" }, /* 175 */ - { 0x03, 177, 0, "nsRevocationUrl" }, /* 176 */ - { 0x04, 178, 0, "nsCaRevocationUrl" }, /* 177 */ - { 0x08, 179, 0, "nsCaPolicyUrl" }, /* 178 */ - { 0x0d, 0, 0, "nsComment" }, /* 179 */ - { 0x03, 183, 1, "directory" }, /* 180 */ - { 0x01, 0, 1, "" }, /* 181 */ - { 0x03, 0, 0, "employeeNumber" }, /* 182 */ - { 0x04, 0, 1, "policy" }, /* 183 */ - { 0x01, 0, 0, "nsSGC" }, /* 184 */ - { 0x45, 0, 1, "verisign" }, /* 185 */ - { 0x01, 0, 1, "pki" }, /* 186 */ - { 0x09, 0, 1, "attributes" }, /* 187 */ - { 0x02, 189, 0, "messageType" }, /* 188 */ - { 0x03, 190, 0, "pkiStatus" }, /* 189 */ - { 0x04, 191, 0, "failInfo" }, /* 190 */ - { 0x05, 192, 0, "senderNonce" }, /* 191 */ - { 0x06, 193, 0, "recipientNonce" }, /* 192 */ - { 0x07, 194, 0, "transID" }, /* 193 */ - { 0x08, 0, 0, "extensionReq" } /* 194 */ + { 0x0E, 89, 0, "extensionRequest" }, /* 88 */ + { 0x0F, 0, 0, "S/MIME Capabilities" }, /* 89 */ + { 0x02, 93, 1, "digestAlgorithm" }, /* 90 */ + { 0x02, 92, 0, "md2" }, /* 91 */ + { 0x05, 0, 0, "md5" }, /* 92 */ + { 0x03, 0, 1, "encryptionAlgorithm" }, /* 93 */ + { 0x07, 0, 0, "3des-ede-cbc" }, /* 94 */ + {0x2B, 161, 1, "" }, /* 95 */ + { 0x06, 148, 1, "dod" }, /* 96 */ + { 0x01, 0, 1, "internet" }, /* 97 */ + { 0x04, 116, 1, "private" }, /* 98 */ + { 0x01, 0, 1, "enterprise" }, /* 99 */ + { 0x82, 109, 1, "" }, /* 100 */ + { 0x37, 0, 1, "Microsoft" }, /* 101 */ + { 0x0A, 106, 1, "" }, /* 102 */ + { 0x03, 0, 1, "" }, /* 103 */ + { 0x03, 105, 0, "msSGC" }, /* 104 */ + { 0x04, 0, 0, "msEncryptingFileSystem" }, /* 105 */ + { 0x14, 0, 1, "msEnrollmentInfrastructure"}, /* 106 */ + { 0x02, 0, 1, "msCertificateTypeExtension"}, /* 107 */ + { 0x02, 0, 0, "msSmartcardLogon" }, /* 108 */ + { 0x89, 0, 1, "" }, /* 109 */ + { 0x31, 0, 1, "" }, /* 110 */ + { 0x01, 0, 1, "" }, /* 111 */ + { 0x01, 0, 1, "" }, /* 112 */ + { 0x02, 0, 1, "" }, /* 113 */ + { 0x02, 115, 0, "" }, /* 114 */ + { 0x4B, 0, 0, "TCGID" }, /* 115 */ + { 0x05, 0, 1, "security" }, /* 116 */ + { 0x05, 0, 1, "mechanisms" }, /* 117 */ + { 0x07, 0, 1, "id-pkix" }, /* 118 */ + { 0x01, 121, 1, "id-pe" }, /* 119 */ + { 0x01, 0, 0, "authorityInfoAccess" }, /* 120 */ + { 0x03, 131, 1, "id-kp" }, /* 121 */ + { 0x01, 123, 0, "serverAuth" }, /* 122 */ + { 0x02, 124, 0, "clientAuth" }, /* 123 */ + { 0x03, 125, 0, "codeSigning" }, /* 124 */ + { 0x04, 126, 0, "emailProtection" }, /* 125 */ + { 0x05, 127, 0, "ipsecEndSystem" }, /* 126 */ + { 0x06, 128, 0, "ipsecTunnel" }, /* 127 */ + { 0x07, 129, 0, "ipsecUser" }, /* 128 */ + { 0x08, 130, 0, "timeStamping" }, /* 129 */ + { 0x09, 0, 0, "ocspSigning" }, /* 130 */ + { 0x08, 133, 1, "id-otherNames" }, /* 131 */ + { 0x05, 0, 0, "xmppAddr" }, /* 132 */ + { 0x0A, 138, 1, "id-aca" }, /* 133 */ + { 0x01, 135, 0, "authenticationInfo" }, /* 134 */ + { 0x02, 136, 0, "accessIdentity" }, /* 135 */ + { 0x03, 137, 0, "chargingIdentity" }, /* 136 */ + { 0x04, 0, 0, "group" }, /* 137 */ + { 0x30, 0, 1, "id-ad" }, /* 138 */ + { 0x01, 147, 1, "ocsp" }, /* 139 */ + { 0x01, 141, 0, "basic" }, /* 140 */ + { 0x02, 142, 0, "nonce" }, /* 141 */ + { 0x03, 143, 0, "crl" }, /* 142 */ + { 0x04, 144, 0, "response" }, /* 143 */ + { 0x05, 145, 0, "noCheck" }, /* 144 */ + { 0x06, 146, 0, "archiveCutoff" }, /* 145 */ + { 0x07, 0, 0, "serviceLocator" }, /* 146 */ + { 0x02, 0, 0, "caIssuers" }, /* 147 */ + { 0x0E, 154, 1, "oiw" }, /* 148 */ + { 0x03, 0, 1, "secsig" }, /* 149 */ + { 0x02, 0, 1, "algorithms" }, /* 150 */ + { 0x07, 152, 0, "des-cbc" }, /* 151 */ + { 0x1A, 153, 0, "sha-1" }, /* 152 */ + { 0x1D, 0, 0, "sha-1WithRSASignature" }, /* 153 */ + { 0x24, 0, 1, "TeleTrusT" }, /* 154 */ + { 0x03, 0, 1, "algorithm" }, /* 155 */ + { 0x03, 0, 1, "signatureAlgorithm" }, /* 156 */ + { 0x01, 0, 1, "rsaSignature" }, /* 157 */ + { 0x02, 159, 0, "rsaSigWithripemd160" }, /* 158 */ + { 0x03, 160, 0, "rsaSigWithripemd128" }, /* 159 */ + { 0x04, 0, 0, "rsaSigWithripemd256" }, /* 160 */ + {0x60, 0, 1, "" }, /* 161 */ + { 0x86, 0, 1, "" }, /* 162 */ + { 0x48, 0, 1, "" }, /* 163 */ + { 0x01, 0, 1, "organization" }, /* 164 */ + { 0x65, 172, 1, "gov" }, /* 165 */ + { 0x03, 0, 1, "csor" }, /* 166 */ + { 0x04, 0, 1, "nistalgorithm" }, /* 167 */ + { 0x02, 0, 1, "hashalgs" }, /* 168 */ + { 0x01, 170, 0, "id-SHA-256" }, /* 169 */ + { 0x02, 171, 0, "id-SHA-384" }, /* 170 */ + { 0x03, 0, 0, "id-SHA-512" }, /* 171 */ + { 0x86, 0, 1, "" }, /* 172 */ + { 0xf8, 0, 1, "" }, /* 173 */ + { 0x42, 186, 1, "netscape" }, /* 174 */ + { 0x01, 181, 1, "" }, /* 175 */ + { 0x01, 177, 0, "nsCertType" }, /* 176 */ + { 0x03, 178, 0, "nsRevocationUrl" }, /* 177 */ + { 0x04, 179, 0, "nsCaRevocationUrl" }, /* 178 */ + { 0x08, 180, 0, "nsCaPolicyUrl" }, /* 179 */ + { 0x0d, 0, 0, "nsComment" }, /* 180 */ + { 0x03, 184, 1, "directory" }, /* 181 */ + { 0x01, 0, 1, "" }, /* 182 */ + { 0x03, 0, 0, "employeeNumber" }, /* 183 */ + { 0x04, 0, 1, "policy" }, /* 184 */ + { 0x01, 0, 0, "nsSGC" }, /* 185 */ + { 0x45, 0, 1, "verisign" }, /* 186 */ + { 0x01, 0, 1, "pki" }, /* 187 */ + { 0x09, 0, 1, "attributes" }, /* 188 */ + { 0x02, 190, 0, "messageType" }, /* 189 */ + { 0x03, 191, 0, "pkiStatus" }, /* 190 */ + { 0x04, 192, 0, "failInfo" }, /* 191 */ + { 0x05, 193, 0, "senderNonce" }, /* 192 */ + { 0x06, 194, 0, "recipientNonce" }, /* 193 */ + { 0x07, 195, 0, "transID" }, /* 194 */ + { 0x08, 0, 0, "extensionReq" } /* 195 */ }; diff --git a/src/libstrongswan/asn1/oid.h b/src/libstrongswan/asn1/oid.h index 5814a3ba0..9980221ab 100644 --- a/src/libstrongswan/asn1/oid.h +++ b/src/libstrongswan/asn1/oid.h @@ -1,5 +1,5 @@ /* Object identifiers (OIDs) used by FreeS/WAN - * Copyright (C) 2003-2004 Andreas Steffen, Zuercher Hochschule Winterthur + * Copyright (C) 2003-2008 Andreas Steffen, Hochschule fuer Technik Rapperswil * * This file has been automatically generated by the script oid.pl * Do not edit manually! @@ -17,7 +17,7 @@ typedef struct { extern const oid_t oid_names[]; -#define OID_UNKNOWN -1 +#define OID_UNKNOWN -1 #define OID_ROLE 35 #define OID_SUBJECT_KEY_ID 38 #define OID_SUBJECT_ALT_NAME 41 @@ -46,40 +46,40 @@ extern const oid_t oid_names[]; #define OID_PKCS9_CONTENT_TYPE 82 #define OID_PKCS9_MESSAGE_DIGEST 83 #define OID_PKCS9_SIGNING_TIME 84 -#define OID_MD2 90 -#define OID_MD5 91 -#define OID_3DES_EDE_CBC 93 -#define OID_AUTHORITY_INFO_ACCESS 119 -#define OID_OCSP_SIGNING 129 -#define OID_XMPP_ADDR 131 -#define OID_AUTHENTICATION_INFO 133 -#define OID_ACCESS_IDENTITY 134 -#define OID_CHARGING_IDENTITY 135 -#define OID_GROUP 136 -#define OID_OCSP 138 -#define OID_BASIC 139 -#define OID_NONCE 140 -#define OID_CRL 141 -#define OID_RESPONSE 142 -#define OID_NO_CHECK 143 -#define OID_ARCHIVE_CUTOFF 144 -#define OID_SERVICE_LOCATOR 145 -#define OID_CA_ISSUERS 146 -#define OID_DES_CBC 150 -#define OID_SHA1 151 -#define OID_SHA1_WITH_RSA_OIW 152 -#define OID_SHA256 168 -#define OID_SHA384 169 -#define OID_SHA512 170 -#define OID_NS_REVOCATION_URL 176 -#define OID_NS_CA_REVOCATION_URL 177 -#define OID_NS_CA_POLICY_URL 178 -#define OID_NS_COMMENT 179 -#define OID_PKI_MESSAGE_TYPE 188 -#define OID_PKI_STATUS 189 -#define OID_PKI_FAIL_INFO 190 -#define OID_PKI_SENDER_NONCE 191 -#define OID_PKI_RECIPIENT_NONCE 192 -#define OID_PKI_TRANS_ID 193 +#define OID_MD2 91 +#define OID_MD5 92 +#define OID_3DES_EDE_CBC 94 +#define OID_AUTHORITY_INFO_ACCESS 120 +#define OID_OCSP_SIGNING 130 +#define OID_XMPP_ADDR 132 +#define OID_AUTHENTICATION_INFO 134 +#define OID_ACCESS_IDENTITY 135 +#define OID_CHARGING_IDENTITY 136 +#define OID_GROUP 137 +#define OID_OCSP 139 +#define OID_BASIC 140 +#define OID_NONCE 141 +#define OID_CRL 142 +#define OID_RESPONSE 143 +#define OID_NO_CHECK 144 +#define OID_ARCHIVE_CUTOFF 145 +#define OID_SERVICE_LOCATOR 146 +#define OID_CA_ISSUERS 147 +#define OID_DES_CBC 151 +#define OID_SHA1 152 +#define OID_SHA1_WITH_RSA_OIW 153 +#define OID_SHA256 169 +#define OID_SHA384 170 +#define OID_SHA512 171 +#define OID_NS_REVOCATION_URL 177 +#define OID_NS_CA_REVOCATION_URL 178 +#define OID_NS_CA_POLICY_URL 179 +#define OID_NS_COMMENT 180 +#define OID_PKI_MESSAGE_TYPE 189 +#define OID_PKI_STATUS 190 +#define OID_PKI_FAIL_INFO 191 +#define OID_PKI_SENDER_NONCE 192 +#define OID_PKI_RECIPIENT_NONCE 193 +#define OID_PKI_TRANS_ID 194 #endif /* OID_H_ */ diff --git a/src/libstrongswan/asn1/oid.pl b/src/libstrongswan/asn1/oid.pl index 5db619755..04030d3ee 100644 --- a/src/libstrongswan/asn1/oid.pl +++ b/src/libstrongswan/asn1/oid.pl @@ -1,6 +1,8 @@ #!/usr/bin/perl # Generates oid.h and oid.c out of oid.txt -# Copyright (C) 2003-2004 Andreas Steffen, Zuercher Hochschule Winterthur +# +# Copyright (C) 2003-2008 Andreas Steffen +# Hochschule fuer Technik Rapperswil # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -13,7 +15,7 @@ # for more details. # -$copyright="Copyright (C) 2003-2004 Andreas Steffen, Zuercher Hochschule Winterthur"; +$copyright="Copyright (C) 2003-2008 Andreas Steffen, Hochschule fuer Technik Rapperswil"; $automatic="This file has been automatically generated by the script oid.pl"; $warning="Do not edit manually!"; @@ -41,7 +43,7 @@ print OID_H "/* Object identifiers (OIDs) used by FreeS/WAN\n", "\n", "extern const oid_t oid_names[];\n", "\n", - "#define OID_UNKNOWN -1\n"; + "#define OID_UNKNOWN -1\n"; # parse oid.txt diff --git a/src/libstrongswan/asn1/oid.txt b/src/libstrongswan/asn1/oid.txt index 6ae2dc29a..e6dede287 100644 --- a/src/libstrongswan/asn1/oid.txt +++ b/src/libstrongswan/asn1/oid.txt @@ -33,23 +33,23 @@ 0x2A "G" 0x2B "I" 0x2D "ID" - 0x48 "role" OID_ROLE + 0x48 "role" OID_ROLE 0x1D "id-ce" 0x09 "subjectDirectoryAttrs" - 0x0E "subjectKeyIdentifier" OID_SUBJECT_KEY_ID + 0x0E "subjectKeyIdentifier" OID_SUBJECT_KEY_ID 0x0F "keyUsage" 0x10 "privateKeyUsagePeriod" - 0x11 "subjectAltName" OID_SUBJECT_ALT_NAME + 0x11 "subjectAltName" OID_SUBJECT_ALT_NAME 0x12 "issuerAltName" - 0x13 "basicConstraints" OID_BASIC_CONSTRAINTS - 0x14 "crlNumber" OID_CRL_NUMBER - 0x15 "reasonCode" OID_CRL_REASON_CODE + 0x13 "basicConstraints" OID_BASIC_CONSTRAINTS + 0x14 "crlNumber" OID_CRL_NUMBER + 0x15 "reasonCode" OID_CRL_REASON_CODE 0x1F "crlDistributionPoints" OID_CRL_DISTRIBUTION_POINTS 0x20 "certificatePolicies" 0x23 "authorityKeyIdentifier" OID_AUTHORITY_KEY_ID - 0x25 "extendedKeyUsage" OID_EXTENDED_KEY_USAGE - 0x37 "targetInformation" OID_TARGET_INFORMATION - 0x38 "noRevAvail" OID_NO_REV_AVAIL + 0x25 "extendedKeyUsage" OID_EXTENDED_KEY_USAGE + 0x37 "targetInformation" OID_TARGET_INFORMATION + 0x38 "noRevAvail" OID_NO_REV_AVAIL 0x2A "" 0x86 "" 0x48 "" @@ -63,35 +63,36 @@ 0x0D "RSADSI" 0x01 "PKCS" 0x01 "PKCS-1" - 0x01 "rsaEncryption" OID_RSA_ENCRYPTION - 0x02 "md2WithRSAEncryption" OID_MD2_WITH_RSA - 0x04 "md5WithRSAEncryption" OID_MD5_WITH_RSA + 0x01 "rsaEncryption" OID_RSA_ENCRYPTION + 0x02 "md2WithRSAEncryption" OID_MD2_WITH_RSA + 0x04 "md5WithRSAEncryption" OID_MD5_WITH_RSA 0x05 "sha-1WithRSAEncryption" OID_SHA1_WITH_RSA 0x0B "sha256WithRSAEncryption" OID_SHA256_WITH_RSA 0x0C "sha384WithRSAEncryption" OID_SHA384_WITH_RSA 0x0D "sha512WithRSAEncryption" OID_SHA512_WITH_RSA 0x07 "PKCS-7" - 0x01 "data" OID_PKCS7_DATA - 0x02 "signedData" OID_PKCS7_SIGNED_DATA - 0x03 "envelopedData" OID_PKCS7_ENVELOPED_DATA + 0x01 "data" OID_PKCS7_DATA + 0x02 "signedData" OID_PKCS7_SIGNED_DATA + 0x03 "envelopedData" OID_PKCS7_ENVELOPED_DATA 0x04 "signedAndEnvelopedData" OID_PKCS7_SIGNED_ENVELOPED_DATA - 0x05 "digestedData" OID_PKCS7_DIGESTED_DATA - 0x06 "encryptedData" OID_PKCS7_ENCRYPTED_DATA + 0x05 "digestedData" OID_PKCS7_DIGESTED_DATA + 0x06 "encryptedData" OID_PKCS7_ENCRYPTED_DATA 0x09 "PKCS-9" - 0x01 "E" OID_PKCS9_EMAIL + 0x01 "E" OID_PKCS9_EMAIL 0x02 "unstructuredName" - 0x03 "contentType" OID_PKCS9_CONTENT_TYPE - 0x04 "messageDigest" OID_PKCS9_MESSAGE_DIGEST - 0x05 "signingTime" OID_PKCS9_SIGNING_TIME + 0x03 "contentType" OID_PKCS9_CONTENT_TYPE + 0x04 "messageDigest" OID_PKCS9_MESSAGE_DIGEST + 0x05 "signingTime" OID_PKCS9_SIGNING_TIME 0x06 "counterSignature" 0x07 "challengePassword" 0x08 "unstructuredAddress" 0x0E "extensionRequest" + 0x0F "S/MIME Capabilities" 0x02 "digestAlgorithm" - 0x02 "md2" OID_MD2 - 0x05 "md5" OID_MD5 + 0x02 "md2" OID_MD2 + 0x05 "md5" OID_MD5 0x03 "encryptionAlgorithm" - 0x07 "3des-ede-cbc" OID_3DES_EDE_CBC + 0x07 "3des-ede-cbc" OID_3DES_EDE_CBC 0x2B "" 0x06 "dod" 0x01 "internet" @@ -117,7 +118,7 @@ 0x05 "mechanisms" 0x07 "id-pkix" 0x01 "id-pe" - 0x01 "authorityInfoAccess" OID_AUTHORITY_INFO_ACCESS + 0x01 "authorityInfoAccess" OID_AUTHORITY_INFO_ACCESS 0x03 "id-kp" 0x01 "serverAuth" 0x02 "clientAuth" @@ -127,29 +128,29 @@ 0x06 "ipsecTunnel" 0x07 "ipsecUser" 0x08 "timeStamping" - 0x09 "ocspSigning" OID_OCSP_SIGNING + 0x09 "ocspSigning" OID_OCSP_SIGNING 0x08 "id-otherNames" - 0x05 "xmppAddr" OID_XMPP_ADDR + 0x05 "xmppAddr" OID_XMPP_ADDR 0x0A "id-aca" - 0x01 "authenticationInfo" OID_AUTHENTICATION_INFO - 0x02 "accessIdentity" OID_ACCESS_IDENTITY - 0x03 "chargingIdentity" OID_CHARGING_IDENTITY - 0x04 "group" OID_GROUP + 0x01 "authenticationInfo" OID_AUTHENTICATION_INFO + 0x02 "accessIdentity" OID_ACCESS_IDENTITY + 0x03 "chargingIdentity" OID_CHARGING_IDENTITY + 0x04 "group" OID_GROUP 0x30 "id-ad" - 0x01 "ocsp" OID_OCSP - 0x01 "basic" OID_BASIC - 0x02 "nonce" OID_NONCE - 0x03 "crl" OID_CRL - 0x04 "response" OID_RESPONSE - 0x05 "noCheck" OID_NO_CHECK - 0x06 "archiveCutoff" OID_ARCHIVE_CUTOFF - 0x07 "serviceLocator" OID_SERVICE_LOCATOR - 0x02 "caIssuers" OID_CA_ISSUERS + 0x01 "ocsp" OID_OCSP + 0x01 "basic" OID_BASIC + 0x02 "nonce" OID_NONCE + 0x03 "crl" OID_CRL + 0x04 "response" OID_RESPONSE + 0x05 "noCheck" OID_NO_CHECK + 0x06 "archiveCutoff" OID_ARCHIVE_CUTOFF + 0x07 "serviceLocator" OID_SERVICE_LOCATOR + 0x02 "caIssuers" OID_CA_ISSUERS 0x0E "oiw" 0x03 "secsig" 0x02 "algorithms" - 0x07 "des-cbc" OID_DES_CBC - 0x1A "sha-1" OID_SHA1 + 0x07 "des-cbc" OID_DES_CBC + 0x1A "sha-1" OID_SHA1 0x1D "sha-1WithRSASignature" OID_SHA1_WITH_RSA_OIW 0x24 "TeleTrusT" 0x03 "algorithm" @@ -166,18 +167,18 @@ 0x03 "csor" 0x04 "nistalgorithm" 0x02 "hashalgs" - 0x01 "id-SHA-256" OID_SHA256 - 0x02 "id-SHA-384" OID_SHA384 - 0x03 "id-SHA-512" OID_SHA512 + 0x01 "id-SHA-256" OID_SHA256 + 0x02 "id-SHA-384" OID_SHA384 + 0x03 "id-SHA-512" OID_SHA512 0x86 "" 0xf8 "" 0x42 "netscape" 0x01 "" 0x01 "nsCertType" - 0x03 "nsRevocationUrl" OID_NS_REVOCATION_URL - 0x04 "nsCaRevocationUrl" OID_NS_CA_REVOCATION_URL - 0x08 "nsCaPolicyUrl" OID_NS_CA_POLICY_URL - 0x0d "nsComment" OID_NS_COMMENT + 0x03 "nsRevocationUrl" OID_NS_REVOCATION_URL + 0x04 "nsCaRevocationUrl" OID_NS_CA_REVOCATION_URL + 0x08 "nsCaPolicyUrl" OID_NS_CA_POLICY_URL + 0x0d "nsComment" OID_NS_COMMENT 0x03 "directory" 0x01 "" 0x03 "employeeNumber" @@ -186,10 +187,10 @@ 0x45 "verisign" 0x01 "pki" 0x09 "attributes" - 0x02 "messageType" OID_PKI_MESSAGE_TYPE - 0x03 "pkiStatus" OID_PKI_STATUS - 0x04 "failInfo" OID_PKI_FAIL_INFO - 0x05 "senderNonce" OID_PKI_SENDER_NONCE - 0x06 "recipientNonce" OID_PKI_RECIPIENT_NONCE - 0x07 "transID" OID_PKI_TRANS_ID + 0x02 "messageType" OID_PKI_MESSAGE_TYPE + 0x03 "pkiStatus" OID_PKI_STATUS + 0x04 "failInfo" OID_PKI_FAIL_INFO + 0x05 "senderNonce" OID_PKI_SENDER_NONCE + 0x06 "recipientNonce" OID_PKI_RECIPIENT_NONCE + 0x07 "transID" OID_PKI_TRANS_ID 0x08 "extensionReq" diff --git a/src/libstrongswan/crypto/hashers/hasher.c b/src/libstrongswan/crypto/hashers/hasher.c index 14bfb022f..9fa778aa6 100644 --- a/src/libstrongswan/crypto/hashers/hasher.c +++ b/src/libstrongswan/crypto/hashers/hasher.c @@ -6,8 +6,9 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2005-2006 Martin Willi + * * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -20,7 +21,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: hasher.c 3304 2007-10-12 23:18:42Z andreas $ + * RCSID $Id: hasher.c 3423 2008-01-22 10:32:37Z andreas $ */ @@ -110,6 +111,39 @@ hash_algorithm_t hasher_algorithm_from_oid(int oid) /* * Described in header. */ +int hasher_algorithm_to_oid(hash_algorithm_t alg) +{ + int oid; + + switch (alg) + { + case HASH_MD2: + oid = OID_MD2; + break; + case HASH_MD5: + oid = OID_MD5; + break; + case HASH_SHA1: + oid = OID_SHA1; + break; + case HASH_SHA256: + oid = OID_SHA256; + break; + case HASH_SHA384: + oid = OID_SHA384; + break; + case HASH_SHA512: + oid = OID_SHA512; + break; + default: + oid = OID_UNKNOWN; + } + return oid; +} + +/* + * Described in header. + */ int hasher_signature_algorithm_to_oid(hash_algorithm_t alg) { int oid; diff --git a/src/libstrongswan/crypto/hashers/hasher.h b/src/libstrongswan/crypto/hashers/hasher.h index 48b904576..e73de7f01 100644 --- a/src/libstrongswan/crypto/hashers/hasher.h +++ b/src/libstrongswan/crypto/hashers/hasher.h @@ -6,8 +6,9 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2005-2006 Martin Willi + * * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -20,7 +21,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: hasher.h 3307 2007-10-17 02:56:24Z andreas $ + * RCSID $Id: hasher.h 3423 2008-01-22 10:32:37Z andreas $ */ #ifndef HASHER_H_ @@ -171,11 +172,23 @@ hasher_t *hasher_create(hash_algorithm_t hash_algorithm); hash_algorithm_t hasher_algorithm_from_oid(int oid); /** - * @brief Conversion of hash signature algorithm ASN.1 OID. + * @brief Conversion of hash algorithm into ASN.1 OID. + * + * @param alg hash algorithm + * @return + * - ASN.1 hash OID if known hash algorithm + * - OID_UNKNOW + * + * @ingroup hashers + */ +int hasher_algorithm_to_oid(hash_algorithm_t alg); + +/** + * @brief Conversion of hash signature algorithm into ASN.1 OID. * * @param alg hash algorithm * @return - * - ASN.1 OID if known hash algorithm + * - ASN.1 signature OID if known hash algorithm * - OID_UNKNOW * * @ingroup hashers diff --git a/src/libstrongswan/crypto/ocsp.c b/src/libstrongswan/crypto/ocsp.c index e4d907188..4bbec31de 100644 --- a/src/libstrongswan/crypto/ocsp.c +++ b/src/libstrongswan/crypto/ocsp.c @@ -6,8 +6,11 @@ */ /* Support of the Online Certificate Status Protocol (OCSP) + * * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen - * Zuercher Hochschule Winterthur + * Copyright (C) 2007 Andreas Steffen + * + * Hochschule für 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 @@ -19,6 +22,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * + * RCSID $Id$ */ #include <unistd.h> @@ -325,7 +329,7 @@ static chunk_t build_request(private_ocsp_t *this, certinfo_t *certinfo) chunk_t serialNumber = certinfo->get_serialNumber(certinfo); chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "cmmm", - ASN1_sha1_id, + asn1_algorithmIdentifier(OID_SHA1), asn1_simple_object(ASN1_OCTET_STRING, this->authNameID), asn1_simple_object(ASN1_OCTET_STRING, this->authKeyID), asn1_simple_object(ASN1_INTEGER, serialNumber)); diff --git a/src/libstrongswan/crypto/ocsp.h b/src/libstrongswan/crypto/ocsp.h index 42059e1c6..e468bb8be 100644 --- a/src/libstrongswan/crypto/ocsp.h +++ b/src/libstrongswan/crypto/ocsp.h @@ -6,9 +6,11 @@ */ /* Support of the Online Certificate Status Protocol (OCSP) Support + * * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen * Copyright (C) 2007 Andreas Steffen - * Hochschule fuer Technik Rapperswil, Switzerland + * + * Hochschule fuer Technik Rapperswil, Switzerland * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -20,6 +22,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * + * RCSID $Id$ */ #ifndef OCSP_H_ diff --git a/src/libstrongswan/crypto/pkcs7.c b/src/libstrongswan/crypto/pkcs7.c index 70510471a..48d3e2d78 100644 --- a/src/libstrongswan/crypto/pkcs7.c +++ b/src/libstrongswan/crypto/pkcs7.c @@ -7,7 +7,8 @@ /* * Copyright (C) 2005 Jan Hutter, Martin Willi - * Copyright (C) 2002-2005 Andreas Steffen + * Copyright (C) 2002-2008 Andreas Steffen + * * Hochschule fuer Technik Rapperswil, Switzerland * * This program is free software; you can redistribute it and/or modify it @@ -20,7 +21,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: pkcs7.c 3302 2007-10-12 21:57:20Z andreas $ + * RCSID $Id: pkcs7.c 3438 2008-02-02 00:29:03Z andreas $ */ #include <stdlib.h> @@ -32,8 +33,11 @@ #include <asn1/asn1.h> #include <asn1/oid.h> #include <crypto/x509.h> +#include <crypto/pkcs9.h> #include <crypto/hashers/hasher.h> #include <crypto/crypters/crypter.h> +#include <crypto/rsa/rsa_public_key.h> +#include <utils/randomizer.h> #include <utils/linked_list.h> #include "pkcs7.h" @@ -77,7 +81,7 @@ struct private_pkcs7_t { /** * ASN.1 encoded attributes */ - chunk_t attributes; + pkcs9_t *attributes; /** * Linked list of X.509 certificates @@ -244,25 +248,7 @@ static const chunk_t ASN1_des_cbc_oid = chunk_from_buf(ASN1_des_cbc_oid_str); /** - * PKCS#7 attribute type OIDs - */ -static u_char ASN1_contentType_oid_str[] = { - 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x03 -}; - -static u_char ASN1_messageDigest_oid_str[] = { - 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x04 -}; - -static const chunk_t ASN1_contentType_oid = - chunk_from_buf(ASN1_contentType_oid_str); -static const chunk_t ASN1_messageDigest_oid = - chunk_from_buf(ASN1_messageDigest_oid_str); - -/** - * Implements pkcs7_t.is_signedData. + * Implements pkcs7_t.is_data. */ static bool is_data(private_pkcs7_t *this) { @@ -278,7 +264,7 @@ static bool is_signedData(private_pkcs7_t *this) } /** - * Implements pkcs7_t.is_signedData. + * Implements pkcs7_t.is_envelopedData. */ static bool is_envelopedData(private_pkcs7_t *this) { @@ -316,6 +302,11 @@ static bool parse_data(private_pkcs7_t *this) { return FALSE; } + if (data.len == 0) + { + this->data = chunk_empty; + return TRUE; + } if (parse_asn1_simple_object(&data, ASN1_OCTET_STRING, this->level, "data")) { this->data = chunk_clone(data); @@ -328,7 +319,7 @@ static bool parse_data(private_pkcs7_t *this) } /** - * Parse PKCS#7 signedData content + * Implements pkcs7_t.parse_signedData. */ static bool parse_signedData(private_pkcs7_t *this, x509_t *cacert) { @@ -363,11 +354,27 @@ static bool parse_signedData(private_pkcs7_t *this, x509_t *cacert) digest_alg = parse_algorithmIdentifier(object, level, NULL); break; case PKCS7_SIGNED_CONTENT_INFO: - this->data = chunk_clone(object); + { + chunk_t pureData; + pkcs7_t *data = pkcs7_create_from_chunk(object, level+1); + + if (data == NULL) + { + return FALSE; + } + if (!data->parse_data(data)) + { + data->destroy(data); + return FALSE; + } + pureData = data->get_data(data); + this->data = (pureData.len)? chunk_clone(pureData) : chunk_empty; + data->destroy(data); + } break; case PKCS7_SIGNED_CERT: { - x509_t *cert = x509_create_from_chunk(object, level+1); + x509_t *cert = x509_create_from_chunk(chunk_clone(object), level+1); if (cert) { @@ -389,8 +396,9 @@ static bool parse_signedData(private_pkcs7_t *this, x509_t *cacert) } break; case PKCS7_AUTH_ATTRIBUTES: - this->attributes = object; - *this->attributes.ptr = ASN1_SET; + *object.ptr = ASN1_SET; + this->attributes = pkcs9_create_from_chunk(object, level+1); + *object.ptr = ASN1_CONTEXT_C_0; break; case PKCS7_DIGEST_ALGORITHM: digest_alg = parse_algorithmIdentifier(object, level, NULL); @@ -407,8 +415,8 @@ static bool parse_signedData(private_pkcs7_t *this, x509_t *cacert) /* check the signature only if a cacert is available */ if (cacert != NULL) { - rsa_public_key_t *signer = cacert->get_public_key(cacert); hash_algorithm_t algorithm = hasher_algorithm_from_oid(digest_alg); + rsa_public_key_t *signer = cacert->get_public_key(cacert); if (signerInfos == 0) { @@ -420,7 +428,7 @@ static bool parse_signedData(private_pkcs7_t *this, x509_t *cacert) DBG1("more than one signerInfo object found"); return FALSE; } - if (this->attributes.ptr == NULL) + if (this->attributes == NULL) { DBG1("no authenticatedAttributes object found"); return FALSE; @@ -431,7 +439,7 @@ static bool parse_signedData(private_pkcs7_t *this, x509_t *cacert) return FALSE; } if (signer->verify_emsa_pkcs1_signature(signer, algorithm, - this->attributes, encrypted_digest) != SUCCESS) + this->attributes->get_encoding(this->attributes), encrypted_digest) != SUCCESS) { DBG1("invalid digest signature"); return FALSE; @@ -440,6 +448,39 @@ static bool parse_signedData(private_pkcs7_t *this, x509_t *cacert) { DBG2("digest signature is valid"); } + if (this->data.ptr != NULL) + { + chunk_t messageDigest = this->attributes->get_messageDigest(this->attributes); + + if (messageDigest.ptr == NULL) + { + DBG1("messageDigest attribute not found"); + return FALSE; + } + else + { + hasher_t *hasher = hasher_create(algorithm); + chunk_t hash; + bool valid; + + hasher->allocate_hash(hasher, this->data, &hash); + hasher->destroy(hasher); + DBG3("hash: %B", &hash); + + valid = chunk_equals(messageDigest, hash); + free(messageDigest.ptr); + free(hash.ptr); + if (valid) + { + DBG2("messageDigest is valid"); + } + else + { + DBG1("invalid messageDigest"); + return FALSE; + } + } + } } return TRUE; } @@ -574,8 +615,9 @@ static bool parse_envelopedData(private_pkcs7_t *this, chunk_t serialNumber, } /* decrypt the content */ + crypter->set_key(crypter, symmetric_key); crypter->decrypt(crypter, encrypted_content, iv, &this->data); - DBG4("decrypted content with padding: %B", &this->data); + DBG3("decrypted content with padding: %B", &this->data); /* remove the padding */ { @@ -611,7 +653,7 @@ failed: } /** - * Implements pkcs7_t.get_data + * Implements pkcs7_t.get_data. */ static chunk_t get_data(private_pkcs7_t *this) { @@ -619,7 +661,49 @@ static chunk_t get_data(private_pkcs7_t *this) } /** - * Implements pkcs_t.create_crluri_iterator + * Implements pkcs7_t.get_contentInfo. + */ +static chunk_t get_contentInfo(private_pkcs7_t *this) +{ + chunk_t content_type; + + /* select DER-encoded OID for pkcs7_contentInfo type */ + switch(this->type) + { + case OID_PKCS7_DATA: + content_type = ASN1_pkcs7_data_oid; + break; + case OID_PKCS7_SIGNED_DATA: + content_type = ASN1_pkcs7_signed_data_oid; + break; + case OID_PKCS7_ENVELOPED_DATA: + content_type = ASN1_pkcs7_enveloped_data_oid; + break; + case OID_PKCS7_SIGNED_ENVELOPED_DATA: + content_type = ASN1_pkcs7_signed_enveloped_data_oid; + break; + case OID_PKCS7_DIGESTED_DATA: + content_type = ASN1_pkcs7_digested_data_oid; + break; + case OID_PKCS7_ENCRYPTED_DATA: + content_type = ASN1_pkcs7_encrypted_data_oid; + break; + case OID_UNKNOWN: + default: + DBG1("invalid pkcs7 contentInfo type"); + return chunk_empty; + } + + return (this->content.ptr == NULL) + ? asn1_simple_object(ASN1_SEQUENCE, content_type) + : asn1_wrap(ASN1_SEQUENCE, "cm", + content_type, + asn1_simple_object(ASN1_CONTEXT_C_0, this->content) + ); +} + +/** + * Implements pkcs7_t.create_certificate_iterator */ static iterator_t *create_certificate_iterator(const private_pkcs7_t *this) { @@ -627,11 +711,243 @@ static iterator_t *create_certificate_iterator(const private_pkcs7_t *this) } /** + * Implements pkcs7_t.set_certificate + */ +static void set_certificate(private_pkcs7_t *this, x509_t *cert) +{ + if (cert) + { + /* TODO the certificate is currently not cloned */ + this->certs->insert_last(this->certs, cert); + } +} + +/** + * Implements pkcs7_t.set_attributes + */ +static void set_attributes(private_pkcs7_t *this, pkcs9_t *attributes) +{ + this->attributes = attributes; +} + +/** + * build a DER-encoded issuerAndSerialNumber object + */ +chunk_t pkcs7_build_issuerAndSerialNumber(x509_t *cert) +{ + identification_t *issuer = cert->get_issuer(cert); + + return asn1_wrap(ASN1_SEQUENCE, "cm", + issuer->get_encoding(issuer), + asn1_simple_object(ASN1_INTEGER, cert->get_serialNumber(cert))); +} + +/** + * Implements pkcs7_t.build_envelopedData. + */ +bool build_envelopedData(private_pkcs7_t *this, x509_t *cert, + encryption_algorithm_t alg) +{ + chunk_t iv, symmetricKey, in, out, alg_oid; + crypter_t *crypter; + + /* select OID of symmetric encryption algorithm */ + switch (alg) + { + case ENCR_DES: + alg_oid = ASN1_des_cbc_oid; + break; + case ENCR_3DES: + alg_oid = ASN1_3des_ede_cbc_oid; + break; + default: + DBG1(" encryption algorithm %N not supported", + encryption_algorithm_names, alg); + return FALSE; + } + + crypter = crypter_create(alg, 0); + if (crypter == NULL) + { + DBG1(" could not create crypter for algorithm %N", + encryption_algorithm_names, alg); + return FALSE; + } + + /* generate a true random symmetric encryption key + * and a pseudo-random iv + */ + { + randomizer_t *randomizer = randomizer_create(); + + randomizer->allocate_random_bytes(randomizer, + crypter->get_key_size(crypter), &symmetricKey); + DBG4(" symmetric encryption key: %B", &symmetricKey); + + randomizer->allocate_pseudo_random_bytes(randomizer, + crypter->get_block_size(crypter), &iv); + DBG4(" initialization vector: %B", &iv); + + randomizer->destroy(randomizer); + } + + /* pad the data so that the total length becomes + * a multiple of the block size + */ + { + size_t block_size = crypter->get_block_size(crypter); + size_t padding = block_size - this->data.len % block_size; + + in.len = this->data.len + padding; + in.ptr = malloc(in.len); + + DBG2(" padding %d bytes of data to multiple block size of %d bytes", + (int)this->data.len, (int)in.len); + + /* copy data */ + memcpy(in.ptr, this->data.ptr, this->data.len); + /* append padding */ + memset(in.ptr + this->data.len, padding, padding); + } + DBG3(" padded unencrypted data: %B", &in); + + /* symmetric encryption of data object */ + crypter->set_key(crypter, symmetricKey); + crypter->encrypt(crypter, in, iv, &out); + crypter->destroy(crypter); + chunk_free_randomized(&in); + DBG3(" encrypted data: %B", &out); + + /* build pkcs7 enveloped data object */ + { + chunk_t contentEncryptionAlgorithm = asn1_wrap(ASN1_SEQUENCE, "cm", + alg_oid, + asn1_wrap(ASN1_OCTET_STRING, "m", iv)); + + chunk_t encryptedContentInfo = asn1_wrap(ASN1_SEQUENCE, "cmm", + ASN1_pkcs7_data_oid, + contentEncryptionAlgorithm, + asn1_wrap(ASN1_CONTEXT_S_0, "m", out)); + + chunk_t wrappedKey, encryptedKey, recipientInfo; + + rsa_public_key_t *public_key = cert->get_public_key(cert); + + public_key->pkcs1_encrypt(public_key, symmetricKey, &wrappedKey); + chunk_free_randomized(&symmetricKey); + + encryptedKey = asn1_wrap(ASN1_OCTET_STRING, "m", wrappedKey); + + recipientInfo = asn1_wrap(ASN1_SEQUENCE, "cmcm", + ASN1_INTEGER_0, + pkcs7_build_issuerAndSerialNumber(cert), + asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), + encryptedKey); + + this->content = asn1_wrap(ASN1_SEQUENCE, "cmm", + ASN1_INTEGER_0, + asn1_wrap(ASN1_SET, "m", recipientInfo), + encryptedContentInfo); + this->type = OID_PKCS7_ENVELOPED_DATA; + } + return TRUE; +} + +/** + * Implements pkcs7_t.build_signedData. + */ +bool build_signedData(private_pkcs7_t *this, rsa_private_key_t *private_key, + hash_algorithm_t alg) +{ + int signature_oid = hasher_signature_algorithm_to_oid(alg); + chunk_t authenticatedAttributes = chunk_empty; + chunk_t encryptedDigest = chunk_empty; + chunk_t signerInfo; + x509_t *cert; + + if (this->certs->get_first(this->certs, (void**)&cert) != SUCCESS) + { + DBG1(" no pkcs7 signer certificate found"); + return FALSE; + } + + if (this->attributes != NULL) + { + if (this->data.ptr != NULL) + { + /* take the current time as signingTime */ + time_t now = time(NULL); + chunk_t signingTime = timetoasn1(&now, ASN1_UTCTIME); + + chunk_t messageDigest, attributes; + hasher_t *hasher = hasher_create(alg); + + hasher->allocate_hash(hasher, this->data, &messageDigest); + hasher->destroy(hasher); + this->attributes->set_attribute(this->attributes, + OID_PKCS9_CONTENT_TYPE, ASN1_pkcs7_data_oid); + this->attributes->set_messageDigest(this->attributes, + messageDigest); + this->attributes->set_attribute(this->attributes, + OID_PKCS9_SIGNING_TIME, signingTime); + attributes = this->attributes->get_encoding(this->attributes); + + free(messageDigest.ptr); + free(signingTime.ptr); + + private_key->build_emsa_pkcs1_signature(private_key, alg, + attributes, &encryptedDigest); + authenticatedAttributes = chunk_clone(attributes); + *authenticatedAttributes.ptr = ASN1_CONTEXT_C_0; + } + } + else if (this->data.ptr != NULL) + { + private_key->build_emsa_pkcs1_signature(private_key, alg, + this->data, &encryptedDigest); + } + if (encryptedDigest.ptr) + { + encryptedDigest = asn1_wrap(ASN1_OCTET_STRING, "m", encryptedDigest); + } + + signerInfo = asn1_wrap(ASN1_SEQUENCE, "cmcmcm", + ASN1_INTEGER_1, + pkcs7_build_issuerAndSerialNumber(cert), + asn1_algorithmIdentifier(signature_oid), + authenticatedAttributes, + asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), + encryptedDigest); + + if (this->data.ptr != NULL) + { + this->content = asn1_simple_object(ASN1_OCTET_STRING, this->data); + chunk_free(&this->data); + } + this->type = OID_PKCS7_DATA; + this->data = get_contentInfo(this); + chunk_free(&this->content); + + this->type = OID_PKCS7_SIGNED_DATA; + + this->content = asn1_wrap(ASN1_SEQUENCE, "cmcmm", + ASN1_INTEGER_1, + asn1_simple_object(ASN1_SET, asn1_algorithmIdentifier(signature_oid)), + this->data, + asn1_simple_object(ASN1_CONTEXT_C_0, cert->get_certificate(cert)), + asn1_wrap(ASN1_SET, "m", signerInfo)); + + return TRUE; +} + +/** * Implements pkcs7_t.destroy */ static void destroy(private_pkcs7_t *this) { + DESTROY_IF(this->attributes); this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy)); + free(this->content.ptr); free(this->data.ptr); free(this); } @@ -665,19 +981,19 @@ static bool parse_contentInfo(chunk_t blob, u_int level0, private_pkcs7_t *cInfo return FALSE; } } - else if (objectID == PKCS7_INFO_CONTENT) + else if (objectID == PKCS7_INFO_CONTENT && object.len > 0) { - cInfo->content = object; + cInfo->content = chunk_clone(object); } objectID++; } return TRUE; } -/* - * Described in header. +/** + * Generic private constructor */ -pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level) +static private_pkcs7_t *pkcs7_create_empty(void) { private_pkcs7_t *this = malloc_thing(private_pkcs7_t); @@ -685,9 +1001,9 @@ pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level) this->type = OID_UNKNOWN; this->content = chunk_empty; this->parsed = FALSE; - this->level = level + 2; + this->level = 0; this->data = chunk_empty; - this->attributes = chunk_empty; + this->attributes = NULL; this->certs = linked_list_create(); /*public functions */ @@ -698,9 +1014,25 @@ pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level) this->public.parse_signedData = (bool (*) (pkcs7_t*,x509_t*))parse_signedData; this->public.parse_envelopedData = (bool (*) (pkcs7_t*,chunk_t,rsa_private_key_t*))parse_envelopedData; this->public.get_data = (chunk_t (*) (pkcs7_t*))get_data; + this->public.get_contentInfo = (chunk_t (*) (pkcs7_t*))get_contentInfo; this->public.create_certificate_iterator = (iterator_t* (*) (pkcs7_t*))create_certificate_iterator; + this->public.set_certificate = (void (*) (pkcs7_t*,x509_t*))set_certificate; + this->public.set_attributes = (void (*) (pkcs7_t*,pkcs9_t*))set_attributes; + this->public.build_envelopedData = (bool (*) (pkcs7_t*,x509_t*,encryption_algorithm_t))build_envelopedData; + this->public.build_signedData = (bool (*) (pkcs7_t*,rsa_private_key_t*,hash_algorithm_t))build_signedData; this->public.destroy = (void (*) (pkcs7_t*))destroy; + return this; +} + +/* + * Described in header. + */ +pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level) +{ + private_pkcs7_t *this = pkcs7_create_empty(); + + this->level = level + 2; if (!parse_contentInfo(chunk, level, this)) { destroy(this); @@ -708,3 +1040,38 @@ pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level) } return &this->public; } + +/* + * Described in header. + */ +pkcs7_t *pkcs7_create_from_data(chunk_t data) +{ + private_pkcs7_t *this = pkcs7_create_empty(); + + this->data = chunk_clone(data); + this->parsed = TRUE; + + return &this->public; +} + +/* + * Described in header. + */ +pkcs7_t *pkcs7_create_from_file(const char *filename, const char *label) +{ + bool pgp = FALSE; + chunk_t chunk = chunk_empty; + char cert_label[BUF_LEN]; + pkcs7_t *pkcs7; + + snprintf(cert_label, BUF_LEN, "%s pkcs7", label); + + if (!pem_asn1_load_file(filename, NULL, cert_label, &chunk, &pgp)) + { + return NULL; + } + + pkcs7 = pkcs7_create_from_chunk(chunk, 0); + free(chunk.ptr); + return pkcs7; +} diff --git a/src/libstrongswan/crypto/pkcs7.h b/src/libstrongswan/crypto/pkcs7.h index c8434225a..74bd25361 100644 --- a/src/libstrongswan/crypto/pkcs7.h +++ b/src/libstrongswan/crypto/pkcs7.h @@ -7,7 +7,7 @@ /* * Copyright (C) 2005 Jan Hutter, Martin Willi - * Copyright (C) 2002-2007 Andreas Steffen + * Copyright (C) 2002-2008 Andreas Steffen * * Hochschule fuer Technik Rapperswil, Switzerland * @@ -21,7 +21,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: pkcs7.h 3302 2007-10-12 21:57:20Z andreas $ + * RCSID $Id: pkcs7.h 3437 2008-02-01 22:26:01Z andreas $ */ #ifndef _PKCS7_H @@ -31,7 +31,9 @@ typedef struct pkcs7_t pkcs7_t; #include <library.h> #include <crypto/x509.h> +#include <crypto/pkcs9.h> #include <crypto/rsa/rsa_private_key.h> +#include <crypto/crypters/crypter.h> #include <utils/iterator.h> /** @@ -39,6 +41,7 @@ typedef struct pkcs7_t pkcs7_t; * * @b Constructors: * -pkcs7_create_from_chunk() + * -pkcs7_create_from_data() * * @ingroup crypto */ @@ -103,14 +106,66 @@ struct pkcs7_t { chunk_t (*get_data) (pkcs7_t *this); /** + * @brief Returns the a DER-encoded contentInfo object + * + * @param this calling object + * @return chunk containing the contentInfo object + */ + chunk_t (*get_contentInfo) (pkcs7_t *this); + + /** * @brief Create an iterator for the certificates. * - * @param this calling object - * @return iterator for the certificates + * @param this calling object + * @return iterator for the certificates */ iterator_t *(*create_certificate_iterator) (pkcs7_t *this); /** + * @brief Add a certificate. + * + * @param this calling object + * @param cert certificate to be included + */ + void (*set_certificate) (pkcs7_t *this, x509_t *cert); + + /** + * @brief Add authenticated attributes. + * + * @param this calling object + * @param attributes attributes to be included + */ + void (*set_attributes) (pkcs7_t *this, pkcs9_t *attributes); + + /** + * @brief Build a data object + * + * @param this PKCS#7 data to be built + * @return TRUE if build was successful + */ + bool (*build_data) (pkcs7_t *this); + + /** + * @brief Build an envelopedData object + * + * @param this PKCS#7 data object to envelop + * @param cert receivers's certificate + * @param alg encryption algorithm + * @return TRUE if build was successful + */ + bool (*build_envelopedData) (pkcs7_t *this, x509_t *cert, encryption_algorithm_t alg); + + /** + * @brief Build an signedData object + * + * @param this PKCS#7 data object to sign + * @param key signer's RSA private key + * @param alg digest algorithm used for signature + * @return TRUE if build was successful + */ + bool (*build_signedData) (pkcs7_t *this, rsa_private_key_t *key, hash_algorithm_t alg); + + /** * @brief Destroys the contentInfo object. * * @param this PKCS#7 contentInfo object to destroy @@ -129,4 +184,26 @@ struct pkcs7_t { */ pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level); +/** + * @brief Create a PKCS#7 contentInfo object + * + * @param chunk chunk containing data + * @return created pkcs7_contentInfo object. + * + * @ingroup crypto + */ +pkcs7_t *pkcs7_create_from_data(chunk_t data); + +/** + * @brief Read a X.509 certificate from a DER encoded file. + * + * @param filename file containing DER encoded data + * @param label label describing kind of PKCS#7 file + * @return created pkcs7_t object, or NULL if invalid. + * + * @ingroup crypto + */ +pkcs7_t *pkcs7_create_from_file(const char *filename, const char *label); + + #endif /* _PKCS7_H */ diff --git a/src/libstrongswan/crypto/pkcs9.c b/src/libstrongswan/crypto/pkcs9.c new file mode 100644 index 000000000..1003c9011 --- /dev/null +++ b/src/libstrongswan/crypto/pkcs9.c @@ -0,0 +1,470 @@ +/** + * @file pkcs9.c + * + * @brief Implementation of pkcs9_t. + * + */ + +/* + * Copyright (C)2008 Andreas Steffen + * + * Hochschule fuer Technik Rapperswil, Switzerland + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: pkcs7.c 3423 2008-01-22 10:32:37Z andreas $ + */ + +#include <library.h> +#include <debug.h> + +#include <asn1/oid.h> +#include <asn1/asn1.h> +#include <utils/linked_list.h> + +#include "pkcs9.h" + +typedef struct private_pkcs9_t private_pkcs9_t; + +/** + * Private data of a pkcs9_t attribute list. + */ +struct private_pkcs9_t { + /** + * Public interface + */ + pkcs9_t public; + + /** + * DER encoding of PKCS#9 attributes + */ + chunk_t encoding; + + /** + * Linked list of PKCS#9 attributes + */ + linked_list_t *attributes; +}; + +typedef struct attribute_t attribute_t; + +/** + * Definition of an attribute_t object. + */ +struct attribute_t { + /** + * Object Identifier (OID) + */ + int oid; + + /** + * Attribute value + */ + chunk_t value; + + /** + * ASN.1 encoding + */ + chunk_t encoding; + + /** + * Destroys the attribute. + * + * @param this attribute to destroy + */ + void (*destroy) (attribute_t *this); + +}; + +/* ASN.1 definition of the X.501 atttribute type */ + +static const asn1Object_t attributesObjects[] = { + { 0, "attributes", ASN1_SET, ASN1_LOOP }, /* 0 */ + { 1, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ + { 2, "type", ASN1_OID, ASN1_BODY }, /* 2 */ + { 2, "values", ASN1_SET, ASN1_LOOP }, /* 3 */ + { 3, "value", ASN1_EOC, ASN1_RAW }, /* 4 */ + { 2, "end loop", ASN1_EOC, ASN1_END }, /* 5 */ + { 0, "end loop", ASN1_EOC, ASN1_END }, /* 6 */ +}; + +#define ATTRIBUTE_OBJ_TYPE 2 +#define ATTRIBUTE_OBJ_VALUE 4 +#define ATTRIBUTE_OBJ_ROOF 7 + +/** + * PKCS#9 attribute type OIDs + */ +static u_char ASN1_contentType_oid_str[] = { + 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x03 +}; + +static u_char ASN1_messageDigest_oid_str[] = { + 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x04 +}; + +static u_char ASN1_signingTime_oid_str[] = { + 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x05 +}; + +static char ASN1_messageType_oid_str[] = { + 0x06, 0x0A, + 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x02 +}; + +static char ASN1_senderNonce_oid_str[] = { + 0x06, 0x0A, + 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x05 +}; + +static char ASN1_transId_oid_str[] = { + 0x06, 0x0A, + 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x07 +}; + +static const chunk_t ASN1_contentType_oid = + chunk_from_buf(ASN1_contentType_oid_str); +static const chunk_t ASN1_messageDigest_oid = + chunk_from_buf(ASN1_messageDigest_oid_str); +static const chunk_t ASN1_signingTime_oid = + chunk_from_buf(ASN1_signingTime_oid_str); +static const chunk_t ASN1_messageType_oid = + chunk_from_buf(ASN1_messageType_oid_str); +static const chunk_t ASN1_senderNonce_oid = + chunk_from_buf(ASN1_senderNonce_oid_str); +static const chunk_t ASN1_transId_oid = + chunk_from_buf(ASN1_transId_oid_str); + +/** + * return the ASN.1 encoded OID of a PKCS#9 attribute + */ +static chunk_t asn1_attributeIdentifier(int oid) +{ + switch (oid) + { + case OID_PKCS9_CONTENT_TYPE: + return ASN1_contentType_oid; + case OID_PKCS9_MESSAGE_DIGEST: + return ASN1_messageDigest_oid; + case OID_PKCS9_SIGNING_TIME: + return ASN1_signingTime_oid; + case OID_PKI_MESSAGE_TYPE: + return ASN1_messageType_oid; + case OID_PKI_SENDER_NONCE: + return ASN1_senderNonce_oid; + case OID_PKI_TRANS_ID: + return ASN1_transId_oid;; + default: + return chunk_empty; + } +} + +/** + * return the ASN.1 encoding of a PKCS#9 attribute + */ +static asn1_t asn1_attributeType(int oid) +{ + asn1_t type; + + switch (oid) + { + case OID_PKCS9_CONTENT_TYPE: + type = ASN1_OID; + break; + case OID_PKCS9_SIGNING_TIME: + type = ASN1_UTCTIME; + break; + case OID_PKCS9_MESSAGE_DIGEST: + type = ASN1_OCTET_STRING; + break; + case OID_PKI_MESSAGE_TYPE: + type = ASN1_PRINTABLESTRING; + break; + case OID_PKI_STATUS: + type = ASN1_PRINTABLESTRING; + break; + case OID_PKI_FAIL_INFO: + type = ASN1_PRINTABLESTRING; + break; + case OID_PKI_SENDER_NONCE: + type = ASN1_OCTET_STRING; + break; + case OID_PKI_RECIPIENT_NONCE: + type = ASN1_OCTET_STRING; + break; + case OID_PKI_TRANS_ID: + type = ASN1_PRINTABLESTRING; + break; + default: + type = ASN1_EOC; + } + return type; +} + +/** + * Destroy an attribute_t object. + */ +static void attribute_destroy(attribute_t *this) +{ + free(this->value.ptr); + free(this->encoding.ptr); + free(this); +} + +/** + * Create an attribute_t object. + */ +static attribute_t *attribute_create(int oid, chunk_t value) +{ + attribute_t *this = malloc_thing(attribute_t); + + this->oid = oid; + this->value = chunk_clone(value); + this->encoding = asn1_wrap(ASN1_SEQUENCE, "cm", + asn1_attributeIdentifier(oid), + asn1_simple_object(ASN1_SET, value)); + this->destroy = (void (*) (attribute_t*))attribute_destroy; + return this; +} + +/** + * Implements pkcs9_t.build_encoding + */ +static void build_encoding(private_pkcs9_t *this) +{ + iterator_t *iterator; + attribute_t *attribute; + u_int attributes_len = 0; + + if (this->encoding.ptr) + { + chunk_free(&this->encoding); + } + if (this->attributes->get_count(this->attributes) == 0) + { + return; + } + + /* compute the total length of the encoded attributes */ + iterator = this->attributes->create_iterator(this->attributes, TRUE); + + while (iterator->iterate(iterator, (void**)&attribute)) + { + attributes_len += attribute->encoding.len; + } + iterator->destroy(iterator); + + /* allocate memory for the attributes and build the encoding */ + { + u_char *pos = build_asn1_object(&this->encoding, ASN1_SET, attributes_len); + + iterator = this->attributes->create_iterator(this->attributes, TRUE); + + while (iterator->iterate(iterator, (void**)&attribute)) + { + memcpy(pos, attribute->encoding.ptr, attribute->encoding.len); + pos += attribute->encoding.len; + } + iterator->destroy(iterator); + } +} + +/** + * Implements pkcs9_t.get_encoding + */ +static chunk_t get_encoding(private_pkcs9_t *this) +{ + if (this->encoding.ptr == NULL) + { + build_encoding(this); + } + return this->encoding; +} + +/** + * Implements pkcs9_t.get_attribute + */ +static chunk_t get_attribute(private_pkcs9_t *this, int oid) +{ + iterator_t *iterator = this->attributes->create_iterator(this->attributes, TRUE); + chunk_t value = chunk_empty; + attribute_t *attribute; + + while (iterator->iterate(iterator, (void**)&attribute)) + { + if (attribute->oid == oid) + { + value = attribute->value; + break; + } + } + iterator->destroy(iterator); + return value; +} + +/** + * Implements pkcs9_t.set_attribute + */ +static void set_attribute(private_pkcs9_t *this, int oid, chunk_t value) +{ + attribute_t *attribute = attribute_create(oid, value); + + this->attributes->insert_last(this->attributes, (void*)attribute); +} + +/** + * Implements pkcs9_t.get_messageDigest + */ +static chunk_t get_messageDigest(private_pkcs9_t *this) +{ + const int oid = OID_PKCS9_MESSAGE_DIGEST; + chunk_t value = get_attribute(this, oid); + + if (value.ptr == NULL) + { + return chunk_empty; + } + if (!parse_asn1_simple_object(&value, asn1_attributeType(oid), 0, oid_names[oid].name)) + { + return chunk_empty; + } + return chunk_clone(value); +} + +/** + * Implements pkcs9_t.set_attribute + */ +static void set_messageDigest(private_pkcs9_t *this, chunk_t value) +{ + const int oid = OID_PKCS9_MESSAGE_DIGEST; + chunk_t messageDigest = asn1_simple_object(asn1_attributeType(oid), value); + + set_attribute(this, oid, messageDigest); + free(messageDigest.ptr); +} + +/** + * Implements pkcs9_t.destroy + */ +static void destroy(private_pkcs9_t *this) +{ + this->attributes->destroy_offset(this->attributes, offsetof(attribute_t, destroy)); + free(this->encoding.ptr); + free(this); +} + +/** + * Generic private constructor + */ +static private_pkcs9_t *pkcs9_create_empty(void) +{ + private_pkcs9_t *this = malloc_thing(private_pkcs9_t); + + /* initialize */ + this->encoding = chunk_empty; + this->attributes = linked_list_create(); + + /*public functions */ + this->public.build_encoding = (void (*) (pkcs9_t*))build_encoding; + this->public.get_encoding = (chunk_t (*) (pkcs9_t*))get_encoding; + this->public.get_attribute = (chunk_t (*) (pkcs9_t*,int))get_attribute; + this->public.set_attribute = (void (*) (pkcs9_t*,int,chunk_t))set_attribute; + this->public.get_messageDigest = (chunk_t (*) (pkcs9_t*))get_messageDigest; + this->public.set_messageDigest = (void (*) (pkcs9_t*,chunk_t))set_messageDigest; + this->public.destroy = (void (*) (pkcs9_t*))destroy; + + return this; +} + +/* + * Described in header. + */ +pkcs9_t *pkcs9_create(void) +{ + private_pkcs9_t *this = pkcs9_create_empty(); + + return &this->public; +} + +/** + * Parse a PKCS#9 attribute list + */ +static bool parse_attributes(chunk_t chunk, int level0, private_pkcs9_t* this) +{ + asn1_ctx_t ctx; + chunk_t object; + u_int level; + int oid = OID_UNKNOWN; + int objectID = 0; + + asn1_init(&ctx, chunk, level0, FALSE, FALSE); + + while (objectID < ATTRIBUTE_OBJ_ROOF) + { + if (!extract_object(attributesObjects, &objectID, &object, &level, &ctx)) + { + return FALSE; + } + + switch (objectID) + { + case ATTRIBUTE_OBJ_TYPE: + oid = known_oid(object); + break; + case ATTRIBUTE_OBJ_VALUE: + if (oid == OID_UNKNOWN) + { + break; + } + /* add the attribute to a linked list */ + { + attribute_t *attribute = attribute_create(oid, object); + + this->attributes->insert_last(this->attributes, (void*)attribute); + } + /* parse known attributes */ + { + asn1_t type = asn1_attributeType(oid); + + if (type != ASN1_EOC) + { + if (!parse_asn1_simple_object(&object, type, level+1, oid_names[oid].name)) + { + return FALSE; + } + } + } + } + objectID++; + } + return TRUE; +} + + + /* + * Described in header. + */ +pkcs9_t *pkcs9_create_from_chunk(chunk_t chunk, u_int level) +{ + private_pkcs9_t *this = pkcs9_create_empty(); + + this->encoding = chunk_clone(chunk); + + if (!parse_attributes(chunk, level, this)) + { + destroy(this); + return NULL; + } + return &this->public; +} diff --git a/src/libstrongswan/crypto/pkcs9.h b/src/libstrongswan/crypto/pkcs9.h new file mode 100644 index 000000000..44915720c --- /dev/null +++ b/src/libstrongswan/crypto/pkcs9.h @@ -0,0 +1,121 @@ +/** + * @file pkcs7.h + * + * @brief Interface of pkcs9_t. + * + */ + +/* + * Copyright (C) 2008 Andreas Steffen + * + * Hochschule fuer Technik Rapperswil, Switzerland + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: pkcs7.h 3423 2008-01-22 10:32:37Z andreas $ + */ + +#ifndef _PKCS9_H +#define _PKCS9_H + +typedef struct pkcs9_t pkcs9_t; + +#include <library.h> + +/** + * @brief PKCS#9 . + * + * @b Constructors: + * -pkcs9_create_from_chunk() + * -pkcs9_create() + * + * @ingroup crypto + */ +struct pkcs9_t { + /** + * @brief generate ASN.1 encoding of attribute list + * + * @param this PKCS#9 attribute list to be encoded + */ + void (*build_encoding) (pkcs9_t *this); + + /** + * @brief gets ASN.1 encoding of PKCS#9 attribute list + * + * @param this calling object + * @return ASN.1 encoded PKCSI#9 list + */ + chunk_t (*get_encoding) (pkcs9_t *this); + + /** + * @brief gets a PKCS#9 attribute + * + * @param this calling object + * @param oid OID of the attribute + * @return ASN.1 encoded value of the attribute + */ + chunk_t (*get_attribute) (pkcs9_t *this, int oid); + + /** + * @brief adds a PKCS#9 attribute + * + * @param this calling object + * @param oid OID of the attribute + * @param value ASN.1 encoded value of the attribute + */ + void (*set_attribute) (pkcs9_t *this, int oid, chunk_t value); + + /** + * @brief gets a PKCS#9 messageDigest attribute + * + * @param this calling object + * @return messageDigest + */ + chunk_t (*get_messageDigest) (pkcs9_t *this); + + /** + * @brief add a PKCS#9 messageDigest attribute + * + * @param this calling object + * @param value messageDigest + */ + void (*set_messageDigest) (pkcs9_t *this, chunk_t value); + + /** + * @brief Destroys the PKCS#9 attribute list. + * + * @param this PKCS#9 attribute list to destroy + */ + void (*destroy) (pkcs9_t *this); +}; + +/** + * @brief Read a PKCS#9 attribute list from a DER encoded chunk. + * + * @param chunk chunk containing DER encoded data + * @param level ASN.1 parsing start level + * @return created pkcs9 attribute list, or NULL if invalid. + * + * @ingroup crypto + */ +pkcs9_t *pkcs9_create_from_chunk(chunk_t chunk, u_int level); + +/** + * @brief Create an empty PKCS#9 attribute list + * + * @param chunk chunk containing data + * @return created pkcs9 attribute list. + * + * @ingroup crypto + */ +pkcs9_t *pkcs9_create(void); + +#endif /* _PKCS9_H */ diff --git a/src/libstrongswan/crypto/rsa/rsa_private_key.c b/src/libstrongswan/crypto/rsa/rsa_private_key.c index ec2f2fc74..1b1499887 100644 --- a/src/libstrongswan/crypto/rsa/rsa_private_key.c +++ b/src/libstrongswan/crypto/rsa/rsa_private_key.c @@ -6,8 +6,10 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2007-2008 Andreas Steffen + * * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -20,7 +22,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: rsa_private_key.c 3306 2007-10-17 02:55:53Z andreas $ + * RCSID $Id: rsa_private_key.c 3429 2008-01-27 20:59:22Z andreas $ */ #include <gmp.h> @@ -40,6 +42,7 @@ * defined in rsa_public_key.c */ extern chunk_t rsa_public_key_info_to_asn1(const mpz_t n, const mpz_t e); +extern chunk_t rsa_public_key_id_create(const mpz_t n, const mpz_t e); /** * Public exponent to use for key generation. @@ -111,7 +114,6 @@ struct private_rsa_private_key_t { * Keyid formed as a SHA-1 hash of a publicKeyInfo object */ chunk_t keyid; - /** * @brief Implements the RSADP algorithm specified in PKCS#1. @@ -129,16 +131,6 @@ struct private_rsa_private_key_t { * @return processed data */ chunk_t (*rsasp1) (private_rsa_private_key_t *this, chunk_t data); - - /** - * @brief Generate a prime value. - * - * @param this calling object - * @param prime_size size of the prime, in bytes - * @param[out] prime uninitialized mpz - */ - status_t (*compute_prime) (private_rsa_private_key_t *this, size_t prime_size, mpz_t *prime); - }; /* ASN.1 definition of a PKCS#1 RSA private key */ @@ -173,8 +165,6 @@ static const asn1Object_t privkey_objects[] = { #define PRIV_KEY_COEFF 9 #define PRIV_KEY_ROOF 16 -static private_rsa_private_key_t *rsa_private_key_create_empty(void); - /** * Auxiliary function overwriting private key material with * pseudo-random bytes before releasing it @@ -196,9 +186,9 @@ static void mpz_clear_randomized(mpz_t z) } /** - * Implementation of private_rsa_private_key_t.compute_prime. + * Generate a random prime number with prime_len bytes */ -static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_size, mpz_t *prime) +static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_len, mpz_t *prime) { randomizer_t *randomizer; chunk_t random_bytes; @@ -209,7 +199,8 @@ static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_size do { - status = randomizer->allocate_random_bytes(randomizer, prime_size, &random_bytes); + DBG1(" generating %d bit prime from %s ...", BITS_PER_BYTE * prime_len, DEV_RANDOM); + status = randomizer->allocate_random_bytes(randomizer, prime_len, &random_bytes); if (status != SUCCESS) { randomizer->destroy(randomizer); @@ -230,7 +221,7 @@ static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_size chunk_free_randomized(&random_bytes); } /* check if it isnt too large */ - while (((mpz_sizeinbase(*prime, 2) + 7) / 8) > prime_size); + while (((mpz_sizeinbase(*prime, 2) + 7) / BITS_PER_BYTE) > prime_len); randomizer->destroy(randomizer); return SUCCESS; @@ -269,7 +260,7 @@ static chunk_t rsadp(private_rsa_private_key_t *this, chunk_t data) } /** - * Implementation of rsa_private_key_t.eme_pkcs1_decrypt. + * Implementation of rsa_private_key_t.pkcs1_decrypt. */ static status_t pkcs1_decrypt(private_rsa_private_key_t *this, chunk_t in, chunk_t *out) @@ -319,47 +310,14 @@ static status_t build_emsa_pkcs1_signature(private_rsa_private_key_t *this, chunk_t data, chunk_t *signature) { hasher_t *hasher; - chunk_t em, digestInfo, hash_id, hash; - - /* get oid string prepended to hash */ - switch (hash_algorithm) - { - case HASH_MD2: - { - hash_id =ASN1_md2_id; - break; - } - case HASH_MD5: - { - hash_id = ASN1_md5_id; - break; - } - case HASH_SHA1: - { - hash_id = ASN1_sha1_id; - break; - } - case HASH_SHA256: - { - hash_id = ASN1_sha256_id; - break; - } - case HASH_SHA384: - { - hash_id = ASN1_sha384_id; - break; - } - case HASH_SHA512: - { - hash_id = ASN1_sha512_id; - break; - } - default: - { - return NOT_SUPPORTED; - } + chunk_t em, digestInfo, hash; + int hash_oid = hasher_algorithm_to_oid(hash_algorithm); + + if (hash_oid == OID_UNKNOWN) + { + return NOT_SUPPORTED; } - + /* get hasher */ hasher = hasher_create(hash_algorithm); if (hasher == NULL) @@ -373,7 +331,7 @@ static status_t build_emsa_pkcs1_signature(private_rsa_private_key_t *this, /* build DER-encoded digestInfo */ digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm", - hash_id, + asn1_algorithmIdentifier(hash_oid), asn1_simple_object(ASN1_OCTET_STRING, hash) ); chunk_free(&hash); @@ -432,7 +390,7 @@ static bool pkcs1_write(private_rsa_private_key_t *this, const char *filename, b */ rsa_public_key_t *get_public_key(private_rsa_private_key_t *this) { - return NULL; + return rsa_public_key_create(this->n, this->e); } /** @@ -455,13 +413,13 @@ static status_t check(private_rsa_private_key_t *this) /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets. * We actually require more (for security). */ - if (this->k < 512/8) + if (this->k < 512 / BITS_PER_BYTE) { return FAILED; } /* we picked a max modulus size to simplify buffer allocation */ - if (this->k > 8192/8) + if (this->k > 8192 / BITS_PER_BYTE) { return FAILED; } @@ -572,7 +530,6 @@ static private_rsa_private_key_t *rsa_private_key_create_empty(void) /* private functions */ this->rsadp = rsadp; this->rsasp1 = rsadp; /* same algorithm */ - this->compute_prime = compute_prime; this->keyid = chunk_empty; @@ -587,20 +544,17 @@ rsa_private_key_t *rsa_private_key_create(size_t key_size) mpz_t p, q, n, e, d, exp1, exp2, coeff; mpz_t m, q1, t; private_rsa_private_key_t *this; - - this = rsa_private_key_create_empty(); - key_size = key_size / 8; + size_t key_len = key_size / BITS_PER_BYTE; + size_t prime_len = key_len / 2; /* Get values of primes p and q */ - if (this->compute_prime(this, key_size/2, &p) != SUCCESS) + if (compute_prime(this, prime_len, &p) != SUCCESS) { - free(this); return NULL; } - if (this->compute_prime(this, key_size/2, &q) != SUCCESS) + if (compute_prime(this, prime_len, &q) != SUCCESS) { mpz_clear(p); - free(this); return NULL; } @@ -648,7 +602,13 @@ rsa_private_key_t *rsa_private_key_create(size_t key_size) mpz_clear_randomized(m); mpz_clear_randomized(t); - /* apply values */ + /* determine exact the modulus size in bits */ + key_size = mpz_sizeinbase(n, 2); + + /* create and fill in rsa_private_key_t object */ + this = rsa_private_key_create_empty(); + this->k = (key_size + 7) / BITS_PER_BYTE; + this->keyid = rsa_public_key_id_create(n, e); *(this->p) = *p; *(this->q) = *q; *(this->n) = *n; @@ -657,10 +617,8 @@ rsa_private_key_t *rsa_private_key_create(size_t key_size) *(this->exp1) = *exp1; *(this->exp2) = *exp2; *(this->coeff) = *coeff; - - /* set key size in bytes */ - this->k = key_size; - + DBG1("generated %d bit RSA key with keyid: %#B", key_size, &this->keyid); + return &this->public; } @@ -733,17 +691,8 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob) } this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; + this->keyid = rsa_public_key_id_create(this->n, this->e); - /* form the keyid as a SHA-1 hash of a publicKeyInfo object */ - { - chunk_t publicKeyInfo = rsa_public_key_info_to_asn1(this->n, this->e); - hasher_t *hasher = hasher_create(HASH_SHA1); - - hasher->allocate_hash(hasher, publicKeyInfo, &this->keyid); - hasher->destroy(hasher); - free(publicKeyInfo.ptr); - } - if (check(this) != SUCCESS) { destroy(this); diff --git a/src/libstrongswan/crypto/rsa/rsa_private_key.h b/src/libstrongswan/crypto/rsa/rsa_private_key.h index e5cf49810..8013f03c2 100644 --- a/src/libstrongswan/crypto/rsa/rsa_private_key.h +++ b/src/libstrongswan/crypto/rsa/rsa_private_key.h @@ -6,8 +6,10 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2007-2008 Andreas Steffen + * * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -20,7 +22,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: rsa_private_key.h 3296 2007-10-12 15:23:29Z andreas $ + * RCSID $Id: rsa_private_key.h 3423 2008-01-22 10:32:37Z andreas $ */ #ifndef RSA_PRIVATE_KEY_H_ diff --git a/src/libstrongswan/crypto/rsa/rsa_public_key.c b/src/libstrongswan/crypto/rsa/rsa_public_key.c index 6f2158d2b..10af0527e 100644 --- a/src/libstrongswan/crypto/rsa/rsa_public_key.c +++ b/src/libstrongswan/crypto/rsa/rsa_public_key.c @@ -6,8 +6,10 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2007-2008 Andreas Steffen + * * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -20,7 +22,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: rsa_public_key.c 3303 2007-10-12 22:49:39Z andreas $ + * RCSID $Id: rsa_public_key.c 3428 2008-01-27 20:58:52Z andreas $ */ #include <gmp.h> @@ -32,6 +34,7 @@ #include "rsa_public_key.h" #include <debug.h> +#include <utils/randomizer.h> #include <crypto/hashers/hasher.h> #include <asn1/asn1.h> #include <asn1/pem.h> @@ -110,8 +113,6 @@ struct private_rsa_public_key_t { chunk_t (*rsavp1) (const private_rsa_public_key_t *this, chunk_t data); }; -private_rsa_public_key_t *rsa_public_key_create_empty(void); - /** * Implementation of private_rsa_public_key_t.rsaep and private_rsa_public_key_t.rsavp1 */ @@ -137,6 +138,55 @@ static chunk_t rsaep(const private_rsa_public_key_t *this, chunk_t data) } /** + * Implementation of rsa_public_key_t.eme_pkcs1_encrypt. + */ +static status_t pkcs1_encrypt(private_rsa_public_key_t *this, + chunk_t in, chunk_t *out) +{ + chunk_t em; + u_char *pos; + int padding = this->k - in.len - 3; + + if (padding < 8) + { + DBG1("rsa padding of %d bytes is too small", padding); + return FAILED; + } + em.len = this->k; + em.ptr = pos = malloc(em.len); + + /* add padding according to PKCS#1 7.2.1 1.+2. */ + *pos++ = 0x00; + *pos++ = 0x02; + + /* pad with pseudo random bytes unequal to zero */ + { + randomizer_t *randomizer = randomizer_create(); + + /* pad with pseudo random bytes unequal to zero */ + while (padding--) + { + randomizer->get_pseudo_random_bytes(randomizer, 1, pos); + while (!*pos) + { + randomizer->get_pseudo_random_bytes(randomizer, 1, pos); + } + pos++; + } + randomizer->destroy(randomizer); + } + + /* append the padding terminator */ + *pos++ = 0x00; + + /* now add the data */ + memcpy(pos, in.ptr, in.len); + *out = this->rsaep(this, em); + free(em.ptr); + return SUCCESS; +} + +/** * Implementation of rsa_public_key.verify_emsa_pkcs1_signature. */ static status_t verify_emsa_pkcs1_signature(const private_rsa_public_key_t *this, @@ -297,19 +347,30 @@ static size_t get_keysize(const private_rsa_public_key_t *this) */ chunk_t rsa_public_key_info_to_asn1(const mpz_t n, const mpz_t e) { - chunk_t rawKey = asn1_wrap(ASN1_SEQUENCE, "mm", + chunk_t publicKey = asn1_wrap(ASN1_SEQUENCE, "mm", asn1_integer_from_mpz(n), asn1_integer_from_mpz(e)); - chunk_t publicKey; - u_char *pos = build_asn1_object(&publicKey, ASN1_BIT_STRING, 1 + rawKey.len); + return asn1_wrap(ASN1_SEQUENCE, "cm", + asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), + asn1_bitstring("m", publicKey)); +} - *pos++ = 0x00; - memcpy(pos, rawKey.ptr, rawKey.len); - free(rawKey.ptr); +/** + * Form the RSA keyid as a SHA-1 hash of a publicKeyInfo object + * Also used in rsa_private_key.c. + */ +chunk_t rsa_public_key_id_create(mpz_t n, mpz_t e) +{ + chunk_t keyid; + chunk_t publicKeyInfo = rsa_public_key_info_to_asn1(n, e); + hasher_t *hasher = hasher_create(HASH_SHA1); + + hasher->allocate_hash(hasher, publicKeyInfo, &keyid); + hasher->destroy(hasher); + free(publicKeyInfo.ptr); - return asn1_wrap(ASN1_SEQUENCE, "cm", ASN1_rsaEncryption_id, - publicKey); + return keyid; } /** @@ -328,6 +389,9 @@ static chunk_t get_keyid(const private_rsa_public_key_t *this) return this->keyid; } +/* forward declaration used by rsa_public_key_t.clone */ +private_rsa_public_key_t *rsa_public_key_create_empty(void); + /** * Implementation of rsa_public_key_t.clone. */ @@ -362,6 +426,7 @@ private_rsa_public_key_t *rsa_public_key_create_empty(void) private_rsa_public_key_t *this = malloc_thing(private_rsa_public_key_t); /* public functions */ + this->public.pkcs1_encrypt = (status_t (*) (rsa_public_key_t*,chunk_t,chunk_t*))pkcs1_encrypt; this->public.verify_emsa_pkcs1_signature = (status_t (*) (const rsa_public_key_t*,hash_algorithm_t,chunk_t,chunk_t))verify_emsa_pkcs1_signature; this->public.get_modulus = (mpz_t *(*) (const rsa_public_key_t*))get_modulus; this->public.get_keysize = (size_t (*) (const rsa_public_key_t*))get_keysize; @@ -380,6 +445,20 @@ private_rsa_public_key_t *rsa_public_key_create_empty(void) /* * See header */ +rsa_public_key_t *rsa_public_key_create(mpz_t n, mpz_t e) +{ + private_rsa_public_key_t *this = rsa_public_key_create_empty(); + + mpz_init_set(this->n, n); + mpz_init_set(this->e, e); + + this->k = (mpz_sizeinbase(n, 2) + 7) / BITS_PER_BYTE; + this->keyid = rsa_public_key_id_create(n, e); + return &this->public; +} +/* + * See header + */ rsa_public_key_t *rsa_public_key_create_from_chunk(chunk_t blob) { asn1_ctx_t ctx; @@ -412,19 +491,9 @@ rsa_public_key_t *rsa_public_key_create_from_chunk(chunk_t blob) } objectID++; } - - this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8; - - /* form the keyid as a SHA-1 hash of a publicKeyInfo object */ - { - chunk_t publicKeyInfo = rsa_public_key_info_to_asn1(this->n, this->e); - hasher_t *hasher = hasher_create(HASH_SHA1); - - hasher->allocate_hash(hasher, publicKeyInfo, &this->keyid); - hasher->destroy(hasher); - free(publicKeyInfo.ptr); - } + this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; + this->keyid = rsa_public_key_id_create(this->n, this->e); return &this->public; } diff --git a/src/libstrongswan/crypto/rsa/rsa_public_key.h b/src/libstrongswan/crypto/rsa/rsa_public_key.h index 0a40c2204..c0bd3e351 100644 --- a/src/libstrongswan/crypto/rsa/rsa_public_key.h +++ b/src/libstrongswan/crypto/rsa/rsa_public_key.h @@ -6,8 +6,10 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2007-2008 Andreas Steffen + * * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -20,7 +22,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: rsa_public_key.h 3303 2007-10-12 22:49:39Z andreas $ + * RCSID $Id: rsa_public_key.h 3423 2008-01-22 10:32:37Z andreas $ */ #ifndef RSA_PUBLIC_KEY_H_ @@ -40,20 +42,29 @@ typedef struct rsa_public_key_t rsa_public_key_t; * the EMSA encoding (see PKCS1) * * @b Constructors: + * - rsa_public_key_create() * - rsa_public_key_create_from_chunk() * - rsa_public_key_create_from_file() - * - rsa_private_key_t.get_public_key() - * - * @see rsa_private_key_t - * - * @todo Implement getkey() and savekey() - * + * * @ingroup rsa */ struct rsa_public_key_t { /** - * @brief Verify a EMSA-PKCS1 encodined signature. + * @brief Encrypt a data block using EME-PKCS1 encoding. + * + * + * @param this calling object + * @param data plaintext input data + * @param out encrypted output data + * @return + * - SUCCESS + * - FAILED if data block is too large + */ + status_t (*pkcs1_encrypt) (rsa_public_key_t *this, chunk_t in, chunk_t *out); + + /** + * @brief Verify an EMSA-PKCS1 encoded signature. * * Processes the supplied signature with the RSAVP1 function, * selects the hash algorithm form the resultign ASN1-OID and @@ -123,6 +134,17 @@ struct rsa_public_key_t { }; /** + * @brief Create a RSA public key from modulus and public exponent. + * + * @param n modulus + * @param e public exponent + * @return created rsa_public_key_t + * + * @ingroup rsa + */ +rsa_public_key_t *rsa_public_key_create(mpz_t n, mpz_t e); + +/** * @brief Load an RSA public key from a chunk. * * Load a key from a chunk, encoded in the more frequently diff --git a/src/libstrongswan/crypto/x509.c b/src/libstrongswan/crypto/x509.c index 6f154b36f..eadf11327 100755 --- a/src/libstrongswan/crypto/x509.c +++ b/src/libstrongswan/crypto/x509.c @@ -9,8 +9,8 @@ * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss * Copyright (C) 2002 Mario Strasser - * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur - * Copyright (C) 2006 Martin Willi, Andreas Steffen + * Copyright (C) 2006 Martin Willi + * Copyright (C) 2000-2008 Andreas Steffen * * Hochschule fuer Technik Rapperswil * @@ -24,7 +24,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: x509.c 3355 2007-11-20 12:06:40Z martin $ + * RCSID $Id: x509.c 3423 2008-01-22 10:32:37Z andreas $ */ #include <gmp.h> @@ -514,7 +514,7 @@ static identification_t *parse_generalName(chunk_t blob, int level0) id_type = ID_DER_ASN1_DN; break; case GN_OBJ_IP_ADDRESS: - id_type = ID_IPV4_ADDR; + id_type = (object.len == 4)? ID_IPV4_ADDR : ID_IPV6_ADDR; break; case GN_OBJ_OTHER_NAME: if (!parse_otherName(object, level + 1)) @@ -1243,6 +1243,22 @@ static void list(private_x509_t *this, FILE *out, bool utc) } } +/** + * Implements x509_t.add_subjectAltNames. + */ +static void add_subjectAltNames(private_x509_t *this, linked_list_t *subjectAltNames) +{ + iterator_t *iterator = subjectAltNames->create_iterator(subjectAltNames, TRUE); + identification_t *name = NULL; + + while (iterator->iterate(iterator, (void**)&name)) + { + name = name->clone(name); + this->subjectAltNames->insert_last(this->subjectAltNames, (void*)name); + } + iterator->destroy(iterator); +} + /* * Defined in header. */ @@ -1251,12 +1267,13 @@ chunk_t x509_build_generalNames(linked_list_t *list) linked_list_t *generalNames = linked_list_create(); iterator_t *iterator = list->create_iterator(list, TRUE); identification_t *name; + chunk_t names = chunk_empty; size_t len = 0; while (iterator->iterate(iterator, (void**)&name)) { asn1_t asn1_type = ASN1_EOC; - chunk_t *generalName = malloc_thing(chunk_t); + chunk_t *generalName; switch (name->get_type(name)) { @@ -1273,22 +1290,24 @@ chunk_t x509_build_generalNames(linked_list_t *list) asn1_type = ASN1_CONTEXT_S_6; break; case ID_IPV4_ADDR: + case ID_IPV6_ADDR: asn1_type = ASN1_CONTEXT_S_7; break; default: continue; } + generalName = malloc_thing(chunk_t); *generalName = asn1_simple_object(asn1_type, name->get_encoding(name)); len += generalName->len; - generalNames->insert_last(generalNames, generalName); + generalNames->insert_last(generalNames, (void*)generalName); } iterator->destroy(iterator); if (len > 0) { iterator_t *iterator = generalNames->create_iterator(generalNames, TRUE); - chunk_t names, *generalName; + chunk_t *generalName; u_char *pos = build_asn1_object(&names, ASN1_SEQUENCE, len); while (iterator->iterate(iterator, (void**)&generalName)) @@ -1299,14 +1318,9 @@ chunk_t x509_build_generalNames(linked_list_t *list) free(generalName); } iterator->destroy(iterator); - generalNames->destroy(generalNames); - - return asn1_wrap(ASN1_OCTET_STRING, "m", names); - } - else - { - return chunk_empty; } + generalNames->destroy(generalNames); + return names; } /* @@ -1330,11 +1344,54 @@ chunk_t x509_build_subjectAltNames(linked_list_t *list) } /** + * Build a to-be-signed X.509 certificate body + */ +static chunk_t x509_build_tbs(private_x509_t *this) +{ + /* version is always X.509v3 */ + chunk_t version = asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2); + + chunk_t extensions = chunk_empty; + + if (this->subjectAltNames->get_count(this->subjectAltNames)) + { + extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m", + asn1_wrap(ASN1_SEQUENCE, "m", + x509_build_subjectAltNames(this->subjectAltNames))); + } + + return asn1_wrap(ASN1_SEQUENCE, "mmccmcmm", + version, + asn1_simple_object(ASN1_INTEGER, this->serialNumber), + asn1_algorithmIdentifier(this->signatureAlgorithm), + this->issuer->get_encoding(this->issuer), + asn1_wrap(ASN1_SEQUENCE, "mm", + timetoasn1(&this->notBefore, ASN1_UTCTIME), + timetoasn1(&this->notAfter, ASN1_UTCTIME) + ), + this->subject->get_encoding(this->subject), + this->public_key->get_publicKeyInfo(this->public_key), + extensions + ); +} + +/** * Implementation of x509_t.build_encoding. */ static void build_encoding(private_x509_t *this, hash_algorithm_t alg, rsa_private_key_t *private_key) { + chunk_t signature; + + this->signatureAlgorithm = hasher_signature_algorithm_to_oid(alg); + this->tbsCertificate = x509_build_tbs(this); + private_key->build_emsa_pkcs1_signature(private_key, alg, + this->tbsCertificate, &signature); + this->signature = asn1_bitstring("m", signature); + this->certificate = asn1_wrap(ASN1_SEQUENCE, "mcm", + this->tbsCertificate, + asn1_algorithmIdentifier(this->signatureAlgorithm), + this->signature); } @@ -1408,6 +1465,7 @@ static private_x509_t *x509_create_empty(void) this->public.create_ocspuri_iterator = (iterator_t* (*) (const x509_t*))create_ocspuri_iterator; this->public.verify = (bool (*) (const x509_t*,const rsa_public_key_t*))verify; this->public.list = (void (*) (x509_t*, FILE *out, bool utc))list; + this->public.add_subjectAltNames = (void (*) (x509_t*,linked_list_t*))add_subjectAltNames; this->public.build_encoding = (void (*) (x509_t*,hash_algorithm_t,rsa_private_key_t*))build_encoding; this->public.destroy = (void (*) (x509_t*))destroy; @@ -1417,13 +1475,19 @@ static private_x509_t *x509_create_empty(void) /* * Described in header. */ -x509_t *x509_create_(chunk_t serialNumber, identification_t *issuer, identification_t *subject) +x509_t *x509_create(chunk_t serialNumber, identification_t *issuer, + time_t notBefore, time_t notAfter, + identification_t *subject, + rsa_public_key_t *public_key) { private_x509_t *this = x509_create_empty(); this->serialNumber = serialNumber; this->issuer = issuer->clone(issuer); + this->notBefore = notBefore; + this->notAfter = notAfter; this->subject = subject->clone(subject); + this->public_key = public_key->clone(public_key); return &this->public; } diff --git a/src/libstrongswan/crypto/x509.h b/src/libstrongswan/crypto/x509.h index 1ab267dac..def45be6b 100755 --- a/src/libstrongswan/crypto/x509.h +++ b/src/libstrongswan/crypto/x509.h @@ -9,8 +9,8 @@ * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss * Copyright (C) 2002 Mario Strasser - * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur - * Copyright (C) 2006 Martin Willi, Andreas Steffen + * Copyright (C) 2006 Martin Willi + * Copyright (C) 2000-2008 Andreas Steffen * * Hochschule fuer Technik Rapperswil * @@ -24,7 +24,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: x509.h 3301 2007-10-12 21:56:30Z andreas $ + * RCSID $Id: x509.h 3421 2008-01-22 01:09:19Z andreas $ */ #ifndef X509_H_ @@ -327,6 +327,7 @@ struct x509_t { * @param notBefore start date of validity * @param notAfter end date of validity * @param subject subject distinguished name + * @param public_key public key * * @return created x509_t certificate, or NULL if invalid. * @@ -334,7 +335,8 @@ struct x509_t { */ x509_t *x509_create(chunk_t serialNumber, identification_t *issuer, time_t notBefore, time_t notAfter, - identification_t *subject); + identification_t *subject, + rsa_public_key_t *public_key); /** * @brief Read a X.509 certificate from a DER encoded blob. diff --git a/src/libstrongswan/utils/linked_list.c b/src/libstrongswan/utils/linked_list.c index 5cd8ffd7a..63e1bcfbf 100644 --- a/src/libstrongswan/utils/linked_list.c +++ b/src/libstrongswan/utils/linked_list.c @@ -677,6 +677,52 @@ static status_t get_last(private_linked_list_t *this, void **item) } /** + * Implementation of linked_list_t.find_first. + */ +static status_t find_first(private_linked_list_t *this, linked_list_match_t match, + void **item, void *d1, void *d2, void *d3, void *d4, void *d5) +{ + element_t *current = this->first; + + while (current) + { + if (match(current->value, d1, d2, d3, d4, d5)) + { + if (item != NULL) + { + *item = current->value; + } + return SUCCESS; + } + current = current->next; + } + return NOT_FOUND; +} + +/** + * Implementation of linked_list_t.find_last. + */ +static status_t find_last(private_linked_list_t *this, linked_list_match_t match, + void **item, void *d1, void *d2, void *d3, void *d4, void *d5) +{ + element_t *current = this->last; + + while (current) + { + if (match(current->value, d1, d2, d3, d4, d5)) + { + if (item != NULL) + { + *item = current->value; + } + return SUCCESS; + } + current = current->previous; + } + return NOT_FOUND; +} + +/** * Implementation of linked_list_t.invoke_offset. */ static void invoke_offset(private_linked_list_t *this, size_t offset) @@ -843,6 +889,8 @@ linked_list_t *linked_list_create() this->public.create_enumerator = (enumerator_t*(*)(linked_list_t*))create_enumerator; this->public.get_first = (status_t (*) (linked_list_t *, void **item))get_first; this->public.get_last = (status_t (*) (linked_list_t *, void **item))get_last; + this->public.find_first = (status_t (*) (linked_list_t *, linked_list_match_t,void**,...))find_first; + this->public.find_last = (status_t (*) (linked_list_t *, linked_list_match_t,void**,...))find_last; this->public.insert_first = (void (*) (linked_list_t *, void *item))insert_first; this->public.insert_last = (void (*) (linked_list_t *, void *item))insert_last; this->public.remove_first = (status_t (*) (linked_list_t *, void **item))remove_first; diff --git a/src/libstrongswan/utils/linked_list.h b/src/libstrongswan/utils/linked_list.h index ebe5c187c..ac36ef46d 100644 --- a/src/libstrongswan/utils/linked_list.h +++ b/src/libstrongswan/utils/linked_list.h @@ -33,6 +33,19 @@ typedef struct linked_list_t linked_list_t; #include <utils/iterator.h> #include <utils/enumerator.h> + +/** + * Method to match elements in a linked list (used in find_* functions) + * + * @param item current list item + * @param ... user supplied data (only pointers, at most 5) + * @return + * - TRUE, if the item matched + * - FALSE, otherwise + * @ingroup utils + */ +typedef bool (*linked_list_match_t)(void *item, ...); + /** * @brief Class implementing a double linked list. * @@ -187,6 +200,50 @@ struct linked_list_t { */ status_t (*get_last) (linked_list_t *this, void **item); + /** @brief Find the first matching element in the list. + * + * The first object passed to the match function is the current list item, + * followed by the user supplied data. + * If the supplied function returns TRUE this function returns SUCCESS, and + * the current object is returned in the third parameter, otherwise, + * the next item is checked. + * + * @warning Only use pointers as user supplied data. + * + * @param this calling object + * @param match comparison function to call on each object + * @param[out] item + * - the list item, if found + * - NULL, otherwise + * @param ... user data to supply to match function (limited to 5 arguments) + * @return + * - SUCCESS, if found + * - NOT_FOUND, otherwise + */ + status_t (*find_first) (linked_list_t *this, linked_list_match_t match, void **item, ...); + + /** @brief Find the last matching element in the list. + * + * The first object passed to the match function is the current list item, + * followed by the user supplied data. + * If the supplied function returns TRUE this function returns SUCCESS, and + * the current object is returned in the third parameter, otherwise, + * the next item is checked. + * + * @warning Only use pointers as user supplied data. + * + * @param this calling object + * @param match comparison function to call on each object + * @param[out] item + * - the list item, if found + * - NULL, otherwise + * @param ... user data to supply to match function (limited to 5 arguments) + * @return + * - SUCCESS, if found + * - NOT_FOUND, otherwise + */ + status_t (*find_last) (linked_list_t *this, linked_list_match_t match, void **item, ...); + /** * @brief Invoke a method on all of the contained objects. * diff --git a/src/libstrongswan/utils/optionsfrom.c b/src/libstrongswan/utils/optionsfrom.c index ffa571b05..39e38cc58 100644 --- a/src/libstrongswan/utils/optionsfrom.c +++ b/src/libstrongswan/utils/optionsfrom.c @@ -6,8 +6,10 @@ */ /* - * Copyright (C) 1998, 1999 Henry Spencer. - * + * Copyright (C) 2007-2008 Andreas Steffen + * + * Hochschule fuer Technik Rapperswil + * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your @@ -18,6 +20,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * + * RCSID $Id$ */ #include <stdio.h> @@ -30,29 +33,64 @@ #include "optionsfrom.h" #define MAX_USES 20 /* loop-detection limit */ -#define SOME_ARGS 10 /* first guess at how many arguments we'll need */ +#define MORE_ARGS 10 /* first guess at how many arguments we'll need */ /* * Defined in header. */ -bool optionsfrom(const char *filename, int *argcp, char **argvp[], int optind) -{ - static int nuses = 0; + +typedef struct private_options_t private_options_t; + +/** + * Private data of a options_t object. + */ +struct private_options_t { + /** + * Public interface + */ + options_t public; + + /** + * reallocated argv array + */ char **newargv; + + /** + * number of free arguments in newargv + */ + int room; + + /** + * number of included option files + */ + int nuses; + + /** + * allocated space for option files + */ + char *buffers[MAX_USES]; +}; + +/** + * Defined in header + */ +bool from(private_options_t *this, char *filename, int *argcp, char **argvp[], + int optind) +{ int newargc; int next; /* place for next argument */ - int room; /* how many more new arguments we can hold */ + char **newargv; size_t bytes; - chunk_t chunk, src, line, token; + chunk_t src, line, token; bool good = TRUE; int linepos = 0; FILE *fd; /* avoid endless loops with recursive --optionsfrom arguments */ - nuses++; - if (nuses >= MAX_USES) + this->nuses++; + if (this->nuses >= MAX_USES) { - DBG1("optionsfrom called %d times - looping?", (*argvp)[0], nuses); + DBG1("optionsfrom called %d times by \"%s\" - looping?", this->nuses + 1, (*argvp)[0]); return FALSE; } @@ -66,26 +104,31 @@ bool optionsfrom(const char *filename, int *argcp, char **argvp[], int optind) /* determine the file size */ fseek(fd, 0, SEEK_END); - chunk.len = ftell(fd); + src.len = ftell(fd); rewind(fd); /* allocate one byte more just in case of a missing final newline */ - chunk.ptr = malloc(chunk.len + 1); + src.ptr = this->buffers[this->nuses] = malloc(src.len + 1); /* read the whole file into a chunk */ - bytes = fread(chunk.ptr, 1, chunk.len, fd); + bytes = fread(src.ptr, 1, src.len, fd); fclose(fd); - newargc = *argcp + SOME_ARGS; - newargv = malloc((newargc + 1) * sizeof(char *)); + if (this->room) + { + newargc = *argcp; + newargv = malloc((newargc + 1 + this->room) * sizeof(char *)); + } + else + { + newargc = *argcp + MORE_ARGS; + this->room = MORE_ARGS; + newargv = malloc((newargc + 1) * sizeof(char *)); + } memcpy(newargv, *argvp, optind * sizeof(char *)); - room = SOME_ARGS; next = optind; newargv[next] = NULL; - /* we keep the chunk pointer so that we can still free it */ - src = chunk; - while (fetchline(&src, &line) && good) { linepos++; @@ -116,11 +159,11 @@ bool optionsfrom(const char *filename, int *argcp, char **argvp[], int optind) } /* do we have to allocate more memory for additional arguments? */ - if (room == 0) + if (this->room == 0) { - newargc += SOME_ARGS; - newargv = realloc(newargv, (newargc+1) * sizeof(char *)); - room = SOME_ARGS; + newargc += MORE_ARGS; + newargv = realloc(newargv, (newargc + 1) * sizeof(char *)); + this->room = MORE_ARGS; } /* terminate the token by replacing the delimiter with a null character */ @@ -129,20 +172,54 @@ bool optionsfrom(const char *filename, int *argcp, char **argvp[], int optind) /* assign the token to the next argument */ newargv[next] = token.ptr; next++; - room--; + this->room--; } } - if (!good) /* error of some kind */ + /* assign newargv to argv */ + if (good) { - free(chunk.ptr); - free(newargv); - return FALSE; + memcpy(newargv + next, *argvp + optind, (*argcp + 1 - optind) * sizeof(char *)); + *argcp += next - optind; + *argvp = newargv; } - memcpy(newargv + next, *argvp + optind, (*argcp + 1 - optind) * sizeof(char *)); - *argcp += next - optind; - *argvp = newargv; - return TRUE; + /* keep a pointer to the latest newargv and free any earlier version */ + free(this->newargv); + this->newargv = newargv; + + return good; +} + +/** + * Defined in header + */ +void destroy(private_options_t *this) +{ + while (this->nuses >= 0) + { + free(this->buffers[this->nuses--]); + } + free(this->newargv); + free(this); } +/* + * Defined in header + */ +options_t *options_create(void) +{ + private_options_t *this = malloc_thing(private_options_t); + + /* initialize */ + this->newargv = NULL; + this->room = 0; + this->nuses = -1; + memset(this->buffers, '\0', MAX_USES); + + /* public functions */ + this->public.from = (bool (*) (options_t*,char*,int*,char***,int))from; + this->public.destroy = (void (*) (options_t*))destroy; + + return &this->public; +} diff --git a/src/libstrongswan/utils/optionsfrom.h b/src/libstrongswan/utils/optionsfrom.h index d6b9efde5..0014cec36 100644 --- a/src/libstrongswan/utils/optionsfrom.h +++ b/src/libstrongswan/utils/optionsfrom.h @@ -6,8 +6,9 @@ */ /* - * Copyright (C) 1998, 1999 Henry Spencer. - * Copyright (C) 2007 Andreas Steffen, Hochschule fuer Technik Rapperswil + * Copyright (C) 2007-2008 Andreas Steffen + * + * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -18,20 +19,51 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. + * + * RCSID $Id$ */ #ifndef OPTIONSFROM_H_ #define OPTIONSFROM_H_ +typedef struct options_t options_t; + /** - * @brief Pick up more options from a file, in the middle of an option scan + * @brief options object. * - * @param filename file containing the options - * @param argcp pointer to argc - * @param argvp pointer to argv[] - * @param optind current optind, number of next argument - * @return TRUE if optionsfrom parsing successful + * @b Constructors: + * - options_create() + * + * @ingroup utils + */ +struct options_t { + /** + * @brief Check if the PKCS#7 contentType is data + * + * @param this calling object + * @param filename file containing the options + * @param argcp pointer to argc + * @param argvp pointer to argv[] + * @param optind current optind, number of next argument + * @return TRUE if optionsfrom parsing successful + */ + bool (*from) (options_t * this, char *filename, int *argcp, char **argvp[], int optind); + + /** + * @brief Destroys the options_t object. + * + * @param this options_t object to destroy + */ + void (*destroy) (options_t *this); +}; + +/** + * @brief Create an options object. + * + * @return created options_t object + * + * @ingroup utils */ -bool optionsfrom(const char *filename, int *argcp, char **argvp[], int optind); +options_t *options_create(void); #endif /*OPTIONSFROM_H_*/ diff --git a/src/manager/Makefile.in b/src/manager/Makefile.in index 3830d37fc..d8cb38881 100644 --- a/src/manager/Makefile.in +++ b/src/manager/Makefile.in @@ -221,11 +221,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ diff --git a/src/manager/lib/request.c b/src/manager/lib/request.c index 2e18bded5..bbaec10cc 100644 --- a/src/manager/lib/request.c +++ b/src/manager/lib/request.c @@ -27,6 +27,7 @@ #include <library.h> #include <stdlib.h> #include <string.h> +#include <pthread.h> #include <ClearSilver/ClearSilver.h> typedef struct private_request_t private_request_t; @@ -58,22 +59,28 @@ struct private_request_t { }; /** - * thread specific FCGX_Request, used for ClearSilver cgiwrap callbacks. - * ClearSilver cgiwrap is not threadsave, so we use a private + * key to a thread specific FCGX_Request, used for ClearSilver cgiwrap callbacks. + * ClearSilver cgiwrap is not threadsave, so we use a private * context for each thread. */ -static __thread FCGX_Request *req; +static pthread_key_t req_key; /** * length of param list in req->envp */ -static __thread int req_env_len; +static pthread_key_t req_env_len_key; + +/** + * control variable for pthread_once + */ +pthread_once_t once = PTHREAD_ONCE_INIT; /** * fcgiwrap read callback */ static int read_cb(void *null, char *buf, int size) { + FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key); return FCGX_GetStr(buf, size, req->in); } @@ -82,6 +89,7 @@ static int read_cb(void *null, char *buf, int size) */ static int writef_cb(void *null, const char *format, va_list args) { + FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key); FCGX_VFPrintF(req->out, format, args); return 0; } @@ -90,6 +98,7 @@ static int writef_cb(void *null, const char *format, va_list args) */ static int write_cb(void *null, const char *buf, int size) { + FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key); return FCGX_PutStr(buf, size, req->out); } @@ -99,7 +108,7 @@ static int write_cb(void *null, const char *buf, int size) static char *getenv_cb(void *null, const char *key) { char *value; - + FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key); value = FCGX_GetParam(key, req->envp); return value ? strdup(value) : NULL; } @@ -120,7 +129,8 @@ static int iterenv_cb(void *null, int num, char **key, char **value) { *key = NULL; *value = NULL; - + FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key); + int req_env_len = (int)pthread_getspecific(req_env_len_key); if (num < req_env_len) { char *eq; @@ -256,13 +266,24 @@ static void destroy(private_request_t *this) free(this); } +/** + * This initialization method is guaranteed to run only once + * for all threads. + */ +static void init(void) +{ + cgiwrap_init_emu(NULL, read_cb, writef_cb, write_cb, + getenv_cb, putenv_cb, iterenv_cb); + pthread_key_create(&req_key, NULL); + pthread_key_create(&req_env_len_key, NULL); +} + /* * see header file */ request_t *request_create(FCGX_Request *request, bool debug) { NEOERR* err; - static bool initialized = FALSE; private_request_t *this = malloc_thing(private_request_t); this->public.get_path = (char*(*)(request_t*))get_path; @@ -277,21 +298,19 @@ request_t *request_create(FCGX_Request *request, bool debug) this->public.setf = (void(*)(request_t*, char *format, ...))setf; this->public.destroy = (void(*)(request_t*))destroy; - if (!initialized) - { - cgiwrap_init_emu(NULL, read_cb, writef_cb, write_cb, - getenv_cb, putenv_cb, iterenv_cb); - initialized = TRUE; - } + pthread_once(&once, init); this->req = request; - req = request; - req_env_len = 0; - while (req->envp[req_env_len] != NULL) + pthread_setspecific(req_key, (void*)request); + + int req_env_len = 0; + while (request->envp[req_env_len] != NULL) { req_env_len++; } + pthread_setspecific(req_env_len_key, (void*)req_env_len); + err = hdf_init(&this->hdf); if (!err) { diff --git a/src/openac/Makefile.in b/src/openac/Makefile.in index d0f7817dc..3cca270a7 100644 --- a/src/openac/Makefile.in +++ b/src/openac/Makefile.in @@ -187,11 +187,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ diff --git a/src/openac/build.c b/src/openac/build.c index d03e73048..40c8b7964 100644 --- a/src/openac/build.c +++ b/src/openac/build.c @@ -13,7 +13,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: build.c 3270 2007-10-08 20:09:57Z andreas $ + * RCSID $Id: build.c 3424 2008-01-22 10:34:44Z andreas $ */ #include <stdlib.h> @@ -167,7 +167,7 @@ static chunk_t build_attr_cert_info(void) ASN1_INTEGER_1, build_holder(), build_v2_form(), - ASN1_sha1WithRSA_id, + asn1_algorithmIdentifier(OID_SHA1_WITH_RSA), asn1_simple_object(ASN1_INTEGER, serial), build_attr_cert_validity(), build_attributes(), @@ -180,21 +180,14 @@ static chunk_t build_attr_cert_info(void) */ chunk_t build_attr_cert(void) { - u_char *pos; - chunk_t rawSignature, signatureValue; + chunk_t signatureValue; chunk_t attributeCertificateInfo = build_attr_cert_info(); - /* build the signature */ signerkey->build_emsa_pkcs1_signature(signerkey, HASH_SHA1, - attributeCertificateInfo, &rawSignature); - pos = build_asn1_object(&signatureValue, ASN1_BIT_STRING, - 1 + rawSignature.len); - *pos++ = 0x00; - memcpy(pos, rawSignature.ptr, rawSignature.len); - free(rawSignature.ptr); + attributeCertificateInfo, &signatureValue); return asn1_wrap(ASN1_SEQUENCE, "mcm", attributeCertificateInfo, - ASN1_sha1WithRSA_id, - signatureValue); + asn1_algorithmIdentifier(OID_SHA1_WITH_RSA), + asn1_bitstring("m", signatureValue)); } diff --git a/src/openac/openac.c b/src/openac/openac.c index 075f0039a..3d82940c2 100755 --- a/src/openac/openac.c +++ b/src/openac/openac.c @@ -20,7 +20,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: openac.c 3305 2007-10-17 02:55:17Z andreas $ + * RCSID $Id: openac.c 3442 2008-02-04 14:46:43Z andreas $ */ #include <stdio.h> @@ -234,6 +234,8 @@ int main(int argc, char **argv) time_t validity = 0; int status = 1; + options_t *options = options_create(); + /* enable openac debugging hook */ dbg = openac_dbg; @@ -300,7 +302,7 @@ int main(int argc, char **argv) { snprintf(path, BUF_LEN, "%s/%s", OPENAC_PATH, optarg); } - if (!optionsfrom(path, &argc, &argv, optind)) + if (!options->from(options, path, &argc, &argv, optind)) { status = 1; goto end; @@ -509,5 +511,6 @@ end: free(serial.ptr); closelog(); dbg = dbg_default; + options->destroy(options); exit(status); } diff --git a/src/pluto/Makefile.in b/src/pluto/Makefile.in index 77a0a7548..a9ae01d65 100644 --- a/src/pluto/Makefile.in +++ b/src/pluto/Makefile.in @@ -237,11 +237,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ diff --git a/src/pluto/asn1.c b/src/pluto/asn1.c index 0e50b8211..7436d4d1a 100644 --- a/src/pluto/asn1.c +++ b/src/pluto/asn1.c @@ -11,7 +11,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: asn1.c 3252 2007-10-06 21:24:50Z andreas $ + * RCSID $Id: asn1.c 3451 2008-02-05 19:27:05Z andreas $ */ #include <stdlib.h> @@ -758,13 +758,23 @@ is_asn1(chunk_t blob) ) return FALSE; } + len = asn1_length(&blob); - if (len != blob.len) + + /* exact match */ + if (len == blob.len) { - DBG(DBG_PARSING, - DBG_log(" file size does not match ASN.1 coded length"); - ) - return FALSE; + return TRUE; } - return TRUE; + + /* some websites append a surplus newline character to the blob */ + if (len + 1 == blob.len && *(blob.ptr + len) == '\n') + { + return TRUE; + } + + DBG(DBG_PARSING, + DBG_log(" file size does not match ASN.1 coded length"); + ) + return FALSE; } diff --git a/src/pluto/pkcs1.c b/src/pluto/pkcs1.c index bb8afde0a..49a06a8bc 100644 --- a/src/pluto/pkcs1.c +++ b/src/pluto/pkcs1.c @@ -13,7 +13,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: pkcs1.c 3252 2007-10-06 21:24:50Z andreas $ + * RCSID $Id: pkcs1.c 3427 2008-01-27 20:17:15Z andreas $ */ #include <stddef.h> @@ -442,11 +442,13 @@ RSA_encrypt(const RSA_public_key_t *key, chunk_t in) *pos++ = 0x02; /* pad with pseudo random bytes unequal to zero */ - get_rnd_bytes(pos, padding); for (i = 0; i < padding; i++) { + get_rnd_bytes(pos, padding); while (!*pos) - get_rnd_bytes(pos, 1); + { + get_rnd_bytes(pos, 1); + } pos++; } diff --git a/src/pluto/vendor.c b/src/pluto/vendor.c index 0e6e3d9b7..c31a4195b 100644 --- a/src/pluto/vendor.c +++ b/src/pluto/vendor.c @@ -11,7 +11,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: vendor.c 3380 2007-12-04 23:54:32Z andreas $ + * RCSID $Id: vendor.c 3472 2008-02-14 21:26:21Z andreas $ */ #include <stdlib.h> @@ -206,7 +206,8 @@ static struct vid_struct _vid_tab[] = { /* * strongSwan */ - DEC_MD5_VID(STRONGSWAN, "strongSwan 4.1.10") + DEC_MD5_VID(STRONGSWAN, "strongSwan 4.1.11") + DEC_MD5_VID(STRONGSWAN_4_1_10,"strongSwan 4.1.10") DEC_MD5_VID(STRONGSWAN_4_1_9, "strongSwan 4.1.9") DEC_MD5_VID(STRONGSWAN_4_1_8, "strongSwan 4.1.8") DEC_MD5_VID(STRONGSWAN_4_1_7, "strongSwan 4.1.7") diff --git a/src/pluto/vendor.h b/src/pluto/vendor.h index d0853b08c..03d2fde77 100644 --- a/src/pluto/vendor.h +++ b/src/pluto/vendor.h @@ -11,7 +11,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: vendor.h 3380 2007-12-04 23:54:32Z andreas $ + * RCSID $Id: vendor.h 3413 2007-12-24 18:07:55Z andreas $ */ #ifndef _VENDOR_H_ @@ -113,6 +113,7 @@ enum known_vendorid { VID_STRONGSWAN_4_1_7 = 95, VID_STRONGSWAN_4_1_8 = 96, VID_STRONGSWAN_4_1_9 = 97, + VID_STRONGSWAN_4_1_10 = 98, /* 101 - 200 : NAT-Traversal */ VID_NATT_STENBERG_01 =101, diff --git a/src/scepclient/Makefile.in b/src/scepclient/Makefile.in index 52304d44a..1f0cbf48f 100644 --- a/src/scepclient/Makefile.in +++ b/src/scepclient/Makefile.in @@ -198,11 +198,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ diff --git a/src/starter/Makefile.in b/src/starter/Makefile.in index 509ec6668..a9e86fab0 100644 --- a/src/starter/Makefile.in +++ b/src/starter/Makefile.in @@ -194,11 +194,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ diff --git a/src/stroke/Makefile.in b/src/stroke/Makefile.in index dbb15c0e0..ad3df98d5 100644 --- a/src/stroke/Makefile.in +++ b/src/stroke/Makefile.in @@ -182,11 +182,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ diff --git a/src/whack/Makefile.in b/src/whack/Makefile.in index 44ac0c8da..258102021 100644 --- a/src/whack/Makefile.in +++ b/src/whack/Makefile.in @@ -182,11 +182,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ +plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +simreader = @simreader@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ |