summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2008-03-30 08:31:24 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2008-03-30 08:31:24 +0000
commit1c088a8b6237ec67f63c23f97a0f2dc4e99af869 (patch)
tree7fff7c8329d19bbaa910312e746a116f28fbfaf5 /src
parentbcc8f7ca7fd8e8ff6e8a4d579251458313133598 (diff)
downloadvyos-strongswan-1c088a8b6237ec67f63c23f97a0f2dc4e99af869.tar.gz
vyos-strongswan-1c088a8b6237ec67f63c23f97a0f2dc4e99af869.zip
[svn-upgrade] Integrating new upstream version, strongswan (4.1.11)
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in2
-rw-r--r--src/_copyright/Makefile.in2
-rw-r--r--src/_updown/Makefile.in2
-rw-r--r--src/_updown_espmark/Makefile.in2
-rw-r--r--src/charon/Makefile.am7
-rw-r--r--src/charon/Makefile.in104
-rw-r--r--src/charon/control/interface_manager.c15
-rwxr-xr-xsrc/charon/control/interfaces/stroke_interface.c21
-rw-r--r--src/charon/encoding/payloads/eap_payload.c8
-rw-r--r--src/charon/encoding/payloads/eap_payload.h11
-rw-r--r--src/charon/encoding/payloads/id_payload.c3
-rw-r--r--src/charon/sa/authenticators/eap/eap_sim.c482
-rw-r--r--src/charon/sa/authenticators/eap/eap_sim.h89
-rw-r--r--src/charon/sa/authenticators/eap/sim/eap_sim_file.c288
-rw-r--r--src/charon/sa/authenticators/eap_authenticator.c15
-rw-r--r--src/charon/sa/connect_manager.c223
-rw-r--r--src/charon/sa/ike_sa.c9
-rw-r--r--src/charon/sa/ike_sa_manager.c23
-rw-r--r--src/charon/sa/ike_sa_manager.h21
-rw-r--r--src/dumm/Makefile.in2
-rw-r--r--src/include/Makefile.in2
-rw-r--r--src/ipsec/Makefile.in2
-rw-r--r--src/libcrypto/Makefile.in2
-rw-r--r--src/libfreeswan/Makefile.in2
-rw-r--r--src/libstrongswan/Makefile.am1
-rw-r--r--src/libstrongswan/Makefile.in57
-rw-r--r--src/libstrongswan/asn1/asn1.c133
-rw-r--r--src/libstrongswan/asn1/asn1.h32
-rw-r--r--src/libstrongswan/asn1/oid.c221
-rw-r--r--src/libstrongswan/asn1/oid.h74
-rw-r--r--src/libstrongswan/asn1/oid.pl8
-rw-r--r--src/libstrongswan/asn1/oid.txt111
-rw-r--r--src/libstrongswan/crypto/hashers/hasher.c38
-rw-r--r--src/libstrongswan/crypto/hashers/hasher.h21
-rw-r--r--src/libstrongswan/crypto/ocsp.c8
-rw-r--r--src/libstrongswan/crypto/ocsp.h5
-rw-r--r--src/libstrongswan/crypto/pkcs7.c449
-rw-r--r--src/libstrongswan/crypto/pkcs7.h85
-rw-r--r--src/libstrongswan/crypto/pkcs9.c470
-rw-r--r--src/libstrongswan/crypto/pkcs9.h121
-rw-r--r--src/libstrongswan/crypto/rsa/rsa_private_key.c123
-rw-r--r--src/libstrongswan/crypto/rsa/rsa_private_key.h6
-rw-r--r--src/libstrongswan/crypto/rsa/rsa_public_key.c117
-rw-r--r--src/libstrongswan/crypto/rsa/rsa_public_key.h40
-rwxr-xr-xsrc/libstrongswan/crypto/x509.c94
-rwxr-xr-xsrc/libstrongswan/crypto/x509.h10
-rw-r--r--src/libstrongswan/utils/linked_list.c48
-rw-r--r--src/libstrongswan/utils/linked_list.h57
-rw-r--r--src/libstrongswan/utils/optionsfrom.c143
-rw-r--r--src/libstrongswan/utils/optionsfrom.h50
-rw-r--r--src/manager/Makefile.in2
-rw-r--r--src/manager/lib/request.c51
-rw-r--r--src/openac/Makefile.in2
-rw-r--r--src/openac/build.c19
-rwxr-xr-xsrc/openac/openac.c7
-rw-r--r--src/pluto/Makefile.in2
-rw-r--r--src/pluto/asn1.c24
-rw-r--r--src/pluto/pkcs1.c8
-rw-r--r--src/pluto/vendor.c5
-rw-r--r--src/pluto/vendor.h3
-rw-r--r--src/scepclient/Makefile.in2
-rw-r--r--src/starter/Makefile.in2
-rw-r--r--src/stroke/Makefile.in2
-rw-r--r--src/whack/Makefile.in2
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**)&current))
- {
- 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**)&current))
- {
- 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**)&current))
- {
- 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**)&current))
- {
- 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**)&current))
- {
- 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**)&current))
- {
- 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**)&current))
- {
- 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@